mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 11:12:29 +00:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
965 changed files with 264882 additions and 0 deletions
351
src/ui/CBackdropGenerator.cpp
Normal file
351
src/ui/CBackdropGenerator.cpp
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
#include "ui/CBackdropGenerator.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include "ui/Util.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
CBackdropGenerator::CBackdropGenerator() {
|
||||
this->m_color.Set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
this->m_borderColor.Set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void CBackdropGenerator::Generate(const CRect* rect) {
|
||||
STORM_ASSERT(rect);
|
||||
|
||||
C2Vector texCoords[4];
|
||||
|
||||
float v3 = rect->maxX - rect->minX;
|
||||
float v7 = rect->maxY - rect->minY;
|
||||
|
||||
float v4 = 1.0f / this->m_cornerSize;
|
||||
float v5 = v4 * v3 - 2.0f;
|
||||
float v9 = v4 * v7 - 2.0f;
|
||||
|
||||
float v34 = v5 < 0.0f ? 0.0f : v5;
|
||||
float v17 = v9 < 0.0f ? 0.0f : v9;
|
||||
|
||||
const char* background = this->m_background.GetString();
|
||||
|
||||
if (background && *background && this->m_tileBackground) {
|
||||
float v13 = this->m_backgroundSize == 0.0f
|
||||
? this->m_cornerSize
|
||||
: this->m_backgroundSize;
|
||||
|
||||
texCoords[0] = { 0.0f, 0.0f };
|
||||
texCoords[1] = { 0.0f, v7 / v13 };
|
||||
texCoords[2] = { v3 / v13, 0.0f };
|
||||
texCoords[3] = { v3 / v13, v7 / v13 };
|
||||
|
||||
this->m_backgroundTexture->SetTexCoord(texCoords);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x1) {
|
||||
texCoords[0] = { 0.0078125f, 0.0625f };
|
||||
texCoords[1] = { 0.0078125f, v17 - 0.0625f };
|
||||
texCoords[2] = { 0.1171875f, 0.0625f };
|
||||
texCoords[3] = { 0.1171875f, v17 - 0.0625f };
|
||||
|
||||
this->m_leftTexture->SetTexCoord(texCoords);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x2) {
|
||||
texCoords[0] = { 0.1328125f, 0.0625f };
|
||||
texCoords[1] = { 0.1328125f, v17 - 0.0625f };
|
||||
texCoords[2] = { 0.2421875f, 0.0625f };
|
||||
texCoords[3] = { 0.2421875f, v17 - 0.0625f };
|
||||
|
||||
this->m_rightTexture->SetTexCoord(texCoords);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x4) {
|
||||
texCoords[0] = { 0.2578125f, v34 - 0.0625f };
|
||||
texCoords[1] = { 0.3671875f, v34 - 0.0625f };
|
||||
texCoords[2] = { 0.2578125f, 0.0625f };
|
||||
texCoords[3] = { 0.3671875f, 0.0625f };
|
||||
|
||||
this->m_topTexture->SetTexCoord(texCoords);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x8) {
|
||||
texCoords[0] = { 0.3828125f, v34 - 0.0625f };
|
||||
texCoords[1] = { 0.4921875f, v34 - 0.0625f };
|
||||
texCoords[2] = { 0.3828125f, 0.0625f };
|
||||
texCoords[3] = { 0.4921875f, 0.0625f };
|
||||
|
||||
this->m_bottomTexture->SetTexCoord(texCoords);
|
||||
}
|
||||
|
||||
if (this->m_backgroundTexture) {
|
||||
this->m_backgroundTexture->SetVertexColor(this->m_color);
|
||||
}
|
||||
|
||||
this->SetBorderVertexColor(this->m_borderColor);
|
||||
}
|
||||
|
||||
void CBackdropGenerator::LoadXML(XMLNode* node, CStatus* status) {
|
||||
const char* bgFileAttr = node->GetAttributeByName("bgFile");
|
||||
const char* edgeFileAttr = node->GetAttributeByName("edgeFile");
|
||||
const char* tileAttr = node->GetAttributeByName("tile");
|
||||
const char* alphaModeAttr = node->GetAttributeByName("alphaMode");
|
||||
|
||||
this->m_background.Copy(bgFileAttr);
|
||||
this->m_border.Copy(edgeFileAttr);
|
||||
|
||||
this->m_tileBackground = tileAttr && *tileAttr
|
||||
? StringToBOOL(tileAttr)
|
||||
: 0;
|
||||
|
||||
this->m_pieces = edgeFileAttr && *edgeFileAttr
|
||||
? 0xFF
|
||||
: 0;
|
||||
|
||||
this->m_blend = GxBlend_Alpha;
|
||||
if (alphaModeAttr && *alphaModeAttr) {
|
||||
StringToBlendMode(alphaModeAttr, this->m_blend);
|
||||
}
|
||||
|
||||
for (auto child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "TileSize", STORM_MAX_STR)) {
|
||||
float backgroundSize;
|
||||
|
||||
if (LoadXML_Value(child, backgroundSize, status)) {
|
||||
this->m_backgroundSize = backgroundSize;
|
||||
}
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "EdgeSize", STORM_MAX_STR)) {
|
||||
float cornerSize;
|
||||
|
||||
if (LoadXML_Value(child, cornerSize, status)) {
|
||||
this->m_cornerSize = cornerSize;
|
||||
}
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "BackgroundInsets", STORM_MAX_STR)) {
|
||||
float leftInset, rightInset, topInset, bottomInset;
|
||||
|
||||
if (LoadXML_Insets(child, leftInset, rightInset, topInset, bottomInset, status)) {
|
||||
this->m_leftInset = leftInset;
|
||||
this->m_rightInset = rightInset;
|
||||
this->m_topInset = topInset;
|
||||
this->m_bottomInset = bottomInset;
|
||||
}
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "Color", STORM_MAX_STR)) {
|
||||
// TODO
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "BorderColor", STORM_MAX_STR)) {
|
||||
// TODO
|
||||
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Unknown child node in %s element: %s",
|
||||
node->GetName(),
|
||||
child->GetName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBackdropGenerator::SetBorderVertexColor(const CImVector& borderColor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CBackdropGenerator::SetOutput(CSimpleFrame* frame) {
|
||||
STORM_ASSERT(frame);
|
||||
|
||||
C2Vector texCoords[4];
|
||||
|
||||
const char* background = this->m_background.GetString();
|
||||
const char* border = this->m_border.GetString();
|
||||
|
||||
if (background && *background) {
|
||||
// TODO
|
||||
// CSimpleTexture* backgroundTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* backgroundTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND, 1);
|
||||
|
||||
this->m_backgroundTexture = backgroundTexture;
|
||||
|
||||
backgroundTexture->SetPoint(FRAMEPOINT_TOPLEFT, frame, FRAMEPOINT_TOPLEFT, this->m_leftInset, -this->m_topInset, 0);
|
||||
backgroundTexture->SetPoint(FRAMEPOINT_TOPRIGHT, frame, FRAMEPOINT_TOPRIGHT, -this->m_rightInset, -this->m_topInset, 0);
|
||||
backgroundTexture->SetPoint(FRAMEPOINT_BOTTOMLEFT, frame, FRAMEPOINT_BOTTOMLEFT, this->m_leftInset, this->m_bottomInset, 0);
|
||||
backgroundTexture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, frame, FRAMEPOINT_BOTTOMRIGHT, -this->m_rightInset, this->m_topInset, 0);
|
||||
|
||||
backgroundTexture->Resize(0);
|
||||
|
||||
backgroundTexture->SetTexture(background, this->m_tileBackground, 0, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x1) {
|
||||
// TODO
|
||||
// CSimpleTexture* leftTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* leftTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_leftTexture = leftTexture;
|
||||
|
||||
leftTexture->SetWidth(this->m_cornerSize);
|
||||
leftTexture->SetPoint(FRAMEPOINT_TOPLEFT, frame, FRAMEPOINT_TOPLEFT, 0.0f, -this->m_cornerSize, 0);
|
||||
leftTexture->SetPoint(FRAMEPOINT_BOTTOMLEFT, frame, FRAMEPOINT_BOTTOMLEFT, 0.0f, this->m_cornerSize, 0);
|
||||
|
||||
leftTexture->Resize(0);
|
||||
|
||||
leftTexture->SetTexture(border, 1, 1, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
leftTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x2) {
|
||||
// TODO
|
||||
// CSimpleTexture* rightTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* rightTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_rightTexture = rightTexture;
|
||||
|
||||
rightTexture->SetWidth(this->m_cornerSize);
|
||||
rightTexture->SetPoint(FRAMEPOINT_TOPRIGHT, frame, FRAMEPOINT_TOPRIGHT, 0.0f, -this->m_cornerSize, 0);
|
||||
rightTexture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, frame, FRAMEPOINT_BOTTOMRIGHT, 0.0f, this->m_cornerSize, 0);
|
||||
|
||||
rightTexture->Resize(0);
|
||||
|
||||
rightTexture->SetTexture(border, 1, 1, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
rightTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x4) {
|
||||
// TODO
|
||||
// CSimpleTexture* topTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* topTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_topTexture = topTexture;
|
||||
|
||||
topTexture->SetHeight(this->m_cornerSize);
|
||||
topTexture->SetPoint(FRAMEPOINT_TOPLEFT, frame, FRAMEPOINT_TOPLEFT, this->m_cornerSize, 0.0f, 0);
|
||||
topTexture->SetPoint(FRAMEPOINT_TOPRIGHT, frame, FRAMEPOINT_TOPRIGHT, -this->m_cornerSize, 0.0f, 0);
|
||||
|
||||
topTexture->Resize(0);
|
||||
|
||||
topTexture->SetTexture(border, 1, 1, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
topTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x8) {
|
||||
// TODO
|
||||
// CSimpleTexture* bottomTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* bottomTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_bottomTexture = bottomTexture;
|
||||
|
||||
bottomTexture->SetHeight(this->m_cornerSize);
|
||||
bottomTexture->SetPoint(FRAMEPOINT_BOTTOMLEFT, frame, FRAMEPOINT_BOTTOMLEFT, this->m_cornerSize, 0.0f, 0);
|
||||
bottomTexture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, frame, FRAMEPOINT_BOTTOMRIGHT, -this->m_cornerSize, 0.0f, 0);
|
||||
|
||||
bottomTexture->Resize(0);
|
||||
|
||||
bottomTexture->SetTexture(border, 1, 1, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
bottomTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x10) {
|
||||
// TODO
|
||||
// CSimpleTexture* topLeftTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* topLeftTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_topLeftTexture = topLeftTexture;
|
||||
|
||||
topLeftTexture->SetWidth(this->m_cornerSize);
|
||||
topLeftTexture->SetHeight(this->m_cornerSize);
|
||||
topLeftTexture->SetPoint(FRAMEPOINT_TOPLEFT, frame, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f, 1);
|
||||
|
||||
texCoords[0] = { 0.5078125f, 0.0625f };
|
||||
texCoords[1] = { 0.5078125f, 0.9375f };
|
||||
texCoords[2] = { 0.6171875f, 0.0625f };
|
||||
texCoords[3] = { 0.6171875f, 0.9375f };
|
||||
|
||||
topLeftTexture->SetTexture(border, 0, 0, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
topLeftTexture->SetTexCoord(texCoords);
|
||||
topLeftTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x20) {
|
||||
// TODO
|
||||
// CSimpleTexture* topRightTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* topRightTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_topRightTexture = topRightTexture;
|
||||
|
||||
topRightTexture->SetWidth(this->m_cornerSize);
|
||||
topRightTexture->SetHeight(this->m_cornerSize);
|
||||
topRightTexture->SetPoint(FRAMEPOINT_TOPRIGHT, frame, FRAMEPOINT_TOPRIGHT, 0.0f, 0.0f, 1);
|
||||
|
||||
texCoords[0] = { 0.6328125f, 0.0625f };
|
||||
texCoords[1] = { 0.6328125f, 0.9375f };
|
||||
texCoords[2] = { 0.7421875f, 0.0625f };
|
||||
texCoords[3] = { 0.7421875f, 0.9375f };
|
||||
|
||||
topRightTexture->SetTexture(border, 0, 0, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
topRightTexture->SetTexCoord(texCoords);
|
||||
topRightTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x40) {
|
||||
// TODO
|
||||
// CSimpleTexture* bottomLeftTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* bottomLeftTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_bottomLeftTexture = bottomLeftTexture;
|
||||
|
||||
bottomLeftTexture->SetWidth(this->m_cornerSize);
|
||||
bottomLeftTexture->SetHeight(this->m_cornerSize);
|
||||
bottomLeftTexture->SetPoint(FRAMEPOINT_BOTTOMLEFT, frame, FRAMEPOINT_BOTTOMLEFT, 0.0f, 0.0f, 1);
|
||||
|
||||
texCoords[0] = { 0.7578125f, 0.0625f };
|
||||
texCoords[1] = { 0.7578125f, 0.9375f };
|
||||
texCoords[2] = { 0.8671875f, 0.0625f };
|
||||
texCoords[3] = { 0.8671875f, 0.9375f };
|
||||
|
||||
bottomLeftTexture->SetTexture(border, 0, 0, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
bottomLeftTexture->SetTexCoord(texCoords);
|
||||
bottomLeftTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
|
||||
if (this->m_pieces & 0x80) {
|
||||
// TODO
|
||||
// CSimpleTexture* bottomRightTexture = CSimpleTexture::s_allocator.GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
CSimpleTexture* bottomRightTexture = new (m) CSimpleTexture(frame, DRAWLAYER_BACKGROUND_BORDER, 1);
|
||||
|
||||
this->m_bottomRightTexture = bottomRightTexture;
|
||||
|
||||
bottomRightTexture->SetWidth(this->m_cornerSize);
|
||||
bottomRightTexture->SetHeight(this->m_cornerSize);
|
||||
bottomRightTexture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, frame, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f, 1);
|
||||
|
||||
texCoords[0] = { 0.8828125f, 0.0625f };
|
||||
texCoords[1] = { 0.8828125f, 0.9375f };
|
||||
texCoords[2] = { 0.9921875f, 0.0625f };
|
||||
texCoords[3] = { 0.9921875f, 0.9375f };
|
||||
|
||||
bottomRightTexture->SetTexture(border, 0, 0, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
bottomRightTexture->SetTexCoord(texCoords);
|
||||
bottomRightTexture->SetBlendMode(this->m_blend);
|
||||
}
|
||||
}
|
||||
49
src/ui/CBackdropGenerator.hpp
Normal file
49
src/ui/CBackdropGenerator.hpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef UI_C_BACKDROP_GENERATOR_HPP
|
||||
#define UI_C_BACKDROP_GENERATOR_HPP
|
||||
|
||||
#include "gx/Types.hpp"
|
||||
#include <common/String.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CRect;
|
||||
class CSimpleFrame;
|
||||
class CSimpleTexture;
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
|
||||
class CBackdropGenerator {
|
||||
public:
|
||||
// Member variables
|
||||
CSimpleTexture* m_backgroundTexture = nullptr;
|
||||
CSimpleTexture* m_leftTexture = nullptr;
|
||||
CSimpleTexture* m_rightTexture = nullptr;
|
||||
CSimpleTexture* m_topTexture = nullptr;
|
||||
CSimpleTexture* m_bottomTexture = nullptr;
|
||||
CSimpleTexture* m_topLeftTexture = nullptr;
|
||||
CSimpleTexture* m_topRightTexture = nullptr;
|
||||
CSimpleTexture* m_bottomLeftTexture = nullptr;
|
||||
CSimpleTexture* m_bottomRightTexture = nullptr;
|
||||
RCString m_background;
|
||||
RCString m_border;
|
||||
uint32_t m_pieces = 0;
|
||||
int32_t m_tileBackground = 0;
|
||||
int32_t int44;
|
||||
float m_cornerSize = 0.025f;
|
||||
float m_backgroundSize = 0.0f;
|
||||
float m_topInset = 0.0f;
|
||||
float m_bottomInset = 0.0f;
|
||||
float m_leftInset = 0.0f;
|
||||
float m_rightInset = 0.0f;
|
||||
CImVector m_color = { 0x00 };
|
||||
CImVector m_borderColor = { 0x00 };
|
||||
EGxBlend m_blend;
|
||||
|
||||
// Member functions
|
||||
CBackdropGenerator();
|
||||
void Generate(const CRect*);
|
||||
void LoadXML(XMLNode*, CStatus*);
|
||||
void SetBorderVertexColor(const CImVector&);
|
||||
void SetOutput(CSimpleFrame*);
|
||||
};
|
||||
|
||||
#endif
|
||||
146
src/ui/CFramePoint.cpp
Normal file
146
src/ui/CFramePoint.cpp
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#include "ui/CFramePoint.hpp"
|
||||
#include "ui/CLayoutFrame.hpp"
|
||||
|
||||
const float CFramePoint::UNDEFINED = 3.4028237e38;
|
||||
|
||||
CFramePoint::CFramePoint(CLayoutFrame* relative, FRAMEPOINT framePoint, float offsetX, float offsetY) {
|
||||
this->m_offset = { offsetX, offsetY };
|
||||
this->m_framePoint = framePoint;
|
||||
this->m_relative = relative;
|
||||
|
||||
// TODO
|
||||
// - this doesn't appear to be zeroed out
|
||||
// - what is it actually checking?
|
||||
this->m_flags = (this->m_flags & 0x2) >= 1 ? 0x6 : 0;
|
||||
}
|
||||
|
||||
CLayoutFrame* CFramePoint::GetRelative() {
|
||||
return this->m_relative;
|
||||
}
|
||||
|
||||
int32_t CFramePoint::GetRelativeRect(CRect& rect) {
|
||||
bool flag2initial = this->m_flags & 0x2;
|
||||
|
||||
if (!flag2initial) {
|
||||
this->m_flags |= 0x2;
|
||||
}
|
||||
|
||||
this->m_flags &= ~0x4;
|
||||
|
||||
CLayoutFrame* relative = this->GetRelative();
|
||||
|
||||
if (relative->IsResizePending()) {
|
||||
relative->Resize(1);
|
||||
|
||||
if (this->m_flags & 0x4) {
|
||||
if (!flag2initial) {
|
||||
this->m_flags &= ~0x2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (relative->m_flags & 0x2) {
|
||||
relative->SetDeferredResize(0);
|
||||
|
||||
if (this->m_flags & 0x4) {
|
||||
if (!flag2initial) {
|
||||
this->m_flags &= ~0x2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!relative->GetRect(&rect)) {
|
||||
if (!flag2initial) {
|
||||
this->m_flags &= ~0x2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (relative->IsAttachmentOrigin()) {
|
||||
rect.minY -= rect.minY;
|
||||
rect.minX -= rect.minX;
|
||||
rect.maxY -= rect.minY;
|
||||
rect.maxX -= rect.minX;
|
||||
}
|
||||
|
||||
if (!flag2initial) {
|
||||
this->m_flags &= ~0x2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CFramePoint::MarkUnused() {
|
||||
this->m_framePoint = FRAMEPOINT_NUMPOINTS;
|
||||
this->m_offset = { 0.0f, 0.0f };
|
||||
this->m_relative = nullptr;
|
||||
this->m_flags = this->m_flags & 0x2 ? 0x2 | 0x4 | 0x8 : 0x8;
|
||||
}
|
||||
|
||||
void CFramePoint::SetRelative(CLayoutFrame* relative, FRAMEPOINT relativePoint, float offsetX, float offsetY) {
|
||||
this->m_offset = { offsetX, offsetY };
|
||||
this->m_framePoint = relativePoint;
|
||||
this->m_relative = relative;
|
||||
this->m_flags = this->m_flags & 0x2 ? 0x2 | 0x4 : 0x0;
|
||||
}
|
||||
|
||||
float CFramePoint::X(float scale) {
|
||||
CRect relative = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (!this->GetRelativeRect(relative)) {
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
switch (this->m_framePoint) {
|
||||
case FRAMEPOINT_TOPLEFT:
|
||||
case FRAMEPOINT_LEFT:
|
||||
case FRAMEPOINT_BOTTOMLEFT:
|
||||
return relative.minX + (this->m_offset.x * scale);
|
||||
|
||||
case FRAMEPOINT_TOP:
|
||||
case FRAMEPOINT_CENTER:
|
||||
case FRAMEPOINT_BOTTOM:
|
||||
return ((relative.minX + relative.maxX) * 0.5f) + (this->m_offset.x * scale);
|
||||
|
||||
case FRAMEPOINT_TOPRIGHT:
|
||||
case FRAMEPOINT_RIGHT:
|
||||
case FRAMEPOINT_BOTTOMRIGHT:
|
||||
return relative.maxX + (this->m_offset.x * scale);
|
||||
|
||||
default:
|
||||
return UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
float CFramePoint::Y(float scale) {
|
||||
CRect relative = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (!this->GetRelativeRect(relative)) {
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
switch (this->m_framePoint) {
|
||||
case FRAMEPOINT_TOPLEFT:
|
||||
case FRAMEPOINT_TOP:
|
||||
case FRAMEPOINT_TOPRIGHT:
|
||||
return relative.maxY + (this->m_offset.y * scale);
|
||||
|
||||
case FRAMEPOINT_LEFT:
|
||||
case FRAMEPOINT_CENTER:
|
||||
case FRAMEPOINT_RIGHT:
|
||||
return ((relative.minY + relative.maxY) * 0.5f) + (this->m_offset.y * scale);
|
||||
|
||||
case FRAMEPOINT_BOTTOMLEFT:
|
||||
case FRAMEPOINT_BOTTOM:
|
||||
case FRAMEPOINT_BOTTOMRIGHT:
|
||||
return relative.minY + (this->m_offset.y * scale);
|
||||
|
||||
default:
|
||||
return UNDEFINED;
|
||||
}
|
||||
}
|
||||
32
src/ui/CFramePoint.hpp
Normal file
32
src/ui/CFramePoint.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef UI_C_FRAME_POINT_HPP
|
||||
#define UI_C_FRAME_POINT_HPP
|
||||
|
||||
#include "ui/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CLayoutFrame;
|
||||
class CRect;
|
||||
|
||||
class CFramePoint {
|
||||
public:
|
||||
// Static variables
|
||||
static float const UNDEFINED;
|
||||
|
||||
// Member variables
|
||||
C2Vector m_offset;
|
||||
CLayoutFrame* m_relative;
|
||||
uint32_t m_framePoint : 8;
|
||||
uint32_t m_flags : 24;
|
||||
|
||||
// Member functions
|
||||
CFramePoint(CLayoutFrame*, FRAMEPOINT, float, float);
|
||||
CLayoutFrame* GetRelative();
|
||||
int32_t GetRelativeRect(CRect&);
|
||||
void MarkUnused(void);
|
||||
void SetRelative(CLayoutFrame*, FRAMEPOINT, float, float);
|
||||
float X(float);
|
||||
float Y(float);
|
||||
};
|
||||
|
||||
#endif
|
||||
168
src/ui/CFrameStrata.cpp
Normal file
168
src/ui/CFrameStrata.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include "ui/CFrameStrata.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleRender.hpp"
|
||||
|
||||
int32_t CFrameStrataNode::BuildBatches() {
|
||||
if (!this->batchDirty) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t batchDirty = this->batchDirty;
|
||||
this->batchDirty = 0;
|
||||
|
||||
for (int32_t layer = 0; layer < NUM_SIMPLEFRAME_DRAWLAYERS; layer++) {
|
||||
CRenderBatch* batch = &this->batches[layer];
|
||||
|
||||
this->renderList.UnlinkNode(batch);
|
||||
|
||||
if ((1 << layer) & batchDirty) {
|
||||
batch->Clear();
|
||||
|
||||
for (auto frame = this->frames.Head(); frame; frame = this->frames.Link(frame)->Next()) {
|
||||
if (!(frame->m_flags & 0x2000)) {
|
||||
frame->OnFrameRender(batch, layer);
|
||||
}
|
||||
}
|
||||
|
||||
batch->Finish();
|
||||
}
|
||||
|
||||
if (batch->m_count) {
|
||||
this->renderList.LinkToTail(batch);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->batchDirty & 0x20) {
|
||||
this->batchDirty |= 0x1F;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CFrameStrataNode::OnLayerUpdate(float elapsedSec) {
|
||||
auto frame = this->frames.Head();
|
||||
|
||||
while (frame) {
|
||||
auto next = this->frames.Link(frame)->Next();
|
||||
this->pendingFrame = next;
|
||||
frame->OnLayerUpdate(elapsedSec);
|
||||
frame = this->pendingFrame;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->frames.Combine(this->pendingFrames, 2, nullptr);
|
||||
}
|
||||
|
||||
bool CFrameStrataNode::RemoveFrame(CSimpleFrame* frame) {
|
||||
if (!this->frames.Link(frame)->IsLinked()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (frame == this->pendingFrame) {
|
||||
this->pendingFrame = this->frames.Link(frame)->Next();
|
||||
}
|
||||
|
||||
this->frames.UnlinkNode(frame);
|
||||
|
||||
if (!(frame->m_flags & 0x2000)) {
|
||||
this->batchDirty = -1;
|
||||
}
|
||||
|
||||
return this->batchDirty != 0;
|
||||
}
|
||||
|
||||
void CFrameStrata::AddFrame(CSimpleFrame* frame) {
|
||||
// TODO
|
||||
// - potentially an inlined TSFixedArray function?
|
||||
if (frame->m_level >= this->levels.Count()) {
|
||||
uint32_t count = this->levels.Count();
|
||||
|
||||
this->levels.SetCount(frame->m_level + 1);
|
||||
|
||||
for (int32_t i = count; i < frame->m_level + 1; i++) {
|
||||
void* m = SMemAlloc(sizeof(CFrameStrataNode), __FILE__, __LINE__, 0);
|
||||
CFrameStrataNode* node = m ? new (m) CFrameStrataNode() : nullptr;
|
||||
this->levels[i] = node;
|
||||
}
|
||||
}
|
||||
|
||||
if (frame->m_level >= this->topLevel) {
|
||||
this->topLevel = frame->m_level + 1;
|
||||
}
|
||||
|
||||
auto level = this->levels[frame->m_level];
|
||||
|
||||
if (!frame->m_strataLink.IsLinked()) {
|
||||
auto frames = level->pendingFrame ? &level->pendingFrames : &level->frames;
|
||||
|
||||
frames->LinkToTail(frame);
|
||||
|
||||
if (!(frame->m_flags & 0x2000)) {
|
||||
level->batchDirty = -1;
|
||||
}
|
||||
}
|
||||
|
||||
this->levelsDirty = 1;
|
||||
this->batchDirty |= (level->batchDirty != 0);
|
||||
}
|
||||
|
||||
void CFrameStrata::CheckOcclusion() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CFrameStrata::BuildBatches(int32_t a2) {
|
||||
if (this->levelsDirty) {
|
||||
this->CheckOcclusion();
|
||||
this->levelsDirty = 0;
|
||||
}
|
||||
|
||||
if (!this->batchDirty) {
|
||||
return this->batchDirty;
|
||||
}
|
||||
|
||||
this->batchDirty = 0;
|
||||
|
||||
if (this->topLevel == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < this->topLevel; i++) {
|
||||
if (this->levels[i]->BuildBatches()) {
|
||||
this->batchDirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return this->batchDirty;
|
||||
}
|
||||
|
||||
int32_t CFrameStrata::FrameOccluded(CSimpleFrame* frame) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CFrameStrata::OnLayerUpdate(float elapsedSec) {
|
||||
if (this->topLevel) {
|
||||
for (int32_t l = 0; l < this->topLevel; l++) {
|
||||
this->levels[l]->OnLayerUpdate(elapsedSec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFrameStrata::RemoveFrame(CSimpleFrame* frame) {
|
||||
if (frame->m_level < this->levels.Count()) {
|
||||
CFrameStrataNode* level = this->levels[frame->m_level];
|
||||
int32_t batchDirty = level->RemoveFrame(frame);
|
||||
this->batchDirty |= batchDirty;
|
||||
this->levelsDirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CFrameStrata::RenderBatches() {
|
||||
for (int32_t i = 0; i < this->topLevel; i++) {
|
||||
auto renderList = &this->levels[i]->renderList;
|
||||
|
||||
for (auto batch = renderList->Head(); batch; batch = renderList->Link(batch)->Next()) {
|
||||
CSimpleRender::DrawBatch(batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/ui/CFrameStrata.hpp
Normal file
44
src/ui/CFrameStrata.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef UI_C_FRAME_STRATA_HPP
|
||||
#define UI_C_FRAME_STRATA_HPP
|
||||
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Array.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CFrameStrataNode {
|
||||
public:
|
||||
// Member variables
|
||||
STORM_EXPLICIT_LIST(CSimpleFrame, m_strataLink) pendingFrames;
|
||||
STORM_EXPLICIT_LIST(CSimpleFrame, m_strataLink) frames;
|
||||
CSimpleFrame* pendingFrame = nullptr;
|
||||
CRenderBatch batches[5];
|
||||
int32_t batchDirty = 0;
|
||||
STORM_EXPLICIT_LIST(CRenderBatch, renderLink) renderList;
|
||||
|
||||
// Member functions
|
||||
int32_t BuildBatches(void);
|
||||
void OnLayerUpdate(float);
|
||||
bool RemoveFrame(CSimpleFrame*);
|
||||
};
|
||||
|
||||
class CFrameStrata {
|
||||
public:
|
||||
// Member variables
|
||||
int32_t batchDirty = 0;
|
||||
int32_t levelsDirty = 0;
|
||||
uint32_t topLevel = 0;
|
||||
TSFixedArray<CFrameStrataNode*> levels;
|
||||
|
||||
// Member functions
|
||||
void AddFrame(CSimpleFrame*);
|
||||
int32_t BuildBatches(int32_t);
|
||||
void CheckOcclusion(void);
|
||||
int32_t FrameOccluded(CSimpleFrame*);
|
||||
void OnLayerUpdate(float);
|
||||
void RemoveFrame(CSimpleFrame*);
|
||||
void RenderBatches(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
920
src/ui/CLayoutFrame.cpp
Normal file
920
src/ui/CLayoutFrame.cpp
Normal file
|
|
@ -0,0 +1,920 @@
|
|||
#include "ui/CLayoutFrame.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "math/Utils.hpp"
|
||||
#include "ui/CFramePoint.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
STORM_EXPLICIT_LIST(CLayoutFrame, resizeLink) LayoutFrame::s_resizePendingList;
|
||||
|
||||
float SynthesizeSide(float center, float opposite, float size) {
|
||||
if (center != CFramePoint::UNDEFINED && opposite != CFramePoint::UNDEFINED) {
|
||||
return center + center - opposite;
|
||||
} else if (opposite != CFramePoint::UNDEFINED && size != 0.0f) {
|
||||
return opposite + size;
|
||||
} else if (center != CFramePoint::UNDEFINED && size != 0.0f) {
|
||||
return center + (size * 0.5f);
|
||||
} else {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
float SynthesizeCenter(float side1, float side2, float size) {
|
||||
if (side1 != CFramePoint::UNDEFINED && side2 != CFramePoint::UNDEFINED) {
|
||||
return (side1 + side2) * 0.5f;
|
||||
} else if (side1 != CFramePoint::UNDEFINED && size != 0.0f) {
|
||||
return side1 + (size * 0.5f);
|
||||
} else if (side2 != CFramePoint::UNDEFINED && size != 0.0f) {
|
||||
return side2 - (size * 0.5f);
|
||||
} else {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::ResizePending() {
|
||||
int32_t loading = 0;
|
||||
|
||||
for (CLayoutFrame* frame = LayoutFrame::s_resizePendingList.Head(); frame && loading < 32; frame = LayoutFrame::s_resizePendingList.Link(frame)->Next()) {
|
||||
if (!frame->IsObjectLoaded()) {
|
||||
loading++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (frame->OnFrameResize() || (frame->m_resizeCounter--, frame->m_resizeCounter == 0)) {
|
||||
frame->m_flags &= ~0x4;
|
||||
LayoutFrame::s_resizePendingList.UnlinkNode(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLayoutFrame::CLayoutFrame() {
|
||||
this->m_flags = 0;
|
||||
|
||||
this->m_rect = { 0.0, 0.0, 0.0, 0.0 };
|
||||
this->m_width = 0.0;
|
||||
this->m_height = 0.0;
|
||||
|
||||
this->m_layoutScale = 1.0;
|
||||
this->m_layoutDepth = 1.0;
|
||||
|
||||
this->m_guard = { 0 };
|
||||
}
|
||||
|
||||
CLayoutFrame::~CLayoutFrame() {
|
||||
this->DestroyLayout();
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CLayoutFrame::AddToResizeList() {
|
||||
if (LayoutFrame::s_resizePendingList.IsLinked(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CLayoutFrame* dependent = nullptr;
|
||||
|
||||
for (auto frame = LayoutFrame::s_resizePendingList.Head(); frame; frame = LayoutFrame::s_resizePendingList.Link(frame)->Next()) {
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
auto point = frame->m_points[i];
|
||||
|
||||
if (point && !(point->m_flags & 0x8) && point->GetRelative() == this) {
|
||||
dependent = frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dependent) {
|
||||
LayoutFrame::s_resizePendingList.LinkNode(this, 2, dependent);
|
||||
} else {
|
||||
LayoutFrame::s_resizePendingList.LinkToTail(this);
|
||||
}
|
||||
|
||||
this->m_resizeCounter = 6;
|
||||
}
|
||||
|
||||
float CLayoutFrame::Bottom() {
|
||||
if (this->m_guard.bottom) {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
|
||||
this->m_guard.bottom = 1;
|
||||
|
||||
static FRAMEPOINT sidepoints[] = {
|
||||
FRAMEPOINT_BOTTOMLEFT,
|
||||
FRAMEPOINT_BOTTOM,
|
||||
FRAMEPOINT_BOTTOMRIGHT
|
||||
};
|
||||
|
||||
float bottom = CFramePoint::UNDEFINED;
|
||||
this->GetFirstPointY(sidepoints, 3, bottom);
|
||||
|
||||
if (bottom == CFramePoint::UNDEFINED) {
|
||||
float size = -(this->GetHeight() * this->m_layoutScale);
|
||||
float opposite = this->Top();
|
||||
float center = this->CenterY();
|
||||
|
||||
bottom = SynthesizeSide(center, opposite, size);
|
||||
}
|
||||
|
||||
this->m_guard.bottom = 0;
|
||||
|
||||
return bottom;
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::CalculateRect(CRect* rect) {
|
||||
rect->minX = this->Left();
|
||||
|
||||
if (rect->minX == CFramePoint::UNDEFINED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rect->minY = this->Bottom();
|
||||
|
||||
if (rect->minY == CFramePoint::UNDEFINED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rect->maxX = this->Right();
|
||||
|
||||
if (rect->maxX == CFramePoint::UNDEFINED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rect->maxY = this->Top();
|
||||
|
||||
if (rect->maxY == CFramePoint::UNDEFINED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(this->m_flags & 0x10)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
float v14 = 0.0f;
|
||||
float v15 = 0.0f;
|
||||
float v16 = 0.0f;
|
||||
float v17 = 0.0f;
|
||||
|
||||
this->GetClampRectInsets(v15, v17, v16, v14);
|
||||
|
||||
float v12 = -(this->m_layoutScale * v15);
|
||||
float v7 = NDCToDDCWidth(1.0f);
|
||||
float v13 = v7 - this->m_layoutScale * v17;
|
||||
float v11 = -(this->m_layoutScale * v14);
|
||||
float v8 = NDCToDDCHeight(1.0f);
|
||||
float v9 = v8 - this->m_layoutScale * v16;
|
||||
|
||||
if (v12 > rect->minX) {
|
||||
rect->maxX = rect->maxX - (rect->minX - v12);
|
||||
rect->minX = v12;
|
||||
}
|
||||
|
||||
if (v11 > rect->minY) {
|
||||
rect->maxY = rect->maxY - (rect->minY - v11);
|
||||
rect->minY = v11;
|
||||
}
|
||||
|
||||
if (v13 < rect->maxX) {
|
||||
rect->minX = rect->minX - (rect->maxX - v13);
|
||||
rect->maxX = v13;
|
||||
}
|
||||
|
||||
if (v9 < rect->maxY ) {
|
||||
rect->minY = rect->minY - (rect->maxY - v9);
|
||||
rect->maxY = v9;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CLayoutFrame::CanBeAnchorFor(CLayoutFrame*) {
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float CLayoutFrame::CenterX() {
|
||||
if (this->m_guard.centerX) {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
|
||||
this->m_guard.centerX = 1;
|
||||
|
||||
static FRAMEPOINT sidepoints[] = {
|
||||
FRAMEPOINT_TOP,
|
||||
FRAMEPOINT_CENTER,
|
||||
FRAMEPOINT_BOTTOM
|
||||
};
|
||||
|
||||
float centerX = CFramePoint::UNDEFINED;
|
||||
this->GetFirstPointX(sidepoints, 3, centerX);
|
||||
|
||||
if (centerX == CFramePoint::UNDEFINED) {
|
||||
float size = this->GetWidth() * this->m_layoutScale;
|
||||
float side2 = this->Right();
|
||||
float side1 = this->Left();
|
||||
|
||||
centerX = SynthesizeCenter(side1, side2, size);
|
||||
}
|
||||
|
||||
this->m_guard.centerX = 0;
|
||||
|
||||
return centerX;
|
||||
}
|
||||
|
||||
float CLayoutFrame::CenterY() {
|
||||
if (this->m_guard.centerY) {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
|
||||
this->m_guard.centerY = 1;
|
||||
|
||||
static FRAMEPOINT sidepoints[] = {
|
||||
FRAMEPOINT_LEFT,
|
||||
FRAMEPOINT_CENTER,
|
||||
FRAMEPOINT_RIGHT
|
||||
};
|
||||
|
||||
float centerY = CFramePoint::UNDEFINED;
|
||||
this->GetFirstPointY(sidepoints, 3, centerY);
|
||||
|
||||
if (centerY == CFramePoint::UNDEFINED) {
|
||||
float size = this->GetHeight() * this->m_layoutScale;
|
||||
float side2 = this->Top();
|
||||
float side1 = this->Bottom();
|
||||
|
||||
centerY = SynthesizeCenter(side1, side2, size);
|
||||
}
|
||||
|
||||
this->m_guard.centerY = 0;
|
||||
|
||||
return centerY;
|
||||
}
|
||||
|
||||
void CLayoutFrame::ClearAllPoints() {
|
||||
this->FreePoints();
|
||||
}
|
||||
|
||||
void CLayoutFrame::DestroyLayout() {
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
auto point = this->m_points[i];
|
||||
|
||||
if (point) {
|
||||
if (!(point->m_flags & 0x8) && point->m_relative) {
|
||||
point->m_relative->UnregisterResize(this, 1 << i);
|
||||
}
|
||||
|
||||
delete point;
|
||||
this->m_points[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto node = this->m_resizeList.Head(); node; node = this->m_resizeList.Link(node)->Next()) {
|
||||
auto frame = node->frame;
|
||||
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
auto point = this->m_points[i];
|
||||
|
||||
if (point && point->m_relative == this) {
|
||||
point->MarkUnused();
|
||||
}
|
||||
}
|
||||
|
||||
frame->m_flags &= ~0x8;
|
||||
}
|
||||
|
||||
this->m_resizeList.DeleteAll();
|
||||
}
|
||||
|
||||
void CLayoutFrame::FreePoints() {
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
auto point = this->m_points[i];
|
||||
|
||||
if (point && !(point->m_flags & 0x8)) {
|
||||
if (point->m_relative) {
|
||||
point->m_relative->UnregisterResize(this, 1 << i);
|
||||
}
|
||||
|
||||
point->MarkUnused();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::GetClampRectInsets(float& a1, float& a2, float& a3, float& a4) {
|
||||
a4 = 0.0f;
|
||||
a3 = 0.0f;
|
||||
a2 = 0.0f;
|
||||
a1 = 0.0f;
|
||||
}
|
||||
|
||||
void CLayoutFrame::GetFirstPointX(const FRAMEPOINT* const pointarray, int32_t elements, float& x) {
|
||||
// TODO
|
||||
// - what's up with this loop?
|
||||
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
if (this->Sub488DB0(pointarray, elements, x)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::GetFirstPointY(const FRAMEPOINT* const pointarray, int32_t elements, float& y) {
|
||||
// TODO
|
||||
// - what's up with this loop?
|
||||
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
if (this->Sub488E40(pointarray, elements, y)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLayoutFrame* CLayoutFrame::GetLayoutFrameByName(const char* name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CLayoutFrame* CLayoutFrame::GetLayoutParent() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::GetRect(CRect* rect) {
|
||||
if (!(this->m_flags & 0x1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rect->minY = this->m_rect.minY;
|
||||
rect->minX = this->m_rect.minX;
|
||||
rect->maxY = this->m_rect.maxY;
|
||||
rect->maxX = this->m_rect.maxX;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CLayoutFrame::GetHeight() {
|
||||
return this->m_height;
|
||||
}
|
||||
|
||||
float CLayoutFrame::GetWidth() {
|
||||
return this->m_width;
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::IsAttachmentOrigin() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::IsObjectLoaded() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::IsResizeDependency(CLayoutFrame* dependentFrame) {
|
||||
CLayoutFrame* v2 = nullptr;
|
||||
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
auto framePoint = this->m_points[i];
|
||||
|
||||
if (!framePoint || framePoint->m_flags & 0x8) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!framePoint->GetRelative() || framePoint->GetRelative() == v2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (framePoint->GetRelative() == dependentFrame || framePoint->GetRelative()->IsResizeDependency(dependentFrame)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
v2 = framePoint->GetRelative();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t CLayoutFrame::IsResizePending() {
|
||||
return this->m_flags & 0x4;
|
||||
}
|
||||
|
||||
float CLayoutFrame::Left() {
|
||||
if (this->m_guard.left) {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
|
||||
this->m_guard.left = 1;
|
||||
|
||||
static FRAMEPOINT sidepoints[] = {
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
FRAMEPOINT_LEFT,
|
||||
FRAMEPOINT_BOTTOMLEFT
|
||||
};
|
||||
|
||||
float left = CFramePoint::UNDEFINED;
|
||||
this->GetFirstPointX(sidepoints, 3, left);
|
||||
|
||||
if (left == CFramePoint::UNDEFINED) {
|
||||
float size = -(this->GetWidth() * this->m_layoutScale);
|
||||
float opposite = this->Right();
|
||||
float center = this->CenterX();
|
||||
|
||||
left = SynthesizeSide(center, opposite, size);
|
||||
}
|
||||
|
||||
this->m_guard.left = 0;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
void CLayoutFrame::LoadXML(XMLNode* node, CStatus* status) {
|
||||
XMLNode* size = node->GetChildByName("Size");
|
||||
float width;
|
||||
float height;
|
||||
|
||||
if (size && LoadXML_Dimensions(size, width, height, status)) {
|
||||
this->SetWidth(width);
|
||||
this->SetHeight(height);
|
||||
}
|
||||
|
||||
CLayoutFrame* layoutParent = this->GetLayoutParent();
|
||||
|
||||
int32_t setAllPoints;
|
||||
|
||||
const char* setAllPointsAttr = node->GetAttributeByName("setAllPoints");
|
||||
|
||||
if (setAllPointsAttr && !SStrCmpI(setAllPointsAttr, "true", 0x7FFFFFFF)) {
|
||||
setAllPoints = 1;
|
||||
} else {
|
||||
setAllPoints = 0;
|
||||
}
|
||||
|
||||
const XMLNode* anchorsNode = node->GetChildByName("Anchors");
|
||||
|
||||
if (anchorsNode) {
|
||||
if (setAllPoints) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"SETALLPOINTS set to true in frame with anchors (ignored)"
|
||||
);
|
||||
}
|
||||
|
||||
for (XMLNode* anchorNode = anchorsNode->m_child; anchorNode; anchorNode = anchorNode->m_next) {
|
||||
const char* pointAttr = anchorNode->GetAttributeByName("point");
|
||||
|
||||
FRAMEPOINT point;
|
||||
|
||||
if (!pointAttr || !StringToFramePoint(pointAttr, point)) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Invalid anchor point in frame: %s",
|
||||
pointAttr
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* relativePointAttr = anchorNode->GetAttributeByName("relativePoint");
|
||||
|
||||
FRAMEPOINT relativePoint;
|
||||
|
||||
if (relativePointAttr && *relativePointAttr) {
|
||||
if (!StringToFramePoint(relativePointAttr, relativePoint)) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Invalid anchor point in frame: %s",
|
||||
relativePointAttr
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
relativePoint = point;
|
||||
}
|
||||
|
||||
const char* relativeToAttr = anchorNode->GetAttributeByName("relativeTo");
|
||||
|
||||
CLayoutFrame* relative;
|
||||
|
||||
if (!relativeToAttr || !*relativeToAttr) {
|
||||
relative = layoutParent;
|
||||
} else {
|
||||
relative = this->GetLayoutFrameByName(relativeToAttr);
|
||||
|
||||
if (!relative) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Couldn't find relative frame: %s",
|
||||
relativeToAttr
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (relative && relative == this) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame anchored to itself: %s",
|
||||
relativeToAttr
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode* offsetNode = anchorNode->GetChildByName("Offset");
|
||||
|
||||
float offsetX = 0.0f;
|
||||
float offsetY = 0.0f;
|
||||
|
||||
if (offsetNode) {
|
||||
LoadXML_Dimensions(offsetNode, offsetX, offsetY, status);
|
||||
} else {
|
||||
LoadXML_Dimensions(anchorNode, offsetX, offsetY, status);
|
||||
}
|
||||
|
||||
this->SetPoint(point, relative, relativePoint, offsetX, offsetY, 0);
|
||||
}
|
||||
|
||||
this->Resize(0);
|
||||
} else if (setAllPoints) {
|
||||
this->SetAllPoints(layoutParent, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::OnFrameResize() {
|
||||
CRect rect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (!this->CalculateRect(&rect)) {
|
||||
this->m_flags = (this->m_flags & ~0x1) | 0x8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
this->m_flags &= ~(0x4 | 0x8);
|
||||
|
||||
if (
|
||||
this->m_flags & 0x1
|
||||
&& AreEqual(rect.minX, this->m_rect.minX, WHOA_EPSILON_2)
|
||||
&& AreEqual(rect.maxX, this->m_rect.maxX, WHOA_EPSILON_2)
|
||||
&& AreEqual(rect.minY, this->m_rect.minY, WHOA_EPSILON_2)
|
||||
&& AreEqual(rect.maxY, this->m_rect.maxY, WHOA_EPSILON_2)
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
CRect prevRect = {
|
||||
this->m_rect.minY,
|
||||
this->m_rect.minX,
|
||||
this->m_rect.maxY,
|
||||
this->m_rect.maxX
|
||||
};
|
||||
|
||||
this->m_rect.minY = rect.minY;
|
||||
this->m_rect.minX = rect.minX;
|
||||
this->m_rect.maxY = rect.maxY;
|
||||
this->m_rect.maxX = rect.maxX;
|
||||
|
||||
this->m_flags |= 0x1;
|
||||
|
||||
this->OnFrameSizeChanged(prevRect);
|
||||
|
||||
return this->m_flags & 0x1;
|
||||
}
|
||||
|
||||
void CLayoutFrame::OnFrameSizeChanged(const CRect& rect) {
|
||||
for (auto node = this->m_resizeList.Head(); node; node = this->m_resizeList.Link(node)->Next()) {
|
||||
node->frame->Resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::OnProtectedAttach(CLayoutFrame* frame) {
|
||||
if (this->m_flags & 0x400) {
|
||||
frame->SetProtectFlag(0x400);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x300) {
|
||||
frame->SetProtectFlag(0x200);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::PtInFrameRect(const C2Vector& pt) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CLayoutFrame::RegisterResize(CLayoutFrame* frame, uint32_t dep) {
|
||||
for (auto node = this->m_resizeList.Head(); node; node = this->m_resizeList.Link(node)->Next()) {
|
||||
if (node->frame == frame) {
|
||||
node->dep |= dep;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto node = this->m_resizeList.NewNode(2, 0, 0x8);
|
||||
|
||||
node->frame = frame;
|
||||
node->dep = dep;
|
||||
|
||||
if (static_cast<CLayoutFrame*>(frame)->m_flags & 0x400) {
|
||||
this->SetProtectFlag(0x400);
|
||||
}
|
||||
|
||||
if (static_cast<CLayoutFrame*>(frame)->m_flags & (0x100 | 0x200)) {
|
||||
this->SetProtectFlag(0x200);
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::Resize(int32_t force) {
|
||||
if (force && !(this->m_flags & 0x8) && this->OnFrameResize()) {
|
||||
LayoutFrame::s_resizePendingList.UnlinkNode(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x4 && (this->m_flags & 0x2 || LayoutFrame::s_resizePendingList.IsLinked(this))) {
|
||||
this->m_resizeCounter = 6;
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_flags |= 0x4;
|
||||
|
||||
if (this->m_flags & 0x2) {
|
||||
for (auto node = this->m_resizeList.Head(); node; node = this->m_resizeList.Link(node)->Next()) {
|
||||
node->frame->Resize(0);
|
||||
}
|
||||
} else {
|
||||
this->AddToResizeList();
|
||||
}
|
||||
}
|
||||
|
||||
float CLayoutFrame::Right() {
|
||||
if (this->m_guard.right) {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
|
||||
this->m_guard.right = 1;
|
||||
|
||||
static FRAMEPOINT sidepoints[] = {
|
||||
FRAMEPOINT_TOPRIGHT,
|
||||
FRAMEPOINT_RIGHT,
|
||||
FRAMEPOINT_BOTTOMRIGHT
|
||||
};
|
||||
|
||||
float right = CFramePoint::UNDEFINED;
|
||||
this->GetFirstPointX(sidepoints, 3, right);
|
||||
|
||||
if (right == CFramePoint::UNDEFINED) {
|
||||
float size = this->GetWidth() * this->m_layoutScale;
|
||||
float opposite = this->Left();
|
||||
float center = this->CenterX();
|
||||
|
||||
right = SynthesizeSide(center, opposite, size);
|
||||
}
|
||||
|
||||
this->m_guard.right = 0;
|
||||
|
||||
return right;
|
||||
}
|
||||
|
||||
void CLayoutFrame::SetAllPoints(CLayoutFrame* relative, int32_t doResize) {
|
||||
STORM_ASSERT(relative);
|
||||
STORM_ASSERT(relative != this);
|
||||
|
||||
if (!relative->CanBeAnchorFor(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->FreePoints();
|
||||
|
||||
auto topLeft = this->m_points[FRAMEPOINT_TOPLEFT];
|
||||
|
||||
if (topLeft) {
|
||||
topLeft->SetRelative(relative, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f);
|
||||
} else {
|
||||
// TODO
|
||||
// CFramePoint::s_framePointHeap->GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CFramePoint), __FILE__, __LINE__, 0);
|
||||
topLeft = m ? new (m) CFramePoint(relative, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f) : nullptr;
|
||||
|
||||
this->m_points[FRAMEPOINT_TOPLEFT] = topLeft;
|
||||
}
|
||||
|
||||
auto bottomRight = this->m_points[FRAMEPOINT_BOTTOMRIGHT];
|
||||
|
||||
if (bottomRight) {
|
||||
bottomRight->SetRelative(relative, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f);
|
||||
} else {
|
||||
// TODO
|
||||
// CFramePoint::s_framePointHeap->GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CFramePoint), __FILE__, __LINE__, 0);
|
||||
bottomRight = m ? new (m) CFramePoint(relative, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f) : nullptr;
|
||||
|
||||
this->m_points[FRAMEPOINT_BOTTOMRIGHT] = bottomRight;
|
||||
}
|
||||
|
||||
this->m_flags &= ~0x8;
|
||||
relative->RegisterResize(this, (1 << FRAMEPOINT_TOPLEFT) | (1 << FRAMEPOINT_BOTTOMRIGHT));
|
||||
|
||||
if (doResize) {
|
||||
this->Resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::SetDeferredResize(int32_t enable) {
|
||||
if (enable) {
|
||||
this->m_flags |= 0x2;
|
||||
|
||||
if (LayoutFrame::s_resizePendingList.Link(this)->IsLinked()) {
|
||||
LayoutFrame::s_resizePendingList.UnlinkNode(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_flags &= ~0x2;
|
||||
|
||||
if (this->m_flags & 0x4) {
|
||||
this->Resize(1);
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::SetHeight(float height) {
|
||||
this->m_flags &= ~0x8;
|
||||
this->m_height = height;
|
||||
this->Resize(0);
|
||||
}
|
||||
|
||||
bool CLayoutFrame::SetLayoutScale(float scale, bool force) {
|
||||
STORM_ASSERT(scale);
|
||||
|
||||
if (force || (!AreEqual(this->m_layoutScale, scale, WHOA_EPSILON_1) && scale > 0.00000011920929)) {
|
||||
this->m_layoutScale = scale;
|
||||
this->m_rect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
this->m_flags &= ~0x1;
|
||||
|
||||
this->Resize(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CLayoutFrame::SetPoint(FRAMEPOINT point, CLayoutFrame* relative, FRAMEPOINT relativePoint, float offsetX, float offsetY, int32_t doResize) {
|
||||
STORM_ASSERT(relative);
|
||||
STORM_ASSERT(relative != this);
|
||||
|
||||
if (!relative->CanBeAnchorFor(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto framePoint = this->m_points[point];
|
||||
|
||||
if (framePoint) {
|
||||
if (framePoint->GetRelative()) {
|
||||
if (relative == framePoint->GetRelative()) {
|
||||
if (
|
||||
framePoint->m_framePoint != relativePoint
|
||||
|| !AreEqual(framePoint->m_offset.x, offsetX, WHOA_EPSILON_1)
|
||||
|| !AreEqual(framePoint->m_offset.y, offsetY, WHOA_EPSILON_1)
|
||||
) {
|
||||
framePoint->SetRelative(relative, relativePoint, offsetX, offsetY);
|
||||
this->m_flags &= ~0x8;
|
||||
|
||||
if (doResize) {
|
||||
this->Resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
framePoint->GetRelative()->UnregisterResize(this, 1 << point);
|
||||
}
|
||||
}
|
||||
|
||||
framePoint->SetRelative(relative, relativePoint, offsetX, offsetY);
|
||||
} else {
|
||||
// TODO
|
||||
// CFramePoint::s_framePointHeap->GetData(0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CFramePoint), __FILE__, __LINE__, 0);
|
||||
framePoint = m ? new (m) CFramePoint(relative, relativePoint, offsetX, offsetY) : nullptr;
|
||||
this->m_points[point] = framePoint;
|
||||
}
|
||||
|
||||
this->m_flags &= ~0x8;
|
||||
relative->RegisterResize(this, 1 << point);
|
||||
|
||||
if (doResize) {
|
||||
this->Resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CLayoutFrame::SetProtectFlag(uint32_t flag) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CLayoutFrame::SetWidth(float width) {
|
||||
this->m_flags &= ~0x8;
|
||||
this->m_width = width;
|
||||
this->Resize(0);
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::Sub488DB0(const FRAMEPOINT* const pointarray, int32_t elements, float& x) {
|
||||
for (int32_t i = 0; i < elements; i++) {
|
||||
FRAMEPOINT f = pointarray[i];
|
||||
CFramePoint* point = this->m_points[f];
|
||||
|
||||
if (point && !(point->m_flags & 0x8)) {
|
||||
x = point->X(this->m_layoutScale);
|
||||
|
||||
if (point->m_flags & 0x4) {
|
||||
x = CFramePoint::UNDEFINED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x != CFramePoint::UNDEFINED) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x = CFramePoint::UNDEFINED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CLayoutFrame::Sub488E40(const FRAMEPOINT* const pointarray, int32_t elements, float& y) {
|
||||
for (int32_t i = 0; i < elements; i++) {
|
||||
FRAMEPOINT f = pointarray[i];
|
||||
CFramePoint* point = this->m_points[f];
|
||||
|
||||
if (point && !(point->m_flags & 0x8)) {
|
||||
y = point->Y(this->m_layoutScale);
|
||||
|
||||
if (point->m_flags & 0x4) {
|
||||
y = CFramePoint::UNDEFINED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (y != CFramePoint::UNDEFINED) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
y = CFramePoint::UNDEFINED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CLayoutFrame::Top() {
|
||||
if (this->m_guard.top) {
|
||||
return CFramePoint::UNDEFINED;
|
||||
}
|
||||
|
||||
this->m_guard.top = 1;
|
||||
|
||||
static FRAMEPOINT sidepoints[] = {
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
FRAMEPOINT_TOP,
|
||||
FRAMEPOINT_TOPRIGHT
|
||||
};
|
||||
|
||||
float top = CFramePoint::UNDEFINED;
|
||||
this->GetFirstPointY(sidepoints, 3, top);
|
||||
|
||||
if (top == CFramePoint::UNDEFINED) {
|
||||
float size = this->GetHeight() * this->m_layoutScale;
|
||||
float opposite = this->Bottom();
|
||||
float center = this->CenterY();
|
||||
|
||||
top = SynthesizeSide(center, opposite, size);
|
||||
}
|
||||
|
||||
this->m_guard.top = 0;
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
void CLayoutFrame::UnflattenFrame(CLayoutFrame* frame) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CLayoutFrame::UnregisterResize(CLayoutFrame* frame, uint32_t dep) {
|
||||
for (auto node = this->m_resizeList.Head(); node; node = this->m_resizeList.Link(node)->Next()) {
|
||||
if (node->frame == frame) {
|
||||
node->dep &= ~dep;
|
||||
|
||||
if (node->dep) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<CLayoutFrame*>(frame)->m_flags & (0x100 | 0x200 | 0x400)) {
|
||||
this->SetProtectFlag(0x400);
|
||||
}
|
||||
|
||||
this->m_resizeList.DeleteNode(node);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
99
src/ui/CLayoutFrame.hpp
Normal file
99
src/ui/CLayoutFrame.hpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#ifndef UI_C_LAYOUT_FRAME_HPP
|
||||
#define UI_C_LAYOUT_FRAME_HPP
|
||||
|
||||
#include "ui/Types.hpp"
|
||||
#include "ui/Util.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
#include <tempest/Rect.hpp>
|
||||
|
||||
class CFramePoint;
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
|
||||
class CLayoutFrame {
|
||||
public:
|
||||
// Types
|
||||
struct FRAMENODE : public TSLinkedNode<FRAMENODE> {
|
||||
CLayoutFrame* frame;
|
||||
uint32_t dep;
|
||||
};
|
||||
|
||||
// Static functions
|
||||
static void ResizePending(void);
|
||||
|
||||
// Member variables
|
||||
TSLink<CLayoutFrame> resizeLink;
|
||||
CFramePoint* m_points[FRAMEPOINT_NUMPOINTS] = {};
|
||||
TSList<FRAMENODE, TSGetLink<FRAMENODE>> m_resizeList;
|
||||
struct {
|
||||
int32_t left : 1;
|
||||
int32_t top : 1;
|
||||
int32_t right : 1;
|
||||
int32_t bottom : 1;
|
||||
int32_t centerX : 1;
|
||||
int32_t centerY : 1;
|
||||
} m_guard;
|
||||
uint32_t m_resizeCounter : 8;
|
||||
uint32_t m_flags : 16;
|
||||
CRect m_rect;
|
||||
float m_width;
|
||||
float m_height;
|
||||
float m_layoutScale;
|
||||
float m_layoutDepth;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CLayoutFrame();
|
||||
virtual CLayoutFrame* GetLayoutParent(void);
|
||||
virtual bool SetLayoutScale(float, bool);
|
||||
virtual void SetWidth(float);
|
||||
virtual void SetHeight(float);
|
||||
virtual float GetWidth(void);
|
||||
virtual float GetHeight(void);
|
||||
virtual void GetClampRectInsets(float&, float&, float&, float&);
|
||||
virtual int32_t IsAttachmentOrigin(void);
|
||||
virtual CLayoutFrame* GetLayoutFrameByName(const char*);
|
||||
virtual int32_t IsObjectLoaded(void);
|
||||
virtual void OnFrameSizeChanged(const CRect&);
|
||||
|
||||
// Member functions
|
||||
CLayoutFrame();
|
||||
void AddToResizeList(void);
|
||||
float Bottom(void);
|
||||
int32_t CalculateRect(CRect*);
|
||||
bool CanBeAnchorFor(CLayoutFrame*);
|
||||
float CenterX(void);
|
||||
float CenterY(void);
|
||||
void ClearAllPoints(void);
|
||||
void DestroyLayout();
|
||||
void FreePoints(void);
|
||||
void GetFirstPointX(const FRAMEPOINT* const, int32_t, float&);
|
||||
void GetFirstPointY(const FRAMEPOINT* const, int32_t, float&);
|
||||
int32_t GetRect(CRect*);
|
||||
int32_t IsResizeDependency(CLayoutFrame*);
|
||||
uint32_t IsResizePending(void);
|
||||
float Left(void);
|
||||
void LoadXML(XMLNode*, CStatus*);
|
||||
int32_t OnFrameResize(void);
|
||||
void OnProtectedAttach(CLayoutFrame*);
|
||||
int32_t PtInFrameRect(const C2Vector&);
|
||||
void RegisterResize(CLayoutFrame*, uint32_t);
|
||||
void Resize(int32_t);
|
||||
float Right(void);
|
||||
void SetAllPoints(CLayoutFrame*, int32_t);
|
||||
void SetDeferredResize(int32_t);
|
||||
void SetPoint(FRAMEPOINT, CLayoutFrame*, FRAMEPOINT, float, float, int32_t);
|
||||
void SetProtectFlag(uint32_t);
|
||||
int32_t Sub488DB0(const FRAMEPOINT* const, int32_t, float&);
|
||||
int32_t Sub488E40(const FRAMEPOINT* const, int32_t, float&);
|
||||
float Top(void);
|
||||
void UnflattenFrame(CLayoutFrame*);
|
||||
void UnregisterResize(CLayoutFrame*, uint32_t);
|
||||
};
|
||||
|
||||
namespace LayoutFrame {
|
||||
// TODO put in better location
|
||||
extern STORM_EXPLICIT_LIST(CLayoutFrame, resizeLink) s_resizePendingList;
|
||||
}
|
||||
|
||||
#endif
|
||||
24
src/ui/CMakeLists.txt
Normal file
24
src/ui/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
add_library(ui STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(ui
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(ui
|
||||
PRIVATE
|
||||
event
|
||||
glue
|
||||
gx
|
||||
math
|
||||
model
|
||||
util
|
||||
PUBLIC
|
||||
common
|
||||
storm
|
||||
tempest
|
||||
)
|
||||
220
src/ui/CRenderBatch.cpp
Normal file
220
src/ui/CRenderBatch.cpp
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Font.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "gx/font/CGxStringBatch.hpp"
|
||||
#include <cstdlib>
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
int32_t SortByTexture(const void* a, const void* b) {
|
||||
auto meshA = reinterpret_cast<const CSimpleBatchedMesh*>(a);
|
||||
auto meshB = reinterpret_cast<const CSimpleBatchedMesh*>(b);
|
||||
|
||||
if (meshA->textureID != meshB->textureID) {
|
||||
return meshA->textureID - meshB->textureID;
|
||||
}
|
||||
|
||||
if (meshA->alphaMode != meshB->alphaMode) {
|
||||
if ((meshA->alphaMode >= 2 || !meshA->color) && (meshB->alphaMode >= 2 || !meshB->color)) {
|
||||
return meshA->alphaMode - meshB->alphaMode;
|
||||
} else if (meshA->alphaMode >= 2 || !meshA->color) {
|
||||
return meshA->alphaMode - 2;
|
||||
} else if (meshB->alphaMode >= 2 || !meshB->color) {
|
||||
return 2 - meshB->alphaMode;
|
||||
}
|
||||
}
|
||||
|
||||
if (meshA->shader != meshB->shader) {
|
||||
return meshA->shader - meshB->shader;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGxBlend CSimpleBatchedMesh::GetAlphaMode() {
|
||||
if (this->color && this->alphaMode < GxBlend_Alpha) {
|
||||
return GxBlend_Alpha;
|
||||
} else {
|
||||
return this->alphaMode;
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderBatch::Clear() {
|
||||
this->m_texturelist.SetCount(0);
|
||||
|
||||
if (this->m_stringbatch) {
|
||||
GxuFontDestroyBatch(this->m_stringbatch);
|
||||
this->m_stringbatch = nullptr;
|
||||
}
|
||||
|
||||
this->m_callbacks.DeleteAll();
|
||||
|
||||
this->m_count = 0;
|
||||
}
|
||||
|
||||
void CRenderBatch::Finish() {
|
||||
if (this->m_texturelist.Count() > 1) {
|
||||
qsort(this->m_texturelist.m_data, this->m_texturelist.Count(), sizeof(CSimpleBatchedMesh), SortByTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderBatch::Queue(CTexture* texture, EGxBlend alphaMode, int32_t posCount, const C3Vector* position, const C2Vector* texCoord, int32_t colorCount, const CImVector* color, int32_t idxCount, const uint16_t* indices, CGxShader* shader) {
|
||||
CGxTex* textureID = TextureGetGxTex(texture, 1, nullptr);
|
||||
|
||||
if (!textureID) {
|
||||
return;
|
||||
}
|
||||
|
||||
CSimpleBatchedMesh* mesh = this->m_texturelist.New();
|
||||
|
||||
mesh->texture = texture;
|
||||
mesh->textureID = textureID;
|
||||
mesh->alphaMode = alphaMode;
|
||||
mesh->shader = shader;
|
||||
mesh->posCount = posCount;
|
||||
mesh->position = const_cast<C3Vector*>(position);
|
||||
mesh->texCoord = const_cast<C2Vector*>(texCoord);
|
||||
mesh->color = const_cast<CImVector*>(color);
|
||||
mesh->colorCount = colorCount;
|
||||
mesh->indices = const_cast<uint16_t*>(indices);
|
||||
mesh->idxCount = idxCount;
|
||||
|
||||
// TODO
|
||||
// - implement atlas stuff
|
||||
mesh->onAtlas = 0;
|
||||
// mesh->onAtlas = TextureOnAtlas(texture);
|
||||
// if (onAtlas) {
|
||||
// TextureGetAtlasOffsetAndScale(mesh->texture, mesh->offset, mesh->scale);
|
||||
// }
|
||||
|
||||
this->m_count++;
|
||||
}
|
||||
|
||||
void CRenderBatch::QueueCallback(void (*callback)(void*), void* param) {
|
||||
auto node = this->m_callbacks.NewNode(2, 0, 0);
|
||||
node->callback = callback;
|
||||
node->param = param;
|
||||
|
||||
this->m_count++;
|
||||
}
|
||||
|
||||
void CRenderBatch::QueueFontString(CSimpleFontString* string) {
|
||||
CRect rect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (!string->GetRect(&rect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rect.minX > 1.0f || rect.maxX < 0.0f || rect.minY > 1.0f || rect.maxY < 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string->m_string) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto gxString = TextBlockGetStringPtr(string->m_string);
|
||||
|
||||
if (gxString) {
|
||||
if (!this->m_stringbatch) {
|
||||
this->m_stringbatch = GxuFontCreateBatch(false, false);
|
||||
STORM_ASSERT(this->m_stringbatch);
|
||||
}
|
||||
|
||||
GxuFontAddToBatch(this->m_stringbatch, gxString);
|
||||
this->m_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderBatch::QueueTexture(CSimpleTexture* texture) {
|
||||
CGxTex* gxTex = TextureGetGxTex(texture->m_texture, texture->m_nonBlocking ? 0 : 2, 0);
|
||||
|
||||
if (!gxTex) {
|
||||
// TODO
|
||||
// this->OnDelayedLoad();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture->IsResizePending()) {
|
||||
texture->Resize(1);
|
||||
}
|
||||
|
||||
if (texture->m_updateTexCoord) {
|
||||
C2Vector texCoord[4];
|
||||
texture->GetTexCoord(texCoord);
|
||||
|
||||
CRect rect = {
|
||||
texture->m_position[1].y,
|
||||
texture->m_position[0].x,
|
||||
texture->m_position[0].y,
|
||||
texture->m_position[2].x
|
||||
};
|
||||
|
||||
if (texture->m_horizTile) {
|
||||
float width = gxTex->GetWidth();
|
||||
float ddcWidth = CoordinateGetAspectCompensation() * 1024.0f * (rect.maxX - rect.minX);
|
||||
float ndcWidth = DDCToNDCWidth(ddcWidth);
|
||||
|
||||
if (width && ndcWidth > 0.0f) {
|
||||
if (texCoord[0].x != 0.0f) {
|
||||
texCoord[0].x = ndcWidth / width;
|
||||
}
|
||||
|
||||
if (texCoord[1].x != 0.0f) {
|
||||
texCoord[1].x = ndcWidth / width;
|
||||
}
|
||||
|
||||
if (texCoord[2].x != 0.0f) {
|
||||
texCoord[2].x = ndcWidth / width;
|
||||
}
|
||||
|
||||
if (texCoord[3].x != 0.0f) {
|
||||
texCoord[3].x = ndcWidth / width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (texture->m_vertTile) {
|
||||
float height = gxTex->GetHeight();
|
||||
float ddcHeight = CoordinateGetAspectCompensation() * 1024.0f * (rect.maxY - rect.minY);
|
||||
float ndcHeight = DDCToNDCWidth(ddcHeight);
|
||||
|
||||
if (height && ndcHeight > 0.0f) {
|
||||
if (texCoord[0].y != 0.0f) {
|
||||
texCoord[0].y = ndcHeight / height;
|
||||
}
|
||||
|
||||
if (texCoord[1].y != 0.0f) {
|
||||
texCoord[1].y = ndcHeight / height;
|
||||
}
|
||||
|
||||
if (texCoord[2].y != 0.0f) {
|
||||
texCoord[2].y = ndcHeight / height;
|
||||
}
|
||||
|
||||
if (texCoord[3].y != 0.0f) {
|
||||
texCoord[3].y = ndcHeight / height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture->m_updateTexCoord = 0;
|
||||
texture->SetTexCoord(texCoord);
|
||||
}
|
||||
|
||||
this->Queue(
|
||||
TextureGetTexturePtr(texture->m_texture),
|
||||
texture->m_alphaMode,
|
||||
4,
|
||||
texture->m_position,
|
||||
texture->m_texCoord,
|
||||
texture->m_colorCount > 1 ? 4 : 0,
|
||||
texture->m_colorCount ? texture->m_color : nullptr,
|
||||
6,
|
||||
CSimpleTexture::s_indices,
|
||||
texture->m_shader
|
||||
);
|
||||
}
|
||||
63
src/ui/CRenderBatch.hpp
Normal file
63
src/ui/CRenderBatch.hpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef UI_C_RENDER_BATCH_HPP
|
||||
#define UI_C_RENDER_BATCH_HPP
|
||||
|
||||
#include "gx/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Array.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CGxShader;
|
||||
class CGxStringBatch;
|
||||
class CGxTex;
|
||||
class CSimpleFontString;
|
||||
class CSimpleTexture;
|
||||
class CTexture;
|
||||
|
||||
class RENDERCALLBACKNODE : public TSLinkedNode<RENDERCALLBACKNODE> {
|
||||
public:
|
||||
void (*callback)(void*);
|
||||
void* param;
|
||||
};
|
||||
|
||||
class CSimpleBatchedMesh {
|
||||
public:
|
||||
// Member variables
|
||||
CTexture* texture;
|
||||
CGxTex* textureID;
|
||||
EGxBlend alphaMode;
|
||||
CGxShader* shader;
|
||||
int32_t posCount;
|
||||
C3Vector* position;
|
||||
C2Vector* texCoord;
|
||||
CImVector* color;
|
||||
int32_t colorCount;
|
||||
uint16_t* indices;
|
||||
int32_t idxCount;
|
||||
int32_t onAtlas;
|
||||
float atlasScale;
|
||||
C2Vector atlasOffset;
|
||||
|
||||
// Member functions
|
||||
EGxBlend GetAlphaMode(void);
|
||||
};
|
||||
|
||||
class CRenderBatch {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t m_count = 0;
|
||||
TSGrowableArray<CSimpleBatchedMesh> m_texturelist;
|
||||
CGxStringBatch* m_stringbatch = nullptr;
|
||||
TSList<RENDERCALLBACKNODE,TSGetLink<RENDERCALLBACKNODE>> m_callbacks;
|
||||
TSLink<CRenderBatch> renderLink;
|
||||
|
||||
// Member functions
|
||||
void Clear(void);
|
||||
void Finish(void);
|
||||
void Queue(CTexture*, EGxBlend, int32_t, const C3Vector*, const C2Vector*, int32_t, const CImVector*, int32_t, const uint16_t*, CGxShader*);
|
||||
void QueueCallback(void (*)(void*), void*);
|
||||
void QueueFontString(CSimpleFontString*);
|
||||
void QueueTexture(CSimpleTexture*);
|
||||
};
|
||||
|
||||
#endif
|
||||
131
src/ui/CScriptObject.cpp
Normal file
131
src/ui/CScriptObject.cpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#include "ui/CScriptObject.hpp"
|
||||
#include "ui/CScriptObjectScript.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <cstdint>
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
int32_t CScriptObject::s_objectType;
|
||||
const char* CScriptObject::s_objectTypeName = "Object";
|
||||
|
||||
void CScriptObject::RegisterScriptMethods(lua_State* L) {
|
||||
FrameScript_Object::FillScriptMethodTable(L, ScriptObjectMethods, NUM_SCRIPT_OBJECT_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CScriptObject* CScriptObject::GetScriptObjectByName(const char* name, int32_t type) {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, LUA_GLOBALSINDEX);
|
||||
|
||||
if (lua_type(L, -1) == 5) {
|
||||
lua_rawgeti(L, -1, 0);
|
||||
auto v4 = static_cast<CScriptObject*>(lua_touserdata(L, -1));
|
||||
lua_settop(L, -3);
|
||||
|
||||
if (v4 && v4->IsA(type)) {
|
||||
return v4;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
lua_settop(L, -2);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CScriptObject::~CScriptObject() {
|
||||
if (this->m_name.GetString()) {
|
||||
this->UnregisterScriptObject(this->m_name.GetString());
|
||||
this->m_name.Copy(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts the value of the name="" attribute into a fully resolved name.
|
||||
* @param source eg. $parentCategory from <FontString name="$parentCategory" />
|
||||
*/
|
||||
void CScriptObject::CreateName(const char* source, char* dest, uint32_t destsize) {
|
||||
// If source is not $parent, use it as the name
|
||||
uint32_t v5 = SStrLen("$parent");
|
||||
if (SStrCmpI(source, "$parent", v5)) {
|
||||
SStrCopy(dest, source, destsize);
|
||||
return;
|
||||
}
|
||||
|
||||
SStrCopy(dest, "", 0x7FFFFFFF);
|
||||
|
||||
CScriptObject* parent = this->GetScriptObjectParent();
|
||||
|
||||
if (parent) {
|
||||
const char* parentName;
|
||||
|
||||
while (1) {
|
||||
parentName = parent->GetName();
|
||||
|
||||
// Found a name
|
||||
if (parentName && *parentName) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Didn't find a name, go up a level
|
||||
parent = parent->GetScriptObjectParent();
|
||||
|
||||
// Out of levels to go up
|
||||
if (!parent) {
|
||||
goto LABEL_8;
|
||||
}
|
||||
}
|
||||
|
||||
SStrCopy(dest, parentName, destsize);
|
||||
}
|
||||
|
||||
LABEL_8:
|
||||
// Copy the part of the string after $parent into dest
|
||||
int v8 = SStrLen("$parent");
|
||||
SStrPack(dest, &source[v8], destsize);
|
||||
}
|
||||
|
||||
char* CScriptObject::GetName() {
|
||||
return this->m_name.m_str;
|
||||
}
|
||||
|
||||
void CScriptObject::PreLoadXML(XMLNode* node, CStatus* status) {
|
||||
const char* name = node->GetAttributeByName("name");
|
||||
|
||||
if (name && *name) {
|
||||
this->SetName(name);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptObject::SetName(const char* name) {
|
||||
// If name is already set, clear it out
|
||||
if (this->m_name.m_str) {
|
||||
this->UnregisterScriptObject(this->m_name.m_str);
|
||||
this->m_name.Copy(0);
|
||||
}
|
||||
|
||||
// Set the name
|
||||
if (name && *name) {
|
||||
// Deal with $parent in name
|
||||
char fullName[1024];
|
||||
this->CreateName(name, fullName, 1024);
|
||||
|
||||
this->m_name.Copy(fullName);
|
||||
|
||||
this->RegisterScriptObject(fullName);
|
||||
}
|
||||
}
|
||||
|
||||
const char* CScriptObject::GetObjectTypeName() {
|
||||
return CScriptObject::s_objectTypeName;
|
||||
}
|
||||
|
||||
bool CScriptObject::IsA(int32_t type) {
|
||||
return type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
bool CScriptObject::IsA(const char* typeName) {
|
||||
return SStrCmpI(typeName, CScriptObject::s_objectTypeName, 0x7FFFFFFFu) == 0;
|
||||
}
|
||||
38
src/ui/CScriptObject.hpp
Normal file
38
src/ui/CScriptObject.hpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef UI_C_SCRIPT_OBJECT_HPP
|
||||
#define UI_C_SCRIPT_OBJECT_HPP
|
||||
|
||||
#include "ui/FrameScript_Object.hpp"
|
||||
#include <cstdint>
|
||||
#include <common/String.hpp>
|
||||
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
|
||||
class CScriptObject : public FrameScript_Object {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_objectType;
|
||||
static const char* s_objectTypeName;
|
||||
|
||||
// Static functions
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
static CScriptObject* GetScriptObjectByName(const char*, int32_t);
|
||||
|
||||
// Member variables
|
||||
RCString m_name;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CScriptObject(void);
|
||||
virtual char* GetName(void);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual CScriptObject* GetScriptObjectParent(void) = 0;
|
||||
virtual bool IsA(const char*);
|
||||
virtual const char* GetObjectTypeName(void);
|
||||
|
||||
// Member functions
|
||||
void CreateName(const char*, char*, uint32_t);
|
||||
void PreLoadXML(XMLNode*, CStatus*);
|
||||
void SetName(const char*);
|
||||
};
|
||||
|
||||
#endif
|
||||
94
src/ui/CScriptObjectScript.cpp
Normal file
94
src/ui/CScriptObjectScript.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include "ui/CScriptObjectScript.hpp"
|
||||
#include "ui/CScriptObject.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CScriptObject_GetObjectType(lua_State* L) {
|
||||
if (!CScriptObject::s_objectType) {
|
||||
CScriptObject::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
CScriptObject* object = (CScriptObject*)FrameScript_GetObjectThis(L, CScriptObject::s_objectType);
|
||||
|
||||
const char* type = object->GetObjectTypeName();
|
||||
|
||||
lua_pushstring(L, type);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CScriptObject_IsObjectType(lua_State* L) {
|
||||
if (!CScriptObject::s_objectType) {
|
||||
CScriptObject::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
CScriptObject* object = (CScriptObject*)FrameScript_GetObjectThis(L, CScriptObject::s_objectType);
|
||||
|
||||
if (!lua_isstring(L, 2)) {
|
||||
const char* name = object->GetName();
|
||||
|
||||
if (!name) {
|
||||
name = "<unnamed>";
|
||||
}
|
||||
|
||||
luaL_error(L, "Usage: %s:IsObjectType(\"type\")", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* type = lua_tolstring(L, 2, 0);
|
||||
|
||||
if (object->IsA(type)) {
|
||||
lua_pushnumber(L, 1.0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CScriptObject_GetName(lua_State* L) {
|
||||
if (!CScriptObject::s_objectType) {
|
||||
CScriptObject::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
CScriptObject* object = (CScriptObject*)FrameScript_GetObjectThis(L, CScriptObject::s_objectType);
|
||||
|
||||
char* name = object->GetName();
|
||||
|
||||
if (name && *name) {
|
||||
lua_pushstring(L, name);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CScriptObject_GetParent(lua_State* L) {
|
||||
if (!CScriptObject::s_objectType) {
|
||||
CScriptObject::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
CScriptObject* object = (CScriptObject*)FrameScript_GetObjectThis(L, CScriptObject::s_objectType);
|
||||
|
||||
CScriptObject* parent = object->GetScriptObjectParent();
|
||||
|
||||
if (parent) {
|
||||
if (!parent->lua_registered) {
|
||||
parent->RegisterScriptObject(0);
|
||||
}
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, parent->lua_objectRef);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
FrameScript_Method ScriptObjectMethods[NUM_SCRIPT_OBJECT_SCRIPT_METHODS] = {
|
||||
{ "GetObjectType", &CScriptObject_GetObjectType },
|
||||
{ "IsObjectType", &CScriptObject_IsObjectType },
|
||||
{ "GetName", &CScriptObject_GetName },
|
||||
{ "GetParent", &CScriptObject_GetParent }
|
||||
};
|
||||
10
src/ui/CScriptObjectScript.hpp
Normal file
10
src/ui/CScriptObjectScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SCRIPT_OBJECT_SCRIPT_HPP
|
||||
#define UI_C_SCRIPT_OBJECT_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SCRIPT_OBJECT_SCRIPT_METHODS 4
|
||||
|
||||
extern FrameScript_Method ScriptObjectMethods[NUM_SCRIPT_OBJECT_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
122
src/ui/CScriptRegion.cpp
Normal file
122
src/ui/CScriptRegion.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include "ui/CScriptRegion.hpp"
|
||||
#include "ui/CScriptObject.hpp"
|
||||
#include "ui/CScriptRegionScript.hpp"
|
||||
#include "ui/CSimpleTop.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <common/XML.hpp>
|
||||
|
||||
int32_t CScriptRegion::s_objectType;
|
||||
const char* CScriptRegion::s_objectTypeName = "Region";
|
||||
|
||||
int32_t CScriptRegion::GetObjectType() {
|
||||
if (!CScriptRegion::s_objectType) {
|
||||
CScriptRegion::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CScriptRegion::s_objectType;
|
||||
}
|
||||
|
||||
void CScriptRegion::RegisterScriptMethods(lua_State* L) {
|
||||
CScriptObject::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, ScriptRegionMethods, NUM_SCRIPT_REGION_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
// TODO verify return type
|
||||
CLayoutFrame* CScriptRegion::GetLayoutParent() {
|
||||
if (!this->m_parent || this->m_parent->m_layoutScale == 0.0f) {
|
||||
return CSimpleTop::s_instance;
|
||||
} else {
|
||||
return (CLayoutFrame*)this->m_parent;
|
||||
}
|
||||
}
|
||||
|
||||
CLayoutFrame* CScriptRegion::GetLayoutFrameByName(const char* name) {
|
||||
char fullName[1024];
|
||||
this->CreateName(name, fullName, 1024);
|
||||
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
CScriptRegion* object = static_cast<CScriptRegion*>(this->GetScriptObjectByName(fullName, type));
|
||||
|
||||
return static_cast<CLayoutFrame*>(object);
|
||||
}
|
||||
|
||||
const char* CScriptRegion::GetObjectTypeName() {
|
||||
return CScriptRegion::s_objectTypeName;
|
||||
}
|
||||
|
||||
// TODO verify return type
|
||||
CScriptObject* CScriptRegion::GetScriptObjectParent() {
|
||||
return (CScriptObject*)(this->m_parent);
|
||||
}
|
||||
|
||||
bool CScriptRegion::IsA(int32_t type) {
|
||||
return type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
bool CScriptRegion::IsA(const char* typeName) {
|
||||
return !SStrCmpI(typeName, CScriptRegion::s_objectTypeName, 0x7FFFFFFF)
|
||||
|| !SStrCmpI(typeName, CScriptObject::s_objectTypeName, 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
bool CScriptRegion::IsDragging() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
void CScriptRegion::LoadXML(XMLNode* node, CStatus* status) {
|
||||
CLayoutFrame::LoadXML(node, status);
|
||||
|
||||
const char* parentKey = node->GetAttributeByName("parentKey");
|
||||
|
||||
if (parentKey && *parentKey) {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
|
||||
CScriptObject* parent = this->GetScriptObjectParent();
|
||||
|
||||
if (parent) {
|
||||
if (!parent->lua_registered) {
|
||||
parent->RegisterScriptObject(0);
|
||||
}
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, parent->lua_objectRef);
|
||||
lua_pushstring(L, parentKey);
|
||||
|
||||
if (!this->lua_registered) {
|
||||
this->RegisterScriptObject(0);
|
||||
}
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
||||
lua_settable(L, -3);
|
||||
lua_settop(L, -2);
|
||||
}
|
||||
}
|
||||
|
||||
this->LoadXML_Animations(node, status);
|
||||
}
|
||||
|
||||
void CScriptRegion::LoadXML_Animations(XMLNode* node, CStatus* status) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CScriptRegion::NotifyAnimBegin(CSimpleAnimGroup* animGroup) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CScriptRegion::NotifyAnimEnd(CSimpleAnimGroup* animGroup) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CScriptRegion::OnLayerUpdate(float elapsedSec) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool CScriptRegion::ProtectedFunctionsAllowed() {
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CScriptRegion::StopAnimating() {
|
||||
// TODO
|
||||
}
|
||||
52
src/ui/CScriptRegion.hpp
Normal file
52
src/ui/CScriptRegion.hpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef UI_C_SCRIPT_REGION_HPP
|
||||
#define UI_C_SCRIPT_REGION_HPP
|
||||
|
||||
#include "ui/CLayoutFrame.hpp"
|
||||
#include "ui/CScriptObject.hpp"
|
||||
|
||||
class C2Vector;
|
||||
class CSimpleAnimGroup;
|
||||
class CSimpleFrame;
|
||||
class XMLNode;
|
||||
struct lua_State;
|
||||
|
||||
class CScriptRegion : public CScriptObject, public CLayoutFrame {
|
||||
public:
|
||||
// Static members
|
||||
static int32_t s_objectType;
|
||||
static const char* s_objectTypeName;
|
||||
|
||||
// Static functions
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
static int32_t GetObjectType(void);
|
||||
|
||||
// Member variables
|
||||
CSimpleFrame* m_parent = NULL; // TODO verify type
|
||||
|
||||
// Virtual member functions
|
||||
virtual bool IsA(int32_t);
|
||||
virtual CScriptObject* GetScriptObjectParent(void);
|
||||
virtual bool IsA(const char*);
|
||||
virtual const char* GetObjectTypeName(void);
|
||||
virtual bool IsDragging(void);
|
||||
virtual void PreOnAnimUpdate(void) {};
|
||||
virtual void OnLayerUpdate(float);
|
||||
virtual void NotifyAnimBegin(CSimpleAnimGroup*);
|
||||
virtual void NotifyAnimEnd(CSimpleAnimGroup*);
|
||||
virtual void StopAnimating(void);
|
||||
virtual void AnimActivated(CSimpleAnimGroup*, int32_t, int32_t) {};
|
||||
virtual void AnimDeactivated(CSimpleAnimGroup*, int32_t, int32_t) {};
|
||||
virtual void AddAnimTranslation(CScriptRegion*, const C2Vector&) {};
|
||||
virtual void AddAnimRotation(CScriptRegion*, FRAMEPOINT, const C2Vector&, float) {};
|
||||
virtual void AddAnimScale(CScriptRegion*, FRAMEPOINT, const C2Vector&, const C2Vector&) {};
|
||||
virtual void AddAnimAlpha(CScriptRegion*, int16_t) {};
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual CLayoutFrame* GetLayoutParent(void);
|
||||
virtual CLayoutFrame* GetLayoutFrameByName(const char*);
|
||||
|
||||
// Member functions
|
||||
void LoadXML_Animations(XMLNode*, CStatus*);
|
||||
bool ProtectedFunctionsAllowed(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
387
src/ui/CScriptRegionScript.cpp
Normal file
387
src/ui/CScriptRegionScript.cpp
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
#include "ui/CScriptRegionScript.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "ui/FrameScript_Object.hpp"
|
||||
#include "ui/CScriptRegion.hpp"
|
||||
#include "ui/CSimpleTop.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
#include <tempest/Rect.hpp>
|
||||
|
||||
int32_t CScriptRegion_IsProtected(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_CanChangeProtectedState(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_SetParent(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetRect(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetCenter(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (region->IsResizePending()) {
|
||||
region->Resize(1);
|
||||
}
|
||||
|
||||
CRect rect;
|
||||
|
||||
if (region->GetRect(&rect)) {
|
||||
float width = rect.maxX - rect.minX;
|
||||
float v5 = CoordinateGetAspectCompensation() * 1024.0f * ((width * 0.5f + rect.minX) / region->m_layoutScale);
|
||||
float v6 = DDCToNDCWidth(v5);
|
||||
lua_pushnumber(L, v6);
|
||||
|
||||
float height = rect.maxY - rect.minY;
|
||||
float v7 = CoordinateGetAspectCompensation() * 1024.0f * ((height * 0.5f + rect.minY) / region->m_layoutScale);
|
||||
float v8 = DDCToNDCWidth(v7);
|
||||
lua_pushnumber(L, v8);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetLeft(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetRight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetTop(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetBottom(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetWidth(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float width = region->GetWidth();
|
||||
|
||||
if (width == 0.0 && !StringToBOOL(L, 2, 0)) {
|
||||
if (region->IsResizePending()) {
|
||||
region->Resize(1);
|
||||
}
|
||||
|
||||
CRect rect = { 0.0, 0.0, 0.0, 0.0 };
|
||||
|
||||
if (region->GetRect(&rect)) {
|
||||
width = (rect.maxX - rect.minX) / region->m_layoutScale;
|
||||
}
|
||||
}
|
||||
|
||||
float ddcWidth = CoordinateGetAspectCompensation() * 1024.0 * width;
|
||||
float ndcWidth = DDCToNDCWidth(ddcWidth);
|
||||
lua_pushnumber(L, ndcWidth);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_SetWidth(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!region->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetWidth(width)", region->GetDisplayName());
|
||||
}
|
||||
|
||||
float width = lua_tonumber(L, 2);
|
||||
float ndcWidth = width / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcWidth = NDCToDDCWidth(ndcWidth);
|
||||
|
||||
region->SetWidth(ddcWidth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetHeight(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float height = region->GetHeight();
|
||||
|
||||
if (height == 0.0f && !StringToBOOL(L, 2, 0)) {
|
||||
if (region->IsResizePending()) {
|
||||
region->Resize(1);
|
||||
}
|
||||
|
||||
CRect rect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (region->GetRect(&rect)) {
|
||||
height = (rect.maxY - rect.minY) / region->m_layoutScale;
|
||||
}
|
||||
}
|
||||
|
||||
float ddcHeight = CoordinateGetAspectCompensation() * 1024.0f * height;
|
||||
float ndcHeight = DDCToNDCWidth(ddcHeight);
|
||||
lua_pushnumber(L, ndcHeight);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_SetHeight(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!region->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetHeight(height)", region->GetDisplayName());
|
||||
}
|
||||
|
||||
float height = lua_tonumber(L, 2);
|
||||
float ndcHeight = height / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcHeight = NDCToDDCWidth(ndcHeight);
|
||||
|
||||
region->SetHeight(ddcHeight);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_SetSize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetSize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetNumPoints(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetPoint(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_SetPoint(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!region->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isstring(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetPoint(\"point\" [, region or nil] [, \"relativePoint\"] [, offsetX, offsetY])", region->GetDisplayName());
|
||||
}
|
||||
|
||||
auto relative = region->GetLayoutParent();
|
||||
|
||||
const char* pointStr = lua_tolstring(L, 2, 0);
|
||||
FRAMEPOINT point;
|
||||
|
||||
if (!StringToFramePoint(pointStr, point)) {
|
||||
return luaL_error(L, "%s:SetPoint(): Unknown region point", region->GetDisplayName());
|
||||
}
|
||||
|
||||
int32_t argsIndex = 3;
|
||||
|
||||
if (lua_type(L, 3) == LUA_TSTRING) {
|
||||
const char* name = lua_tolstring(L, 3, 0);
|
||||
relative = region->GetLayoutFrameByName(name);
|
||||
|
||||
argsIndex++;
|
||||
} else if (lua_type(L, 3) == LUA_TTABLE) {
|
||||
lua_rawgeti(L, 3, 0);
|
||||
|
||||
auto r = reinterpret_cast<CScriptRegion*>(lua_touserdata(L, -1));
|
||||
relative = r ? static_cast<CLayoutFrame*>(r) : nullptr;
|
||||
|
||||
lua_settop(L, -2);
|
||||
|
||||
argsIndex++;
|
||||
} else if (lua_type(L, 3) == LUA_TNIL) {
|
||||
relative = CSimpleTop::s_instance;
|
||||
|
||||
argsIndex++;
|
||||
}
|
||||
|
||||
if (!relative) {
|
||||
const char* name = lua_tolstring(L, 3, 0);
|
||||
return luaL_error(L, "%s:SetPoint(): Couldn't find region named '%s'", region->GetDisplayName(), name);
|
||||
}
|
||||
|
||||
if (relative == region) {
|
||||
return luaL_error(L, "%s:SetPoint(): trying to anchor to itself", region->GetDisplayName());
|
||||
}
|
||||
|
||||
if (relative->IsResizeDependency(region)) {
|
||||
return luaL_error(L, "%s:SetPoint(): %s is dependent on this", region->GetDisplayName(), static_cast<CScriptRegion*>(relative)->GetDisplayName());
|
||||
}
|
||||
|
||||
FRAMEPOINT relativePoint = point;
|
||||
|
||||
if (lua_type(L, argsIndex) == LUA_TSTRING) {
|
||||
const char* relativePointStr = lua_tolstring(L, argsIndex, 0);
|
||||
|
||||
if (!StringToFramePoint(relativePointStr, relativePoint)) {
|
||||
return luaL_error(L, "%s:SetPoint(): Unknown region point", region->GetDisplayName());
|
||||
}
|
||||
|
||||
argsIndex++;
|
||||
}
|
||||
|
||||
float offsetX = 0.0f;
|
||||
float offsetY = 0.0f;
|
||||
|
||||
if (lua_isnumber(L, argsIndex) && lua_isnumber(L, argsIndex + 1)) {
|
||||
float x = lua_tonumber(L, argsIndex);
|
||||
float ndcX = x / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcX = NDCToDDCWidth(ndcX);
|
||||
|
||||
float y = lua_tonumber(L, argsIndex + 1);
|
||||
float ndcY = y / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcY = NDCToDDCWidth(ndcY);
|
||||
|
||||
offsetX = ddcX;
|
||||
offsetY = ddcY;
|
||||
}
|
||||
|
||||
region->SetPoint(point, relative, relativePoint, offsetX, offsetY, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_SetAllPoints(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!region->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto relative = region->GetLayoutParent();
|
||||
|
||||
if (lua_isstring(L, 2)) {
|
||||
const char* name = lua_tolstring(L, 2, 0);
|
||||
relative = region->GetLayoutFrameByName(name);
|
||||
} else if (lua_type(L, 2) == LUA_TTABLE) {
|
||||
lua_rawgeti(L, 2, 0);
|
||||
|
||||
auto r = reinterpret_cast<CScriptRegion*>(lua_touserdata(L, -1));
|
||||
relative = r ? static_cast<CLayoutFrame*>(r) : nullptr;
|
||||
|
||||
lua_settop(L, -2);
|
||||
} else if (lua_type(L, 2) == LUA_TNIL) {
|
||||
relative = CSimpleTop::s_instance;
|
||||
}
|
||||
|
||||
if (!relative) {
|
||||
const char* name = lua_tolstring(L, 2, 0);
|
||||
return luaL_error(L, "%s:SetAllPoints(): Couldn't find region named '%s'", region->GetDisplayName(), name);
|
||||
}
|
||||
|
||||
if (relative == region) {
|
||||
return luaL_error(L, "%s:SetAllPoints(): trying to anchor to itself", region->GetDisplayName());
|
||||
}
|
||||
|
||||
if (relative->IsResizeDependency(region)) {
|
||||
return luaL_error(L, "%s:SetAllPoints(): %s is dependent on this", region->GetDisplayName(), static_cast<CScriptRegion*>(relative)->GetDisplayName());
|
||||
}
|
||||
|
||||
region->SetAllPoints(relative, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_ClearAllPoints(lua_State* L) {
|
||||
int32_t type = CScriptRegion::GetObjectType();
|
||||
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (region->ProtectedFunctionsAllowed()) {
|
||||
region->ClearAllPoints();
|
||||
} else {
|
||||
// TODO
|
||||
// void* v3 = CSimpleTop::s_instance->Function4692;
|
||||
|
||||
// if (v3) {
|
||||
// v3(object);
|
||||
// }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_CreateAnimationGroup(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_GetAnimationGroups(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_StopAnimating(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_IsDragging(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CScriptRegion_IsMouseOver(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method ScriptRegionMethods[NUM_SCRIPT_REGION_SCRIPT_METHODS] = {
|
||||
{ "IsProtected", &CScriptRegion_IsProtected },
|
||||
{ "CanChangeProtectedState", &CScriptRegion_CanChangeProtectedState },
|
||||
{ "SetParent", &CScriptRegion_SetParent },
|
||||
{ "GetRect", &CScriptRegion_GetRect },
|
||||
{ "GetCenter", &CScriptRegion_GetCenter },
|
||||
{ "GetLeft", &CScriptRegion_GetLeft },
|
||||
{ "GetRight", &CScriptRegion_GetRight },
|
||||
{ "GetTop", &CScriptRegion_GetTop },
|
||||
{ "GetBottom", &CScriptRegion_GetBottom },
|
||||
{ "GetWidth", &CScriptRegion_GetWidth },
|
||||
{ "SetWidth", &CScriptRegion_SetWidth },
|
||||
{ "GetHeight", &CScriptRegion_GetHeight },
|
||||
{ "SetHeight", &CScriptRegion_SetHeight },
|
||||
{ "SetSize", &CScriptRegion_SetSize },
|
||||
{ "GetSize", &CScriptRegion_GetSize },
|
||||
{ "GetNumPoints", &CScriptRegion_GetNumPoints },
|
||||
{ "GetPoint", &CScriptRegion_GetPoint },
|
||||
{ "SetPoint", &CScriptRegion_SetPoint },
|
||||
{ "SetAllPoints", &CScriptRegion_SetAllPoints },
|
||||
{ "ClearAllPoints", &CScriptRegion_ClearAllPoints },
|
||||
{ "CreateAnimationGroup", &CScriptRegion_CreateAnimationGroup },
|
||||
{ "GetAnimationGroups", &CScriptRegion_GetAnimationGroups },
|
||||
{ "StopAnimating", &CScriptRegion_StopAnimating },
|
||||
{ "IsDragging", &CScriptRegion_IsDragging },
|
||||
{ "IsMouseOver", &CScriptRegion_IsMouseOver }
|
||||
};
|
||||
10
src/ui/CScriptRegionScript.hpp
Normal file
10
src/ui/CScriptRegionScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SCRIPT_REGION_SCRIPT_HPP
|
||||
#define UI_C_SCRIPT_REGION_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SCRIPT_REGION_SCRIPT_METHODS 25
|
||||
|
||||
extern FrameScript_Method ScriptRegionMethods[NUM_SCRIPT_REGION_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
617
src/ui/CSimpleButton.cpp
Normal file
617
src/ui/CSimpleButton.cpp
Normal file
|
|
@ -0,0 +1,617 @@
|
|||
#include "ui/CSimpleButton.hpp"
|
||||
#include "event/Input.hpp"
|
||||
#include "ui/CSimpleButtonScript.hpp"
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "ui/CSimpleTop.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
int32_t CSimpleButton::s_metatable;
|
||||
int32_t CSimpleButton::s_objectType;
|
||||
|
||||
void CSimpleButton::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleButton::RegisterScriptMethods);
|
||||
CSimpleButton::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton::GetObjectType() {
|
||||
if (!CSimpleButton::s_objectType) {
|
||||
CSimpleButton::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleButton::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleButton::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleFrame::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleButtonMethods, NUM_SIMPLE_BUTTON_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleButton::CSimpleButton(CSimpleFrame* parent) : CSimpleFrame(parent) {
|
||||
this->m_pressedOffset = { 0.001, -0.001 };
|
||||
|
||||
this->m_textures[BUTTONSTATE_DISABLED] = nullptr;
|
||||
this->m_textures[BUTTONSTATE_NORMAL] = nullptr;
|
||||
this->m_textures[BUTTONSTATE_PUSHED] = nullptr;
|
||||
|
||||
this->Enable(1);
|
||||
this->EnableEvent(SIMPLE_EVENT_MOUSE, -1);
|
||||
this->SetFrameFlag(0x10000, 1);
|
||||
}
|
||||
|
||||
void CSimpleButton::Enable(int32_t enabled) {
|
||||
if (enabled) {
|
||||
if (this->m_state != BUTTONSTATE_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->SetButtonState(BUTTONSTATE_NORMAL, 0);
|
||||
|
||||
if (this == this->m_top->m_mouseFocus) {
|
||||
this->OnLayerCursorEnter(0);
|
||||
}
|
||||
|
||||
if (this->m_highlightLocked) {
|
||||
this->EnableDrawLayer(DRAWLAYER_HIGHLIGHT);
|
||||
}
|
||||
} else {
|
||||
if (this->m_state == BUTTONSTATE_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this == this->m_top->m_mouseFocus) {
|
||||
this->OnLayerCursorExit(0, 1);
|
||||
}
|
||||
|
||||
this->DisableDrawLayer(DRAWLAYER_HIGHLIGHT);
|
||||
this->SetButtonState(BUTTONSTATE_DISABLED, 0);
|
||||
}
|
||||
|
||||
this->SetFrameFlag(0x400, enabled == 0);
|
||||
|
||||
auto& script = enabled ? this->m_onEnable : this->m_onDisable;
|
||||
|
||||
if (script.luaRef && !this->m_loading) {
|
||||
this->RunScript(script, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
FrameScript_Object::ScriptIx* CSimpleButton::GetScriptByName(const char* name, ScriptData& data) {
|
||||
auto parentScript = CSimpleFrame::GetScriptByName(name, data);
|
||||
|
||||
if (parentScript) {
|
||||
return parentScript;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "PreClick", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,button,down) %s end";
|
||||
return &this->m_preClick;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnClick", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,button,down) %s end";
|
||||
return &this->m_onClick;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "PostClick", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,button,down) %s end";
|
||||
return &this->m_postClick;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnDoubleClick", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,button) %s end";
|
||||
return &this->m_onDoubleClick;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton::GetScriptMetaTable() {
|
||||
return CSimpleButton::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleButton::IsA(int32_t type) {
|
||||
return type == CSimpleButton::s_objectType
|
||||
|| type == CSimpleFrame::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleButton::LoadXML(XMLNode* node, CStatus* status) {
|
||||
CSimpleFrame::LoadXML(node, status);
|
||||
|
||||
CSimpleFontString* buttonText = nullptr;
|
||||
|
||||
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "NormalTexture", STORM_MAX_STR)) {
|
||||
CSimpleTexture* texture = LoadXML_Texture(child, this, status);
|
||||
this->SetStateTexture(BUTTONSTATE_NORMAL, texture);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "PushedTexture", STORM_MAX_STR)) {
|
||||
CSimpleTexture* texture = LoadXML_Texture(child, this, status);
|
||||
this->SetStateTexture(BUTTONSTATE_PUSHED, texture);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "DisabledTexture", STORM_MAX_STR)) {
|
||||
CSimpleTexture* texture = LoadXML_Texture(child, this, status);
|
||||
this->SetStateTexture(BUTTONSTATE_DISABLED, texture);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "HighlightTexture", STORM_MAX_STR)) {
|
||||
CSimpleTexture* texture = LoadXML_Texture(child, this, status);
|
||||
this->SetHighlight(texture, texture->m_alphaMode);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "ButtonText", STORM_MAX_STR)) {
|
||||
buttonText = LoadXML_String(child, this, status);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "NormalFont", STORM_MAX_STR)) {
|
||||
const char* fontName = child->GetAttributeByName("style");
|
||||
|
||||
if (fontName && *fontName) {
|
||||
CSimpleFont* font = CSimpleFont::GetFont(fontName, 0);
|
||||
|
||||
this->m_normalFont = font;
|
||||
|
||||
if (!font) {
|
||||
status->Add(STATUS_WARNING, "Couldn't find NORMAL font: %s", fontName);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "DisabledFont", STORM_MAX_STR)) {
|
||||
const char* fontName = child->GetAttributeByName("style");
|
||||
|
||||
if (fontName && *fontName) {
|
||||
CSimpleFont* font = CSimpleFont::GetFont(fontName, 0);
|
||||
|
||||
this->m_disabledFont = font;
|
||||
|
||||
if (!font) {
|
||||
status->Add(STATUS_WARNING, "Couldn't find DISABLED font: %s", fontName);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "HighlightFont", STORM_MAX_STR)) {
|
||||
const char* fontName = child->GetAttributeByName("style");
|
||||
|
||||
if (fontName && *fontName) {
|
||||
CSimpleFont* font = CSimpleFont::GetFont(fontName, 0);
|
||||
|
||||
this->m_highlightFont = font;
|
||||
|
||||
if (!font) {
|
||||
status->Add(STATUS_WARNING, "Couldn't find HIGHLIGHT font: %s", fontName);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "NormalColor", STORM_MAX_STR)) {
|
||||
// TODO
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "DisabledColor", STORM_MAX_STR)) {
|
||||
// TODO
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "HighlightColor", STORM_MAX_STR)) {
|
||||
// TODO
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "PushedTextOffset", STORM_MAX_STR)) {
|
||||
float x, y;
|
||||
|
||||
if (LoadXML_Dimensions(child, x, y, status)) {
|
||||
C2Vector offset = { x, y };
|
||||
this->SetPressedOffset(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buttonText) {
|
||||
this->SetFontString(buttonText);
|
||||
} else {
|
||||
// TODO
|
||||
// int32_t v24 = (this + 162) << 28 >> 28;
|
||||
// this->UpdateTextState(v24);
|
||||
}
|
||||
|
||||
const char* textRef = node->GetAttributeByName("text");
|
||||
|
||||
if (textRef && *textRef) {
|
||||
const char* text = FrameScript_GetText(textRef, -1, GENDER_NOT_APPLICABLE);
|
||||
|
||||
if (!text || !*text) {
|
||||
text = textRef;
|
||||
}
|
||||
|
||||
this->SetText(text);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - registerForClicks
|
||||
|
||||
// TODO
|
||||
// - motionScriptsWhileDisabled
|
||||
}
|
||||
|
||||
void CSimpleButton::LockHighlight(int32_t lock) {
|
||||
CSimpleFrame::LockHighlight(lock);
|
||||
this->UpdateTextState(this->m_state);
|
||||
}
|
||||
|
||||
void CSimpleButton::OnClick(const char* btn, int32_t a3) {
|
||||
// TODO
|
||||
// - also check this->m_unk != 1
|
||||
if (this->m_state != BUTTONSTATE_DISABLED) {
|
||||
// TODO
|
||||
// const char* old1234 = this->m_top->m_char1234;
|
||||
// this->m_top->m_char1234 = btn;
|
||||
|
||||
// TODO
|
||||
// this->m_unk = 1;
|
||||
|
||||
this->RunOnClickScript(btn, a3);
|
||||
|
||||
// TODO
|
||||
// this->m_unk = 0;
|
||||
|
||||
// TODO
|
||||
// this->m_top->m_char1234 = old1234;
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleButton::OnDoubleClick(const char* btn) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleButton::OnLayerCursorEnter(int32_t a2) {
|
||||
if (this->m_state == BUTTONSTATE_DISABLED) {
|
||||
// TODO
|
||||
// if (this->GetMotionScriptsWhileDisabled()) {
|
||||
// if (this->m_tooltip) {
|
||||
// this->m_tooltip->Show();
|
||||
// }
|
||||
//
|
||||
// this->RunOnEnterScript(a2);
|
||||
// }
|
||||
} else {
|
||||
CSimpleFrame::OnLayerCursorEnter(a2);
|
||||
this->UpdateTextState(this->m_state);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleButton::OnLayerCursorExit(int32_t a2, int32_t a3) {
|
||||
if (this->m_state == BUTTONSTATE_DISABLED) {
|
||||
// TODO
|
||||
// if (this->GetMotionScriptsWhileDisabled()) {
|
||||
// if (this->m_tooltip) {
|
||||
// this->m_tooltip->Hide();
|
||||
// }
|
||||
//
|
||||
// this->RunOnLeaveScript(a2);
|
||||
// }
|
||||
} else {
|
||||
CSimpleFrame::OnLayerCursorExit(a2, a3);
|
||||
this->UpdateTextState(this->m_state);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleButton::OnLayerHide() {
|
||||
if (this->m_state && !this->m_stateLocked) {
|
||||
this->SetButtonState(BUTTONSTATE_NORMAL, 0);
|
||||
}
|
||||
|
||||
CSimpleFrame::OnLayerHide();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton::OnLayerMouseDown(const CMouseEvent& evt, const char* btn) {
|
||||
if (CSimpleFrame::OnLayerMouseDown(evt, btn)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
C2Vector pt = { evt.x, evt.y };
|
||||
|
||||
if ((btn || this->TestHitRect(pt)) && this->m_state != BUTTONSTATE_DISABLED) {
|
||||
int32_t v7 = btn ? 0x7FFFFFFF : evt.button;
|
||||
|
||||
if (this->m_clickAction & v7) {
|
||||
if (!btn) {
|
||||
btn = GetButtonName(evt.button);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->m_top->m_int1241 = 1;
|
||||
|
||||
this->OnClick(btn, 1);
|
||||
|
||||
// TODO
|
||||
// this->m_top->m_int1241 = 0;
|
||||
}
|
||||
|
||||
if (!this->m_stateLocked && this->m_state != BUTTONSTATE_DISABLED) {
|
||||
this->SetButtonState(BUTTONSTATE_PUSHED, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton::OnLayerMouseUp(const CMouseEvent& evt, const char* btn) {
|
||||
if (CSimpleFrame::OnLayerMouseUp(evt, btn)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this->m_state != BUTTONSTATE_PUSHED) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
C2Vector pt = { evt.x, evt.y };
|
||||
|
||||
if (btn || this->TestHitRect(pt)) {
|
||||
uint64_t v6 = btn ? 0xFFFFFFFF80000000 : static_cast<uint64_t>(evt.button) << 31;
|
||||
|
||||
if (this->m_clickAction & v6) {
|
||||
if (!btn) {
|
||||
btn = GetButtonName(evt.button);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->m_top->m_int1241 = 1;
|
||||
|
||||
uint32_t currentTime = OsGetAsyncTimeMs();
|
||||
|
||||
if (this->m_onDoubleClick.luaRef && this->m_doubleClickTime && currentTime - this->m_doubleClickTime <= 300) {
|
||||
this->OnDoubleClick(btn);
|
||||
this->m_doubleClickTime = 0;
|
||||
} else {
|
||||
this->OnClick(btn, 0);
|
||||
this->m_doubleClickTime = currentTime;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->m_top->m_int1241 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->m_stateLocked && this->m_state != BUTTONSTATE_DISABLED) {
|
||||
this->SetButtonState(BUTTONSTATE_NORMAL, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSimpleButton::RunOnClickScript(const char* btn, int32_t down) {
|
||||
if (this->m_preClick.luaRef) {
|
||||
auto L = FrameScript_GetContext();
|
||||
lua_pushstring(L, btn);
|
||||
lua_pushboolean(L, down);
|
||||
|
||||
this->RunScript(this->m_preClick, 2, 0);
|
||||
}
|
||||
|
||||
if (this->m_onClick.luaRef) {
|
||||
auto L = FrameScript_GetContext();
|
||||
lua_pushstring(L, btn);
|
||||
lua_pushboolean(L, down);
|
||||
|
||||
this->RunScript(this->m_onClick, 2, 0);
|
||||
}
|
||||
|
||||
if (this->m_postClick.luaRef) {
|
||||
auto L = FrameScript_GetContext();
|
||||
lua_pushstring(L, btn);
|
||||
lua_pushboolean(L, down);
|
||||
|
||||
this->RunScript(this->m_postClick, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleButton::SetButtonState(CSimpleButtonState state, int32_t stateLocked) {
|
||||
this->m_stateLocked = stateLocked;
|
||||
|
||||
if (state == this->m_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_activeTexture && (this->m_textures[state] || state == BUTTONSTATE_NORMAL)) {
|
||||
this->m_activeTexture->Hide();
|
||||
this->m_activeTexture = nullptr;
|
||||
}
|
||||
|
||||
if (this->m_textures[state]) {
|
||||
this->m_activeTexture = this->m_textures[state];
|
||||
this->m_activeTexture->Show();
|
||||
}
|
||||
|
||||
this->UpdateTextState(state);
|
||||
|
||||
this->m_state = state;
|
||||
}
|
||||
|
||||
void CSimpleButton::SetClickAction(uint64_t action) {
|
||||
this->m_clickAction = action;
|
||||
}
|
||||
|
||||
void CSimpleButton::SetHighlight(CSimpleTexture* texture, EGxBlend blend) {
|
||||
if (texture == this->m_highlightTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_highlightTexture) {
|
||||
delete this->m_highlightTexture;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texture->SetFrame(this, DRAWLAYER_HIGHLIGHT, 1);
|
||||
texture->SetBlendMode(blend);
|
||||
}
|
||||
|
||||
this->m_highlightTexture = texture;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton::SetHighlight(const char* texFile, EGxBlend blendMode) {
|
||||
if (this->m_highlightTexture) {
|
||||
this->m_highlightTexture->SetTexture(texFile, false, false, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
this->m_highlightTexture->SetBlendMode(blendMode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO void* m = CDataAllocator::GetData(CSimpleTexture::s_allocator, 0, __FILE__, __LINE__);
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
auto texture = new (m) CSimpleTexture(this, DRAWLAYER_HIGHLIGHT, 1);
|
||||
|
||||
if (!texture->SetTexture(texFile, false, false, CSimpleTexture::s_textureFilterMode, ImageMode_UI)) {
|
||||
delete texture;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture->SetAllPoints(this, 1);
|
||||
texture->SetBlendMode(blendMode);
|
||||
this->m_highlightTexture = texture;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSimpleButton::SetFontString(CSimpleFontString* text) {
|
||||
if (this->m_text == text) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_text) {
|
||||
delete this->m_text;
|
||||
}
|
||||
|
||||
if (text) {
|
||||
text->SetFrame(this, 2, 1);
|
||||
}
|
||||
|
||||
if (!text->Sub482AC0()) {
|
||||
auto font = this->m_normalFont;
|
||||
|
||||
int32_t styleFlags;
|
||||
|
||||
if (font) {
|
||||
styleFlags = font->m_attributes.m_styleFlags;
|
||||
} else {
|
||||
styleFlags = 0;
|
||||
}
|
||||
|
||||
float offsetX = 0.0f;
|
||||
float offsetY = 0.0f;
|
||||
|
||||
if (styleFlags & 0x1) {
|
||||
text->SetPoint(FRAMEPOINT_LEFT, this, FRAMEPOINT_LEFT, offsetX, offsetY, 1);
|
||||
} else if (styleFlags & 0x4) {
|
||||
text->SetPoint(FRAMEPOINT_RIGHT, this, FRAMEPOINT_RIGHT, offsetX, offsetY, 1);
|
||||
} else {
|
||||
text->SetPoint(FRAMEPOINT_CENTER, this, FRAMEPOINT_CENTER, offsetX, offsetY, 1);
|
||||
}
|
||||
}
|
||||
|
||||
this->m_text = text;
|
||||
|
||||
this->UpdateTextState(this->m_state);
|
||||
}
|
||||
|
||||
void CSimpleButton::SetPressedOffset(C2Vector& offset) {
|
||||
this->m_pressedOffset = offset;
|
||||
}
|
||||
|
||||
void CSimpleButton::SetStateTexture(CSimpleButtonState state, CSimpleTexture* texture) {
|
||||
if (this->m_textures[state] == texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_textures[state] == this->m_activeTexture) {
|
||||
this->m_activeTexture = nullptr;
|
||||
}
|
||||
|
||||
if (this->m_textures[state]) {
|
||||
delete this->m_textures[state];
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texture->SetFrame(this, DRAWLAYER_ARTWORK, 0);
|
||||
}
|
||||
|
||||
this->m_textures[state] = texture;
|
||||
|
||||
if (texture) {
|
||||
if (state == this->m_state) {
|
||||
this->m_activeTexture = texture;
|
||||
texture->Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CSimpleButton::SetStateTexture(CSimpleButtonState state, const char* texFile) {
|
||||
if (this->m_textures[state]) {
|
||||
this->m_textures[state]->SetTexture(texFile, false, false, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO void* m = CDataAllocator::GetData(CSimpleTexture::s_allocator, 0, __FILE__, __LINE__);
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
||||
auto texture = new (m) CSimpleTexture(nullptr, 2, 1);
|
||||
|
||||
if (texture->SetTexture(texFile, false, false, CSimpleTexture::s_textureFilterMode, ImageMode_UI)) {
|
||||
texture->SetAllPoints(this, 1);
|
||||
this->SetStateTexture(state, texture);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
delete texture;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSimpleButton::SetText(const char* string) {
|
||||
if ((string && *string) || this->m_text) {
|
||||
if (!this->m_text) {
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleFontString::s_allocator, 0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleFontString), __FILE__, __LINE__, 0x0);
|
||||
|
||||
CSimpleFontString* text;
|
||||
|
||||
if (m) {
|
||||
text = new (m) CSimpleFontString(this, 2, 1);
|
||||
} else {
|
||||
text = nullptr;
|
||||
}
|
||||
|
||||
this->SetFontString(text);
|
||||
}
|
||||
|
||||
this->m_text->SetText(string, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleButton::UpdateTextState(CSimpleButtonState state) {
|
||||
if (!this->m_text) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == BUTTONSTATE_PUSHED) {
|
||||
this->m_text->SetJustificationOffset(this->m_pressedOffset.x, this->m_pressedOffset.y);
|
||||
} else {
|
||||
this->m_text->SetJustificationOffset(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
if (state == BUTTONSTATE_DISABLED) {
|
||||
this->m_text->SetFontObject(this->m_disabledFont);
|
||||
} else if (this->m_drawenabled[DRAWLAYER_HIGHLIGHT]) {
|
||||
this->m_text->SetFontObject(this->m_highlightFont);
|
||||
} else {
|
||||
this->m_text->SetFontObject(this->m_normalFont);
|
||||
}
|
||||
}
|
||||
77
src/ui/CSimpleButton.hpp
Normal file
77
src/ui/CSimpleButton.hpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef UI_C_SIMPLE_BUTTON_HPP
|
||||
#define UI_C_SIMPLE_BUTTON_HPP
|
||||
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CSimpleFont;
|
||||
class CSimpleFontString;
|
||||
class CSimpleTexture;
|
||||
|
||||
enum CSimpleButtonState {
|
||||
BUTTONSTATE_DISABLED = 0x0,
|
||||
BUTTONSTATE_NORMAL = 0x1,
|
||||
BUTTONSTATE_PUSHED = 0x2,
|
||||
NUM_BUTTONSTATES = 0x3,
|
||||
};
|
||||
|
||||
class CSimpleButton : public CSimpleFrame {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
uint32_t m_doubleClickTime = 0;
|
||||
uint64_t m_clickAction = 0x0000000080000000;
|
||||
CSimpleButtonState m_state = BUTTONSTATE_DISABLED;
|
||||
int32_t m_stateLocked = 0;
|
||||
CSimpleFontString* m_text = nullptr;
|
||||
CSimpleFont* m_normalFont = nullptr;
|
||||
CSimpleFont* m_highlightFont = nullptr;
|
||||
CSimpleFont* m_disabledFont = nullptr;
|
||||
C2Vector m_pressedOffset;
|
||||
CSimpleTexture* m_textures[NUM_BUTTONSTATES];
|
||||
CSimpleTexture* m_activeTexture = nullptr;
|
||||
CSimpleTexture* m_highlightTexture = nullptr;
|
||||
ScriptIx m_preClick;
|
||||
ScriptIx m_onClick;
|
||||
ScriptIx m_postClick;
|
||||
ScriptIx m_onDoubleClick;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ScriptIx* GetScriptByName(const char*, ScriptData&);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual void OnLayerHide(void);
|
||||
virtual void OnLayerCursorEnter(int32_t);
|
||||
virtual void OnLayerCursorExit(int32_t, int32_t);
|
||||
virtual int32_t OnLayerMouseDown(const CMouseEvent&, const char*);
|
||||
virtual int32_t OnLayerMouseUp(const CMouseEvent&, const char*);
|
||||
virtual void LockHighlight(int32_t);
|
||||
virtual void Enable(int32_t);
|
||||
virtual void OnClick(const char*, int32_t);
|
||||
virtual void OnDoubleClick(const char*);
|
||||
virtual void SetButtonState(CSimpleButtonState, int32_t);
|
||||
|
||||
// Member functions
|
||||
CSimpleButton(CSimpleFrame*);
|
||||
void RunOnClickScript(const char*, int32_t);
|
||||
void SetClickAction(uint64_t action);
|
||||
void SetFontString(CSimpleFontString*);
|
||||
void SetHighlight(CSimpleTexture*, EGxBlend);
|
||||
int32_t SetHighlight(const char* texFile, EGxBlend blendMode);
|
||||
void SetPressedOffset(C2Vector&);
|
||||
void SetStateTexture(CSimpleButtonState, CSimpleTexture*);
|
||||
int32_t SetStateTexture(CSimpleButtonState state, const char* texFile);
|
||||
void SetText(const char*);
|
||||
void UpdateTextState(CSimpleButtonState);
|
||||
};
|
||||
|
||||
#endif
|
||||
349
src/ui/CSimpleButtonScript.cpp
Normal file
349
src/ui/CSimpleButtonScript.cpp
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
#include "ui/CSimpleButtonScript.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "ui/CSimpleButton.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleButton_SetStateTexture(lua_State* L, CSimpleButtonState state, const char* method) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (lua_type(L, 2) == LUA_TTABLE) {
|
||||
lua_rawgeti(L, 2, 0);
|
||||
auto texture = static_cast<CSimpleTexture*>(lua_touserdata(L, -1));
|
||||
lua_settop(L, -2);
|
||||
|
||||
if (!texture) {
|
||||
luaL_error(L, "%s:%s(): Couldn't find 'this' in texture", button->GetDisplayName(), method);
|
||||
}
|
||||
|
||||
if (!texture->IsA(CSimpleTexture::GetObjectType())) {
|
||||
luaL_error(L, "%s:%s(): Wrong object type, expected texture", button->GetDisplayName(), method);
|
||||
}
|
||||
|
||||
button->SetStateTexture(state, texture);
|
||||
|
||||
} else if (lua_isstring(L, 2)) {
|
||||
auto texFile = lua_tolstring(L, 2, nullptr);
|
||||
button->SetStateTexture(state, texFile);
|
||||
|
||||
} else if (lua_type(L, 2) == LUA_TNIL) {
|
||||
CSimpleTexture* texture = nullptr;
|
||||
button->SetStateTexture(state, texture);
|
||||
|
||||
} else {
|
||||
luaL_error(L, "Usage: %s:%s(texture or \"texture\" or nil)", button->GetDisplayName(), method);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_Enable(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (button->ProtectedFunctionsAllowed()) {
|
||||
button->Enable(1);
|
||||
} else {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_Disable(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (button->ProtectedFunctionsAllowed()) {
|
||||
button->Enable(0);
|
||||
} else {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_IsEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetButtonState(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetButtonState(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetNormalFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetNormalFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetDisabledFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetDisabledFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetHighlightFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetHighlightFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetFontString(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetFontString(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetText(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
const char* text = lua_tolstring(L, 2, 0);
|
||||
button->SetText(text);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetFormattedText(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetText(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
const char* text = nullptr;
|
||||
|
||||
if (button->m_text && button->m_text->GetText() && *button->m_text->GetText()) {
|
||||
text = button->m_text->GetText();
|
||||
}
|
||||
|
||||
lua_pushstring(L, text);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetNormalTexture(lua_State* L) {
|
||||
return CSimpleButton_SetStateTexture(L, BUTTONSTATE_NORMAL, "SetNormalTexture");
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetNormalTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetPushedTexture(lua_State* L) {
|
||||
return CSimpleButton_SetStateTexture(L, BUTTONSTATE_PUSHED, "SetPushedTexture");
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetPushedTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetDisabledTexture(lua_State* L) {
|
||||
return CSimpleButton_SetStateTexture(L, BUTTONSTATE_DISABLED, "SetDisabledTexture");
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetDisabledTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetHighlightTexture(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
EGxBlend blendMode = GxBlend_Add;
|
||||
if (lua_isstring(L, 3)) {
|
||||
auto blendString = lua_tolstring(L, 3, nullptr);
|
||||
StringToBlendMode(blendString, blendMode);
|
||||
}
|
||||
|
||||
if (lua_type(L, 2) == LUA_TTABLE) {
|
||||
lua_rawgeti(L, 2, 0);
|
||||
auto texture = static_cast<CSimpleTexture*>(lua_touserdata(L, -1));
|
||||
lua_settop(L, -2);
|
||||
|
||||
if (!texture) {
|
||||
luaL_error(L, "%s:SetHighlightTexture(): Couldn't find 'this' in texture", button->GetDisplayName());
|
||||
}
|
||||
|
||||
if (!texture->IsA(CSimpleTexture::GetObjectType())) {
|
||||
luaL_error(L, "%s:SetHighlightTexture(): Wrong object type, expected texture", button->GetDisplayName());
|
||||
}
|
||||
|
||||
button->SetHighlight(texture, blendMode);
|
||||
|
||||
} else if (lua_isstring(L, 2)) {
|
||||
auto texFile = lua_tolstring(L, 2, nullptr);
|
||||
button->SetHighlight(texFile, blendMode);
|
||||
|
||||
} else if (lua_type(L, 2) == LUA_TNIL) {
|
||||
CSimpleTexture* texture = nullptr;
|
||||
button->SetHighlight(texture, GxBlend_Add);
|
||||
|
||||
} else {
|
||||
luaL_error(L, "Usage: %s:SetHighlightTexture(texture or \"texture\" or nil [, \"blendmode\")", button->GetDisplayName());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetHighlightTexture(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
auto texture = button->m_highlightTexture;
|
||||
|
||||
if (texture) {
|
||||
if (!texture->lua_registered) {
|
||||
texture->RegisterScriptObject(nullptr);
|
||||
}
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, texture->lua_objectRef);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetPushedTextOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetPushedTextOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetTextWidth(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
auto text = button->m_text;
|
||||
|
||||
float width = text ? text->GetWidth() : 0.0f;
|
||||
float ddcWidth = CoordinateGetAspectCompensation() * 1024.0f * width;
|
||||
float ndcWidth = DDCToNDCWidth(ddcWidth);
|
||||
|
||||
lua_pushnumber(L, ndcWidth);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetTextHeight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_RegisterForClicks(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
uint64_t action = 0;
|
||||
|
||||
for (int32_t i = 2; lua_isstring(L, i); i++) {
|
||||
auto actionStr = lua_tolstring(L, i, nullptr);
|
||||
action |= StringToClickAction(actionStr);
|
||||
}
|
||||
|
||||
button->SetClickAction(action);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_Click(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
auto inputButton = "LeftButton";
|
||||
if (lua_isstring(L, 2)) {
|
||||
inputButton = lua_tolstring(L, 2, nullptr);
|
||||
}
|
||||
|
||||
auto v6 = StringToBOOL(L, 3, 0);
|
||||
|
||||
button->OnClick(inputButton, v6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_LockHighlight(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
button->LockHighlight(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_UnlockHighlight(lua_State* L) {
|
||||
auto type = CSimpleButton::GetObjectType();
|
||||
auto button = static_cast<CSimpleButton*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
button->LockHighlight(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_GetMotionScriptsWhileDisabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleButton_SetMotionScriptsWhileDisabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleButtonMethods[NUM_SIMPLE_BUTTON_SCRIPT_METHODS] = {
|
||||
{ "Enable", &CSimpleButton_Enable },
|
||||
{ "Disable", &CSimpleButton_Disable },
|
||||
{ "IsEnabled", &CSimpleButton_IsEnabled },
|
||||
{ "GetButtonState", &CSimpleButton_GetButtonState },
|
||||
{ "SetButtonState", &CSimpleButton_SetButtonState },
|
||||
{ "SetNormalFontObject", &CSimpleButton_SetNormalFontObject },
|
||||
{ "GetNormalFontObject", &CSimpleButton_GetNormalFontObject },
|
||||
{ "SetDisabledFontObject", &CSimpleButton_SetDisabledFontObject },
|
||||
{ "GetDisabledFontObject", &CSimpleButton_GetDisabledFontObject },
|
||||
{ "SetHighlightFontObject", &CSimpleButton_SetHighlightFontObject },
|
||||
{ "GetHighlightFontObject", &CSimpleButton_GetHighlightFontObject },
|
||||
{ "SetFontString", &CSimpleButton_SetFontString },
|
||||
{ "GetFontString", &CSimpleButton_GetFontString },
|
||||
{ "SetText", &CSimpleButton_SetText },
|
||||
{ "SetFormattedText", &CSimpleButton_SetFormattedText },
|
||||
{ "GetText", &CSimpleButton_GetText },
|
||||
{ "SetNormalTexture", &CSimpleButton_SetNormalTexture },
|
||||
{ "GetNormalTexture", &CSimpleButton_GetNormalTexture },
|
||||
{ "SetPushedTexture", &CSimpleButton_SetPushedTexture },
|
||||
{ "GetPushedTexture", &CSimpleButton_GetPushedTexture },
|
||||
{ "SetDisabledTexture", &CSimpleButton_SetDisabledTexture },
|
||||
{ "GetDisabledTexture", &CSimpleButton_GetDisabledTexture },
|
||||
{ "SetHighlightTexture", &CSimpleButton_SetHighlightTexture },
|
||||
{ "GetHighlightTexture", &CSimpleButton_GetHighlightTexture },
|
||||
{ "SetPushedTextOffset", &CSimpleButton_SetPushedTextOffset },
|
||||
{ "GetPushedTextOffset", &CSimpleButton_GetPushedTextOffset },
|
||||
{ "GetTextWidth", &CSimpleButton_GetTextWidth },
|
||||
{ "GetTextHeight", &CSimpleButton_GetTextHeight },
|
||||
{ "RegisterForClicks", &CSimpleButton_RegisterForClicks },
|
||||
{ "Click", &CSimpleButton_Click },
|
||||
{ "LockHighlight", &CSimpleButton_LockHighlight },
|
||||
{ "UnlockHighlight", &CSimpleButton_UnlockHighlight },
|
||||
{ "GetMotionScriptsWhileDisabled", &CSimpleButton_GetMotionScriptsWhileDisabled },
|
||||
{ "SetMotionScriptsWhileDisabled", &CSimpleButton_SetMotionScriptsWhileDisabled }
|
||||
};
|
||||
10
src/ui/CSimpleButtonScript.hpp
Normal file
10
src/ui/CSimpleButtonScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_BUTTON_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_BUTTON_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_BUTTON_SCRIPT_METHODS 34
|
||||
|
||||
extern FrameScript_Method SimpleButtonMethods[NUM_SIMPLE_BUTTON_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
40
src/ui/CSimpleCheckbox.cpp
Normal file
40
src/ui/CSimpleCheckbox.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include "ui/CSimpleCheckbox.hpp"
|
||||
#include "ui/CSimpleCheckboxScript.hpp"
|
||||
|
||||
int32_t CSimpleCheckbox::s_metatable;
|
||||
int32_t CSimpleCheckbox::s_objectType;
|
||||
|
||||
void CSimpleCheckbox::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleCheckbox::RegisterScriptMethods);
|
||||
CSimpleCheckbox::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox::GetObjectType() {
|
||||
if (!CSimpleCheckbox::s_objectType) {
|
||||
CSimpleCheckbox::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleCheckbox::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleCheckbox::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleButton::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleCheckboxMethods, NUM_SIMPLE_CHECKBOX_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleCheckbox::CSimpleCheckbox(CSimpleFrame* parent) : CSimpleButton(parent) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox::GetScriptMetaTable() {
|
||||
return CSimpleCheckbox::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleCheckbox::IsA(int32_t type) {
|
||||
return type == CSimpleCheckbox::s_objectType
|
||||
|| type == CSimpleButton::s_objectType
|
||||
|| type == CSimpleFrame::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
27
src/ui/CSimpleCheckbox.hpp
Normal file
27
src/ui/CSimpleCheckbox.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef UI_C_SIMPLE_CHECKBOX_HPP
|
||||
#define UI_C_SIMPLE_CHECKBOX_HPP
|
||||
|
||||
#include "ui/CSimpleButton.hpp"
|
||||
|
||||
class CSimpleCheckbox : public CSimpleButton {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
|
||||
// Virtual member functions
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
|
||||
// Member functions
|
||||
CSimpleCheckbox(CSimpleFrame*);
|
||||
};
|
||||
|
||||
#endif
|
||||
36
src/ui/CSimpleCheckboxScript.cpp
Normal file
36
src/ui/CSimpleCheckboxScript.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include "ui/CSimpleCheckboxScript.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleCheckbox_SetChecked(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox_GetChecked(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox_GetCheckedTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox_SetCheckedTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox_GetDisabledCheckedTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleCheckbox_SetDisabledCheckedTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleCheckboxMethods[NUM_SIMPLE_CHECKBOX_SCRIPT_METHODS] = {
|
||||
{ "SetChecked", &CSimpleCheckbox_SetChecked },
|
||||
{ "GetChecked", &CSimpleCheckbox_GetChecked },
|
||||
{ "GetCheckedTexture", &CSimpleCheckbox_GetCheckedTexture },
|
||||
{ "SetCheckedTexture", &CSimpleCheckbox_SetCheckedTexture },
|
||||
{ "GetDisabledCheckedTexture", &CSimpleCheckbox_GetDisabledCheckedTexture },
|
||||
{ "SetDisabledCheckedTexture", &CSimpleCheckbox_SetDisabledCheckedTexture }
|
||||
};
|
||||
10
src/ui/CSimpleCheckboxScript.hpp
Normal file
10
src/ui/CSimpleCheckboxScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_CHECKBOX_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_CHECKBOX_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_CHECKBOX_SCRIPT_METHODS 6
|
||||
|
||||
extern FrameScript_Method SimpleCheckboxMethods[NUM_SIMPLE_CHECKBOX_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
1349
src/ui/CSimpleEditBox.cpp
Normal file
1349
src/ui/CSimpleEditBox.cpp
Normal file
File diff suppressed because it is too large
Load diff
114
src/ui/CSimpleEditBox.hpp
Normal file
114
src/ui/CSimpleEditBox.hpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#ifndef UI_C_SIMPLE_EDIT_BOX_HPP
|
||||
#define UI_C_SIMPLE_EDIT_BOX_HPP
|
||||
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleFontedFrame.hpp"
|
||||
|
||||
class CSimpleFontString;
|
||||
class CSimpleTexture;
|
||||
|
||||
class CSimpleEditBox : public CSimpleFrame, CSimpleFontedFrame {
|
||||
public:
|
||||
// Static variables
|
||||
static CSimpleEditBox* s_currentFocus;
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
static void SetKeyboardFocus(CSimpleEditBox*);
|
||||
|
||||
// Member variables
|
||||
int32_t m_autoFocus : 1;
|
||||
int32_t m_multiline : 1;
|
||||
int32_t m_numeric : 1;
|
||||
int32_t m_password : 1;
|
||||
int32_t m_ignoreArrows : 1;
|
||||
int32_t m_countInvisibleLetters : 1;
|
||||
int32_t m_dirtyFlags = 0x1;
|
||||
CSimpleFontedFrameFont* m_font;
|
||||
CSimpleFontString* m_string;
|
||||
char* m_text;
|
||||
uint32_t* m_textInfo;
|
||||
char* m_textHidden = nullptr;
|
||||
int32_t m_textLength = 0;
|
||||
int32_t m_textLengthMax = -1;
|
||||
int32_t m_textLettersMax = 0;
|
||||
int32_t m_textSize = 32;
|
||||
int32_t m_visiblePos = 0;
|
||||
int32_t m_visibleLen = 0;
|
||||
CSimpleTexture* m_highlight[3];
|
||||
int32_t m_highlightLeft = 0;
|
||||
int32_t m_highlightRight = 0;
|
||||
int32_t m_highlightDrag = 0;
|
||||
CSimpleTexture* m_cursor = nullptr;
|
||||
int32_t m_cursorPos = 0;
|
||||
float m_cursorBlinkSpeed = 0.5f;
|
||||
float m_blinkElapsedTime = 0.0f;
|
||||
TSGrowableArray<uint32_t> m_visibleLines;
|
||||
int32_t m_imeInputMode = 0;
|
||||
CRect m_editTextInset = {};
|
||||
ScriptIx m_onEnterPressed;
|
||||
ScriptIx m_onEscapePressed;
|
||||
ScriptIx m_onSpacePressed;
|
||||
ScriptIx m_onTabPressed;
|
||||
ScriptIx m_onTextChanged;
|
||||
ScriptIx m_onTextSet;
|
||||
ScriptIx m_onCursorChanged;
|
||||
ScriptIx m_onInputLanguageChanged;
|
||||
ScriptIx m_onEditFocusGained;
|
||||
ScriptIx m_onEditFocusLost;
|
||||
ScriptIx m_onCharComposition;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ScriptIx* GetScriptByName(const char*, ScriptData&);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual void OnLayerUpdate(float);
|
||||
virtual void OnFrameSizeChanged(float, float);
|
||||
virtual int32_t OnLayerChar(const CCharEvent&);
|
||||
virtual int32_t OnLayerKeyDown(const CKeyEvent&);
|
||||
virtual int32_t OnLayerMouseDown(const CMouseEvent&, const char*);
|
||||
virtual int32_t OnLayerMouseUp(const CMouseEvent&, const char*);
|
||||
virtual void FontUpdated(CSimpleFontedFrameFont*, int32_t);
|
||||
|
||||
// Member functions
|
||||
CSimpleEditBox(CSimpleFrame*);
|
||||
int32_t ConvertCoordinateToIndex(float, float, int32_t&);
|
||||
void DeleteBackward(int32_t a2);
|
||||
void DeleteForward(int32_t a2);
|
||||
void DeleteHighlight(int32_t);
|
||||
void DeleteSubstring(int32_t left, int32_t right, int32_t a4);
|
||||
int32_t GetNumToLen(int32_t, int32_t, bool);
|
||||
void GrowText(int32_t);
|
||||
void Insert(uint32_t);
|
||||
void Insert(const char*, const char*, int32_t, int32_t, int32_t);
|
||||
int32_t IsCurrentFocus(void);
|
||||
void Move(int32_t distance, int32_t highlight);
|
||||
void MoveBackward(int32_t highlight);
|
||||
void MoveForward(int32_t highlight);
|
||||
void OnEnterPressed(void);
|
||||
void OnEscapePressed(void);
|
||||
void OnTextChanged(void);
|
||||
int32_t PrevCharOffset(int32_t);
|
||||
void RunOnCursorChangedScript(float, float, float, float);
|
||||
void RunOnEditFocusGainedScript(void);
|
||||
void RunOnEditFocusLostScript(void);
|
||||
void RunOnEnterPressedScript(void);
|
||||
void RunOnTextChangedScript(int32_t);
|
||||
void SetCursorPosition(int32_t);
|
||||
void SetHistoryLines(int32_t);
|
||||
void SetMultiLine(int32_t);
|
||||
void StartHighlight(void);
|
||||
void UpdateDirtyBits(void);
|
||||
void UpdateSizes(void);
|
||||
void UpdateTextInfo(void);
|
||||
void UpdateVisibleCursor(void);
|
||||
void UpdateVisibleHighlight(void);
|
||||
void UpdateVisibleText(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
309
src/ui/CSimpleEditBoxScript.cpp
Normal file
309
src/ui/CSimpleEditBoxScript.cpp
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
#include "ui/CSimpleEditBoxScript.hpp"
|
||||
#include "ui/CSimpleEditBox.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleEditBox_SetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetAutoFocus(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_IsAutoFocus(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetCountInvisibleLetters(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_IsCountInvisibleLetters(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetMultiLine(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_IsMultiLine(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetNumeric(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_IsNumeric(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetPassword(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_IsPassword(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetBlinkSpeed(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetBlinkSpeed(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_Insert(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetText(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetText(lua_State* L) {
|
||||
int32_t type = CSimpleEditBox::GetObjectType();
|
||||
CSimpleEditBox* editBox = static_cast<CSimpleEditBox*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
// TODO
|
||||
// - taint management
|
||||
// if (editBox->m_dwordC && lua_taintexpected && !lua_taintedclosure) {
|
||||
// lua_tainted = editBox->simpleeditbox_dwordC;
|
||||
// }
|
||||
|
||||
lua_pushstring(L, editBox->m_text);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetNumber(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetNumber(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_HighlightText(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_AddHistoryLine(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_ClearHistory(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetTextInsets(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetTextInsets(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetFocus(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_ClearFocus(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_HasFocus(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetMaxBytes(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetMaxBytes(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetMaxLetters(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetMaxLetters(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetNumLetters(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetHistoryLines(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetHistoryLines(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetInputLanguage(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_ToggleInputLanguage(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetAltArrowKeyMode(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetAltArrowKeyMode(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_IsInIMECompositionMode(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_SetCursorPosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetCursorPosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleEditBox_GetUTF8CursorPosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleEditBoxMethods[NUM_SIMPLE_EDIT_BOX_SCRIPT_METHODS] = {
|
||||
{ "SetFontObject", &CSimpleEditBox_SetFontObject },
|
||||
{ "GetFontObject", &CSimpleEditBox_GetFontObject },
|
||||
{ "SetFont", &CSimpleEditBox_SetFont },
|
||||
{ "GetFont", &CSimpleEditBox_GetFont },
|
||||
{ "SetTextColor", &CSimpleEditBox_SetTextColor },
|
||||
{ "GetTextColor", &CSimpleEditBox_GetTextColor },
|
||||
{ "SetShadowColor", &CSimpleEditBox_SetShadowColor },
|
||||
{ "GetShadowColor", &CSimpleEditBox_GetShadowColor },
|
||||
{ "SetShadowOffset", &CSimpleEditBox_SetShadowOffset },
|
||||
{ "GetShadowOffset", &CSimpleEditBox_GetShadowOffset },
|
||||
{ "SetSpacing", &CSimpleEditBox_SetSpacing },
|
||||
{ "GetSpacing", &CSimpleEditBox_GetSpacing },
|
||||
{ "SetJustifyH", &CSimpleEditBox_SetJustifyH },
|
||||
{ "GetJustifyH", &CSimpleEditBox_GetJustifyH },
|
||||
{ "SetJustifyV", &CSimpleEditBox_SetJustifyV },
|
||||
{ "GetJustifyV", &CSimpleEditBox_GetJustifyV },
|
||||
{ "SetIndentedWordWrap", &CSimpleEditBox_SetIndentedWordWrap },
|
||||
{ "GetIndentedWordWrap", &CSimpleEditBox_GetIndentedWordWrap },
|
||||
{ "SetAutoFocus", &CSimpleEditBox_SetAutoFocus },
|
||||
{ "IsAutoFocus", &CSimpleEditBox_IsAutoFocus },
|
||||
{ "SetCountInvisibleLetters", &CSimpleEditBox_SetCountInvisibleLetters },
|
||||
{ "IsCountInvisibleLetters", &CSimpleEditBox_IsCountInvisibleLetters },
|
||||
{ "SetMultiLine", &CSimpleEditBox_SetMultiLine },
|
||||
{ "IsMultiLine", &CSimpleEditBox_IsMultiLine },
|
||||
{ "SetNumeric", &CSimpleEditBox_SetNumeric },
|
||||
{ "IsNumeric", &CSimpleEditBox_IsNumeric },
|
||||
{ "SetPassword", &CSimpleEditBox_SetPassword },
|
||||
{ "IsPassword", &CSimpleEditBox_IsPassword },
|
||||
{ "SetBlinkSpeed", &CSimpleEditBox_SetBlinkSpeed },
|
||||
{ "GetBlinkSpeed", &CSimpleEditBox_GetBlinkSpeed },
|
||||
{ "Insert", &CSimpleEditBox_Insert },
|
||||
{ "SetText", &CSimpleEditBox_SetText },
|
||||
{ "GetText", &CSimpleEditBox_GetText },
|
||||
{ "SetNumber", &CSimpleEditBox_SetNumber },
|
||||
{ "GetNumber", &CSimpleEditBox_GetNumber },
|
||||
{ "HighlightText", &CSimpleEditBox_HighlightText },
|
||||
{ "AddHistoryLine", &CSimpleEditBox_AddHistoryLine },
|
||||
{ "ClearHistory", &CSimpleEditBox_ClearHistory },
|
||||
{ "SetTextInsets", &CSimpleEditBox_SetTextInsets },
|
||||
{ "GetTextInsets", &CSimpleEditBox_GetTextInsets },
|
||||
{ "SetFocus", &CSimpleEditBox_SetFocus },
|
||||
{ "ClearFocus", &CSimpleEditBox_ClearFocus },
|
||||
{ "HasFocus", &CSimpleEditBox_HasFocus },
|
||||
{ "SetMaxBytes", &CSimpleEditBox_SetMaxBytes },
|
||||
{ "GetMaxBytes", &CSimpleEditBox_GetMaxBytes },
|
||||
{ "SetMaxLetters", &CSimpleEditBox_SetMaxLetters },
|
||||
{ "GetMaxLetters", &CSimpleEditBox_GetMaxLetters },
|
||||
{ "GetNumLetters", &CSimpleEditBox_GetNumLetters },
|
||||
{ "GetHistoryLines", &CSimpleEditBox_GetHistoryLines },
|
||||
{ "SetHistoryLines", &CSimpleEditBox_SetHistoryLines },
|
||||
{ "GetInputLanguage", &CSimpleEditBox_GetInputLanguage },
|
||||
{ "ToggleInputLanguage", &CSimpleEditBox_ToggleInputLanguage },
|
||||
{ "SetAltArrowKeyMode", &CSimpleEditBox_SetAltArrowKeyMode },
|
||||
{ "GetAltArrowKeyMode", &CSimpleEditBox_GetAltArrowKeyMode },
|
||||
{ "IsInIMECompositionMode", &CSimpleEditBox_IsInIMECompositionMode },
|
||||
{ "SetCursorPosition", &CSimpleEditBox_SetCursorPosition },
|
||||
{ "GetCursorPosition", &CSimpleEditBox_GetCursorPosition },
|
||||
{ "GetUTF8CursorPosition", &CSimpleEditBox_GetUTF8CursorPosition }
|
||||
};
|
||||
10
src/ui/CSimpleEditBoxScript.hpp
Normal file
10
src/ui/CSimpleEditBoxScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_EDIT_BOX_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_EDIT_BOX_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_EDIT_BOX_SCRIPT_METHODS 58
|
||||
|
||||
extern FrameScript_Method SimpleEditBoxMethods[NUM_SIMPLE_EDIT_BOX_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
241
src/ui/CSimpleFont.cpp
Normal file
241
src/ui/CSimpleFont.cpp
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
#include "ui/CSimpleFont.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Font.hpp"
|
||||
#include "ui/CSimpleFontScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
TSHashTable<SIMPLEFONT, HASHKEY_STRI> CSimpleFont::s_fontList;
|
||||
int32_t CSimpleFont::s_metatable;
|
||||
int32_t CSimpleFont::s_objectType;
|
||||
|
||||
SIMPLEFONT::SIMPLEFONT() : TSHashObject<SIMPLEFONT, HASHKEY_STRI>() {
|
||||
void* m = SMemAlloc(sizeof(CSimpleFont), __FILE__, __LINE__, 0);
|
||||
|
||||
if (m) {
|
||||
this->font = new (m) CSimpleFont();
|
||||
} else {
|
||||
this->font = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFont::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleFont::RegisterScriptMethods);
|
||||
CSimpleFont::s_metatable = ref;
|
||||
}
|
||||
|
||||
CSimpleFont* CSimpleFont::GetFont(const char* name, int32_t a2) {
|
||||
SIMPLEFONT* hashed = CSimpleFont::s_fontList.Ptr(name);
|
||||
|
||||
if (hashed) {
|
||||
return hashed->font;
|
||||
}
|
||||
|
||||
if (!a2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hashed = CSimpleFont::s_fontList.New(name, 0, 0);
|
||||
|
||||
CSimpleFont* font = hashed->font;
|
||||
|
||||
if (font->m_name) {
|
||||
font->UnregisterScriptObject(font->m_name);
|
||||
}
|
||||
|
||||
font->m_name = hashed->m_key.m_str;
|
||||
|
||||
if (font->m_name) {
|
||||
font->RegisterScriptObject(font->m_name);
|
||||
}
|
||||
|
||||
return hashed->font;
|
||||
}
|
||||
|
||||
int32_t CSimpleFont::GetObjectType() {
|
||||
if (!CSimpleFont::s_objectType) {
|
||||
CSimpleFont::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleFont::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleFont::RegisterScriptMethods(lua_State* L) {
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleFontMethods, NUM_SIMPLE_FONT_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleFont::CSimpleFont() : FrameScript_Object() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleFont::FontObjectUpdated(CSimpleFontStringAttributes& attributes) {
|
||||
attributes.Update(this->m_attributes, this->m_fontableFlags);
|
||||
this->UpdateObjects();
|
||||
}
|
||||
|
||||
char* CSimpleFont::GetName() {
|
||||
return const_cast<char*>(this->m_name);
|
||||
}
|
||||
|
||||
int32_t CSimpleFont::GetScriptMetaTable() {
|
||||
return CSimpleFont::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleFont::IsA(int32_t type) {
|
||||
return type == CSimpleFont::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleFont::LoadXML(XMLNode* node, CStatus* status) {
|
||||
const char* inheritsAttr = node->GetAttributeByName("inherits");
|
||||
if (inheritsAttr && *inheritsAttr) {
|
||||
auto font = CSimpleFont::GetFont(inheritsAttr, 0);
|
||||
|
||||
if (font) {
|
||||
this->SetFontObject(font);
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Couldn't find inherited font: %s",
|
||||
inheritsAttr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const char* fontAttr = node->GetAttributeByName("font");
|
||||
if (fontAttr && *fontAttr) {
|
||||
auto font = CSimpleFont::GetFont(fontAttr, 0);
|
||||
|
||||
if (font) {
|
||||
this->SetFontObject(font);
|
||||
} else {
|
||||
float fontHeight = 0.0f;
|
||||
|
||||
XMLNode* fontHeightNode = node->GetChildByName("FontHeight");
|
||||
if (fontHeightNode) {
|
||||
LoadXML_Value(fontHeightNode, fontHeight, status);
|
||||
}
|
||||
|
||||
if (fontHeight == 0.0f) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Font %s: Missing font height in %s element",
|
||||
this->GetDisplayName(),
|
||||
node->GetName()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t fontFlags = 0;
|
||||
|
||||
const char* outlineAttr = node->GetAttributeByName("outline");
|
||||
if (outlineAttr && *outlineAttr) {
|
||||
if (!SStrCmpI(outlineAttr, "NORMAL", STORM_MAX_STR)) {
|
||||
fontFlags |= FONT_OUTLINE;
|
||||
} else if (!SStrCmpI(outlineAttr, "THICK", STORM_MAX_STR)) {
|
||||
fontFlags |= (FONT_OUTLINE | FONT_THICKOUTLINE);
|
||||
}
|
||||
}
|
||||
|
||||
const char* monochromeAttr = node->GetAttributeByName("monochrome");
|
||||
if (monochromeAttr && *monochromeAttr && StringToBOOL(monochromeAttr)) {
|
||||
fontFlags |= FONT_MONOCHROME;
|
||||
}
|
||||
|
||||
if (this->m_attributes.SetFont(fontAttr, fontHeight, fontFlags)) {
|
||||
this->m_fontableFlags &= ~FLAG_FONT_UPDATE;
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Font %s: Unable to load font file %s",
|
||||
this->GetDisplayName(),
|
||||
fontAttr
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* spacingAttr = node->GetAttributeByName("spacing");
|
||||
if (spacingAttr && *spacingAttr) {
|
||||
float spacing = SStrToFloat(spacingAttr);
|
||||
float ndcSpacing = spacing / (CoordinateGetAspectCompensation() * 1024.0);
|
||||
float ddcSpacing = NDCToDDCWidth(ndcSpacing);
|
||||
|
||||
this->m_attributes.SetSpacing(ddcSpacing);
|
||||
this->m_fontableFlags &= ~FLAG_SPACING_UPDATE;
|
||||
}
|
||||
|
||||
const char* justifyVAttr = node->GetAttributeByName("justifyV");
|
||||
if (justifyVAttr && *justifyVAttr) {
|
||||
uint32_t justify;
|
||||
|
||||
if (StringToJustify(justifyVAttr, justify)) {
|
||||
this->m_attributes.SetJustifyV(justify);
|
||||
this->m_fontableFlags &= ~FLAG_STYLE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
const char* justifyHAttr = node->GetAttributeByName("justifyH");
|
||||
if (justifyHAttr && *justifyHAttr) {
|
||||
uint32_t justify;
|
||||
|
||||
if (StringToJustify(justifyHAttr, justify)) {
|
||||
this->m_attributes.SetJustifyH(justify);
|
||||
this->m_fontableFlags &= ~FLAG_STYLE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
const char* nonspacewrapAttr = node->GetAttributeByName("nonspacewrap");
|
||||
if (nonspacewrapAttr && *nonspacewrapAttr) {
|
||||
bool nonspacewrap = StringToBOOL(nonspacewrapAttr);
|
||||
this->m_attributes.SetNonSpaceWrap(nonspacewrap);
|
||||
}
|
||||
|
||||
const char* indentedAttr = node->GetAttributeByName("indented");
|
||||
if (indentedAttr && *indentedAttr) {
|
||||
bool indented = StringToBOOL(indentedAttr);
|
||||
this->m_attributes.SetIndented(indented);
|
||||
}
|
||||
|
||||
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "Color", STORM_MAX_STR)) {
|
||||
CImVector color;
|
||||
LoadXML_Color(child, color);
|
||||
this->m_attributes.SetColor(color);
|
||||
this->m_fontableFlags &= ~FLAG_COLOR_UPDATE;
|
||||
|
||||
} else if(!SStrCmpI(child->GetName(), "Shadow", STORM_MAX_STR)) {
|
||||
C2Vector shadowOffset = { 0.001f, -0.001f };
|
||||
CImVector shadowColor = { 0x00, 0x00, 0x00, 0xFF };
|
||||
|
||||
auto colorChild = child->GetChildByName("Color");
|
||||
if (colorChild) {
|
||||
LoadXML_Color(colorChild, shadowColor);
|
||||
}
|
||||
|
||||
auto offsetChild = child->GetChildByName("Offset");
|
||||
if (offsetChild) {
|
||||
LoadXML_Dimensions(offsetChild, shadowOffset.x, shadowOffset.y, status);
|
||||
}
|
||||
|
||||
this->m_attributes.SetShadow(shadowColor, shadowOffset);
|
||||
this->m_fontableFlags &= ~FLAG_SHADOW_UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFont::UpdateObjects() {
|
||||
if (this->m_attributes.m_flags) {
|
||||
for (auto node = this->m_fontableList.Head(); node; node = this->m_fontableList.Link(node)->Next()) {
|
||||
node->FontObjectUpdated(this->m_attributes);
|
||||
}
|
||||
|
||||
this->m_attributes.m_flags &= ~FLAG_COMPLETE_UPDATE;
|
||||
}
|
||||
}
|
||||
54
src/ui/CSimpleFont.hpp
Normal file
54
src/ui/CSimpleFont.hpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef UI_C_SIMPLE_FONT_HPP
|
||||
#define UI_C_SIMPLE_FONT_HPP
|
||||
|
||||
#include "ui/CSimpleFontable.hpp"
|
||||
#include "ui/CSimpleFontStringAttributes.hpp"
|
||||
#include "ui/FrameScript_Object.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Hash.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CSimpleFont;
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
|
||||
class SIMPLEFONT : public TSHashObject<SIMPLEFONT, HASHKEY_STRI> {
|
||||
public:
|
||||
// Member variables
|
||||
CSimpleFont* font = nullptr;
|
||||
|
||||
// Member functions
|
||||
SIMPLEFONT();
|
||||
};
|
||||
|
||||
class CSimpleFont : public FrameScript_Object, public CSimpleFontable {
|
||||
public:
|
||||
// Static variables
|
||||
static TSHashTable<SIMPLEFONT, HASHKEY_STRI> s_fontList;
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static CSimpleFont* GetFont(const char*, int32_t);
|
||||
static int32_t GetObjectType();
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
CSimpleFontStringAttributes m_attributes;
|
||||
const char* m_name = nullptr;
|
||||
STORM_EXPLICIT_LIST(CSimpleFontable, m_fontableLink) m_fontableList;
|
||||
|
||||
// Virtual member functions
|
||||
virtual char* GetName(void);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual void FontObjectUpdated(CSimpleFontStringAttributes&);
|
||||
|
||||
// Member functions
|
||||
CSimpleFont();
|
||||
void LoadXML(XMLNode*, CStatus*);
|
||||
void UpdateObjects(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
126
src/ui/CSimpleFontScript.cpp
Normal file
126
src/ui/CSimpleFontScript.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include "ui/CSimpleFontScript.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleFont_GetObjectType(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_IsObjectType(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetName(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_CopyFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_SetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFont_GetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleFontMethods[NUM_SIMPLE_FONT_SCRIPT_METHODS] = {
|
||||
{ "GetObjectType", &CSimpleFont_GetObjectType },
|
||||
{ "IsObjectType", &CSimpleFont_IsObjectType },
|
||||
{ "GetName", &CSimpleFont_GetName },
|
||||
{ "SetFontObject", &CSimpleFont_SetFontObject },
|
||||
{ "GetFontObject", &CSimpleFont_GetFontObject },
|
||||
{ "CopyFontObject", &CSimpleFont_CopyFontObject },
|
||||
{ "SetFont", &CSimpleFont_SetFont },
|
||||
{ "GetFont", &CSimpleFont_GetFont },
|
||||
{ "SetAlpha", &CSimpleFont_SetAlpha },
|
||||
{ "GetAlpha", &CSimpleFont_GetAlpha },
|
||||
{ "SetTextColor", &CSimpleFont_SetTextColor },
|
||||
{ "GetTextColor", &CSimpleFont_GetTextColor },
|
||||
{ "SetShadowColor", &CSimpleFont_SetShadowColor },
|
||||
{ "GetShadowColor", &CSimpleFont_GetShadowColor },
|
||||
{ "SetShadowOffset", &CSimpleFont_SetShadowOffset },
|
||||
{ "GetShadowOffset", &CSimpleFont_GetShadowOffset },
|
||||
{ "SetSpacing", &CSimpleFont_SetSpacing },
|
||||
{ "GetSpacing", &CSimpleFont_GetSpacing },
|
||||
{ "SetJustifyH", &CSimpleFont_SetJustifyH },
|
||||
{ "GetJustifyH", &CSimpleFont_GetJustifyH },
|
||||
{ "SetJustifyV", &CSimpleFont_SetJustifyV },
|
||||
{ "GetJustifyV", &CSimpleFont_GetJustifyV },
|
||||
{ "SetIndentedWordWrap", &CSimpleFont_SetIndentedWordWrap },
|
||||
{ "GetIndentedWordWrap", &CSimpleFont_GetIndentedWordWrap }
|
||||
};
|
||||
10
src/ui/CSimpleFontScript.hpp
Normal file
10
src/ui/CSimpleFontScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_FONT_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_FONT_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_FONT_SCRIPT_METHODS 24
|
||||
|
||||
extern FrameScript_Method SimpleFontMethods[NUM_SIMPLE_FONT_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
919
src/ui/CSimpleFontString.cpp
Normal file
919
src/ui/CSimpleFontString.cpp
Normal file
|
|
@ -0,0 +1,919 @@
|
|||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "math/Utils.hpp"
|
||||
#include "ui/CFramePoint.hpp"
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
#include "ui/CSimpleFontStringScript.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleTop.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include "ui/Util.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
int32_t CSimpleFontString::s_count;
|
||||
int32_t CSimpleFontString::s_metatable;
|
||||
int32_t CSimpleFontString::s_objectType;
|
||||
|
||||
void CSimpleFontString::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleFontString::RegisterScriptMethods);
|
||||
CSimpleFontString::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString::GetObjectType() {
|
||||
if (!CSimpleFontString::s_objectType) {
|
||||
CSimpleFontString::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleFontString::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleFontString::RegisterScriptMethods(lua_State* L) {
|
||||
CScriptRegion::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleFontStringMethods, NUM_SIMPLE_FONT_STRING_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleFontString::CSimpleFontString(CSimpleFrame* frame, uint32_t drawlayer, int32_t show) : CSimpleRegion(frame, drawlayer, show) {
|
||||
this->m_maxLines = 0;
|
||||
this->m_unk12b = 1;
|
||||
|
||||
// TODO
|
||||
|
||||
CSimpleFontString::s_count++;
|
||||
}
|
||||
|
||||
CSimpleFontString::~CSimpleFontString() {
|
||||
this->FreeEmbeddedTextures();
|
||||
|
||||
if (this->m_text) {
|
||||
SMemFree(this->m_text, __FILE__, __LINE__, 0x0);
|
||||
this->m_text = nullptr;
|
||||
}
|
||||
|
||||
this->m_fontHeight = 0.0f;
|
||||
|
||||
if (this->m_string) {
|
||||
HandleClose(this->m_string);
|
||||
this->m_string = nullptr;
|
||||
}
|
||||
|
||||
if (this->m_font) {
|
||||
HandleClose(this->m_font);
|
||||
this->m_font = nullptr;
|
||||
}
|
||||
|
||||
CSimpleFontString::s_count--;
|
||||
}
|
||||
|
||||
void CSimpleFontString::AddShadow(const CImVector& shadowColor, const C2Vector& shadowOffset) {
|
||||
auto styleFlags = this->m_styleFlags;
|
||||
|
||||
if (
|
||||
!(styleFlags & 0x100)
|
||||
|| shadowColor != this->m_shadowColor
|
||||
|| this->m_shadowOffset.x != shadowOffset.x
|
||||
|| this->m_shadowOffset.y != shadowOffset.y
|
||||
) {
|
||||
this->m_styleFlags = styleFlags | 0x100;
|
||||
this->m_shadowColor = shadowColor;
|
||||
this->m_shadowOffset = shadowOffset;
|
||||
|
||||
if (this->m_string) {
|
||||
auto shadowColor = this->m_shadowColor;
|
||||
// TODO alpha manipulation
|
||||
|
||||
auto shadowOffset = this->m_shadowOffset;
|
||||
shadowOffset.x *= this->m_layoutScale;
|
||||
shadowOffset.y *= this->m_layoutScale;
|
||||
|
||||
TextBlockAddShadow(this->m_string, shadowColor, shadowOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::ClearString() {
|
||||
this->m_cachedWidth = 0.0f;
|
||||
this->m_cachedHeight = 0.0f;
|
||||
|
||||
if (this->m_string) {
|
||||
HandleClose(this->m_string);
|
||||
this->m_string = nullptr;
|
||||
}
|
||||
|
||||
this->m_flags &= ~0x1;
|
||||
this->Resize(0);
|
||||
}
|
||||
|
||||
void CSimpleFontString::Draw(CRenderBatch* batch) {
|
||||
if (this->m_font && this->m_text && *this->m_text) {
|
||||
batch->QueueFontString(this);
|
||||
this->DrawEmbeddedTextures(batch);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::DrawEmbeddedTextures(CRenderBatch* batch) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool CSimpleFontString::IsA(int32_t type) {
|
||||
return type == CSimpleFontString::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleFontString::FontObjectUpdated(CSimpleFontStringAttributes& attributes) {
|
||||
attributes.Update(this, this->m_fontableFlags);
|
||||
}
|
||||
|
||||
void CSimpleFontString::FreeEmbeddedTextures() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
const char* CSimpleFontString::GetDisplayText(float width, float height) {
|
||||
static char buffer[8192];
|
||||
|
||||
if (!this->m_text || !*this->m_text) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!this->m_font || width <= 0.0f || /* TODO */ height <= 0.0f) {
|
||||
return this->m_text;
|
||||
}
|
||||
|
||||
auto fontHeight = this->GetFontHeight(true);
|
||||
auto v5 = (CSimpleTop::RoundToPixelHeight(this->m_spacing) + fontHeight) * this->m_layoutScale;
|
||||
|
||||
// TODO
|
||||
|
||||
auto text = this->m_text;
|
||||
auto textLen = SStrLen(text);
|
||||
auto scaledSpacing = this->m_spacing * this->m_layoutScale;
|
||||
auto scaledShadowOffset = this->m_shadowOffset.x * this->m_layoutScale;
|
||||
auto scaledFontHeight = fontHeight * this->m_layoutScale;
|
||||
|
||||
auto maxChars = TextBlockGetMaxCharsWithinWidthAndHeight(
|
||||
this->m_font,
|
||||
text,
|
||||
scaledFontHeight,
|
||||
width,
|
||||
height,
|
||||
textLen,
|
||||
scaledShadowOffset,
|
||||
this->m_layoutScale,
|
||||
scaledSpacing,
|
||||
this->m_styleFlags
|
||||
);
|
||||
|
||||
if (maxChars >= textLen) {
|
||||
return text;
|
||||
}
|
||||
|
||||
SStrCopy(buffer, text, sizeof(buffer));
|
||||
auto end = std::min(textLen, sizeof(buffer) - 4);
|
||||
|
||||
do {
|
||||
if (end) {
|
||||
do {
|
||||
end--;
|
||||
} while (end && (buffer[end] & 0xC0) == 0x80);
|
||||
}
|
||||
|
||||
SStrCopy(&buffer[end], "...", STORM_MAX_STR);
|
||||
|
||||
maxChars = TextBlockGetMaxCharsWithinWidthAndHeight(
|
||||
this->m_font,
|
||||
buffer,
|
||||
scaledFontHeight,
|
||||
width,
|
||||
height,
|
||||
end + 3,
|
||||
scaledShadowOffset,
|
||||
this->m_layoutScale,
|
||||
scaledSpacing,
|
||||
this->m_styleFlags
|
||||
);
|
||||
} while (end && maxChars < end + 3);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint32_t CSimpleFontString::GetFontFlags() {
|
||||
if (this->m_font) {
|
||||
return TextBlockGetFontFlags(this->m_font);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float CSimpleFontString::GetFontHeight(bool a2) {
|
||||
float fontHeight = this->m_fontHeight;
|
||||
|
||||
if (a2 && this->m_font && this->m_styleFlags & 0x200) {
|
||||
auto font = TextBlockGetFontPtr(this->m_font);
|
||||
float ndcHeight = GxuFontGetOneToOneHeight(font) / this->m_layoutScale;
|
||||
NDCToDDC(0.0f, ndcHeight, nullptr, &fontHeight);
|
||||
}
|
||||
|
||||
return fontHeight;
|
||||
}
|
||||
|
||||
const char* CSimpleFontString::GetFontName() {
|
||||
return this->m_font
|
||||
? TextBlockGetFontName(this->m_font)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
float CSimpleFontString::GetHeight() {
|
||||
float v2 = CLayoutFrame::GetHeight();
|
||||
float v9 = v2 == 0.0f ? this->GetStringHeight() : v2;
|
||||
|
||||
float v3 = 1.0f / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float v4 = NDCToDDCWidth(v3);
|
||||
|
||||
return v9 <= v4 ? v4 : v9;
|
||||
}
|
||||
|
||||
uint32_t CSimpleFontString::GetNumCharsWithinWidth(const char* text, uint32_t textBytes, float maxWidth) {
|
||||
if (!this->m_font) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (textBytes == 0) {
|
||||
textBytes = SStrLen(text);
|
||||
}
|
||||
|
||||
float fontHeight = this->GetFontHeight(true);
|
||||
float shadowWidth = this->m_shadowOffset.x;
|
||||
float extent[4];
|
||||
|
||||
return TextBlockGetMaxCharsWithinWidth(
|
||||
this->m_font,
|
||||
text,
|
||||
fontHeight * this->m_layoutScale,
|
||||
maxWidth * this->m_layoutScale,
|
||||
textBytes,
|
||||
extent,
|
||||
shadowWidth * this->m_layoutScale,
|
||||
this->m_layoutScale,
|
||||
0.0f,
|
||||
this->m_styleFlags
|
||||
);
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString::GetScriptMetaTable() {
|
||||
return CSimpleFontString::s_metatable;
|
||||
}
|
||||
|
||||
float CSimpleFontString::GetStringHeight() {
|
||||
if (this->m_cachedHeight == 0.0f && this->m_font) {
|
||||
float width = CLayoutFrame::GetWidth() * this->m_layoutScale;
|
||||
float height = CLayoutFrame::GetHeight() * this->m_layoutScale;
|
||||
|
||||
const char* displayText = this->GetDisplayText(width, height);
|
||||
if (displayText && *displayText) {
|
||||
float fontHeight = this->GetFontHeight(1) * this->m_layoutScale;
|
||||
C2Vector shadowSize = {
|
||||
this->m_shadowOffset.x * this->m_layoutScale,
|
||||
this->m_shadowOffset.y * this->m_layoutScale
|
||||
};
|
||||
|
||||
this->m_cachedHeight = TextBlockGetWrappedTextHeight(
|
||||
this->m_font,
|
||||
displayText,
|
||||
fontHeight,
|
||||
this->GetWidth() * this->m_layoutScale,
|
||||
shadowSize,
|
||||
this->m_layoutScale,
|
||||
this->m_spacing * this->m_layoutScale,
|
||||
this->m_styleFlags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return this->m_cachedHeight / this->m_layoutScale;
|
||||
}
|
||||
|
||||
float CSimpleFontString::GetStringWidth() {
|
||||
if (this->m_cachedWidth == 0.0f && this->m_font) {
|
||||
float width = CLayoutFrame::GetWidth() * this->m_layoutScale;
|
||||
float height = CLayoutFrame::GetHeight() * this->m_layoutScale;
|
||||
|
||||
const char* displayText = this->GetDisplayText(width, height);
|
||||
if (displayText && *displayText) {
|
||||
float fontHeight = this->GetFontHeight(1) * this->m_layoutScale;
|
||||
float shadowWidth = this->m_shadowOffset.x * this->m_layoutScale;
|
||||
size_t displayTextLength = SStrLen(displayText);
|
||||
|
||||
TextBlockGetTextExtent(
|
||||
this->m_font,
|
||||
displayText,
|
||||
displayTextLength,
|
||||
fontHeight,
|
||||
&this->m_cachedWidth,
|
||||
shadowWidth,
|
||||
this->m_layoutScale,
|
||||
0.0f,
|
||||
this->m_styleFlags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return this->m_cachedWidth / this->m_layoutScale;
|
||||
}
|
||||
|
||||
const char* CSimpleFontString::GetText() {
|
||||
return this->m_text;
|
||||
}
|
||||
|
||||
float CSimpleFontString::GetTextWidth(const char* text, uint32_t textBytes) {
|
||||
if (!this->m_font) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (textBytes == 0) {
|
||||
textBytes = SStrLen(text);
|
||||
}
|
||||
|
||||
float fontHeight = this->GetFontHeight(true);
|
||||
float extent = 0.0f;
|
||||
|
||||
TextBlockGetTextExtent(
|
||||
this->m_font,
|
||||
text,
|
||||
textBytes,
|
||||
fontHeight * this->m_layoutScale,
|
||||
&extent,
|
||||
this->m_shadowOffset.x * this->m_layoutScale,
|
||||
this->m_layoutScale,
|
||||
0.0f,
|
||||
this->m_styleFlags
|
||||
);
|
||||
|
||||
float width = extent / this->m_layoutScale;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
float CSimpleFontString::GetWidth() {
|
||||
float v2 = CLayoutFrame::GetWidth();
|
||||
float v9 = v2 == 0.0f ? this->GetStringWidth() : v2;
|
||||
|
||||
float v3 = 1.0f / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float v4 = NDCToDDCWidth(v3);
|
||||
|
||||
return v9 <= v4 ? v4 : v9;
|
||||
}
|
||||
|
||||
void CSimpleFontString::LoadXML(XMLNode* node, CStatus* status) {
|
||||
const char* inheritsAttr = node->GetAttributeByName("inherits");
|
||||
if (inheritsAttr && *inheritsAttr) {
|
||||
auto font = CSimpleFont::GetFont(inheritsAttr, 0);
|
||||
|
||||
if (font) {
|
||||
if (this->m_unk12b) {
|
||||
this->SetFontObject(font);
|
||||
}
|
||||
} else {
|
||||
const char* tainted;
|
||||
bool locked;
|
||||
|
||||
XMLNode* inheritsNode = FrameXML_AcquireHashNode(inheritsAttr, tainted, locked);
|
||||
|
||||
if (inheritsNode) {
|
||||
if (locked) {
|
||||
status->Add(STATUS_WARNING, "Recursively inherited node: %s", inheritsAttr);
|
||||
} else {
|
||||
this->LoadXML(inheritsNode, status);
|
||||
FrameXML_ReleaseHashNode(inheritsAttr);
|
||||
}
|
||||
} else {
|
||||
status->Add(STATUS_WARNING, "Couldn't find inherited node: %s", inheritsAttr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleRegion::LoadXML(node, status);
|
||||
|
||||
const char* hiddenAttr = node->GetAttributeByName("hidden");
|
||||
if (hiddenAttr && *hiddenAttr) {
|
||||
bool hide = StringToBOOL(hiddenAttr);
|
||||
|
||||
if (hide) {
|
||||
this->Hide();
|
||||
} else {
|
||||
this->Show();
|
||||
}
|
||||
}
|
||||
|
||||
const char* textAttr = node->GetAttributeByName("text");
|
||||
if (textAttr && *textAttr) {
|
||||
const char* text = FrameScript_GetText(textAttr, -1, GENDER_NOT_APPLICABLE);
|
||||
this->SetText(text && *text ? text : textAttr, 1);
|
||||
}
|
||||
|
||||
const char* nonSpaceWrapAttr = node->GetAttributeByName("nonspacewrap");
|
||||
if (nonSpaceWrapAttr && *nonSpaceWrapAttr) {
|
||||
this->SetNonSpaceWrap(StringToBOOL(nonSpaceWrapAttr));
|
||||
}
|
||||
|
||||
const char* wordWrapAttr = node->GetAttributeByName("wordwrap");
|
||||
if (wordWrapAttr && *wordWrapAttr) {
|
||||
this->SetNonWordWrap(!StringToBOOL(wordWrapAttr));
|
||||
}
|
||||
|
||||
const char* bytesAttr = node->GetAttributeByName("bytes");
|
||||
if (bytesAttr && *bytesAttr) {
|
||||
uint32_t length = SStrToInt(bytesAttr);
|
||||
this->SetTextLength(length);
|
||||
}
|
||||
|
||||
if (!this->m_unk12b) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* fontAttr = node->GetAttributeByName("font");
|
||||
if (fontAttr && *fontAttr) {
|
||||
auto font = CSimpleFont::GetFont(fontAttr, 0);
|
||||
|
||||
if (font) {
|
||||
this->SetFontObject(font);
|
||||
} else {
|
||||
float fontHeight = 0.0f;
|
||||
|
||||
XMLNode* fontHeightNode = node->GetChildByName("FontHeight");
|
||||
if (fontHeightNode) {
|
||||
LoadXML_Value(fontHeightNode, fontHeight, status);
|
||||
}
|
||||
|
||||
if (fontHeight == 0.0f) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"FontString %s: invalid font height %f in %s element",
|
||||
this->GetDisplayName(),
|
||||
fontHeight,
|
||||
node->GetName()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t fontFlags = 0;
|
||||
|
||||
const char* outlineAttr = node->GetAttributeByName("outline");
|
||||
if (outlineAttr && *outlineAttr) {
|
||||
if (!SStrCmpI(outlineAttr, "NORMAL", STORM_MAX_STR)) {
|
||||
fontFlags |= FONT_OUTLINE;
|
||||
} else if (!SStrCmpI(outlineAttr, "THICK", STORM_MAX_STR)) {
|
||||
fontFlags |= (FONT_OUTLINE | FONT_THICKOUTLINE);
|
||||
}
|
||||
}
|
||||
|
||||
const char* monochromeAttr = node->GetAttributeByName("monochrome");
|
||||
if (monochromeAttr && *monochromeAttr && StringToBOOL(monochromeAttr)) {
|
||||
fontFlags |= FONT_MONOCHROME;
|
||||
}
|
||||
|
||||
if (this->SetFont(fontAttr, fontHeight, fontFlags, false)) {
|
||||
this->m_fontableFlags &= ~FLAG_FONT_UPDATE;
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"FontString %s: Unable to load font file %s",
|
||||
this->GetDisplayName(),
|
||||
fontAttr
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* spacingAttr = node->GetAttributeByName("spacing");
|
||||
if (spacingAttr && *spacingAttr) {
|
||||
float spacing = SStrToFloat(spacingAttr);
|
||||
float ndcSpacing = spacing / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcSpacing = NDCToDDCWidth(ndcSpacing);
|
||||
|
||||
this->SetSpacing(ddcSpacing);
|
||||
this->m_fontableFlags &= ~FLAG_SPACING_UPDATE;
|
||||
}
|
||||
|
||||
const char* justifyVAttr = node->GetAttributeByName("justifyV");
|
||||
if (justifyVAttr && *justifyVAttr) {
|
||||
uint32_t justify;
|
||||
|
||||
if (StringToJustify(justifyVAttr, justify)) {
|
||||
this->SetJustifyV(justify);
|
||||
this->m_fontableFlags &= ~FLAG_STYLE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
const char* justifyHAttr = node->GetAttributeByName("justifyH");
|
||||
if (justifyHAttr && *justifyHAttr) {
|
||||
uint32_t justify;
|
||||
|
||||
if (StringToJustify(justifyHAttr, justify)) {
|
||||
this->SetJustifyH(justify);
|
||||
this->m_fontableFlags &= ~FLAG_STYLE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
const char* indentedAttr = node->GetAttributeByName("indented");
|
||||
if (indentedAttr && *indentedAttr) {
|
||||
bool indented = StringToBOOL(indentedAttr);
|
||||
this->SetIndentedWordWrap(indented);
|
||||
}
|
||||
|
||||
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "Color", STORM_MAX_STR)) {
|
||||
CImVector color;
|
||||
LoadXML_Color(child, color);
|
||||
this->SetVertexColor(color);
|
||||
this->m_fontableFlags &= ~FLAG_COLOR_UPDATE;
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "Shadow", STORM_MAX_STR)) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - alpha
|
||||
|
||||
// TODO
|
||||
// - children
|
||||
}
|
||||
|
||||
void CSimpleFontString::OnColorChanged(bool a2) {
|
||||
CSimpleRegion::OnColorChanged(a2);
|
||||
|
||||
if (this->m_string) {
|
||||
CImVector color = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
if (this->m_colorCount == 1) {
|
||||
color = this->m_color[0];
|
||||
}
|
||||
|
||||
TextBlockUpdateColor(this->m_string, color);
|
||||
|
||||
if (this->m_styleFlags & 0x100) {
|
||||
CImVector shadowColor = this->m_shadowColor;
|
||||
|
||||
C2Vector shadowOffset = {
|
||||
this->m_shadowOffset.x * this->m_layoutScale,
|
||||
this->m_shadowOffset.y * this->m_layoutScale
|
||||
};
|
||||
|
||||
// TODO
|
||||
// - shadow color alpha calculation
|
||||
|
||||
TextBlockAddShadow(this->m_string, shadowColor, shadowOffset);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - embedded texture color updates
|
||||
}
|
||||
|
||||
void CSimpleFontString::OnScreenSizeChanged() {
|
||||
this->m_cachedWidth = 0.0f;
|
||||
this->m_cachedHeight = 0.0f;
|
||||
this->Resize(0);
|
||||
}
|
||||
|
||||
void CSimpleFontString::OnFrameSizeChanged(const CRect& rect) {
|
||||
CLayoutFrame::OnFrameSizeChanged(rect);
|
||||
|
||||
if (
|
||||
this->m_string
|
||||
&& AreEqual(rect.maxX - rect.minX, this->m_rect.maxX - this->m_rect.minX, WHOA_EPSILON_2)
|
||||
&& AreEqual(rect.maxY - rect.minY, this->m_rect.maxY - this->m_rect.minY, WHOA_EPSILON_2)
|
||||
) {
|
||||
C3Vector pos = {
|
||||
this->m_justificationOffset.x * this->m_layoutScale + this->m_rect.minX,
|
||||
this->m_justificationOffset.y * this->m_layoutScale + this->m_rect.minY,
|
||||
this->m_layoutDepth
|
||||
};
|
||||
|
||||
TextBlockSetStringPos(this->m_string, pos);
|
||||
|
||||
if (rect.Sub4826D0() != this->m_rect.Sub4826D0()) {
|
||||
this->OnRegionChanged();
|
||||
}
|
||||
} else {
|
||||
this->UpdateString();
|
||||
}
|
||||
|
||||
// TODO logic if region flags & 0x40
|
||||
|
||||
if (this->m_parent) {
|
||||
this->m_parent->NotifyScrollParent();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::PostLoadXML(XMLNode* node, CStatus* status) {
|
||||
if (this->m_parent) {
|
||||
int32_t hasPoint = 0;
|
||||
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
auto point = this->m_points[i];
|
||||
|
||||
if (point && !(point->m_flags & 0x08)) {
|
||||
hasPoint = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasPoint) {
|
||||
float offsetX = 0.0f;
|
||||
float offsetY = 0.0f;
|
||||
|
||||
if (this->m_styleFlags & 0x01) {
|
||||
this->SetPoint(FRAMEPOINT_LEFT, this->m_parent, FRAMEPOINT_LEFT, offsetX, offsetY, 1);
|
||||
} else if (this->m_styleFlags & 0x04) {
|
||||
this->SetPoint(FRAMEPOINT_RIGHT, this->m_parent, FRAMEPOINT_RIGHT, offsetX, offsetY, 1);
|
||||
} else {
|
||||
this->SetPoint(FRAMEPOINT_CENTER, this->m_parent, FRAMEPOINT_CENTER, offsetX, offsetY, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::RefreshEmbeddedTextures() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleFontString::RemoveShadow() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString::SetFont(const char* fontName, float fontHeight, uint32_t fontFlags, bool force) {
|
||||
if (!force) {
|
||||
const char* curFontName = this->GetFontName();
|
||||
|
||||
if (
|
||||
fontName
|
||||
&& curFontName
|
||||
&& !SStrCmpI(fontName, curFontName, STORM_MAX_STR)
|
||||
&& AreEqual(fontHeight, this->m_fontHeight, WHOA_EPSILON_1)
|
||||
&& fontFlags == this->GetFontFlags()
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
HTEXTFONT font = nullptr;
|
||||
|
||||
if (fontName && fontHeight != 0.0f) {
|
||||
font = TextBlockGenerateFont(fontName, fontFlags, fontHeight * this->m_layoutScale);
|
||||
|
||||
if (!font) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_fontHeight = fontHeight;
|
||||
|
||||
if (this->m_string) {
|
||||
HandleClose(this->m_string);
|
||||
this->m_string = nullptr;
|
||||
}
|
||||
|
||||
if (this->m_font) {
|
||||
HandleClose(this->m_font);
|
||||
}
|
||||
|
||||
this->m_font = font;
|
||||
|
||||
if (font) {
|
||||
this->m_cachedWidth = 0.0f;
|
||||
this->m_cachedHeight = 0.0f;
|
||||
}
|
||||
|
||||
this->m_flags &= ~0x1;
|
||||
this->Resize(0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetIndentedWordWrap(bool a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetJustificationOffset(float x, float y) {
|
||||
if (this->m_justificationOffset.x == x && this->m_justificationOffset.y == y) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_justificationOffset = { x, y };
|
||||
|
||||
if (this->m_string) {
|
||||
C3Vector pos = {
|
||||
this->m_rect.minX + (this->m_justificationOffset.x * this->m_layoutScale),
|
||||
this->m_rect.minY + (this->m_justificationOffset.y * this->m_layoutScale),
|
||||
this->m_layoutDepth
|
||||
};
|
||||
|
||||
TextBlockSetStringPos(this->m_string, pos);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetJustifyV(uint8_t justify) {
|
||||
this->m_settableStyleFlags &= ~(0x8 | 0x10 | 0x20);
|
||||
uint32_t newStyleFlags = this->m_styleFlags ^ ((justify ^ this->m_styleFlags) & (0x8 | 0x10 | 0x20));
|
||||
|
||||
if (this->m_styleFlags != newStyleFlags) {
|
||||
this->m_styleFlags = newStyleFlags;
|
||||
|
||||
if (this->m_string) {
|
||||
this->UpdateString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetJustifyH(uint8_t justify) {
|
||||
this->m_settableStyleFlags &= ~(0x1 | 0x2 | 0x4);
|
||||
uint32_t newStyleFlags = this->m_styleFlags ^ ((justify ^ this->m_styleFlags) & (0x1 | 0x2 | 0x4));
|
||||
|
||||
if (this->m_styleFlags != newStyleFlags) {
|
||||
this->m_styleFlags = newStyleFlags;
|
||||
|
||||
if (this->m_string) {
|
||||
this->UpdateString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetNonSpaceWrap(int32_t a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetSpacing(float spacing) {
|
||||
if (spacing < 0.0f) {
|
||||
spacing = 0.0f;
|
||||
}
|
||||
|
||||
if (fabs(spacing - this->m_spacing) >= WHOA_EPSILON_1) {
|
||||
this->m_spacing = spacing;
|
||||
this->m_cachedHeight = 0.0f;
|
||||
|
||||
if (this->m_string) {
|
||||
this->UpdateString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetStyleFlags(uint32_t styleFlags) {
|
||||
uint32_t newStyleFlags = (styleFlags & this->m_settableStyleFlags) | (this->m_styleFlags & ~this->m_settableStyleFlags);
|
||||
|
||||
if (this->m_styleFlags != newStyleFlags) {
|
||||
this->m_styleFlags = newStyleFlags;
|
||||
|
||||
if (this->m_string) {
|
||||
this->UpdateString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetText(const char* text, int32_t a3) {
|
||||
if (text && a3) {
|
||||
text = LanguageProcess(text);
|
||||
}
|
||||
|
||||
if (text && *text) {
|
||||
if (this->m_text && !SStrCmp(text, this->m_text, STORM_MAX_STR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_textMaxSize & 0xFFFF) {
|
||||
SStrCopy(this->m_text, text, this->m_textMaxSize & 0xFFFF);
|
||||
} else {
|
||||
size_t textSize = SStrLen(text);
|
||||
|
||||
if (textSize <= this->m_textCurSize) {
|
||||
SStrCopy(this->m_text, text, STORM_MAX_STR);
|
||||
} else {
|
||||
if (this->m_text) {
|
||||
SMemFree(this->m_text, __FILE__, __LINE__, 0x0);
|
||||
}
|
||||
|
||||
this->m_text = SStrDupA(text, __FILE__, __LINE__);
|
||||
this->m_textCurSize = textSize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->m_text) {
|
||||
*this->m_text = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
this->ClearString();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString::Sub482AC0() {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetTextLength(uint32_t a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleFontString::SetNonWordWrap(int32_t a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleFontString::UpdateString() {
|
||||
if (!(this->m_flags & 0x1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_string) {
|
||||
HandleClose(this->m_string);
|
||||
this->m_string = nullptr;
|
||||
}
|
||||
|
||||
this->FreeEmbeddedTextures();
|
||||
|
||||
if (this->m_rect.maxY <= this->m_rect.minY || this->m_rect.maxX <= this->m_rect.minX) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_font && this->m_text && *this->m_text) {
|
||||
C3Vector pos = {
|
||||
this->m_rect.minX + this->m_justificationOffset.x * this->m_layoutScale,
|
||||
this->m_rect.minY + this->m_justificationOffset.y * this->m_layoutScale,
|
||||
this->m_layoutDepth
|
||||
};
|
||||
|
||||
float width = this->GetWidth();
|
||||
float blockWidth = width == 0.0f ? this->m_cachedWidth : width * this->m_layoutScale;
|
||||
if (NotEqual(blockWidth, this->m_rect.maxX - this->m_rect.minX, WHOA_EPSILON_2)) {
|
||||
blockWidth = this->m_rect.maxX - this->m_rect.minX;
|
||||
}
|
||||
|
||||
float height = this->GetHeight();
|
||||
float blockHeight = height == 0.0f ? this->m_cachedHeight : height * this->m_layoutScale;
|
||||
if (NotEqual(blockHeight, this->m_rect.maxY - this->m_rect.minY, WHOA_EPSILON_2)) {
|
||||
blockHeight = this->m_rect.maxY - this->m_rect.minY;
|
||||
}
|
||||
|
||||
const char* displayText = this->GetDisplayText(blockWidth, blockHeight);
|
||||
|
||||
uint32_t styleFlags = this->m_styleFlags;
|
||||
|
||||
if (!(this->m_styleFlags & 0x400)) {
|
||||
// TODO
|
||||
|
||||
styleFlags |= 0x400;
|
||||
}
|
||||
|
||||
CImVector color = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
if (this->m_colorCount) {
|
||||
color = this->m_color[0];
|
||||
}
|
||||
|
||||
float scale = this->m_layoutScale;
|
||||
float lineSpacing = this->m_spacing * this->m_layoutScale;
|
||||
float fontHeight = this->GetFontHeight(true) * this->m_layoutScale;
|
||||
|
||||
this->m_string = TextBlockCreate(
|
||||
this->m_font,
|
||||
displayText,
|
||||
color,
|
||||
pos,
|
||||
fontHeight,
|
||||
blockWidth,
|
||||
blockHeight,
|
||||
styleFlags,
|
||||
0.0f,
|
||||
lineSpacing,
|
||||
scale
|
||||
);
|
||||
|
||||
if (this->m_styleFlags & 0x100) {
|
||||
auto shadowColor = this->m_shadowColor;
|
||||
// TODO alpha manipulation
|
||||
|
||||
auto shadowOffset = this->m_shadowOffset;
|
||||
shadowOffset.x *= this->m_layoutScale;
|
||||
shadowOffset.y *= this->m_layoutScale;
|
||||
|
||||
TextBlockAddShadow(this->m_string, shadowColor, shadowOffset);
|
||||
}
|
||||
|
||||
if (this->m_alphaGradientStart > 0) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
this->RefreshEmbeddedTextures();
|
||||
|
||||
// TODO
|
||||
// - logic if region flags & 0x40, CLayoutFrame::AnimData_HasActivePosition?
|
||||
}
|
||||
|
||||
this->OnRegionChanged();
|
||||
}
|
||||
89
src/ui/CSimpleFontString.hpp
Normal file
89
src/ui/CSimpleFontString.hpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef UI_C_SIMPLE_FONT_STRING_HPP
|
||||
#define UI_C_SIMPLE_FONT_STRING_HPP
|
||||
|
||||
#include "gx/Font.hpp"
|
||||
#include "ui/CSimpleFontable.hpp"
|
||||
#include "ui/CSimpleRegion.hpp"
|
||||
|
||||
class CRenderBatch;
|
||||
class CSimpleFrame;
|
||||
|
||||
class CSimpleFontString : public CSimpleRegion, public CSimpleFontable {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_count;
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
HTEXTFONT m_font = nullptr;
|
||||
float m_fontHeight = 0.0f;
|
||||
uint16_t m_textMaxSize = 0;
|
||||
uint16_t m_textCurSize = 0;
|
||||
char* m_text = nullptr;
|
||||
float m_spacing = 0.0f;
|
||||
HTEXTBLOCK m_string = nullptr;
|
||||
float m_cachedWidth = 0.0f;
|
||||
float m_cachedHeight = 0.0f;
|
||||
CImVector m_shadowColor;
|
||||
C2Vector m_shadowOffset;
|
||||
C2Vector m_justificationOffset;
|
||||
int16_t m_alphaGradientStart = -1;
|
||||
int16_t m_alphaGradientLength;
|
||||
uint32_t m_styleFlags = 0x2 | 0x10 | 0x200;
|
||||
uint32_t m_settableStyleFlags = 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40 | 0x1000 | 0x20000;
|
||||
uint32_t m_maxLines : 24;
|
||||
uint32_t m_unk12b : 1;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CSimpleFontString();
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual void OnColorChanged(bool);
|
||||
virtual void OnScreenSizeChanged();
|
||||
virtual void Draw(CRenderBatch*);
|
||||
virtual float GetWidth(void);
|
||||
virtual float GetHeight(void);
|
||||
virtual void OnFrameSizeChanged(const CRect&);
|
||||
virtual void FontObjectUpdated(CSimpleFontStringAttributes&);
|
||||
|
||||
// Member functions
|
||||
CSimpleFontString(CSimpleFrame*, uint32_t, int32_t);
|
||||
void AddShadow(const CImVector&, const C2Vector&);
|
||||
void ClearString(void);
|
||||
void DrawEmbeddedTextures(CRenderBatch*);
|
||||
void FreeEmbeddedTextures(void);
|
||||
const char* GetDisplayText(float, float);
|
||||
uint32_t GetFontFlags(void);
|
||||
float GetFontHeight(bool);
|
||||
const char* GetFontName(void);
|
||||
uint32_t GetNumCharsWithinWidth(const char*, uint32_t, float);
|
||||
float GetStringHeight(void);
|
||||
float GetStringWidth(void);
|
||||
const char* GetText(void);
|
||||
float GetTextWidth(const char*, uint32_t);
|
||||
void PostLoadXML(XMLNode*, CStatus*);
|
||||
void RefreshEmbeddedTextures(void);
|
||||
void RemoveShadow(void);
|
||||
int32_t SetFont(const char*, float, uint32_t, bool);
|
||||
void SetIndentedWordWrap(bool);
|
||||
void SetJustificationOffset(float, float);
|
||||
void SetJustifyV(uint8_t);
|
||||
void SetJustifyH(uint8_t);
|
||||
void SetNonSpaceWrap(int32_t);
|
||||
void SetNonWordWrap(int32_t);
|
||||
void SetSpacing(float);
|
||||
void SetStyleFlags(uint32_t);
|
||||
void SetText(const char*, int32_t);
|
||||
void SetTextLength(uint32_t);
|
||||
int32_t Sub482AC0();
|
||||
void UpdateString(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
179
src/ui/CSimpleFontStringAttributes.cpp
Normal file
179
src/ui/CSimpleFontStringAttributes.cpp
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
#include "ui/CSimpleFontStringAttributes.hpp"
|
||||
#include "gx/Font.hpp"
|
||||
#include "math/Utils.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
void CSimpleFontStringAttributes::SetColor(const CImVector& color) {
|
||||
if (this->m_color == color && this->m_flags & 0x400) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_color = color;
|
||||
this->m_flags |= (0x4 | 0x400);
|
||||
}
|
||||
|
||||
int32_t CSimpleFontStringAttributes::SetFont(const char* fontName, float fontHeight, uint32_t fontFlags) {
|
||||
if (!fontName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return early if existing attributes match arguments
|
||||
if (
|
||||
this->m_font.GetString()
|
||||
&& !SStrCmpI(fontName, this->m_font.m_str, STORM_MAX_STR)
|
||||
&& AreEqual(fontHeight, this->m_fontHeight, WHOA_EPSILON_1)
|
||||
&& fontFlags == this->m_fontFlags
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fontHeight <= 0.0f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto v6 = TextBlockGenerateFont(fontName, fontFlags, fontHeight);
|
||||
|
||||
if (!v6) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HandleClose(v6);
|
||||
|
||||
this->m_font.Copy(fontName);
|
||||
this->m_fontHeight = fontHeight;
|
||||
this->m_fontFlags = fontFlags;
|
||||
this->m_flags |= (0x1 | 0x100);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetIndented(bool indented) {
|
||||
uint32_t styleFlags = indented
|
||||
? this->m_styleFlags | 0x20000
|
||||
: this->m_styleFlags & ~0x20000;
|
||||
|
||||
if (this->m_styleFlags == styleFlags && this->m_flags & 0x200) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_styleFlags = styleFlags;
|
||||
this->m_flags |= (0x2 | 0x200);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetJustifyH(uint8_t justify) {
|
||||
uint32_t styleFlags = this->m_styleFlags ^ ((justify ^ this->m_styleFlags) & 0x7);
|
||||
|
||||
if (this->m_styleFlags == styleFlags && this->m_flags & 0x200) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_styleFlags = styleFlags;
|
||||
this->m_flags |= (0x2 | 0x200);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetJustifyV(uint8_t justify) {
|
||||
uint32_t styleFlags = this->m_styleFlags ^ ((justify ^ this->m_styleFlags) & 0x38);
|
||||
|
||||
if (this->m_styleFlags == styleFlags && this->m_flags & 0x200) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_styleFlags = styleFlags;
|
||||
this->m_flags |= (0x2 | 0x200);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetNonSpaceWrap(bool wrap) {
|
||||
uint32_t styleFlags = wrap
|
||||
? this->m_styleFlags | 0x1000
|
||||
: this->m_styleFlags & ~0x1000;
|
||||
|
||||
if (this->m_styleFlags == styleFlags && this->m_flags & 0x200) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_styleFlags = styleFlags;
|
||||
this->m_flags |= (0x2 | 0x200);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetShadow(const CImVector& shadowColor, const C2Vector& shadowOffset) {
|
||||
if (this->m_shadowColor == shadowColor && this->m_shadowOffset == shadowOffset && this->m_flags & 0x800) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_shadowColor = shadowColor;
|
||||
this->m_shadowOffset = shadowOffset;
|
||||
this->m_flags |= (0x8 | 0x800);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetSpacing(float spacing) {
|
||||
if (AreEqual(spacing, this->m_spacing, WHOA_EPSILON_1) && this->m_flags & 0x1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_spacing = spacing;
|
||||
this->m_flags |= (0x10 | 0x1000);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::SetStyleFlags(uint32_t styleFlags) {
|
||||
if (this->m_styleFlags == styleFlags && this->m_flags & 0x200) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_styleFlags = styleFlags;
|
||||
this->m_flags |= (0x2 | 0x200);
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::Update(CSimpleFontString* fontString, uint32_t flags) {
|
||||
STORM_ASSERT(fontString);
|
||||
|
||||
uint32_t v5 = flags & this->m_flags;
|
||||
|
||||
if (this->m_flags & 0x100 && v5 & 0x1) {
|
||||
fontString->SetFont(this->m_font.GetString(), this->m_fontHeight, this->m_fontFlags, 0);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x200 && v5 & 0x2) {
|
||||
fontString->SetStyleFlags(this->m_styleFlags);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x400 && v5 & 0x4) {
|
||||
fontString->SetVertexColor(this->m_color);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x800 && v5 & 0x8) {
|
||||
if (this->m_shadowOffset.x == 0.0f && this->m_shadowOffset.y == 0.0f) {
|
||||
fontString->RemoveShadow();
|
||||
} else {
|
||||
fontString->AddShadow(this->m_shadowColor, this->m_shadowOffset);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x1000 && v5 & 0x10) {
|
||||
fontString->SetSpacing(this->m_spacing);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleFontStringAttributes::Update(CSimpleFontStringAttributes& attributes, uint32_t flags) {
|
||||
uint32_t v4 = flags & this->m_flags;
|
||||
|
||||
if (this->m_flags & 0x100 && v4 & 0x1) {
|
||||
attributes.SetFont(this->m_font.GetString(), this->m_fontHeight, this->m_fontFlags);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x200 && v4 & 0x2) {
|
||||
attributes.SetStyleFlags(this->m_styleFlags);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x400 && v4 & 0x4) {
|
||||
attributes.SetColor(this->m_color);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x800 && v4 & 0x8) {
|
||||
attributes.SetShadow(this->m_shadowColor, this->m_shadowOffset);
|
||||
}
|
||||
|
||||
if (this->m_flags & 0x1000 && v4 & 0x10) {
|
||||
attributes.SetSpacing(this->m_spacing);
|
||||
}
|
||||
}
|
||||
37
src/ui/CSimpleFontStringAttributes.hpp
Normal file
37
src/ui/CSimpleFontStringAttributes.hpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef UI_C_SIMPLE_FONT_STRING_ATTRIBUTES_HPP
|
||||
#define UI_C_SIMPLE_FONT_STRING_ATTRIBUTES_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <common/String.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CSimpleFontString;
|
||||
|
||||
class CSimpleFontStringAttributes {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t m_flags = 0;
|
||||
RCString m_font;
|
||||
float m_fontHeight = 0.0f;
|
||||
uint32_t m_fontFlags = 0;
|
||||
float m_spacing = 0.0f;
|
||||
uint32_t m_styleFlags = 0x2 | 0x10 | 0x200;
|
||||
CImVector m_color = { 0, 0, 0, 0 };
|
||||
CImVector m_shadowColor = { 0, 0, 0, 0 };
|
||||
C2Vector m_shadowOffset;
|
||||
|
||||
// Member functions
|
||||
void SetColor(const CImVector&);
|
||||
int32_t SetFont(const char*, float, uint32_t);
|
||||
void SetIndented(bool);
|
||||
void SetJustifyV(uint8_t);
|
||||
void SetJustifyH(uint8_t);
|
||||
void SetNonSpaceWrap(bool);
|
||||
void SetShadow(const CImVector&, const C2Vector&);
|
||||
void SetSpacing(float);
|
||||
void SetStyleFlags(uint32_t);
|
||||
void Update(CSimpleFontString*, uint32_t);
|
||||
void Update(CSimpleFontStringAttributes&, uint32_t);
|
||||
};
|
||||
|
||||
#endif
|
||||
264
src/ui/CSimpleFontStringScript.cpp
Normal file
264
src/ui/CSimpleFontStringScript.cpp
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
#include "ui/CSimpleFontStringScript.hpp"
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleFontString_IsObjectType(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetObjectType(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetDrawLayer(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetDrawLayer(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetVertexColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetAlphaGradient(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_Show(lua_State* L) {
|
||||
auto type = CSimpleFontString::GetObjectType();
|
||||
auto string = static_cast<CSimpleFontString*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
string->Show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_Hide(lua_State* L) {
|
||||
auto type = CSimpleFontString::GetObjectType();
|
||||
auto string = static_cast<CSimpleFontString*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
string->Hide();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_IsVisible(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_IsShown(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetFontObject(lua_State* L) {
|
||||
auto type = CSimpleFontString::GetObjectType();
|
||||
auto string = static_cast<CSimpleFontString*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
CSimpleFont* font = nullptr;
|
||||
|
||||
if (lua_type(L, 2) == LUA_TTABLE) {
|
||||
lua_rawgeti(L, 2, 0);
|
||||
font = static_cast<CSimpleFont*>(lua_touserdata(L, -1));
|
||||
lua_settop(L, -2);
|
||||
|
||||
if (!font) {
|
||||
luaL_error(L, "%s:SetFontObject(): Couldn't find 'this' in font object", string->GetDisplayName());
|
||||
}
|
||||
|
||||
if (!font->IsA(CSimpleFont::GetObjectType())) {
|
||||
luaL_error(L, "%s:SetFontObject(): Wrong object type, expected font", string->GetDisplayName());
|
||||
}
|
||||
} else if (lua_type(L, 2) == LUA_TSTRING) {
|
||||
auto fontName = lua_tolstring(L, 2, nullptr);
|
||||
font = CSimpleFont::GetFont(fontName, 0);
|
||||
|
||||
if (!font) {
|
||||
luaL_error(L, "%s:SetFontObject(): Couldn't find font named %s", string->GetDisplayName(), fontName);
|
||||
}
|
||||
} else if (lua_type(L, 2) != LUA_TNIL) {
|
||||
luaL_error(L, "Usage: %s:SetFontObject(font or \"font\" or nil)", string->GetDisplayName());
|
||||
}
|
||||
|
||||
string->SetFontObject(font);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetText(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetFieldSize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetText(lua_State* L) {
|
||||
auto type = CSimpleFontString::GetObjectType();
|
||||
auto string = static_cast<CSimpleFontString*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!string->m_font) {
|
||||
luaL_error(L, "%s:SetText(): Font not set", string->GetDisplayName());
|
||||
}
|
||||
|
||||
const char* text = lua_tolstring(L, 2, 0);
|
||||
string->SetText(text, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetFormattedText(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetTextHeight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetStringWidth(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetStringHeight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_CanNonSpaceWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetNonSpaceWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_CanWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_GetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFontString_SetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleFontStringMethods[NUM_SIMPLE_FONT_STRING_SCRIPT_METHODS] = {
|
||||
{ "IsObjectType", &CSimpleFontString_IsObjectType },
|
||||
{ "GetObjectType", &CSimpleFontString_GetObjectType },
|
||||
{ "GetDrawLayer", &CSimpleFontString_GetDrawLayer },
|
||||
{ "SetDrawLayer", &CSimpleFontString_SetDrawLayer },
|
||||
{ "SetVertexColor", &CSimpleFontString_SetVertexColor },
|
||||
{ "GetAlpha", &CSimpleFontString_GetAlpha },
|
||||
{ "SetAlpha", &CSimpleFontString_SetAlpha },
|
||||
{ "SetAlphaGradient", &CSimpleFontString_SetAlphaGradient },
|
||||
{ "Show", &CSimpleFontString_Show },
|
||||
{ "Hide", &CSimpleFontString_Hide },
|
||||
{ "IsVisible", &CSimpleFontString_IsVisible },
|
||||
{ "IsShown", &CSimpleFontString_IsShown },
|
||||
{ "GetFontObject", &CSimpleFontString_GetFontObject },
|
||||
{ "SetFontObject", &CSimpleFontString_SetFontObject },
|
||||
{ "GetFont", &CSimpleFontString_GetFont },
|
||||
{ "SetFont", &CSimpleFontString_SetFont },
|
||||
{ "GetText", &CSimpleFontString_GetText },
|
||||
{ "GetFieldSize", &CSimpleFontString_GetFieldSize },
|
||||
{ "SetText", &CSimpleFontString_SetText },
|
||||
{ "SetFormattedText", &CSimpleFontString_SetFormattedText },
|
||||
{ "GetTextColor", &CSimpleFontString_GetTextColor },
|
||||
{ "SetTextColor", &CSimpleFontString_SetTextColor },
|
||||
{ "GetShadowColor", &CSimpleFontString_GetShadowColor },
|
||||
{ "SetShadowColor", &CSimpleFontString_SetShadowColor },
|
||||
{ "GetShadowOffset", &CSimpleFontString_GetShadowOffset },
|
||||
{ "SetShadowOffset", &CSimpleFontString_SetShadowOffset },
|
||||
{ "GetSpacing", &CSimpleFontString_GetSpacing },
|
||||
{ "SetSpacing", &CSimpleFontString_SetSpacing },
|
||||
{ "SetTextHeight", &CSimpleFontString_SetTextHeight },
|
||||
{ "GetStringWidth", &CSimpleFontString_GetStringWidth },
|
||||
{ "GetStringHeight", &CSimpleFontString_GetStringHeight },
|
||||
{ "GetJustifyH", &CSimpleFontString_GetJustifyH },
|
||||
{ "SetJustifyH", &CSimpleFontString_SetJustifyH },
|
||||
{ "GetJustifyV", &CSimpleFontString_GetJustifyV },
|
||||
{ "SetJustifyV", &CSimpleFontString_SetJustifyV },
|
||||
{ "CanNonSpaceWrap", &CSimpleFontString_CanNonSpaceWrap },
|
||||
{ "SetNonSpaceWrap", &CSimpleFontString_SetNonSpaceWrap },
|
||||
{ "CanWordWrap", &CSimpleFontString_CanWordWrap },
|
||||
{ "SetWordWrap", &CSimpleFontString_SetWordWrap },
|
||||
{ "GetIndentedWordWrap", &CSimpleFontString_GetIndentedWordWrap },
|
||||
{ "SetIndentedWordWrap", &CSimpleFontString_SetIndentedWordWrap }
|
||||
};
|
||||
10
src/ui/CSimpleFontStringScript.hpp
Normal file
10
src/ui/CSimpleFontStringScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_FONT_STRING_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_FONT_STRING_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_FONT_STRING_SCRIPT_METHODS 41
|
||||
|
||||
extern FrameScript_Method SimpleFontStringMethods[NUM_SIMPLE_FONT_STRING_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
30
src/ui/CSimpleFontable.cpp
Normal file
30
src/ui/CSimpleFontable.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "ui/CSimpleFontable.hpp"
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
|
||||
CSimpleFontable::~CSimpleFontable() {
|
||||
this->SetFontObject(nullptr);
|
||||
}
|
||||
|
||||
CSimpleFont* CSimpleFontable::GetFontObject() {
|
||||
return this->m_fontObject;
|
||||
}
|
||||
|
||||
void CSimpleFontable::SetFontObject(CSimpleFont* fontObject) {
|
||||
if (this->m_fontObject == fontObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_fontObject) {
|
||||
this->m_fontObject->m_fontableList.UnlinkNode(this);
|
||||
}
|
||||
|
||||
this->m_fontObject = fontObject;
|
||||
|
||||
if (fontObject) {
|
||||
fontObject->m_fontableList.LinkToTail(this);
|
||||
|
||||
fontObject->m_attributes.m_flags |= FLAG_COMPLETE_UPDATE;
|
||||
this->FontObjectUpdated(fontObject->m_attributes);
|
||||
fontObject->m_attributes.m_flags &= ~(FLAG_COMPLETE_UPDATE);
|
||||
}
|
||||
}
|
||||
26
src/ui/CSimpleFontable.hpp
Normal file
26
src/ui/CSimpleFontable.hpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef UI_C_SIMPLE_FONTABLE_HPP
|
||||
#define UI_C_SIMPLE_FONTABLE_HPP
|
||||
|
||||
#include "ui/Types.hpp"
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CSimpleFont;
|
||||
class CSimpleFontStringAttributes;
|
||||
|
||||
class CSimpleFontable {
|
||||
public:
|
||||
// Member variables
|
||||
CSimpleFont* m_fontObject = nullptr;
|
||||
uint32_t m_fontableFlags = FLAG_COMPLETE_UPDATE;
|
||||
TSLink<CSimpleFontable> m_fontableLink;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CSimpleFontable();
|
||||
virtual void FontObjectUpdated(CSimpleFontStringAttributes&) = 0;
|
||||
|
||||
// Member functions
|
||||
CSimpleFont* GetFontObject(void);
|
||||
void SetFontObject(CSimpleFont*);
|
||||
};
|
||||
|
||||
#endif
|
||||
14
src/ui/CSimpleFontedFrame.hpp
Normal file
14
src/ui/CSimpleFontedFrame.hpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef UI_C_SIMPLE_FONTED_FRAME_HPP
|
||||
#define UI_C_SIMPLE_FONTED_FRAME_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CSimpleFontedFrameFont;
|
||||
|
||||
class CSimpleFontedFrame {
|
||||
public:
|
||||
// Virtual member functions
|
||||
virtual void FontUpdated(CSimpleFontedFrameFont*, int32_t) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
19
src/ui/CSimpleFontedFrameFont.hpp
Normal file
19
src/ui/CSimpleFontedFrameFont.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef UI_C_SIMPLE_FONTED_FRAME_FONT_HPP
|
||||
#define UI_C_SIMPLE_FONTED_FRAME_FONT_HPP
|
||||
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
|
||||
class CSimpleFontedFrame;
|
||||
|
||||
class CSimpleFontedFrameFont : public CSimpleFont {
|
||||
public:
|
||||
// Member variables
|
||||
CSimpleFontedFrame* m_frame;
|
||||
|
||||
// Member functions
|
||||
CSimpleFontedFrameFont(CSimpleFontedFrame* frame)
|
||||
: m_frame(frame)
|
||||
{};
|
||||
};
|
||||
|
||||
#endif
|
||||
1584
src/ui/CSimpleFrame.cpp
Normal file
1584
src/ui/CSimpleFrame.cpp
Normal file
File diff suppressed because it is too large
Load diff
162
src/ui/CSimpleFrame.hpp
Normal file
162
src/ui/CSimpleFrame.hpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#ifndef UI_C_SIMPLE_FRAME_HPP
|
||||
#define UI_C_SIMPLE_FRAME_HPP
|
||||
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CScriptRegion.hpp"
|
||||
#include "ui/CSimpleRegion.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CBackdropGenerator;
|
||||
class CCharEvent;
|
||||
class CKeyEvent;
|
||||
class CMouseEvent;
|
||||
class CSimpleTitleRegion;
|
||||
class CSimpleTop;
|
||||
struct lua_State;
|
||||
|
||||
class CSimpleFrame : public CScriptRegion {
|
||||
public:
|
||||
// Static members
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
CSimpleTop* m_top = NULL;
|
||||
CSimpleTitleRegion* m_titleRegion = NULL;
|
||||
int32_t m_intAC = 1;
|
||||
int32_t m_id = 0;
|
||||
uint32_t m_flags = 0;
|
||||
float m_frameScale = 1.0f;
|
||||
float m_depth = 0.0;
|
||||
FRAME_STRATA m_strata = FRAME_STRATA_MEDIUM;
|
||||
int32_t m_level = 0;
|
||||
uint32_t m_eventmask = 0;
|
||||
int32_t m_shown = 0;
|
||||
int32_t m_visible = 0;
|
||||
CRect m_hitRect = {};
|
||||
CRect m_hitOffset = {};
|
||||
int32_t m_highlightLocked = 0;
|
||||
uint32_t m_lookForDrag = 0;
|
||||
int32_t m_mouseDown = 0;
|
||||
int32_t m_dragging = 0;
|
||||
int32_t m_dragButton;
|
||||
C2Vector m_clickPoint;
|
||||
int32_t m_loading = 0;
|
||||
ScriptIx m_onLoad;
|
||||
ScriptIx m_onSizeChanged;
|
||||
ScriptIx m_onUpdate;
|
||||
ScriptIx m_onShow;
|
||||
ScriptIx m_onHide;
|
||||
ScriptIx m_onEnter;
|
||||
ScriptIx m_onLeave;
|
||||
ScriptIx m_onMouseDown;
|
||||
ScriptIx m_onMouseUp;
|
||||
ScriptIx m_onMouseWheel;
|
||||
ScriptIx m_onDragStart;
|
||||
ScriptIx m_onDragStop;
|
||||
ScriptIx m_onReceiveDrag;
|
||||
ScriptIx m_onChar;
|
||||
ScriptIx m_onKeyDown;
|
||||
ScriptIx m_onKeyUp;
|
||||
ScriptIx m_onAttributeChange;
|
||||
ScriptIx m_onEnable;
|
||||
ScriptIx m_onDisable;
|
||||
int32_t m_drawenabled[NUM_SIMPLEFRAME_DRAWLAYERS];
|
||||
CBackdropGenerator* m_backdrop = nullptr;
|
||||
STORM_EXPLICIT_LIST(CSimpleRegion, m_regionLink) m_regions;
|
||||
STORM_EXPLICIT_LIST(CSimpleRegion, m_layerLink) m_drawlayers[NUM_SIMPLEFRAME_DRAWLAYERS];
|
||||
uint32_t m_batchDirty = 0;
|
||||
CRenderBatch* m_batch[NUM_SIMPLEFRAME_DRAWLAYERS] = {};
|
||||
STORM_EXPLICIT_LIST(CRenderBatch, renderLink) m_renderList;
|
||||
TSList<SIMPLEFRAMENODE, TSGetLink<SIMPLEFRAMENODE>> m_children;
|
||||
TSLink<CSimpleFrame> m_framesLink;
|
||||
TSLink<CSimpleFrame> m_destroyedLink;
|
||||
TSLink<CSimpleFrame> m_strataLink;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CSimpleFrame();
|
||||
virtual ScriptIx* GetScriptByName(const char*, ScriptData&);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual void PreOnAnimUpdate(void);
|
||||
virtual void OnLayerShow(void);
|
||||
virtual void OnLayerHide(void);
|
||||
virtual void OnLayerUpdate(float);
|
||||
virtual int32_t OnLayerTrackUpdate(const CMouseEvent&);
|
||||
virtual void OnFrameRender(void);
|
||||
virtual void OnFrameRender(CRenderBatch*, uint32_t);
|
||||
virtual void OnScreenSizeChanged();
|
||||
virtual void OnFrameSizeChanged(float, float);
|
||||
virtual void OnLayerCursorEnter(int32_t);
|
||||
virtual void OnLayerCursorExit(int32_t, int32_t);
|
||||
virtual int32_t OnLayerChar(const CCharEvent&);
|
||||
virtual int32_t OnLayerKeyDown(const CKeyEvent&);
|
||||
virtual int32_t OnLayerKeyUp(const CKeyEvent&);
|
||||
virtual int32_t OnLayerMouseDown(const CMouseEvent&, const char*);
|
||||
virtual int32_t OnLayerMouseUp(const CMouseEvent&, const char*);
|
||||
virtual void PostLoadXML(XMLNode*, CStatus*);
|
||||
virtual void UnregisterRegion(CSimpleRegion*);
|
||||
virtual int32_t GetBoundsRect(CRect& bounds);
|
||||
virtual void PreLoadXML(XMLNode*, CStatus*);
|
||||
virtual void LockHighlight(int32_t);
|
||||
virtual int32_t HideThis(void);
|
||||
virtual int32_t ShowThis(void);
|
||||
virtual bool UpdateScale(bool);
|
||||
virtual void UpdateDepth(bool);
|
||||
virtual void ParentFrame(CSimpleFrame*);
|
||||
virtual void OnFrameSizeChanged(const CRect&);
|
||||
|
||||
// Member functions
|
||||
CSimpleFrame(CSimpleFrame*);
|
||||
void AddFrameRegion(CSimpleRegion*, uint32_t);
|
||||
void DisableDrawLayer(uint32_t);
|
||||
void EnableDrawLayer(uint32_t);
|
||||
void EnableEvent(CSimpleEventType, int32_t);
|
||||
int32_t GetHitRect(CRect& rect);
|
||||
void Hide(void);
|
||||
void LoadXML_Attributes(XMLNode*, CStatus*);
|
||||
void LoadXML_Backdrop(XMLNode*, CStatus*);
|
||||
void LoadXML_Layers(XMLNode*, CStatus*);
|
||||
void LoadXML_Scripts(XMLNode*, CStatus*);
|
||||
void NotifyDrawLayerChanged(uint32_t);
|
||||
void NotifyScrollParent(void);
|
||||
void PostLoadXML_Frames(XMLNode*, CStatus*);
|
||||
void Raise(void);
|
||||
void RegisterForEvents(int32_t);
|
||||
void RegisterRegion(CSimpleRegion*);
|
||||
void RemoveFrameRegion(CSimpleRegion*, uint32_t);
|
||||
void RunOnCharScript(const char*);
|
||||
void RunOnEnterScript(int32_t);
|
||||
void RunOnHideScript(void);
|
||||
void RunOnKeyDownScript(const char*);
|
||||
void RunOnKeyUpScript(const char*);
|
||||
void RunOnLeaveScript(int32_t);
|
||||
void RunOnLoadScript(void);
|
||||
void RunOnMouseDownScript(const char*);
|
||||
void RunOnMouseUpScript(const char*);
|
||||
void RunOnShowScript(void);
|
||||
void RunOnSizeChangedScript(float, float);
|
||||
void RunOnUpdateScript(float);
|
||||
void SetBackdrop(CBackdropGenerator*);
|
||||
void SetBeingScrolled(int32_t, int32_t);
|
||||
void SetFrameAlpha(uint8_t alpha);
|
||||
void SetFrameFlag(int32_t, int32_t);
|
||||
void SetFrameLevel(int32_t, int32_t);
|
||||
bool SetFrameScale(float scale, bool a3);
|
||||
void SetFrameStrata(FRAME_STRATA);
|
||||
void SetHitRect(void);
|
||||
void SetParent(CSimpleFrame*);
|
||||
void Show(void);
|
||||
int32_t TestHitRect(const C2Vector&);
|
||||
void UnregisterForEvents(int32_t);
|
||||
};
|
||||
|
||||
#endif
|
||||
580
src/ui/CSimpleFrameScript.cpp
Normal file
580
src/ui/CSimpleFrameScript.cpp
Normal file
|
|
@ -0,0 +1,580 @@
|
|||
#include "ui/CSimpleFrameScript.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
int32_t CSimpleFrame_GetTitleRegion(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_CreateTitleRegion(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_CreateTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_CreateFontString(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetBoundsRect(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
CRect bounds = {
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max(),
|
||||
0.0f,
|
||||
0.0f
|
||||
};
|
||||
|
||||
if (!frame->GetBoundsRect(bounds)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float ooScale = 1.0f / frame->m_layoutScale;
|
||||
|
||||
float ddcTop = CoordinateGetAspectCompensation() * 1024.0f * ooScale * bounds.minX;
|
||||
float ndcTop = DDCToNDCWidth(ddcTop);
|
||||
lua_pushnumber(L, ndcTop);
|
||||
|
||||
float ddcLeft = CoordinateGetAspectCompensation() * 1024.0f * ooScale * bounds.minY;
|
||||
float ndcLeft = DDCToNDCWidth(ddcLeft);
|
||||
lua_pushnumber(L, ndcLeft);
|
||||
|
||||
float ddcWidth = CoordinateGetAspectCompensation() * 1024.0f * ooScale * (bounds.maxX - bounds.minX);
|
||||
float ndcWidth = DDCToNDCWidth(ddcWidth);
|
||||
lua_pushnumber(L, ndcWidth);
|
||||
|
||||
float ddcHeight = CoordinateGetAspectCompensation() * 1024.0f * ooScale * (bounds.maxY - bounds.minY);
|
||||
float ndcHeight = DDCToNDCWidth(ddcHeight);
|
||||
lua_pushnumber(L, ndcHeight);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetNumRegions(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetRegions(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetNumChildren(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetChildren(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetFrameStrata(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetFrameStrata(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetFrameLevel(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
lua_pushnumber(L, frame->m_level);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetFrameLevel(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!frame->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetFrameLevel(level)", frame->GetDisplayName());
|
||||
}
|
||||
|
||||
int32_t level = lua_tonumber(L, 2);
|
||||
|
||||
if (level < 0) {
|
||||
return luaL_error(L, "%s:SetFrameLevel(): Passed negative frame level: %d", frame->GetDisplayName(), level);
|
||||
}
|
||||
|
||||
frame->SetFrameLevel(level, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_HasScript(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetScript(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetScript(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_HookScript(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_RegisterEvent(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isstring(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:RegisterEvent(\"event\")", frame->GetDisplayName());
|
||||
}
|
||||
|
||||
const char* event = lua_tolstring(L, 2, 0);
|
||||
|
||||
frame->RegisterScriptEvent(event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_UnregisterEvent(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_RegisterAllEvents(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_UnregisterAllEvents(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsEventRegistered(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_AllowAttributeChanges(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_CanChangeAttributes(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetAttribute(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetAttribute(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetEffectiveScale(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetScale(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetScale(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetEffectiveAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetAlpha(lua_State* L) {
|
||||
auto type = CSimpleFrame::GetObjectType();
|
||||
auto frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "Usage: %s:SetAlpha(alpha 0 to 1)", frame->GetDisplayName());
|
||||
}
|
||||
|
||||
float alpha = lua_tonumber(L, 2);
|
||||
alpha = std::max(std::min(alpha, 1.0f), 0.0f);
|
||||
frame->SetFrameAlpha(static_cast<uint8_t>(alpha * 255.0f));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetID(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
lua_pushnumber(L, frame->m_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetID(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!frame->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetID(ID)", frame->GetDisplayName());
|
||||
}
|
||||
|
||||
frame->m_id = lua_tonumber(L, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetToplevel(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsToplevel(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_EnableDrawLayer(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_DisableDrawLayer(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_Show(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (frame->ProtectedFunctionsAllowed()) {
|
||||
frame->Show();
|
||||
} else {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_Hide(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (frame->ProtectedFunctionsAllowed()) {
|
||||
frame->Hide();
|
||||
} else {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsVisible(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsShown(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (frame->m_shown) {
|
||||
lua_pushnumber(L, 1.0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_Raise(lua_State* L) {
|
||||
int32_t type = CSimpleFrame::GetObjectType();
|
||||
CSimpleFrame* frame = static_cast<CSimpleFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!frame->ProtectedFunctionsAllowed()) {
|
||||
// TODO
|
||||
// - disallowed logic
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
frame->Raise();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_Lower(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetHitRectInsets(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetHitRectInsets(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetClampRectInsets(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetClampRectInsets(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetMinResize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetMinResize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetMaxResize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetMaxResize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetMovable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsMovable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetDontSavePosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetDontSavePosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetResizable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsResizable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_StartMoving(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_StartSizing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_StopMovingOrSizing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetUserPlaced(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsUserPlaced(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetClampedToScreen(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsClampedToScreen(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_RegisterForDrag(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_EnableKeyboard(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsKeyboardEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_EnableMouse(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsMouseEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_EnableMouseWheel(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsMouseWheelEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_EnableJoystick(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsJoystickEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetBackdrop(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetBackdrop(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetBackdropColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetBackdropColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetBackdropBorderColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetBackdropBorderColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_SetDepth(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetDepth(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_GetEffectiveDepth(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IgnoreDepth(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleFrame_IsIgnoringDepth(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleFrameMethods[NUM_SIMPLE_FRAME_SCRIPT_METHODS] = {
|
||||
{ "GetTitleRegion", &CSimpleFrame_GetTitleRegion },
|
||||
{ "CreateTitleRegion", &CSimpleFrame_CreateTitleRegion },
|
||||
{ "CreateTexture", &CSimpleFrame_CreateTexture },
|
||||
{ "CreateFontString", &CSimpleFrame_CreateFontString },
|
||||
{ "GetBoundsRect", &CSimpleFrame_GetBoundsRect },
|
||||
{ "GetNumRegions", &CSimpleFrame_GetNumRegions },
|
||||
{ "GetRegions", &CSimpleFrame_GetRegions },
|
||||
{ "GetNumChildren", &CSimpleFrame_GetNumChildren },
|
||||
{ "GetChildren", &CSimpleFrame_GetChildren },
|
||||
{ "GetFrameStrata", &CSimpleFrame_GetFrameStrata },
|
||||
{ "SetFrameStrata", &CSimpleFrame_SetFrameStrata },
|
||||
{ "GetFrameLevel", &CSimpleFrame_GetFrameLevel },
|
||||
{ "SetFrameLevel", &CSimpleFrame_SetFrameLevel },
|
||||
{ "HasScript", &CSimpleFrame_HasScript },
|
||||
{ "GetScript", &CSimpleFrame_GetScript },
|
||||
{ "SetScript", &CSimpleFrame_SetScript },
|
||||
{ "HookScript", &CSimpleFrame_HookScript },
|
||||
{ "RegisterEvent", &CSimpleFrame_RegisterEvent },
|
||||
{ "UnregisterEvent", &CSimpleFrame_UnregisterEvent },
|
||||
{ "RegisterAllEvents", &CSimpleFrame_RegisterAllEvents },
|
||||
{ "UnregisterAllEvents", &CSimpleFrame_UnregisterAllEvents },
|
||||
{ "IsEventRegistered", &CSimpleFrame_IsEventRegistered },
|
||||
{ "AllowAttributeChanges", &CSimpleFrame_AllowAttributeChanges },
|
||||
{ "CanChangeAttribute", &CSimpleFrame_CanChangeAttributes },
|
||||
{ "GetAttribute", &CSimpleFrame_GetAttribute },
|
||||
{ "SetAttribute", &CSimpleFrame_SetAttribute },
|
||||
{ "GetEffectiveScale", &CSimpleFrame_GetEffectiveScale },
|
||||
{ "GetScale", &CSimpleFrame_GetScale },
|
||||
{ "SetScale", &CSimpleFrame_SetScale },
|
||||
{ "GetEffectiveAlpha", &CSimpleFrame_GetEffectiveAlpha },
|
||||
{ "GetAlpha", &CSimpleFrame_GetAlpha },
|
||||
{ "SetAlpha", &CSimpleFrame_SetAlpha },
|
||||
{ "GetID", &CSimpleFrame_GetID },
|
||||
{ "SetID", &CSimpleFrame_SetID },
|
||||
{ "SetToplevel", &CSimpleFrame_SetToplevel },
|
||||
{ "IsToplevel", &CSimpleFrame_IsToplevel },
|
||||
{ "EnableDrawLayer", &CSimpleFrame_EnableDrawLayer },
|
||||
{ "DisableDrawLayer", &CSimpleFrame_DisableDrawLayer },
|
||||
{ "Show", &CSimpleFrame_Show },
|
||||
{ "Hide", &CSimpleFrame_Hide },
|
||||
{ "IsVisible", &CSimpleFrame_IsVisible },
|
||||
{ "IsShown", &CSimpleFrame_IsShown },
|
||||
{ "Raise", &CSimpleFrame_Raise },
|
||||
{ "Lower", &CSimpleFrame_Lower },
|
||||
{ "GetHitRectInsets", &CSimpleFrame_GetHitRectInsets },
|
||||
{ "SetHitRectInsets", &CSimpleFrame_SetHitRectInsets },
|
||||
{ "GetClampRectInsets", &CSimpleFrame_GetClampRectInsets },
|
||||
{ "SetClampRectInsets", &CSimpleFrame_SetClampRectInsets },
|
||||
{ "GetMinResize", &CSimpleFrame_GetMinResize },
|
||||
{ "SetMinResize", &CSimpleFrame_SetMinResize },
|
||||
{ "GetMaxResize", &CSimpleFrame_GetMaxResize },
|
||||
{ "SetMaxResize", &CSimpleFrame_SetMaxResize },
|
||||
{ "SetMovable", &CSimpleFrame_SetMovable },
|
||||
{ "IsMovable", &CSimpleFrame_IsMovable },
|
||||
{ "SetDontSavePosition", &CSimpleFrame_SetDontSavePosition },
|
||||
{ "GetDontSavePosition", &CSimpleFrame_GetDontSavePosition },
|
||||
{ "SetResizable", &CSimpleFrame_SetResizable },
|
||||
{ "IsResizable", &CSimpleFrame_IsResizable },
|
||||
{ "StartMoving", &CSimpleFrame_StartMoving },
|
||||
{ "StartSizing", &CSimpleFrame_StartSizing },
|
||||
{ "StopMovingOrSizing", &CSimpleFrame_StopMovingOrSizing },
|
||||
{ "SetUserPlaced", &CSimpleFrame_SetUserPlaced },
|
||||
{ "IsUserPlaced", &CSimpleFrame_IsUserPlaced },
|
||||
{ "SetClampedToScreen", &CSimpleFrame_SetClampedToScreen },
|
||||
{ "IsClampedToScreen", &CSimpleFrame_IsClampedToScreen },
|
||||
{ "RegisterForDrag", &CSimpleFrame_RegisterForDrag },
|
||||
{ "EnableKeyboard", &CSimpleFrame_EnableKeyboard },
|
||||
{ "IsKeyboardEnabled", &CSimpleFrame_IsKeyboardEnabled },
|
||||
{ "EnableMouse", &CSimpleFrame_EnableMouse },
|
||||
{ "IsMouseEnabled", &CSimpleFrame_IsMouseEnabled },
|
||||
{ "EnableMouseWheel", &CSimpleFrame_EnableMouseWheel },
|
||||
{ "IsMouseWheelEnabled", &CSimpleFrame_IsMouseWheelEnabled },
|
||||
{ "EnableJoystick", &CSimpleFrame_EnableJoystick },
|
||||
{ "IsJoystickEnabled", &CSimpleFrame_IsJoystickEnabled },
|
||||
{ "GetBackdrop", &CSimpleFrame_GetBackdrop },
|
||||
{ "SetBackdrop", &CSimpleFrame_SetBackdrop },
|
||||
{ "GetBackdropColor", &CSimpleFrame_GetBackdropColor },
|
||||
{ "SetBackdropColor", &CSimpleFrame_SetBackdropColor },
|
||||
{ "GetBackdropBorderColor", &CSimpleFrame_GetBackdropBorderColor },
|
||||
{ "SetBackdropBorderColor", &CSimpleFrame_SetBackdropBorderColor },
|
||||
{ "SetDepth", &CSimpleFrame_SetDepth },
|
||||
{ "GetDepth", &CSimpleFrame_GetDepth },
|
||||
{ "GetEffectiveDepth", &CSimpleFrame_GetEffectiveDepth },
|
||||
{ "IgnoreDepth", &CSimpleFrame_IgnoreDepth },
|
||||
{ "IsIgnoringDepth", &CSimpleFrame_IsIgnoringDepth }
|
||||
};
|
||||
10
src/ui/CSimpleFrameScript.hpp
Normal file
10
src/ui/CSimpleFrameScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_FRAME_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_FRAME_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_FRAME_SCRIPT_METHODS 85
|
||||
|
||||
extern FrameScript_Method SimpleFrameMethods[NUM_SIMPLE_FRAME_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
371
src/ui/CSimpleHTML.cpp
Normal file
371
src/ui/CSimpleHTML.cpp
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
#include "ui/CSimpleHTML.hpp"
|
||||
#include "ui/CSimpleFontedFrameFont.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "ui/CSimpleHTMLScript.hpp"
|
||||
#include "ui/CSimpleTop.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include <common/XML.hpp>
|
||||
|
||||
int32_t CSimpleHTML::s_metatable;
|
||||
int32_t CSimpleHTML::s_objectType;
|
||||
|
||||
CONTENTNODE::~CONTENTNODE() {
|
||||
if (this->string) {
|
||||
delete string;
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleHTML::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleHTML::RegisterScriptMethods);
|
||||
CSimpleHTML::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML::GetObjectType() {
|
||||
if (!CSimpleHTML::s_objectType) {
|
||||
CSimpleHTML::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleHTML::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleHTML::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleFrame::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleHTMLMethods, NUM_SIMPLE_HTML_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleHTML::CSimpleHTML(CSimpleFrame* parent) : CSimpleHyperlinkedFrame(parent) {
|
||||
// TODO
|
||||
|
||||
for (int32_t i = 0; i < NUM_HTML_TEXT_TYPES; i++) {
|
||||
auto m = SMemAlloc(sizeof(CSimpleFontedFrameFont), __FILE__, __LINE__, 0x0);
|
||||
auto font = new (m) CSimpleFontedFrameFont(this);
|
||||
this->m_fonts[i] = font;
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleHTML::AddText(const char* text, HTML_TEXT_TYPE type, uint32_t justify) {
|
||||
// TODO void* stringMem = CDataAllocator::GetData(CSimpleFontString::s_allocator, 0x0, __FILE__, __LINE__);
|
||||
void* stringMem = SMemAlloc(sizeof(CSimpleFontString), __FILE__, __LINE__, 0x0);
|
||||
CSimpleFontString* string = new (stringMem) CSimpleFontString(this, DRAWLAYER_ARTWORK, 1);
|
||||
|
||||
if (this->m_layoutAnchor) {
|
||||
string->SetPoint(
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
this->m_layoutAnchor,
|
||||
FRAMEPOINT_BOTTOMLEFT,
|
||||
0.0f,
|
||||
this->m_layoutOffset,
|
||||
1
|
||||
);
|
||||
} else {
|
||||
string->SetPoint(
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
this,
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
string->SetWidth(this->GetWidth());
|
||||
|
||||
auto font = this->m_fonts[type];
|
||||
if (!font->m_attributes.m_font.GetString()) {
|
||||
font = this->m_fonts[0];
|
||||
}
|
||||
string->SetFontObject(font);
|
||||
|
||||
string->SetJustifyH(justify);
|
||||
// TODO something with style flag 0x1000?
|
||||
|
||||
string->SetText(text, 1);
|
||||
|
||||
this->m_layoutAnchor = string;
|
||||
this->m_layoutOffset = -CSimpleTop::RoundToPixelHeight(string->m_spacing);
|
||||
|
||||
auto contentNode = this->m_content.NewNode(2, 0, 0x0);
|
||||
contentNode->string = string;
|
||||
// TODO contentNode->dword8 = SStrStr(text, "|H") != 0;
|
||||
}
|
||||
|
||||
void CSimpleHTML::ClearContent() {
|
||||
this->m_content.DeleteAll();
|
||||
|
||||
this->m_layoutAnchor = nullptr;
|
||||
this->m_layoutOffset = 0.0f;
|
||||
|
||||
// TODO clear hyperlinks
|
||||
}
|
||||
|
||||
void CSimpleHTML::FontUpdated(CSimpleFontedFrameFont* font, int32_t a3) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML::GetScriptMetaTable() {
|
||||
return CSimpleHTML::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleHTML::IsA(int32_t type) {
|
||||
return type == CSimpleHTML::s_objectType
|
||||
|| type == CSimpleFrame::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleHTML::LoadXML(XMLNode* node, CStatus* status) {
|
||||
CSimpleFrame::LoadXML(node, status);
|
||||
|
||||
const char* fontAttr = node->GetAttributeByName("font");
|
||||
if (fontAttr && *fontAttr) {
|
||||
auto font = CSimpleFont::GetFont(fontAttr, 0);
|
||||
|
||||
if (font) {
|
||||
for (int32_t i = 0; i < NUM_HTML_TEXT_TYPES; i++) {
|
||||
this->m_fonts[i]->SetFontObject(font);
|
||||
}
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"%s %s: Couldn't find font object named %s",
|
||||
this->GetObjectTypeName(),
|
||||
this->GetDisplayName(),
|
||||
fontAttr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "FontString", STORM_MAX_STR)) {
|
||||
this->m_fonts[HTML_TEXT_NORMAL]->LoadXML(child, status);
|
||||
} else if (!SStrCmpI(child->GetName(), "FontStringHeader1", STORM_MAX_STR)) {
|
||||
this->m_fonts[HTML_TEXT_HEADER1]->LoadXML(child, status);
|
||||
} else if (!SStrCmpI(child->GetName(), "FontStringHeader2", STORM_MAX_STR)) {
|
||||
this->m_fonts[HTML_TEXT_HEADER2]->LoadXML(child, status);
|
||||
} else if (!SStrCmpI(child->GetName(), "FontStringHeader3", STORM_MAX_STR)) {
|
||||
this->m_fonts[HTML_TEXT_HEADER3]->LoadXML(child, status);
|
||||
}
|
||||
}
|
||||
|
||||
const char* fileAttr = node->GetAttributeByName("file");
|
||||
void* fileData;
|
||||
if (fileAttr && SFile::Load(nullptr, fileAttr, &fileData, nullptr, 1, 0x1, nullptr)) {
|
||||
this->SetText(static_cast<char*>(fileData), nullptr);
|
||||
SFile::Unload(fileData);
|
||||
}
|
||||
|
||||
// TODO hyperlinkFormat
|
||||
}
|
||||
|
||||
void CSimpleHTML::ParseBODY(XMLNode* node, CStatus* status) {
|
||||
for (auto child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "H1", STORM_MAX_STR)) {
|
||||
this->ParseP(child, HTML_TEXT_HEADER1, status);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "H2", STORM_MAX_STR)) {
|
||||
this->ParseP(child, HTML_TEXT_HEADER2, status);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "H3", STORM_MAX_STR)) {
|
||||
this->ParseP(child, HTML_TEXT_HEADER3, status);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "P", STORM_MAX_STR)) {
|
||||
this->ParseP(child, HTML_TEXT_NORMAL, status);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "BR", STORM_MAX_STR)) {
|
||||
this->AddText("\n", HTML_TEXT_NORMAL, 1);
|
||||
|
||||
} else if (!SStrCmpI(child->GetName(), "IMG", STORM_MAX_STR)) {
|
||||
this->ParseIMG(child, status);
|
||||
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Unknown element type: %s",
|
||||
this->GetDisplayName(),
|
||||
child->GetName()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleHTML::ParseIMG(XMLNode* node, CStatus* status) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleHTML::ParseP(XMLNode* node, HTML_TEXT_TYPE type, CStatus* status) {
|
||||
uint32_t justify = 1;
|
||||
auto justifyAttr = node->GetAttributeByName("align");
|
||||
if (justifyAttr && *justifyAttr) {
|
||||
StringToJustify(justifyAttr, justify);
|
||||
}
|
||||
|
||||
auto body = node->GetBody();
|
||||
if (!body) {
|
||||
body = "";
|
||||
}
|
||||
|
||||
auto text = SStrDupA(body, __FILE__, __LINE__);
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (auto child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "BR", STORM_MAX_STR)) {
|
||||
char* newText = static_cast<char*>(SMemAlloc(SStrLen(text) + 3, __FILE__, __LINE__, 0x0));
|
||||
SStrCopy(newText, text, child->m_offset + offset + 1);
|
||||
SStrPack(newText, "|n", STORM_MAX_STR);
|
||||
SStrPack(newText, &text[child->m_offset + offset], STORM_MAX_STR);
|
||||
SMemFree(text, __FILE__, __LINE__, 0x0);
|
||||
text = newText;
|
||||
|
||||
offset += 2;
|
||||
} else if (!SStrCmpI(child->GetName(), "A", STORM_MAX_STR)) {
|
||||
// TODO handle anchor child
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Unknown element type: %s",
|
||||
this->GetDisplayName(),
|
||||
child->GetName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t v22 = 0;
|
||||
int32_t v36 = 1;
|
||||
auto v23 = text;
|
||||
auto v24 = text;
|
||||
|
||||
if (*text) {
|
||||
do {
|
||||
switch (*v23) {
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case ' ': {
|
||||
if (!v36 && !v22) {
|
||||
v22 = 1;
|
||||
*v24 = ' ';
|
||||
v24++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case '|': {
|
||||
if (v23[1] != 'n') {
|
||||
v22 = 0;
|
||||
v36 = 0;
|
||||
|
||||
*v24 = *v23;
|
||||
v24++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (v24 > text && v22) {
|
||||
v24--;
|
||||
}
|
||||
|
||||
*v24 = '|';
|
||||
v24++;
|
||||
*v24 = 'n';
|
||||
v24++;
|
||||
|
||||
v22 = 0;
|
||||
v36 = 1;
|
||||
|
||||
v23++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
v22 = 0;
|
||||
v36 = 0;
|
||||
|
||||
*v24 = *v23;
|
||||
v24++;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
v23++;
|
||||
} while (*v23);
|
||||
|
||||
if (v24 > text && v22) {
|
||||
v24--;
|
||||
}
|
||||
}
|
||||
|
||||
*v24 = '\0';
|
||||
|
||||
this->AddText(text, type, justify);
|
||||
|
||||
SMemFree(text, __FILE__, __LINE__, 0x0);
|
||||
}
|
||||
|
||||
bool CSimpleHTML::SetText(const char* text, CStatus* status) {
|
||||
static auto s_nullStatus = CStatus();
|
||||
|
||||
if (!status) {
|
||||
status = &s_nullStatus;
|
||||
}
|
||||
|
||||
if (!text) {
|
||||
text = "";
|
||||
}
|
||||
|
||||
// TODO some sort of guard condition
|
||||
|
||||
this->ClearContent();
|
||||
|
||||
auto textLength = SStrLen(text);
|
||||
auto tree = XMLTree_Load(text, textLength);
|
||||
bool success = false;
|
||||
|
||||
if (tree) {
|
||||
auto node = XMLTree_GetRoot(tree);
|
||||
|
||||
if (!SStrCmpI(node->GetName(), "HTML", STORM_MAX_STR)) {
|
||||
for (auto child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "BODY", STORM_MAX_STR)) {
|
||||
success = true;
|
||||
this->ParseBODY(child, status);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Unknown element type: %s (expected BODY)",
|
||||
this->GetDisplayName(),
|
||||
node->GetName()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Unknown element type: %s (expected HTML)",
|
||||
this->GetDisplayName(),
|
||||
node->GetName()
|
||||
);
|
||||
}
|
||||
|
||||
XMLTree_Free(tree);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
// TODO set flag
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
this->AddText(text, HTML_TEXT_NORMAL, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
51
src/ui/CSimpleHTML.hpp
Normal file
51
src/ui/CSimpleHTML.hpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef UI_C_SIMPLE_HTML_HPP
|
||||
#define UI_C_SIMPLE_HTML_HPP
|
||||
|
||||
#include "ui/CSimpleFontedFrame.hpp"
|
||||
#include "ui/CSimpleHyperlinkedFrame.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
|
||||
struct CONTENTNODE : TSLinkedNode<CONTENTNODE> {
|
||||
CSimpleFontString* string;
|
||||
|
||||
~CONTENTNODE();
|
||||
};
|
||||
|
||||
class CSimpleHTML : public CSimpleHyperlinkedFrame, CSimpleFontedFrame {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
STORM_LIST(CONTENTNODE) m_content;
|
||||
CLayoutFrame* m_layoutAnchor;
|
||||
float m_layoutOffset;
|
||||
CSimpleFontedFrameFont* m_fonts[NUM_HTML_TEXT_TYPES];
|
||||
|
||||
// Virtual member functions
|
||||
virtual bool IsA(int32_t type);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode* node, CStatus* status);
|
||||
virtual void FontUpdated(CSimpleFontedFrameFont* font, int32_t a3);
|
||||
|
||||
// Member functions
|
||||
CSimpleHTML(CSimpleFrame*);
|
||||
void AddText(const char* text, HTML_TEXT_TYPE type, uint32_t justify);
|
||||
void ClearContent();
|
||||
void ParseBODY(XMLNode* node, CStatus* status);
|
||||
void ParseIMG(XMLNode* node, CStatus* status);
|
||||
void ParseP(XMLNode* node, HTML_TEXT_TYPE type, CStatus* status);
|
||||
bool SetText(const char* text, CStatus* status);
|
||||
};
|
||||
|
||||
#endif
|
||||
129
src/ui/CSimpleHTMLScript.cpp
Normal file
129
src/ui/CSimpleHTMLScript.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#include "ui/CSimpleHTMLScript.hpp"
|
||||
#include "ui/CSimpleHTML.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleHTML_SetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetFontObject(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetFont(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetTextColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetShadowColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetShadowOffset(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetSpacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetJustifyH(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetJustifyV(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetIndentedWordWrap(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetText(lua_State* L) {
|
||||
auto type = CSimpleHTML::GetObjectType();
|
||||
auto html = static_cast<CSimpleHTML*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
auto text = lua_tolstring(L, 2, nullptr);
|
||||
html->SetText(text, nullptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetHyperlinkFormat(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetHyperlinkFormat(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_SetHyperlinksEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleHTML_GetHyperlinksEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleHTMLMethods[NUM_SIMPLE_HTML_SCRIPT_METHODS] = {
|
||||
{ "SetFontObject", &CSimpleHTML_SetFontObject },
|
||||
{ "GetFontObject", &CSimpleHTML_GetFontObject },
|
||||
{ "SetFont", &CSimpleHTML_SetFont },
|
||||
{ "GetFont", &CSimpleHTML_GetFont },
|
||||
{ "SetTextColor", &CSimpleHTML_SetTextColor },
|
||||
{ "GetTextColor", &CSimpleHTML_GetTextColor },
|
||||
{ "SetShadowColor", &CSimpleHTML_SetShadowColor },
|
||||
{ "GetShadowColor", &CSimpleHTML_GetShadowColor },
|
||||
{ "SetShadowOffset", &CSimpleHTML_SetShadowOffset },
|
||||
{ "GetShadowOffset", &CSimpleHTML_GetShadowOffset },
|
||||
{ "SetSpacing", &CSimpleHTML_SetSpacing },
|
||||
{ "GetSpacing", &CSimpleHTML_GetSpacing },
|
||||
{ "SetJustifyH", &CSimpleHTML_SetJustifyH },
|
||||
{ "GetJustifyH", &CSimpleHTML_GetJustifyH },
|
||||
{ "SetJustifyV", &CSimpleHTML_SetJustifyV },
|
||||
{ "GetJustifyV", &CSimpleHTML_GetJustifyV },
|
||||
{ "SetIndentedWordWrap", &CSimpleHTML_SetIndentedWordWrap },
|
||||
{ "GetIndentedWordWrap", &CSimpleHTML_GetIndentedWordWrap },
|
||||
{ "SetText", &CSimpleHTML_SetText },
|
||||
{ "SetHyperlinkFormat", &CSimpleHTML_SetHyperlinkFormat },
|
||||
{ "GetHyperlinkFormat", &CSimpleHTML_GetHyperlinkFormat },
|
||||
{ "SetHyperlinksEnabled", &CSimpleHTML_SetHyperlinksEnabled },
|
||||
{ "GetHyperlinksEnabled", &CSimpleHTML_GetHyperlinksEnabled }
|
||||
};
|
||||
10
src/ui/CSimpleHTMLScript.hpp
Normal file
10
src/ui/CSimpleHTMLScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_HTML_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_HTML_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_HTML_SCRIPT_METHODS 23
|
||||
|
||||
extern FrameScript_Method SimpleHTMLMethods[NUM_SIMPLE_HTML_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
5
src/ui/CSimpleHyperlinkedFrame.cpp
Normal file
5
src/ui/CSimpleHyperlinkedFrame.cpp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "ui/CSimpleHyperlinkedFrame.hpp"
|
||||
|
||||
CSimpleHyperlinkedFrame::CSimpleHyperlinkedFrame(CSimpleFrame* parent) : CSimpleFrame(parent) {
|
||||
// TODO
|
||||
}
|
||||
12
src/ui/CSimpleHyperlinkedFrame.hpp
Normal file
12
src/ui/CSimpleHyperlinkedFrame.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef UI_C_SIMPLE_HYPERLINKED_FRAME_HPP
|
||||
#define UI_C_SIMPLE_HYPERLINKED_FRAME_HPP
|
||||
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
|
||||
class CSimpleHyperlinkedFrame : public CSimpleFrame {
|
||||
public:
|
||||
// Member functions
|
||||
CSimpleHyperlinkedFrame(CSimpleFrame*);
|
||||
};
|
||||
|
||||
#endif
|
||||
407
src/ui/CSimpleModel.cpp
Normal file
407
src/ui/CSimpleModel.cpp
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
#include "ui/CSimpleModel.hpp"
|
||||
#include "gx/Camera.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Draw.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "gx/Transform.hpp"
|
||||
#include "math/Utils.hpp"
|
||||
#include "model/CM2Shared.hpp"
|
||||
#include "model/M2Data.hpp"
|
||||
#include "ui/CSimpleModelScript.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include <common/XML.hpp>
|
||||
#include <tempest/Math.hpp>
|
||||
|
||||
int32_t CSimpleModel::s_metatable;
|
||||
int32_t CSimpleModel::s_objectType;
|
||||
|
||||
void CSimpleModel::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleModel::RegisterScriptMethods);
|
||||
CSimpleModel::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel::GetObjectType() {
|
||||
if (!CSimpleModel::s_objectType) {
|
||||
CSimpleModel::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleModel::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleModel::LightingCallback(CM2Model* model, CM2Lighting* lighting, void* userArg) {
|
||||
CSimpleModel* simpleModel = static_cast<CSimpleModel*>(userArg);
|
||||
|
||||
if (simpleModel->m_flags & 0x1) {
|
||||
lighting->SetFog(simpleModel->m_fogColor, simpleModel->m_fogNear, simpleModel->m_fogFar);
|
||||
}
|
||||
|
||||
if (simpleModel->m_light.m_visible) {
|
||||
lighting->AddLight(&simpleModel->m_light);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleModel::ModelLoaded(CM2Model* model, void* arg) {
|
||||
auto simpleModel = static_cast<CSimpleModel*>(arg);
|
||||
simpleModel->OnModelLoaded(model);
|
||||
}
|
||||
|
||||
void CSimpleModel::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleFrame::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleModelMethods, NUM_SIMPLE_MODEL_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
void CSimpleModel::RenderModel(void* arg) {
|
||||
auto simpleModel = static_cast<CSimpleModel*>(arg);
|
||||
|
||||
if (!simpleModel->m_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
CRect viewRect;
|
||||
|
||||
if (!simpleModel->GetRect(&viewRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
C44Matrix proj;
|
||||
GxXformProjection(proj);
|
||||
|
||||
C44Matrix view;
|
||||
GxXformView(view);
|
||||
|
||||
float minX, maxX, minY, maxY, minZ, maxZ;
|
||||
GxXformViewport(minX, maxX, minY, maxY, minZ, maxZ);
|
||||
|
||||
C3Vector cameraPos;
|
||||
C3Vector cameraTarg;
|
||||
|
||||
if (simpleModel->m_camera) {
|
||||
DataMgrGetCoord(simpleModel->m_camera, 7, &cameraPos);
|
||||
DataMgrGetCoord(simpleModel->m_camera, 8, &cameraTarg);
|
||||
CameraSetupWorldProjection(simpleModel->m_camera, viewRect, 0x0);
|
||||
} else {
|
||||
C2Vector v19 = { viewRect.minX, viewRect.minY };
|
||||
CameraSetupScreenProjection(viewRect, v19, 0.0f, 1);
|
||||
}
|
||||
|
||||
DDCToNDC(viewRect.minX, viewRect.minY, &viewRect.minX, &viewRect.minY);
|
||||
DDCToNDC(viewRect.maxX, viewRect.maxY, &viewRect.maxX, &viewRect.maxY);
|
||||
|
||||
viewRect.minX = std::max(0.0f, std::min(viewRect.minX, 1.0f));
|
||||
viewRect.maxX = std::max(0.0f, std::min(viewRect.maxX, 1.0f));
|
||||
viewRect.minY = std::max(0.0f, std::min(viewRect.minY, 1.0f));
|
||||
viewRect.maxY = std::max(0.0f, std::min(viewRect.maxY, 1.0f));
|
||||
|
||||
// Handle zero width or zero height
|
||||
if (AreEqual(viewRect.minX, viewRect.maxX, WHOA_EPSILON_1) || AreEqual(viewRect.minY, viewRect.maxY, WHOA_EPSILON_1)) {
|
||||
GxXformSetProjection(proj);
|
||||
GxXformSetView(view);
|
||||
GxXformSetViewport(minX, maxX, minY, maxY, minZ, maxZ);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float v11 = viewRect.minX * maxX;
|
||||
float v12 = viewRect.maxX * maxX;
|
||||
float v13 = viewRect.minY * maxY;
|
||||
float v14 = viewRect.maxY * maxY;
|
||||
|
||||
GxXformSetViewport(v11, v12, v13, v14, 0.0f, 1.0f);
|
||||
CImVector clearColor = { 0x00, 0x00, 0x00, 0xFF };
|
||||
GxSceneClear(0x2, clearColor);
|
||||
CShaderEffect::UpdateProjMatrix();
|
||||
|
||||
simpleModel->UpdateModel();
|
||||
|
||||
if (simpleModel->m_pendingCameraIndex == -1u) {
|
||||
simpleModel->GetScene()->Animate(cameraPos);
|
||||
simpleModel->GetScene()->Draw(M2PASS_0);
|
||||
simpleModel->GetScene()->Draw(M2PASS_1);
|
||||
}
|
||||
|
||||
GxXformSetProjection(proj);
|
||||
GxXformSetView(view);
|
||||
GxXformSetViewport(minX, maxX, minY, maxY, minZ, maxZ);
|
||||
CShaderEffect::UpdateProjMatrix();
|
||||
}
|
||||
|
||||
CSimpleModel::CSimpleModel(CSimpleFrame* parent) : CSimpleFrame(parent) {
|
||||
this->m_light.SetVisible(0);
|
||||
this->m_light.SetLightType(M2LIGHT_1);
|
||||
this->m_light.m_ambColor = { 1.0f, 1.0f, 1.0f };
|
||||
this->m_light.m_dirColor = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
this->m_fogColor = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
}
|
||||
|
||||
CM2Scene* CSimpleModel::GetScene() {
|
||||
if (!this->m_scene) {
|
||||
this->m_scene = M2CreateScene();
|
||||
}
|
||||
|
||||
return this->m_scene;
|
||||
}
|
||||
|
||||
FrameScript_Object::ScriptIx* CSimpleModel::GetScriptByName(const char* name, ScriptData& data) {
|
||||
auto parentScript = CSimpleFrame::GetScriptByName(name, data);
|
||||
|
||||
if (parentScript) {
|
||||
return parentScript;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnUpdateModel", STORM_MAX_STR)) {
|
||||
return &this->m_onUpdateModel;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnAnimFinished", STORM_MAX_STR)) {
|
||||
return &this->m_onAnimFinished;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel::GetScriptMetaTable() {
|
||||
return CSimpleModel::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleModel::IsA(int32_t type) {
|
||||
return type == CSimpleModel::s_objectType
|
||||
|| type == CSimpleFrame::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleModel::LoadXML(XMLNode* node, CStatus* status) {
|
||||
CSimpleFrame::LoadXML(node, status);
|
||||
|
||||
const char* fileAttr = node->GetAttributeByName("file");
|
||||
if (fileAttr && *fileAttr) {
|
||||
this->SetModel(fileAttr);
|
||||
|
||||
if (!this->m_model) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Bad model file: %s",
|
||||
this->GetDisplayName(),
|
||||
fileAttr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const char* scaleAttr = node->GetAttributeByName("scale");
|
||||
if (scaleAttr && *scaleAttr) {
|
||||
float scale = SStrToFloat(scaleAttr);
|
||||
|
||||
if (scale <= 0.0f) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Invalid model scale: %s",
|
||||
this->GetDisplayName(),
|
||||
scaleAttr
|
||||
);
|
||||
} else {
|
||||
this->SetScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
const char* fogNearAttr = node->GetAttributeByName("fogNear");
|
||||
if (fogNearAttr && *fogNearAttr) {
|
||||
float fogNear = SStrToFloat(fogNearAttr);
|
||||
|
||||
if (fogNear < 0.0f) {
|
||||
fogNear = 0.0f;
|
||||
}
|
||||
|
||||
this->SetFogNear(fogNear);
|
||||
}
|
||||
|
||||
const char* fogFarAttr = node->GetAttributeByName("fogFar");
|
||||
if (fogFarAttr && *fogFarAttr) {
|
||||
float fogFar = SStrToFloat(fogFarAttr);
|
||||
|
||||
if (fogFar < 0.0f) {
|
||||
fogFar = 0.0f;
|
||||
}
|
||||
|
||||
this->SetFogFar(fogFar);
|
||||
}
|
||||
|
||||
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "FogColor", STORM_MAX_STR)) {
|
||||
CImVector color;
|
||||
LoadXML_Color(child, color);
|
||||
this->SetFogColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleModel::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleModel::OnLayerUpdate(float elapsedSec) {
|
||||
CSimpleFrame::OnLayerUpdate(elapsedSec);
|
||||
|
||||
if (this->m_model && this->m_visible && this->m_pendingCameraIndex == -1u) {
|
||||
this->m_model->SetAnimating(1);
|
||||
this->m_model->SetVisible(1);
|
||||
|
||||
if (this->m_model->m_attachParent) {
|
||||
this->m_model->m_flag20000 = 1;
|
||||
} else {
|
||||
this->m_model->m_flag10000 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t advance = CMath::fuint(elapsedSec * 1000.f);
|
||||
this->GetScene()->AdvanceTime(advance);
|
||||
}
|
||||
|
||||
void CSimpleModel::OnModelLoaded(CM2Model* model) {
|
||||
model->SetAnimating(1);
|
||||
|
||||
C3Vector cameraPos;
|
||||
model->m_scene->Animate(cameraPos);
|
||||
|
||||
if (this->m_pendingCameraIndex != -1u) {
|
||||
this->SetCameraByIndex(this->m_pendingCameraIndex);
|
||||
} else if (this->m_pendingCameraId != -1u) {
|
||||
this->SetCameraByID(this->m_pendingCameraId);
|
||||
}
|
||||
|
||||
CAaBox bounds;
|
||||
this->m_bounds = model->GetBoundingBox(bounds);
|
||||
|
||||
this->Resize(0);
|
||||
}
|
||||
|
||||
void CSimpleModel::SetCamera(HCAMERA camera) {
|
||||
if (camera) {
|
||||
camera = HandleDuplicate(camera);
|
||||
}
|
||||
|
||||
if (this->m_camera) {
|
||||
HandleClose(this->m_camera);
|
||||
}
|
||||
|
||||
this->m_camera = camera;
|
||||
this->m_pendingCameraIndex = -1u;
|
||||
this->m_pendingCameraId = -1u;
|
||||
}
|
||||
|
||||
void CSimpleModel::SetCameraByID(uint32_t id) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleModel::SetCameraByIndex(uint32_t index) {
|
||||
if (!this->m_model || !this->m_model->IsLoaded(0, 0)) {
|
||||
this->m_pendingCameraIndex = index;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->m_model->m_loaded) {
|
||||
this->m_model->WaitForLoad(nullptr);
|
||||
}
|
||||
|
||||
if (index >= this->m_model->m_shared->m_data->cameras.Count()) {
|
||||
if (this->m_camera) {
|
||||
HandleClose(this->m_camera);
|
||||
}
|
||||
|
||||
this->m_camera = nullptr;
|
||||
this->m_pendingCameraIndex = -1u;
|
||||
this->m_pendingCameraId = -1u;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HCAMERA camera = this->m_model->GetCameraByIndex(index);
|
||||
this->SetCamera(camera);
|
||||
}
|
||||
|
||||
void CSimpleModel::SetFogColor(CImVector& fogColor) {
|
||||
this->m_fogColor = fogColor;
|
||||
this->m_flags |= 0x1;
|
||||
}
|
||||
|
||||
void CSimpleModel::SetFogFar(float fogFar) {
|
||||
this->m_fogFar = fogFar;
|
||||
}
|
||||
|
||||
void CSimpleModel::SetFogNear(float fogNear) {
|
||||
this->m_fogNear = fogNear;
|
||||
}
|
||||
|
||||
void CSimpleModel::SetModel(const char* sourcefile) {
|
||||
CM2Model* model = nullptr;
|
||||
|
||||
if (sourcefile && *sourcefile) {
|
||||
if (!this->m_scene) {
|
||||
this->m_scene = M2CreateScene();
|
||||
}
|
||||
|
||||
model = this->m_scene->CreateModel(sourcefile, 1);
|
||||
}
|
||||
|
||||
this->SetModel(model);
|
||||
|
||||
if (model) {
|
||||
model->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleModel::SetModel(CM2Model* model) {
|
||||
if (model) {
|
||||
model->m_refCount++;
|
||||
}
|
||||
|
||||
if (this->m_model) {
|
||||
this->m_model->Release();
|
||||
}
|
||||
|
||||
this->m_model = model;
|
||||
|
||||
if (model) {
|
||||
// TODO
|
||||
this->m_model->SetLightingCallback(&CSimpleModel::LightingCallback, this);
|
||||
this->m_model->SetLoadedCallback(&CSimpleModel::ModelLoaded, this);
|
||||
}
|
||||
|
||||
this->NotifyDrawLayerChanged(DRAWLAYER_ARTWORK);
|
||||
}
|
||||
|
||||
void CSimpleModel::SetScale(float scale) {
|
||||
this->m_scale = scale;
|
||||
}
|
||||
|
||||
void CSimpleModel::SetSequence(uint32_t sequenceId) {
|
||||
if (this->m_model) {
|
||||
this->m_model->SetBoneSequence(-1, sequenceId, -1, 0, 1.0f, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CSimpleModel::SetSequenceTime(uint32_t sequence, int32_t time) {
|
||||
if (this->m_model) {
|
||||
this->m_model->SetBoneSequence(-1, sequence, -1, time, 1.0f, 0, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSimpleModel::UpdateModel() {
|
||||
if (this->m_onUpdateModel.luaRef) {
|
||||
this->RunScript(this->m_onUpdateModel, 0, nullptr);
|
||||
}
|
||||
|
||||
C3Vector position = {
|
||||
this->m_position.x * this->m_layoutScale,
|
||||
this->m_position.y * this->m_layoutScale,
|
||||
this->m_position.z * this->m_layoutScale
|
||||
};
|
||||
|
||||
float scale = NDCToDDCHeight(1.0f) * 1.6666666 * (this->m_scale * this->m_layoutScale);
|
||||
|
||||
this->m_model->SetWorldTransform(position, this->m_facing, scale);
|
||||
}
|
||||
71
src/ui/CSimpleModel.hpp
Normal file
71
src/ui/CSimpleModel.hpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef C_SIMPLE_MODEL_HPP
|
||||
#define C_SIMPLE_MODEL_HPP
|
||||
|
||||
#include "gx/Camera.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "model/Model2.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
#include <tempest/Box.hpp>
|
||||
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
|
||||
class CSimpleModel : public CSimpleFrame {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void LightingCallback(CM2Model* model, CM2Lighting* lighting, void* userArg);
|
||||
static void ModelLoaded(CM2Model* model, void* arg);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
static void RenderModel(void* arg);
|
||||
|
||||
// Member variables
|
||||
CM2Scene* m_scene = nullptr;
|
||||
CM2Model* m_model = nullptr;
|
||||
HCAMERA m_camera = nullptr;
|
||||
uint32_t m_pendingCameraIndex = 0;
|
||||
uint32_t m_pendingCameraId = 0;
|
||||
CM2Light m_light;
|
||||
C3Vector m_position;
|
||||
float m_facing = 0.0f;
|
||||
float m_scale = 1.0f;
|
||||
uint32_t m_flags = 0;
|
||||
CImVector m_fogColor = { 0 };
|
||||
float m_fogNear = 0.0f;
|
||||
float m_fogFar = 1.0f;
|
||||
CAaBox m_bounds;
|
||||
ScriptIx m_onUpdateModel;
|
||||
ScriptIx m_onAnimFinished;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data);
|
||||
virtual bool IsA(int32_t type);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual void OnLayerUpdate(float elapsedSec);
|
||||
virtual void OnFrameRender(CRenderBatch*, uint32_t);
|
||||
virtual void UpdateModel(void);
|
||||
virtual void OnModelLoaded(CM2Model* model);
|
||||
|
||||
// Member functions
|
||||
CSimpleModel(CSimpleFrame*);
|
||||
CM2Scene* GetScene(void);
|
||||
void SetCamera(HCAMERA camera);
|
||||
void SetCameraByID(uint32_t id);
|
||||
void SetCameraByIndex(uint32_t index);
|
||||
void SetFogColor(CImVector&);
|
||||
void SetFogFar(float);
|
||||
void SetFogNear(float);
|
||||
void SetModel(const char*);
|
||||
void SetModel(CM2Model*);
|
||||
void SetScale(float);
|
||||
void SetSequence(uint32_t sequence);
|
||||
int32_t SetSequenceTime(uint32_t sequence, int32_t time);
|
||||
};
|
||||
|
||||
#endif
|
||||
64
src/ui/CSimpleModelFFX.cpp
Normal file
64
src/ui/CSimpleModelFFX.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "ui/CSimpleModelFFX.hpp"
|
||||
#include "gx/Draw.hpp"
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CSimpleModelFFXScript.hpp"
|
||||
#include <storm/Memory.hpp>
|
||||
|
||||
int32_t CSimpleModelFFX::s_metatable;
|
||||
|
||||
CSimpleFrame* CSimpleModelFFX::Create(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleModelFFX::s_simpleModelFFXHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleModelFFX), __FILE__, __LINE__, 0);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleModelFFX(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleModelFFX::Render(void* arg) {
|
||||
CSimpleModelFFX* simpleModel = static_cast<CSimpleModelFFX*>(arg);
|
||||
|
||||
CImVector clearColor = { 0x00, 0x00, 0x00, 0xFF };
|
||||
GxSceneClear(0x1 | 0x2, clearColor);
|
||||
|
||||
// TODO
|
||||
|
||||
GxSceneClear(0x1 | 0x2, clearColor);
|
||||
|
||||
if (simpleModel->m_model) {
|
||||
CSimpleModel::RenderModel(simpleModel);
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleModelFFX::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleModelFFX::RegisterScriptMethods);
|
||||
CSimpleModelFFX::s_metatable = ref;
|
||||
}
|
||||
|
||||
void CSimpleModelFFX::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleModel::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleModelFFXMethods, NUM_SIMPLE_MODEL_FFX_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleModelFFX::CSimpleModelFFX(CSimpleFrame* parent) : CSimpleModel(parent) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CSimpleModelFFX::GetScriptMetaTable() {
|
||||
return CSimpleModelFFX::s_metatable;
|
||||
}
|
||||
|
||||
void CSimpleModelFFX::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
|
||||
CSimpleFrame::OnFrameRender(batch, layer);
|
||||
|
||||
if (layer == DRAWLAYER_ARTWORK) {
|
||||
batch->QueueCallback(CSimpleModelFFX::Render, this);
|
||||
}
|
||||
}
|
||||
27
src/ui/CSimpleModelFFX.hpp
Normal file
27
src/ui/CSimpleModelFFX.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef UI_C_SIMPLE_MODEL_FFX_HPP
|
||||
#define UI_C_SIMPLE_MODEL_FFX_HPP
|
||||
|
||||
#include "ui/CSimpleModel.hpp"
|
||||
|
||||
class CSimpleFrame;
|
||||
|
||||
class CSimpleModelFFX : public CSimpleModel {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
|
||||
// Static functions
|
||||
static CSimpleFrame* Create(CSimpleFrame*);
|
||||
static void CreateScriptMetaTable(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
static void Render(void*);
|
||||
|
||||
// Virtual member functions
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void OnFrameRender(CRenderBatch*, uint32_t);
|
||||
|
||||
// Member functions
|
||||
CSimpleModelFFX(CSimpleFrame*);
|
||||
};
|
||||
|
||||
#endif
|
||||
26
src/ui/CSimpleModelFFXScript.cpp
Normal file
26
src/ui/CSimpleModelFFXScript.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "ui/CSimpleModelFFXScript.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleModelFFX_ResetLights(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModelFFX_AddLight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModelFFX_AddCharacterLight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModelFFX_AddPetLight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleModelFFXMethods[NUM_SIMPLE_MODEL_FFX_SCRIPT_METHODS] = {
|
||||
{ "ResetLights", &CSimpleModelFFX_ResetLights },
|
||||
{ "AddLight", &CSimpleModelFFX_AddLight },
|
||||
{ "AddCharacterLight", &CSimpleModelFFX_AddCharacterLight },
|
||||
{ "AddPetLight", &CSimpleModelFFX_AddPetLight }
|
||||
};
|
||||
10
src/ui/CSimpleModelFFXScript.hpp
Normal file
10
src/ui/CSimpleModelFFXScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_MODEL_FFX_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_MODEL_FFX_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_MODEL_FFX_SCRIPT_METHODS 4
|
||||
|
||||
extern FrameScript_Method SimpleModelFFXMethods[NUM_SIMPLE_MODEL_FFX_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
189
src/ui/CSimpleModelScript.cpp
Normal file
189
src/ui/CSimpleModelScript.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#include "ui/CSimpleModelScript.hpp"
|
||||
#include "ui/CSimpleModel.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleModel_SetModel(lua_State* L) {
|
||||
auto type = CSimpleModel::GetObjectType();
|
||||
auto model = static_cast<CSimpleModel*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isstring(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetModel(\"file\")", model->GetDisplayName());
|
||||
}
|
||||
|
||||
const char* file = lua_tolstring(L, 2, 0);
|
||||
|
||||
model->SetModel(file);
|
||||
|
||||
if (!model->m_model) {
|
||||
return luaL_error(L, "Invalid model file: %s", file);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetModel(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_ClearModel(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetPosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetFacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetScale(lua_State* L) {
|
||||
auto type = CSimpleModel::GetObjectType();
|
||||
auto model = static_cast<CSimpleModel*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetScale(scale)", model->GetDisplayName());
|
||||
}
|
||||
|
||||
float scale = lua_tonumber(L, 2);
|
||||
model->SetScale(scale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetSequence(lua_State* L) {
|
||||
auto type = CSimpleModel::GetObjectType();
|
||||
auto model = static_cast<CSimpleModel*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetSequence(sequence)", model->GetDisplayName());
|
||||
}
|
||||
|
||||
uint32_t sequence = lua_tonumber(L, 2);
|
||||
|
||||
if (sequence >= 506) {
|
||||
return luaL_error(L, "Error: %s:SetSequence(sequence) exceeds valid range of 0 - %d", model->GetDisplayName(), 506);
|
||||
}
|
||||
|
||||
model->SetSequence(sequence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetSequenceTime(lua_State* L) {
|
||||
auto type = CSimpleModel::GetObjectType();
|
||||
auto model = static_cast<CSimpleModel*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3)) {
|
||||
return luaL_error(L, "Usage: %s:SetSequenceTime(sequence, time)", model->GetDisplayName());
|
||||
}
|
||||
|
||||
uint32_t sequence = lua_tonumber(L, 2);
|
||||
int32_t time = lua_tonumber(L, 3);
|
||||
model->SetSequenceTime(sequence, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetCamera(lua_State* L) {
|
||||
auto type = CSimpleModel::GetObjectType();
|
||||
auto model = static_cast<CSimpleModel*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
return luaL_error(L, "Usage: %s:SetCamera(index)", model->GetDisplayName());
|
||||
}
|
||||
|
||||
int32_t index = lua_tonumber(L, 2);
|
||||
model->SetCameraByIndex(index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetLight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetLight(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetPosition(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetFacing(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetScale(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_AdvanceTime(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_ReplaceIconTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetFogColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetFogColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetFogNear(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetFogNear(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetFogFar(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_GetFogFar(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_ClearFog(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleModel_SetGlow(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleModelMethods[NUM_SIMPLE_MODEL_SCRIPT_METHODS] = {
|
||||
{ "SetModel", &CSimpleModel_SetModel },
|
||||
{ "GetModel", &CSimpleModel_GetModel },
|
||||
{ "ClearModel", &CSimpleModel_ClearModel },
|
||||
{ "SetPosition", &CSimpleModel_SetPosition },
|
||||
{ "SetFacing", &CSimpleModel_SetFacing },
|
||||
{ "SetModelScale", &CSimpleModel_SetScale },
|
||||
{ "SetSequence", &CSimpleModel_SetSequence },
|
||||
{ "SetSequenceTime", &CSimpleModel_SetSequenceTime },
|
||||
{ "SetCamera", &CSimpleModel_SetCamera },
|
||||
{ "SetLight", &CSimpleModel_SetLight },
|
||||
{ "GetLight", &CSimpleModel_GetLight },
|
||||
{ "GetPosition", &CSimpleModel_GetPosition },
|
||||
{ "GetFacing", &CSimpleModel_GetFacing },
|
||||
{ "GetModelScale", &CSimpleModel_GetScale },
|
||||
{ "AdvanceTime", &CSimpleModel_AdvanceTime },
|
||||
{ "ReplaceIconTexture", &CSimpleModel_ReplaceIconTexture },
|
||||
{ "SetFogColor", &CSimpleModel_SetFogColor },
|
||||
{ "GetFogColor", &CSimpleModel_GetFogColor },
|
||||
{ "SetFogNear", &CSimpleModel_SetFogNear },
|
||||
{ "GetFogNear", &CSimpleModel_GetFogNear },
|
||||
{ "SetFogFar", &CSimpleModel_SetFogFar },
|
||||
{ "GetFogFar", &CSimpleModel_GetFogFar },
|
||||
{ "ClearFog", &CSimpleModel_ClearFog },
|
||||
{ "SetGlow", &CSimpleModel_SetGlow }
|
||||
};
|
||||
10
src/ui/CSimpleModelScript.hpp
Normal file
10
src/ui/CSimpleModelScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_MODEL_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_MODEL_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_MODEL_SCRIPT_METHODS 24
|
||||
|
||||
extern FrameScript_Method SimpleModelMethods[NUM_SIMPLE_MODEL_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
162
src/ui/CSimpleRegion.cpp
Normal file
162
src/ui/CSimpleRegion.cpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#include "ui/CSimpleRegion.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include <cstring>
|
||||
|
||||
CSimpleRegion::~CSimpleRegion() {
|
||||
this->SetFrame(nullptr, DRAWLAYER_BACKGROUND_BORDER, 0);
|
||||
}
|
||||
|
||||
CSimpleRegion::CSimpleRegion(CSimpleFrame* frame, uint32_t drawlayer, int32_t show) : CScriptRegion() {
|
||||
memset(this->m_color, 0, sizeof(CImVector) * this->m_colorCount);
|
||||
this->m_colorCount = 0;
|
||||
|
||||
memset(this->m_alpha, 0, sizeof(uint8_t) * this->m_alphaCount);
|
||||
this->m_alphaCount = 0;
|
||||
|
||||
if (frame) {
|
||||
this->SetFrame(frame, drawlayer, show);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleRegion::GetVertexColor(CImVector& color) const {
|
||||
if (this->m_colorCount == 1) {
|
||||
color.a = this->m_alpha[0];
|
||||
color.r = this->m_color[0].r;
|
||||
color.g = this->m_color[0].g;
|
||||
color.b = this->m_color[0].b;
|
||||
} else {
|
||||
color = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleRegion::Hide() {
|
||||
this->m_shown = 0;
|
||||
this->HideThis();
|
||||
}
|
||||
|
||||
void CSimpleRegion::HideThis() {
|
||||
if (this->m_visible && this->m_parent) {
|
||||
if (!this->m_parent->m_loading) {
|
||||
this->SetDeferredResize(1);
|
||||
}
|
||||
|
||||
this->m_parent->RemoveFrameRegion(this, this->m_drawlayer);
|
||||
this->m_visible = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CSimpleRegion::IsShown() {
|
||||
return this->m_shown == 1;
|
||||
}
|
||||
|
||||
void CSimpleRegion::OnColorChanged(bool a2) {
|
||||
if (this->m_parent) {
|
||||
// TODO adjust color based on parent
|
||||
}
|
||||
|
||||
if (a2) {
|
||||
this->OnRegionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleRegion::OnRegionChanged() {
|
||||
if (this->m_visible && this->m_parent) {
|
||||
this->m_parent->NotifyDrawLayerChanged(this->m_drawlayer);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleRegion::SetVertexColor(const CImVector& color) {
|
||||
if (
|
||||
this->m_colorCount == 0
|
||||
&& color.a >= 0xFE
|
||||
&& color.r == 0xFF
|
||||
&& color.g == 0xFF
|
||||
&& color.b == 0xFF
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this->m_colorCount == 1
|
||||
&& this->m_alpha[0] == color.a
|
||||
&& this->m_color[0].r == color.r
|
||||
&& this->m_color[0].g == color.g
|
||||
&& this->m_color[0].b == color.b
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool b1 = false;
|
||||
|
||||
if (this->m_colorCount != 1) {
|
||||
this->m_colorCount = 1;
|
||||
this->m_alphaCount = 1;
|
||||
|
||||
b1 = true;
|
||||
}
|
||||
|
||||
this->m_color[0] = color;
|
||||
this->m_alpha[0] = color.a;
|
||||
|
||||
this->OnColorChanged(b1);
|
||||
}
|
||||
|
||||
void CSimpleRegion::SetFrame(CSimpleFrame* frame, uint32_t drawlayer, int32_t show) {
|
||||
if (this->m_parent == frame) {
|
||||
if (this->m_drawlayer == drawlayer) {
|
||||
if (show != this->m_shown) {
|
||||
if (show) {
|
||||
this->Show();
|
||||
} else {
|
||||
this->Hide();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->m_shown) {
|
||||
this->Hide();
|
||||
}
|
||||
|
||||
this->m_drawlayer = drawlayer;
|
||||
|
||||
if (show) {
|
||||
this->Show();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->m_parent) {
|
||||
this->HideThis();
|
||||
this->m_parent->UnregisterRegion(this);
|
||||
}
|
||||
|
||||
this->m_parent = frame;
|
||||
this->m_drawlayer = drawlayer;
|
||||
|
||||
if (frame) {
|
||||
frame->RegisterRegion(this);
|
||||
this->SetDeferredResize(static_cast<CLayoutFrame*>(this->m_parent)->m_flags & 0x2);
|
||||
this->OnColorChanged(0);
|
||||
|
||||
if (show) {
|
||||
this->Show();
|
||||
} else {
|
||||
this->Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleRegion::Show() {
|
||||
this->m_shown = 1;
|
||||
this->ShowThis();
|
||||
}
|
||||
|
||||
void CSimpleRegion::ShowThis() {
|
||||
if (this->m_shown && this->m_parent && this->m_parent->m_visible && !this->m_visible) {
|
||||
if (!this->m_parent->m_loading) {
|
||||
this->SetDeferredResize(0);
|
||||
}
|
||||
|
||||
this->m_parent->AddFrameRegion(this, this->m_drawlayer);
|
||||
this->m_visible = 1;
|
||||
}
|
||||
}
|
||||
42
src/ui/CSimpleRegion.hpp
Normal file
42
src/ui/CSimpleRegion.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef UI_C_SIMPLE_REGION_HPP
|
||||
#define UI_C_SIMPLE_REGION_HPP
|
||||
|
||||
#include "ui/CScriptRegion.hpp"
|
||||
#include <storm/List.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CRenderBatch;
|
||||
|
||||
class CSimpleRegion : public CScriptRegion {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t m_alphaCount = 4;
|
||||
uint8_t m_alpha[4];
|
||||
uint32_t m_colorCount = 4;
|
||||
CImVector m_color[4];
|
||||
TSLink<CSimpleRegion> m_regionLink;
|
||||
TSLink<CSimpleRegion> m_layerLink;
|
||||
int32_t m_drawlayer = 0;
|
||||
int32_t m_shown = 0;
|
||||
int32_t m_visible = 0;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CSimpleRegion();
|
||||
virtual void OnColorChanged(bool);
|
||||
virtual void OnScreenSizeChanged() {};
|
||||
virtual void Draw(CRenderBatch*) = 0;
|
||||
|
||||
// Member functions
|
||||
CSimpleRegion(CSimpleFrame*, uint32_t, int32_t);
|
||||
void GetVertexColor(CImVector& color) const;
|
||||
void Hide(void);
|
||||
void HideThis(void);
|
||||
bool IsShown();
|
||||
void OnRegionChanged(void);
|
||||
void SetVertexColor(const CImVector&);
|
||||
void SetFrame(CSimpleFrame*, uint32_t, int32_t);
|
||||
void Show(void);
|
||||
void ShowThis(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
168
src/ui/CSimpleRender.cpp
Normal file
168
src/ui/CSimpleRender.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#include "ui/CSimpleRender.hpp"
|
||||
#include "gx/Buffer.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "gx/Draw.hpp"
|
||||
#include "gx/Font.hpp"
|
||||
#include "gx/Gx.hpp"
|
||||
#include "gx/RenderState.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "gx/Texture.hpp"
|
||||
#include "gx/Transform.hpp"
|
||||
#include "gx/Types.hpp"
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
|
||||
CGxShader* CSimpleRender::s_vertexShader[2];
|
||||
|
||||
void CSimpleRender::DrawBatch(CRenderBatch* batch) {
|
||||
if (batch->m_texturelist.Count()) {
|
||||
GxRsPush();
|
||||
|
||||
CGxShader* vs = g_theGxDevicePtr->StereoEnabled()
|
||||
? CSimpleRender::s_vertexShader[1]
|
||||
: CSimpleRender::s_vertexShader[0];
|
||||
|
||||
if (vs && vs->Valid()) {
|
||||
GxRsSet(GxRs_VertexShader, vs);
|
||||
|
||||
C44Matrix viewProjMat;
|
||||
GxXformViewProjNativeTranspose(viewProjMat);
|
||||
GxShaderConstantsSet(GxSh_Vertex, 0, reinterpret_cast<float*>(&viewProjMat), 4);
|
||||
} else {
|
||||
GxRsSet(GxRs_Lighting, 0);
|
||||
}
|
||||
|
||||
GxRsSet(GxRs_Fog, 0);
|
||||
GxRsSet(GxRs_DepthTest, 0);
|
||||
GxRsSet(GxRs_DepthWrite, 0);
|
||||
|
||||
CGxTex* textureID = nullptr;
|
||||
EGxBlend alphaMode = GxBlends_Last;
|
||||
CGxShader* ps = nullptr;
|
||||
|
||||
uint32_t idxCount = 0;
|
||||
uint32_t posCount = 0;
|
||||
|
||||
for (int32_t i = 0; i < batch->m_texturelist.Count(); i++) {
|
||||
auto mesh = &batch->m_texturelist[i];
|
||||
|
||||
auto dirty = 0;
|
||||
|
||||
if (mesh->textureID != textureID) {
|
||||
textureID = mesh->textureID;
|
||||
dirty = 1;
|
||||
}
|
||||
|
||||
if (mesh->GetAlphaMode() != alphaMode) {
|
||||
alphaMode = mesh->GetAlphaMode();
|
||||
dirty = 1;
|
||||
}
|
||||
|
||||
if (mesh->shader != ps) {
|
||||
ps = mesh->shader;
|
||||
dirty = 1;
|
||||
}
|
||||
|
||||
CTexture* texture = mesh->texture;
|
||||
CGxTex* gxTex = TextureGetGxTex(texture, 1, nullptr);
|
||||
GxRsSet(GxRs_Texture0, gxTex);
|
||||
|
||||
GxRsSet(GxRs_BlendingMode, alphaMode);
|
||||
|
||||
GxRsSet(GxRs_PixelShader, ps);
|
||||
|
||||
// TODO
|
||||
// - alphaRef
|
||||
|
||||
// TODO
|
||||
// - geometry merging (CSimpleRender::s_mergeEnable)
|
||||
|
||||
posCount = mesh->posCount;
|
||||
idxCount = mesh->idxCount;
|
||||
|
||||
CGxBuf* vertexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Vertex, 24, posCount);
|
||||
char* vertexData = g_theGxDevicePtr->BufLock(vertexStream);
|
||||
CGxVertexPCT* vertexBuf = reinterpret_cast<CGxVertexPCT*>(vertexData);
|
||||
|
||||
CGxBuf* indexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Index, 2, idxCount);
|
||||
char* indexData = g_theGxDevicePtr->BufLock(indexStream);
|
||||
uint16_t* indexBuf = reinterpret_cast<uint16_t*>(indexData);
|
||||
|
||||
if (mesh->indices) {
|
||||
for (int32_t i = 0; i < mesh->posCount; i++) {
|
||||
C3Vector* p = &mesh->position[i];
|
||||
vertexBuf->p.x = p->x;
|
||||
vertexBuf->p.y = p->y;
|
||||
vertexBuf->p.z = p->z;
|
||||
|
||||
if (mesh->color) {
|
||||
auto& color = mesh->color[i * mesh->colorCount >> 2];
|
||||
|
||||
if (GxCaps()->m_colorFormat == GxCF_rgba) {
|
||||
vertexBuf->c.r = color.b;
|
||||
vertexBuf->c.g = color.g;
|
||||
vertexBuf->c.b = color.r;
|
||||
vertexBuf->c.a = color.a;
|
||||
} else {
|
||||
vertexBuf->c = color;
|
||||
}
|
||||
} else {
|
||||
vertexBuf->c.r = 0xFF;
|
||||
vertexBuf->c.g = 0xFF;
|
||||
vertexBuf->c.b = 0xFF;
|
||||
vertexBuf->c.a = 0xFF;
|
||||
}
|
||||
|
||||
if (mesh->onAtlas) {
|
||||
// TODO
|
||||
} else {
|
||||
C2Vector* tc = &mesh->texCoord[i];
|
||||
vertexBuf->tc[0].x = tc->x;
|
||||
vertexBuf->tc[0].y = tc->y;
|
||||
}
|
||||
|
||||
vertexBuf++;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < mesh->idxCount; i++) {
|
||||
*indexBuf = mesh->indices[i];
|
||||
indexBuf++;
|
||||
}
|
||||
}
|
||||
|
||||
GxBufUnlock(vertexStream, 24 * posCount);
|
||||
GxBufUnlock(indexStream, 2 * idxCount);
|
||||
|
||||
GxPrimVertexPtr(vertexStream, GxVBF_PCT);
|
||||
GxPrimIndexPtr(indexStream);
|
||||
|
||||
CGxBatch batch;
|
||||
batch.m_primType = GxPrim_Triangles;
|
||||
batch.m_start = 0;
|
||||
batch.m_count = 6;
|
||||
batch.m_minIndex = 0;
|
||||
batch.m_maxIndex = 3;
|
||||
|
||||
GxDraw(&batch, 1);
|
||||
}
|
||||
|
||||
GxRsPop();
|
||||
}
|
||||
|
||||
if (batch->m_stringbatch) {
|
||||
GxuFontRenderBatch(batch->m_stringbatch);
|
||||
}
|
||||
|
||||
for (auto callback = batch->m_callbacks.Head(); callback; callback = batch->m_callbacks.Link(callback)->Next()) {
|
||||
callback->callback(callback->param);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleRender::Init() {
|
||||
g_theGxDevicePtr->ShaderCreate(
|
||||
CSimpleRender::s_vertexShader,
|
||||
GxSh_Vertex,
|
||||
"Shaders\\Vertex",
|
||||
"UI",
|
||||
2
|
||||
);
|
||||
}
|
||||
17
src/ui/CSimpleRender.hpp
Normal file
17
src/ui/CSimpleRender.hpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef UI_C_SIMPLE_RENDER_HPP
|
||||
#define UI_C_SIMPLE_RENDER_HPP
|
||||
|
||||
class CGxShader;
|
||||
class CRenderBatch;
|
||||
|
||||
class CSimpleRender {
|
||||
public:
|
||||
// Static variables
|
||||
static CGxShader* s_vertexShader[];
|
||||
|
||||
// Static functions
|
||||
static void DrawBatch(CRenderBatch*);
|
||||
static void Init(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
410
src/ui/CSimpleScrollFrame.cpp
Normal file
410
src/ui/CSimpleScrollFrame.cpp
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
#include "ui/CSimpleScrollFrame.hpp"
|
||||
#include "gx/Camera.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Transform.hpp"
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CSimpleScrollFrameScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <common/XML.hpp>
|
||||
#include <tempest/Matrix.hpp>
|
||||
|
||||
int32_t CSimpleScrollFrame::s_metatable;
|
||||
int32_t CSimpleScrollFrame::s_objectType;
|
||||
|
||||
void CSimpleScrollFrame::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleScrollFrame::RegisterScriptMethods);
|
||||
CSimpleScrollFrame::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame::GetObjectType() {
|
||||
if (!CSimpleScrollFrame::s_objectType) {
|
||||
CSimpleScrollFrame::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleScrollFrame::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleFrame::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleScrollFrameMethods, NUM_SIMPLE_SCROLL_FRAME_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::RenderScrollChild(void* param) {
|
||||
auto frame = static_cast<CSimpleScrollFrame*>(param);
|
||||
|
||||
CRect viewRect;
|
||||
if (!frame->GetHitRect(viewRect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto scrollChild = frame->m_scrollChild;
|
||||
if (!scrollChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scrollChild->m_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
C44Matrix savedProj;
|
||||
GxXformProjection(savedProj);
|
||||
|
||||
C44Matrix savedView;
|
||||
GxXformView(savedView);
|
||||
|
||||
float minX, maxX, minY, maxY, minZ, maxZ;
|
||||
GxXformViewport(minX, maxX, minY, maxY, minZ, maxZ);
|
||||
|
||||
// TODO clean up
|
||||
float v34 = 0.0f;
|
||||
float v35 = 0.0f;
|
||||
float v36 = 0.0f;
|
||||
float v37 = 0.0f;
|
||||
NDCToDDC(minX, minY, &v35, &v34);
|
||||
NDCToDDC(maxX, maxY, &v37, &v36);
|
||||
|
||||
auto v4 = viewRect.minX;
|
||||
if (v35 > viewRect.minX) {
|
||||
v4 = v35;
|
||||
viewRect.minX = v35;
|
||||
}
|
||||
auto v5 = viewRect.maxX;
|
||||
if (v37 < viewRect.maxX) {
|
||||
v5 = v37;
|
||||
viewRect.maxX = v37;
|
||||
}
|
||||
auto v6 = viewRect.minY;
|
||||
if (v34 > viewRect.minY) {
|
||||
v6 = v34;
|
||||
viewRect.minY = v34;
|
||||
}
|
||||
auto v7 = viewRect.maxY;
|
||||
if (v36 < viewRect.maxY) {
|
||||
v7 = v36;
|
||||
viewRect.maxY = v36;
|
||||
}
|
||||
|
||||
if (v4 != v5 && v6 != v7) {
|
||||
C2Vector screenPoint = { 0.0f, 0.0f };
|
||||
CameraSetupScreenProjection(viewRect, screenPoint, 0.0f, 0);
|
||||
|
||||
DDCToNDC(viewRect.minX, viewRect.minY, &viewRect.minX, &viewRect.minY);
|
||||
DDCToNDC(viewRect.maxX, viewRect.maxY, &viewRect.maxX, &viewRect.maxY);
|
||||
|
||||
float v11, v12, v13, v14;
|
||||
|
||||
if (viewRect.minX >= 0.0f) {
|
||||
v12 = viewRect.minX;
|
||||
v11 = viewRect.maxX;
|
||||
} else {
|
||||
v11 = viewRect.maxX - viewRect.minX;
|
||||
viewRect.maxX = v11;
|
||||
v12 = 0.0f;
|
||||
viewRect.minX = 0.0f;
|
||||
}
|
||||
|
||||
if (v11 > 1.0f) {
|
||||
v12 = v12 - (v11 - 1.0f);
|
||||
viewRect.minX = v12;
|
||||
viewRect.maxX = 1.0f;
|
||||
v11 = 1.0f;
|
||||
}
|
||||
|
||||
if (viewRect.minY >= 0.0f) {
|
||||
v14 = viewRect.minY;
|
||||
v13 = viewRect.maxY;
|
||||
} else {
|
||||
v13 = viewRect.maxY - viewRect.minY;
|
||||
viewRect.maxY = v13;
|
||||
v14 = 0.0f;
|
||||
viewRect.minY = 0.0f;
|
||||
}
|
||||
|
||||
float v15 = v14;
|
||||
float v16 = v13;
|
||||
float v17 = v15;
|
||||
|
||||
if (v16 > 1.0f) {
|
||||
v17 = v17 - (v16 - 1.0f);
|
||||
viewRect.minY = v17;
|
||||
v16 = 1.0f;
|
||||
viewRect.maxY = 1.0f;
|
||||
}
|
||||
|
||||
float v18 = v16;
|
||||
float v19 = v12;
|
||||
float v20 = v18;
|
||||
|
||||
if (v19 < v11) {
|
||||
float v21 = v19;
|
||||
float v22 = v17;
|
||||
float v23 = v21;
|
||||
|
||||
if (v22 < v20) {
|
||||
float v27 = v20;
|
||||
float v26 = v22;
|
||||
float v25 = v11;
|
||||
float v24 = v23;
|
||||
|
||||
GxXformSetViewport(v24, v25, v26, v27, 0.0f, 1.0f);
|
||||
scrollChild->OnFrameRender();
|
||||
}
|
||||
}
|
||||
|
||||
GxXformSetProjection(savedProj);
|
||||
GxXformSetView(savedView);
|
||||
GxXformSetViewport(minX, maxX, minY, maxY, minZ, maxZ);
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleScrollFrame::CSimpleScrollFrame(CSimpleFrame* parent) : CSimpleFrame(parent) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame::GetBoundsRect(CRect& bounds) {
|
||||
if (this->IsResizePending()) {
|
||||
this->Resize(1);
|
||||
}
|
||||
|
||||
CRect rect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (this->GetRect(&rect)) {
|
||||
bounds.minX = rect.minX >= bounds.minX ? bounds.minX : rect.minX;
|
||||
bounds.maxX = rect.maxX <= bounds.maxX ? bounds.maxX : rect.maxX;
|
||||
bounds.minY = rect.minY >= bounds.minY ? bounds.minY : rect.minY;
|
||||
bounds.maxY = rect.maxY <= bounds.maxY ? bounds.maxY : rect.maxY;
|
||||
}
|
||||
|
||||
for (auto region = this->m_regions.Head(); region; region = this->m_regions.Next(region)) {
|
||||
if (region->IsShown()) {
|
||||
if (region->IsResizePending()) {
|
||||
region->Resize(1);
|
||||
}
|
||||
|
||||
if (region->GetRect(&rect)) {
|
||||
bounds.minX = rect.minX >= bounds.minX ? bounds.minX : rect.minX;
|
||||
bounds.maxX = rect.maxX <= bounds.maxX ? bounds.maxX : rect.maxX;
|
||||
bounds.minY = rect.minY >= bounds.minY ? bounds.minY : rect.minY;
|
||||
bounds.maxY = rect.maxY <= bounds.maxY ? bounds.maxY : rect.maxY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto child = this->m_children.Head(); child; child = this->m_children.Next(child)) {
|
||||
if (child->frame != this->m_scrollChild && child->frame->m_shown) {
|
||||
child->frame->GetBoundsRect(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
return bounds.maxY > bounds.minY && bounds.maxX > bounds.minX;
|
||||
}
|
||||
|
||||
FrameScript_Object::ScriptIx* CSimpleScrollFrame::GetScriptByName(const char* name, ScriptData& data) {
|
||||
auto parentScript = CSimpleFrame::GetScriptByName(name, data);
|
||||
|
||||
if (parentScript) {
|
||||
return parentScript;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnHorizontalScroll", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,offset) %s end";
|
||||
return &this->m_onHorizontalScroll;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnVerticalScroll", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,offset) %s end";
|
||||
return &this->m_onVerticalScroll;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnScrollRangeChanged", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,xrange,yrange) %s end";
|
||||
return &this->m_onScrollRangeChanged;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame::GetScriptMetaTable() {
|
||||
return CSimpleScrollFrame::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleScrollFrame::IsA(int32_t type) {
|
||||
return type == CSimpleScrollFrame::s_objectType
|
||||
|| type == CSimpleFrame::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::LoadXML(XMLNode* node, CStatus* status) {
|
||||
CSimpleFrame::LoadXML(node, status);
|
||||
|
||||
XMLNode* scrollChildNode = node->GetChildByName("ScrollChild");
|
||||
|
||||
if (scrollChildNode) {
|
||||
XMLNode* childNode = scrollChildNode->m_child;
|
||||
|
||||
if (childNode) {
|
||||
CSimpleFrame* childFrame = FrameXML_CreateFrame(childNode, this, status);
|
||||
|
||||
if (childFrame) {
|
||||
this->SetScrollChild(childFrame);
|
||||
}
|
||||
} else {
|
||||
const char* frameName = this->GetName();
|
||||
|
||||
if (!frameName) {
|
||||
frameName = "<unnamed>";
|
||||
}
|
||||
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Frame %s: Scroll frame created without scroll child",
|
||||
frameName
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
|
||||
CSimpleFrame::OnFrameRender(batch, layer);
|
||||
|
||||
if (layer == DRAWLAYER_HIGHLIGHT) {
|
||||
batch->QueueCallback(CSimpleScrollFrame::RenderScrollChild, this);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::OnFrameSizeChanged(float w, float h) {
|
||||
CSimpleFrame::OnFrameSizeChanged(w, h);
|
||||
this->m_updateScrollChild = 1;
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::OnLayerUpdate(float elapsedSec) {
|
||||
CSimpleFrame::OnLayerUpdate(elapsedSec);
|
||||
|
||||
if (this->m_updateScrollChild) {
|
||||
CRect rect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
if (this->GetRect(&rect)) {
|
||||
float w = rect.maxX - rect.minX;
|
||||
float h = rect.maxY - rect.minY;
|
||||
this->UpdateScrollChildRect(w, h);
|
||||
}
|
||||
|
||||
this->m_updateScrollChild = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::RunOnScrollRangeChangedScript() {
|
||||
if (!this->m_onScrollRangeChanged.luaRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
auto rangeX = this->m_scrollRange.x;
|
||||
auto ddcRangeX = CoordinateGetAspectCompensation() * 1024.0f * rangeX;
|
||||
auto ndcRangeX = DDCToNDCWidth(ddcRangeX);
|
||||
lua_pushnumber(L, ndcRangeX);
|
||||
|
||||
auto rangeY = this->m_scrollRange.y;
|
||||
auto ddcRangeY = CoordinateGetAspectCompensation() * 1024.0f * rangeY;
|
||||
auto ndcRangeY = DDCToNDCWidth(ddcRangeY);
|
||||
lua_pushnumber(L, ndcRangeY);
|
||||
|
||||
this->RunScript(this->m_onScrollRangeChanged, 2, nullptr);
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::RunOnVerticalScrollScript() {
|
||||
if (!this->m_onVerticalScroll.luaRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
auto offsetY = this->m_scrollOffset.y;
|
||||
auto ddcOffsetY = CoordinateGetAspectCompensation() * 1024.0f * offsetY;
|
||||
auto ndcOffsetY = DDCToNDCWidth(ddcOffsetY);
|
||||
lua_pushnumber(L, ndcOffsetY);
|
||||
|
||||
this->RunScript(this->m_onVerticalScroll, 1, nullptr);
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::SetScrollChild(CSimpleFrame* frame) {
|
||||
if (this->m_scrollChild) {
|
||||
this->m_scrollChild->SetBeingScrolled(0, 0);
|
||||
this->m_scrollChild->SetParent(nullptr);
|
||||
}
|
||||
|
||||
this->m_scrollChild = frame;
|
||||
|
||||
if (this->m_scrollChild) {
|
||||
this->m_scrollChild->SetParent(this);
|
||||
this->m_scrollChild->SetBeingScrolled(1, 1);
|
||||
}
|
||||
|
||||
this->UpdateScrollChild();
|
||||
|
||||
this->m_updateScrollChild = 1;
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::SetVerticalScroll(float offset) {
|
||||
if (fabs(offset - this->m_scrollOffset.y) >= 0.00000095367432) {
|
||||
this->m_scrollOffset.y = offset;
|
||||
this->UpdateScrollChild();
|
||||
this->RunOnVerticalScrollScript();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::UpdateScrollChild() {
|
||||
if (!this->m_scrollChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_scrollChild->ClearAllPoints();
|
||||
this->m_scrollChild->SetPoint(
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
this,
|
||||
FRAMEPOINT_TOPLEFT,
|
||||
-this->m_scrollOffset.x,
|
||||
this->m_scrollOffset.y,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
void CSimpleScrollFrame::UpdateScrollChildRect(float w, float h) {
|
||||
if (!this->m_scrollChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
float rangeX = this->m_scrollRange.x;
|
||||
float rangeY = this->m_scrollRange.y;
|
||||
|
||||
CRect childBounds = {
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max(),
|
||||
0.0f,
|
||||
0.0f
|
||||
};
|
||||
|
||||
this->m_scrollChild->GetBoundsRect(childBounds);
|
||||
|
||||
auto ooScale = 1.0f / this->m_layoutScale;
|
||||
|
||||
auto v7 = std::max(childBounds.maxX - childBounds.minX - w, 0.0f);
|
||||
this->m_scrollRange.x = v7 * ooScale;
|
||||
|
||||
auto v12 = std::max(childBounds.maxY - childBounds.minY - h, 0.0f);
|
||||
this->m_scrollRange.y = v12 * ooScale;
|
||||
|
||||
if (
|
||||
fabs(this->m_scrollRange.x - rangeX) >= 0.00000095367432
|
||||
|| fabs(this->m_scrollRange.y - rangeY) >= 0.00000095367432
|
||||
) {
|
||||
this->RunOnScrollRangeChangedScript();
|
||||
}
|
||||
}
|
||||
51
src/ui/CSimpleScrollFrame.hpp
Normal file
51
src/ui/CSimpleScrollFrame.hpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef UI_C_SIMPLE_SCROLL_FRAME_HPP
|
||||
#define UI_C_SIMPLE_SCROLL_FRAME_HPP
|
||||
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CRect;
|
||||
class CRenderBatch;
|
||||
|
||||
class CSimpleScrollFrame : public CSimpleFrame {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
static void RenderScrollChild(void* param);
|
||||
|
||||
// Member variables
|
||||
int32_t m_updateScrollChild = 0;
|
||||
CSimpleFrame* m_scrollChild = nullptr;
|
||||
C2Vector m_scrollRange;
|
||||
C2Vector m_scrollOffset;
|
||||
ScriptIx m_onHorizontalScroll;
|
||||
ScriptIx m_onVerticalScroll;
|
||||
ScriptIx m_onScrollRangeChanged;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ScriptIx* GetScriptByName(const char*, ScriptData&);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual int32_t GetBoundsRect(CRect& bounds);
|
||||
virtual void OnLayerUpdate(float elapsedSec);
|
||||
virtual void OnFrameRender(CRenderBatch* batch, uint32_t layer);
|
||||
virtual void OnFrameSizeChanged(float w, float h);
|
||||
|
||||
// Member functions
|
||||
CSimpleScrollFrame(CSimpleFrame*);
|
||||
void RunOnScrollRangeChangedScript();
|
||||
void RunOnVerticalScrollScript();
|
||||
void SetScrollChild(CSimpleFrame*);
|
||||
void SetVerticalScroll(float offset);
|
||||
void UpdateScrollChild();
|
||||
void UpdateScrollChildRect(float w, float h);
|
||||
};
|
||||
|
||||
#endif
|
||||
105
src/ui/CSimpleScrollFrameScript.cpp
Normal file
105
src/ui/CSimpleScrollFrameScript.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include "ui/CSimpleScrollFrameScript.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "ui/CSimpleScrollFrame.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleScrollFrame_SetScrollChild(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_GetScrollChild(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_SetHorizontalScroll(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_SetVerticalScroll(lua_State* L) {
|
||||
auto type = CSimpleScrollFrame::GetObjectType();
|
||||
auto scrollFrame = static_cast<CSimpleScrollFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!scrollFrame->ProtectedFunctionsAllowed()) {
|
||||
// TODO handle check
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "Usage: %s:SetVerticalScroll(offset)", scrollFrame->GetDisplayName());
|
||||
}
|
||||
|
||||
float offset = lua_tonumber(L, 2);
|
||||
float ndcOffset = offset / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcOffset = NDCToDDCWidth(ndcOffset);
|
||||
|
||||
scrollFrame->SetVerticalScroll(ddcOffset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_GetHorizontalScroll(lua_State* L) {
|
||||
auto type = CSimpleScrollFrame::GetObjectType();
|
||||
auto scrollFrame = static_cast<CSimpleScrollFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float ddcOffset = CoordinateGetAspectCompensation() * 1024.0f * scrollFrame->m_scrollOffset.x;
|
||||
float ndcOffset = DDCToNDCWidth(ddcOffset);
|
||||
|
||||
lua_pushnumber(L, ndcOffset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_GetVerticalScroll(lua_State* L) {
|
||||
auto type = CSimpleScrollFrame::GetObjectType();
|
||||
auto scrollFrame = static_cast<CSimpleScrollFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float ddcOffset = CoordinateGetAspectCompensation() * 1024.0f * scrollFrame->m_scrollOffset.y;
|
||||
float ndcOffset = DDCToNDCWidth(ddcOffset);
|
||||
|
||||
lua_pushnumber(L, ndcOffset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_GetHorizontalScrollRange(lua_State* L) {
|
||||
auto type = CSimpleScrollFrame::GetObjectType();
|
||||
auto scrollFrame = static_cast<CSimpleScrollFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float ddcRange = CoordinateGetAspectCompensation() * 1024.0f * scrollFrame->m_scrollRange.x;
|
||||
float ndcRange = DDCToNDCWidth(ddcRange);
|
||||
|
||||
lua_pushnumber(L, ndcRange);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_GetVerticalScrollRange(lua_State* L) {
|
||||
auto type = CSimpleScrollFrame::GetObjectType();
|
||||
auto scrollFrame = static_cast<CSimpleScrollFrame*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float ddcRange = CoordinateGetAspectCompensation() * 1024.0f * scrollFrame->m_scrollRange.y;
|
||||
float ndcRange = DDCToNDCWidth(ddcRange);
|
||||
|
||||
lua_pushnumber(L, ndcRange);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleScrollFrame_UpdateScrollChildRect(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleScrollFrameMethods[NUM_SIMPLE_SCROLL_FRAME_SCRIPT_METHODS] = {
|
||||
{ "SetScrollChild", &CSimpleScrollFrame_SetScrollChild },
|
||||
{ "GetScrollChild", &CSimpleScrollFrame_GetScrollChild },
|
||||
{ "SetHorizontalScroll", &CSimpleScrollFrame_SetHorizontalScroll },
|
||||
{ "SetVerticalScroll", &CSimpleScrollFrame_SetVerticalScroll },
|
||||
{ "GetHorizontalScroll", &CSimpleScrollFrame_GetHorizontalScroll },
|
||||
{ "GetVerticalScroll", &CSimpleScrollFrame_GetVerticalScroll },
|
||||
{ "GetHorizontalScrollRange", &CSimpleScrollFrame_GetHorizontalScrollRange },
|
||||
{ "GetVerticalScrollRange", &CSimpleScrollFrame_GetVerticalScrollRange },
|
||||
{ "UpdateScrollChildRect", &CSimpleScrollFrame_UpdateScrollChildRect }
|
||||
};
|
||||
10
src/ui/CSimpleScrollFrameScript.hpp
Normal file
10
src/ui/CSimpleScrollFrameScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_SCROLL_FRAME_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_SCROLL_FRAME_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_SCROLL_FRAME_SCRIPT_METHODS 9
|
||||
|
||||
extern FrameScript_Method SimpleScrollFrameMethods[NUM_SIMPLE_SCROLL_FRAME_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
145
src/ui/CSimpleSlider.cpp
Normal file
145
src/ui/CSimpleSlider.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#include "ui/CSimpleSlider.hpp"
|
||||
#include "math/Utils.hpp"
|
||||
#include "ui/CSimpleSliderScript.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
|
||||
int32_t CSimpleSlider::s_metatable;
|
||||
int32_t CSimpleSlider::s_objectType;
|
||||
|
||||
void CSimpleSlider::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleSlider::RegisterScriptMethods);
|
||||
CSimpleSlider::s_metatable = ref;
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider::GetObjectType() {
|
||||
if (!CSimpleSlider::s_objectType) {
|
||||
CSimpleSlider::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleSlider::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleSlider::RegisterScriptMethods(lua_State* L) {
|
||||
CSimpleFrame::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleSliderMethods, NUM_SIMPLE_SLIDER_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
FrameScript_Object::ScriptIx* CSimpleSlider::GetScriptByName(const char* name, ScriptData& data) {
|
||||
auto parentScript = CSimpleFrame::GetScriptByName(name, data);
|
||||
|
||||
if (parentScript) {
|
||||
return parentScript;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnValueChanged", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,value) %s end";
|
||||
return &this->m_onValueChanged;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(name, "OnMinMaxChanged", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,min,max) %s end";
|
||||
return &this->m_onMinMaxChanged;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider::GetScriptMetaTable() {
|
||||
return CSimpleSlider::s_metatable;
|
||||
}
|
||||
|
||||
bool CSimpleSlider::IsA(int32_t type) {
|
||||
return type == CSimpleSlider::s_objectType
|
||||
|| type == CSimpleFrame::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleSlider::RunOnMinMaxChangedScript() {
|
||||
if (!this->m_onMinMaxChanged.luaRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
lua_pushnumber(L, this->m_baseValue);
|
||||
lua_pushnumber(L, this->m_range + this->m_baseValue);
|
||||
|
||||
this->RunScript(this->m_onMinMaxChanged, 2, nullptr);
|
||||
}
|
||||
|
||||
void CSimpleSlider::RunOnValueChangedScript() {
|
||||
if (!this->m_onValueChanged.luaRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
lua_pushnumber(L, this->m_value);
|
||||
|
||||
this->RunScript(this->m_onValueChanged, 1, nullptr);
|
||||
}
|
||||
|
||||
void CSimpleSlider::SetMinMaxValues(float min, float max) {
|
||||
float range = max - min;
|
||||
|
||||
if (this->m_rangeSet && AreEqual(this->m_range, range, WHOA_EPSILON_1) && AreEqual(this->m_baseValue, min, WHOA_EPSILON_1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_baseValue = min;
|
||||
this->m_range = range;
|
||||
this->m_changed = 1;
|
||||
this->m_rangeSet = 1;
|
||||
|
||||
this->RunOnMinMaxChangedScript();
|
||||
|
||||
if (this->m_valueSet) {
|
||||
// Fit current value within range
|
||||
this->SetValue(this->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleSlider::SetValue(float value) {
|
||||
if (!this->m_rangeSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto v4 = value;
|
||||
auto v5 = std::max(value, this->m_baseValue);
|
||||
auto maxValue = this->m_range + this->m_baseValue;
|
||||
|
||||
if (maxValue >= v5) {
|
||||
if (v4 < this->m_baseValue) {
|
||||
v4 = this->m_baseValue;
|
||||
}
|
||||
} else {
|
||||
v4 = maxValue;
|
||||
}
|
||||
|
||||
auto newValue = this->Sub96BC10(v4);
|
||||
|
||||
// Clamp to max value
|
||||
if (newValue + this->m_valueStep >= maxValue) {
|
||||
newValue = maxValue;
|
||||
}
|
||||
|
||||
// Clamp to base value
|
||||
if (newValue - this->m_valueStep < this->m_baseValue) {
|
||||
newValue = this->m_baseValue;
|
||||
}
|
||||
|
||||
if (!this->m_valueSet || fabs(newValue - this->m_value) >= 0.00000023841858) {
|
||||
this->m_value = newValue;
|
||||
this->m_changed = 1;
|
||||
this->m_valueSet = 1;
|
||||
|
||||
this->RunOnValueChangedScript();
|
||||
}
|
||||
}
|
||||
|
||||
float CSimpleSlider::Sub96BC10(float value) {
|
||||
// TODO
|
||||
return value;
|
||||
}
|
||||
51
src/ui/CSimpleSlider.hpp
Normal file
51
src/ui/CSimpleSlider.hpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef UI_C_SIMPLE_SLIDER_HPP
|
||||
#define UI_C_SIMPLE_SLIDER_HPP
|
||||
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
|
||||
class CSimpleSlider : public CSimpleFrame {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static int32_t GetObjectType(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
int32_t m_changed : 1;
|
||||
int32_t m_rangeSet : 1;
|
||||
int32_t m_valueSet : 1;
|
||||
int32_t m_buttonDown : 1;
|
||||
float m_baseValue = 0.0f;
|
||||
float m_range = 0.0f;
|
||||
float m_value = 0.0f;
|
||||
float m_valueStep = 0.0f;
|
||||
ScriptIx m_onValueChanged;
|
||||
ScriptIx m_onMinMaxChanged;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ScriptIx* GetScriptByName(const char*, ScriptData&);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
|
||||
// Member functions
|
||||
CSimpleSlider(CSimpleFrame* parent)
|
||||
: CSimpleFrame(parent)
|
||||
, m_changed(0)
|
||||
, m_rangeSet(0)
|
||||
, m_valueSet(0)
|
||||
, m_buttonDown(0)
|
||||
{
|
||||
this->EnableEvent(SIMPLE_EVENT_MOUSE, -1);
|
||||
};
|
||||
void RunOnMinMaxChangedScript();
|
||||
void RunOnValueChangedScript();
|
||||
void SetMinMaxValues(float min, float max);
|
||||
void SetValue(float value);
|
||||
float Sub96BC10(float value);
|
||||
};
|
||||
|
||||
#endif
|
||||
108
src/ui/CSimpleSliderScript.cpp
Normal file
108
src/ui/CSimpleSliderScript.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#include "ui/CSimpleSliderScript.hpp"
|
||||
#include "ui/CSimpleSlider.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleSlider_GetThumbTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_SetThumbTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_GetOrientation(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_SetOrientation(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_GetMinMaxValues(lua_State* L) {
|
||||
auto type = CSimpleSlider::GetObjectType();
|
||||
auto slider = static_cast<CSimpleSlider*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
lua_pushnumber(L, slider->m_baseValue);
|
||||
lua_pushnumber(L, slider->m_range + slider->m_baseValue);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_SetMinMaxValues(lua_State* L) {
|
||||
auto type = CSimpleSlider::GetObjectType();
|
||||
auto slider = static_cast<CSimpleSlider*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3) || lua_tonumber(L, 2) > lua_tonumber(L, 3)) {
|
||||
luaL_error(L, "Usage: %s:SetMinMaxValues(min, max)", slider->GetDisplayName());
|
||||
}
|
||||
|
||||
float min = lua_tonumber(L, 2);
|
||||
float max = lua_tonumber(L, 3);
|
||||
|
||||
slider->SetMinMaxValues(min, max);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_GetValue(lua_State* L) {
|
||||
auto type = CSimpleSlider::GetObjectType();
|
||||
auto slider = static_cast<CSimpleSlider*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
float value = slider->m_value;
|
||||
|
||||
lua_pushnumber(L, value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_SetValue(lua_State* L) {
|
||||
auto type = CSimpleSlider::GetObjectType();
|
||||
auto slider = static_cast<CSimpleSlider*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "Usage: %s:SetValue(value)", slider->GetDisplayName());
|
||||
}
|
||||
|
||||
float value = lua_tonumber(L, 2);
|
||||
slider->SetValue(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_GetValueStep(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_SetValueStep(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_Enable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_Disable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleSlider_IsEnabled(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleSliderMethods[NUM_SIMPLE_SLIDER_SCRIPT_METHODS] = {
|
||||
{ "GetThumbTexture", &CSimpleSlider_GetThumbTexture },
|
||||
{ "SetThumbTexture", &CSimpleSlider_SetThumbTexture },
|
||||
{ "GetOrientation", &CSimpleSlider_GetOrientation },
|
||||
{ "SetOrientation", &CSimpleSlider_SetOrientation },
|
||||
{ "GetMinMaxValues", &CSimpleSlider_GetMinMaxValues },
|
||||
{ "SetMinMaxValues", &CSimpleSlider_SetMinMaxValues },
|
||||
{ "GetValue", &CSimpleSlider_GetValue },
|
||||
{ "SetValue", &CSimpleSlider_SetValue },
|
||||
{ "GetValueStep", &CSimpleSlider_GetValueStep },
|
||||
{ "SetValueStep", &CSimpleSlider_SetValueStep },
|
||||
{ "Enable", &CSimpleSlider_Enable },
|
||||
{ "Disable", &CSimpleSlider_Disable },
|
||||
{ "IsEnabled", &CSimpleSlider_IsEnabled }
|
||||
};
|
||||
10
src/ui/CSimpleSliderScript.hpp
Normal file
10
src/ui/CSimpleSliderScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_SLIDER_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_SLIDER_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_SLIDER_SCRIPT_METHODS 13
|
||||
|
||||
extern FrameScript_Method SimpleSliderMethods[NUM_SIMPLE_SLIDER_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
537
src/ui/CSimpleTexture.cpp
Normal file
537
src/ui/CSimpleTexture.cpp
Normal file
|
|
@ -0,0 +1,537 @@
|
|||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "ui/CFramePoint.hpp"
|
||||
#include "ui/CRenderBatch.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleTextureScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/LoadXML.hpp"
|
||||
#include "ui/Util.hpp"
|
||||
#include "util/StringTo.hpp"
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
CGxShader* CSimpleTexture::s_imageModePixelShaders[2] = {};
|
||||
|
||||
uint16_t CSimpleTexture::s_indices[] = {
|
||||
0, 1, 2,
|
||||
2, 1, 3
|
||||
};
|
||||
|
||||
int32_t CSimpleTexture::s_metatable;
|
||||
int32_t CSimpleTexture::s_objectType;
|
||||
EGxTexFilter CSimpleTexture::s_textureFilterMode = GxTex_Linear;
|
||||
|
||||
void CSimpleTexture::CreateScriptMetaTable() {
|
||||
lua_State* L = FrameScript_GetContext();
|
||||
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleTexture::RegisterScriptMethods);
|
||||
CSimpleTexture::s_metatable = ref;
|
||||
}
|
||||
|
||||
CGxShader* CSimpleTexture::GetImageModePixelShader(TextureImageMode mode) {
|
||||
CGxShader* shader = CSimpleTexture::s_imageModePixelShaders[mode];
|
||||
|
||||
if (shader && shader->Valid()) {
|
||||
return shader;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture::GetObjectType() {
|
||||
if (!CSimpleTexture::s_objectType) {
|
||||
CSimpleTexture::s_objectType = ++FrameScript_Object::s_objectTypes;
|
||||
}
|
||||
|
||||
return CSimpleTexture::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleTexture::Init() {
|
||||
static const char* paths[] = { "UI", "Desaturate" };
|
||||
|
||||
for (int32_t i = 0; i < 2; i++) {
|
||||
g_theGxDevicePtr->ShaderCreate(
|
||||
&s_imageModePixelShaders[i],
|
||||
GxSh_Pixel,
|
||||
"Shaders\\Pixel",
|
||||
paths[i],
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTexture::RegisterScriptMethods(lua_State* L) {
|
||||
CScriptRegion::RegisterScriptMethods(L);
|
||||
FrameScript_Object::FillScriptMethodTable(L, SimpleTextureMethods, NUM_SIMPLE_TEXTURE_SCRIPT_METHODS);
|
||||
}
|
||||
|
||||
CSimpleTexture::CSimpleTexture(CSimpleFrame* frame, uint32_t drawlayer, int32_t show) : CSimpleRegion(frame, drawlayer, show) {
|
||||
this->m_nonBlocking = 0;
|
||||
this->m_updateTexCoord = 0;
|
||||
this->m_horizTile = 0;
|
||||
this->m_vertTile = 0;
|
||||
|
||||
this->m_shader = CSimpleTexture::GetImageModePixelShader(ImageMode_UI);
|
||||
|
||||
// TODO
|
||||
// CSimpleTexture::s_count++;
|
||||
|
||||
this->m_texCoord[0] = { 0.0f, 0.0f };
|
||||
this->m_texCoord[1] = { 0.0f, 1.0f };
|
||||
this->m_texCoord[2] = { 1.0f, 0.0f };
|
||||
this->m_texCoord[3] = { 1.0f, 1.0f };
|
||||
}
|
||||
|
||||
CSimpleTexture::~CSimpleTexture() {
|
||||
if (this->m_texture) {
|
||||
HandleClose(this->m_texture);
|
||||
}
|
||||
|
||||
// TODO CSimpleTexture::s_count++;
|
||||
}
|
||||
|
||||
void CSimpleTexture::Draw(CRenderBatch* batch) {
|
||||
if (this->m_texture) {
|
||||
batch->QueueTexture(this);
|
||||
}
|
||||
}
|
||||
|
||||
float CSimpleTexture::GetHeight() {
|
||||
float layoutHeight = CLayoutFrame::GetHeight();
|
||||
|
||||
if (layoutHeight != 0.0f) {
|
||||
return layoutHeight;
|
||||
}
|
||||
|
||||
uint32_t textureHeight;
|
||||
|
||||
if (TextureGetDimensions(this->m_texture, nullptr, &textureHeight, 0)) {
|
||||
float ndcHeight = static_cast<float>(textureHeight) / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcHeight = NDCToDDCWidth(ndcHeight);
|
||||
return ddcHeight;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture::GetScriptMetaTable() {
|
||||
return CSimpleTexture::s_metatable;
|
||||
}
|
||||
|
||||
void CSimpleTexture::GetTexCoord(C2Vector* texCoord) {
|
||||
texCoord[0] = { this->m_texCoord[0].x, this->m_texCoord[0].y };
|
||||
texCoord[1] = { this->m_texCoord[1].x, this->m_texCoord[1].y };
|
||||
texCoord[2] = { this->m_texCoord[2].x, this->m_texCoord[2].y };
|
||||
texCoord[3] = { this->m_texCoord[3].x, this->m_texCoord[3].y };
|
||||
}
|
||||
|
||||
float CSimpleTexture::GetWidth() {
|
||||
float layoutWidth = CLayoutFrame::GetWidth();
|
||||
|
||||
if (layoutWidth != 0.0f) {
|
||||
return layoutWidth;
|
||||
}
|
||||
|
||||
uint32_t textureWidth;
|
||||
|
||||
if (TextureGetDimensions(this->m_texture, &textureWidth, nullptr, 0)) {
|
||||
float ndcWidth = static_cast<float>(textureWidth) / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
float ddcWidth = NDCToDDCWidth(ndcWidth);
|
||||
return ddcWidth;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool CSimpleTexture::IsA(int32_t type) {
|
||||
return type == CSimpleTexture::s_objectType
|
||||
|| type == CScriptRegion::s_objectType
|
||||
|| type == CScriptObject::s_objectType;
|
||||
}
|
||||
|
||||
void CSimpleTexture::LoadXML(XMLNode* node, CStatus* status) {
|
||||
const char* inheritsAttr = node->GetAttributeByName("inherits");
|
||||
|
||||
if (inheritsAttr && *inheritsAttr) {
|
||||
const char* tainted;
|
||||
bool locked;
|
||||
|
||||
XMLNode* inheritsNode = FrameXML_AcquireHashNode(inheritsAttr, tainted, locked);
|
||||
|
||||
if (inheritsNode) {
|
||||
if (locked) {
|
||||
status->Add(STATUS_WARNING, "Recursively inherited node: %s", inheritsAttr);
|
||||
} else {
|
||||
this->LoadXML(inheritsNode, status);
|
||||
FrameXML_ReleaseHashNode(inheritsAttr);
|
||||
}
|
||||
} else {
|
||||
status->Add(STATUS_WARNING, "Couldn't find inherited node: %s", inheritsAttr);
|
||||
}
|
||||
}
|
||||
|
||||
CScriptRegion::LoadXML(node, status);
|
||||
|
||||
const char* hiddenAttr = node->GetAttributeByName("hidden");
|
||||
|
||||
if (hiddenAttr && *hiddenAttr) {
|
||||
bool hide = StringToBOOL(hiddenAttr);
|
||||
|
||||
if (hide) {
|
||||
this->Hide();
|
||||
} else {
|
||||
this->Show();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t wrapU = 0;
|
||||
int32_t wrapV = 0;
|
||||
CImVector color = { 0 };
|
||||
|
||||
const char* horizTileAttr = node->GetAttributeByName("horizTile");
|
||||
if (horizTileAttr && *horizTileAttr) {
|
||||
this->m_horizTile = StringToBOOL(horizTileAttr);
|
||||
wrapU = 1;
|
||||
}
|
||||
|
||||
const char* vertTileAttr = node->GetAttributeByName("vertTile");
|
||||
if (vertTileAttr && *vertTileAttr) {
|
||||
this->m_vertTile = StringToBOOL(vertTileAttr);
|
||||
wrapV = 1;
|
||||
}
|
||||
|
||||
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
||||
if (!SStrCmpI(child->GetName(), "TexCoords", INT_MAX)) {
|
||||
int32_t valid = 1;
|
||||
|
||||
float left = 0.0f;
|
||||
float right = 1.0f;
|
||||
float top = 0.0f;
|
||||
float bottom = 1.0f;
|
||||
|
||||
const char* name = this->GetName();
|
||||
if (!name) {
|
||||
name = "<unnamed>";
|
||||
}
|
||||
|
||||
const XMLNode* rectNode = child->GetChildByName("Rect");
|
||||
|
||||
if (rectNode) {
|
||||
// TODO
|
||||
} else {
|
||||
const char* leftAttr = child->GetAttributeByName("left");
|
||||
if (leftAttr && *leftAttr) {
|
||||
if (this->m_horizTile) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (horizTile is on)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
left = SStrToFloat(leftAttr);
|
||||
|
||||
if (left < -10000.0f || left > 10000.0f) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (out of range)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* rightAttr = child->GetAttributeByName("right");
|
||||
if (rightAttr && *rightAttr) {
|
||||
if (this->m_horizTile) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (horizTile is on)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
right = SStrToFloat(rightAttr);
|
||||
|
||||
if (right < -10000.0f || right > 10000.0f) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (out of range)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* topAttr = child->GetAttributeByName("top");
|
||||
if (topAttr && *topAttr) {
|
||||
if (this->m_vertTile) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (vertTile is on)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
top = SStrToFloat(topAttr);
|
||||
|
||||
if (top < -10000.0f || top > 10000.0f) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (out of range)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* bottomAttr = child->GetAttributeByName("bottom");
|
||||
if (bottomAttr && *bottomAttr) {
|
||||
if (this->m_vertTile) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (vertTile is on)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
bottom = SStrToFloat(bottomAttr);
|
||||
|
||||
if (bottom < -10000.0f || bottom > 10000.0f) {
|
||||
status->Add(
|
||||
STATUS_ERROR,
|
||||
"Texture %s: Invalid TexCoords value (out of range)",
|
||||
name
|
||||
);
|
||||
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
C2Vector coords[4];
|
||||
|
||||
coords[0].x = left;
|
||||
coords[0].y = top;
|
||||
|
||||
coords[1].x = left;
|
||||
coords[1].y = bottom;
|
||||
|
||||
coords[2].x = right;
|
||||
coords[2].y = top;
|
||||
|
||||
coords[3].y = bottom;
|
||||
coords[3].x = right;
|
||||
|
||||
this->SetTexCoord(coords);
|
||||
|
||||
if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) {
|
||||
wrapU = 1;
|
||||
}
|
||||
|
||||
if (top < 0.0f || top > 1.0f || bottom < 0.0f || bottom > 1.0f) {
|
||||
wrapV = 1;
|
||||
}
|
||||
}
|
||||
} else if (!SStrCmpI(child->GetName(), "Color", INT_MAX)) {
|
||||
LoadXML_Color(child, color);
|
||||
this->SetTexture(color);
|
||||
} else if (!SStrCmpI(child->GetName(), "Gradient", INT_MAX)) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
const char* v91 = node->GetAttributeByName("file");
|
||||
|
||||
if (v91 && *v91) {
|
||||
if (this->SetTexture(v91, wrapU, wrapV, CSimpleTexture::s_textureFilterMode, ImageMode_UI)) {
|
||||
|
||||
if (color.value) {
|
||||
this->SetVertexColor(color);
|
||||
}
|
||||
} else {
|
||||
const char* v94 = this->GetName();
|
||||
|
||||
if (!v94) {
|
||||
v94 = "<unnamed>";
|
||||
}
|
||||
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Texture %s: Unable to load texture file %s",
|
||||
v94,
|
||||
v91
|
||||
);
|
||||
|
||||
// TODO
|
||||
// CTexture* texture = TextureCreateSolid(&CRAPPY_GREEN); // 0xFF00FF00
|
||||
|
||||
// if (this->m_texture) {
|
||||
// HandleClose(this->m_texture);
|
||||
// }
|
||||
|
||||
// this->m_texture = texture;
|
||||
|
||||
// this->OnRegionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
const char* alphaModeAttr = node->GetAttributeByName("alphaMode");
|
||||
if (alphaModeAttr && *alphaModeAttr) {
|
||||
EGxBlend alphaMode;
|
||||
|
||||
if (StringToBlendMode(alphaModeAttr, alphaMode)) {
|
||||
this->SetBlendMode(alphaMode);
|
||||
}
|
||||
}
|
||||
|
||||
const char* alphaAttr = node->GetAttributeByName("alpha");
|
||||
if (alphaAttr && *alphaAttr) {
|
||||
float alpha = SStrToFloat(alphaAttr);
|
||||
this->SetAlpha(alpha);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - nonBlocking
|
||||
}
|
||||
|
||||
void CSimpleTexture::OnFrameSizeChanged(const CRect& rect) {
|
||||
CLayoutFrame::OnFrameSizeChanged(rect);
|
||||
|
||||
if (false) {
|
||||
// TODO
|
||||
// - something about animations?
|
||||
} else {
|
||||
this->SetPosition(this->m_rect, this->m_position);
|
||||
}
|
||||
|
||||
if (this->m_horizTile || this->m_vertTile) {
|
||||
this->m_updateTexCoord = 1;
|
||||
this->OnRegionChanged();
|
||||
}
|
||||
|
||||
if (this->m_parent) {
|
||||
this->m_parent->NotifyScrollParent();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTexture::PostLoadXML(XMLNode* node, CStatus* status) {
|
||||
if (this->m_parent) {
|
||||
for (int32_t i = 0; i < FRAMEPOINT_NUMPOINTS; i++) {
|
||||
if (this->m_points[i] && !(this->m_points[i]->m_flags & 0x8)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i + 1 == FRAMEPOINT_NUMPOINTS) {
|
||||
this->SetAllPoints(this->m_parent, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTexture::SetAlpha(float alpha) {
|
||||
// Clamp
|
||||
alpha = std::max(0.0f, std::min(alpha, 1.0f));
|
||||
|
||||
CImVector color = { 0 };
|
||||
this->GetVertexColor(color);
|
||||
color.a = alpha * 255.0f;
|
||||
this->SetVertexColor(color);
|
||||
}
|
||||
|
||||
void CSimpleTexture::SetBlendMode(EGxBlend blend) {
|
||||
if (blend == this->m_alphaMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_alphaMode = blend;
|
||||
this->OnRegionChanged();
|
||||
}
|
||||
|
||||
void CSimpleTexture::SetPosition(const CRect& rect, C3Vector* position) {
|
||||
position[0] = { rect.minX, rect.maxY, this->m_layoutDepth };
|
||||
position[1] = { rect.minX, rect.minY, this->m_layoutDepth };
|
||||
position[2] = { rect.maxX, rect.maxY, this->m_layoutDepth };
|
||||
position[3] = { rect.maxX, rect.minY, this->m_layoutDepth };
|
||||
}
|
||||
|
||||
void CSimpleTexture::SetTexCoord(const CRect& texRect) {
|
||||
this->m_texCoord[0] = { texRect.minX, texRect.minY };
|
||||
this->m_texCoord[1] = { texRect.minX, texRect.maxY };
|
||||
this->m_texCoord[2] = { texRect.maxX, texRect.minY };
|
||||
this->m_texCoord[3] = { texRect.maxX, texRect.maxY };
|
||||
}
|
||||
|
||||
void CSimpleTexture::SetTexCoord(const C2Vector* texCoord) {
|
||||
this->m_texCoord[0] = { texCoord[0].x, texCoord[0].y };
|
||||
this->m_texCoord[1] = { texCoord[1].x, texCoord[1].y };
|
||||
this->m_texCoord[2] = { texCoord[2].x, texCoord[2].y };
|
||||
this->m_texCoord[3] = { texCoord[3].x, texCoord[3].y };
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture::SetTexture(const char* fileName, bool wrapU, bool wrapV, EGxTexFilter filter, TextureImageMode mode) {
|
||||
if (this->m_texture && fileName && TextureIsSame(this->m_texture, fileName)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
HTEXTURE texture = nullptr;
|
||||
|
||||
if (fileName && *fileName) {
|
||||
CStatus status;
|
||||
|
||||
CGxTexFlags texFlags = CGxTexFlags(filter, wrapU, wrapV, 0, 0, 0, 1);
|
||||
|
||||
texture = TextureCreate(fileName, texFlags, &status, 23);
|
||||
|
||||
// TODO
|
||||
// if (status.unk4 >= 2) {
|
||||
// HandleClose(texture);
|
||||
// SysMsgAdd(&status);
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
this->m_shader = CSimpleTexture::GetImageModePixelShader(mode);
|
||||
}
|
||||
|
||||
if (this->m_texture) {
|
||||
HandleClose(this->m_texture);
|
||||
}
|
||||
|
||||
this->m_texture = texture;
|
||||
|
||||
this->OnRegionChanged();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture::SetTexture(const CImVector& color) {
|
||||
HTEXTURE texture = TextureCreateSolid(color);
|
||||
|
||||
if (this->m_texture) {
|
||||
HandleClose(this->m_texture);
|
||||
}
|
||||
|
||||
this->m_texture = texture;
|
||||
|
||||
this->OnRegionChanged();
|
||||
|
||||
return 1;
|
||||
}
|
||||
64
src/ui/CSimpleTexture.hpp
Normal file
64
src/ui/CSimpleTexture.hpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#ifndef UI_C_SIMPLE_TEXTURE_HPP
|
||||
#define UI_C_SIMPLE_TEXTURE_HPP
|
||||
|
||||
#include "gx/Texture.hpp"
|
||||
#include "ui/CSimpleRegion.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CGxShader;
|
||||
class CRect;
|
||||
class CRenderBatch;
|
||||
class CSimpleFrame;
|
||||
|
||||
class CSimpleTexture : public CSimpleRegion {
|
||||
public:
|
||||
// Static variables
|
||||
static CGxShader* s_imageModePixelShaders[];
|
||||
static uint16_t s_indices[];
|
||||
static int32_t s_metatable;
|
||||
static int32_t s_objectType;
|
||||
static EGxTexFilter s_textureFilterMode;
|
||||
|
||||
// Static functions
|
||||
static void CreateScriptMetaTable(void);
|
||||
static CGxShader* GetImageModePixelShader(TextureImageMode);
|
||||
static int32_t GetObjectType(void);
|
||||
static void Init(void);
|
||||
static void RegisterScriptMethods(lua_State*);
|
||||
|
||||
// Member variables
|
||||
HTEXTURE m_texture = nullptr;
|
||||
EGxBlend m_alphaMode = GxBlend_Alpha;
|
||||
CGxShader* m_shader = s_imageModePixelShaders[0];
|
||||
C3Vector m_position[4];
|
||||
C2Vector m_texCoord[4];
|
||||
uint32_t m_nonBlocking : 1;
|
||||
uint32_t m_updateTexCoord : 1;
|
||||
uint32_t m_horizTile : 1;
|
||||
uint32_t m_vertTile : 1;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~CSimpleTexture();
|
||||
virtual int32_t GetScriptMetaTable(void);
|
||||
virtual bool IsA(int32_t);
|
||||
virtual void LoadXML(XMLNode*, CStatus*);
|
||||
virtual float GetWidth(void);
|
||||
virtual float GetHeight(void);
|
||||
virtual void Draw(CRenderBatch*);
|
||||
virtual void OnFrameSizeChanged(const CRect&);
|
||||
|
||||
// Member functions
|
||||
CSimpleTexture(CSimpleFrame*, uint32_t, int32_t);
|
||||
void GetTexCoord(C2Vector*);
|
||||
void PostLoadXML(XMLNode*, CStatus*);
|
||||
void SetAlpha(float alpha);
|
||||
void SetBlendMode(EGxBlend);
|
||||
void SetPosition(const CRect&, C3Vector*);
|
||||
void SetTexCoord(const CRect& texRect);
|
||||
void SetTexCoord(const C2Vector*);
|
||||
int32_t SetTexture(const char*, bool, bool, EGxTexFilter, TextureImageMode);
|
||||
int32_t SetTexture(const CImVector&);
|
||||
};
|
||||
|
||||
#endif
|
||||
275
src/ui/CSimpleTextureScript.cpp
Normal file
275
src/ui/CSimpleTextureScript.cpp
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
#include "ui/CSimpleTextureScript.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t CSimpleTexture_IsObjectType(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetObjectType(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetDrawLayer(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetDrawLayer(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetBlendMode(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetBlendMode(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetVertexColor(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetVertexColor(lua_State* L) {
|
||||
int32_t type = CSimpleTexture::GetObjectType();
|
||||
CSimpleTexture* texture = static_cast<CSimpleTexture*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
CImVector curColor = { 0 };
|
||||
texture->GetVertexColor(curColor);
|
||||
|
||||
CImVector newColor = { 0 };
|
||||
FrameScript_GetColor(L, 2, newColor);
|
||||
if (!lua_isnumber(L, 5)) {
|
||||
newColor.a = curColor.a;
|
||||
}
|
||||
|
||||
texture->SetVertexColor(newColor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetGradient(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetGradientAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetAlpha(lua_State* L) {
|
||||
int32_t type = CSimpleTexture::GetObjectType();
|
||||
CSimpleTexture* texture = static_cast<CSimpleTexture*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (!lua_isnumber(L, 2)) {
|
||||
luaL_error(L, "Usage: %s:SetAlpha(alpha)", texture->GetDisplayName());
|
||||
}
|
||||
|
||||
float alpha = lua_tonumber(L, 2);
|
||||
texture->SetAlpha(alpha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetAlpha(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_Show(lua_State* L) {
|
||||
int32_t type = CSimpleTexture::GetObjectType();
|
||||
CSimpleTexture* texture = static_cast<CSimpleTexture*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
texture->Show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_Hide(lua_State* L) {
|
||||
int32_t type = CSimpleTexture::GetObjectType();
|
||||
CSimpleTexture* texture = static_cast<CSimpleTexture*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
texture->Hide();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_IsVisible(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_IsShown(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetTexture(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetTexture(lua_State* L) {
|
||||
int32_t type = CSimpleTexture::GetObjectType();
|
||||
CSimpleTexture* texture = static_cast<CSimpleTexture*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
if (lua_isnumber(L, 2)) {
|
||||
// TODO
|
||||
// CArgb v9 = 0;
|
||||
// FrameScript_GetRGBA(2, L, &v9);
|
||||
// texture->SetTexture(&v9);
|
||||
|
||||
lua_pushnumber(L, 1.0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lua_isstring(L, 2)) {
|
||||
texture->SetTexture(0, 0, 0, CSimpleTexture::s_textureFilterMode, ImageMode_UI);
|
||||
|
||||
lua_pushnumber(L, 1.0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool v5 = lua_toboolean(L, 3);
|
||||
bool v6 = lua_toboolean(L, 3);
|
||||
const char* v7 = lua_tolstring(L, 2, 0);
|
||||
|
||||
if (texture->SetTexture(v7, v6, v5, CSimpleTexture::s_textureFilterMode, ImageMode_UI)) {
|
||||
lua_pushnumber(L, 1.0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetTexCoord(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetTexCoord(lua_State* L) {
|
||||
auto type = CSimpleTexture::GetObjectType();
|
||||
auto texture = static_cast<CSimpleTexture*>(FrameScript_GetObjectThis(L, type));
|
||||
|
||||
auto argCount = lua_gettop(L) - 1;
|
||||
|
||||
if (argCount == 4) {
|
||||
CRect texRect = {
|
||||
static_cast<float>(lua_tonumber(L, 4)),
|
||||
static_cast<float>(lua_tonumber(L, 2)),
|
||||
static_cast<float>(lua_tonumber(L, 5)),
|
||||
static_cast<float>(lua_tonumber(L, 3))
|
||||
};
|
||||
|
||||
if (
|
||||
texRect.minX < -10000.0f
|
||||
|| texRect.minX > 10000.0f
|
||||
|| texRect.maxX < -10000.0f
|
||||
|| texRect.maxX > 10000.0f
|
||||
|| texRect.minY < -10000.0f
|
||||
|| texRect.minY > 10000.0f
|
||||
|| texRect.maxY < -10000.0f
|
||||
|| texRect.maxY > 10000.0f
|
||||
) {
|
||||
luaL_error(L, "TexCoord out of range");
|
||||
}
|
||||
|
||||
texture->SetTexCoord(texRect);
|
||||
|
||||
} else if (argCount == 8) {
|
||||
C2Vector texCoord[4];
|
||||
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
texCoord[i] = {
|
||||
static_cast<float>(lua_tonumber(L, 2 + (i * 2 + 0))),
|
||||
static_cast<float>(lua_tonumber(L, 2 + (i * 2 + 1)))
|
||||
};
|
||||
|
||||
if (
|
||||
texCoord[i].x < -10000.0f
|
||||
|| texCoord[i].x > 10000.0f
|
||||
|| texCoord[i].y < -10000.0f
|
||||
|| texCoord[i].y > 10000.0f
|
||||
) {
|
||||
luaL_error(L, "TexCoord out of range");
|
||||
}
|
||||
}
|
||||
|
||||
texture->SetTexCoord(texCoord);
|
||||
|
||||
} else {
|
||||
luaL_error(L, "Usage: %s:SetTexCoord(minX, maxX, minY, maxY) or SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)", texture->GetDisplayName());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetRotation(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetDesaturated(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_IsDesaturated(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetNonBlocking(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetNonBlocking(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetHorizTile(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetHorizTile(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_SetVertTile(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t CSimpleTexture_GetVertTile(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
FrameScript_Method SimpleTextureMethods[NUM_SIMPLE_TEXTURE_SCRIPT_METHODS] = {
|
||||
{ "IsObjectType", &CSimpleTexture_IsObjectType },
|
||||
{ "GetObjectType", &CSimpleTexture_GetObjectType },
|
||||
{ "GetDrawLayer", &CSimpleTexture_GetDrawLayer },
|
||||
{ "SetDrawLayer", &CSimpleTexture_SetDrawLayer },
|
||||
{ "GetBlendMode", &CSimpleTexture_GetBlendMode },
|
||||
{ "SetBlendMode", &CSimpleTexture_SetBlendMode },
|
||||
{ "GetVertexColor", &CSimpleTexture_GetVertexColor },
|
||||
{ "SetVertexColor", &CSimpleTexture_SetVertexColor },
|
||||
{ "SetGradient", &CSimpleTexture_SetGradient },
|
||||
{ "SetGradientAlpha", &CSimpleTexture_SetGradientAlpha },
|
||||
{ "SetAlpha", &CSimpleTexture_SetAlpha },
|
||||
{ "GetAlpha", &CSimpleTexture_GetAlpha },
|
||||
{ "Show", &CSimpleTexture_Show },
|
||||
{ "Hide", &CSimpleTexture_Hide },
|
||||
{ "IsVisible", &CSimpleTexture_IsVisible },
|
||||
{ "IsShown", &CSimpleTexture_IsShown },
|
||||
{ "GetTexture", &CSimpleTexture_GetTexture },
|
||||
{ "SetTexture", &CSimpleTexture_SetTexture },
|
||||
{ "GetTexCoord", &CSimpleTexture_GetTexCoord },
|
||||
{ "SetTexCoord", &CSimpleTexture_SetTexCoord },
|
||||
{ "SetRotation", &CSimpleTexture_SetRotation },
|
||||
{ "SetDesaturated", &CSimpleTexture_SetDesaturated },
|
||||
{ "IsDesaturated", &CSimpleTexture_IsDesaturated },
|
||||
{ "SetNonBlocking", &CSimpleTexture_SetNonBlocking },
|
||||
{ "GetNonBlocking", &CSimpleTexture_GetNonBlocking },
|
||||
{ "SetHorizTile", &CSimpleTexture_SetHorizTile },
|
||||
{ "GetHorizTile", &CSimpleTexture_GetHorizTile },
|
||||
{ "SetVertTile", &CSimpleTexture_SetVertTile },
|
||||
{ "GetVertTile", &CSimpleTexture_GetVertTile }
|
||||
};
|
||||
10
src/ui/CSimpleTextureScript.hpp
Normal file
10
src/ui/CSimpleTextureScript.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_TEXTURE_SCRIPT_HPP
|
||||
#define UI_C_SIMPLE_TEXTURE_SCRIPT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
#define NUM_SIMPLE_TEXTURE_SCRIPT_METHODS 29
|
||||
|
||||
extern FrameScript_Method SimpleTextureMethods[NUM_SIMPLE_TEXTURE_SCRIPT_METHODS];
|
||||
|
||||
#endif
|
||||
10
src/ui/CSimpleTitleRegion.hpp
Normal file
10
src/ui/CSimpleTitleRegion.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_C_SIMPLE_TITLE_REGION_HPP
|
||||
#define UI_C_SIMPLE_TITLE_REGION_HPP
|
||||
|
||||
#include "ui/CScriptRegion.hpp"
|
||||
|
||||
class CSimpleTitleRegion : public CScriptRegion {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
||||
577
src/ui/CSimpleTop.cpp
Normal file
577
src/ui/CSimpleTop.cpp
Normal file
|
|
@ -0,0 +1,577 @@
|
|||
#include "ui/CSimpleTop.hpp"
|
||||
#include "gx/Camera.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
#include "gx/Font.hpp"
|
||||
#include "gx/Screen.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleRender.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "ui/CSimpleTitleRegion.hpp"
|
||||
#include <cstring>
|
||||
#include <tempest/Math.hpp>
|
||||
|
||||
CSimpleTop* CSimpleTop::s_instance;
|
||||
uint32_t CSimpleTop::m_eventTime;
|
||||
|
||||
void PaintScreen(void* param, const RECTF* rect, const RECTF* visible, float elapsedSec) {
|
||||
CSimpleTop::s_instance->OnLayerUpdate(elapsedSec);
|
||||
CSimpleTop::s_instance->OnLayerRender();
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnChar(const EVENT_DATA_CHAR* pCharData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
|
||||
int32_t eaten = 0;
|
||||
|
||||
CCharEvent charEvent;
|
||||
charEvent = *pCharData;
|
||||
charEvent.id = 0x40060067;
|
||||
|
||||
for (int32_t strata = FRAME_STRATA_TOOLTIP; strata >= FRAME_STRATA_WORLD; strata--) {
|
||||
if (eaten) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto priorities = &top->m_eventqueue[strata][SIMPLE_EVENT_CHAR];
|
||||
|
||||
for (int32_t i = priorities->Count() - 1; i >= 0; i--) {
|
||||
auto priority = priorities->operator[](i);
|
||||
|
||||
if (!priority || eaten) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto frame = priority->frame;
|
||||
|
||||
eaten = frame->OnLayerChar(charEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return eaten == 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnDisplaySizeChanged(const EVENT_DATA_SIZE* pSizeData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
|
||||
GxuFontWindowSizeChanged();
|
||||
|
||||
for (auto frame = top->m_frames.Head(); frame; frame = top->m_frames.Link(frame)->Next()) {
|
||||
frame->OnScreenSizeChanged();
|
||||
}
|
||||
|
||||
if (top->m_displaySizeCallback) {
|
||||
CSizeEvent sizeEvent;
|
||||
sizeEvent = *pSizeData;
|
||||
sizeEvent.id = 0x40040064;
|
||||
|
||||
top->m_displaySizeCallback(sizeEvent);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnFocusChanged(const void*, void*) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnIme(const void*, void*) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnKeyDown(const EVENT_DATA_KEY* pKeyData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
CSimpleTop::m_eventTime = pKeyData->time;
|
||||
|
||||
CKeyEvent keyEvent;
|
||||
keyEvent = *pKeyData;
|
||||
keyEvent.id = 0x40060064;
|
||||
|
||||
// TODO
|
||||
// if (top->unk1239) {
|
||||
// top->unk1239(keyEvent);
|
||||
// }
|
||||
|
||||
int32_t eaten = 0;
|
||||
|
||||
for (int32_t strata = FRAME_STRATA_TOOLTIP; strata >= FRAME_STRATA_WORLD; strata--) {
|
||||
if (eaten) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto priorities = &top->m_eventqueue[strata][SIMPLE_EVENT_KEY];
|
||||
|
||||
for (int32_t i = priorities->Count() - 1; i >= 0; i--) {
|
||||
auto priority = priorities->operator[](i);
|
||||
|
||||
if (!priority || eaten) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto frame = priority->frame;
|
||||
|
||||
eaten = frame->OnLayerKeyDown(keyEvent);
|
||||
|
||||
if (eaten) {
|
||||
top->m_keydownCapture[keyEvent.key] = frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eaten == 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnKeyDownRepeat(const void*, void*) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnKeyUp(const EVENT_DATA_KEY* pKeyData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
CSimpleTop::m_eventTime = pKeyData->time;
|
||||
|
||||
int32_t eaten = 0;
|
||||
|
||||
CSimpleFrame* frame = top->m_keydownCapture[pKeyData->key];
|
||||
|
||||
if (frame) {
|
||||
CKeyEvent keyEvent;
|
||||
keyEvent = *pKeyData;
|
||||
keyEvent.id = 0x40060066;
|
||||
|
||||
frame->OnLayerKeyUp(keyEvent);
|
||||
|
||||
eaten = 1;
|
||||
} else if (pKeyData->key == KEY_PRINTSCREEN) {
|
||||
eaten = CSimpleTop::OnKeyDown(pKeyData, param);
|
||||
}
|
||||
|
||||
top->m_keydownCapture[pKeyData->key] = nullptr;
|
||||
|
||||
return eaten == 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnMouseDown(const EVENT_DATA_MOUSE* pMouseData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
|
||||
CMouseEvent mouseEvent;
|
||||
mouseEvent = *pMouseData;
|
||||
mouseEvent.id = 0x400500C8;
|
||||
|
||||
CSimpleTop::m_eventTime = pMouseData->time;
|
||||
|
||||
// TODO
|
||||
// bool v4 = top->m_layout.enabled;
|
||||
bool enabled = false;
|
||||
|
||||
memcpy(&top->m_mousePosition, pMouseData, sizeof(top->m_mousePosition));
|
||||
|
||||
if (enabled && (EventIsKeyDown(KEY_LCONTROL) || EventIsKeyDown(KEY_LALT))) {
|
||||
int32_t v5 = EventIsKeyDown(KEY_LCONTROL);
|
||||
top->StartMoveOrResizeFrame(mouseEvent, MOVERESIZE_REASON1, v5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto mouseButtonCallback = top->m_mouseButtonCallback;
|
||||
|
||||
if (!top->m_mouseCapture && mouseButtonCallback && mouseButtonCallback(&mouseEvent)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSimpleFrame* target = top->m_mouseCapture;
|
||||
|
||||
if (!target) {
|
||||
target = top->m_mouseFocus;
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
target->Raise();
|
||||
|
||||
CSimpleTitleRegion* titleRegion = target->m_titleRegion;
|
||||
|
||||
C2Vector pt = { mouseEvent.x, mouseEvent.y };
|
||||
|
||||
if (titleRegion && titleRegion->PtInFrameRect(pt)) {
|
||||
top->StartMoveOrResizeFrame(target, MOVERESIZE_REASON2, mouseEvent.x, mouseEvent.y, 4);
|
||||
} else {
|
||||
top->m_mouseCapture = target;
|
||||
target->OnLayerMouseDown(mouseEvent, nullptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnMouseMove(const EVENT_DATA_MOUSE* pMouseData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
|
||||
CMouseEvent mouseEvent;
|
||||
mouseEvent = *pMouseData;
|
||||
mouseEvent.id = 0x400500CA;
|
||||
|
||||
int32_t v18 = pMouseData != &top->m_mousePosition;
|
||||
|
||||
if (v18) {
|
||||
if (pMouseData->x == top->m_mousePosition.x && pMouseData->y == top->m_mousePosition.y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSimpleTop::m_eventTime = pMouseData->time;
|
||||
}
|
||||
|
||||
memcpy(&top->m_mousePosition, pMouseData, sizeof(top->m_mousePosition));
|
||||
|
||||
CSimpleFrame* lastFocus = top->m_mouseFocus;
|
||||
CSimpleFrame* nextFocus = nullptr;
|
||||
|
||||
if (top->m_layout.frame) {
|
||||
CMouseEvent evt;
|
||||
evt = *pMouseData;
|
||||
|
||||
top->MoveOrResizeFrame(evt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto mousePositionCallback = top->m_mousePositionCallback;
|
||||
|
||||
if (mousePositionCallback && mousePositionCallback(&mouseEvent)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSimpleFrame* mouseCapture = top->m_mouseCapture;
|
||||
|
||||
if (mouseCapture) {
|
||||
mouseCapture->OnLayerTrackUpdate(mouseEvent);
|
||||
}
|
||||
|
||||
for (int32_t strata = FRAME_STRATA_DIALOG; strata >= FRAME_STRATA_WORLD; strata--) {
|
||||
auto priorities = &top->m_eventqueue[strata][SIMPLE_EVENT_MOUSE];
|
||||
|
||||
for (int32_t i = priorities->Count() - 1; i >= 0; i--) {
|
||||
auto frame = priorities->operator[](i)->frame;
|
||||
|
||||
if (frame->OnLayerTrackUpdate(mouseEvent)) {
|
||||
nextFocus = frame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextFocus) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextFocus != lastFocus) {
|
||||
top->m_mouseFocus = nextFocus;
|
||||
|
||||
if (lastFocus) {
|
||||
lastFocus->OnLayerCursorExit(v18, 0);
|
||||
}
|
||||
|
||||
if (nextFocus) {
|
||||
nextFocus->OnLayerCursorEnter(v18);
|
||||
}
|
||||
}
|
||||
|
||||
return nextFocus == nullptr;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnMouseMoveRelative(const EVENT_DATA_MOUSE*, void*) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnMouseUp(const EVENT_DATA_MOUSE* pMouseData, void* param) {
|
||||
CSimpleTop* top = static_cast<CSimpleTop*>(param);
|
||||
|
||||
CMouseEvent mouseEvent;
|
||||
mouseEvent = *pMouseData;
|
||||
mouseEvent.id = 0x400500C9;
|
||||
|
||||
CSimpleTop::m_eventTime = pMouseData->time;
|
||||
|
||||
if (top->m_layout.anchor == 1 || top->m_layout.anchor == 2) {
|
||||
if (top->m_layout.frame) {
|
||||
top->m_layout.frame->UnflattenFrame(top);
|
||||
}
|
||||
|
||||
top->m_layout.frame = nullptr;
|
||||
top->m_layout.anchor = FRAMEPOINT_TOPLEFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// if (v11 && !top->m_mouseCapture && v11(mouseEvent)) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
if (!top->m_mouseCapture) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
top->m_mouseCapture->OnLayerMouseUp(mouseEvent, nullptr);
|
||||
|
||||
if (!mouseEvent.buttonState) {
|
||||
top->m_mouseCapture = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::OnMouseWheel(const EVENT_DATA_MOUSE*, void*) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
float CSimpleTop::RoundToPixelHeight(float ddcHeight) {
|
||||
if (abs(ddcHeight) < 0.00000023841858) {
|
||||
return ddcHeight;
|
||||
}
|
||||
|
||||
CRect windowRect = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
g_theGxDevicePtr->CapsWindowSizeInScreenCoords(windowRect);
|
||||
float windowHeight = windowRect.maxY - windowRect.minY;
|
||||
|
||||
if (abs(windowHeight) < 0.00000023841858) {
|
||||
return ddcHeight;
|
||||
}
|
||||
|
||||
auto ndcHeight = DDCToNDCHeight(ddcHeight);
|
||||
auto pixelHeight = ndcHeight * windowHeight;
|
||||
auto roundedPixelHeight = CMath::fuint_pi(pixelHeight);
|
||||
auto roundedNdcHeight = static_cast<float>(roundedPixelHeight) / windowHeight;
|
||||
auto roundedDdcHeight = NDCToDDCHeight(roundedNdcHeight);
|
||||
|
||||
return roundedDdcHeight;
|
||||
}
|
||||
|
||||
CSimpleTop::CSimpleTop() : CLayoutFrame() {
|
||||
// TODO
|
||||
|
||||
CSimpleTop::s_instance = this;
|
||||
|
||||
ScrnLayerCreate(nullptr, 1.0, 0x4, nullptr, &PaintScreen, &this->m_screenLayer);
|
||||
|
||||
this->EnableEvents();
|
||||
|
||||
// TODO
|
||||
// memset(this->m_keydownCapture, 0, sizeof(this->m_keydownCapture));
|
||||
|
||||
NDCToDDC(1.0f, 1.0f, &this->m_rect.maxX, &this->m_rect.maxY);
|
||||
|
||||
this->m_flags |= 0x1;
|
||||
|
||||
// TODO
|
||||
|
||||
for (int32_t s = 0; s < NUM_FRAME_STRATA; s++) {
|
||||
void* m = SMemAlloc(sizeof(CFrameStrata), __FILE__, __LINE__, 0);
|
||||
this->m_strata[s] = m ? new (m) CFrameStrata() : nullptr;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
CSimpleRender::Init();
|
||||
CSimpleTexture::Init();
|
||||
}
|
||||
|
||||
void CSimpleTop::CompressStrata(int32_t strata) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleTop::EnableEvents() {
|
||||
EventRegisterEx(EVENT_ID_CHAR, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnChar), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_IME, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnIme), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_KEYDOWN, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnKeyDown), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_KEYUP, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnKeyUp), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_KEYDOWN_REPEATING, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnKeyDownRepeat), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_MOUSEMOVE, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnMouseMove), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_MOUSEMOVE_RELATIVE, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnMouseMoveRelative), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_MOUSEDOWN, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnMouseDown), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_MOUSEUP, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnMouseUp), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_MOUSEWHEEL, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnMouseWheel), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_SIZE, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnDisplaySizeChanged), this, 1.0);
|
||||
EventRegisterEx(EVENT_ID_FOCUS, reinterpret_cast<EVENTHANDLERFUNC>(CSimpleTop::OnFocusChanged), this, 1.0);
|
||||
}
|
||||
|
||||
void CSimpleTop::HideFrame(CSimpleFrame* frame, int32_t a4) {
|
||||
if (this->m_layout.frame == frame && !a4) {
|
||||
if (this->m_layout.frame) {
|
||||
this->m_layout.frame->UnflattenFrame(this);
|
||||
}
|
||||
|
||||
this->m_layout.frame = nullptr;
|
||||
this->m_layout.anchor = FRAMEPOINT_TOPLEFT;
|
||||
}
|
||||
|
||||
frame->UnregisterForEvents(a4);
|
||||
this->m_strata[frame->m_strata]->RemoveFrame(frame);
|
||||
}
|
||||
|
||||
void CSimpleTop::OnLayerUpdate(float elapsedSec) {
|
||||
// TODO
|
||||
// - walk m_destroyed and perform some cleanup
|
||||
|
||||
CLayoutFrame::ResizePending();
|
||||
|
||||
for (int32_t s = 0; s < NUM_FRAME_STRATA; s++) {
|
||||
auto strata = this->m_strata[s];
|
||||
strata->OnLayerUpdate(elapsedSec);
|
||||
}
|
||||
|
||||
CLayoutFrame::ResizePending();
|
||||
|
||||
if (this->m_checkFocus) {
|
||||
this->m_checkFocus = 0;
|
||||
CSimpleTop::OnMouseMove(&this->m_mousePosition, this);
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTop::OnLayerRender() {
|
||||
C2Vector v13 = { 0.0f, 0.0f };
|
||||
CameraSetupScreenProjection(this->m_rect, v13, 0.0f, 0);
|
||||
|
||||
for (int32_t s = 0; s < NUM_FRAME_STRATA; s++) {
|
||||
auto strata = this->m_strata[s];
|
||||
strata->BuildBatches(this->m_mouseCapture == nullptr);
|
||||
strata->RenderBatches();
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTop::MoveOrResizeFrame(const CMouseEvent& evt) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleTop::NotifyFrameLayerChanged(CSimpleFrame* frame, uint32_t layer) {
|
||||
auto strata = this->m_strata[frame->m_strata];
|
||||
auto level = strata->levels[frame->m_level];
|
||||
level->batchDirty |= 1 << layer;
|
||||
strata->batchDirty = 1;
|
||||
}
|
||||
|
||||
void CSimpleTop::NotifyFrameMovedOrResized(CSimpleFrame* frame) {
|
||||
auto strata = this->m_strata[frame->m_strata];
|
||||
strata->levelsDirty = 1;
|
||||
|
||||
if (this->m_layout.frame) {
|
||||
this->RaiseFrame(this->m_layout.frame, 0);
|
||||
}
|
||||
|
||||
this->m_checkFocus = 1;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::RaiseFrame(CSimpleFrame* frame, int32_t checkOcclusion) {
|
||||
while (frame && frame->m_flags & 0x01) {
|
||||
frame = frame->m_parent;
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (checkOcclusion) {
|
||||
if (!(static_cast<CLayoutFrame*>(frame)->m_flags & 0x01) || this->IsResizePending()) {
|
||||
frame->Resize(1);
|
||||
}
|
||||
|
||||
int32_t occluded = this->m_strata[frame->m_strata]->FrameOccluded(frame);
|
||||
frame->SetFrameFlag(0x10, occluded);
|
||||
}
|
||||
|
||||
if (frame->m_flags & 0x10) {
|
||||
this->CompressStrata(frame->m_strata);
|
||||
auto strata = this->m_strata[frame->m_strata];
|
||||
frame->SetFrameLevel(strata->topLevel, 1);
|
||||
this->m_checkFocus = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CSimpleTop::RegisterForEvent(CSimpleFrame* frame, CSimpleEventType event, int32_t a4, uint32_t priority) {
|
||||
auto& queue = this->m_eventqueue[frame->m_strata][event];
|
||||
|
||||
auto m = SMemAlloc(sizeof(FRAMEPRIORITY), __FILE__, __LINE__, 0x0);
|
||||
auto framePriority = new (m) FRAMEPRIORITY();
|
||||
|
||||
framePriority->frame = frame;
|
||||
framePriority->priority = priority == -1 ? frame->m_level : priority;
|
||||
|
||||
queue.Insert(framePriority);
|
||||
|
||||
if (!a4 || event == SIMPLE_EVENT_MOUSE) {
|
||||
this->m_checkFocus = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTop::RegisterFrame(CSimpleFrame* frame) {
|
||||
this->m_frames.LinkToTail(frame);
|
||||
}
|
||||
|
||||
void CSimpleTop::ShowFrame(CSimpleFrame* frame, int32_t a3) {
|
||||
this->m_strata[frame->m_strata]->AddFrame(frame);
|
||||
frame->RegisterForEvents(a3);
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::StartMoveOrResizeFrame(const CMouseEvent& start, MOVERESIZE_REASON reason, int32_t resize) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::StartMoveOrResizeFrame(CSimpleFrame* frame, MOVERESIZE_REASON reason, float startx, float starty, int32_t a6) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CSimpleTop::StartMoveOrResizeFrame(CSimpleFrame* frame, MOVERESIZE_REASON reason, float startx, float starty, FRAMEPOINT a6) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSimpleTop::UnregisterForEvent(CSimpleFrame* frame, CSimpleEventType event, int32_t a4) {
|
||||
auto& queue = this->m_eventqueue[frame->m_strata][event];
|
||||
|
||||
int32_t found = 0;
|
||||
|
||||
for (int32_t i = 0; i < queue.Count(); i++) {
|
||||
if (queue[i]->frame == frame) {
|
||||
queue.Remove(i);
|
||||
found = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!a4) {
|
||||
if (event == SIMPLE_EVENT_KEY) {
|
||||
for (int32_t i = 0; i < 787; i++) {
|
||||
if (frame == this->m_keydownCapture[i]) {
|
||||
this->m_keydownCapture[i] = nullptr;
|
||||
}
|
||||
}
|
||||
} else if (event == SIMPLE_EVENT_MOUSE) {
|
||||
if (frame == this->m_mouseCapture) {
|
||||
this->m_mouseCapture = nullptr;
|
||||
}
|
||||
|
||||
if (frame == this->m_mouseFocus) {
|
||||
this->m_mouseFocus = nullptr;
|
||||
this->m_checkFocus = 1;
|
||||
|
||||
if (frame->m_intAC != 3) {
|
||||
frame->OnLayerCursorExit(0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/ui/CSimpleTop.hpp
Normal file
84
src/ui/CSimpleTop.hpp
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#ifndef UI_C_SIMPLE_TOP_HPP
|
||||
#define UI_C_SIMPLE_TOP_HPP
|
||||
|
||||
#include "event/Event.hpp"
|
||||
#include "gx/Screen.hpp"
|
||||
#include "ui/CFrameStrata.hpp"
|
||||
#include "ui/CLayoutFrame.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include <common/Array.hpp>
|
||||
|
||||
enum MOVERESIZE_REASON {
|
||||
MOVERESIZE_REASON0 = 0,
|
||||
MOVERESIZE_REASON1 = 1,
|
||||
MOVERESIZE_REASON2 = 2
|
||||
};
|
||||
|
||||
class CSimpleTop : public CLayoutFrame {
|
||||
public:
|
||||
// Types
|
||||
struct frame_layout {
|
||||
int32_t enabled = 0;
|
||||
CSimpleFrame* frame = nullptr;
|
||||
FRAMEPOINT anchor = FRAMEPOINT_TOPLEFT;
|
||||
C2Vector last;
|
||||
float float14 = 0.0f;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static CSimpleTop* s_instance;
|
||||
static uint32_t m_eventTime;
|
||||
|
||||
// Static functions
|
||||
static int32_t OnChar(const EVENT_DATA_CHAR*, void*);
|
||||
static int32_t OnDisplaySizeChanged(const EVENT_DATA_SIZE*, void*);
|
||||
static int32_t OnFocusChanged(const void*, void*);
|
||||
static int32_t OnIme(const void*, void*);
|
||||
static int32_t OnKeyDown(const EVENT_DATA_KEY*, void*);
|
||||
static int32_t OnKeyDownRepeat(const void*, void*);
|
||||
static int32_t OnKeyUp(const EVENT_DATA_KEY*, void*);
|
||||
static int32_t OnMouseDown(const EVENT_DATA_MOUSE*, void*);
|
||||
static int32_t OnMouseMove(const EVENT_DATA_MOUSE*, void*);
|
||||
static int32_t OnMouseMoveRelative(const EVENT_DATA_MOUSE*, void*);
|
||||
static int32_t OnMouseUp(const EVENT_DATA_MOUSE*, void*);
|
||||
static int32_t OnMouseWheel(const EVENT_DATA_MOUSE*, void*);
|
||||
static float RoundToPixelHeight(float);
|
||||
|
||||
// Member variables
|
||||
HLAYER m_screenLayer;
|
||||
CSimpleFrame* m_mouseFocus = nullptr;
|
||||
CSimpleFrame* m_mouseCapture = nullptr;
|
||||
CSimpleFrame* m_keydownCapture[787] = {};
|
||||
STORM_EXPLICIT_LIST(CSimpleFrame, m_framesLink) m_frames;
|
||||
STORM_EXPLICIT_LIST(CSimpleFrame, m_destroyedLink) m_destroyed;
|
||||
CFrameStrata* m_strata[NUM_FRAME_STRATA];
|
||||
frame_layout m_layout;
|
||||
CSimpleSortedArray<FRAMEPRIORITY*> m_eventqueue[NUM_FRAME_STRATA][NUM_SIMPLE_EVENTS];
|
||||
int32_t m_checkFocus = 1;
|
||||
EVENT_DATA_MOUSE m_mousePosition;
|
||||
int32_t (*m_mouseButtonCallback)(CMouseEvent*) = nullptr;
|
||||
int32_t (*m_mousePositionCallback)(CMouseEvent*) = nullptr;
|
||||
int32_t (*m_displaySizeCallback)(const CSizeEvent&) = nullptr;
|
||||
|
||||
// Member functions
|
||||
CSimpleTop();
|
||||
void CompressStrata(int32_t);
|
||||
void EnableEvents(void);
|
||||
void HideFrame(CSimpleFrame*, int32_t);
|
||||
void MoveOrResizeFrame(const CMouseEvent&);
|
||||
void NotifyFrameLayerChanged(CSimpleFrame*, uint32_t);
|
||||
void NotifyFrameMovedOrResized(CSimpleFrame*);
|
||||
void OnLayerUpdate(float);
|
||||
void OnLayerRender(void);
|
||||
int32_t RaiseFrame(CSimpleFrame*, int32_t);
|
||||
void RegisterForEvent(CSimpleFrame*, CSimpleEventType, int32_t, uint32_t);
|
||||
void RegisterFrame(CSimpleFrame*);
|
||||
void ShowFrame(CSimpleFrame*, int32_t);
|
||||
int32_t StartMoveOrResizeFrame(const CMouseEvent&, MOVERESIZE_REASON, int32_t);
|
||||
int32_t StartMoveOrResizeFrame(CSimpleFrame*, MOVERESIZE_REASON, float, float, int32_t);
|
||||
int32_t StartMoveOrResizeFrame(CSimpleFrame*, MOVERESIZE_REASON, float, float, FRAMEPOINT);
|
||||
void UnregisterForEvent(CSimpleFrame*, CSimpleEventType, int32_t);
|
||||
};
|
||||
|
||||
#endif
|
||||
1566
src/ui/FrameScript.cpp
Normal file
1566
src/ui/FrameScript.cpp
Normal file
File diff suppressed because it is too large
Load diff
107
src/ui/FrameScript.hpp
Normal file
107
src/ui/FrameScript.hpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#ifndef UI_FRAME_SCRIPT_HPP
|
||||
#define UI_FRAME_SCRIPT_HPP
|
||||
|
||||
#include "ui/Types.hpp"
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <common/MD5.hpp>
|
||||
#include <storm/Array.hpp>
|
||||
#include <storm/Hash.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
#define NUM_GLUE_SCRIPT_EVENTS 41
|
||||
|
||||
class CImVector;
|
||||
class CSimpleFrame;
|
||||
class CStatus;
|
||||
class FrameScript_Object;
|
||||
struct lua_State;
|
||||
|
||||
struct SIMPLEFRAMENODE : TSLinkedNode<SIMPLEFRAMENODE> {
|
||||
CSimpleFrame *frame;
|
||||
};
|
||||
|
||||
struct EVENTLISTENERNODE : TSLinkedNode<EVENTLISTENERNODE> {
|
||||
FrameScript_Object *listener;
|
||||
};
|
||||
|
||||
class FrameScript_EventObject : public TSHashObject<FrameScript_EventObject, HASHKEY_STRI> {
|
||||
public:
|
||||
// Member variables
|
||||
TSList<EVENTLISTENERNODE, TSGetLink<EVENTLISTENERNODE>> listeners;
|
||||
TSList<EVENTLISTENERNODE, TSGetLink<EVENTLISTENERNODE>> unregisterListeners;
|
||||
TSList<EVENTLISTENERNODE, TSGetLink<EVENTLISTENERNODE>> registerListeners;
|
||||
uint32_t signalCount = 0;
|
||||
uint32_t pendingSignalCount = 0;
|
||||
// TODO performance counters
|
||||
|
||||
// Member functions
|
||||
FrameScript_EventObject() : TSHashObject<FrameScript_EventObject, HASHKEY_STRI>() {};
|
||||
const char* GetName(void);
|
||||
};
|
||||
|
||||
extern const char* g_glueScriptEvents[41];
|
||||
extern const char* g_scriptEvents[722];
|
||||
|
||||
namespace FrameScript {
|
||||
extern void* s_mempool;
|
||||
extern int32_t s_blocksizes[9];
|
||||
extern lua_State* s_context;
|
||||
extern int64_t s_scriptTimeUsed;
|
||||
extern int32_t s_scriptProfileEnabled;
|
||||
extern int32_t s_errorHandlerFun;
|
||||
extern double_t s_scriptTimeDivisor;
|
||||
extern int32_t s_errorHandlerRef;
|
||||
extern int32_t s_recursiveTableHash;
|
||||
extern char const* s_compat_lua;
|
||||
extern int32_t s_pluralRule;
|
||||
extern int32_t s_handlingError;
|
||||
extern TSFixedArray<FrameScript_EventObject*> s_scriptEvents;
|
||||
extern TSHashTable<FrameScript_EventObject, HASHKEY_STRI> s_scriptEventsHash;
|
||||
}
|
||||
|
||||
int32_t FrameScript_CompileFunction(const char*, const char*, const char*, CStatus*);
|
||||
|
||||
void FrameScript_CreateEvents(const char*[], uint32_t);
|
||||
|
||||
void FrameScript_Destroy(void);
|
||||
|
||||
void FrameScript_Execute(const char*, const char*, const char*);
|
||||
|
||||
void FrameScript_Execute(int32_t, FrameScript_Object*, int32_t, const char*, FrameScript_EventObject*);
|
||||
|
||||
int32_t FrameScript_ExecuteBuffer(const char*, size_t, const char*, CStatus*, const char*);
|
||||
|
||||
int32_t FrameScript_ExecuteFile(const char*, const char*, MD5_CTX*, CStatus*);
|
||||
|
||||
void FrameScript_Flush(void);
|
||||
|
||||
void FrameScript_GetColor(lua_State* L, int32_t idx, CImVector& color);
|
||||
|
||||
lua_State* FrameScript_GetContext(void);
|
||||
|
||||
const char* FrameScript_GetCurrentObject(lua_State*, int32_t);
|
||||
|
||||
char const* FrameScript_GetText(const char*, int32_t, FRAMESCRIPT_GENDER);
|
||||
|
||||
int32_t FrameScript_GetVariable(const char*, const char**);
|
||||
|
||||
int32_t FrameScript_HandleError(lua_State*);
|
||||
|
||||
int32_t FrameScript_Initialize(int32_t);
|
||||
|
||||
void FrameScript_RegisterFunction(const char*, int32_t (*)(lua_State*));
|
||||
|
||||
void FrameScript_RegisterScriptEvent(FrameScript_Object*, FrameScript_EventObject*);
|
||||
|
||||
void FrameScript_SetPluralRule(PLURAL_RULE);
|
||||
|
||||
void FrameScript_SignalEvent(uint32_t, const char*, ...);
|
||||
|
||||
void FrameScript_UnregisterScriptEvent(FrameScript_Object*, FrameScript_EventObject*);
|
||||
|
||||
void GlueScriptEventsInitialize(void);
|
||||
|
||||
void ScriptEventsInitialize(void);
|
||||
|
||||
#endif
|
||||
10
src/ui/FrameScriptInternal.hpp
Normal file
10
src/ui/FrameScriptInternal.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef UI_FRAME_SCRIPT_INTERNAL_HPP
|
||||
#define UI_FRAME_SCRIPT_INTERNAL_HPP
|
||||
|
||||
#include "util/Lua.hpp"
|
||||
|
||||
namespace FrameScriptInternal {
|
||||
extern luaL_Reg extra_funcs[31];
|
||||
}
|
||||
|
||||
#endif
|
||||
189
src/ui/FrameScript_Object.cpp
Normal file
189
src/ui/FrameScript_Object.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#include "ui/FrameScript_Object.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
int32_t FrameScript_Object::s_objectTypes = 0;
|
||||
|
||||
int32_t FrameScript_Object::CreateScriptMetaTable(lua_State* L, void (*a2)(lua_State* L)) {
|
||||
lua_createtable(L, 0, 0);
|
||||
lua_pushstring(L, "__index");
|
||||
lua_createtable(L, 0, 0);
|
||||
|
||||
a2(L);
|
||||
|
||||
lua_settable(L, -3);
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
void FrameScript_Object::FillScriptMethodTable(lua_State *L, FrameScript_Method methods[], int32_t count) {
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
lua_pushstring(L, methods[i].name);
|
||||
lua_pushcclosure(L, methods[i].method, 0);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
}
|
||||
|
||||
FrameScript_Object::~FrameScript_Object() {
|
||||
if (this->m_onEvent.luaRef) {
|
||||
luaL_unref(FrameScript_GetContext(), LUA_REGISTRYINDEX, this->m_onEvent.luaRef);
|
||||
}
|
||||
}
|
||||
|
||||
const char* FrameScript_Object::GetDisplayName() {
|
||||
const char* name = this->GetName();
|
||||
return name ? name : "<unnamed>";
|
||||
}
|
||||
|
||||
FrameScript_Object::ScriptIx* FrameScript_Object::GetScriptByName(const char* name, FrameScript_Object::ScriptData& data) {
|
||||
if (!SStrCmpI(name, "OnEvent", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,event,...) %s end";
|
||||
return &this->m_onEvent;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t FrameScript_Object::RegisterScriptEvent(const char* name) {
|
||||
auto event = FrameScript::s_scriptEventsHash.Ptr(name);
|
||||
|
||||
if (!event) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (event->pendingSignalCount) {
|
||||
auto node = event->unregisterListeners.Head();
|
||||
|
||||
while (node) {
|
||||
if (node->listener == this) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
if (node) {
|
||||
event->unregisterListeners.DeleteNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
auto node = event->listeners.Head();
|
||||
|
||||
while (node) {
|
||||
if (node->listener == this) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
FrameScript_RegisterScriptEvent(this, event);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FrameScript_Object::RegisterScriptObject(const char* name) {
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
if (!this->lua_registered) {
|
||||
// TODO
|
||||
// v4 = lua_taintexpected++ == -1;
|
||||
// v5 = lua_tainted;
|
||||
// if (!v4 && !lua_taintedclosure) {
|
||||
// lua_tainted = 0;
|
||||
// }
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
lua_pushnumber(L, 0.0);
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_rawset(L, -3);
|
||||
|
||||
int32_t metatable = this->GetScriptMetaTable();
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, metatable);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
this->lua_objectRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
// TODO
|
||||
// if (lua_taintexpected && !lua_taintedclosure) {
|
||||
// lua_tainted = v5;
|
||||
// }
|
||||
// if (--lua_taintexpected <= 0) {
|
||||
// lua_taintexpected = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
this->lua_registered++;
|
||||
|
||||
if (name) {
|
||||
int32_t v8 = 0;
|
||||
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, LUA_GLOBALSINDEX);
|
||||
|
||||
if (lua_type(L, -1)) {
|
||||
v8 = 1;
|
||||
}
|
||||
|
||||
lua_settop(L, -2);
|
||||
|
||||
if (!v8) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
||||
lua_pushstring(L, name);
|
||||
lua_insert(L, -2);
|
||||
lua_rawset(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FrameScript_Object::RunScript(ScriptIx const& script, int32_t argCount, const char* a4) {
|
||||
FrameScript_Execute(script.luaRef, this, argCount, a4 ? a4 : script.unk, nullptr);
|
||||
}
|
||||
|
||||
void FrameScript_Object::UnregisterScriptObject(const char* name) {
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
if (this->lua_registered > 0) {
|
||||
this->lua_registered--;
|
||||
|
||||
if (this->lua_registered == 0) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
||||
lua_pushnumber(L, 0.0);
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, -3);
|
||||
lua_settop(L, -2);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, this->lua_objectRef);
|
||||
|
||||
this->lua_objectRef = -2;
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, name);
|
||||
lua_insert(L, -2);
|
||||
lua_rawset(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
}
|
||||
|
||||
FrameScript_Object* FrameScript_GetObjectThis(lua_State* L, int32_t type) {
|
||||
if (lua_type(L, 1) != LUA_TTABLE) {
|
||||
luaL_error(L, "Attempt to find 'this' in non-table object (used '.' instead of ':' ?)");
|
||||
}
|
||||
|
||||
lua_rawgeti(L, 1, 0);
|
||||
auto object = static_cast<FrameScript_Object*>(lua_touserdata(L, -1));
|
||||
lua_settop(L, -2);
|
||||
|
||||
if (!object) {
|
||||
luaL_error(L, "Attempt to find 'this' in non-framescript object");
|
||||
}
|
||||
|
||||
if (!object->IsA(type)) {
|
||||
luaL_error(L, "Wrong object type for member function");
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
53
src/ui/FrameScript_Object.hpp
Normal file
53
src/ui/FrameScript_Object.hpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef UI_FRAME_SCRIPT_OBJECT_HPP
|
||||
#define UI_FRAME_SCRIPT_OBJECT_HPP
|
||||
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class FrameScript_Object {
|
||||
public:
|
||||
// Structs
|
||||
struct ScriptData {
|
||||
const char* wrapper;
|
||||
};
|
||||
|
||||
struct ScriptIx {
|
||||
int32_t luaRef = 0;
|
||||
const char* unk = nullptr;
|
||||
};
|
||||
|
||||
class ScriptFunction {
|
||||
public:
|
||||
int32_t luaRef = 0;
|
||||
};
|
||||
|
||||
// Static members
|
||||
static int32_t s_objectTypes;
|
||||
|
||||
// Static functions
|
||||
static int32_t CreateScriptMetaTable(lua_State* L, void(*a2)(lua_State*));
|
||||
static void FillScriptMethodTable(lua_State* L, FrameScript_Method methods[], int32_t count);
|
||||
|
||||
// Member variables
|
||||
int32_t lua_registered = 0;
|
||||
int32_t lua_objectRef = -2;
|
||||
ScriptIx m_onEvent;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~FrameScript_Object();
|
||||
virtual char* GetName() = 0;
|
||||
virtual int32_t GetScriptMetaTable() = 0;
|
||||
virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data);
|
||||
virtual bool IsA(int32_t type) = 0;
|
||||
|
||||
// Member functions
|
||||
const char* GetDisplayName();
|
||||
int32_t RegisterScriptEvent(const char* name);
|
||||
void RegisterScriptObject(const char* name);
|
||||
void RunScript(ScriptIx const& script, int32_t argCount, const char* a4);
|
||||
void UnregisterScriptObject(const char* name);
|
||||
};
|
||||
|
||||
FrameScript_Object* FrameScript_GetObjectThis(lua_State* L, int32_t type);
|
||||
|
||||
#endif
|
||||
633
src/ui/FrameXML.cpp
Normal file
633
src/ui/FrameXML.cpp
Normal file
|
|
@ -0,0 +1,633 @@
|
|||
#include "ui/FrameXML.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "ui/CSimpleButton.hpp"
|
||||
#include "ui/CSimpleCheckbox.hpp"
|
||||
#include "ui/CSimpleEditBox.hpp"
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleHTML.hpp"
|
||||
#include "ui/CSimpleModel.hpp"
|
||||
#include "ui/CSimpleScrollFrame.hpp"
|
||||
#include "ui/CSimpleSlider.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
int32_t FrameXML::s_debugLevel;
|
||||
TSHashTable<FrameFactoryNode, HASHKEY_STRI> FrameXML::s_factoryHash;
|
||||
TSHashTable<HashedNode, HASHKEY_STRI> FrameXML::s_nodeHash;
|
||||
|
||||
CSimpleFrame* Create_SimpleButton(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleButton), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleFrame::s_simpleButtonHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleButton(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleCheckButton(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleCheckbox), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleCheckbox::s_simpleCheckboxHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleCheckbox(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleEditBox(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleEditBox), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleEditBox::s_simpleEditBoxHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleEditBox(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleFrame(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleFrame), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleFrame::s_simpleFrameHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleFrame(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleMessageFrame(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleModel(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleModel), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleFrame::s_simpleModelHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleModel(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleScrollFrame(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleScrollFrame), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleScrollFrame::s_simpleScrollHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleScrollFrame(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleScrollingMessageFrame(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleSlider(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleSlider), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleSlider::s_simpleSliderHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleSlider(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleHTML(CSimpleFrame* parent) {
|
||||
void* m = SMemAlloc(sizeof(CSimpleHTML), __FILE__, __LINE__, 0);
|
||||
|
||||
// TODO
|
||||
// void* m = CDataAllocator::GetData(CSimpleHTML::s_simpleHTMLHeap, 0, __FILE__, __LINE__);
|
||||
|
||||
if (m) {
|
||||
return new (m) CSimpleHTML(parent);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleStatusBar(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleColorSelect(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleMovieFrame(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XMLNode* FrameXML_AcquireHashNode(const char* name, const char*& tainted, bool& locked) {
|
||||
HashedNode* hashedNode = FrameXML::s_nodeHash.Ptr(name);
|
||||
|
||||
if (!hashedNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
locked = hashedNode->locked;
|
||||
tainted = hashedNode->tainted;
|
||||
hashedNode->locked = true;
|
||||
|
||||
return hashedNode->node;
|
||||
}
|
||||
|
||||
int32_t FrameXML_CheckSignature(const char* tocPath, const char* a2, const unsigned char* key, unsigned char* digest) {
|
||||
// TODO
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return the appropriate parent name.
|
||||
*
|
||||
* Parent priorities:
|
||||
* 1. parent attribute on local node
|
||||
* 2. parent attribute on last inherited node with parent attribute present
|
||||
*/
|
||||
const char* FindParent(XMLNode* node) {
|
||||
const char* parentName = node->GetAttributeByName("parent");
|
||||
|
||||
if (parentName && *parentName) {
|
||||
return parentName;
|
||||
}
|
||||
|
||||
const char* inheritNames = node->GetAttributeByName("inherits");
|
||||
|
||||
if (!inheritNames || !*inheritNames) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char inheritName[1024];
|
||||
|
||||
do {
|
||||
SStrTokenize(&inheritNames, inheritName, 0x400u, " ,", 0);
|
||||
|
||||
if (!*inheritName) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto hashedNode = FrameXML::s_nodeHash.Ptr(inheritName);
|
||||
|
||||
if (hashedNode) {
|
||||
auto inheritNode = hashedNode->node;
|
||||
int32_t v10 = hashedNode->locked;
|
||||
hashedNode->locked = true;
|
||||
|
||||
if (inheritNode && !v10) {
|
||||
parentName = inheritNode->GetAttributeByName("parent");
|
||||
FrameXML::s_nodeHash.Ptr(inheritName)->locked = false;
|
||||
}
|
||||
}
|
||||
} while (*inheritName);
|
||||
|
||||
return parentName;
|
||||
}
|
||||
|
||||
CSimpleFrame* FrameXML_CreateFrame(XMLNode* node, CSimpleFrame* parent, CStatus* status) {
|
||||
if (FrameXML::s_debugLevel > 0) {
|
||||
const char* name = node->GetAttributeByName("name");
|
||||
|
||||
if (name && *name) {
|
||||
status->Add(STATUS_INFO, "-- Creating %s named %s", node->m_name.m_str, name);
|
||||
} else {
|
||||
status->Add(STATUS_INFO, "-- Creating unnamed %s", node->m_name.m_str);
|
||||
}
|
||||
}
|
||||
|
||||
auto factoryNode = FrameXML::s_factoryHash.Ptr(node->m_name.m_str);
|
||||
|
||||
if (!factoryNode) {
|
||||
status->Add(STATUS_WARNING, "Unknown frame type: %s", node->m_name.m_str);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* parentName = FindParent(node);
|
||||
|
||||
if (parentName && *parentName) {
|
||||
int32_t parentType = CSimpleFrame::GetObjectType();
|
||||
parent = static_cast<CSimpleFrame*>(CScriptObject::GetScriptObjectByName(parentName, parentType));
|
||||
|
||||
if (!parent) {
|
||||
status->Add(STATUS_WARNING, "Couldn't find frame parent: %s", parentName);
|
||||
}
|
||||
}
|
||||
|
||||
CSimpleFrame* frame = factoryNode->m_factory(parent);
|
||||
|
||||
if (frame) {
|
||||
if (factoryNode->m_unique) {
|
||||
// TODO
|
||||
// Delete the factory node
|
||||
// sub_565030(factoryNode);
|
||||
// FrameXML::s_factoryHash.InternalDelete(factoryNode);
|
||||
}
|
||||
|
||||
frame->PreLoadXML(node, status);
|
||||
frame->LoadXML(node, status);
|
||||
frame->PostLoadXML(node, status);
|
||||
|
||||
return frame;
|
||||
} else {
|
||||
status->Add(STATUS_WARNING, "Unable to create frame type: %s", node->m_name.m_str);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t FrameXML_CreateFrames(const char* tocPath, const char* a2, MD5_CTX* md5, CStatus* status) {
|
||||
if (!status) {
|
||||
status = new CStatus;
|
||||
}
|
||||
|
||||
char v15[260];
|
||||
v15[0] = 0;
|
||||
memset(v15 + 1, 0, 259);
|
||||
|
||||
const char* v5 = tocPath;
|
||||
|
||||
const char* v6 = SStrChrR(tocPath, '\\');
|
||||
|
||||
if (v6) {
|
||||
uintptr_t v7 = v6 - tocPath + 1;
|
||||
uintptr_t v8 = v7;
|
||||
|
||||
if (v7 < 259) {
|
||||
SStrCopy(v15, tocPath, v7 + 1);
|
||||
v15[v8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void* tocBuffer;
|
||||
size_t tocBytes;
|
||||
|
||||
if (!SFile::Load(nullptr, tocPath, &tocBuffer, &tocBytes, 1, 1, nullptr)) {
|
||||
status->Add(STATUS_ERROR, "Couldn't open %s", a2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MD5Update(md5, static_cast<unsigned char*>(tocBuffer), tocBytes);
|
||||
|
||||
const char* tocData = static_cast<char*>(tocBuffer);
|
||||
|
||||
// Advance past UTF-8 BOM if present
|
||||
if (*tocData == static_cast<char>(0xEF) && *(tocData + 1) == static_cast<char>(0xBB) && *(tocData + 2) == static_cast<char>(0xBF)) {
|
||||
tocData = tocData + 3;
|
||||
}
|
||||
|
||||
CStatus v21;
|
||||
char tocLine[1024];
|
||||
char tocEntryPath[260];
|
||||
|
||||
do {
|
||||
SStrTokenize(&tocData, tocLine, 1024, "\r\n", 0);
|
||||
|
||||
if (!*tocLine) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*tocLine == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
SStrCopy(tocEntryPath, v15, 260);
|
||||
SStrPack(tocEntryPath, tocLine, 260);
|
||||
|
||||
size_t v10 = SStrLen(tocEntryPath);
|
||||
|
||||
bool v11 = tocEntryPath[v10 - 1] == ' ';
|
||||
char* v12 = &tocEntryPath[v10];
|
||||
|
||||
if (v11) {
|
||||
do {
|
||||
if (v12 <= tocEntryPath) {
|
||||
break;
|
||||
}
|
||||
|
||||
--v12;
|
||||
} while (*(v12 - 1) == ' ');
|
||||
}
|
||||
|
||||
*v12 = 0;
|
||||
|
||||
FrameXML_ProcessFile(tocEntryPath, a2, md5, &v21);
|
||||
|
||||
// TODO
|
||||
// if (s_progressCallback && s_progressFiles < s_progressTotal) {
|
||||
// ++s_progressFiles;
|
||||
// v20 = s_progressTotal;
|
||||
// v13 = (double)(unsigned int)s_progressFiles / (double)(unsigned int)s_progressTotal;
|
||||
// s_progressCallback(LODWORD(v13), s_progressParam);
|
||||
// v5 = a2;
|
||||
// }
|
||||
} while (*tocLine);
|
||||
|
||||
// TODO
|
||||
// XMLTree_Cleanup();
|
||||
|
||||
SFile::Unload(tocBuffer);
|
||||
|
||||
// TODO
|
||||
// if (s_debugLevel > 0 || v25 > 0) {
|
||||
// v21.Prepend(STATUS_INFO, "** Loading table of contents %s", v5);
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// status->Add(v21);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FrameXML_FreeHashNodes() {
|
||||
FrameXML::s_nodeHash.Clear();
|
||||
}
|
||||
|
||||
XMLTree* FrameXML_LoadXML(const char* filePath, MD5_CTX* md5, CStatus* status) {
|
||||
void* xmlBuffer;
|
||||
size_t xmlBytes;
|
||||
|
||||
if (SFile::Load(nullptr, filePath, &xmlBuffer, &xmlBytes, 0, 1, nullptr)) {
|
||||
MD5Update(md5, static_cast<unsigned char*>(xmlBuffer), xmlBytes);
|
||||
|
||||
XMLTree* tree = XMLTree_Load(static_cast<char*>(xmlBuffer), xmlBytes);
|
||||
|
||||
if (!tree) {
|
||||
status->Add(STATUS_ERROR, "Couldn't parse XML in %s", filePath);
|
||||
}
|
||||
|
||||
SFile::Unload(xmlBuffer);
|
||||
|
||||
return tree;
|
||||
} else {
|
||||
status->Add(STATUS_ERROR, "Couldn't open %s", filePath);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t FrameXML_ProcessFile(const char* filePath, const char* a2, MD5_CTX* md5, CStatus* status) {
|
||||
const char* v5 = filePath;
|
||||
|
||||
char v25[260];
|
||||
char* i;
|
||||
char* j;
|
||||
|
||||
// Deal with relative file paths
|
||||
if (SStrStr(filePath, "..")) {
|
||||
SStrCopy(v25, filePath, 260);
|
||||
|
||||
for (i = (char*)SStrStr(v25, ".."); i; i = (char*)SStrStr(v25, "..")) {
|
||||
char v7 = *(i - 1);
|
||||
|
||||
if (v7 != '\\' && v7 != '/') {
|
||||
break;
|
||||
}
|
||||
|
||||
char v8 = i[2];
|
||||
|
||||
if (v8 != '\\' && v8 != '/') {
|
||||
break;
|
||||
}
|
||||
|
||||
for (j = i - 2; j >= v25; --j) {
|
||||
if (*j == '\\') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*j == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SStrCopy(j + 1, i + 3, 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
filePath = v25;
|
||||
v5 = v25;
|
||||
}
|
||||
|
||||
const char* v10 = SStrChrR(v5, '.');
|
||||
|
||||
// If file ends in .lua, execute it and return
|
||||
if (v10 && !SStrCmpI(v10, ".lua", 0x7FFFFFFFu)) {
|
||||
return FrameScript_ExecuteFile(v5, a2, md5, status);
|
||||
}
|
||||
|
||||
// Assume all other files are xml
|
||||
XMLTree* tree = FrameXML_LoadXML(v5, md5, status);
|
||||
|
||||
if (!tree) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CStatus unkStatus;
|
||||
|
||||
XMLNode* node = XMLTree_GetRoot(tree)->m_child;
|
||||
|
||||
char v26[271];
|
||||
char v27[264];
|
||||
|
||||
// TODO
|
||||
// Should come from some kind of Lua headers
|
||||
const char* lua_tainted = nullptr;
|
||||
|
||||
while (node) {
|
||||
// <Include>
|
||||
if (!SStrCmpI(node->GetName(), "Include", 0x7FFFFFFFu)) {
|
||||
const char* v14 = node->GetAttributeByName("file");
|
||||
|
||||
if (v14) {
|
||||
const char* v15 = SStrChrR(v5, 92);
|
||||
|
||||
if (v15) {
|
||||
uint32_t v13 = v15 - v5 + 1;
|
||||
|
||||
if (v13 < 260 ) {
|
||||
SStrCopy(v27, v5, 260);
|
||||
v27[v13] = 0;
|
||||
SStrPack(v27, v14, 260);
|
||||
}
|
||||
} else {
|
||||
SStrCopy(v27, v14, 260);
|
||||
}
|
||||
|
||||
FrameXML_ProcessFile(v27, a2, md5, &unkStatus);
|
||||
} else {
|
||||
unkStatus.Add(STATUS_ERROR, "Element 'Include' without file attribute");
|
||||
}
|
||||
// <Script>
|
||||
} else if (!SStrCmpI(node->GetName(), "Script", 0x7FFFFFFFu)) {
|
||||
const char* v16 = node->GetAttributeByName("file");
|
||||
|
||||
if (v16) {
|
||||
const char* v17 = SStrChrR(v5, 92);
|
||||
|
||||
if (v17) {
|
||||
uint32_t v18 = v17 - v5 + 1;
|
||||
|
||||
if (v18 < 260) {
|
||||
SStrCopy(v27, filePath, 260);
|
||||
v27[v18] = 0;
|
||||
SStrPack(v27, v16, 260);
|
||||
}
|
||||
|
||||
v5 = filePath;
|
||||
} else {
|
||||
SStrCopy(v27, v16, 260);
|
||||
}
|
||||
|
||||
FrameScript_ExecuteFile(v27, a2, md5, &unkStatus);
|
||||
}
|
||||
|
||||
char* v19 = node->m_body;
|
||||
|
||||
if (v19 && *v19) {
|
||||
SStrPrintf(v26, 271, "%s:<Scripts>", v5);
|
||||
FrameScript_Execute(v19, v26, lua_tainted);
|
||||
}
|
||||
// <Font>
|
||||
} else if (!SStrCmpI(node->GetName(), "Font", 0x7FFFFFFFu)) {
|
||||
const char* fontName = node->GetAttributeByName("name");
|
||||
|
||||
if (fontName && *fontName) {
|
||||
CSimpleFont* font = CSimpleFont::GetFont(fontName, 1);
|
||||
font->LoadXML(node, status);
|
||||
} else {
|
||||
unkStatus.Add(STATUS_WARNING, "Unnamed font node at top level");
|
||||
}
|
||||
// Everything else (frame nodes)
|
||||
} else {
|
||||
const char* v22 = node->GetAttributeByName("virtual");
|
||||
|
||||
if (!v22 || SStrCmpI(v22, "true", 0x7FFFFFFFu)) {
|
||||
FrameXML_CreateFrame(node, nullptr, &unkStatus);
|
||||
// TODO
|
||||
// CLayoutFrame::ResizePending();
|
||||
} else {
|
||||
const char* v23 = node->GetAttributeByName("name");
|
||||
|
||||
if (v23 && *v23) {
|
||||
FrameXML_StoreHashNode(node, v23, lua_tainted, &unkStatus);
|
||||
} else {
|
||||
unkStatus.Add(STATUS_WARNING, "Unnamed virtual node at top level");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node = node->m_next;
|
||||
}
|
||||
|
||||
XMLTree_Free(tree);
|
||||
|
||||
// TODO
|
||||
// if (s_debugLevel > 0 || v34 > 0) {
|
||||
// unkStatus.Prepend(STATUS_INFO, "++ Loading file %s", v5);
|
||||
// }
|
||||
|
||||
// TODO
|
||||
// status->Unk8(unkStatus);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t FrameXML_RegisterFactory(const char* type, CSimpleFrame* (*factory)(CSimpleFrame*), bool a3) {
|
||||
if (FrameXML::s_factoryHash.Ptr(type)) {
|
||||
// Already registered
|
||||
return 0;
|
||||
}
|
||||
|
||||
FrameFactoryNode* node = FrameXML::s_factoryHash.New(type, 0, 0);
|
||||
|
||||
node->m_factory = factory;
|
||||
node->m_unique = a3;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void FrameXML_RegisterDefault() {
|
||||
FrameXML_RegisterFactory("Button", &Create_SimpleButton, 0);
|
||||
FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, 0);
|
||||
FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, 0);
|
||||
FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, 0);
|
||||
FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, 0);
|
||||
FrameXML_RegisterFactory("Model", &Create_SimpleModel, 0);
|
||||
FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, 0);
|
||||
FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, 0);
|
||||
FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, 0);
|
||||
FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, 0);
|
||||
FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, 0);
|
||||
FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, 0);
|
||||
FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, 0);
|
||||
}
|
||||
|
||||
void FrameXML_ReleaseHashNode(const char* name) {
|
||||
HashedNode* hashedNode = FrameXML::s_nodeHash.Ptr(name);
|
||||
hashedNode->locked = false;
|
||||
}
|
||||
|
||||
void FrameXML_StoreHashNode(XMLNode* node, const char* name, const char* a3, CStatus* status) {
|
||||
HashedNode* hashed = FrameXML::s_nodeHash.Ptr(name);
|
||||
|
||||
if (hashed) {
|
||||
if (!hashed->tainted || a3) {
|
||||
status->Add(STATUS_WARNING, "Virtual object named %s already exists", name);
|
||||
return;
|
||||
}
|
||||
|
||||
XMLNode *v6 = hashed->node;
|
||||
|
||||
if (v6) {
|
||||
delete v6;
|
||||
|
||||
// TODO
|
||||
// CDataAllocator::PutData((int)XMLNode::s_XMLNodeHeap, v6, 0, 0);
|
||||
}
|
||||
} else {
|
||||
HashedNode* hashed = FrameXML::s_nodeHash.New(name, 0, 0);
|
||||
|
||||
hashed->node = node;
|
||||
hashed->tainted = a3;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// sub_814650(a1);
|
||||
|
||||
if (FrameXML::s_debugLevel > 0) {
|
||||
status->Add(STATUS_INFO, "-- Added virtual frame %s", name);
|
||||
}
|
||||
}
|
||||
55
src/ui/FrameXML.hpp
Normal file
55
src/ui/FrameXML.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef UI_FRAME_XML_HPP
|
||||
#define UI_FRAME_XML_HPP
|
||||
|
||||
#include <common/MD5.hpp>
|
||||
#include <storm/Hash.hpp>
|
||||
|
||||
class CSimpleFrame;
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
class XMLTree;
|
||||
|
||||
class FrameFactoryNode : public TSHashObject<FrameFactoryNode, HASHKEY_STRI> {
|
||||
public:
|
||||
CSimpleFrame* (*m_factory)(CSimpleFrame*);
|
||||
uint32_t m_unique;
|
||||
|
||||
FrameFactoryNode() : TSHashObject<FrameFactoryNode, HASHKEY_STRI>() {};
|
||||
};
|
||||
|
||||
class HashedNode : public TSHashObject<HashedNode, HASHKEY_STRI> {
|
||||
public:
|
||||
XMLNode* node;
|
||||
const char* tainted;
|
||||
uint32_t locked;
|
||||
};
|
||||
|
||||
namespace FrameXML {
|
||||
extern int32_t s_debugLevel;
|
||||
extern TSHashTable<FrameFactoryNode, HASHKEY_STRI> s_factoryHash;
|
||||
extern TSHashTable<HashedNode, HASHKEY_STRI> s_nodeHash;
|
||||
}
|
||||
|
||||
XMLNode* FrameXML_AcquireHashNode(const char*, const char*&, bool&);
|
||||
|
||||
int32_t FrameXML_CheckSignature(const char*, const char*, const unsigned char*, unsigned char*);
|
||||
|
||||
CSimpleFrame* FrameXML_CreateFrame(XMLNode*, CSimpleFrame*, CStatus*);
|
||||
|
||||
int32_t FrameXML_CreateFrames(const char*, const char*, MD5_CTX*, CStatus*);
|
||||
|
||||
void FrameXML_FreeHashNodes(void);
|
||||
|
||||
XMLTree* FrameXML_LoadXML(const char*, MD5_CTX*, CStatus*);
|
||||
|
||||
int32_t FrameXML_ProcessFile(const char*, const char*, MD5_CTX*, CStatus*);
|
||||
|
||||
void FrameXML_RegisterDefault(void);
|
||||
|
||||
int32_t FrameXML_RegisterFactory(const char*, CSimpleFrame* (*)(CSimpleFrame*), bool);
|
||||
|
||||
void FrameXML_ReleaseHashNode(const char*);
|
||||
|
||||
void FrameXML_StoreHashNode(XMLNode*, const char*, const char*, CStatus*);
|
||||
|
||||
#endif
|
||||
5
src/ui/Interface.cpp
Normal file
5
src/ui/Interface.cpp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "ui/Interface.hpp"
|
||||
|
||||
void DeleteInterfaceFiles(void) {
|
||||
// TODO
|
||||
}
|
||||
6
src/ui/Interface.hpp
Normal file
6
src/ui/Interface.hpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef UI_INTERFACE_HPP
|
||||
#define UI_INTERFACE_HPP
|
||||
|
||||
void DeleteInterfaceFiles(void);
|
||||
|
||||
#endif
|
||||
334
src/ui/LoadXML.cpp
Normal file
334
src/ui/LoadXML.cpp
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
#include "ui/LoadXML.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include <common/XML.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
int32_t LoadXML_Color(XMLNode* node, CImVector& color) {
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = 0.0f;
|
||||
float a = 1.0f;
|
||||
|
||||
auto rAttr = node->GetAttributeByName("r");
|
||||
if (rAttr && *rAttr) {
|
||||
if (SStrToFloat(rAttr) <= 0.0f) {
|
||||
r = 0.0f;
|
||||
} else if (SStrToFloat(rAttr) >= 1.0f) {
|
||||
r = 1.0f;
|
||||
} else {
|
||||
r = SStrToFloat(rAttr);
|
||||
}
|
||||
}
|
||||
|
||||
auto gAttr = node->GetAttributeByName("g");
|
||||
if (gAttr && *gAttr) {
|
||||
if (SStrToFloat(gAttr) <= 0.0f) {
|
||||
g = 0.0f;
|
||||
} else if (SStrToFloat(gAttr) >= 1.0f) {
|
||||
g = 1.0f;
|
||||
} else {
|
||||
g = SStrToFloat(gAttr);
|
||||
}
|
||||
}
|
||||
|
||||
auto bAttr = node->GetAttributeByName("b");
|
||||
if (bAttr && *bAttr) {
|
||||
if (SStrToFloat(bAttr) <= 0.0f) {
|
||||
b = 0.0f;
|
||||
} else if (SStrToFloat(bAttr) >= 1.0f) {
|
||||
b = 1.0f;
|
||||
} else {
|
||||
b = SStrToFloat(bAttr);
|
||||
}
|
||||
}
|
||||
|
||||
auto aAttr = node->GetAttributeByName("a");
|
||||
if (aAttr && *aAttr) {
|
||||
if (SStrToFloat(aAttr) <= 0.0f) {
|
||||
a = 0.0f;
|
||||
} else if (SStrToFloat(aAttr) >= 1.0f) {
|
||||
a = 1.0f;
|
||||
} else {
|
||||
a = SStrToFloat(aAttr);
|
||||
}
|
||||
}
|
||||
|
||||
color.Set(a, r, g, b);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t LoadXML_Dimensions(XMLNode* node, float& x, float& y, CStatus* status) {
|
||||
const char* xAttr = node->GetAttributeByName("x");
|
||||
|
||||
if (xAttr && *xAttr) {
|
||||
float v18 = SStrToFloat(xAttr);
|
||||
float v6 = v18 / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
x = NDCToDDCWidth(v6);
|
||||
}
|
||||
|
||||
const char* yAttr = node->GetAttributeByName("y");
|
||||
|
||||
if (yAttr && *yAttr) {
|
||||
float v19 = SStrToFloat(yAttr);
|
||||
float v9 = v19 / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
y = NDCToDDCWidth(v9);
|
||||
}
|
||||
|
||||
XMLNode* childNode = node->m_child;
|
||||
|
||||
if (!childNode) {
|
||||
return yAttr != nullptr;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(childNode->GetName(), "RelDimension", 0x7FFFFFFF)) {
|
||||
const char* xAttrRel = childNode->GetAttributeByName("x");
|
||||
|
||||
if (xAttrRel && *xAttrRel) {
|
||||
x = SStrToFloat(xAttrRel);
|
||||
}
|
||||
|
||||
const char* yAttrRel = childNode->GetAttributeByName("y");
|
||||
|
||||
if (yAttrRel && *yAttrRel) {
|
||||
y = SStrToFloat(yAttrRel);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (!SStrCmpI(childNode->GetName(), "AbsDimension", 0x7FFFFFFF)) {
|
||||
const char* xAttrAbs = childNode->GetAttributeByName("x");
|
||||
|
||||
if (xAttrAbs && *xAttrAbs) {
|
||||
float v20 = SStrToFloat(xAttrAbs);
|
||||
float v13 = v20 / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
x = NDCToDDCWidth(v13);
|
||||
}
|
||||
|
||||
const char* yAttrAbs = childNode->GetAttributeByName("y");
|
||||
|
||||
if (yAttrAbs && *yAttrAbs) {
|
||||
float v21 = SStrToFloat(yAttrAbs);
|
||||
float v15 = v21 / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
y = NDCToDDCWidth(v15);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Unknown child node in %s element: %s",
|
||||
node->GetName(),
|
||||
childNode->GetName()
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t LoadXML_Insets(XMLNode* node, float& left, float& right, float& top, float& bottom, CStatus* status) {
|
||||
left = 0.0f;
|
||||
right = 0.0f;
|
||||
top = 0.0f;
|
||||
bottom = 0.0f;
|
||||
|
||||
const char* leftAttr = node->GetAttributeByName("left");
|
||||
if (leftAttr && *leftAttr) {
|
||||
float l = SStrToFloat(leftAttr);
|
||||
float ndcl = l / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
left = NDCToDDCWidth(ndcl);
|
||||
}
|
||||
|
||||
const char* rightAttr = node->GetAttributeByName("right");
|
||||
if (rightAttr && *rightAttr) {
|
||||
float r = SStrToFloat(rightAttr);
|
||||
float ndcr = r / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
right = NDCToDDCWidth(ndcr);
|
||||
}
|
||||
|
||||
const char* topAttr = node->GetAttributeByName("top");
|
||||
if (topAttr && *topAttr) {
|
||||
float t = SStrToFloat(topAttr);
|
||||
float ndct = t / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
top = NDCToDDCWidth(ndct);
|
||||
}
|
||||
|
||||
const char* bottomAttr = node->GetAttributeByName("bottom");
|
||||
if (bottomAttr && *bottomAttr) {
|
||||
float b = SStrToFloat(bottomAttr);
|
||||
float ndcb = b / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
bottom = NDCToDDCWidth(ndcb);
|
||||
}
|
||||
|
||||
auto child = node->m_child;
|
||||
|
||||
if (!child) {
|
||||
if (!bottomAttr) {
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"No \"right\", \"left\", \"top\", or \"bottom\" attributes in element: %s",
|
||||
node->GetName()
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(child->GetName(), "AbsInset", STORM_MAX_STR)) {
|
||||
const char* leftAttr = child->GetAttributeByName("left");
|
||||
if (leftAttr && *leftAttr) {
|
||||
float l = SStrToFloat(leftAttr);
|
||||
float ndcl = l / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
left = NDCToDDCWidth(ndcl);
|
||||
}
|
||||
|
||||
const char* rightAttr = child->GetAttributeByName("right");
|
||||
if (rightAttr && *rightAttr) {
|
||||
float r = SStrToFloat(rightAttr);
|
||||
float ndcr = r / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
right = NDCToDDCWidth(ndcr);
|
||||
}
|
||||
|
||||
const char* topAttr = child->GetAttributeByName("top");
|
||||
if (topAttr && *topAttr) {
|
||||
float t = SStrToFloat(topAttr);
|
||||
float ndct = t / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
top = NDCToDDCWidth(ndct);
|
||||
}
|
||||
|
||||
const char* bottomAttr = child->GetAttributeByName("bottom");
|
||||
if (bottomAttr && *bottomAttr) {
|
||||
float b = SStrToFloat(bottomAttr);
|
||||
float ndcb = b / (CoordinateGetAspectCompensation() * 1024.0f);
|
||||
bottom = NDCToDDCWidth(ndcb);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!SStrCmpI(child->GetName(), "RelInset", STORM_MAX_STR)) {
|
||||
const char* leftAttr = child->GetAttributeByName("left");
|
||||
if (leftAttr && *leftAttr) {
|
||||
left = SStrToFloat(leftAttr);
|
||||
}
|
||||
|
||||
const char* rightAttr = child->GetAttributeByName("right");
|
||||
if (rightAttr && *rightAttr) {
|
||||
right = SStrToFloat(rightAttr);
|
||||
}
|
||||
|
||||
const char* topAttr = child->GetAttributeByName("top");
|
||||
if (topAttr && *topAttr) {
|
||||
top = SStrToFloat(topAttr);
|
||||
}
|
||||
|
||||
const char* bottomAttr = child->GetAttributeByName("bottom");
|
||||
if (bottomAttr && *bottomAttr) {
|
||||
bottom = SStrToFloat(bottomAttr);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
status->Add(
|
||||
STATUS_WARNING,
|
||||
"Unknown child node in %s element: %s",
|
||||
child->GetName()
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSimpleFontString* LoadXML_String(XMLNode* node, CSimpleFrame* frame, CStatus* status) {
|
||||
// TODO
|
||||
// v3 = CDataAllocator::GetData(CSimpleFontString::s_allocator, 0, a__avcsimplefon, -2);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleFontString), __FILE__, __LINE__, 0);
|
||||
|
||||
CSimpleFontString* fontString;
|
||||
|
||||
if (m) {
|
||||
fontString = new (m) CSimpleFontString(frame, 2, 1);
|
||||
} else {
|
||||
fontString = NULL;
|
||||
}
|
||||
|
||||
fontString->PreLoadXML(node, status);
|
||||
fontString->LoadXML(node, status);
|
||||
fontString->PostLoadXML(node, status);
|
||||
|
||||
return fontString;
|
||||
}
|
||||
|
||||
CSimpleTexture* LoadXML_Texture(XMLNode* node, CSimpleFrame* frame, CStatus* status) {
|
||||
// TODO
|
||||
// v3 = (CSimpleTexture *)CDataAllocator::GetData((int)CSimpleTexture::s_allocator, 0, a__avcsimpletex, -2);
|
||||
|
||||
void* m = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0);
|
||||
|
||||
CSimpleTexture* texture;
|
||||
|
||||
if (m) {
|
||||
texture = new (m) CSimpleTexture(frame, 2, 1);
|
||||
} else {
|
||||
texture = NULL;
|
||||
}
|
||||
|
||||
texture->PreLoadXML(node, status);
|
||||
texture->LoadXML(node, status);
|
||||
texture->PostLoadXML(node, status);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
int32_t LoadXML_Value(XMLNode* node, float& value, CStatus* status) {
|
||||
value = 0.0;
|
||||
|
||||
const char* v4 = node->GetAttributeByName("val");
|
||||
|
||||
if (v4 && *v4) {
|
||||
float v = SStrToFloat(v4);
|
||||
float ndc = v / (CoordinateGetAspectCompensation() * 1024.0);
|
||||
value = NDCToDDCWidth(ndc);
|
||||
}
|
||||
|
||||
XMLNode* child = node->m_child;
|
||||
|
||||
if (!child) {
|
||||
if (v4) {
|
||||
return 1;
|
||||
} else {
|
||||
status->Add(STATUS_WARNING, "No \"val\" attribute in element: %s", node->GetName());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SStrCmpI(child->GetName(), "AbsValue", 0x7FFFFFFF)) {
|
||||
const char* v9 = child->GetAttributeByName("val");
|
||||
|
||||
if (v9 && *v9) {
|
||||
float v = SStrToFloat(v9);
|
||||
float ndc = v / (CoordinateGetAspectCompensation() * 1024.0);
|
||||
value = NDCToDDCWidth(ndc);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (!SStrCmpI(child->GetName(), "RelValue", 0x7FFFFFFF)) {
|
||||
const char* v11 = child->GetAttributeByName("val");
|
||||
|
||||
if (v11 && *v11) {
|
||||
value = SStrToFloat(v11);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
status->Add(STATUS_WARNING, "Unknown child node in %s element: %s", child->GetName(), node->GetName());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
25
src/ui/LoadXML.hpp
Normal file
25
src/ui/LoadXML.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef UI_LOAD_XML_HPP
|
||||
#define UI_LOAD_XML_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CSimpleFontString;
|
||||
class CSimpleFrame;
|
||||
class CSimpleTexture;
|
||||
class CStatus;
|
||||
class XMLNode;
|
||||
class CImVector;
|
||||
|
||||
int32_t LoadXML_Color(XMLNode*, CImVector&);
|
||||
|
||||
int32_t LoadXML_Dimensions(XMLNode*, float&, float&, CStatus*);
|
||||
|
||||
int32_t LoadXML_Insets(XMLNode*, float&, float&, float&, float&, CStatus*);
|
||||
|
||||
CSimpleFontString* LoadXML_String(XMLNode*, CSimpleFrame*, CStatus*);
|
||||
|
||||
CSimpleTexture* LoadXML_Texture(XMLNode*, CSimpleFrame*, CStatus*);
|
||||
|
||||
int32_t LoadXML_Value(XMLNode*, float&, CStatus*);
|
||||
|
||||
#endif
|
||||
171
src/ui/LuaExtraFuncs.cpp
Normal file
171
src/ui/LuaExtraFuncs.cpp
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#include "ui/LuaExtraFuncs.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/FrameScriptInternal.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
luaL_Reg FrameScriptInternal::extra_funcs[31] = {
|
||||
{ "setglobal", &sub_8168D0 },
|
||||
{ "getglobal", &sub_816910 },
|
||||
{ "strtrim", &strtrim },
|
||||
{ "strsplit", &strsplit },
|
||||
{ "strjoin", &strjoin },
|
||||
{ "strreplace", &sub_816C40 },
|
||||
{ "strconcat", &sub_816D80 },
|
||||
{ "strlenutf8", &strlenutf8 },
|
||||
{ "issecure", &issecure },
|
||||
{ "issecurevariable", &issecurevariable },
|
||||
{ "forceinsecure", &forceinsecure },
|
||||
{ "securecall", &securecall },
|
||||
{ "hooksecurefunc", &hooksecurefunc },
|
||||
{ "debugload", &debugload },
|
||||
{ "debuginfo", &debuginfo },
|
||||
{ "debugprint", &debugprint },
|
||||
{ "debugdump", &debugdump },
|
||||
{ "debugbreak", &debugbreak },
|
||||
{ "debughook", &debughook },
|
||||
{ "debugtimestamp", &debugtimestamp },
|
||||
{ "debugprofilestart", &debugprofilestart },
|
||||
{ "debugprofilestop", &debugprofilestop },
|
||||
{ "seterrorhandler", &seterrorhandler },
|
||||
{ "geterrorhandler", &geterrorhandler },
|
||||
{ "date", &os_date },
|
||||
{ "time", &os_time },
|
||||
{ "difftime", &os_difftime },
|
||||
{ "debugstack", &debugstack },
|
||||
{ "debuglocals", &debuglocals },
|
||||
{ "scrub", &scrub },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int32_t sub_8168D0(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t sub_816910(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t strtrim(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t strsplit(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t strjoin(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t sub_816C40(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t sub_816D80(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t strlenutf8(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t issecure(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t issecurevariable(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t forceinsecure(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t securecall(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t hooksecurefunc(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugload(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debuginfo(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugprint(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugdump(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugbreak(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debughook(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugtimestamp(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugprofilestart(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugprofilestop(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t seterrorhandler(lua_State* L) {
|
||||
if (lua_type(L, 1) != LUA_TFUNCTION) {
|
||||
luaL_error(L, "Usage: seterrorhandler(errfunc)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FrameScript::s_errorHandlerFun != -1) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, FrameScript::s_errorHandlerFun);
|
||||
}
|
||||
|
||||
FrameScript::s_errorHandlerFun = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t geterrorhandler(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t os_date(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t os_time(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t os_difftime(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debugstack(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t debuglocals(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
int32_t scrub(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
39
src/ui/LuaExtraFuncs.hpp
Normal file
39
src/ui/LuaExtraFuncs.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef UI_LUA_EXTRA_FUNCS_HPP
|
||||
#define UI_LUA_EXTRA_FUNCS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct lua_State;
|
||||
|
||||
int32_t sub_8168D0(lua_State*);
|
||||
int32_t sub_816910(lua_State*);
|
||||
int32_t strtrim(lua_State*);
|
||||
int32_t strsplit(lua_State*);
|
||||
int32_t strjoin(lua_State*);
|
||||
int32_t sub_816C40(lua_State*);
|
||||
int32_t sub_816D80(lua_State*);
|
||||
int32_t strlenutf8(lua_State*);
|
||||
int32_t issecure(lua_State*);
|
||||
int32_t issecurevariable(lua_State*);
|
||||
int32_t forceinsecure(lua_State*);
|
||||
int32_t securecall(lua_State*);
|
||||
int32_t hooksecurefunc(lua_State*);
|
||||
int32_t debugload(lua_State*);
|
||||
int32_t debuginfo(lua_State*);
|
||||
int32_t debugprint(lua_State*);
|
||||
int32_t debugdump(lua_State*);
|
||||
int32_t debugbreak(lua_State*);
|
||||
int32_t debughook(lua_State*);
|
||||
int32_t debugtimestamp(lua_State*);
|
||||
int32_t debugprofilestart(lua_State*);
|
||||
int32_t debugprofilestop(lua_State*);
|
||||
int32_t seterrorhandler(lua_State*);
|
||||
int32_t geterrorhandler(lua_State*);
|
||||
int32_t os_date(lua_State*);
|
||||
int32_t os_time(lua_State*);
|
||||
int32_t os_difftime(lua_State*);
|
||||
int32_t debugstack(lua_State*);
|
||||
int32_t debuglocals(lua_State*);
|
||||
int32_t scrub(lua_State*);
|
||||
|
||||
#endif
|
||||
138
src/ui/LuaMemory.cpp
Normal file
138
src/ui/LuaMemory.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#include "ui/LuaMemory.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
#include <common/MemPool.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
|
||||
void* luaM_initPool() {
|
||||
void* v0 = SMemAlloc(sizeof(MemPool*) * 9, ".\\src\\lmemPool.cpp", 243, 0);
|
||||
MemPool** pools = (MemPool**)v0;
|
||||
|
||||
uint32_t v2 = 0;
|
||||
|
||||
void* v3;
|
||||
MemPool* v4;
|
||||
size_t v5;
|
||||
size_t v6;
|
||||
|
||||
do {
|
||||
v3 = SMemAlloc(sizeof(MemPool), ".\\src\\lmemPool.cpp", 245, 0);
|
||||
|
||||
if (v3) {
|
||||
v4 = new (v3) MemPool();
|
||||
} else {
|
||||
v4 = 0;
|
||||
}
|
||||
|
||||
pools[v2] = v4;
|
||||
|
||||
v5 = FrameScript::s_blocksizes[v2];
|
||||
v6 = FrameScript::s_blocksizes[v2] << 10;
|
||||
|
||||
v4->Init(v5, v6);
|
||||
|
||||
++v2;
|
||||
} while (v2 < 9);
|
||||
|
||||
return pools;
|
||||
}
|
||||
|
||||
void* luaM_reallocPool(void* ud, void *ptr, size_t osize, size_t nsize) {
|
||||
void* result; // eax
|
||||
signed int v5; // esi
|
||||
signed int v6; // edx
|
||||
signed int v7; // ecx
|
||||
signed int v8; // ecx
|
||||
void *v9; // eax
|
||||
void *v10; // edi
|
||||
size_t v11; // eax
|
||||
signed int v12; // [esp+Ch] [ebp-4h]
|
||||
|
||||
MemPool** mempool = (MemPool**)ud;
|
||||
|
||||
result = ptr;
|
||||
|
||||
v5 = -1;
|
||||
v6 = -1;
|
||||
v12 = -1;
|
||||
|
||||
if (ptr) {
|
||||
v7 = 0;
|
||||
|
||||
while (osize > FrameScript::s_blocksizes[v7]) {
|
||||
if (++v7 >= 9) {
|
||||
goto LABEL_7;
|
||||
}
|
||||
}
|
||||
|
||||
v12 = v7;
|
||||
v5 = v7;
|
||||
}
|
||||
|
||||
LABEL_7:
|
||||
if (nsize) {
|
||||
v8 = 0;
|
||||
|
||||
while (nsize > FrameScript::s_blocksizes[v8]) {
|
||||
if (++v8 >= 9) {
|
||||
goto LABEL_18;
|
||||
}
|
||||
}
|
||||
|
||||
v6 = v8;
|
||||
|
||||
LABEL_18:
|
||||
if (v5 == v6) {
|
||||
if (v5 < 0) {
|
||||
result = SMemReAlloc(ptr, nsize, ".\\src\\lmemPool.cpp", 311, 0);
|
||||
}
|
||||
} else {
|
||||
if (v6 < 0) {
|
||||
v9 = SMemAlloc(nsize, ".\\src\\lmemPool.cpp", 326, 0);
|
||||
} else {
|
||||
// Pretty sure: MemPool::MemAlloc
|
||||
// v9 = sub_855820(*((_DWORD *)a1 + v6));
|
||||
v9 = mempool[v6]->MemAlloc();
|
||||
}
|
||||
|
||||
v10 = v9;
|
||||
|
||||
if (ptr) {
|
||||
v11 = osize;
|
||||
|
||||
if (osize >= nsize) {
|
||||
v11 = nsize;
|
||||
}
|
||||
|
||||
memcpy(v10, ptr, v11);
|
||||
|
||||
if (v12 >= 0) {
|
||||
// Pretty sure: MemPool::MemFree
|
||||
// sub_855670(*((_DWORD *)a1 + v12), ptr);
|
||||
mempool[v12]->MemFree(ptr);
|
||||
return v10;
|
||||
}
|
||||
|
||||
SMemFree(ptr, ".\\src\\lmemPool.cpp", 338, 0);
|
||||
}
|
||||
|
||||
result = v10;
|
||||
}
|
||||
} else {
|
||||
if (ptr) {
|
||||
if (v5 >= 0) {
|
||||
// Pretty sure: MemPool::MemFree
|
||||
// sub_855670(*((_DWORD *)a1 + v5), ptr);
|
||||
mempool[v5]->MemFree(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SMemFree(ptr, ".\\src\\lmemPool.cpp", 276, 0);
|
||||
}
|
||||
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
9
src/ui/LuaMemory.hpp
Normal file
9
src/ui/LuaMemory.hpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef UI_LUA_MEMORY_HPP
|
||||
#define UI_LUA_MEMORY_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
void* luaM_initPool(void);
|
||||
void* luaM_reallocPool(void*, void*, size_t, size_t);
|
||||
|
||||
#endif
|
||||
92
src/ui/ScriptFunctions.cpp
Normal file
92
src/ui/ScriptFunctions.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#include "ui/ScriptFunctions.hpp"
|
||||
#include "ui/CSimpleButton.hpp"
|
||||
#include "ui/CSimpleCheckbox.hpp"
|
||||
#include "ui/CSimpleEditBox.hpp"
|
||||
#include "ui/CSimpleFont.hpp"
|
||||
#include "ui/CSimpleFontString.hpp"
|
||||
#include "ui/CSimpleFrame.hpp"
|
||||
#include "ui/CSimpleHTML.hpp"
|
||||
#include "ui/CSimpleModel.hpp"
|
||||
#include "ui/CSimpleModelFFX.hpp"
|
||||
#include "ui/CSimpleScrollFrame.hpp"
|
||||
#include "ui/CSimpleSlider.hpp"
|
||||
#include "ui/CSimpleTexture.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
|
||||
void CharacterCreateRegisterScriptFunctions() {
|
||||
for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_CHAR_CREATE; ++i) {
|
||||
FrameScript_RegisterFunction(
|
||||
FrameScript::s_ScriptFunctions_CharCreate[i].name,
|
||||
FrameScript::s_ScriptFunctions_CharCreate[i].method
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void CharSelectRegisterScriptFunctions() {
|
||||
for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_CHAR_SELECT; ++i) {
|
||||
FrameScript_RegisterFunction(
|
||||
FrameScript::s_ScriptFunctions_CharSelect[i].name,
|
||||
FrameScript::s_ScriptFunctions_CharSelect[i].method
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GlueScriptEventsRegisterFunctions() {
|
||||
for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_GLUE_SCRIPT_EVENTS; ++i) {
|
||||
FrameScript_RegisterFunction(
|
||||
FrameScript::s_ScriptFunctions_GlueScriptEvents[i].name,
|
||||
FrameScript::s_ScriptFunctions_GlueScriptEvents[i].method
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterSimpleFrameScriptMethods() {
|
||||
for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME; ++i) {
|
||||
FrameScript_RegisterFunction(
|
||||
FrameScript::s_ScriptFunctions_SimpleFrame[i].name,
|
||||
FrameScript::s_ScriptFunctions_SimpleFrame[i].method
|
||||
);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// CSimpleAnim::CreateScriptMetaTable();
|
||||
// CSimpleTranslationAnim::CreateScriptMetaTable();
|
||||
// CSimpleRotationAnim::CreateScriptMetaTable();
|
||||
// CSimpleScaleAnim::CreateScriptMetaTable();
|
||||
// CSimpleControlPoint::CreateScriptMetaTable();
|
||||
// CSimplePathAnim::CreateScriptMetaTable();
|
||||
// CSimpleAlphaAnim::CreateScriptMetaTable();
|
||||
// CSimpleAnimGroup::CreateScriptMetaTable();
|
||||
|
||||
CSimpleFont::CreateScriptMetaTable();
|
||||
CSimpleTexture::CreateScriptMetaTable();
|
||||
CSimpleFontString::CreateScriptMetaTable();
|
||||
CSimpleFrame::CreateScriptMetaTable();
|
||||
CSimpleButton::CreateScriptMetaTable();
|
||||
CSimpleCheckbox::CreateScriptMetaTable();
|
||||
CSimpleEditBox::CreateScriptMetaTable();
|
||||
CSimpleHTML::CreateScriptMetaTable();
|
||||
|
||||
// TODO
|
||||
// CSimpleMessageFrame::CreateScriptMetaTable();
|
||||
// CSimpleMessageScrollFrame::CreateScriptMetaTable();
|
||||
|
||||
CSimpleModel::CreateScriptMetaTable();
|
||||
CSimpleModelFFX::CreateScriptMetaTable();
|
||||
CSimpleScrollFrame::CreateScriptMetaTable();
|
||||
CSimpleSlider::CreateScriptMetaTable();
|
||||
|
||||
// TODO
|
||||
// CSimpleStatusBar::CreateScriptMetaTable();
|
||||
// CSimpleColorSelect::CreateScriptMetaTable();
|
||||
// CSimpleMovieFrame::CreateScriptMetaTable();
|
||||
}
|
||||
|
||||
void SystemRegisterFunctions() {
|
||||
for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_SYSTEM; ++i) {
|
||||
FrameScript_RegisterFunction(
|
||||
FrameScript::s_ScriptFunctions_System[i].name,
|
||||
FrameScript::s_ScriptFunctions_System[i].method
|
||||
);
|
||||
}
|
||||
}
|
||||
211
src/ui/ScriptFunctions.hpp
Normal file
211
src/ui/ScriptFunctions.hpp
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#ifndef UI_SCRIPT_FUNCTIONS_HPP
|
||||
#define UI_SCRIPT_FUNCTIONS_HPP
|
||||
|
||||
#include "ui/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct lua_State;
|
||||
|
||||
#define NUM_SCRIPT_FUNCTIONS_CHAR_CREATE 32
|
||||
#define NUM_SCRIPT_FUNCTIONS_CHAR_SELECT 13
|
||||
#define NUM_SCRIPT_FUNCTIONS_GLUE_SCRIPT_EVENTS 113
|
||||
#define NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME 7
|
||||
#define NUM_SCRIPT_FUNCTIONS_SYSTEM 7
|
||||
|
||||
namespace FrameScript {
|
||||
extern FrameScript_Method s_ScriptFunctions_CharCreate[NUM_SCRIPT_FUNCTIONS_CHAR_CREATE];
|
||||
extern FrameScript_Method s_ScriptFunctions_CharSelect[NUM_SCRIPT_FUNCTIONS_CHAR_SELECT];
|
||||
extern FrameScript_Method s_ScriptFunctions_GlueScriptEvents[NUM_SCRIPT_FUNCTIONS_GLUE_SCRIPT_EVENTS];
|
||||
extern FrameScript_Method s_ScriptFunctions_SimpleFrame[NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME];
|
||||
extern FrameScript_Method s_ScriptFunctions_System[NUM_SCRIPT_FUNCTIONS_SYSTEM];
|
||||
}
|
||||
|
||||
// Utility
|
||||
|
||||
void CharacterCreateRegisterScriptFunctions(void);
|
||||
void CharSelectRegisterScriptFunctions(void);
|
||||
void GlueScriptEventsRegisterFunctions(void);
|
||||
void RegisterSimpleFrameScriptMethods(void);
|
||||
void SystemRegisterFunctions(void);
|
||||
|
||||
// Shared
|
||||
int32_t Script_GetAccountExpansionLevel(lua_State*);
|
||||
|
||||
// CharCreate
|
||||
int32_t Script_SetCharCustomizeFrame(lua_State*);
|
||||
int32_t Script_SetCharCustomizeBackground(lua_State*);
|
||||
int32_t Script_ResetCharCustomize(lua_State*);
|
||||
int32_t Script_GetNameForRace(lua_State*);
|
||||
int32_t Script_GetFactionForRace(lua_State*);
|
||||
int32_t Script_GetAvailableRaces(lua_State*);
|
||||
int32_t Script_GetAvailableClasses(lua_State*);
|
||||
int32_t Script_GetClassesForRace(lua_State*);
|
||||
int32_t Script_GetHairCustomization(lua_State*);
|
||||
int32_t Script_GetFacialHairCustomization(lua_State*);
|
||||
int32_t Script_GetSelectedRace(lua_State*);
|
||||
int32_t Script_GetSelectedSex(lua_State*);
|
||||
int32_t Script_GetSelectedClass(lua_State*);
|
||||
int32_t Script_SetSelectedRace(lua_State*);
|
||||
int32_t Script_SetSelectedSex(lua_State*);
|
||||
int32_t Script_SetSelectedClass(lua_State*);
|
||||
int32_t Script_UpdateCustomizationBackground(lua_State*);
|
||||
int32_t Script_UpdateCustomizationScene(lua_State*);
|
||||
int32_t Script_CycleCharCustomization(lua_State*);
|
||||
int32_t Script_RandomizeCharCustomization(lua_State*);
|
||||
int32_t Script_GetCharacterCreateFacing(lua_State*);
|
||||
int32_t Script_SetCharacterCreateFacing(lua_State*);
|
||||
int32_t Script_GetRandomName(lua_State*);
|
||||
int32_t Script_CreateCharacter(lua_State*);
|
||||
int32_t Script_CustomizeExistingCharacter(lua_State*);
|
||||
int32_t Script_PaidChange_GetPreviousRaceIndex(lua_State*);
|
||||
int32_t Script_PaidChange_GetCurrentRaceIndex(lua_State*);
|
||||
int32_t Script_PaidChange_GetCurrentClassIndex(lua_State*);
|
||||
int32_t Script_PaidChange_GetName(lua_State*);
|
||||
int32_t Script_IsRaceClassValid(lua_State*);
|
||||
int32_t Script_IsRaceClassRestricted(lua_State*);
|
||||
int32_t Script_GetCreateBackgroundModel(lua_State*);
|
||||
|
||||
// CharSelect
|
||||
int32_t Script_SetCharSelectModelFrame(lua_State*);
|
||||
int32_t Script_SetCharSelectBackground(lua_State*);
|
||||
int32_t Script_GetCharacterListUpdate(lua_State*);
|
||||
int32_t Script_GetNumCharacters(lua_State*);
|
||||
int32_t Script_GetCharacterInfo(lua_State*);
|
||||
int32_t Script_SelectCharacter(lua_State*);
|
||||
int32_t Script_DeleteCharacter(lua_State*);
|
||||
int32_t Script_RenameCharacter(lua_State*);
|
||||
int32_t Script_DeclineCharacter(lua_State*);
|
||||
int32_t Script_UpdateSelectionCustomizationScene(lua_State*);
|
||||
int32_t Script_GetCharacterSelectFacing(lua_State*);
|
||||
int32_t Script_SetCharacterSelectFacing(lua_State*);
|
||||
int32_t Script_GetSelectBackgroundModel(lua_State*);
|
||||
|
||||
// GlueScriptEvents
|
||||
int32_t Script_IsShiftKeyDown(lua_State*);
|
||||
int32_t Script_GetBuildInfo(lua_State*);
|
||||
int32_t Script_GetLocale(lua_State*);
|
||||
int32_t Script_GetSavedAccountName(lua_State*);
|
||||
int32_t Script_SetSavedAccountName(lua_State*);
|
||||
int32_t Script_GetUsesToken(lua_State*);
|
||||
int32_t Script_SetUsesToken(lua_State*);
|
||||
int32_t Script_GetSavedAccountList(lua_State*);
|
||||
int32_t Script_SetSavedAccountList(lua_State*);
|
||||
int32_t Script_SetCurrentScreen(lua_State*);
|
||||
int32_t Script_QuitGame(lua_State*);
|
||||
int32_t Script_QuitGameAndRunLauncher(lua_State*);
|
||||
int32_t Script_PlayGlueMusic(lua_State*);
|
||||
int32_t Script_PlayCreditsMusic(lua_State*);
|
||||
int32_t Script_StopGlueMusic(lua_State*);
|
||||
int32_t Script_GetMovieResolution(lua_State*);
|
||||
int32_t Script_GetScreenWidth(lua_State*);
|
||||
int32_t Script_GetScreenHeight(lua_State*);
|
||||
int32_t Script_LaunchURL(lua_State*);
|
||||
int32_t Script_ShowTOSNotice(lua_State*);
|
||||
int32_t Script_TOSAccepted(lua_State*);
|
||||
int32_t Script_AcceptTOS(lua_State*);
|
||||
int32_t Script_ShowEULANotice(lua_State*);
|
||||
int32_t Script_EULAAccepted(lua_State*);
|
||||
int32_t Script_AcceptEULA(lua_State*);
|
||||
int32_t Script_ShowTerminationWithoutNoticeNotice(lua_State*);
|
||||
int32_t Script_TerminationWithoutNoticeAccepted(lua_State*);
|
||||
int32_t Script_AcceptTerminationWithoutNotice(lua_State*);
|
||||
int32_t Script_ShowScanningNotice(lua_State*);
|
||||
int32_t Script_ScanningAccepted(lua_State*);
|
||||
int32_t Script_AcceptScanning(lua_State*);
|
||||
int32_t Script_ShowContestNotice(lua_State*);
|
||||
int32_t Script_ContestAccepted(lua_State*);
|
||||
int32_t Script_AcceptContest(lua_State*);
|
||||
int32_t Script_DefaultServerLogin(lua_State*);
|
||||
int32_t Script_StatusDialogClick(lua_State*);
|
||||
int32_t Script_GetServerName(lua_State*);
|
||||
int32_t Script_DisconnectFromServer(lua_State*);
|
||||
int32_t Script_IsConnectedToServer(lua_State*);
|
||||
int32_t Script_EnterWorld(lua_State*);
|
||||
int32_t Script_Screenshot(lua_State*);
|
||||
int32_t Script_PatchDownloadProgress(lua_State*);
|
||||
int32_t Script_PatchDownloadCancel(lua_State*);
|
||||
int32_t Script_PatchDownloadApply(lua_State*);
|
||||
int32_t Script_GetNumAddOns(lua_State*);
|
||||
int32_t Script_GetAddOnInfo(lua_State*);
|
||||
int32_t Script_LaunchAddOnURL(lua_State*);
|
||||
int32_t Script_GetAddOnDependencies(lua_State*);
|
||||
int32_t Script_GetAddOnEnableState(lua_State*);
|
||||
int32_t Script_EnableAddOn(lua_State*);
|
||||
int32_t Script_EnableAllAddOns(lua_State*);
|
||||
int32_t Script_DisableAddOn(lua_State*);
|
||||
int32_t Script_DisableAllAddOns(lua_State*);
|
||||
int32_t Script_SaveAddOns(lua_State*);
|
||||
int32_t Script_ResetAddOns(lua_State*);
|
||||
int32_t Script_IsAddonVersionCheckEnabled(lua_State*);
|
||||
int32_t Script_SetAddonVersionCheck(lua_State*);
|
||||
int32_t Script_GetCursorPosition(lua_State*);
|
||||
int32_t Script_ShowCursor(lua_State*);
|
||||
int32_t Script_HideCursor(lua_State*);
|
||||
int32_t Script_GetBillingTimeRemaining(lua_State*);
|
||||
int32_t Script_GetBillingPlan(lua_State*);
|
||||
int32_t Script_GetBillingTimeRested(lua_State*);
|
||||
int32_t Script_SurveyNotificationDone(lua_State*);
|
||||
int32_t Script_PINEntered(lua_State*);
|
||||
int32_t Script_PlayGlueAmbience(lua_State*);
|
||||
int32_t Script_StopGlueAmbience(lua_State*);
|
||||
int32_t Script_GetCreditsText(lua_State*);
|
||||
int32_t Script_GetClientExpansionLevel(lua_State*);
|
||||
int32_t Script_MatrixEntered(lua_State*);
|
||||
int32_t Script_MatrixRevert(lua_State*);
|
||||
int32_t Script_MatrixCommit(lua_State*);
|
||||
int32_t Script_GetMatrixCoordinates(lua_State*);
|
||||
int32_t Script_ScanDLLStart(lua_State*);
|
||||
int32_t Script_ScanDLLContinueAnyway(lua_State*);
|
||||
int32_t Script_IsScanDLLFinished(lua_State*);
|
||||
int32_t Script_IsWindowsClient(lua_State*);
|
||||
int32_t Script_IsOtherPlatformClient(lua_State*);
|
||||
int32_t Script_SetRealmSplitState(lua_State*);
|
||||
int32_t Script_RequestRealmSplitInfo(lua_State*);
|
||||
int32_t Script_CancelLogin(lua_State*);
|
||||
int32_t Script_GetCVar(lua_State*);
|
||||
int32_t Script_GetCVarBool(lua_State*);
|
||||
int32_t Script_SetCVar(lua_State*);
|
||||
int32_t Script_GetCVarDefault(lua_State*);
|
||||
int32_t Script_GetCVarMin(lua_State*);
|
||||
int32_t Script_GetCVarMax(lua_State*);
|
||||
int32_t Script_GetCVarAbsoluteMin(lua_State*);
|
||||
int32_t Script_GetCVarAbsoluteMax(lua_State*);
|
||||
int32_t Script_GetChangedOptionWarnings(lua_State*);
|
||||
int32_t Script_AcceptChangedOptionWarnings(lua_State*);
|
||||
int32_t Script_ShowChangedOptionWarnings(lua_State*);
|
||||
int32_t Script_TokenEntered(lua_State*);
|
||||
int32_t Script_GetNumDeclensionSets(lua_State*);
|
||||
int32_t Script_DeclineName(lua_State*);
|
||||
int32_t Script_GetNumGameAccounts(lua_State*);
|
||||
int32_t Script_GetGameAccountInfo(lua_State*);
|
||||
int32_t Script_SetGameAccount(lua_State*);
|
||||
int32_t Script_StopAllSFX(lua_State*);
|
||||
int32_t Script_SetClearConfigData(lua_State*);
|
||||
int32_t Script_RestartGx(lua_State*);
|
||||
int32_t Script_RestoreVideoResolutionDefaults(lua_State*);
|
||||
int32_t Script_RestoreVideoEffectsDefaults(lua_State*);
|
||||
int32_t Script_RestoreVideoStereoDefaults(lua_State*);
|
||||
int32_t Script_IsStreamingMode(lua_State*);
|
||||
int32_t Script_IsStreamingTrial(lua_State*);
|
||||
int32_t Script_IsConsoleActive(lua_State*);
|
||||
int32_t Script_RunScript(lua_State*);
|
||||
int32_t Script_ReadyForAccountDataTimes(lua_State*);
|
||||
int32_t Script_IsTrialAccount(lua_State*);
|
||||
int32_t Script_IsSystemSupported(lua_State*);
|
||||
|
||||
// SimpleFrame
|
||||
int32_t Script_GetText(lua_State*);
|
||||
int32_t Script_GetNumFrames(lua_State*);
|
||||
int32_t Script_EnumerateFrames(lua_State*);
|
||||
int32_t Script_CreateFont(lua_State*);
|
||||
int32_t Script_CreateFrame(lua_State*);
|
||||
int32_t Script_GetFramesRegisteredForEvent(lua_State*);
|
||||
int32_t Script_GetCurrentKeyBoardFocus(lua_State*);
|
||||
|
||||
// System
|
||||
int32_t Script_GetTime(lua_State*);
|
||||
int32_t Script_GetGameTime(lua_State*);
|
||||
int32_t Script_ConsoleExec(lua_State*);
|
||||
int32_t Script_AccessDenied(lua_State*);
|
||||
|
||||
#endif
|
||||
231
src/ui/ScriptFunctionsCharCreate.cpp
Normal file
231
src/ui/ScriptFunctionsCharCreate.cpp
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
#include "ui/ScriptFunctions.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t Script_SetCharCustomizeFrame(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_SetCharCustomizeBackground(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_ResetCharCustomize(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetNameForRace(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetFactionForRace(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetAvailableRaces(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetAvailableClasses(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetClassesForRace(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetHairCustomization(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetFacialHairCustomization(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetSelectedRace(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetSelectedSex(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetSelectedClass(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_SetSelectedRace(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_SetSelectedSex(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_SetSelectedClass(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_UpdateCustomizationBackground(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_UpdateCustomizationScene(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_CycleCharCustomization(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_RandomizeCharCustomization(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetCharacterCreateFacing(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_SetCharacterCreateFacing(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetRandomName(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_CreateCharacter(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_CustomizeExistingCharacter(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_PaidChange_GetPreviousRaceIndex(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_PaidChange_GetCurrentRaceIndex(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_PaidChange_GetCurrentClassIndex(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_PaidChange_GetName(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_IsRaceClassValid(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_IsRaceClassRestricted(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetCreateBackgroundModel(lua_State* L) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FrameScript_Method FrameScript::s_ScriptFunctions_CharCreate[NUM_SCRIPT_FUNCTIONS_CHAR_CREATE] = {
|
||||
{ "SetCharCustomizeFrame", &Script_SetCharCustomizeFrame },
|
||||
{ "SetCharCustomizeBackground", &Script_SetCharCustomizeBackground },
|
||||
{ "ResetCharCustomize", &Script_ResetCharCustomize },
|
||||
{ "GetNameForRace", &Script_GetNameForRace },
|
||||
{ "GetFactionForRace", &Script_GetFactionForRace },
|
||||
{ "GetAvailableRaces", &Script_GetAvailableRaces },
|
||||
{ "GetAvailableClasses", &Script_GetAvailableClasses },
|
||||
{ "GetClassesForRace", &Script_GetClassesForRace },
|
||||
{ "GetHairCustomization", &Script_GetHairCustomization },
|
||||
{ "GetFacialHairCustomization", &Script_GetFacialHairCustomization },
|
||||
{ "GetSelectedRace", &Script_GetSelectedRace },
|
||||
{ "GetSelectedSex", &Script_GetSelectedSex },
|
||||
{ "GetSelectedClass", &Script_GetSelectedClass },
|
||||
{ "SetSelectedRace", &Script_SetSelectedRace },
|
||||
{ "SetSelectedSex", &Script_SetSelectedSex },
|
||||
{ "SetSelectedClass", &Script_SetSelectedClass },
|
||||
{ "UpdateCustomizationBackground", &Script_UpdateCustomizationBackground },
|
||||
{ "UpdateCustomizationScene", &Script_UpdateCustomizationScene },
|
||||
{ "CycleCharCustomization", &Script_CycleCharCustomization },
|
||||
{ "RandomizeCharCustomization", &Script_RandomizeCharCustomization },
|
||||
{ "GetCharacterCreateFacing", &Script_GetCharacterCreateFacing },
|
||||
{ "SetCharacterCreateFacing", &Script_SetCharacterCreateFacing },
|
||||
{ "GetRandomName", &Script_GetRandomName },
|
||||
{ "CreateCharacter", &Script_CreateCharacter },
|
||||
{ "CustomizeExistingCharacter", &Script_CustomizeExistingCharacter },
|
||||
{ "PaidChange_GetPreviousRaceIndex", &Script_PaidChange_GetPreviousRaceIndex },
|
||||
{ "PaidChange_GetCurrentRaceIndex", &Script_PaidChange_GetCurrentRaceIndex },
|
||||
{ "PaidChange_GetCurrentClassIndex", &Script_PaidChange_GetCurrentClassIndex },
|
||||
{ "PaidChange_GetName", &Script_PaidChange_GetName },
|
||||
{ "IsRaceClassValid", &Script_IsRaceClassValid },
|
||||
{ "IsRaceClassRestricted", &Script_IsRaceClassRestricted },
|
||||
{ "GetCreateBackgroundModel", &Script_GetCreateBackgroundModel }
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue