error extension - trap_Error2 and trap_EnableErrorCallback

This commit is contained in:
myT 2017-11-10 20:21:03 +01:00
parent ec40b94aa9
commit 69efe163ac
11 changed files with 95 additions and 13 deletions

View file

@ -1,6 +1,8 @@
DD Mmm 17 - 1.49 DD Mmm 17 - 1.49
add: with compatible mods, drop and disconnect errors will be displayed in the UI
add: s_autoMute selects when the audio output should be disabled add: s_autoMute selects when the audio output should be disabled
s_autoMute 0 = never mute s_autoMute 0 = never mute
s_autoMute 1 (default) = mute when the window doesn't have input focus s_autoMute 1 (default) = mute when the window doesn't have input focus

View file

@ -308,6 +308,7 @@ static qbool CL_CG_GetValue( char* value, int valueSize, const char* key )
{ "trap_Cvar_SetHelp", CG_EXT_CVAR_SETHELP }, { "trap_Cvar_SetHelp", CG_EXT_CVAR_SETHELP },
{ "trap_Cmd_SetHelp", CG_EXT_CMD_SETHELP }, { "trap_Cmd_SetHelp", CG_EXT_CMD_SETHELP },
{ "trap_MatchAlertEvent", CG_EXT_MATCHALERTEVENT }, { "trap_MatchAlertEvent", CG_EXT_MATCHALERTEVENT },
{ "trap_Error2", CG_EXT_ERROR2 },
// commands // commands
{ "screenshotnc", 1 }, { "screenshotnc", 1 },
{ "screenshotncJPEG", 1 } { "screenshotncJPEG", 1 }
@ -336,7 +337,7 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
Com_Printf( "%s", (const char*)VMA(1) ); Com_Printf( "%s", (const char*)VMA(1) );
return 0; return 0;
case CG_ERROR: case CG_ERROR:
Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); Com_ErrorExt( ERR_DROP, EXT_ERRMOD_CGAME, qtrue, "%s", (const char*)VMA(1) );
return 0; return 0;
case CG_MILLISECONDS: case CG_MILLISECONDS:
return Sys_Milliseconds(); return Sys_Milliseconds();
@ -615,6 +616,10 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
Sys_MatchAlert( (sysMatchAlertEvent_t)args[1] ); Sys_MatchAlert( (sysMatchAlertEvent_t)args[1] );
return 0; return 0;
case CG_EXT_ERROR2:
Com_ErrorExt( ERR_DROP, EXT_ERRMOD_CGAME, (qbool)args[2], "%s", (const char*)VMA(1) );
return 0;
default: default:
Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] ); Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] );
} }

View file

@ -843,7 +843,7 @@ void CL_Disconnect_f( void )
{ {
SCR_StopCinematic(); SCR_StopCinematic();
if ( cls.state != CA_DISCONNECTED && cls.state != CA_CINEMATIC ) { if ( cls.state != CA_DISCONNECTED && cls.state != CA_CINEMATIC ) {
Com_Error (ERR_DISCONNECT, "Disconnected from server"); Com_ErrorExt( ERR_DISCONNECT, EXT_ERRMOD_ENGINE, qfalse, "Disconnected from server" );
} }
} }

View file

