summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/cl_console.c1
-rw-r--r--src/client/cl_keys.c119
-rw-r--r--src/client/client.h2
-rw-r--r--src/client/snd_codec.c2
-rw-r--r--src/client/snd_codec_ogg.c2
-rw-r--r--src/client/snd_openal.c43
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 );