diff --git a/LEGO1/mxvariable.h b/LEGO1/mxvariable.h index c4427e33..6899dfac 100644 --- a/LEGO1/mxvariable.h +++ b/LEGO1/mxvariable.h @@ -8,13 +8,23 @@ class MxVariable { public: - __declspec(dllexport) MxVariable(const char *, const char *); MxVariable() {} + MxVariable(const char *p_key) + { + m_key = p_key; + m_key.ToUpperCase(); + } + MxVariable(const char *p_key, const char *p_value) + { + m_key = p_key; + m_key.ToUpperCase(); + m_value = p_value; + } virtual MxString *GetValue(); virtual void SetValue(const char *); virtual void Destroy(); - inline const MxString *GetKey() const { return &m_value; } + inline const MxString *GetKey() const { return &m_key; } protected: MxString m_key; diff --git a/LEGO1/mxvariabletable.cpp b/LEGO1/mxvariabletable.cpp index b5ebee63..7dfe59b3 100644 --- a/LEGO1/mxvariabletable.cpp +++ b/LEGO1/mxvariabletable.cpp @@ -1,13 +1,19 @@ #include "mxvariabletable.h" +MxS8 MxVariableTable::Compare(MxVariable *p_var0, MxVariable *p_var1) +{ + return strcmp(p_var0->GetKey()->GetData(), + p_var1->GetKey()->GetData()); +} + // OFFSET: LEGO1 0x100b7370 -int MxVariableTable::KeyChecksum(MxVariable *p_var) +MxU32 MxVariableTable::Hash(MxVariable *p_var) { const char *str = p_var->GetKey()->GetData(); - int value = 0; + MxU32 value = 0; for (int i = 0; str[i]; i++) { - value += (int)str[i]; + value += str[i]; } return value; @@ -16,7 +22,12 @@ int MxVariableTable::KeyChecksum(MxVariable *p_var) // OFFSET: LEGO1 0x100b73a0 void MxVariableTable::SetVariable(const char *p_key, const char *p_value) { - MxVariable *var = new MxVariable(); + MxHashTableCursor cursor(this); + MxVariable *var = new MxVariable(p_key, p_value); + + if (cursor.Find(var)) { + delete var; + } // TODO } @@ -27,8 +38,19 @@ void MxVariableTable::SetVariable(MxVariable *var) } // OFFSET: LEGO1 0x100b78f0 -const char *MxVariableTable::GetVariable(const char *key) +const char *MxVariableTable::GetVariable(const char *p_key) { - // TODO - return 0; + const char *value = NULL; + MxHashTableCursor cursor(this); + MxVariable *var = new MxVariable(p_key); + + MxBool found = cursor.Find(var); + delete var; + + if (found) { + cursor.GetMatch(&var); + value = var->GetValue()->GetData(); + } + + return value; } diff --git a/LEGO1/mxvariabletable.h b/LEGO1/mxvariabletable.h index b7940871..5d05c7d5 100644 --- a/LEGO1/mxvariabletable.h +++ b/LEGO1/mxvariabletable.h @@ -1,29 +1,115 @@ #ifndef MXVARIABLETABLE_H #define MXVARIABLETABLE_H +#include "mxtypes.h" #include "mxcore.h" #include "mxvariable.h" -// VTABLE 0x100dc1c8 -// SIZE 0x28 -class MxVariableTable : public MxCore +template +class MxHashTableNode { public: - __declspec(dllexport) const char * GetVariable(const char *key); - __declspec(dllexport) void SetVariable(MxVariable *var); - __declspec(dllexport) void SetVariable(const char *key, const char *value); - - virtual int KeyChecksum(MxVariable *); // +0x18 + MxHashTableNode() {} + MxHashTableNode(T *p_obj, MxU32 p_hash) + { + m_obj = p_obj; + m_hash = p_hash; + m_prev = NULL; + m_next = NULL; + } //private: - int m_unk8; + T* m_obj; + MxU32 m_hash; + MxHashTableNode *m_prev; + MxHashTableNode *m_next; +}; + +template +class MxHashTable : public MxCore +{ +public: + MxHashTable() + { + m_size = 128; + m_table = new MxHashTableNode[128]; + } + + ~MxHashTable() + { + delete[] m_table; + } + + virtual MxS8 Compare(T*, T*); + virtual MxU32 Hash(T*); + +//private: + int m_used; // +0x8 void (*m_unkc)(void *); // +0xc - void *m_table; // +0x10 - int m_tableLen; // +0x14 + MxHashTableNode *m_table; // +0x10 + int m_size; // +0x14 int m_unk18; int m_unk1c; int m_unk20; int m_unk24; }; +template +class MxHashTableCursor : public MxCore +{ +public: + MxHashTableCursor(MxHashTable *p_hashTable) + { + m_hashTable = p_hashTable; + m_match = NULL; + } + + MxBool Find(T *p_obj) + { + MxU32 hash = m_hashTable->Hash(p_obj); + int bucket = hash / m_hashTable->m_size; + + MxHashTableNode *t = &m_hashTable->m_table[bucket]; + + while (t) { + if (t->m_hash == hash && !m_hashTable->Compare(p_obj, t->m_obj)) + m_match = t; + t = t->m_next; + } + + return m_match != NULL; + } + + void GetMatch(T **p_obj) + { + if (m_match) + *p_obj = m_match->m_obj; + //p_obj = m_match ? m_match->m_obj : NULL; // ? + } + + /* + T* GetMatch() + { + return m_match ? m_match->m_obj : NULL; + } + */ + +private: + MxHashTable *m_hashTable; + MxHashTableNode *m_match; // type ? +}; + +// VTABLE 0x100dc1c8 +// SIZE 0x28 +class MxVariableTable : protected MxHashTable +{ +public: + __declspec(dllexport) const char * GetVariable(const char *key); + __declspec(dllexport) void SetVariable(MxVariable *var); + __declspec(dllexport) void SetVariable(const char *key, const char *value); + + virtual MxS8 Compare(MxVariable *, MxVariable *); // +0x14 + virtual MxU32 Hash(MxVariable *); // +0x18 +}; + #endif // MXVARIABLETABLE_H