]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
add feature "prvm_errordump" to make a savegame on PRVM_Crash - hopefully this helps...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 19 Jul 2008 19:31:03 +0000 (19:31 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 19 Jul 2008 19:31:03 +0000 (19:31 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8417 d7cf8633-e32d-0410-b094-e92efae38249

host_cmd.c
prvm_edict.c
prvm_exec.c

index 5c835c63f598e7dece987d00d2316a30b5913132..1a1b3d8d3916dc1fd4d08205e6a8bc7fd1271b24 100644 (file)
@@ -435,6 +435,75 @@ LOAD / SAVE GAME
 
 #define        SAVEGAME_VERSION        5
 
+void Host_Savegame_to (const char *name)
+{
+       qfile_t *f;
+       int             i;
+       char    comment[SAVEGAME_COMMENT_LENGTH+1];
+       qboolean isserver;
+
+       isserver = !strcmp(PRVM_NAME, "server");
+
+       Con_Printf("Saving game to %s...\n", name);
+       f = FS_Open (name, "wb", false, false);
+       if (!f)
+       {
+               Con_Print("ERROR: couldn't open.\n");
+               return;
+       }
+
+       FS_Printf(f, "%i\n", SAVEGAME_VERSION);
+
+       memset(comment, 0, sizeof(comment));
+       if(isserver)
+               dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog->edicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters);
+       else
+               dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", PRVM_NAME);
+       // convert space to _ to make stdio happy
+       // LordHavoc: convert control characters to _ as well
+       for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
+               if (comment[i] <= ' ')
+                       comment[i] = '_';
+       comment[SAVEGAME_COMMENT_LENGTH] = '\0';
+
+       FS_Printf(f, "%s\n", comment);
+       if(isserver)
+       {
+               for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
+                       FS_Printf(f, "%f\n", svs.clients[0].spawn_parms[i]);
+               FS_Printf(f, "%d\n", current_skill);
+               FS_Printf(f, "%s\n", sv.name);
+               FS_Printf(f, "%f\n",sv.time);
+       }
+       else
+       {
+               for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
+                       FS_Printf(f, "(dummy)\n");
+               FS_Printf(f, "%d\n", 0);
+               FS_Printf(f, "%s\n", "(dummy)");
+               FS_Printf(f, "%f\n", realtime);
+       }
+
+       // write the light styles
+       for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
+       {
+               if (isserver && sv.lightstyles[i][0])
+                       FS_Printf(f, "%s\n", sv.lightstyles[i]);
+               else
+                       FS_Print(f,"m\n");
+       }
+
+       PRVM_ED_WriteGlobals (f);
+       for (i=0 ; i<prog->num_edicts ; i++)
+       {
+               //Con_Printf("edict %d...\n", i);
+               PRVM_ED_Write (f, PRVM_EDICT_NUM(i));
+       }
+
+       FS_Close (f);
+       Con_Print("done.\n");
+}
+
 /*
 ===============
 Host_Savegame_f
@@ -443,9 +512,6 @@ Host_Savegame_f
 void Host_Savegame_f (void)
 {
        char    name[MAX_QPATH];
-       qfile_t *f;
-       int             i;
-       char    comment[SAVEGAME_COMMENT_LENGTH+1];
 
        if (!sv.active)
        {
@@ -486,54 +552,9 @@ void Host_Savegame_f (void)
        strlcpy (name, Cmd_Argv(1), sizeof (name));
        FS_DefaultExtension (name, ".sav", sizeof (name));
 
-       Con_Printf("Saving game to %s...\n", name);
-       f = FS_Open (name, "wb", false, false);
-       if (!f)
-       {
-               Con_Print("ERROR: couldn't open.\n");
-               return;
-       }
-
        SV_VM_Begin();
-
-       FS_Printf(f, "%i\n", SAVEGAME_VERSION);
-
-       memset(comment, 0, sizeof(comment));
-       dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog->edicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters);
-       // convert space to _ to make stdio happy
-       // LordHavoc: convert control characters to _ as well
-       for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
-               if (comment[i] <= ' ')
-                       comment[i] = '_';
-       comment[SAVEGAME_COMMENT_LENGTH] = '\0';
-
-       FS_Printf(f, "%s\n", comment);
-       for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
-               FS_Printf(f, "%f\n", svs.clients[0].spawn_parms[i]);
-       FS_Printf(f, "%d\n", current_skill);
-       FS_Printf(f, "%s\n", sv.name);
-       FS_Printf(f, "%f\n",sv.time);
-
-       // write the light styles
-       for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
-       {
-               if (sv.lightstyles[i][0])
-                       FS_Printf(f, "%s\n", sv.lightstyles[i]);
-               else
-                       FS_Print(f,"m\n");
-       }
-
-       PRVM_ED_WriteGlobals (f);
-       for (i=0 ; i<prog->num_edicts ; i++)
-       {
-               Con_Printf("edict %d...\n", i);
-               PRVM_ED_Write (f, PRVM_EDICT_NUM(i));
-       }
-
+       Host_Savegame_to(name);
        SV_VM_End();
-
-       FS_Close (f);
-       Con_Print("done.\n");
 }
 
 
index cb5ef02ae5bfd5165141dcaf392d3fa0304b3853..1ccfc36ab08d0bf3a96326dc761432706e2d74c4 100644 (file)
@@ -42,6 +42,7 @@ cvar_t prvm_statementprofiling = {0, "prvm_statementprofiling", "0", "counts how
 cvar_t prvm_backtraceforwarnings = {0, "prvm_backtraceforwarnings", "0", "print a backtrace for warnings too"};
 cvar_t prvm_leaktest = {0, "prvm_leaktest", "0", "try to detect memory leaks in strings or entities"};
 cvar_t prvm_leaktest_ignore_classnames = {0, "prvm_leaktest_ignore_classnames", "", "classnames of entities to NOT leak check because they are found by find(world, classname, ...) but are actually spawned by QC code (NOT map entities)"};
+cvar_t prvm_errordump = {0, "prvm_errordump", "0", "write a savegame on crash to crash-server.dmp"};
 
 extern sizebuf_t vm_tempstringsbuf;
 
@@ -2097,6 +2098,7 @@ void PRVM_Init (void)
        Cvar_RegisterVariable (&prvm_backtraceforwarnings);
        Cvar_RegisterVariable (&prvm_leaktest);
        Cvar_RegisterVariable (&prvm_leaktest_ignore_classnames);
+       Cvar_RegisterVariable (&prvm_errordump);
 
        //VM_Cmd_Init();
 }
index b866ed27f40e4756d2c61341047f6ca84b8ccffd..8adee10ff3fc3a8b654513711b74c7e817a1dcf0 100644 (file)
@@ -455,6 +455,8 @@ void PRVM_PrintState(void)
 }
 
 extern sizebuf_t vm_tempstringsbuf;
+extern cvar_t prvm_errordump;
+void Host_Savegame_to (const char *name);
 void PRVM_Crash(void)
 {
        if (prog == NULL)
@@ -468,6 +470,12 @@ void PRVM_Crash(void)
                PRVM_PrintState();
        }
 
+       if(prvm_errordump.integer)
+       {
+               // make a savegame
+               Host_Savegame_to(va("crash-%s.dmp", PRVM_NAME));
+       }
+
        // dump the stack so host_error can shutdown functions
        prog->depth = 0;
        prog->localstack_used = 0;