Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish Implementing the ObjInfo module #82

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 178 additions & 7 deletions src/openlrr/game/interface/hud/ObjInfo.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// ObjInfo.cpp :
//

#include "../../../engine/core/Maths.h"

#include "../../../engine/core/Config.h"
#include "../../../engine/core/Maths.h"
#include "../../../engine/core/Utils.h"
#include "../../../engine/drawing/Draw.h"

#include "../../effects/DamageText.h"
Expand Down Expand Up @@ -69,19 +71,188 @@ void LegoRR::ObjInfo_TryEndDraw()


// <LegoRR.exe @004597f0>
//void __cdecl LegoRR::ObjInfo_Initialise(const Gods98::Config* config, const char* gameName);
void __cdecl LegoRR::ObjInfo_Initialise(const Gods98::Config* config, const char* gameName)
{
ObjInfo_LoadHealthBar(config, gameName);
ObjInfo_LoadHunger(config, gameName);
ObjInfo_LoadBubble(config, gameName);
}

// <LegoRR.exe @00459820>
//bool32 __cdecl LegoRR::ObjInfo_LoadHealthBar(const Gods98::Config* config, const char* gameName);
bool32 __cdecl LegoRR::ObjInfo_LoadHealthBar(const Gods98::Config* config, const char* gameName)
{
char* str;
uint32 numParts;
char* stringParts[10];

str = Gods98::Config_GetStringValue(config, Config_ID(gameName, "ObjInfo", "HealthBarPosition"));
if (str == nullptr) {
return false;
}

numParts = Gods98::Util_Tokenise(str, stringParts, ":");
if (numParts == 2) {
objinfoGlobs.HealthBarPosition.x = (float)std::atoi(stringParts[0]);
objinfoGlobs.HealthBarPosition.y = (float)std::atoi(stringParts[1]);
Gods98::Mem_Free(str);

str = Gods98::Config_GetStringValue(config, Config_ID(gameName, "ObjInfo", "HealthBarWidthHeight"));
if (str == nullptr) {
return false;
}

numParts = Gods98::Util_Tokenise(str, stringParts, ":");
if (numParts == 2) {
objinfoGlobs.HealthBarWidthHeight.width = (float)std::atoi(stringParts[0]);
objinfoGlobs.HealthBarWidthHeight.height = (float)std::atoi(stringParts[1]);
Gods98::Mem_Free(str);

const char* tempStr = Gods98::Config_GetTempStringValue(config, Config_ID(gameName, "ObjInfo", "HealthBarBorderSize"));
if (tempStr == nullptr) {
tempStr = "";
}
else {
// Not sure why this is repeated
// tempStr = Gods98::Config_GetTempStringValue(config, Config_ID(gameName, "ObjInfo", "HealthBarBorderSize"));
}
objinfoGlobs.HealthBarBorderSize = std::atoi(tempStr);

float* r = objinfoGlobs.HealthBarBorderRGB_r;
float* g = objinfoGlobs.HealthBarBorderRGB_g;
float* b = objinfoGlobs.HealthBarBorderRGB_b;
bool success = Gods98::Config_GetRGBValue(config, Config_ID(gameName, "ObjInfo", "HealthBarBorderRGB"), r, g, b);
if (!success) {
return false;
}

// Calculate the high/low rgb values
objinfoGlobs.HealthBarBorderRGB_r[1] = objinfoGlobs.HealthBarBorderRGB_r[0] + objinfoGlobs.HealthBarBorderRGB_r[1] * 0.4f;
objinfoGlobs.HealthBarBorderRGB_r[2] = objinfoGlobs.HealthBarBorderRGB_r[0] - objinfoGlobs.HealthBarBorderRGB_r[1] * 0.4f;

objinfoGlobs.HealthBarBorderRGB_g[1] = objinfoGlobs.HealthBarBorderRGB_g[0] + objinfoGlobs.HealthBarBorderRGB_g[1] * 0.4f;
objinfoGlobs.HealthBarBorderRGB_g[2] = objinfoGlobs.HealthBarBorderRGB_g[0] - objinfoGlobs.HealthBarBorderRGB_g[1] * 0.4f;

objinfoGlobs.HealthBarBorderRGB_b[1] = objinfoGlobs.HealthBarBorderRGB_b[0] + objinfoGlobs.HealthBarBorderRGB_b[1] * 0.4f;
objinfoGlobs.HealthBarBorderRGB_b[2] = objinfoGlobs.HealthBarBorderRGB_b[0] - objinfoGlobs.HealthBarBorderRGB_b[1] * 0.4f;

// clamp their values to 0 -> 1.0
for (uint32 i = 0; i < 3; i++) {
if (1.0 < objinfoGlobs.HealthBarBorderRGB_r[i]) {
objinfoGlobs.HealthBarBorderRGB_r[i] = 1.0;
}
if (1.0 < objinfoGlobs.HealthBarBorderRGB_g[i]) {
objinfoGlobs.HealthBarBorderRGB_g[i] = 1.0;
}
if (1.0 < objinfoGlobs.HealthBarBorderRGB_b[i]) {
objinfoGlobs.HealthBarBorderRGB_b[i] = 1.0;
}

if (objinfoGlobs.HealthBarBorderRGB_r[i] < 0) {
objinfoGlobs.HealthBarBorderRGB_r[i] = 0;
}
if (objinfoGlobs.HealthBarBorderRGB_g[i] < 0) {
objinfoGlobs.HealthBarBorderRGB_g[i] = 0;
}
if (objinfoGlobs.HealthBarBorderRGB_b[i] < 0) {
objinfoGlobs.HealthBarBorderRGB_b[i] = 0;
}
}

r = &objinfoGlobs.HealthBarBackgroundRGB.r;
g = &objinfoGlobs.HealthBarBackgroundRGB.g;
b = &objinfoGlobs.HealthBarBackgroundRGB.b;
success = Gods98::Config_GetRGBValue(config, Config_ID(gameName, "ObjInfo", "HealthBarBackgroundRGB"), r, g, b);
if (!success) {
return false;
}

r = &objinfoGlobs.HealthBarRGB.r;
g = &objinfoGlobs.HealthBarRGB.g;
b = &objinfoGlobs.HealthBarRGB.b;
success = Gods98::Config_GetRGBValue(config, Config_ID(gameName, "ObjInfo", "HealthBarRGB"), r, g, b);
if (!success) {
return false;
}

BoolTri verticalHealthBar = Gods98::Config_GetBoolValue(config, Config_ID(gameName, "ObjInfo", "HealthBarVertical"));
if (verticalHealthBar == BOOL3_TRUE) {
objinfoGlobs.flags |= ObjInfo_GlobFlags::OBJINFO_GLOB_FLAG_HEALTHBAR_VERTICAL;
}

objinfoGlobs.flags |= ObjInfo_GlobFlags::OBJINFO_GLOB_FLAG_HEALTHBAR;
return true;
}
}

Gods98::Mem_Free(str);

return false;
}


