summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_main.c55
-rw-r--r--src/cgame/cg_public.h6
-rw-r--r--src/client/cl_input.c40
-rw-r--r--src/client/cl_main.c53
4 files changed, 113 insertions, 41 deletions
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index a440bf7f..68a34159 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -32,6 +32,7 @@ displayContextDef_t cgDC;
void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum );
void CG_Shutdown( void );
+static char *CG_VoIPString( void );
/*
================
@@ -84,6 +85,9 @@ Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3,
CG_EventHandling( arg0 );
return 0;
+ case CG_VOIP_STRING:
+ return (intptr_t)CG_VoIPString( );
+
default:
CG_Error( "vmMain: unknown command %i", command );
break;
@@ -1836,3 +1840,54 @@ void CG_Shutdown( void )
// some mods may need to do cleanup work here,
// like closing files or archiving session data
}
+
+/*
+================
+CG_VoIPString
+================
+*/
+static char *CG_VoIPString( void )
+{
+ // a generous overestimate of the space needed for 0,1,2...61,62,63
+ static char voipString[ MAX_CLIENTS * 4 ];
+ char voipSendTarget[ MAX_CVAR_VALUE_STRING ];
+
+ trap_Cvar_VariableStringBuffer( "cl_voipSendTarget", voipSendTarget,
+ sizeof( voipSendTarget ) );
+
+ if( Q_stricmp( voipSendTarget, "team" ) == 0 )
+ {
+ int i, slen, nlen;
+ for( slen = i = 0; i < cgs.maxclients; i++ )
+ {
+ if( !cgs.clientinfo[ i ].infoValid || i == cg.clientNum )
+ continue;
+ if( cgs.clientinfo[ i ].team != cgs.clientinfo[ cg.clientNum ].team )
+ continue;
+
+ nlen = Q_snprintf( &voipString[ slen ], sizeof( voipString ) - slen,
+ "%s%d", ( slen > 0 ) ? "," : "", i );
+ if( slen + nlen + 1 >= sizeof( voipString ) )
+ {
+ CG_Printf( S_COLOR_YELLOW "WARNING: voipString overflowed\n" );
+ break;
+ }
+
+ slen += nlen;
+ }
+
+ // Notice that if the snprintf was truncated, slen was not updated
+ // so this will remove any trailing commas or partially-completed numbers
+ voipString[ slen ] = '\0';
+ }
+ else if( Q_stricmp( voipSendTarget, "crosshair" ) == 0 )
+ Com_sprintf( voipString, sizeof( voipString ), "%d",
+ CG_CrosshairPlayer( ) );
+ else if( Q_stricmp( voipSendTarget, "attacker" ) == 0 )
+ Com_sprintf( voipString, sizeof( voipString ), "%d",
+ CG_LastAttacker( ) );
+ else
+ return NULL;
+
+ return voipString;
+}
diff --git a/src/cgame/cg_public.h b/src/cgame/cg_public.h
index 3f4b13f3..98ffb00a 100644
--- a/src/cgame/cg_public.h
+++ b/src/cgame/cg_public.h
@@ -248,10 +248,14 @@ typedef enum
CG_EVENT_HANDLING,
// void (*CG_EventHandling)(int type);
- CG_CONSOLE_TEXT
+ CG_CONSOLE_TEXT,
// void (*CG_ConsoleText)( void );
// pass text that has been printed to the console to cgame
// use Cmd_Argc() / Cmd_Argv() to read it
+
+ CG_VOIP_STRING
+ // char *(*CG_VoIPString)( void );
+ // returns a string of comma-delimited clientnums based on cl_voipSendTarget
} cgameExport_t;
//----------------------------------------------
diff --git a/src/client/cl_input.c b/src/client/cl_input.c
index dae244bb..d3c38868 100644
--- a/src/client/cl_input.c
+++ b/src/client/cl_input.c
@@ -761,46 +761,6 @@ void CL_WritePacket( void ) {
#ifdef USE_VOIP
if (clc.voipOutgoingDataSize > 0) { // only send if data.
- // Move cl_voipSendTarget from a string to the bitmasks if needed.
- if (cl_voipSendTarget->modified) {
- char buffer[32];
- const char *target = cl_voipSendTarget->string;
-
- if (Q_stricmp(target, "attacker") == 0) {
- int player = VM_Call( cgvm, CG_LAST_ATTACKER );
- Com_sprintf(buffer, sizeof (buffer), "%d", player);
- target = buffer;
- } else if (Q_stricmp(target, "crosshair") == 0) {
- int player = VM_Call( cgvm, CG_CROSSHAIR_PLAYER );
- Com_sprintf(buffer, sizeof (buffer), "%d", player);
- target = buffer;
- }
-
- if ((*target == '\0') || (Q_stricmp(target, "all") == 0)) {
- const int all = 0x7FFFFFFF;
- clc.voipTarget1 = clc.voipTarget2 = clc.voipTarget3 = all;
- } else if (Q_stricmp(target, "none") == 0) {
- clc.voipTarget1 = clc.voipTarget2 = clc.voipTarget3 = 0;
- } else {
- const char *ptr = target;
- clc.voipTarget1 = clc.voipTarget2 = clc.voipTarget3 = 0;
- do {
- if ((*ptr == ',') || (*ptr == '\0')) {
- const int val = atoi(target);
- target = ptr + 1;
- if ((val >= 0) && (val < 31)) {
- clc.voipTarget1 |= (1 << (val-0));
- } else if ((val >= 31) && (val < 62)) {
- clc.voipTarget2 |= (1 << (val-31));
- } else if ((val >= 62) && (val < 93)) {
- clc.voipTarget3 |= (1 << (val-62));
- }
- }
- } while (*(ptr++));
- }
- cl_voipSendTarget->modified = qfalse;
- }
-
MSG_WriteByte (&buf, clc_EOF); // placate legacy servers.
MSG_WriteByte (&buf, clc_extension);
MSG_WriteByte (&buf, clc_voip);
diff --git a/src/client/cl_main.c b/src/client/cl_main.c
index a891e5a3..738347ea 100644
--- a/src/client/cl_main.c
+++ b/src/client/cl_main.c
@@ -214,6 +214,58 @@ void CL_UpdateVoipGain(const char *idstr, float gain)
}
}
+/*
+================
+CL_VoipParseTargets
+
+Sets clc.voipTarget{1,2,3} by asking the cgame to produce a string and then
+parsing it as a series of client numbers
+Perhaps it would be better to allow the cgame to set the three integers
+directly, but this way we can change the net protocol without changing the
+vmcall
+================
+*/
+static void CL_VoipParseTargets( void )
+{
+ const char *target = cl_voipSendTarget->string;
+ intptr_t p = VM_Call( cgvm, CG_VOIP_STRING );
+
+ if( p )
+ target = VM_ExplicitArgPtr( cgvm, p );
+
+ if( !target[ 0 ] || Q_stricmp( target, "all" ) == 0 )
+ clc.voipTarget1 = clc.voipTarget2 = clc.voipTarget3 = 0x7FFFFFFF;
+ else if( Q_stricmp( target, "none" ) == 0 )
+ clc.voipTarget1 = clc.voipTarget2 = clc.voipTarget3 = 0;
+ else
+ {
+ char *end;
+ int val;
+ clc.voipTarget1 = clc.voipTarget2 = clc.voipTarget3 = 0;
+
+ while( 1 )
+ {
+ while( *target && !isdigit( *target ) )
+ target++;
+ if( !*target )
+ break;
+
+ val = strtol( target, &end, 10 );
+ assert( target != end );
+ if( val < 0 || val >= MAX_CLIENTS )
+ Com_Printf( S_COLOR_YELLOW "WARNING: VoIP target %d is not a valid "
+ "client number\n", val );
+ else if( val < 31 )
+ clc.voipTarget1 |= 1 << val;
+ else if( ( val -= 31 ) < 31 )
+ clc.voipTarget2 |= 1 << val;
+ else if( ( val -= 31 ) < 31 )
+ clc.voipTarget3 |= 1 << val;
+ target = end;
+ }
+ }
+}
+
void CL_Voip_f( void )
{
const char *cmd = Cmd_Argv(1);
@@ -348,6 +400,7 @@ void CL_CaptureVoip(void)
S_MasterGain(cl_voipGainDuringCapture->value);
S_StartCapture();
CL_VoipNewGeneration();
+ CL_VoipParseTargets();
}
if ((cl_voipSend->integer) || (finalFrame)) { // user wants to capture audio?