diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index 3d76eaa..45b75ea 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -342,25 +342,62 @@ PLError_t AEProcessAppleEvent(EventRecord *evt) void GetIndString(unsigned char *str, int stringsID, int fnameIndex) { if (fnameIndex < 1) + { + str[0] = 0; return; + } THandle istrRes = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('STR#', stringsID).StaticCast(); if (istrRes && *istrRes) { const uint8_t *contentsBytes = *istrRes; - const BEUInt16_t *pArraySize = reinterpret_cast(contentsBytes); + const uint8_t *endPos = contentsBytes + istrRes.MMBlock()->m_size; + const uint8_t *lineStart = contentsBytes; + const uint8_t *lineEnd = contentsBytes; - const uint16_t arraySize = *pArraySize; + for (;;) + { + if (contentsBytes == endPos) + { + if (fnameIndex == 1) + { + lineEnd = contentsBytes; + break; + } + else + { + str[0] = 0; + return; + } + } - if (fnameIndex > static_cast(arraySize)) - return; + const uint8_t lchar = contentsBytes[0]; - const uint8_t *strStart = contentsBytes + 2; - for (int i = 1; i < fnameIndex; i++) - strStart += (*strStart) + 1; + if (lchar == '\n') + { + if (fnameIndex == 1) + { + lineEnd = contentsBytes; + break; + } + else + { + fnameIndex--; + contentsBytes++; + lineStart = lineEnd = contentsBytes; + } + } + else + contentsBytes++; + } - str[0] = strStart[0]; - memcpy(str + 1, strStart + 1, *strStart); + ptrdiff_t strLength = lineEnd - lineStart; + if (strLength < 0 || strLength > 255) + strLength = 255; + + str[0] = static_cast(strLength); + + memcpy(str + 1, lineStart, strLength); } } diff --git a/PortabilityLayer/PLResourceManager.cpp b/PortabilityLayer/PLResourceManager.cpp index e08b3f0..c78720b 100644 --- a/PortabilityLayer/PLResourceManager.cpp +++ b/PortabilityLayer/PLResourceManager.cpp @@ -308,6 +308,8 @@ namespace PortabilityLayer extension = ".bmp"; validationRule = ResourceValidationRules::kBMP; } + else if (resTypeID == ResTypeID('STR#')) + extension = ".txt"; char resourceFile[64]; diff --git a/gpr2gpa/gpr2gpa.cpp b/gpr2gpa/gpr2gpa.cpp index eb828cb..afeaee6 100644 --- a/gpr2gpa/gpr2gpa.cpp +++ b/gpr2gpa/gpr2gpa.cpp @@ -719,6 +719,46 @@ bool ImportSound(std::vector &outWAV, const void *inData, size_t inSize return true; } +bool ImportIndexedString(std::vector &outTXT, const void *inData, size_t inSize) +{ + size_t remainingSize = inSize; + const uint8_t *inBytes = static_cast(inData); + + if (remainingSize < 2) + return false; + + const size_t arraySize = (inBytes[0] << 8) + inBytes[1]; + + inBytes += 2; + remainingSize -= 2; + + for (size_t i = 0; i < arraySize; i++) + { + if (remainingSize < 1) + return false; + + uint8_t strLength = *inBytes; + + inBytes++; + remainingSize--; + + if (strLength > remainingSize) + return false; + + if (i != 0) + outTXT.push_back('\n'); + + for (size_t j = 0; j < strLength; j++) + { + outTXT.push_back(*inBytes); + inBytes++; + remainingSize--; + } + } + + return true; +} + int main(int argc, const char **argv) { if (argc != 4) @@ -765,6 +805,7 @@ int main(int argc, const char **argv) const PortabilityLayer::ResTypeID pictTypeID = PortabilityLayer::ResTypeID('PICT'); const PortabilityLayer::ResTypeID dateTypeID = PortabilityLayer::ResTypeID('Date'); const PortabilityLayer::ResTypeID sndTypeID = PortabilityLayer::ResTypeID('snd '); + const PortabilityLayer::ResTypeID indexStringTypeID = PortabilityLayer::ResTypeID('STR#'); for (size_t tlIndex = 0; tlIndex < typeListCount; tlIndex++) { @@ -813,6 +854,17 @@ int main(int argc, const char **argv) if (ImportSound(entry.m_contents, resData, resSize)) contents.push_back(entry); } + else if (typeList.m_resType == indexStringTypeID) + { + PlannedEntry entry; + char resName[256]; + sprintf_s(resName, "%s/%i.txt", resTag.m_id, static_cast(res.m_resID)); + + entry.m_name = resName; + + if (ImportIndexedString(entry.m_contents, resData, resSize)) + contents.push_back(entry); + } else { PlannedEntry entry;