// <LegoRR.exe @00459bc0>
//bool32 __cdecl LegoRR::ObjInfo_LoadHunger(const Gods98::Config* config, const char* gameName);
bool32 __cdecl LegoRR::ObjInfo_LoadHunger(const Gods98::Config* config, const char* gameName)
{
char* stringParts[10];

ObjInfo_LoadHungerImages(config, gameName);
char* str = Gods98::Config_GetStringValue(config, Config_ID(gameName, "ObjInfo", "HungerImagesPosition"));
if (str != nullptr) {
uint32 numParts = Gods98::Util_Tokenise(str, stringParts, ":");
if (numParts == 2) {
objinfoGlobs.HungerPosition.x = (float)std::atoi(stringParts[0]);
objinfoGlobs.HungerPosition.y = (float)std::atoi(stringParts[1]);
Gods98::Mem_Free(str);
objinfoGlobs.flags|= OBJINFO_GLOB_FLAG_HUNGERIMAGES;
return true;
}
Gods98::Mem_Free(str);
}

return false;
}

// <LegoRR.exe @00459c80>
//void __cdecl LegoRR::ObjInfo_LoadHungerImages(const Gods98::Config* config, const char* gameName);
void __cdecl LegoRR::ObjInfo_LoadHungerImages(const Gods98::Config* config, const char* gameName)
{
char buffer[64];

for (uint32 i=0; i < OBJINFO_HUNGERIMAGECOUNT; i++) {
std::sprintf(&buffer[0], "HungerImage%i", i);

const char* str = Gods98::Config_GetTempStringValue(config, Config_ID(gameName, "ObjInfo", "HungerImages", &buffer[0]));

uint32 width = 0;
uint32 height = 0;
Gods98::Image* image = Gods98::Image_LoadBMPScaled(str, width, height);
objinfoGlobs.HungerImages[i] = image;

if (image != nullptr) {
Gods98::Image_SetupTrans(image, 0, 0, 0, 0, 0, 0);
}
}
}