@ -759,7 +759,9 @@ static qbool CL_UI_GetValue( char* value, int valueSize, const char* key )
{ "trap_R_AddRefEntityToScene2", UI_EXT_R_ADDREFENTITYTOSCENE2 }, { "trap_R_AddRefEntityToScene2", UI_EXT_R_ADDREFENTITYTOSCENE2 },
{ "trap_Cvar_SetRange", UI_EXT_CVAR_SETRANGE }, { "trap_Cvar_SetRange", UI_EXT_CVAR_SETRANGE },
{ "trap_Cvar_SetHelp", UI_EXT_CVAR_SETHELP }, { "trap_Cvar_SetHelp", UI_EXT_CVAR_SETHELP },
{ "trap_Cmd_SetHelp", UI_EXT_CMD_SETHELP } { "trap_Cmd_SetHelp", UI_EXT_CMD_SETHELP },
{ "trap_Error2", UI_EXT_ERROR2 },
{ "trap_EnableErrorCallback", UI_EXT_ENABLEERRORCALLBACK }
}; };
for ( int i = 0; i < ARRAY_LEN( syscalls ); ++i ) { for ( int i = 0; i < ARRAY_LEN( syscalls ); ++i ) {
@ -782,7 +784,7 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
{ {
switch( args[0] ) { switch( args[0] ) {
case UI_ERROR: case UI_ERROR:
Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); Com_ErrorExt( ERR_DROP, EXT_ERRMOD_UI, qtrue, "%s", (const char*)VMA(1) );
return 0; return 0;
case UI_PRINT: case UI_PRINT:
@ -1134,6 +1136,14 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
Cmd_SetHelp( VMA(1), VMA(2) ); Cmd_SetHelp( VMA(1), VMA(2) );
return 0; return 0;
case UI_EXT_ERROR2:
Com_ErrorExt( ERR_DROP, EXT_ERRMOD_UI, (qbool)args[2], "%s", (const char*)VMA(1) );
return 0;
case UI_EXT_ENABLEERRORCALLBACK:
cls.uiErrorCallbackVMCall = (int)args[1];
return 0;
default: default:
Com_Error( ERR_DROP, "Bad UI system trap: %i", args[0] ); Com_Error( ERR_DROP, "Bad UI system trap: %i", args[0] );
} }
@ -1144,6 +1154,7 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
void CL_ShutdownUI() void CL_ShutdownUI()
{ {
cls.uiErrorCallbackVMCall = 0;
cls.keyCatchers &= ~KEYCATCH_UI; cls.keyCatchers &= ~KEYCATCH_UI;
cls.uiStarted = qfalse; cls.uiStarted = qfalse;
if ( !uivm ) if ( !uivm )
@ -1173,10 +1184,21 @@ void CL_InitUI()
} }
// init for this gamestate // init for this gamestate
cls.uiErrorCallbackVMCall = 0;
VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE) ); VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE) );
} }
void CL_ForwardUIError( int level, int module, const char* error )
{
if ( uivm == NULL || cls.uiErrorCallbackVMCall == 0 )
return;
Q_strncpyz( (char*)interopBufferOut, error, interopBufferOutSize );
VM_Call( uivm, cls.uiErrorCallbackVMCall, level, module );
}
// see if the current console command is claimed by the ui // see if the current console command is claimed by the ui
qbool UI_GameCommand() qbool UI_GameCommand()

View file

@ -259,9 +259,12 @@ typedef struct {
qbool uiStarted; qbool uiStarted;
qbool cgameStarted; qbool cgameStarted;
// forward input to cgame regardless of keycatcher state? // extension: forward input to cgame regardless of keycatcher state?
int cgameForwardInput; // 1=mouse, 2=keys (note: we don't forward the escape key) int cgameForwardInput; // 1=mouse, 2=keys (note: we don't forward the escape key)
// extension: forward errors to ui?
int uiErrorCallbackVMCall; // 0 when not available
int framecount; int framecount;
int frametime; // msec since last frame int frametime; // msec since last frame
@ -477,6 +480,7 @@ void CL_SetCGameTime();
// //
void CL_InitUI(); void CL_InitUI();
void CL_ShutdownUI(); void CL_ShutdownUI();
void CL_ForwardUIError( int level, int module, const char* error );
int Key_GetCatcher( void ); int Key_GetCatcher( void );
void Key_SetCatcher( int catcher ); void Key_SetCatcher( int catcher );
void LAN_LoadCachedServers( void ); void LAN_LoadCachedServers( void );

View file

@ -187,7 +187,8 @@ typedef enum {
CG_EXT_CVAR_SETRANGE, CG_EXT_CVAR_SETRANGE,
CG_EXT_CVAR_SETHELP, CG_EXT_CVAR_SETHELP,
CG_EXT_CMD_SETHELP, CG_EXT_CMD_SETHELP,
CG_EXT_MATCHALERTEVENT CG_EXT_MATCHALERTEVENT,
CG_EXT_ERROR2
} cgameImport_t; } cgameImport_t;

