summaryrefslogtreecommitdiff
path: root/src/libms
diff options
context:
space:
mode:
Diffstat (limited to 'src/libms')
-rw-r--r--src/libms/commonlib.c24
-rw-r--r--src/libms/flowfile.c80
-rw-r--r--src/libms/libms.c8
-rw-r--r--src/libms/msgfile.c68
4 files changed, 146 insertions, 34 deletions
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;
+}
+
+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);
}
-const unsigned short *LMS_GetBranchPoints(struct MsbfInfo *info, int index) {
- // TODO
+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);
}