mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-26 22:21:50 -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
@ -1,10 +1,18 @@
|
|||||||
#ifndef LEGOMETERPRESENTER_H
|
#ifndef LEGOMETERPRESENTER_H
|
||||||
#define LEGOMETERPRESENTER_H
|
#define LEGOMETERPRESENTER_H
|
||||||
|
|
||||||
|
#include "mxrect16.h"
|
||||||
#include "mxstillpresenter.h"
|
#include "mxstillpresenter.h"
|
||||||
#include "mxstring.h"
|
#include "mxstring.h"
|
||||||
|
|
||||||
|
// SIZE 0x08
|
||||||
|
struct MeterRect : public MxRect16 {
|
||||||
|
// FUNCTION: BETA10 0x10097eb0
|
||||||
|
MeterRect() {}
|
||||||
|
};
|
||||||
|
|
||||||
// VTABLE: LEGO1 0x100d7ac8
|
// VTABLE: LEGO1 0x100d7ac8
|
||||||
|
// VTABLE: BETA10 0x101bca68
|
||||||
// SIZE 0x94
|
// SIZE 0x94
|
||||||
class LegoMeterPresenter : public MxStillPresenter {
|
class LegoMeterPresenter : public MxStillPresenter {
|
||||||
public:
|
public:
|
||||||
@ -18,17 +26,21 @@ public:
|
|||||||
void ParseExtra() override; // vtable+0x30
|
void ParseExtra() override; // vtable+0x30
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FUN_10043a50();
|
enum MeterLayout {
|
||||||
|
e_leftToRight = 0,
|
||||||
|
e_rightToLeft,
|
||||||
|
e_bottomToTop,
|
||||||
|
e_topToBottom
|
||||||
|
};
|
||||||
|
|
||||||
MxU8* m_unk0x6c; // 0x6c
|
void DrawMeter();
|
||||||
MxU16 m_type; // 0x70
|
|
||||||
MxString m_variable; // 0x74
|
MxU8* m_meterPixels; // 0x6c
|
||||||
MxFloat m_unk0x84; // 0x84
|
MxU16 m_fillColor; // 0x70
|
||||||
MxU16 m_unk0x88; // 0x88
|
MxString m_variable; // 0x74
|
||||||
MxU16 m_unk0x8a; // 0x8a
|
MxFloat m_curPercent; // 0x84
|
||||||
MxU16 m_unk0x8c; // 0x8c
|
MeterRect m_meterRect; // 0x88
|
||||||
MxU16 m_unk0x8e; // 0x8e
|
MxS16 m_layout; // 0x90
|
||||||
MxU16 m_layout; // 0x90
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x10043760
|
// SYNTHETIC: LEGO1 0x10043760
|
||||||
|
@ -4,27 +4,34 @@
|
|||||||
#include "define.h"
|
#include "define.h"
|
||||||
#include "mxbitmap.h"
|
#include "mxbitmap.h"
|
||||||
#include "mxdsaction.h"
|
#include "mxdsaction.h"
|
||||||
|
#include "mxmisc.h"
|
||||||
#include "mxutilities.h"
|
#include "mxutilities.h"
|
||||||
|
#include "mxvariabletable.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(LegoMeterPresenter, 0x94)
|
DECOMP_SIZE_ASSERT(LegoMeterPresenter, 0x94)
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10043430
|
// FUNCTION: LEGO1 0x10043430
|
||||||
|
// FUNCTION: BETA10 0x10097570
|
||||||
LegoMeterPresenter::LegoMeterPresenter()
|
LegoMeterPresenter::LegoMeterPresenter()
|
||||||
{
|
{
|
||||||
m_layout = 0;
|
m_meterPixels = NULL;
|
||||||
m_unk0x6c = 0;
|
m_fillColor = 1;
|
||||||
m_unk0x84 = 0;
|
m_curPercent = 0;
|
||||||
m_type = 1;
|
m_layout = e_leftToRight;
|
||||||
SetBit1(FALSE);
|
m_flags.m_bit1 = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10043780
|
// FUNCTION: LEGO1 0x10043780
|
||||||
|
// FUNCTION: BETA10 0x1009764a
|
||||||
LegoMeterPresenter::~LegoMeterPresenter()
|
LegoMeterPresenter::~LegoMeterPresenter()
|
||||||
{
|
{
|
||||||
delete m_unk0x6c;
|
delete m_meterPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10043800
|
// FUNCTION: LEGO1 0x10043800
|
||||||
|
// FUNCTION: BETA10 0x100976ec
|
||||||
void LegoMeterPresenter::ParseExtra()
|
void LegoMeterPresenter::ParseExtra()
|
||||||
{
|
{
|
||||||
MxStillPresenter::ParseExtra();
|
MxStillPresenter::ParseExtra();
|
||||||
@ -41,27 +48,28 @@ void LegoMeterPresenter::ParseExtra()
|
|||||||
char output[256];
|
char output[256];
|
||||||
if (KeyValueStringParse(extraCopy, g_strTYPE, output)) {
|
if (KeyValueStringParse(extraCopy, g_strTYPE, output)) {
|
||||||
if (!strcmpi(output, g_strLEFT_TO_RIGHT)) {
|
if (!strcmpi(output, g_strLEFT_TO_RIGHT)) {
|
||||||
m_layout = 0;
|
m_layout = e_leftToRight;
|
||||||
}
|
}
|
||||||
else if (!strcmpi(output, g_strRIGHT_TO_LEFT)) {
|
else if (!strcmpi(output, g_strRIGHT_TO_LEFT)) {
|
||||||
m_layout = 1;
|
m_layout = e_rightToLeft;
|
||||||
}
|
}
|
||||||
else if (!strcmpi(output, g_strBOTTOM_TO_TOP)) {
|
else if (!strcmpi(output, g_strBOTTOM_TO_TOP)) {
|
||||||
m_layout = 2;
|
m_layout = e_bottomToTop;
|
||||||
}
|
}
|
||||||
else if (!strcmpi(output, g_strTOP_TO_BOTTOM)) {
|
else if (!strcmpi(output, g_strTOP_TO_BOTTOM)) {
|
||||||
m_layout = 3;
|
m_layout = e_topToBottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyValueStringParse(extraCopy, g_strFILLER_INDEX, output)) {
|
if (KeyValueStringParse(extraCopy, g_strFILLER_INDEX, output)) {
|
||||||
m_type = atoi(output);
|
m_fillColor = atoi(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyValueStringParse(extraCopy, g_strVARIABLE, output)) {
|
if (KeyValueStringParse(extraCopy, g_strVARIABLE, output)) {
|
||||||
m_variable = output;
|
m_variable = output;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert(0);
|
||||||
EndAction();
|
EndAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,30 +79,84 @@ void LegoMeterPresenter::ParseExtra()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10043990
|
// FUNCTION: LEGO1 0x10043990
|
||||||
|
// FUNCTION: BETA10 0x10097917
|
||||||
void LegoMeterPresenter::StreamingTickle()
|
void LegoMeterPresenter::StreamingTickle()
|
||||||
{
|
{
|
||||||
MxStillPresenter::StreamingTickle();
|
MxStillPresenter::StreamingTickle();
|
||||||
m_unk0x6c = new MxU8[m_frameBitmap->GetBmiStride() * m_frameBitmap->GetBmiHeightAbs()];
|
m_meterPixels = new MxU8[m_frameBitmap->GetDataSize()];
|
||||||
if (m_unk0x6c == NULL) {
|
if (m_meterPixels == NULL) {
|
||||||
|
assert(0);
|
||||||
EndAction();
|
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_meterRect.SetLeft(0);
|
||||||
m_unk0x8a = 0;
|
m_meterRect.SetTop(0);
|
||||||
m_unk0x8c = m_frameBitmap->GetBmiWidth() - 1;
|
m_meterRect.SetRight(m_frameBitmap->GetBmiWidth() - 1);
|
||||||
m_unk0x8e = m_frameBitmap->GetBmiHeightAbs() - 1;
|
m_meterRect.SetBottom(m_frameBitmap->GetBmiHeightAbs() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10043a30
|
// FUNCTION: LEGO1 0x10043a30
|
||||||
|
// FUNCTION: BETA10 0x10097a1a
|
||||||
void LegoMeterPresenter::RepeatingTickle()
|
void LegoMeterPresenter::RepeatingTickle()
|
||||||
{
|
{
|
||||||
FUN_10043a50();
|
DrawMeter();
|
||||||
MxStillPresenter::RepeatingTickle();
|
MxStillPresenter::RepeatingTickle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10043a50
|
// FUNCTION: LEGO1 0x10043a50
|
||||||
void LegoMeterPresenter::FUN_10043a50()
|
// 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
|
// FUNCTION: BETA10 0x100982b0
|
||||||
inline MxLong GetDataSize() const { return AlignToFourByte(m_bmiHeader->biWidth) * GetBmiHeightAbs(); }
|
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()
|
inline MxLong GetAdjustedStride()
|
||||||
{
|
{
|
||||||
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN || m_bmiHeader->biHeight < 0) {
|
if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN || m_bmiHeader->biHeight < 0) {
|
||||||
@ -123,28 +134,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MxLong GetLine(MxS32 p_top)
|
// FUNCTION: BETA10 0x1002c320
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline MxU8* GetStart(MxS32 p_left, MxS32 p_top)
|
inline MxU8* GetStart(MxS32 p_left, MxS32 p_top)
|
||||||
{
|
{
|
||||||
if (m_bmiHeader->biCompression == BI_RGB) {
|
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) {
|
else if (m_bmiHeader->biCompression == BI_RGB_TOPDOWN) {
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
else {
|
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…
x
Reference in New Issue
Block a user