the VM error functions.
-Moved the static variables of Host_Error into the function body.
-Changed the definition of error_cmd to be called instead of Host_Error,
so the VM control code is in full control of the error processing.
-Added MP_Error to the menu, so a menu crash wont shutdown the server anymore.
-Fixed an annying bug caused by a typo, that crashes Nexuiz if you query for
a string in the serverlist.
-PRVM_Crash resets the prog pointer now.
-PRVM_Begin use Con_Printf again (but PRVM_DEBUGPRSTACK has been disabled again).
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5374
d7cf8633-e32d-0410-b094-
e92efae38249
cvar_t timestamps = {CVAR_SAVE, "timestamps", "0"};
cvar_t timeformat = {CVAR_SAVE, "timeformat", "[%b %e %X] "};
+/*
+================
+Host_AbortCurrentFrame
+
+aborts the current host frame and goes on with the next one
+================
+*/
+void Host_AbortCurrentFrame(void)
+{
+ longjmp (host_abortserver, 1);
+}
+
/*
================
Host_Error
This shuts down both the client and server
================
*/
-void PRVM_ProcessError(void);
-static char hosterrorstring1[4096];
-static char hosterrorstring2[4096];
-static qboolean hosterror = false;
void Host_Error (const char *error, ...)
{
+ static char hosterrorstring1[4096];
+ static char hosterrorstring2[4096];
+ static qboolean hosterror = false;
va_list argptr;
va_start (argptr,error);
//PR_Crash();
- //PRVM_Crash(); // crash current prog
+ // print out where the crash happened, if it was caused by QC (and do a cleanup)
+ PRVM_Crash();
- // crash all prvm progs
- PRVM_CrashAll();
-
- PRVM_ProcessError();
Host_ShutdownServer (false);
hosterror = false;
- longjmp (host_abortserver, 1);
+ Host_AbortCurrentFrame();
}
void Host_ServerOptions (void)
return;
SV_VM_Begin();
- // print out where the crash happened, if it was caused by QC
- //PRVM_Crash();
NetConn_Heartbeat(2);
NetConn_Heartbeat(2);
}
}
-
/*
==================
Host_ServerFrame
void MR_SetRouting (qboolean forceold);
-void MP_Error(void)
+void MP_Error(const char *format, ...)
{
+ char errorstring[4096];
+ va_list argptr;
+
+ va_start (argptr, format);
+ dpvsnprintf (errorstring, sizeof(errorstring), format, argptr);
+ va_end (argptr);
+ Con_Printf( "Menu_Error: %s\n", errorstring );
+
+ PRVM_Crash();
+
// fall back to the normal menu
// say it
key_dest = key_game;
- //PRVM_ResetProg();
-
// init the normal menu now -> this will also correct the menu router pointers
MR_SetRouting (TRUE);
+
+ Host_AbortCurrentFrame();
}
void MP_Keydown (int key, char ascii)
PRVM_End;
}
+void MP_Fallback (void)
+{
+ MP_Shutdown();
+
+ key_dest = key_game;
+
+ // init the normal menu now -> this will also correct the menu router pointers
+ MR_SetRouting (TRUE);
+}
+
void MP_Init (void)
{
PRVM_Begin;
Cvar_RegisterVariable (&forceqmenu);
Cvar_RegisterVariable (&menu_options_colorcontrol_correctionvalue);
if (gamemode == GAME_NETHERWORLD)
- Cmd_AddCommand ("menu_fallback", MP_Error); //Force to old-style menu
+ Cmd_AddCommand ("menu_fallback", MP_Fallback); //Force to old-style menu
Cmd_AddCommand ("menu_restart",MR_Restart);
Cmd_AddCommand ("togglemenu", Call_MR_ToggleMenu_f);
}
int field;
VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmaskstring );
- str = PRVM_G_STRING( OFS_PARM1 );
+ str = PRVM_G_STRING( OFS_PARM2 );
if( !str )
PRVM_ERROR( "VM_M_setserverlistmaskstring: null string passed!" );
void (*init_cmd)(void); // [INIT] used by PRVM_InitProg
void (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg
- void (*error_cmd)(void); // [INIT]
+ void (*error_cmd)(const char *format, ...); // [INIT]
} prvm_prog_t;
//============================================================================
// used as replacement for a prog stack
-#define PRVM_DEBUGPRSTACK
+//#define PRVM_DEBUGPRSTACK
#ifdef PRVM_DEBUGPRSTACK
-#define PRVM_Begin if(prog != 0) Host_Error("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__)
+#define PRVM_Begin if(prog != 0) Con_Printf("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__)
#define PRVM_End prog = 0
#else
#define PRVM_Begin
// helper macro to make function pointer calls easier
#define PRVM_GCALL(func) if(prog->func) prog->func
-#define PRVM_ERROR Host_Error
+#define PRVM_ERROR prog->error_cmd
// other prog handling functions
qboolean PRVM_SetProgFromString(const char *str);
ddef_t *infielddefs;
dfunction_t *dfunctions;
+ if( prog->loaded ) {
+ PRVM_ERROR ("PRVM_LoadProgs: there is already a %s program loaded!\n", PRVM_NAME );
+ }
+
prog->progs = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false);
if (prog->progs == NULL)
PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
memset(prog, 0, sizeof(prvm_prog_t));
prog->time = &prog->_time;
+ prog->error_cmd = Host_Error;
}
int PRVM_GetProgNr()
return NULL;
}
-void PRVM_ProcessError(void)
-{
- if(prog)
- PRVM_GCALL(error_cmd)();
-}
-
/*
int NUM_FOR_EDICT_ERROR(prvm_edict_t *e)
{
void PRVM_Crash()
{
-
- //TODO: make this more compilant with PR_Crash
- if (prog->depth < 1)
+ if( prog->depth > 0 )
{
- // kill the stack just to be sure
- prog->depth = 0;
- prog->localstack_used = 0;
- return;
+ Con_Printf("QuakeC crash report for %s:\n", PRVM_NAME);
+ PRVM_PrintState();
}
- Con_Printf("QuakeC crash report for %s:\n", PRVM_NAME);
- PRVM_PrintState();
-
// dump the stack so host_error can shutdown functions
prog->depth = 0;
prog->localstack_used = 0;
+ // reset the prog pointer
+ prog = NULL;
}
/*
void Host_ShutdownServer(qboolean crash);
void Host_Reconnect_f(void);
+void Host_AbortCurrentFrame(void);
+
// skill level for currently loaded level (in case the user changes the cvar while the level is running, this reflects the level actually in use)
extern int current_skill;
extern client_t *host_client;
-extern jmp_buf host_abortserver;
-
//===========================================================
void SV_Init (void);