// <LegoRR.exe @00459d10>
//bool32 __cdecl LegoRR::ObjInfo_LoadBubble(const Gods98::Config* config, const char* gameName);
bool32 __cdecl LegoRR::ObjInfo_LoadBubble(const Gods98::Config* config, const char* gameName)
{
char* stringParts[10];

char* str = Gods98::Config_GetStringValue(config, Config_ID(gameName, "ObjInfo", "BubbleImagesPosition"));
if (str != nullptr) {
int numParts = Gods98::Util_Tokenise(str, stringParts, ":");
if (numParts == 2) {
objinfoGlobs.BubblePosition.x = (float)std::atoi(stringParts[0]);
objinfoGlobs.BubblePosition.y = (float)std::atoi(stringParts[1]);
Gods98::Mem_Free(str);
objinfoGlobs.flags|= OBJINFO_GLOB_FLAG_BUBBLEIMAGES;
return true;
}
Gods98::Mem_Free(str);
}

return false;
}

// DRAW MODE: Only Draw API drawing calls can be used within this function.
// <LegoRR.exe @00459dc0>
Expand Down
20 changes: 10 additions & 10 deletions src/openlrr/game/interface/hud/ObjInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,24 @@ void ObjInfo_TryEndDraw();


// <LegoRR.exe @004597f0>
#define ObjInfo_Initialise ((void (__cdecl* )(const Gods98::Config* config, const char* gameName))0x004597f0)
//void __cdecl ObjInfo_Initialise(const Gods98::Config* config, const char* gameName);
//#define ObjInfo_Initialise ((void (__cdecl* )(const Gods98::Config* config, const char* gameName))0x004597f0)
void __cdecl ObjInfo_Initialise(const Gods98::Config* config, const char* gameName);

// <LegoRR.exe @00459820>
#define ObjInfo_LoadHealthBar ((bool32 (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459820)
//bool32 __cdecl ObjInfo_LoadHealthBar(const Gods98::Config* config, const char* gameName);
//#define ObjInfo_LoadHealthBar ((bool32 (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459820)
bool32 __cdecl ObjInfo_LoadHealthBar(const Gods98::Config* config, const char* gameName);

// <LegoRR.exe @00459bc0>
#define ObjInfo_LoadHunger ((bool32 (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459bc0)
//bool32 __cdecl ObjInfo_LoadHunger(const Gods98::Config* config, const char* gameName);
//#define ObjInfo_LoadHunger ((bool32 (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459bc0)
bool32 __cdecl ObjInfo_LoadHunger(const Gods98::Config* config, const char* gameName);

// <LegoRR.exe @00459c80>
#define ObjInfo_LoadHungerImages ((void (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459c80)
//void __cdecl ObjInfo_LoadHungerImages(const Gods98::Config* config, const char* gameName);
//#define ObjInfo_LoadHungerImages ((void (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459c80)
void __cdecl ObjInfo_LoadHungerImages(const Gods98::Config* config, const char* gameName);

// <LegoRR.exe @00459d10>
#define ObjInfo_LoadBubble ((bool32 (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459d10)
//bool32 __cdecl ObjInfo_LoadBubble(const Gods98::Config* config, const char* gameName);
//#define ObjInfo_LoadBubble ((bool32 (__cdecl* )(const Gods98::Config* config, const char* gameName))0x00459d10)
bool32 __cdecl ObjInfo_LoadBubble(const Gods98::Config* config, const char* gameName);

// DRAW MODE: Only Draw API drawing calls can be used within this function.
// <LegoRR.exe @00459dc0>
Expand Down
12 changes: 11 additions & 1 deletion src/openlrr/interop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3815,7 +3815,17 @@ bool interop_hook_LegoRR_Objective(void)
bool interop_hook_LegoRR_ObjInfo(void)
{
bool result = true;


// used by: Lego_Initialise
result &= hook_write_jmpret(0x004597f0, LegoRR::ObjInfo_Initialise);
// used by: ObjInfo_Initialise
result &= hook_write_jmpret(0x00459820, LegoRR::ObjInfo_LoadHealthBar);
// used by: ObjInfo_Initialise
result &= hook_write_jmpret(0x00459bc0, LegoRR::ObjInfo_LoadHunger);
// used by: ObjInfo_LoadHunger
result &= hook_write_jmpret(0x00459c80, LegoRR::ObjInfo_LoadHungerImages);
// used by: ObjInfo_Initialise
result &= hook_write_jmpret(0x00459d10, LegoRR::ObjInfo_LoadBubble);
// used by: Bubble_DrawAllObjInfos, Bubble_Callback_DrawObjInfo
result &= hook_write_jmpret(0x00459dc0, LegoRR::ObjInfo_DrawHealthBar);
// used by: Bubble_Callback_DrawObjInfo
Expand Down