diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 1c644bf3..2047692c 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -3846,7 +3846,7 @@ setTextWithTextProcessorV__10dTextBox_cFPCwP15dTagProcessor_cPvP16__va_list_stru calcTextLines__10dTextBox_cFPCwP15dTagProcessor_c = .text:0x800AF6B0; // type:function size:0x64 setMessageWithGlobalTextProcessor__10dTextBox_cFPCcPvPve = .text:0x800AF720; // type:function size:0x8C setMessageWithGlobalTextProcessorV__10dTextBox_cFPCcPvPvP16__va_list_struct = .text:0x800AF7B0; // type:function size:0x84 -setMessageWithGlobalTextProcessorAndMsbtInfo__10dTextBox_cFPC8MsbtInfoPCcPwUl = .text:0x800AF840; // type:function size:0xEC +setMessageWithGlobalTextProcessorAndMsbtInfo__10dTextBox_cFP8MsbtInfoPCcPwUl = .text:0x800AF840; // type:function size:0xEC setTextWithGlobalTextProcessor__10dTextBox_cFPCw = .text:0x800AF930; // type:function size:0x50 GetLineWidth__10dTextBox_cCFPf = .text:0x800AF980; // type:function size:0x1E4 GetLinesHeight__10dTextBox_cCFv = .text:0x800AFB70; // type:function size:0x1A4 @@ -36231,8 +36231,8 @@ lbl_8054721C = .data:0x8054721C; // type:object size:0x14 lbl_80547230 = .data:0x80547230; // type:object size:0x14 lbl_80547244 = .data:0x80547244; // type:object size:0x14 lbl_80547258 = .data:0x80547258; // type:object size:0x10 -lbl_80547268 = .data:0x80547268; // type:object size:0x10 -lbl_80547278 = .data:0x80547278; // type:object size:0x10 +lbl_80547268 = .data:0x80547268; // type:object size:0x9 scope:local data:string +lbl_80547278 = .data:0x80547278; // type:object size:0x9 scope:local data:string lbl_80547288 = .data:0x80547288; // type:object size:0x100 __vt__8cBgS_Chk = .data:0x80547388; // type:object size:0xC __vt__11cBgS_GndChk = .data:0x80547398; // type:object size:0xC @@ -39261,13 +39261,13 @@ maxChunkSize__4mDvd = .sdata:0x80573FD8; // type:object size:0x4 data:4byte g_DefaultGameHeapId__5mHeap = .sdata:0x80573FF8; // type:object size:0x1 data:byte lbl_80574000 = .sdata:0x80574000; // type:object size:0x8 data:4byte lbl_80574008 = .sdata:0x80574008; // type:object size:0x8 -lbl_80574010 = .sdata:0x80574010; // type:object size:0x8 -lbl_80574018 = .sdata:0x80574018; // type:object size:0x8 -lbl_80574020 = .sdata:0x80574020; // type:object size:0x8 -lbl_80574028 = .sdata:0x80574028; // type:object size:0x8 -lbl_80574030 = .sdata:0x80574030; // type:object size:0x8 -lbl_80574038 = .sdata:0x80574038; // type:object size:0x8 -lbl_80574040 = .sdata:0x80574040; // type:object size:0x8 +lbl_80574010 = .sdata:0x80574010; // type:object size:0x5 data:string +lbl_80574018 = .sdata:0x80574018; // type:object size:0x5 data:string +lbl_80574020 = .sdata:0x80574020; // type:object size:0x5 data:string +lbl_80574028 = .sdata:0x80574028; // type:object size:0x5 data:string +lbl_80574030 = .sdata:0x80574030; // type:object size:0x5 data:string +lbl_80574038 = .sdata:0x80574038; // type:object size:0x5 data:string +lbl_80574040 = .sdata:0x80574040; // type:object size:0x5 data:string lbl_80574048 = .sdata:0x80574048; // type:object size:0x8 lbl_80574050 = .sdata:0x80574050; // type:object size:0x8 data:4byte lbl_80574058 = .sdata:0x80574058; // type:object size:0x8 data:4byte diff --git a/configure.py b/configure.py index 2af65881..633c8566 100644 --- a/configure.py +++ b/configure.py @@ -569,10 +569,10 @@ config.libs = [ "progress_category": "core", "host": False, "objects": [ - Object(NonMatching, "libms/commonlib.c"), - Object(NonMatching, "libms/flowfile.c"), + Object(Matching, "libms/commonlib.c"), + Object(Matching, "libms/flowfile.c"), Object(NonMatching, "libms/libms.c"), - Object(NonMatching, "libms/msgfile.c"), + Object(Matching, "libms/msgfile.c"), ], }, { diff --git a/include/d/lyt/d_textbox.h b/include/d/lyt/d_textbox.h index 57b406fc..88b9c703 100644 --- a/include/d/lyt/d_textbox.h +++ b/include/d/lyt/d_textbox.h @@ -58,7 +58,9 @@ public: void setTextWithTextProcessor(const wchar_t *str, dTagProcessor_c *tagProcessor, void *, ...); s32 calcTextLines(const wchar_t *src, dTagProcessor_c *tagProcessor); - void setMessageWithGlobalTextProcessorAndMsbtInfo(const MsbtInfo *info, const char *labelId, wchar_t *destBuf, u32 maxLen); + void setMessageWithGlobalTextProcessorAndMsbtInfo( + MsbtInfo *info, const char *labelId, wchar_t *destBuf, u32 maxLen + ); void loadTextFormatVars(); void setupGX() const; diff --git a/include/libms/commonlib.h b/include/libms/commonlib.h index 7a0680e4..6829f278 100644 --- a/include/libms/commonlib.h +++ b/include/libms/commonlib.h @@ -48,6 +48,8 @@ void LMSi_AnalyzeMessageBinary(struct MsbInfo *info, const char *type); int LMSi_SearchBlockByName(struct MsbInfo *info, const char *name); int LMSi_GetHashTableIndexFromLabel(const char *label, int tableSize); +#define LMS_OFS_TO_PTR(ty, ptr, offset) (ty *)((char *)(ptr) + (offset)) + #ifdef __cplusplus } #endif diff --git a/include/libms/flowfile.h b/include/libms/flowfile.h index edd1710f..dbd5be3d 100644 --- a/include/libms/flowfile.h +++ b/include/libms/flowfile.h @@ -10,23 +10,23 @@ extern "C" { struct MsbfInfo; struct MsbFlowInfo { - /* 0x00 */ char type; + /* 0x00 */ unsigned char type; /* 0x01 */ char subType; /* 0x04 */ int params1n2; /* 0x08 */ short next; /* 0x0A */ short param3; /* 0x0C */ short param4; - /* 0x0E */ short param5; + /* 0x0E */ unsigned short param5; }; // Func names are made up struct MsbfInfo *LMS_InitFlow(void *data); void LMS_CloseFlow(struct MsbfInfo *info); -int LMS_GetFlow(struct MsbfInfo *info, int index); +int LMS_GetFlow(struct MsbfInfo *info); int LMS_GetEntrypoint(struct MsbfInfo *info, const char *label); struct MsbFlowInfo *LMS_GetFlowElement(struct MsbfInfo *info, int index); -const unsigned short *LMS_GetBranchPoints(struct MsbfInfo *info, int index); +unsigned short *LMS_GetBranchPoints(struct MsbfInfo *info, int index); #ifdef __cplusplus } diff --git a/include/libms/libms.h b/include/libms/libms.h index 86345e16..6ad2fd22 100644 --- a/include/libms/libms.h +++ b/include/libms/libms.h @@ -7,6 +7,14 @@ extern "C" { #endif +// made up +enum LMS_Error { + LMS_NOT_FOUND = -1, + LMS_MISSING_LBL1_DATA = -2, + LMS_MISSING_FLW3_DATA = -4, + LMS_MISSING_FEN1_DATA = -10, +}; + void LMS_SetMemFuncs(void *(*alloc)(size_t size), void (*free)(void *ptr)); // internal diff --git a/include/libms/msgfile.h b/include/libms/msgfile.h index bc6f2aaa..b9433f05 100644 --- a/include/libms/msgfile.h +++ b/include/libms/msgfile.h @@ -17,11 +17,11 @@ struct MsbtAttrInfo { struct MsbtInfo *LMS_InitMessage(void *data); void LMS_CloseMessage(struct MsbtInfo *info); -int LMS_GetTextIndexByLabel(const struct MsbtInfo *info, const char *label); -const wchar_t *LMS_GetText(const struct MsbtInfo *info, int index); -const wchar_t *LMS_GetTextByLabel(const struct MsbtInfo *info, const char *label); -const char *LMS_GetLabelByTextIndex(const struct MsbtInfo *info, int index); -struct MsbtAttrInfo *LMS_GetAttribute(const struct MsbtInfo *info, int index); +int LMS_GetTextIndexByLabel(struct MsbtInfo *info, const char *label); +const wchar_t *LMS_GetText(struct MsbtInfo *info, int index); +const wchar_t *LMS_GetTextByLabel(struct MsbtInfo *info, const char *label); +int LMS_GetLabelByTextIndex(struct MsbtInfo *info, int index, char *outLabel); +struct MsbtAttrInfo *LMS_GetAttribute(struct MsbtInfo *info, int index); #ifdef __cplusplus } diff --git a/src/d/lyt/d_textbox.cpp b/src/d/lyt/d_textbox.cpp index 46c31c49..6bf867fb 100644 --- a/src/d/lyt/d_textbox.cpp +++ b/src/d/lyt/d_textbox.cpp @@ -316,7 +316,7 @@ void dTextBox_c::setMessageWithGlobalTextProcessorV(const char *labelId, void *u } void dTextBox_c::setMessageWithGlobalTextProcessorAndMsbtInfo( - const MsbtInfo *info, const char *labelId, wchar_t *destBuf, u32 maxLen + MsbtInfo *info, const char *labelId, wchar_t *destBuf, u32 maxLen ) { const wchar_t *src = LMS_GetTextByLabel(info, labelId); SetFontSize(mMyTextScale); diff --git a/src/libms/commonlib.c b/src/libms/commonlib.c index d3ab83d7..edbd7b8e 100644 --- a/src/libms/commonlib.c +++ b/src/libms/commonlib.c @@ -2,7 +2,6 @@ #include "libms/libms.h" - void LMSi_AnalyzeMessageHeader(struct MsbInfo *info) { info->version = info->header->version; info->sectionCount = info->header->sectionCount; @@ -14,23 +13,30 @@ void LMSi_AnalyzeMessageHeader(struct MsbInfo *info) { info->fileLength = info->header->fileLength; } +// Complete fakematch here but hey, it works inline static struct MsbBlockHeader *GetBlockHeader(struct MsbInfo *info, int offset) { + return (struct MsbBlockHeader *)((unsigned int)info->header + offset); +} + +inline static struct MsbBlockHeader *GetBlockHeader2(struct MsbInfo *info, int offset) { return (struct MsbBlockHeader *)(offset + (unsigned int)info->header); } void LMSi_AnalyzeMessageBlocks(struct MsbInfo *info) { - // TODO regswap int i; - int offset = ROUND_UP(sizeof(struct MsbHeader), 0x20); // file header + int offset; + struct MsbBlock *section; + + offset = ROUND_UP(sizeof(struct MsbHeader), 0x20); // file header for (i = 0; i < info->sectionCount; i++) { - struct MsbBlock *section = &info->sectionInfos[i]; + section = &info->sectionInfos[i]; section->ptr = &GetBlockHeader(info, offset)->numEntries; section->name[0] = GetBlockHeader(info, offset)->name[0]; - section->name[1] = GetBlockHeader(info, offset)->name[1]; - section->name[2] = GetBlockHeader(info, offset)->name[2]; - section->name[3] = GetBlockHeader(info, offset)->name[3]; - section->sectionLength = GetBlockHeader(info, offset)->sectionLength; - section->field_0x0C = GetBlockHeader(info, offset)->field_0x08; + section->name[1] = GetBlockHeader2(info, offset)->name[1]; + section->name[2] = GetBlockHeader2(info, offset)->name[2]; + section->name[3] = GetBlockHeader2(info, offset)->name[3]; + section->sectionLength = GetBlockHeader2(info, offset)->sectionLength; + section->field_0x0C = GetBlockHeader2(info, offset)->field_0x08; offset = offset + 0x10; // section header offset = offset + section->sectionLength; // section offset = ROUND_UP(offset, 0x10); // align diff --git a/src/libms/flowfile.c b/src/libms/flowfile.c index d25151b5..09519eb7 100644 --- a/src/libms/flowfile.c +++ b/src/libms/flowfile.c @@ -13,10 +13,10 @@ struct MsbfInfo { struct MsbfInfo *LMS_InitFlow(void *data) { struct MsbfInfo *info = (struct MsbfInfo *)LMSi_Malloc(sizeof(struct MsbfInfo)); info->base.header = (struct MsbHeader *)data; - LMSi_AnalyzeMessageBinary(&info->base, "MsgStdBn"); - info->flw3Index = LMSi_SearchBlockByName(&info->base, "LBL1"); - info->fen1Index = LMSi_SearchBlockByName(&info->base, "TXT2"); - info->ref1Index = LMSi_SearchBlockByName(&info->base, "ATR1"); + LMSi_AnalyzeMessageBinary(&info->base, "MsgFlwBn"); + info->flw3Index = LMSi_SearchBlockByName(&info->base, "FLW3"); + info->fen1Index = LMSi_SearchBlockByName(&info->base, "FEN1"); + info->ref1Index = LMSi_SearchBlockByName(&info->base, "REF1"); return info; } @@ -27,18 +27,78 @@ void LMS_CloseFlow(struct MsbfInfo *info) { LMSi_Free(info); } -int LMS_GetFlow(struct MsbfInfo *info, int index) { - // TODO +int LMS_GetFlow(struct MsbfInfo *info) { + if (info->flw3Index == -1) { + return LMS_MISSING_FLW3_DATA; + } + return *LMS_OFS_TO_PTR(unsigned short, info->base.sectionInfos[info->flw3Index].ptr, 0); } +// Basically copied from msgfile int LMS_GetEntrypoint(struct MsbfInfo *info, const char *label) { - // TODO + const struct MsbBlock *infos; + int hashIndex; + unsigned i; + unsigned bucketLen; + int offset; + int entryLen; + int sectionIndex; + int labelLen; + + sectionIndex = info->fen1Index; + labelLen = 0; + if (info->fen1Index == -1) { + return LMS_MISSING_FEN1_DATA; + } else { + while (label[labelLen] != '\0') { + labelLen++; + } + infos = info->base.sectionInfos; + hashIndex = LMSi_GetHashTableIndexFromLabel(label, infos[sectionIndex].ptr[0]); + bucketLen = infos[sectionIndex].ptr[hashIndex * 2 + 1]; + offset = infos[sectionIndex].ptr[hashIndex * 2 + 2]; + for (i = 0; i < bucketLen; i++) { + entryLen = *LMS_OFS_TO_PTR(unsigned char, infos[sectionIndex].ptr, offset); + if (entryLen == labelLen && + LMSi_MemCmp(label, LMS_OFS_TO_PTR(const char, infos[sectionIndex].ptr, offset + 1), entryLen)) { + return *LMS_OFS_TO_PTR(int, infos[sectionIndex].ptr, offset + entryLen + 1); + } + offset += entryLen + 5; + } + } + return LMS_NOT_FOUND; } struct MsbFlowInfo *LMS_GetFlowElement(struct MsbfInfo *info, int index) { - // TODO + if (info->flw3Index == -1) { + return NULL; + } + + return LMS_OFS_TO_PTR(struct MsbFlowInfo, info->base.sectionInfos[info->flw3Index].ptr, index * 16) + 1; } -const unsigned short *LMS_GetBranchPoints(struct MsbfInfo *info, int index) { - // TODO +inline unsigned short *LMSi_GetBranchPoints(int *ptr, int off1, int off2) { + return (unsigned short *)((char *)ptr + off1 * sizeof(struct MsbFlowInfo) + sizeof(struct MsbFlowInfo) + off2 * 2); +} + +unsigned short *LMS_GetBranchPoints(struct MsbfInfo *info, int index) { + const struct MsbBlock *block; + struct MsbFlowInfo *element; + + int flow; + int idx; + + flow = LMS_GetFlow(info); + block = &info->base.sectionInfos[info->flw3Index]; + element = LMS_GetFlowElement(info, index); + + if (element == NULL) { + return NULL; + } + + if (element->type != 2) { + return NULL; + } + + return LMSi_GetBranchPoints(block->ptr, flow, element->param5); } diff --git a/src/libms/libms.c b/src/libms/libms.c index 2b77adc3..0e678693 100644 --- a/src/libms/libms.c +++ b/src/libms/libms.c @@ -28,10 +28,10 @@ int LMSi_MemCmp(const char *p1, const char *p2, int n) { } void LMSi_MemCopy(char *p1, const char *p2, int n) { - // TODO register usage too optimal + // https://decomp.me/scratch/JOWiM + // NONMATCHING - register usage too optimal + // Look, how difficult can an unrolled memcopy be to match for (int i = 0; i < n; i++) { - *p1 = *p2; - p1++; - p2++; + *(p1++) = *(p2++); } } diff --git a/src/libms/msgfile.c b/src/libms/msgfile.c index c151d206..10b69d7c 100644 --- a/src/libms/msgfile.c +++ b/src/libms/msgfile.c @@ -3,7 +3,6 @@ #include "libms/commonlib.h" #include "libms/libms.h" - struct MsbtInfo { /* 0x00 */ struct MsbInfo base; /* 0x10 */ int lbl1Index; @@ -30,15 +29,41 @@ void LMS_CloseMessage(struct MsbtInfo *info) { LMSi_Free(info); } -int LMS_GetTextIndexByLabel(const struct MsbtInfo *info, const char *label) { +int LMS_GetTextIndexByLabel(struct MsbtInfo *info, const char *label) { + const struct MsbBlock *infos; + int hashIndex; + unsigned i; + unsigned bucketLen; + int offset; + int entryLen; + int sectionIndex; + int labelLen; + + sectionIndex = info->lbl1Index; + labelLen = 0; if (info->lbl1Index == -1) { - return -2; + return LMS_MISSING_LBL1_DATA; } else { - // TODO + while (label[labelLen] != '\0') { + labelLen++; + } + infos = info->base.sectionInfos; + hashIndex = LMSi_GetHashTableIndexFromLabel(label, infos[sectionIndex].ptr[0]); + bucketLen = infos[sectionIndex].ptr[hashIndex * 2 + 1]; + offset = infos[sectionIndex].ptr[hashIndex * 2 + 2]; + for (i = 0; i < bucketLen; i++) { + entryLen = *LMS_OFS_TO_PTR(unsigned char, infos[sectionIndex].ptr, offset); + if (entryLen == labelLen && + LMSi_MemCmp(label, LMS_OFS_TO_PTR(const char, infos[sectionIndex].ptr, offset + 1), entryLen)) { + return *LMS_OFS_TO_PTR(int, infos[sectionIndex].ptr, offset + entryLen + 1); + } + offset += entryLen + 5; + } } + return LMS_NOT_FOUND; } -const wchar_t *LMS_GetText(const struct MsbtInfo *info, int index) { +const wchar_t *LMS_GetText(struct MsbtInfo *info, int index) { if (info->txt2Index == -1) { return NULL; } @@ -48,10 +73,10 @@ const wchar_t *LMS_GetText(const struct MsbtInfo *info, int index) { return NULL; } - return (const wchar_t*)&((const char *)header)[header[index + 1]]; + return LMS_OFS_TO_PTR(const wchar_t , header, header[index + 1]); } -const wchar_t *LMS_GetTextByLabel(const struct MsbtInfo *info, const char *label) { +const wchar_t *LMS_GetTextByLabel(struct MsbtInfo *info, const char *label) { int index = LMS_GetTextIndexByLabel(info, label); if (index < 0) { return NULL; @@ -60,11 +85,32 @@ const wchar_t *LMS_GetTextByLabel(const struct MsbtInfo *info, const char *label } } -const char *LMS_GetLabelByTextIndex(const struct MsbtInfo *info, int index) { - // TODO +int LMS_GetLabelByTextIndex(struct MsbtInfo *info, int index, char *outLabel) { + const struct MsbBlock *block; + + int existingIndex; + unsigned offset; + unsigned labelLen; + + block = &info->base.sectionInfos[info->lbl1Index]; + offset = block->ptr[0] * 8 + 4; + + while (1) { + if (offset >= block->sectionLength) { + return 0; + } + labelLen = *LMS_OFS_TO_PTR(unsigned char, block->ptr, offset); + existingIndex = *LMS_OFS_TO_PTR(int, block->ptr, (offset + labelLen + 1)); + if (existingIndex == index) { + LMSi_MemCopy(outLabel, LMS_OFS_TO_PTR(char, block->ptr, (offset + 1)), labelLen); + outLabel[labelLen] = '\0'; + return 1; + } + offset = offset + labelLen + 5; + } } -struct MsbtAttrInfo *LMS_GetAttribute(const struct MsbtInfo *info, int index) { +struct MsbtAttrInfo *LMS_GetAttribute(struct MsbtInfo *info, int index) { int *p = info->base.sectionInfos[info->atr1Index].ptr; - return (struct MsbtAttrInfo *)&((const char *)p)[p[1] * index + 8]; + return LMS_OFS_TO_PTR(struct MsbtAttrInfo, p, p[1] * index + 8); }