changeset 44:a862fd9906ec

Introduce error resilience feature.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 24 Sep 2011 23:11:49 +0300
parents e2020fcc4c51
children 3a7dc2c61e13
files CHANGES src/cfgfile.cc src/levels.cc src/yadex.h yadex.cfg
diffstat 5 files changed, 65 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES	Sat Sep 24 20:02:06 2011 +0300
+++ b/CHANGES	Sat Sep 24 23:11:49 2011 +0300
@@ -2,6 +2,11 @@
 
 Yadex 1.7.1 (2011-09-24)
 
+  * Added error resiliency option (commandline and configuration file)
+    for blatantly ignoring some or almost all errors during WAD/map
+    loading. May be useful when trying to rescue data from corrupted
+    WADs. Will also most likely lead to crashes, though.
+
   * Cleaned out DOS-related mouse and BGI code, or at least most of it.
     Also got rid of far memory routines and swapping, etc. cruft.
 
--- a/src/cfgfile.cc	Sat Sep 24 20:02:06 2011 +0300
+++ b/src/cfgfile.cc	Sat Sep 24 23:11:49 2011 +0300
@@ -529,6 +529,13 @@
      "Step between zoom factors (in %)",
      &zoom_step},
 
+    {"error_resiliency",
+     "e",
+     OPT_UNSIGNED,
+     0,
+     "Error resiliency of the WAD/map loader (0-4). See yadex.cfg for more info.",
+     &error_res},
+
     {0,
      0,
      OPT_END,
--- a/src/levels.cc	Sat Sep 24 20:02:06 2011 +0300
+++ b/src/levels.cc	Sat Sep 24 23:11:49 2011 +0300
@@ -41,6 +41,11 @@
 #include "wads.h"
 #include "wads2.h"
 
+/* Error resiliency of during loading of WAD / map data, 0 - 4
+ * 0 = Bail on all errors.
+ * 4 = Ignore almost anything.
+ */
+int error_res = 0;
 
 /*
          FIXME
@@ -229,7 +234,7 @@
             {
                 err("%s: seek error", lump_name);
                 rc = 1;
-                goto byebye;
+                if (error_res <= 3) goto byebye;
             }
             if (MainWad == Iwad4)        // Hexen mode
                 for (long n = 0; n < NumThings; n++)
@@ -247,7 +252,7 @@
                     {
                         err("%s: error reading thing #%ld", lump_name, n);
                         rc = 1;
-                        goto byebye;
+                        if (error_res <= 3) goto byebye;
                     }
                 }
             else                // Doom/Heretic/Strife mode
@@ -264,7 +269,7 @@
                     {
                         err("%s: error reading thing #%ld", lump_name, n);
                         rc = 1;
-                        goto byebye;
+                        if (error_res <= 3) goto byebye;
                     }
                 }
         }
@@ -306,7 +311,7 @@
             {
                 err("%s: seek error", lump_name);
                 rc = 1;
-                goto byebye;
+                if (error_res <= 3) goto byebye;
             }
             if (MainWad == Iwad4)        // Hexen mode
                 for (long n = 0; n < NumLineDefs; n++)
@@ -324,7 +329,7 @@
                     {
                         err("%s: error reading linedef #%ld", lump_name, n);
                         rc = 1;
-                        goto byebye;
+                        if (error_res <= 3) goto byebye;
                     }
                 }
             else                // Doom/Heretic/Strife mode
@@ -341,7 +346,7 @@
                     {
                         err("%s: error reading linedef #%ld", lump_name, n);
                         rc = 1;
-                        goto byebye;
+                        if (error_res <= 3) goto byebye;
                     }
                 }
         }
@@ -371,7 +376,7 @@
             {
                 err("%s: seek error", lump_name);
                 rc = 1;
-                goto byebye;
+                if (error_res <= 3) goto byebye;
             }
             for (long n = 0; n < NumSideDefs; n++)
             {
@@ -385,7 +390,7 @@
                 {
                     err("%s: error reading sidedef #%ld", lump_name, n);
                     rc = 1;
-                    goto byebye;
+                    if (error_res <= 3) goto byebye;
                 }
             }
         }
@@ -402,7 +407,8 @@
             err("linedef %ld has bad 1st sidedef number %d, giving up",
                 n, LineDefs[n].sidedef1);
             rc = 1;
-            goto byebye;
+            if (error_res <= 2) goto byebye;
+            LineDefs[n].sidedef1 = 0;
         }
         if (LineDefs[n].sidedef2 != -1
             && outside(LineDefs[n].sidedef2, 0, NumSideDefs - 1))
@@ -410,21 +416,24 @@
             err("linedef %ld has bad 2nd sidedef number %d, giving up",
                 n, LineDefs[n].sidedef2);
             rc = 1;
-            goto byebye;
+            if (error_res <= 2) goto byebye;
+            LineDefs[n].sidedef2 = 0;
         }
         if (outside(LineDefs[n].start, 0, OldNumVertices - 1))
         {
             err("linedef %ld has bad 1st vertex number %d, giving up",
                 n, LineDefs[n].start);
             rc = 1;
-            goto byebye;
+            if (error_res <= 2) goto byebye;
+            LineDefs[n].start = 0;
         }
         if (outside(LineDefs[n].end, 0, OldNumVertices - 1))
         {
             err("linedef %ld has bad 2nd vertex number %d, giving up",
                 n, LineDefs[n].end);
             rc = 1;
-            goto byebye;
+            if (error_res <= 2) goto byebye;
+            LineDefs[n].end = 0;
         }
     }
 
@@ -523,7 +532,7 @@
             {
                 err("%s: seek error", lump_name);
                 rc = 1;
-                goto byebye;
+                if (error_res <= 3) goto byebye;
             }
             size_t s = 0;
             for (size_t n = 0; n < nlines; n++)
@@ -579,7 +588,7 @@
                 {
                     err("%s: error reading line #%d", lump_name, int (n));
                     rc = 1;
-                    goto byebye;
+                    if (error_res <= 3) goto byebye;
                 }
             }
             // (size_t) to silence GCC warning
@@ -624,6 +633,7 @@
         {
             bitvec_c vertex_used(OldNumVertices);
             for (long n = 0; n < NumLineDefs; n++)
+            if (LineDefs[n].start != -1 && LineDefs[n].end != -1)
             {
                 vertex_used.set(LineDefs[n].start);
                 vertex_used.set(LineDefs[n].end);
@@ -685,7 +695,7 @@
                 {
                     err("%s: seek error", lump_name);
                     rc = 1;
-                    goto byebye;
+                    if (error_res <= 3) goto byebye;
                 }
                 MapMaxX = -32767;
                 MapMaxY = -32767;
@@ -710,7 +720,7 @@
                     {
                         err("%s: error reading vertex #%ld", lump_name, n);
                         rc = 1;
-                        goto byebye;
+                        if (error_res <= 3) goto byebye;
                     }
                 }
             }
@@ -747,7 +757,7 @@
                 {
                     err("%s: seek error", lump_name);
                     rc = 1;
-                    goto byebye;
+                    if (error_res <= 3) goto byebye;
                 }
                 for (long n = 0; n < NumSectors; n++)
                 {
@@ -762,7 +772,7 @@
                     {
                         err("%s: error reading sector #%ld", lump_name, n);
                         rc = 1;
-                        goto byebye;
+                        if (error_res <= 3) goto byebye;
                     }
                 }
             }
@@ -785,14 +795,14 @@
                 {
                     err("%s: seek error", lump_name);
                     rc = 1;
-                    goto byebye;
+                    if (error_res <= 3) goto byebye;
                 }
                 wf->read_i32(&nsectors);
                 if (wf->error())
                 {
                     err("%s: error reading sector count", lump_name);
                     rc = 1;
-                    goto byebye;
+                    if (error_res <= 3) goto byebye;
                 }
                 if (nsectors < 0)
                 {
@@ -910,8 +920,7 @@
                 delete[]offset_table;
             if (flatnames != 0)
                 delete[]flatnames;
-            if (rc != 0)
-                goto byebye;
+            if (rc != 0 && error_res <= 3) goto byebye;
         }
     }
 
@@ -936,10 +945,11 @@
          (int) NumSideDefs, (int) NumSectors);
     verbmsg("  Map: (%d,%d)-(%d,%d)\n", MapMinX, MapMinY, MapMaxX, MapMaxY);
 
-  byebye:
+byebye:
     if (rc != 0)
         err("%s: errors found, giving up", levelname);
-    return rc;
+
+    return (error_res > 0) ? 0 : rc;
 }
 
 
@@ -1506,7 +1516,9 @@
                     }
                     wf->read_bytes(WTexture[NumWTexture + n], WAD_TEX_NAME);
                     if (wf->error())
-                        ;        // FIXME
+                    {
+                        warn("%s: read error for texture %d / %d\n", lump_name, n, NumWTexture + n);
+                    }
                     WTexture[NumWTexture + n][WAD_TEX_NAME] = '\0';
                 }
                 NumWTexture += val;
--- a/src/yadex.h	Sat Sep 24 20:02:06 2011 +0300
+++ b/src/yadex.h	Sat Sep 24 23:11:49 2011 +0300
@@ -470,6 +470,7 @@
 void unlink_sidedef(SelPtr linedefs, int side1, int side2);
 
 // levels.cc
+extern int error_res;
 int ReadLevelData(const char *);        /* SWAP! */
 void ForgetLevelData(void);        /* SWAP! */
 int SaveLevelData(const char *, const char *level_name);        /* SWAP! */
--- a/yadex.cfg	Sat Sep 24 20:02:06 2011 +0300
+++ b/yadex.cfg	Sat Sep 24 23:11:49 2011 +0300
@@ -38,6 +38,21 @@
 
 
 #
+# Error resiliency of the WAD / map loader.
+#
+# 0       = Bail on any and all errors (default)
+# 1 .. 3  = Ignore more and more errors.
+# 4       = Ignore almost all errors
+#
+# NOTICE that using anything else than 0 may lead to crashes when
+# loading broken data files! But it may also give you the chance to
+# rescue data from corrupted files, though it WILL require careful
+# manual work to repair the invalid parts.
+#
+  error_resiliency = 0
+
+
+#
 #	Editing options
 #