diff --git a/LEGO1/legogamestate.cpp b/LEGO1/legogamestate.cpp index 0473a07f..3ac770da 100644 --- a/LEGO1/legogamestate.cpp +++ b/LEGO1/legogamestate.cpp @@ -2,6 +2,7 @@ #include "infocenterstate.h" #include "legoomni.h" +#include "legoroi.h" #include "legostate.h" #include "legostream.h" #include "mxobjectfactory.h" @@ -43,6 +44,8 @@ extern const char* s_endOfVariables; LegoGameState::LegoGameState() { // TODO + SetROIHandlerFunction(); + m_stateCount = 0; m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68"); VariableTable()->SetVariable(m_backgroundColor); @@ -57,10 +60,22 @@ LegoGameState::LegoGameState() SerializeScoreHistory(1); } -// OFFSET: LEGO1 0x10039720 STUB +// OFFSET: LEGO1 0x10039720 LegoGameState::~LegoGameState() { - // TODO + LegoROI::SetSomeHandlerFunction(NULL); + + if (m_stateCount) { + for (MxS16 i = 0; i < m_stateCount; i++) { + LegoState* state = m_stateArray[i]; + if (state) + delete state; + } + + delete[] m_stateArray; + } + + delete[] m_savePath; } // OFFSET: LEGO1 0x10039c60 STUB @@ -163,6 +178,33 @@ void LegoGameState::SetSavePath(char* p_savePath) m_savePath = NULL; } +// OFFSET: LEGO1 0x1003bac0 +void LegoGameState::SetROIHandlerFunction() +{ + LegoROI::SetSomeHandlerFunction(&ROIHandlerFunction); +} + +// OFFSET: LEGO1 0x1003bad0 +MxBool ROIHandlerFunction(char* p_input, char* p_output, MxU32 p_copyLen) +{ + if (p_output != NULL && p_copyLen != 0 && + (strnicmp(p_input, "INDIR-F-", strlen("INDIR-F-")) == 0 || + strnicmp(p_input, "INDIR-G-", strlen("INDIR-F-")) == 0)) { + + char buf[256]; + sprintf(buf, "c_%s", &p_input[strlen("INDIR-F-")]); + + const char* value = VariableTable()->GetVariable(buf); + if (value != NULL) { + strncpy(p_output, value, p_copyLen); + p_output[p_copyLen - 1] = '\0'; + return TRUE; + } + } + + return FALSE; +} + // OFFSET: LEGO1 0x1003bbb0 LegoState* LegoGameState::GetState(COMPAT_CONST char* p_stateName) { diff --git a/LEGO1/legogamestate.h b/LEGO1/legogamestate.h index 03455a37..ac268a8b 100644 --- a/LEGO1/legogamestate.h +++ b/LEGO1/legogamestate.h @@ -40,6 +40,7 @@ public: private: void RegisterState(LegoState* p_state); MxResult WriteEndOfVariables(LegoStream* p_stream); + void SetROIHandlerFunction(); private: char* m_savePath; // 0x0 @@ -58,4 +59,6 @@ private: undefined4 m_unk42c; }; +MxBool ROIHandlerFunction(char* p_0, char* p_output, MxU32 p_copyLen); + #endif // LEGOGAMESTATE_H diff --git a/LEGO1/legoroi.cpp b/LEGO1/legoroi.cpp index f177cd8b..a458fa60 100644 --- a/LEGO1/legoroi.cpp +++ b/LEGO1/legoroi.cpp @@ -1,16 +1,96 @@ #include "legoroi.h" -// 0x10101368 -int g_roiConfig = 100; +#include -// OFFSET: LEGO1 0x100a9e10 -void LegoROI::SetDisplayBB(int p_displayBB) -{ - // Intentionally empty function -} +// SIZE 0x14 +typedef struct { + const char* m_name; + MxS32 m_red; + MxS32 m_green; + MxS32 m_blue; + MxS32 m_unk10; +} ROIColorAlias; + +// 0x100dbe28 +const double g_normalizeByteToFloat = 1.0 / 255; + +// 0x101011b0 +ROIColorAlias g_roiColorAliases[22] = { + {"lego black", 0x21, 0x21, 0x21, 0}, {"lego black f", 0x21, 0x21, 0x21, 0}, + {"lego black flat", 0x21, 0x21, 0x21, 0}, {"lego blue", 0x00, 0x54, 0x8c, 0}, + {"lego blue flat", 0x00, 0x54, 0x8c, 0}, {"lego brown", 0x4a, 0x23, 0x1a, 0}, + {"lego brown flt", 0x4a, 0x23, 0x1a, 0}, {"lego brown flat", 0x4a, 0x23, 0x1a, 0}, + {"lego drk grey", 0x40, 0x40, 0x40, 0}, {"lego drk grey flt", 0x40, 0x40, 0x40, 0}, + {"lego dk grey flt", 0x40, 0x40, 0x40, 0}, {"lego green", 0x00, 0x78, 0x2d, 0}, + {"lego green flat", 0x00, 0x78, 0x2d, 0}, {"lego lt grey", 0x82, 0x82, 0x82, 0}, + {"lego lt grey flt", 0x82, 0x82, 0x82, 0}, {"lego lt grey fla", 0x82, 0x82, 0x82, 0}, + {"lego red", 0xcb, 0x12, 0x20, 0}, {"lego red flat", 0xcb, 0x12, 0x20, 0}, + {"lego white", 0xfa, 0xfa, 0xfa, 0}, {"lego white flat", 0xfa, 0xfa, 0xfa, 0}, + {"lego yellow", 0xff, 0xb9, 0x00, 0}, {"lego yellow flat", 0xff, 0xb9, 0x00, 0}, +}; + +// 0x10101368 +MxS32 g_roiConfig = 100; + +// 0x101013ac +ROIHandler g_someHandlerFunction = NULL; // OFFSET: LEGO1 0x100a81c0 -void LegoROI::configureLegoROI(int p_roi) +void LegoROI::configureLegoROI(MxS32 p_roi) { g_roiConfig = p_roi; } + +// OFFSET: LEGO1 0x100a9bf0 +MxBool LegoROI::CallTheHandlerFunction( + char* p_param, + MxFloat& p_red, + MxFloat& p_green, + MxFloat& p_blue, + MxFloat& p_other +) +{ + // TODO + if (p_param == NULL) + return FALSE; + + if (g_someHandlerFunction) { + char buf[32]; + if (g_someHandlerFunction(p_param, buf, 32)) + p_param = buf; + } + + return ColorAliasLookup(p_param, p_red, p_green, p_blue, p_other); +} + +// OFFSET: LEGO1 0x100a9c50 +MxBool LegoROI::ColorAliasLookup(char* p_param, MxFloat& p_red, MxFloat& p_green, MxFloat& p_blue, MxFloat& p_other) +{ + // TODO: this seems awfully hacky for these devs. is there a dynamic way + // to represent `the end of this array` that would improve this? + MxU32 i = 0; + do { + if (strcmpi(g_roiColorAliases[i].m_name, p_param) == 0) { + p_red = g_roiColorAliases[i].m_red * g_normalizeByteToFloat; + p_green = g_roiColorAliases[i].m_green * g_normalizeByteToFloat; + p_blue = g_roiColorAliases[i].m_blue * g_normalizeByteToFloat; + p_other = g_roiColorAliases[i].m_unk10 * g_normalizeByteToFloat; + return TRUE; + } + i++; + } while ((MxS32*) &g_roiColorAliases[i] < &g_roiConfig); + + return FALSE; +} + +// OFFSET: LEGO1 0x100a9d30 +void LegoROI::SetSomeHandlerFunction(ROIHandler p_func) +{ + g_someHandlerFunction = p_func; +} + +// OFFSET: LEGO1 0x100a9e10 +void LegoROI::SetDisplayBB(MxS32 p_displayBB) +{ + // Intentionally empty function +} diff --git a/LEGO1/legoroi.h b/LEGO1/legoroi.h index 9585f42b..341c9bd2 100644 --- a/LEGO1/legoroi.h +++ b/LEGO1/legoroi.h @@ -1,10 +1,24 @@ #ifndef LEGOROI_H #define LEGOROI_H +#include "mxtypes.h" + +typedef MxBool (*ROIHandler)(char*, char*, MxU32); + class LegoROI { public: - __declspec(dllexport) void SetDisplayBB(int p_displayBB); - __declspec(dllexport) static void configureLegoROI(int p_roi); + __declspec(dllexport) void SetDisplayBB(MxS32 p_displayBB); + __declspec(dllexport) static void configureLegoROI(MxS32 p_roi); + + static void SetSomeHandlerFunction(ROIHandler p_func); + static MxBool CallTheHandlerFunction( + char* p_param, + MxFloat& p_red, + MxFloat& p_green, + MxFloat& p_blue, + MxFloat& p_other + ); + static MxBool ColorAliasLookup(char* p_param, MxFloat& p_red, MxFloat& p_green, MxFloat& p_blue, MxFloat& p_other); }; #endif // LEGOROI_H