summaryrefslogtreecommitdiff
path: root/library/DataDefs.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-03-17 12:52:22 +0400
committerAlexander Gavrilov2012-03-17 12:52:22 +0400
commit58eb199036db3662ec2f7a2d6d301e7f432d5639 (patch)
treec01d46ab4d403cd900ddbf6e0c31c22946c02a7c /library/DataDefs.cpp
parent14d6a62e1d212808623f1a71b3c559ac4a8dada3 (diff)
downloaddfhack-58eb199036db3662ec2f7a2d6d301e7f432d5639.tar.gz
dfhack-58eb199036db3662ec2f7a2d6d301e7f432d5639.tar.bz2
dfhack-58eb199036db3662ec2f7a2d6d301e7f432d5639.tar.xz
Add many new template functions for enums & bitfields.
An incompatible change: ENUM_KEY_STR returns std::string now. The old behavior is available via enum_item_key_str function.
Diffstat (limited to 'library/DataDefs.cpp')
-rw-r--r--library/DataDefs.cpp93
1 files changed, 64 insertions, 29 deletions
diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp
index 2396e03f..30a4da27 100644
--- a/library/DataDefs.cpp
+++ b/library/DataDefs.cpp
@@ -164,57 +164,92 @@ void virtual_identity::Init(Core *core)
*/
}
-std::string DFHack::bitfieldToString(const void *p, int size, const bitfield_item_info *items)
+bool DFHack::findBitfieldField(unsigned *idx, const std::string &name,
+ unsigned size, const bitfield_item_info *items)
{
- std::string res;
- const char *data = (const char*)p;
+ for (unsigned i = 0; i < size; i++) {
+ if (items[i].name && items[i].name == name)
+ {
+ *idx = i;
+ return true;
+ }
+ }
- for (int i = 0; i < size; i++) {
- unsigned v;
+ return false;
+}
- if (items[i].size > 1) {
- unsigned pdv = *(unsigned*)&data[i/8];
- v = (pdv >> (i%8)) & ((1 << items[i].size)-1);
- } else {
- v = (data[i/8]>>(i%8)) & 1;
- }
+void DFHack::setBitfieldField(void *p, unsigned idx, unsigned size, int value)
+{
+ uint8_t *data = ((uint8_t*)p) + (idx/8);
+ unsigned shift = idx%8;
+ uint32_t mask = ((1<<size)-1) << shift;
+ uint32_t vmask = ((value << shift) & mask);
- if (v) {
- if (!res.empty())
- res += ' ';
+#define ACCESS(type) *(type*)data = type((*(type*)data & ~mask) | vmask)
- if (items[i].name)
- res += items[i].name;
- else
- res += stl_sprintf("UNK_%d", i);
+ if (!(mask & ~0xFFU)) ACCESS(uint8_t);
+ else if (!(mask & ~0xFFFFU)) ACCESS(uint16_t);
+ else ACCESS(uint32_t);
+
+#undef ACCESS
+}
+
+int DFHack::getBitfieldField(const void *p, unsigned idx, unsigned size)
+{
+ const uint8_t *data = ((const uint8_t*)p) + (idx/8);
+ unsigned shift = idx%8;
+ uint32_t mask = ((1<<size)-1) << shift;
+
+#define ACCESS(type) return int((*(type*)data & mask) >> shift)
+
+ if (!(mask & ~0xFFU)) ACCESS(uint8_t);
+ else if (!(mask & ~0xFFFFU)) ACCESS(uint16_t);
+ else ACCESS(uint32_t);
+
+#undef ACCESS
+}
+
+void DFHack::bitfieldToString(std::vector<std::string> *pvec, const void *p,
+ unsigned size, const bitfield_item_info *items)
+{
+ for (unsigned i = 0; i < size; i++) {
+ int value = getBitfieldField(p, i, std::min(1,items[i].size));
+
+ if (value) {
+ std::string name = format_key(items[i].name, i);
if (items[i].size > 1)
- res += stl_sprintf("=%u", v);
+ name += stl_sprintf("=%u", value);
+
+ pvec->push_back(name);
}
if (items[i].size > 1)
i += items[i].size-1;
}
-
- return res;
}
-int DFHack::findBitfieldField_(const std::string &name, int size, const bitfield_item_info *items)
+int DFHack::findEnumItem(const std::string &name, int size, const char *const *items)
{
for (int i = 0; i < size; i++) {
- if (items[i].name && items[i].name == name)
+ if (items[i] && items[i] == name)
return i;
}
return -1;
}
-int DFHack::findEnumItem_(const std::string &name, int size, const char *const *items)
+void DFHack::flagarrayToString(std::vector<std::string> *pvec, const void *p,
+ int bytes, int base, int size, const char *const *items)
{
- for (int i = 0; i < size; i++) {
- if (items[i] && items[i] == name)
- return i;
+ for (unsigned i = 0; i < bytes*8; i++) {
+ int value = getBitfieldField(p, i, 1);
+
+ if (value)
+ {
+ int ridx = int(i) - base;
+ const char *name = (ridx >= 0 && ridx < size) ? items[ridx] : NULL;
+ pvec->push_back(format_key(name, i));
+ }
}
-
- return -1;
}