diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/cl_console.c | 1 | ||||
-rw-r--r-- | src/client/cl_keys.c | 119 | ||||
-rw-r--r-- | src/client/client.h | 2 | ||||
-rw-r--r-- | src/client/snd_codec.c | 2 | ||||
-rw-r--r-- | src/client/snd_codec_ogg.c | 2 | ||||
-rw-r--r-- | src/client/snd_openal.c | 43 |
6 files changed, 162 insertions, 7 deletions
diff --git a/src/client/cl_console.c b/src/client/cl_console.c index efbf2d17..22a148a1 100644 --- a/src/client/cl_console.c +++ b/src/client/cl_console.c @@ -312,6 +312,7 @@ void Con_Init (void) { Field_Clear( &historyEditLines[i] ); historyEditLines[i].widthInChars = g_console_field_width; } + CL_LoadConsoleHistory( ); Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f); Cmd_AddCommand ("messagemode", Con_MessageMode_f); diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c index f80c24c3..232f04a4 100644 --- a/src/client/cl_keys.c +++ b/src/client/cl_keys.c @@ -484,10 +484,10 @@ void Console_Key (int key) { // enter finishes the line if ( key == K_ENTER || key == K_KP_ENTER ) { - // if not in the game explicitly prepent a slash if needed + // if not in the game explicitly prepend a slash if needed if ( cls.state != CA_ACTIVE && g_consoleField.buffer[0] != '\\' && g_consoleField.buffer[0] != '/' ) { - char temp[MAX_STRING_CHARS]; + char temp[MAX_EDIT_LINE-1]; Q_strncpyz( temp, g_consoleField.buffer, sizeof( temp ) ); Com_sprintf( g_consoleField.buffer, sizeof( g_consoleField.buffer ), "\\%s", temp ); @@ -520,6 +520,8 @@ void Console_Key (int key) { g_consoleField.widthInChars = g_console_field_width; + CL_SaveConsoleHistory( ); + if ( cls.state == CA_DISCONNECTED ) { SCR_UpdateScreen (); // force an update, because the command } // may take some time @@ -529,7 +531,7 @@ void Console_Key (int key) { // command completion if (key == K_TAB) { - Field_CompleteCommand(&g_consoleField); + Field_AutoComplete(&g_consoleField); return; } @@ -1210,6 +1212,12 @@ void CL_CharEvent( int key ) { return; } + // delete is not a printable character and is + // otherwise handled by Field_KeyDownEvent + if ( key == 127 ) { + return; + } + // distribute the key down event to the apropriate handler if ( cls.keyCatchers & KEYCATCH_CONSOLE ) { @@ -1294,3 +1302,108 @@ Ket_SetCatcher void Key_SetCatcher( int catcher ) { cls.keyCatchers = catcher; } + +// This must not exceed MAX_CMD_LINE +#define MAX_CONSOLE_SAVE_BUFFER 1024 +static char consoleSaveBuffer[ MAX_CONSOLE_SAVE_BUFFER ]; + +/* +================ +CL_LoadConsoleHistory + +Load the console history from cl_consoleHistory +================ +*/ +void CL_LoadConsoleHistory( void ) +{ + char *token, *text_p; + int i, numChars, numLines = 0; + cvar_t *cv; + + cv = Cvar_Get( "cl_consoleHistory", "", CVAR_ARCHIVE|CVAR_ROM ); + Q_strncpyz( consoleSaveBuffer, cv->string, MAX_CONSOLE_SAVE_BUFFER ); + + text_p = consoleSaveBuffer; + + for( i = COMMAND_HISTORY - 1; i >= 0; i-- ) + { + if( !*( token = COM_Parse( &text_p ) ) ) + break; + + historyEditLines[ i ].cursor = atoi( token ); + + if( !*( token = COM_Parse( &text_p ) ) ) + break; + + historyEditLines[ i ].scroll = atoi( token ); + + if( !*( token = COM_Parse( &text_p ) ) ) + break; + + numChars = atoi( token ); + text_p++; + if( numChars > ( strlen( consoleSaveBuffer ) - ( text_p - consoleSaveBuffer ) ) ) + { + Com_DPrintf( S_COLOR_YELLOW "WARNING: probable corrupt history\n" ); + break; + } + Com_Memcpy( historyEditLines[ i ].buffer, + text_p, numChars ); + historyEditLines[ i ].buffer[ numChars ] = '\0'; + text_p += numChars; + + numLines++; + } + + memmove( &historyEditLines[ 0 ], &historyEditLines[ i + 1 ], + numLines * sizeof( field_t ) ); + for( i = numLines; i < COMMAND_HISTORY; i++ ) + Field_Clear( &historyEditLines[ i ] ); + + historyLine = nextHistoryLine = numLines; +} + +/* +================ +CL_SaveConsoleHistory + +Save the console history into the cvar cl_consoleHistory +so that it persists across invocations of q3 +================ +*/ +void CL_SaveConsoleHistory( void ) +{ + int i; + int lineLength, saveBufferLength, additionalLength; + + consoleSaveBuffer[ 0 ] = '\0'; + + i = ( nextHistoryLine - 1 ) % COMMAND_HISTORY; + do + { + if( historyEditLines[ i ].buffer[ 0 ] ) + { + lineLength = strlen( historyEditLines[ i ].buffer ); + saveBufferLength = strlen( consoleSaveBuffer ); + + //ICK "seta cl_consoleHistory " + "%d %d %d " = 23 + 13 = 36 + additionalLength = lineLength + 36; + + if( saveBufferLength + additionalLength < MAX_CONSOLE_SAVE_BUFFER ) + { + Q_strcat( consoleSaveBuffer, MAX_CONSOLE_SAVE_BUFFER, + va( "%d %d %d %s ", + historyEditLines[ i ].cursor, + historyEditLines[ i ].scroll, + lineLength, + historyEditLines[ i ].buffer ) ); + } + else + break; + } + i = ( i - 1 + COMMAND_HISTORY ) % COMMAND_HISTORY; + } + while( i != ( nextHistoryLine - 1 ) % COMMAND_HISTORY ); + + Cvar_Set( "cl_consoleHistory", consoleSaveBuffer ); +} diff --git a/src/client/client.h b/src/client/client.h index fb1ecea1..f0aa6e8e 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -454,6 +454,8 @@ void Con_Top( void ); void Con_Bottom( void ); void Con_Close( void ); +void CL_LoadConsoleHistory( void ); +void CL_SaveConsoleHistory( void ); // // cl_scrn.c diff --git a/src/client/snd_codec.c b/src/client/snd_codec.c index e1c6bb47..98fae65f 100644 --- a/src/client/snd_codec.c +++ b/src/client/snd_codec.c @@ -98,7 +98,7 @@ void S_CodecInit() { codecs = NULL; S_CodecRegister(&wav_codec); -#ifdef USE_CODEC_VORBIS +#if USE_CODEC_VORBIS S_CodecRegister(&ogg_codec); #endif } diff --git a/src/client/snd_codec_ogg.c b/src/client/snd_codec_ogg.c index 20462fcb..464d8d38 100644 --- a/src/client/snd_codec_ogg.c +++ b/src/client/snd_codec_ogg.c @@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // OGG support is enabled by this define -#ifdef USE_CODEC_VORBIS +#if USE_CODEC_VORBIS // includes for the Q3 sound system #include "client.h" diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c index e8b0915d..01b965ae 100644 --- a/src/client/snd_openal.c +++ b/src/client/snd_openal.c @@ -39,6 +39,7 @@ cvar_t *s_alDopplerSpeed; cvar_t *s_alMinDistance; cvar_t *s_alRolloff; cvar_t *s_alDriver; +cvar_t *s_alMaxSpeakerDistance; /* ================= @@ -469,6 +470,7 @@ typedef struct src_s static src_t srcList[MAX_SRC]; static int srcCount = 0; static qboolean alSourcesInitialised = qfalse; +static vec3_t lastListenerOrigin = { 0.0f, 0.0f, 0.0f }; typedef struct sentity_s { @@ -487,6 +489,22 @@ static sentity_t entityList[MAX_GENTITIES]; /* ================= +S_AL_SanitiseVector +================= +*/ +#define S_AL_SanitiseVector(v) _S_AL_SanitiseVector(v,__LINE__) +static void _S_AL_SanitiseVector( vec3_t v, int line ) +{ + if( Q_isnan( v[ 0 ] ) || Q_isnan( v[ 1 ] ) || Q_isnan( v[ 2 ] ) ) + { + Com_DPrintf( S_COLOR_YELLOW "WARNING: vector with one or more NaN components " + "being passed to OpenAL at %s:%d -- zeroing\n", __FILE__, line ); + VectorClear( v ); + } +} + +/* +================= S_AL_SrcInit ================= */ @@ -762,6 +780,7 @@ S_AL_UpdateEntityPosition static void S_AL_UpdateEntityPosition( int entityNum, const vec3_t origin ) { + S_AL_SanitiseVector( (vec_t *)origin ); if ( entityNum < 0 || entityNum > MAX_GENTITIES ) Com_Error( ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum ); VectorCopy( origin, entityList[entityNum].origin ); @@ -816,6 +835,7 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx } else VectorCopy( origin, sorigin ); + S_AL_SanitiseVector( sorigin ); qalSourcefv(srcList[src].alSource, AL_POSITION, sorigin); // Start it playing @@ -896,7 +916,9 @@ S_AL_AddLoopingSound static void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) { - S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, origin, velocity, entityNum); + S_AL_SanitiseVector( (vec_t *)origin ); + S_AL_SanitiseVector( (vec_t *)velocity ); + S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum); } /* @@ -907,7 +929,17 @@ S_AL_AddRealLoopingSound static void S_AL_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) { - S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum); + S_AL_SanitiseVector( (vec_t *)origin ); + S_AL_SanitiseVector( (vec_t *)velocity ); + + // There are certain maps (*cough* Q3:TA mpterra*) that have large quantities + // of ET_SPEAKERS in the PVS at any given time. OpenAL can't cope with mixing + // large numbers of sounds, so this culls them by distance + if( DistanceSquared( origin, lastListenerOrigin ) > + s_alMaxSpeakerDistance->value * s_alMaxSpeakerDistance->value ) + return; + + S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, origin, velocity, entityNum); } /* @@ -1429,12 +1461,18 @@ S_AL_Respatialize static void S_AL_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ) { + S_AL_SanitiseVector( (vec_t *)origin ); + S_AL_SanitiseVector( axis[ 0 ] ); + S_AL_SanitiseVector( axis[ 1 ] ); + S_AL_SanitiseVector( axis[ 2 ] ); // Axis[0] = Forward // Axis[2] = Up float velocity[] = {0.0f, 0.0f, 0.0f}; float orientation[] = {axis[0][0], axis[0][1], axis[0][2], axis[2][0], axis[2][1], axis[2][2]}; + VectorCopy( origin, lastListenerOrigin ); + // Set OpenAL listener paramaters qalListenerfv(AL_POSITION, (ALfloat *)origin); qalListenerfv(AL_VELOCITY, velocity); @@ -1592,6 +1630,7 @@ qboolean S_AL_Init( soundInterface_t *si ) s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE ); s_alMinDistance = Cvar_Get( "s_alMinDistance", "120", CVAR_CHEAT ); s_alRolloff = Cvar_Get( "s_alRolloff", "0.8", CVAR_CHEAT ); + s_alMaxSpeakerDistance = Cvar_Get( "s_alMaxSpeakerDistance", "1024", CVAR_ARCHIVE ); s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE ); |