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
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
s_autoMute 0 = never mute
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_Cmd_SetHelp", CG_EXT_CMD_SETHELP },
{ "trap_MatchAlertEvent", CG_EXT_MATCHALERTEVENT },
{ "trap_Error2", CG_EXT_ERROR2 },
// commands
{ "screenshotnc", 1 },
{ "screenshotncJPEG", 1 }
@ -336,7 +337,7 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
Com_Printf( "%s", (const char*)VMA(1) );
return 0;
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;
case CG_MILLISECONDS:
return Sys_Milliseconds();
@ -615,6 +616,10 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
Sys_MatchAlert( (sysMatchAlertEvent_t)args[1] );
return 0;
case CG_EXT_ERROR2:
Com_ErrorExt( ERR_DROP, EXT_ERRMOD_CGAME, (qbool)args[2], "%s", (const char*)VMA(1) );
return 0;
default:
Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] );
}

View file

@ -843,7 +843,7 @@ void CL_Disconnect_f( void )
{
SCR_StopCinematic();
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_Cvar_SetRange", UI_EXT_CVAR_SETRANGE },
{ "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 ) {
@ -782,7 +784,7 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
{
switch( args[0] ) {
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;
case UI_PRINT:
@ -1134,6 +1136,14 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
Cmd_SetHelp( VMA(1), VMA(2) );
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:
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()
{
cls.uiErrorCallbackVMCall = 0;
cls.keyCatchers &= ~KEYCATCH_UI;
cls.uiStarted = qfalse;
if ( !uivm )
@ -1173,10 +1184,21 @@ void CL_InitUI()
}
// init for this gamestate
cls.uiErrorCallbackVMCall = 0;
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
qbool UI_GameCommand()

View file

@ -259,9 +259,12 @@ typedef struct {
qbool uiStarted;
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)
// extension: forward errors to ui?
int uiErrorCallbackVMCall; // 0 when not available
int framecount;
int frametime; // msec since last frame
@ -477,6 +480,7 @@ void CL_SetCGameTime();
//
void CL_InitUI();
void CL_ShutdownUI();
void CL_ForwardUIError( int level, int module, const char* error );
int Key_GetCatcher( void );
void Key_SetCatcher( int catcher );
void LAN_LoadCachedServers( void );

View file

@ -187,7 +187,8 @@ typedef enum {
CG_EXT_CVAR_SETRANGE,
CG_EXT_CVAR_SETHELP,
CG_EXT_CMD_SETHELP,
CG_EXT_MATCHALERTEVENT
CG_EXT_MATCHALERTEVENT,
CG_EXT_ERROR2
} 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 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
FS_PureServerSetLoadedPaks( "" );
@ -266,15 +282,22 @@ void QDECL Com_Error( int code, const char *fmt, ... )
#ifndef DEDICATED
CL_Disconnect( qtrue );
CL_FlushMemory();
if ( realError )
CL_ForwardUIError( EXT_ERRLEV_SVDISC, module, com_errorMessage );
#endif
com_errorEntered = qfalse;
longjmp (abortframe, -1);
} else if ( code == ERR_DROP || code == ERR_DISCONNECT ) {
Com_Printf( "********************\nERROR: %s\n********************\n", com_errorMessage );
if (realError)
Com_Printf( "********************\nERROR: %s\n********************\n", com_errorMessage );
else
Com_Printf( "ERROR: %s\n", com_errorMessage );
SV_Shutdown( va("Server crashed: %s", com_errorMessage) );
#ifndef DEDICATED
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
com_errorEntered = qfalse;
longjmp (abortframe, -1);

View file

@ -392,7 +392,8 @@ typedef enum {
G_EXT_LOCATEINTEROPDATA,
G_EXT_CVAR_SETRANGE,
G_EXT_CVAR_SETHELP,
G_EXT_CMD_SETHELP
G_EXT_CMD_SETHELP,
G_EXT_ERROR2
} 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, ... );
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_sprintf (char *dest, int size, const char *fmt, ...);

View file

@ -146,7 +146,9 @@ typedef enum {
UI_EXT_R_ADDREFENTITYTOSCENE2,
UI_EXT_CVAR_SETRANGE,
UI_EXT_CVAR_SETHELP,
UI_EXT_CMD_SETHELP
UI_EXT_CMD_SETHELP,
UI_EXT_ERROR2,
UI_EXT_ENABLEERRORCALLBACK
} uiImport_t;
@ -294,6 +296,7 @@ typedef enum {
UI_DRAW_CONNECT_SCREEN,
// void UI_DrawConnectScreen( qboolean overlay );
UI_HASUNIQUECDKEY
// if !overlay, the background will be drawn, otherwise it will be
// 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_Cvar_SetRange", G_EXT_CVAR_SETRANGE },
{ "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 ) {
@ -267,7 +268,7 @@ static intptr_t SV_GameSystemCalls( intptr_t* args )
Com_Printf( "%s", (const char*)VMA(1) );
return 0;
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;
case G_MILLISECONDS:
return Sys_Milliseconds();
@ -826,6 +827,10 @@ static intptr_t SV_GameSystemCalls( intptr_t* args )
Cmd_SetHelp( VMA(1), VMA(2) );
return 0;
case G_EXT_ERROR2:
Com_ErrorExt( ERR_DROP, EXT_ERRMOD_GAME, (qbool)args[2], "%s", (const char*)VMA(1) );
return 0;
default:
Com_Error( ERR_DROP, "Bad game system trap: %i", args[0] );
}