summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Howard2010-02-07 02:59:25 +0000
committerSimon Howard2010-02-07 02:59:25 +0000
commite22d6a0d26b08e2e7c69972fed1cb96f300ef523 (patch)
treefe3e21703bfe2b20f6af9542934cae613c7ddd11
parentb786d601aeaaa20167f408be56f7e8d13ecc2f8c (diff)
downloadchocolate-doom-e22d6a0d26b08e2e7c69972fed1cb96f300ef523.tar.gz
chocolate-doom-e22d6a0d26b08e2e7c69972fed1cb96f300ef523.tar.bz2
chocolate-doom-e22d6a0d26b08e2e7c69972fed1cb96f300ef523.zip
Refactor dehacked structure mapping code to support string fields in
addition to integer fields. Subversion-branch: /branches/raven-branch Subversion-revision: 1856
-rw-r--r--src/deh_mapping.c140
-rw-r--r--src/deh_mapping.h22
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);