mirror of
https://github.com/zeldaret/ss
synced 2026-05-23 23:05:20 -04:00
lyt_textBox matching
This commit is contained in:
@@ -19,6 +19,7 @@ force_active: [
|
||||
"RegistFont__Q34nw4r3lyt24MultiArcResourceAccessorFPQ34nw4r3lyt11FontRefLink",
|
||||
"GetFont__Q34nw4r3lyt24MultiArcResourceAccessorFPCc",
|
||||
"GetPaneRect__Q34nw4r3lyt4PaneCFRCQ34nw4r3lyt8DrawInfo",
|
||||
"SetFont__Q34nw4r3lyt7TextBoxFPCQ34nw4r2ut4Font",
|
||||
|
||||
]
|
||||
# modules:
|
||||
|
||||
@@ -345,6 +345,14 @@ nw4r/lyt/lyt_picture.cpp:
|
||||
.sbss start:0x80576700 end:0x80576704
|
||||
.sdata2 start:0x8057F248 end:0x8057F250
|
||||
|
||||
nw4r/lyt/lyt_textBox.cpp:
|
||||
.text start:0x80489800 end:0x8048B16C
|
||||
.ctors start:0x804DB97C end:0x804DB980
|
||||
.data start:0x8056E570 end:0x8056E5F4
|
||||
.sdata start:0x80574EB8 end:0x80574EBC
|
||||
.sbss start:0x80576708 end:0x8057670C
|
||||
.sdata2 start:0x8057F250 end:0x8057F268
|
||||
|
||||
nw4r/lyt/lyt_resourceAccessor.cpp:
|
||||
.text start:0x80492000 end:0x80492058
|
||||
.data start:0x8056E7E0 end:0x8056E7F8
|
||||
|
||||
+11
-11
@@ -3860,7 +3860,7 @@ fn_800B0F40 = .text:0x800B0F40; // type:function size:0x240
|
||||
fn_800B1180 = .text:0x800B1180; // type:function size:0x3F0
|
||||
fn_800B1570 = .text:0x800B1570; // type:function size:0x14
|
||||
fn_800B1590 = .text:0x800B1590; // type:function size:0x14
|
||||
fn_800B15B0 = .text:0x800B15B0; // type:function size:0x8
|
||||
GetRuntimeTypeInfo__Q34nw4r3lyt7TextBoxCFv = .text:0x800B15B0; // type:function size:0x8 scope:weak
|
||||
fn_800B15C0 = .text:0x800B15C0; // type:function size:0x68
|
||||
fn_800B1630 = .text:0x800B1630; // type:function size:0x3C
|
||||
fn_800B1670 = .text:0x800B1670; // type:function size:0x134
|
||||
@@ -25941,10 +25941,10 @@ SetFont__Q34nw4r3lyt7TextBoxFPCQ34nw4r2ut4Font = .text:0x8048A9E0; // type:funct
|
||||
LoadMtx__Q34nw4r3lyt7TextBoxFRCQ34nw4r3lyt8DrawInfo = .text:0x8048AB10; // type:function size:0x84
|
||||
GetTextDrawRect__Q34nw4r3lyt7TextBoxCFPQ34nw4r2ut17TextWriterBase<w> = .text:0x8048ABA0; // type:function size:0x2A4
|
||||
CalcStringRectImpl<w>__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FPQ34nw4r2ut4RectPQ34nw4r2ut17TextWriterBase<w>PCwif_v = .text:0x8048AE50; // type:function size:0x1D4
|
||||
FUN_8048b030 = .text:0x8048B030; // type:function size:0x4C
|
||||
FUN_8048b080 = .text:0x8048B080; // type:function size:0x44
|
||||
FUN_8048b0d0 = .text:0x8048B0D0; // type:function size:0x84
|
||||
__sinit_lyt_textBox_cpp = .text:0x8048B160; // type:function size:0xC
|
||||
GetTextMagH__Q34nw4r3lyt7TextBoxCFv = .text:0x8048B030; // type:function size:0x4C
|
||||
GetTextMagV__Q34nw4r3lyt7TextBoxCFv = .text:0x8048B080; // type:function size:0x44
|
||||
GetTextAlignMag__Q34nw4r3lyt7TextBoxCFv = .text:0x8048B0D0; // type:function size:0x84
|
||||
__sinit_\lyt_textBox_cpp = .text:0x8048B160; // type:function size:0xC scope:local
|
||||
__ct__Q34nw4r3lyt6WindowFPCQ44nw4r3lyt3res6WindowRCQ34nw4r3lyt11ResBlockSet = .text:0x8048B170; // type:function size:0x284
|
||||
__dt__Q34nw4r3lyt6WindowFv = .text:0x8048B400; // type:function size:0x144
|
||||
FindMaterialByName__Q34nw4r3lyt6WindowFPCcb = .text:0x8048B550; // type:function size:0xFC
|
||||
@@ -37076,7 +37076,7 @@ __vt__Q34nw4r3lyt4Pane = .data:0x8056E430; // type:object size:0x74
|
||||
__vt__Q34nw4r3lyt5Group = .data:0x8056E4A8; // type:object size:0xC
|
||||
__vt__Q34nw4r3lyt6Layout = .data:0x8056E4B8; // type:object size:0x40
|
||||
__vt__Q34nw4r3lyt7Picture = .data:0x8056E4F8; // type:object size:0x78
|
||||
lbl_8056E570 = .data:0x8056E570; // type:object size:0x88
|
||||
__vt__Q34nw4r3lyt7TextBox = .data:0x8056E570; // type:object size:0x84
|
||||
lbl_8056E5F8 = .data:0x8056E5F8; // type:object size:0x3C
|
||||
lbl_8056E634 = .data:0x8056E634; // type:object size:0x8C
|
||||
lbl_8056E6C0 = .data:0x8056E6C0; // type:object size:0x78
|
||||
@@ -39585,7 +39585,7 @@ lbl_80574E98 = .sdata:0x80574E98; // type:object size:0x8
|
||||
lbl_80574EA0 = .sdata:0x80574EA0; // type:object size:0x8 data:4byte
|
||||
lbl_80574EA8 = .sdata:0x80574EA8; // type:object size:0x8 data:4byte
|
||||
NW4R_LYT_Version___22@unnamed@lyt_init_cpp@ = .sdata:0x80574EB0; // type:object size:0x4 scope:local data:4byte
|
||||
lbl_80574EB8 = .sdata:0x80574EB8; // type:object size:0x8
|
||||
lbl_80574EB8 = .sdata:0x80574EB8; // type:object size:0x4 data:string
|
||||
lbl_80574EC0 = .sdata:0x80574EC0; // type:object size:0x2 data:string
|
||||
lbl_80574EC4 = .sdata:0x80574EC4; // type:object size:0x3 data:string
|
||||
lbl_80574EC8 = .sdata:0x80574EC8; // type:object size:0x8
|
||||
@@ -47567,10 +47567,10 @@ lbl_8057F238 = .sdata2:0x8057F238; // type:object size:0x8 data:double
|
||||
lbl_8057F240 = .sdata2:0x8057F240; // type:object size:0x4 data:float
|
||||
lbl_8057F244 = .sdata2:0x8057F244; // type:object size:0x4 data:float
|
||||
lbl_8057F248 = .sdata2:0x8057F248; // type:object size:0x4 data:float
|
||||
lbl_8057F250 = .sdata2:0x8057F250; // type:object size:0x4 data:float
|
||||
lbl_8057F258 = .sdata2:0x8057F258; // type:object size:0x8 data:double
|
||||
lbl_8057F260 = .sdata2:0x8057F260; // type:object size:0x4 data:float
|
||||
lbl_8057F264 = .sdata2:0x8057F264; // type:object size:0x4 data:float
|
||||
lbl_8057F250 = .sdata2:0x8057F250; // type:object size:0x4 scope:local data:float
|
||||
lbl_8057F258 = .sdata2:0x8057F258; // type:object size:0x8 scope:local data:double
|
||||
lbl_8057F260 = .sdata2:0x8057F260; // type:object size:0x4 scope:local data:float
|
||||
lbl_8057F264 = .sdata2:0x8057F264; // type:object size:0x4 scope:local data:float
|
||||
lbl_8057F268 = .sdata2:0x8057F268; // type:object size:0x4 data:float
|
||||
lbl_8057F270 = .sdata2:0x8057F270; // type:object size:0x8 data:double
|
||||
lbl_8057F278 = .sdata2:0x8057F278; // type:object size:0x8 data:double
|
||||
|
||||
+1
-1
@@ -203,7 +203,6 @@ cflags_nw4r = [
|
||||
*cflags_base,
|
||||
"-ipa file",
|
||||
"-fp_contract off",
|
||||
|
||||
]
|
||||
|
||||
# REL flags
|
||||
@@ -357,6 +356,7 @@ config.libs = [
|
||||
Object(Matching, "nw4r/lyt/lyt_group.cpp"),
|
||||
Object(Matching, "nw4r/lyt/lyt_layout.cpp"),
|
||||
Object(Matching, "nw4r/lyt/lyt_picture.cpp"),
|
||||
Object(Matching, "nw4r/lyt/lyt_textBox.cpp"),
|
||||
Object(Matching, "nw4r/lyt/lyt_resourceAccessor.cpp"),
|
||||
Object(Matching, "nw4r/lyt/lyt_arcResourceAccessor.cpp"),
|
||||
Object(Matching, "nw4r/lyt/lyt_common.cpp"),
|
||||
|
||||
@@ -28,6 +28,19 @@ inline void SetVtxColElement(ut::Color *cols, u32 idx, u8 value) {
|
||||
((u8 *)cols)[(idx & ~3) + (idx & 3)] = value;
|
||||
}
|
||||
|
||||
inline u8 GetHorizontalPosition(u8 var) {
|
||||
return var % 3;
|
||||
}
|
||||
inline u8 GetVerticalPosition(u8 var) {
|
||||
return var / 3;
|
||||
}
|
||||
inline void SetHorizontalPosition(u8 *pVar, u8 newVal) {
|
||||
*pVar = newVal + GetVerticalPosition(*pVar) * 3;
|
||||
}
|
||||
inline void SetVerticalPosition(u8 *pVar, u8 newVal) {
|
||||
*pVar = newVal * 3 + GetHorizontalPosition(*pVar);
|
||||
}
|
||||
|
||||
typedef math::VEC2 TexCoordData[TEXCOORD_VTX_COUNT];
|
||||
|
||||
class TexCoordAry {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <new.h>
|
||||
#include <nw4r/lyt/lyt_animation.h>
|
||||
#include <nw4r/lyt/lyt_types.h>
|
||||
#include <nw4r/ut/ut_ResFont.h>
|
||||
#include <rvl/MEM/mem_allocator.h>
|
||||
|
||||
namespace nw4r {
|
||||
@@ -70,6 +71,9 @@ public:
|
||||
template <typename T>
|
||||
static T *NewArray(size_t n) {
|
||||
T *array = (T *)AllocMemory(n * sizeof(T));
|
||||
if (!array) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
new (&array[i]) T();
|
||||
@@ -86,6 +90,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void DeletePrimArray(T *objAry) {
|
||||
if (objAry) {
|
||||
FreeMemory(objAry);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T *NewObj() {
|
||||
T *pMem = (T *)AllocMemory(sizeof(T));
|
||||
|
||||
@@ -81,6 +81,14 @@ public:
|
||||
TexMap *GetTexMapAry();
|
||||
TexCoordGen *GetTexCoordGenAry();
|
||||
|
||||
GXColorS10 GetTevColor(u32 idx) const {
|
||||
return mTevCols[idx];
|
||||
}
|
||||
|
||||
ut::Color GetTevKColor(u32 idx) const {
|
||||
return mTevKCols[idx];
|
||||
}
|
||||
|
||||
void SetTexture(u32 texMapIdx, const TexMap &texMap) {
|
||||
GetTexMapAry()[texMapIdx] = texMap;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,12 @@ struct FontList {
|
||||
u8 padding[2]; // at 0x0A
|
||||
};
|
||||
|
||||
struct Font {
|
||||
u32 nameStrOffset; // at 0x0
|
||||
u8 type; // at 0x4
|
||||
u8 padding[3]; // at 0x5
|
||||
};
|
||||
|
||||
struct TextureList {
|
||||
DataBlockHeader blockHeader; // at 0x00
|
||||
u16 texNum; // at 0x08
|
||||
@@ -117,6 +123,7 @@ struct TextureList {
|
||||
};
|
||||
struct TextBox : public Pane {
|
||||
u16 textBufBytes; // at 0x4C
|
||||
u16 textStrBytes; // at 0x4E
|
||||
u16 materialIdx; // at 0x50
|
||||
u16 fontIdx; // at 0x52
|
||||
u8 textPosition; // at 0x54
|
||||
|
||||
@@ -8,17 +8,75 @@ namespace nw4r {
|
||||
namespace lyt {
|
||||
class TextBox : public Pane {
|
||||
public:
|
||||
TextBox(u16 allocStrLen);
|
||||
TextBox(const wchar_t *str, const ut::Font *pFont);
|
||||
TextBox(u16, const wchar_t *str, u16, const ut::Font *pFont);
|
||||
TextBox(const res::TextBox *pBlock, const ResBlockSet &resBlockSet);
|
||||
|
||||
void Init(u16 allocStrLen);
|
||||
|
||||
ut::Rect GetTextDrawRect() const;
|
||||
ut::Rect GetTextDrawRect(const DrawInfo &drawInfo) const;
|
||||
u16 GetStringBufferLength() const;
|
||||
u16 SetStringImpl(const wchar_t *str, u16 dstIdx, u32 strLen);
|
||||
const ut::Font *GetFont() const;
|
||||
void SetFont(const ut::Font *pFont);
|
||||
ut::Rect GetTextDrawRect(ut::TextWriterBase<wchar_t> *pWriter) const;
|
||||
f32 GetTextMagH() const;
|
||||
f32 GetTextMagV() const;
|
||||
f32 GetTextAlignMag() const;
|
||||
UNKTYPE MakeDrawFlag() const;
|
||||
|
||||
ut::Color GetTextColor(u32 type) const {
|
||||
return mTextColors[type / 2];
|
||||
}
|
||||
void SetTextColor(u32 type, ut::Color value) {
|
||||
mTextColors[type] = value;
|
||||
}
|
||||
u8 GetTextPositionH() const {
|
||||
return detail::GetHorizontalPosition(mTextPosition);
|
||||
}
|
||||
void SetTextPositionH(u8 val) {
|
||||
detail::SetHorizontalPosition(&mTextPosition, val);
|
||||
}
|
||||
u8 GetTextPositionV() const {
|
||||
return detail::GetVerticalPosition(mTextPosition);
|
||||
}
|
||||
void SetTextPositionV(u8 val) {
|
||||
detail::SetVerticalPosition(&mTextPosition, val);
|
||||
}
|
||||
|
||||
const Size &GetFontSize() const {
|
||||
return mFontSize;
|
||||
}
|
||||
|
||||
void SetFontSize(const Size &fontSize) {
|
||||
mFontSize = fontSize;
|
||||
}
|
||||
ut::TagProcessorBase<wchar_t> *GetTagProcessor() const {
|
||||
return mpTagProcessor;
|
||||
}
|
||||
void SetTagProcessor(ut::TagProcessorBase<wchar_t> *pTagProcessor) {
|
||||
mpTagProcessor = pTagProcessor;
|
||||
}
|
||||
|
||||
TextBox(const res::TextBox *, const ResBlockSet &resBlockSet);
|
||||
virtual ~TextBox();
|
||||
NW4R_UT_RTTI_DECL(TextBox);
|
||||
virtual void DrawSelf(const DrawInfo &drawInfo); // at 0x18
|
||||
virtual ut::Color GetVtxColor(u32 idx) const; // at 0x24
|
||||
virtual void SetVtxColor(u32 idx, ut::Color value); // at 0x28
|
||||
virtual u8 GetVtxColorElement(u32 idx) const; // at 0x34
|
||||
virtual void SetVtxColorElement(u32 idx, u8 value); // at 0x38
|
||||
virtual void LoadMtx(const DrawInfo &drawInfo); // at 0x70
|
||||
virtual void AllocStringBuffer(u16 minLen); // at 0x
|
||||
virtual void FreeStringBuffer(); // at 0x
|
||||
virtual u16 SetString(const wchar_t *str, u16 dstIdx); // at 0x
|
||||
virtual u16 SetString(const wchar_t *str, u16 dstIdx, u16 strLen); // at 0x
|
||||
|
||||
protected:
|
||||
wchar_t *mTextBuf; // at 0xD8 // ptr to is Guess
|
||||
ut::Color mTextColors[2]; // at 0xDC
|
||||
ut::Font *mpFont; // at 0xE4
|
||||
const ut::Font *mpFont; // at 0xE4
|
||||
Size mFontSize; // at 0xE8
|
||||
f32 mLineSpace; // at 0xF0
|
||||
f32 mCharSpace; // at 0xF4
|
||||
@@ -28,7 +86,7 @@ public:
|
||||
u8 mTextPosition; // at 0x100
|
||||
struct { //
|
||||
u8 bAllocFont : 1; //
|
||||
u8 textAligntment : 1; //
|
||||
u8 textAlignment : 2; //
|
||||
} mBits; // at 0x101
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ inline void SetBit(T *bits, int pos, bool val) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *ConvertOffsetToPtr(const void *baseAddress, unsigned int offset) {
|
||||
T *ConvertOffsToPtr(const void *baseAddress, unsigned int offset) {
|
||||
return (T *)((u32)baseAddress + offset);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
@@ -17,6 +17,9 @@ public:
|
||||
Color(int red, int green, int blue, int alpha) {
|
||||
Set(red, green, blue, alpha);
|
||||
}
|
||||
Color(const GXColor &clr) {
|
||||
*this = *(u32 *)&clr;
|
||||
}
|
||||
~Color() {}
|
||||
|
||||
void Set(int red, int green, int blue, int alpha) {
|
||||
|
||||
@@ -42,8 +42,8 @@ void TexCoordAry::Free() {
|
||||
void TexCoordAry::Reserve(u8 num) {
|
||||
if (mCap < num) {
|
||||
Free();
|
||||
const TexCoordData *pData = (TexCoordData *)Layout::NewArray<VEC2>(num * TEXCOORD_VTX_COUNT);
|
||||
this->mpData = pData ? const_cast<TexCoordData *>(pData) : nullptr;
|
||||
TexCoordData *pData = (TexCoordData *)Layout::NewArray<VEC2>(num * TEXCOORD_VTX_COUNT);
|
||||
this->mpData = pData;
|
||||
if (mpData != NULL) {
|
||||
mCap = num;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ Group::Group(const res::Group *pResGroup, Pane *pRootPane) : mLink(), mPaneListL
|
||||
Init();
|
||||
strncpy(this->mName, pResGroup->mName, NW4R_RES_NAME_SIZE);
|
||||
this->mName[NW4R_RES_NAME_SIZE] = '\0';
|
||||
const char *paneNameBase = detail::ConvertOffsetToPtr<char>(pResGroup, sizeof(res::Group));
|
||||
const char *paneNameBase = detail::ConvertOffsToPtr<char>(pResGroup, sizeof(res::Group));
|
||||
|
||||
for (int i = 0; i < pResGroup->paneNum; i++) {
|
||||
Pane *pFindPane = pRootPane->FindPaneByName(paneNameBase + i * NW4R_RES_NAME_SIZE, true);
|
||||
|
||||
@@ -514,7 +514,7 @@ u16 Pane::GetExtUserDataNum() const {
|
||||
}
|
||||
res::ExtUserData *Pane::GetExtUserData() const {
|
||||
if (this->mpExtUserDataList) {
|
||||
return detail::ConvertOffsetToPtr<res::ExtUserData>(this->mpExtUserDataList, sizeof(res::ExtUserDataList));
|
||||
return detail::ConvertOffsToPtr<res::ExtUserData>(this->mpExtUserDataList, sizeof(res::ExtUserDataList));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -530,7 +530,7 @@ res::ExtUserData *Pane::FindExtUserDataByName(const char *name) {
|
||||
u32 offset = pUserData->nameOffs;
|
||||
const char *str = 0;
|
||||
if (offset != 0) {
|
||||
str = detail::ConvertOffsetToPtr<char>(pUserData, offset);
|
||||
str = detail::ConvertOffsToPtr<char>(pUserData, offset);
|
||||
} else {
|
||||
str = nullptr;
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ Picture::Picture(const res::Picture *pResPic, const ResBlockSet &resBlockSet)
|
||||
if (texCoordNum != 0 && !mTexCoordAry.IsEmpty()) {
|
||||
mTexCoordAry.Copy((void *)&pResPic[1], texCoordNum);
|
||||
}
|
||||
const u32 *matOffsTbl = detail::ConvertOffsetToPtr<u32>(resBlockSet.pMaterialList, sizeof(res::MaterialList));
|
||||
const u32 *matOffsTbl = detail::ConvertOffsToPtr<u32>(resBlockSet.pMaterialList, sizeof(res::MaterialList));
|
||||
const res::Material *pResMaterial =
|
||||
detail::ConvertOffsetToPtr<res::Material>(resBlockSet.pMaterialList, matOffsTbl[pResPic->materialIdx]);
|
||||
detail::ConvertOffsToPtr<res::Material>(resBlockSet.pMaterialList, matOffsTbl[pResPic->materialIdx]);
|
||||
mpMaterial = Layout::NewObj<Material>(pResMaterial, resBlockSet);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
#include <nw4r/lyt/lyt_bounding.h>
|
||||
#include <nw4r/lyt/lyt_drawInfo.h>
|
||||
#include <nw4r/lyt/lyt_layout.h>
|
||||
#include <nw4r/lyt/lyt_material.h>
|
||||
#include <nw4r/lyt/lyt_textBox.h>
|
||||
#include <nw4r/ut/ut_Rect.h>
|
||||
#include <nw4r/ut/ut_TextWriterBase.h>
|
||||
|
||||
namespace nw4r {
|
||||
namespace lyt {
|
||||
|
||||
NW4R_UT_RTTI_DEF_DERIVED(TextBox, Pane);
|
||||
|
||||
namespace {
|
||||
// ReverseYAxis__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FPQ34nw4r4math5MTX34
|
||||
void ReverseYAxis(math::MTX34 *pMtx) {
|
||||
// Based on impl in LoadMtx
|
||||
pMtx->_01 = -pMtx->_01;
|
||||
pMtx->_11 = -pMtx->_11;
|
||||
pMtx->_21 = -pMtx->_21;
|
||||
}
|
||||
|
||||
// ClampColor__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@Fs
|
||||
u8 ClampColor(s16 colVal) {
|
||||
// The CLAMP macro was reversed for this -_-
|
||||
return colVal < 0 ? 0 : (colVal > 0xFF ? 0xFF : colVal);
|
||||
}
|
||||
|
||||
// GetColor__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FRC11_GXColorS10
|
||||
ut::Color GetColor(const GXColorS10 &src) {
|
||||
GXColor dst;
|
||||
dst.r = ClampColor(src.r);
|
||||
dst.g = ClampColor(src.g);
|
||||
dst.b = ClampColor(src.b);
|
||||
dst.a = ClampColor(src.a);
|
||||
return dst;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CalcStringRect(ut::Rect *pRect, ut::TextWriterBase<T> *pTextWriter, const T *str, int length, f32 maxWidth) {
|
||||
ut::TextWriterBase<T> myCopy = *pTextWriter;
|
||||
CalcStringRectImpl<T>(pRect, &myCopy, str, length, maxWidth);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int CalcLineStrNum(f32 *pWidth, ut::TextWriterBase<T> *pTextWriter, const T *str, int length, f32 maxWidth,
|
||||
bool *pbOver) {
|
||||
ut::Rect rect;
|
||||
ut::TextWriterBase<T> myCopy = *pTextWriter;
|
||||
myCopy.SetCursor(0.0f, 0.0f);
|
||||
int ret = CalcLineRectImpl(&rect, &myCopy, str, length, maxWidth, pbOver);
|
||||
|
||||
*pWidth = rect.GetWidth();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int CalcLineRectImpl(ut::Rect *pRect, ut::TextWriterBase<T> *pTextWriter, const T *str, int length, f32 maxWidth,
|
||||
bool *pbOver) {
|
||||
ut::PrintContext<T> context = {pTextWriter, str, 0.0f, 0.0f, 0};
|
||||
f32 x = 0.0f;
|
||||
|
||||
const ut::Font *font = pTextWriter->GetFont();
|
||||
bool bCharSpace = false;
|
||||
ut::CharStrmReader reader = font->GetCharStrmReader();
|
||||
|
||||
const T *prStrPos = (const T *)reader.GetCurrentPos();
|
||||
|
||||
pRect->left = 0.0f;
|
||||
pRect->right = 0.0f;
|
||||
pRect->top = ut::Min(0.0f, pTextWriter->GetLineHeight());
|
||||
pRect->bottom = ut::Max(0.0f, pTextWriter->GetLineHeight());
|
||||
|
||||
*pbOver = false;
|
||||
|
||||
reader.Set(str);
|
||||
ut::Rect prMaxRect = *pRect;
|
||||
u16 code = reader.Next();
|
||||
while (((const T *)reader.GetCurrentPos() - str) <= length) {
|
||||
if (code < ' ') {
|
||||
ut::Operation operation;
|
||||
ut::Rect rect(x, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
context.str = (const T *)reader.GetCurrentPos();
|
||||
context.flags = !bCharSpace;
|
||||
|
||||
pTextWriter->SetCursorX(x);
|
||||
operation = pTextWriter->GetTagProcessor()->CalcRect(&rect, code, &context);
|
||||
reader.Set(context.str);
|
||||
|
||||
pRect->left = ut::Min(pRect->left, rect.left);
|
||||
pRect->top = ut::Min(pRect->top, rect.top);
|
||||
pRect->right = ut::Max(pRect->right, rect.right);
|
||||
pRect->bottom = ut::Max(pRect->bottom, rect.bottom);
|
||||
|
||||
x = pTextWriter->GetCursorX();
|
||||
|
||||
if (pRect->GetWidth() > maxWidth) {
|
||||
*pbOver = true;
|
||||
break;
|
||||
}
|
||||
if (operation == ut::OPERATION_END_DRAW) {
|
||||
return length;
|
||||
} else if (operation == ut::OPERATION_NO_CHAR_SPACE) {
|
||||
bCharSpace = false;
|
||||
} else if (operation == ut::OPERATION_CHAR_SPACE) {
|
||||
bCharSpace = true;
|
||||
} else if (operation == ut::OPERATION_NEXT_LINE) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (bCharSpace) {
|
||||
x += pTextWriter->GetCharSpace();
|
||||
}
|
||||
bCharSpace = true;
|
||||
if (pTextWriter->IsWidthFixed()) {
|
||||
x += pTextWriter->GetFixedWidth();
|
||||
} else {
|
||||
x += pTextWriter->GetFont()->GetCharWidth(code) * pTextWriter->GetScaleH();
|
||||
}
|
||||
pRect->left = ut::Min(pRect->left, x);
|
||||
pRect->right = ut::Max(pRect->right, x);
|
||||
|
||||
if (pRect->GetWidth() > maxWidth) {
|
||||
*pbOver = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prStrPos = (const T *)reader.GetCurrentPos();
|
||||
code = reader.Next();
|
||||
prMaxRect = *pRect;
|
||||
}
|
||||
|
||||
if (*pbOver) {
|
||||
if (prStrPos) {
|
||||
*pRect = prMaxRect;
|
||||
return (prStrPos - str);
|
||||
}
|
||||
}
|
||||
return ((const T *)reader.GetCurrentPos() - str);
|
||||
}
|
||||
template <typename T>
|
||||
void CalcStringRectImpl(ut::Rect *pRect, ut::TextWriterBase<T> *pTextWriter, const T *str, int length, f32 maxWidth) {
|
||||
pRect->left = 0.0f;
|
||||
pRect->right = 0.0f;
|
||||
pRect->top = 0.0f;
|
||||
pRect->bottom = 0.0f;
|
||||
pTextWriter->SetCursor(0.0f, 0.0f);
|
||||
int remain = length;
|
||||
const T *pos = str;
|
||||
do {
|
||||
ut::Rect rect;
|
||||
bool bOver;
|
||||
int read = CalcLineRectImpl(&rect, pTextWriter, pos, remain, maxWidth, &bOver);
|
||||
pos += read;
|
||||
remain -= read;
|
||||
pRect->left = ut::Min(pRect->left, rect.left);
|
||||
pRect->top = ut::Min(pRect->top, rect.top);
|
||||
pRect->right = ut::Max(pRect->right, rect.right);
|
||||
pRect->bottom = ut::Max(pRect->bottom, rect.bottom);
|
||||
if (bOver) {
|
||||
CalcLineRectImpl(&rect, pTextWriter, L"\n", 1, maxWidth, &bOver);
|
||||
pRect->left = ut::Min(pRect->left, rect.left);
|
||||
pRect->top = ut::Min(pRect->top, rect.top);
|
||||
pRect->right = ut::Max(pRect->right, rect.right);
|
||||
pRect->bottom = ut::Max(pRect->bottom, rect.bottom);
|
||||
}
|
||||
} while (remain > 0);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// __ct__Q34nw4r3lyt7TextBoxFUs
|
||||
TextBox::TextBox(u16 allocStrLen) {
|
||||
// TODO: Not in SS
|
||||
}
|
||||
|
||||
// __ct__Q34nw4r3lyt7TextBoxFUsPCwPCQ34nw4r2ut4Font
|
||||
TextBox::TextBox(const wchar_t *str, const ut::Font *pFont) {
|
||||
// TODO: Not in SS
|
||||
}
|
||||
|
||||
// __ct__Q34nw4r3lyt7TextBoxFUsPCwUsPCQ34nw4r2ut4Font
|
||||
TextBox::TextBox(u16, const wchar_t *str, u16, const ut::Font *pFont) {
|
||||
// TODO: Not in SS
|
||||
}
|
||||
|
||||
// __ct__Q34nw4r3lyt7TextBoxFPCQ44nw4r3lyt3res7TextBoxRCQ34nw4r3lyt11ResBlockSet
|
||||
TextBox::TextBox(const res::TextBox *pBlock, const ResBlockSet &resBlockSet)
|
||||
: Pane(pBlock), mTextColors(), mFontSize() {
|
||||
u16 allocStrBufferLen = pBlock->textBufBytes / 2;
|
||||
if (allocStrBufferLen > 0) {
|
||||
allocStrBufferLen -= 1;
|
||||
}
|
||||
Init(allocStrBufferLen);
|
||||
if (pBlock->textStrBytes >= 2 && mTextBuf) {
|
||||
u16 resStringLen = pBlock->textStrBytes / 2 - 1;
|
||||
const wchar_t *pBlockText = detail::ConvertOffsToPtr<wchar_t>(pBlock, pBlock->textStrOffset);
|
||||
SetString(pBlockText, 0, resStringLen);
|
||||
}
|
||||
mTextColors[0] = pBlock->textCols[0];
|
||||
mTextColors[1] = pBlock->textCols[1];
|
||||
mFontSize = pBlock->fontSize;
|
||||
mTextPosition = pBlock->textPosition;
|
||||
mBits.textAlignment = pBlock->textAlignment;
|
||||
mCharSpace = pBlock->charSpace;
|
||||
mLineSpace = pBlock->lineSpace;
|
||||
|
||||
int i = pBlock->fontIdx;
|
||||
const res::Font *fonts = detail::ConvertOffsToPtr<res::Font>(resBlockSet.pFontList, sizeof(res::FontList));
|
||||
const char *fontName = detail::ConvertOffsToPtr<char>(fonts, fonts[i].nameStrOffset);
|
||||
ut::Font *pFont = resBlockSet.pResAccessor->GetFont(fontName);
|
||||
if (pFont) {
|
||||
mpFont = pFont;
|
||||
} else {
|
||||
void *fontRes = resBlockSet.pResAccessor->GetResource('font', fontName, nullptr);
|
||||
if (fontRes) {
|
||||
ut::ResFont *pResFont = Layout::NewObj<ut::ResFont>();
|
||||
if (pResFont) {
|
||||
bool bSucces = pResFont->SetResource(fontRes);
|
||||
mpFont = pResFont;
|
||||
mBits.bAllocFont = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
const u32 *matOffsTbl = detail::ConvertOffsToPtr<u32>(resBlockSet.pMaterialList, sizeof(res::MaterialList));
|
||||
const res::Material *pResMaterial =
|
||||
detail::ConvertOffsToPtr<res::Material>(resBlockSet.pMaterialList, matOffsTbl[pBlock->materialIdx]);
|
||||
mpMaterial = Layout::NewObj<Material>(pResMaterial, resBlockSet);
|
||||
}
|
||||
|
||||
// Init__Q34nw4r3lyt7TextBoxFUs
|
||||
void TextBox::Init(u16 allocStrLen) {
|
||||
mTextBuf = nullptr;
|
||||
mTextBufBytes = 0;
|
||||
mTextLen = 0;
|
||||
mpFont = nullptr;
|
||||
mFontSize = Size(0.0f, 0.0f);
|
||||
mLineSpace = 0.0f;
|
||||
mCharSpace = 0.0f;
|
||||
mpTagProcessor = nullptr;
|
||||
SetTextPositionH(1);
|
||||
SetTextPositionV(1);
|
||||
memset(&mBits, 0, sizeof(mBits));
|
||||
if (allocStrLen != 0) {
|
||||
AllocStringBuffer(allocStrLen);
|
||||
}
|
||||
}
|
||||
|
||||
// __dt__Q34nw4r3lyt7TextBoxFv
|
||||
TextBox::~TextBox() {
|
||||
SetFont(nullptr);
|
||||
if (mpMaterial && !mpMaterial->IsUserAllocated()) {
|
||||
Layout::DeleteObj(mpMaterial);
|
||||
mpMaterial = nullptr;
|
||||
}
|
||||
FreeStringBuffer();
|
||||
}
|
||||
|
||||
// GetVtxColor__Q34nw4r3lyt7TextBoxCFUl
|
||||
ut::Color TextBox::GetVtxColor(u32 idx) const {
|
||||
return GetTextColor(idx);
|
||||
}
|
||||
|
||||
// SetVtxColor__Q34nw4r3lyt7TextBoxFUlQ34nw4r2ut5Color
|
||||
void TextBox::SetVtxColor(u32 idx, ut::Color value) {
|
||||
SetTextColor(idx / 2, value);
|
||||
}
|
||||
|
||||
// GetVtxColorElement__Q34nw4r3lyt7TextBoxCFUl
|
||||
u8 TextBox::GetVtxColorElement(u32 idx) const {
|
||||
return ((u8 *)mTextColors)[((idx / 2) & ~3) + (idx & 3)];
|
||||
}
|
||||
|
||||
// SetVtxColorElement__Q34nw4r3lyt7TextBoxFUlUc
|
||||
void TextBox::SetVtxColorElement(u32 idx, u8 value) {
|
||||
((u8 *)mTextColors)[((idx / 2) & ~3) + (idx & 3)] = value;
|
||||
}
|
||||
|
||||
// 1] IDK which one is accurate, both symbols exist
|
||||
// GetTextDrawRect__Q34nw4r3lyt7TextBoxCFv
|
||||
ut::Rect TextBox::GetTextDrawRect() const {
|
||||
return GetTextDrawRect(&ut::TextWriterBase<wchar_t>());
|
||||
}
|
||||
|
||||
// 2] IDK which one is accurate, both symbols exist
|
||||
// GetTextDrawRect__Q34nw4r3lyt7TextBoxCFRCQ34nw4r3lyt8DrawInfo
|
||||
ut::Rect TextBox::GetTextDrawRect(const DrawInfo &drawInfo) const {
|
||||
// Not in SS
|
||||
return GetTextDrawRect();
|
||||
}
|
||||
|
||||
// DrawSelf__Q34nw4r3lyt7TextBoxFRCQ34nw4r3lyt8DrawInfo
|
||||
void TextBox::DrawSelf(const DrawInfo &drawInfo) {
|
||||
if (!mTextBuf || !mpFont || !mpMaterial) {
|
||||
return;
|
||||
}
|
||||
LoadMtx(drawInfo);
|
||||
ut::TextWriterBase<wchar_t> writer;
|
||||
ut::Rect textRect = GetTextDrawRect(&writer);
|
||||
ut::Color topCol = detail::MultipleAlpha(mTextColors[0], mGlbAlpha);
|
||||
ut::Color btmCol = detail::MultipleAlpha(mTextColors[1], mGlbAlpha);
|
||||
writer.SetGradationMode(topCol != btmCol ? ut::CharWriter::GRADMODE_V : ut::CharWriter::GRADMODE_NONE);
|
||||
writer.SetTextColor(topCol, btmCol);
|
||||
|
||||
ut::Color minCol = GetColor(mpMaterial->GetTevColor(0));
|
||||
ut::Color maxCol = GetColor(mpMaterial->GetTevColor(1));
|
||||
writer.SetColorMapping(minCol, maxCol);
|
||||
writer.SetupGX();
|
||||
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
||||
f32 hMag = GetTextAlignMag();
|
||||
|
||||
const wchar_t *strPos = mTextBuf;
|
||||
writer.SetCursor(textRect.left, -textRect.top);
|
||||
f32 texWidth = textRect.GetWidth();
|
||||
int remain = mTextLen;
|
||||
|
||||
while (remain > 0) {
|
||||
bool bOver;
|
||||
f32 lineWidth;
|
||||
int lineStrNum = CalcLineStrNum(&lineWidth, &writer, strPos, remain, mSize.width, &bOver);
|
||||
f32 textPosX = textRect.left + hMag * (texWidth - lineWidth);
|
||||
writer.SetCursorX(textPosX);
|
||||
writer.PrintMutable(strPos, lineStrNum);
|
||||
if (bOver) {
|
||||
writer.PrintMutable(L"\n", 1);
|
||||
}
|
||||
strPos += lineStrNum;
|
||||
remain -= lineStrNum;
|
||||
}
|
||||
}
|
||||
|
||||
// CalcLineStrNum<w>__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FPfPQ34nw4r2ut17TextWriterBase<w>PCwifPb_i
|
||||
// CalcLineRectImpl<w>__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FPQ34nw4r2ut4RectPQ34nw4r2ut17TextWriterBase<w>PCwifPb_i
|
||||
|
||||
// GetStringBufferLength__Q34nw4r3lyt7TextBoxCFv
|
||||
u16 TextBox::GetStringBufferLength() const {
|
||||
if (mTextBufBytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
return mTextBufBytes / sizeof(wchar_t) - 1;
|
||||
}
|
||||
|
||||
// AllocStringBuffer__Q34nw4r3lyt7TextBoxFUs
|
||||
void TextBox::AllocStringBuffer(u16 minLen) {
|
||||
if (minLen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
u32 allocLen = minLen;
|
||||
u32 texBufBytes = (minLen + 1) * sizeof(wchar_t);
|
||||
|
||||
if (texBufBytes > mTextBufBytes) {
|
||||
FreeStringBuffer();
|
||||
mTextBuf = Layout::NewArray<wchar_t>(allocLen + 1);
|
||||
if (mTextBuf) {
|
||||
mTextBufBytes = texBufBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FreeStringBuffer__Q34nw4r3lyt7TextBoxFv
|
||||
void TextBox::FreeStringBuffer() {
|
||||
if (mTextBuf) {
|
||||
Layout::DeletePrimArray(mTextBuf);
|
||||
mTextBuf = nullptr;
|
||||
mTextBufBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// SetString__Q34nw4r3lyt7TextBoxFPCwUs
|
||||
u16 TextBox::SetString(const wchar_t *str, u16 dstIdx) {
|
||||
return SetStringImpl(str, dstIdx, wcslen(str));
|
||||
}
|
||||
|
||||
// SetString__Q34nw4r3lyt7TextBoxFPCwUsUs
|
||||
u16 TextBox::SetString(const wchar_t *str, u16 dstIdx, u16 strLen) {
|
||||
return SetStringImpl(str, dstIdx, strLen);
|
||||
}
|
||||
|
||||
// SetStringImpl__Q34nw4r3lyt7TextBoxFPCwUsUl
|
||||
u16 TextBox::SetStringImpl(const wchar_t *str, u16 dstIdx, u32 strLen) {
|
||||
if (!mTextBuf) {
|
||||
return 0;
|
||||
}
|
||||
u16 bufLen = GetStringBufferLength();
|
||||
if (dstIdx >= bufLen) {
|
||||
return 0;
|
||||
}
|
||||
u32 cpLen = ut::Min<u32>(strLen, bufLen - dstIdx);
|
||||
memcpy(&mTextBuf[dstIdx], str, cpLen * sizeof(wchar_t));
|
||||
mTextLen = dstIdx + cpLen;
|
||||
mTextBuf[mTextLen] = L'\0';
|
||||
return cpLen;
|
||||
}
|
||||
|
||||
// GetFont__Q34nw4r3lyt7TextBoxCFv
|
||||
const ut::Font *TextBox::GetFont() const {
|
||||
return mpFont;
|
||||
}
|
||||
|
||||
// SetFont__Q34nw4r3lyt7TextBoxFPCQ34nw4r2ut4Font
|
||||
void TextBox::SetFont(const ut::Font *pFont) {
|
||||
if (mBits.bAllocFont) {
|
||||
Layout::DeleteObj(const_cast<ut::Font *>(mpFont));
|
||||
mBits.bAllocFont = false;
|
||||
}
|
||||
mpFont = pFont;
|
||||
if (mpFont) {
|
||||
SetFontSize(Size(mpFont->GetWidth(), mpFont->GetHeight()));
|
||||
} else {
|
||||
SetFontSize(Size(0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// LoadMtx__Q34nw4r3lyt7TextBoxFRCQ34nw4r3lyt8DrawInfo
|
||||
void TextBox::LoadMtx(const DrawInfo &drawInfo) {
|
||||
math::MTX34 mtx;
|
||||
if (drawInfo.IsMultipleViewMtxOnDraw()) {
|
||||
PSMTXConcat(drawInfo.GetViewMtx(), mGlbMtx, mtx);
|
||||
} else {
|
||||
PSMTXCopy(mGlbMtx, mtx);
|
||||
}
|
||||
|
||||
ReverseYAxis(&mtx);
|
||||
|
||||
GXLoadPosMtxImm(mtx, GX_PNMTX0);
|
||||
GXSetCurrentMtx(GX_PNMTX0);
|
||||
}
|
||||
|
||||
// GetTextDrawRect__Q34nw4r3lyt7TextBoxCFPQ34nw4r2ut17TextWriterBase<w>
|
||||
// BBA map failed me here xD, probably different impl
|
||||
ut::Rect TextBox::GetTextDrawRect(ut::TextWriterBase<wchar_t> *pWriter) const {
|
||||
ut::Rect textRect;
|
||||
pWriter->SetCursor(0.0f, 0.0f);
|
||||
pWriter->SetFont(*mpFont);
|
||||
pWriter->SetFontSize(mFontSize.width, mFontSize.height);
|
||||
pWriter->SetLineSpace(mLineSpace);
|
||||
pWriter->SetCharSpace(mCharSpace);
|
||||
if (mpTagProcessor) {
|
||||
pWriter->SetTagProcessor(mpTagProcessor);
|
||||
}
|
||||
CalcStringRect(&textRect, pWriter, mTextBuf, mTextLen, mSize.width);
|
||||
|
||||
Size textSize(textRect.GetWidth(), textRect.GetHeight());
|
||||
math::VEC2 ltPos = GetVtxPos();
|
||||
|
||||
// Adjust for Alignment (left, center, right)
|
||||
ltPos.x += (mSize.width - textSize.width) * GetTextMagH();
|
||||
ltPos.y -= (mSize.height - textSize.height) * GetTextMagV();
|
||||
|
||||
// Apply the new pos
|
||||
textRect.left = ltPos.x;
|
||||
textRect.top = ltPos.y;
|
||||
textRect.right = ltPos.x + textSize.width;
|
||||
textRect.bottom = ltPos.y - textSize.height;
|
||||
|
||||
return textRect;
|
||||
}
|
||||
|
||||
// CalcStringRect<w>__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FPQ34nw4r2ut4RectPQ34nw4r2ut17TextWriterBase<w>PCwif_v
|
||||
// CalcStringRectImpl<w>__Q34nw4r3lyt25@unnamed@lyt_textBox_cpp@FPQ34nw4r2ut4RectPQ34nw4r2ut17TextWriterBase<w>PCwif_v
|
||||
|
||||
// GetTextMagH__Q34nw4r3lyt7TextBoxCFv
|
||||
f32 TextBox::GetTextMagH() const {
|
||||
switch (GetTextPositionH()) {
|
||||
default:
|
||||
return 0.0f;
|
||||
case 1:
|
||||
return 0.5f;
|
||||
case 2:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// GetTextMagV__Q34nw4r3lyt7TextBoxCFv
|
||||
f32 TextBox::GetTextMagV() const {
|
||||
switch (GetTextPositionV()) {
|
||||
default:
|
||||
return 0.0f;
|
||||
case 1:
|
||||
return 0.5f;
|
||||
case 2:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// GetTextAlignMag__Q34nw4r3lyt7TextBoxCFv
|
||||
f32 TextBox::GetTextAlignMag() const {
|
||||
switch (mBits.textAlignment) {
|
||||
default:
|
||||
return GetTextMagH();
|
||||
case 1:
|
||||
return 0.0f;
|
||||
case 2:
|
||||
return 0.5f;
|
||||
case 3:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// MakeDrawFlag__Q34nw4r3lyt7TextBoxCFv
|
||||
UNKTYPE TextBox::MakeDrawFlag() const {
|
||||
// TODO: Not In SS
|
||||
// Calls GetTextPositionH()
|
||||
}
|
||||
|
||||
} // namespace lyt
|
||||
} // namespace nw4r
|
||||
|
||||
Reference in New Issue
Block a user