View file

@ -221,11 +221,27 @@ void QDECL Com_DPrintf( const char *fmt, ...)
} }
void QDECL Com_Error( int code, const char *fmt, ... ) void QDECL Com_Error( int level, const char* fmt, ... )
{
static char msg[MAXPRINTMSG];
va_list argptr;
va_start( argptr, fmt );
Q_vsnprintf( msg, sizeof(msg), fmt, argptr );
Com_ErrorExt( level, EXT_ERRMOD_ENGINE, qtrue, "%s", msg );
va_end(argptr);
}
void QDECL Com_ErrorExt( int code, int module, qbool realError, const char *fmt, ... )
{ {
static int lastErrorTime; static int lastErrorTime;
static int errorCount; static int errorCount;
#ifndef DEDICATED
void CL_ForwardUIError( int level, int module, const char* error ); // client.h
#endif
// make sure we can get at our local stuff // make sure we can get at our local stuff
FS_PureServerSetLoadedPaks( "" ); FS_PureServerSetLoadedPaks( "" );
@ -266,15 +282,22 @@ void QDECL Com_Error( int code, const char *fmt, ... )
#ifndef DEDICATED #ifndef DEDICATED
CL_Disconnect( qtrue ); CL_Disconnect( qtrue );
CL_FlushMemory(); CL_FlushMemory();
if ( realError )
CL_ForwardUIError( EXT_ERRLEV_SVDISC, module, com_errorMessage );
#endif #endif
com_errorEntered = qfalse; com_errorEntered = qfalse;
longjmp (abortframe, -1); longjmp (abortframe, -1);
} else if ( code == ERR_DROP || code == ERR_DISCONNECT ) { } else if ( code == ERR_DROP || code == ERR_DISCONNECT ) {
if (realError)
Com_Printf( "********************\nERROR: %s\n********************\n", com_errorMessage ); Com_Printf( "********************\nERROR: %s\n********************\n", com_errorMessage );
else
Com_Printf( "ERROR: %s\n", com_errorMessage );
SV_Shutdown( va("Server crashed: %s", com_errorMessage) ); SV_Shutdown( va("Server crashed: %s", com_errorMessage) );
#ifndef DEDICATED #ifndef DEDICATED
CL_Disconnect( qtrue ); CL_Disconnect( qtrue );
CL_FlushMemory(); CL_FlushMemory(); // shuts down the VMs and starts them back up
if ( realError )
CL_ForwardUIError( code == ERR_DROP ? EXT_ERRLEV_DROP : EXT_ERRLEV_DISC, module, com_errorMessage );
#endif #endif
com_errorEntered = qfalse; com_errorEntered = qfalse;
longjmp (abortframe, -1); longjmp (abortframe, -1);

View file

@ -392,7 +392,8 @@ typedef enum {
G_EXT_LOCATEINTEROPDATA, G_EXT_LOCATEINTEROPDATA,
G_EXT_CVAR_SETRANGE, G_EXT_CVAR_SETRANGE,
G_EXT_CVAR_SETHELP, G_EXT_CVAR_SETHELP,
G_EXT_CMD_SETHELP G_EXT_CMD_SETHELP,
G_EXT_ERROR2
} gameImport_t; } gameImport_t;

View file

@ -501,9 +501,25 @@ void PerpendicularVector( vec3_t dst, const vec3_t src );
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// error extension
typedef enum {
EXT_ERRMOD_ENGINE,
EXT_ERRMOD_CGAME,
EXT_ERRMOD_GAME,
EXT_ERRMOD_UI
} extErrorModule_t;
// error extension
typedef enum {
EXT_ERRLEV_DROP, // ERR_DROP
EXT_ERRLEV_DISC, // ERR_DISCONNECT
EXT_ERRLEV_SVDISC // ERR_SERVERDISCONNECT
} extErrorLevel_t;
const char* QDECL va( const char* format, ... ); const char* QDECL va( const char* format, ... );
void QDECL Com_Error( int level, const char* error, ... ); void QDECL Com_Error( int level, const char* error, ... );
void QDECL Com_ErrorExt( int level, int module, qbool realError, const char* error, ... );
void QDECL Com_Printf( const char* msg, ... ); void QDECL Com_Printf( const char* msg, ... );
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...); void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...);

