foxygit / doom Log in
commit e22d6a0d26b08e2e7c69972fed1cb96f300ef523
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sun Feb 7 02:59:25 2010 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sun Feb 7 02:59:25 2010 +0000

    Refactor dehacked structure mapping code to support string fields in
    addition to integer fields.

    Subversion-branch: /branches/raven-branch
    Subversion-revision: 1856
---
 src/deh_mapping.c | 140 +++++++++++++++++++++++++++++++++++++++++-------------
 src/deh_mapping.h |  22 +++++++--
 2 files changed, 124 insertions(+), 38 deletions(-)

diff --git a/src/deh_mapping.c b/src/deh_mapping.c
index b215b128..f061c298 100644
--- a/src/deh_mapping.c
+++ b/src/deh_mapping.c
@@ -34,12 +34,9 @@
 #include "i_system.h"
 #include "deh_mapping.h"

-//
-// Set the value of a particular field in a structure by name
-//
-
-boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
-                       void *structptr, char *name, int value)
+static deh_mapping_entry_t *GetMappingEntryByName(deh_context_t *context,
+                                                  deh_mapping_t *mapping,
+                                                  char *name)
 {
     int i;

@@ -49,44 +46,121 @@ boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,

         if (!strcasecmp(entry->name, name))
         {
-            void *location;
-
             if (entry->location == NULL)
             {
                 DEH_Warning(context, "Field '%s' is unsupported", name);
-                return false;
+                return NULL;
             }

-            location = (uint8_t *)structptr + ((uint8_t *)entry->location - (uint8_t *)mapping->base);
-
-     //       printf("Setting %p::%s to %i (%i bytes)\n",
-     //               structptr, name, value, entry->size);
-
-            switch (entry->size)
-            {
-                case 1:
-                    * ((uint8_t *) location) = value;
-                    break;
-                case 2:
-                    * ((uint16_t *) location) = value;
-                    break;
-                case 4:
-                    * ((uint32_t *) location) = value;
-                    break;
-                default:
-                    DEH_Error(context, "Unknown field type for '%s' (BUG)", name);
-                    return false;
-            }
-
-            return true;
+            return entry;
         }
     }

-    // field with this name not found
+    // Not found.

     DEH_Warning(context, "Field named '%s' not found", name);

-    return false;
+    return NULL;
+}
+
+//
+// Get the location of the specified field in the specified structure.
+//
+
+static void *GetStructField(void *structptr,
+                            deh_mapping_t *mapping,
+                            deh_mapping_entry_t *entry)
+{
+    unsigned int offset;
+
+    offset = (uint8_t *)entry->location - (uint8_t *)mapping->base;
+
+    return (uint8_t *)structptr + offset;
+}
+
+//
+// Set the value of a particular field in a structure by name
+//
+
+boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
+                       void *structptr, char *name, int value)
+{
+    deh_mapping_entry_t *entry;
+    void *location;
+
+    entry = GetMappingEntryByName(context, mapping, name);
+
+    if (entry == NULL)
+    {
+        return false;
+    }
+
+    // Sanity check:
+
+    if (entry->is_string)
+    {
+        DEH_Error(context, "Tried to set '%s' as integer (BUG)", name);
+        return false;
+    }
+
+    location = GetStructField(structptr, mapping, entry);
+
+    //       printf("Setting %p::%s to %i (%i bytes)\n",
+    //               structptr, name, value, entry->size);
+
+    // Set field content based on its type:
+
+    switch (entry->size)
+    {
+        case 1:
+            * ((uint8_t *) location) = value;
+            break;
+        case 2:
+            * ((uint16_t *) location) = value;
+            break;
+        case 4:
+            * ((uint32_t *) location) = value;
+            break;
+        default:
+            DEH_Error(context, "Unknown field type for '%s' (BUG)", name);
+            return false;
+    }
+
+    return true;
+}
+
+//
+// Set the value of a string field in a structure by name
+//
+
+boolean DEH_SetStringMapping(deh_context_t *context, deh_mapping_t *mapping,
+                             void *structptr, char *name, char *value)
+{
+    deh_mapping_entry_t *entry;
+    void *location;
+
+    entry = GetMappingEntryByName(context, mapping, name);
+
+    if (entry == NULL)
+    {
+        return false;
+    }
+
+    // Sanity check:
+
+    if (!entry->is_string)
+    {
+        DEH_Error(context, "Tried to set '%s' as string (BUG)", name);
+        return false;
+    }
+
+    location = GetStructField(structptr, mapping, entry);
+
+    // Copy value into field:
+
+    strncpy(location, value, entry->size);
+
+    return true;
 }

 void DEH_StructMD5Sum(md5_context_t *context, deh_mapping_t *mapping,
diff --git a/src/deh_mapping.h b/src/deh_mapping.h
index 4862dec9..129ddcfd 100644
--- a/src/deh_mapping.h
+++ b/src/deh_mapping.h
@@ -42,17 +42,23 @@

 #define DEH_MAPPING(deh_name, fieldname)                      \
              {deh_name, &deh_mapping_base.fieldname,          \
-                 sizeof(deh_mapping_base.fieldname)},
+                 sizeof(deh_mapping_base.fieldname),          \
+                 false},
+
+#define DEH_MAPPING_STRING(deh_name, fieldname)               \
+             {deh_name, &deh_mapping_base.fieldname,          \
+                 sizeof(deh_mapping_base.fieldname),          \
+                 true},

 #define DEH_UNSUPPORTED_MAPPING(deh_name)                     \
-             {deh_name, NULL, -1},
-
+             {deh_name, NULL, -1, false},
+
 #define DEH_END_MAPPING                                       \
              {NULL, NULL, -1}                                 \
         }                                                     \
     };

-
+

 #define MAX_MAPPING_ENTRIES 32

@@ -73,6 +79,10 @@ struct deh_mapping_entry_s
     // field size

     int size;
+
+    // if true, this is a string value.
+
+    boolean is_string;
 };

 struct deh_mapping_s
@@ -81,8 +91,10 @@ struct deh_mapping_s
     deh_mapping_entry_t entries[MAX_MAPPING_ENTRIES];
 };

-boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
+boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
                        void *structptr, char *name, int value);
+boolean DEH_SetStringMapping(deh_context_t *context, deh_mapping_t *mapping,
+                             void *structptr, char *name, char *value);
 void DEH_StructMD5Sum(md5_context_t *context, deh_mapping_t *mapping,
                       void *structptr);