foxygit / doom Log in
commit d29437d459167d40bac2d0c2c7881f3e3b8f2e8f
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sun Apr 18 21:28:26 2010 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sun Apr 18 21:28:26 2010 +0000

    Suggest a different Heretic version when an invalid string or code
    offset is encountered.

    Subversion-branch: /branches/raven-branch
    Subversion-revision: 1909
---
 src/heretic/deh_frame.c | 31 ++++++++++++++++++++++++++++++-
 src/heretic/deh_htext.c | 41 +++++++++++++++++++++++++++++++++++++++++
 src/heretic/deh_htic.c  | 15 +++++++++++++++
 src/heretic/deh_htic.h  |  1 +
 4 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/src/heretic/deh_frame.c b/src/heretic/deh_frame.c
index c576d490..8623ab0c 100644
--- a/src/heretic/deh_frame.c
+++ b/src/heretic/deh_frame.c
@@ -229,6 +229,14 @@ static boolean GetActionPointerForOffset(int offset, void **result)
 {
     int i;

+    // Special case.
+
+    if (offset == 0)
+    {
+        *result = NULL;
+        return true;
+    }
+
     for (i=0; i<arrlen(action_pointers); ++i)
     {
         if (action_pointers[i].offsets[deh_hhe_version] == offset)
@@ -241,6 +249,26 @@ static boolean GetActionPointerForOffset(int offset, void **result)
     return false;
 }

+// If an invalid action pointer is specified, the patch may be for a
+// different version from the version we are currently set to.  Try to
+// suggest a different version to use.
+
+static void SuggestOtherVersions(unsigned int offset)
+{
+    unsigned int i, v;
+
+    for (i=0; i<arrlen(action_pointers); ++i)
+    {
+        for (v=0; v<deh_hhe_num_versions; ++v)
+        {
+            if (action_pointers[i].offsets[v] == offset)
+            {
+                DEH_SuggestHereticVersion(v);
+            }
+        }
+    }
+}
+
 static void DEH_FrameParseLine(deh_context_t *context, char *line, void *tag)
 {
     state_t *state;
@@ -274,7 +302,8 @@ static void DEH_FrameParseLine(deh_context_t *context, char *line, void *tag)

         if (!GetActionPointerForOffset(ivalue, &func))
         {
-            DEH_Warning(context, "Unknown action pointer: %i", ivalue);
+            SuggestOtherVersions(ivalue);
+            DEH_Error(context, "Unknown action pointer: %i", ivalue);
             return;
         }

diff --git a/src/heretic/deh_htext.c b/src/heretic/deh_htext.c
index d39c9fdb..5dfddac3 100644
--- a/src/heretic/deh_htext.c
+++ b/src/heretic/deh_htext.c
@@ -732,6 +732,46 @@ static int MaxStringLength(int len)
     return len - 1;
 }

+// If a string offset does not match any string, it may be because
+// we are running in the wrong version mode, and the patch was generated
+// for a different Heretic version.  Search the lookup tables to find
+// versiosn that match.
+
+static void SuggestOtherVersions(unsigned int offset)
+{
+    const int *string_list;
+    unsigned int i;
+    unsigned int v;
+
+    // Check main string table.
+
+    for (i=0; i<arrlen(strings); ++i)
+    {
+        for (v=0; v<deh_hhe_num_versions; ++v)
+        {
+            if (strings[i].offsets[v] == offset)
+            {
+                DEH_SuggestHereticVersion(v);
+            }
+        }
+    }
+
+    // Check unsupported string tables.
+
+    for (v=0; v<deh_hhe_num_versions; ++v)
+    {
+        string_list = unsupported_strings[v];
+
+        for (i=0; string_list[i] >= 0; ++i)
+        {
+            if (string_list[i] == offset)
+            {
+                DEH_SuggestHereticVersion(v);
+            }
+        }
+    }
+}
+
 static void *DEH_TextStart(deh_context_t *context, char *line)
 {
     char *repl_text;
@@ -770,6 +810,7 @@ static void *DEH_TextStart(deh_context_t *context, char *line)

     else if (!GetStringByOffset(orig_offset, &orig_text))
     {
+        SuggestOtherVersions(orig_offset);
         DEH_Error(context, "Unknown string offset: %i", orig_offset);
     }

diff --git a/src/heretic/deh_htic.c b/src/heretic/deh_htic.c
index 40fa5765..440fde96 100644
--- a/src/heretic/deh_htic.c
+++ b/src/heretic/deh_htic.c
@@ -169,3 +169,18 @@ int DEH_MapHereticFrameNumber(int frame)
     return frame;
 }

+void DEH_SuggestHereticVersion(deh_hhe_version_t version)
+{
+    fprintf(stderr,
+    "\n"
+    "This patch may be for version %s. You are currently running in\n"
+    "Heretic %s mode. For %s mode, this mode, add this to your command line:\n"
+    "\n"
+    "\t-hhever %s\n"
+    "\n",
+    hhe_versions[version],
+    hhe_versions[deh_hhe_version],
+    hhe_versions[version],
+    hhe_versions[version]);
+}
+
diff --git a/src/heretic/deh_htic.h b/src/heretic/deh_htic.h
index f006c149..7855da8c 100644
--- a/src/heretic/deh_htic.h
+++ b/src/heretic/deh_htic.h
@@ -52,6 +52,7 @@ typedef enum

 void DEH_HereticInit(void);
 int DEH_MapHereticFrameNumber(int frame);
+void DEH_SuggestHereticVersion(deh_hhe_version_t version);

 extern deh_hhe_version_t deh_hhe_version;