View file

@ -146,7 +146,9 @@ typedef enum {
UI_EXT_R_ADDREFENTITYTOSCENE2, UI_EXT_R_ADDREFENTITYTOSCENE2,
UI_EXT_CVAR_SETRANGE, UI_EXT_CVAR_SETRANGE,
UI_EXT_CVAR_SETHELP, UI_EXT_CVAR_SETHELP,
UI_EXT_CMD_SETHELP UI_EXT_CMD_SETHELP,
UI_EXT_ERROR2,
UI_EXT_ENABLEERRORCALLBACK
} uiImport_t; } uiImport_t;
@ -294,6 +296,7 @@ typedef enum {
UI_DRAW_CONNECT_SCREEN, UI_DRAW_CONNECT_SCREEN,
// void UI_DrawConnectScreen( qboolean overlay ); // void UI_DrawConnectScreen( qboolean overlay );
UI_HASUNIQUECDKEY UI_HASUNIQUECDKEY
// if !overlay, the background will be drawn, otherwise it will be // if !overlay, the background will be drawn, otherwise it will be
// overlayed over whatever the cgame has drawn. // overlayed over whatever the cgame has drawn.

View file

@ -241,7 +241,8 @@ static qbool SV_G_GetValue( char* value, int valueSize, const char* key )
{ "trap_LocateInteropData", G_EXT_LOCATEINTEROPDATA }, { "trap_LocateInteropData", G_EXT_LOCATEINTEROPDATA },
{ "trap_Cvar_SetRange", G_EXT_CVAR_SETRANGE }, { "trap_Cvar_SetRange", G_EXT_CVAR_SETRANGE },
{ "trap_Cvar_SetHelp", G_EXT_CVAR_SETHELP }, { "trap_Cvar_SetHelp", G_EXT_CVAR_SETHELP },
{ "trap_Cmd_SetHelp", G_EXT_CMD_SETHELP } { "trap_Cmd_SetHelp", G_EXT_CMD_SETHELP },
{ "trap_Error2", G_EXT_ERROR2 }
}; };
for ( int i = 0; i < ARRAY_LEN( syscalls ); ++i ) { for ( int i = 0; i < ARRAY_LEN( syscalls ); ++i ) {
@ -267,7 +268,7 @@ static intptr_t SV_GameSystemCalls( intptr_t* args )
Com_Printf( "%s", (const char*)VMA(1) ); Com_Printf( "%s", (const char*)VMA(1) );
return 0; return 0;
case G_ERROR: case G_ERROR:
Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); Com_ErrorExt( ERR_DROP, EXT_ERRMOD_GAME, qtrue, "%s", (const char*)VMA(1) );
return 0; return 0;
case G_MILLISECONDS: case G_MILLISECONDS:
return Sys_Milliseconds(); return Sys_Milliseconds();
@ -826,6 +827,10 @@ static intptr_t SV_GameSystemCalls( intptr_t* args )
Cmd_SetHelp( VMA(1), VMA(2) ); Cmd_SetHelp( VMA(1), VMA(2) );
return 0; return 0;
case G_EXT_ERROR2:
Com_ErrorExt( ERR_DROP, EXT_ERRMOD_GAME, (qbool)args[2], "%s", (const char*)VMA(1) );
return 0;
default: default:
Com_Error( ERR_DROP, "Bad game system trap: %i", args[0] ); Com_Error( ERR_DROP, "Bad game system trap: %i", args[0] );
} }