mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-04-14 07:34:45 -04:00
Implement LegoMeterPresenter::DrawMeter (#964)
* Implement LegoMeterPresenter::DrawMeter * New MxRect16 header, offsets and size annotations * Missing mxtypes include
This commit is contained in:
parent
da48dfb40d
commit
5f00634b9c
4 changed files with 167 additions and 45 deletions
LEGO1
lego/legoomni
omni/include
|
@ -1,10 +1,18 @@
|
|||
#ifndef LEGOMETERPRESENTER_H
|
||||
#define LEGOMETERPRESENTER_H
|
||||
|
||||
#include "mxrect16.h"
|
||||
#include "mxstillpresenter.h"
|
||||
#include "mxstring.h"
|
||||
|
||||
// SIZE 0x08
|
||||
struct MeterRect : public MxRect16 {
|
||||
// FUNCTION: BETA10 0x10097eb0
|
||||
MeterRect() {}
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d7ac8
|
||||
// VTABLE: BETA10 0x101bca68
|
||||
// SIZE 0x94
|
||||
class LegoMeterPresenter : public MxStillPresenter {
|
||||
public:
|
||||
|
@ -18,17 +26,21 @@ public:
|
|||
void ParseExtra() override; // vtable+0x30
|
||||
|
||||
private:
|
||||
void FUN_10043a50();
|
||||
enum MeterLayout {
|
||||
e_leftToRight = 0,
|
||||
e_rightToLeft,
|
||||
e_bottomToTop,
|
||||
e_topToBottom
|
||||
};
|
||||
|
||||
MxU8* m_unk0x6c; // 0x6c
|
||||
MxU16 m_type; // 0x70
|
||||
MxString m_variable; // 0x74
|
||||
MxFloat m_unk0x84; // 0x84
|
||||
MxU16 m_unk0x88; // 0x88
|
||||
MxU16 m_unk0x8a; // 0x8a
|
||||
MxU16 m_unk0x8c; // 0x8c
|
||||
MxU16 m_unk0x8e; // 0x8e
|
||||
MxU16 m_layout; // 0x90
|
||||
void DrawMeter();
|
||||
|
||||
MxU8* m_meterPixels; // 0x6c
|
||||
MxU16 m_fillColor; // 0x70
|
||||
MxString m_variable; // 0x74
|
||||
MxFloat m_curPercent; // 0x84
|
||||
MeterRect m_meterRect; // 0x88
|
||||
MxS16 m_layout; // 0x90
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10043760
|
||||
|
|
|
@ -4,27 +4,34 @@
|
|||
#include "define.h"
|
||||
#include "mxbitmap.h"
|
||||
#include "mxdsaction.h"
|
||||
#include "mxmisc.h"
|
||||
#include "mxutilities.h"
|
||||
#include "mxvariabletable.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
DECOMP_SIZE_ASSERT(LegoMeterPresenter, 0x94)
|
||||
|
||||
// FUNCTION: LEGO1 0x10043430
|
||||
// FUNCTION: BETA10 0x10097570
|
||||
LegoMeterPresenter::LegoMeterPresenter()
|
||||
{
|
||||
m_layout = 0;
|
||||
m_unk0x6c = 0;
|
||||
m_unk0x84 = 0;
|
||||
m_type = 1;
|
||||
SetBit1(FALSE);
|
||||
m_meterPixels = NULL;
|
||||
m_fillColor = 1;
|
||||
m_curPercent = 0;
|
||||
m_layout = e_leftToRight;
|
||||
m_flags.m_bit1 = FALSE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10043780
|
||||
// FUNCTION: BETA10 0x1009764a
|
||||
LegoMeterPresenter::~LegoMeterPresenter()
|
||||
{
|
||||
delete m_unk0x6c;
|
||||
delete m_meterPixels;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10043800
|
||||
// FUNCTION: BETA10 0x100976ec
|
||||
void LegoMeterPresenter::ParseExtra()
|
||||
{
|
||||
MxStillPresenter::ParseExtra();
|
||||
|
@ -41,27 +48,28 @@ void LegoMeterPresenter::ParseExtra()
|
|||
char output[256];
|
||||
if (KeyValueStringParse(extraCopy, g_strTYPE, output)) {
|
||||
if (!strcmpi(output, g_strLEFT_TO_RIGHT)) {
|
||||
m_layout = 0;
|
||||
m_layout = e_leftToRight;
|
||||
}
|
||||
else if (!strcmpi(output, g_strRIGHT_TO_LEFT)) {
|
||||
m_layout = 1;
|
||||
m_layout = e_rightToLeft;
|
||||
}
|
||||
else if (!strcmpi(output, g_strBOTTOM_TO_TOP)) {
|
||||
m_layout = 2;
|
||||
m_layout = e_bottomToTop;
|
||||
}
|
||||
else if (!strcmpi(output, g_strTOP_TO_BOTTOM)) {
|
||||
m_layout = 3;
|
||||
m_layout = e_topToBottom;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeyValueStringParse(extraCopy, g_strFILLER_INDEX, output)) {
|
||||
m_type = atoi(output);
|
||||
m_fillColor = atoi(output);
|
||||
}
|
||||
|
||||
if (KeyValueStringParse(extraCopy, g_strVARIABLE, output)) {
|
||||
m_variable = output;
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
EndAction();
|
||||
}
|
||||
}
|
||||
|
@ -71,30 +79,84 @@ void LegoMeterPresenter::ParseExtra()
|
|||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10043990
|
||||
// FUNCTION: BETA10 0x10097917
|
||||
void LegoMeterPresenter::StreamingTickle()
|
||||
{
|
||||
MxStillPresenter::StreamingTickle();
|
||||
m_unk0x6c = new MxU8[m_frameBitmap->GetBmiStride() * m_frameBitmap->GetBmiHeightAbs()];
|
||||
if (m_unk0x6c == NULL) {
|
||||
m_meterPixels = new MxU8[m_frameBitmap->GetDataSize()];
|
||||
if (m_meterPixels == NULL) {
|
||||
assert(0);
|
||||
EndAction();
|
||||
}
|
||||
|
||||
memcpy(m_unk0x6c, m_frameBitmap->GetImage(), m_frameBitmap->GetBmiStride() * m_frameBitmap->GetBmiHeightAbs());
|
||||
memcpy(m_meterPixels, m_frameBitmap->GetImage(), m_frameBitmap->GetDataSize());
|
||||
|
||||
m_unk0x88 = 0;
|
||||
m_unk0x8a = 0;
|
||||
m_unk0x8c = m_frameBitmap->GetBmiWidth() - 1;
|
||||
m_unk0x8e = m_frameBitmap->GetBmiHeightAbs() - 1;
|
||||
m_meterRect.SetLeft(0);
|
||||
m_meterRect.SetTop(0);
|
||||
m_meterRect.SetRight(m_frameBitmap->GetBmiWidth() - 1);
|
||||
m_meterRect.SetBottom(m_frameBitmap->GetBmiHeightAbs() - 1);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10043a30
|
||||
// FUNCTION: BETA10 0x10097a1a
|
||||
void LegoMeterPresenter::RepeatingTickle()
|
||||
{
|
||||
FUN_10043a50();
|
||||
DrawMeter();
|
||||
MxStillPresenter::RepeatingTickle();
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x10043a50
|
||||
void LegoMeterPresenter::FUN_10043a50()
|
||||
// FUNCTION: LEGO1 0x10043a50
|
||||
// FUNCTION: BETA10 0x10097a40
|
||||
void LegoMeterPresenter::DrawMeter()
|
||||
{
|
||||
const char* strval = VariableTable()->GetVariable(m_variable.GetData());
|
||||
MxFloat percent = atof(strval);
|
||||
MxS16 row, leftRightCol, bottomTopCol, leftRightEnd, bottomTopEnd;
|
||||
|
||||
if (strval != NULL && m_curPercent != percent) {
|
||||
m_curPercent = percent;
|
||||
|
||||
// DECOMP: This clamp is retail only
|
||||
if (percent > 0.99) {
|
||||
m_curPercent = 0.99f;
|
||||
}
|
||||
else if (percent < 0.0) {
|
||||
m_curPercent = 0.0f;
|
||||
}
|
||||
|
||||
// Copy the previously drawn meter back into the bitmap
|
||||
memcpy(m_frameBitmap->GetImage(), m_meterPixels, m_frameBitmap->GetDataSize());
|
||||
|
||||
switch (m_layout) {
|
||||
case e_leftToRight:
|
||||
leftRightEnd = m_meterRect.GetWidth() * m_curPercent;
|
||||
|
||||
for (row = m_meterRect.GetTop(); row < m_meterRect.GetBottom(); row++) {
|
||||
MxU8* line = m_frameBitmap->GetStart(m_meterRect.GetLeft(), row);
|
||||
|
||||
for (leftRightCol = 0; leftRightCol < leftRightEnd; leftRightCol++, line++) {
|
||||
if (*line) {
|
||||
*line = m_fillColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case e_bottomToTop:
|
||||
bottomTopEnd = m_meterRect.GetBottom() - (MxS16) (m_meterRect.GetHeight() * m_curPercent);
|
||||
|
||||
for (row = m_meterRect.GetBottom(); row < bottomTopEnd; row--) {
|
||||
MxU8* line = m_frameBitmap->GetStart(m_meterRect.GetLeft(), row);
|
||||
|
||||
for (bottomTopCol = 0; bottomTopCol < m_meterRect.GetWidth(); bottomTopCol++, line++) {
|
||||
if (*line) {
|
||||
*line = m_fillColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
// break;
|
||||
default:
|
||||
// The other two fill options are not implemented.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,17 @@ public:
|
|||
// FUNCTION: BETA10 0x100982b0
|
||||
inline MxLong GetDataSize() const { return AlignToFourByte(m_bmiHeader->biWidth) * GetBmiHeightAbs(); }
|
||||
|
||||
// FUNCTION: BETA10 0x1002c4b0
|
||||
inline MxBool IsTopDown()
|
||||
{
|
||||
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return m_bmiHeader->biHeight < 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline MxLong GetAdjustedStride()
|
||||
{
|
||||
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN || m_bmiHeader->biHeight < 0) {
|
||||
|
@ -123,28 +134,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
inline MxLong GetLine(MxS32 p_top)
|
||||
{
|
||||
MxS32 height;
|
||||
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN || m_bmiHeader->biHeight < 0) {
|
||||
height = p_top;
|
||||
}
|
||||
else {
|
||||
height = GetBmiHeightAbs() - p_top - 1;
|
||||
}
|
||||
return GetBmiStride() * height;
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x1002c320
|
||||
inline MxU8* GetStart(MxS32 p_left, MxS32 p_top)
|
||||
{
|
||||
if (m_bmiHeader->biCompression == BI_RGB) {
|
||||
return GetLine(p_top) + m_data + p_left;
|
||||
return m_data + p_left +
|
||||
AlignToFourByte(GetBmiWidth()) * (IsTopDown() ? p_top : (GetBmiHeightAbs() - 1) - p_top);
|
||||
}
|
||||
else if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN) {
|
||||
return m_data;
|
||||
}
|
||||
else {
|
||||
return GetLine(0) + m_data;
|
||||
return m_data + AlignToFourByte(GetBmiWidth()) * (IsTopDown() ? 0 : (GetBmiHeightAbs() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
47
LEGO1/omni/include/mxrect16.h
Normal file
47
LEGO1/omni/include/mxrect16.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef MXRECT16_H
|
||||
#define MXRECT16_H
|
||||
|
||||
#include "mxtypes.h"
|
||||
|
||||
// SIZE 0x08
|
||||
struct MxRect16 {
|
||||
// FUNCTION: BETA10 0x10097ee0
|
||||
MxRect16() {}
|
||||
|
||||
// FUNCTION: BETA10 0x100981f0
|
||||
inline void SetLeft(MxS16 p_left) { m_left = p_left; }
|
||||
|
||||
// FUNCTION: BETA10 0x10098220
|
||||
inline void SetTop(MxS16 p_top) { m_top = p_top; }
|
||||
|
||||
// FUNCTION: BETA10 0x10098250
|
||||
inline void SetRight(MxS16 p_right) { m_right = p_right; }
|
||||
|
||||
// FUNCTION: BETA10 0x10098280
|
||||
inline void SetBottom(MxS16 p_bottom) { m_bottom = p_bottom; }
|
||||
|
||||
// FUNCTION: BETA10 0x10098300
|
||||
inline MxS16 GetLeft() const { return m_left; }
|
||||
|
||||
// FUNCTION: BETA10 0x10098330
|
||||
inline MxS16 GetTop() const { return m_top; }
|
||||
|
||||
// There is no GetRight()
|
||||
|
||||
// FUNCTION: BETA10 0x10098360
|
||||
inline MxS16 GetBottom() const { return m_bottom; }
|
||||
|
||||
// FUNCTION: BETA10 0x10098390
|
||||
inline MxS16 GetWidth() const { return m_right - m_left + 1; }
|
||||
|
||||
// FUNCTION: BETA10 0x100983c0
|
||||
inline MxS16 GetHeight() const { return m_bottom - m_top + 1; }
|
||||
|
||||
private:
|
||||
MxS16 m_left; // 0x00
|
||||
MxS16 m_top; // 0x02
|
||||
MxS16 m_right; // 0x04
|
||||
MxS16 m_bottom; // 0x06
|
||||
};
|
||||
|
||||
#endif // MXRECT16_H
|
Loading…
Add table
Reference in a new issue