From 1ac9c36e84faa2baaf2b4c2ec4b5085290e923ee Mon Sep 17 00:00:00 2001 From: Archez Date: Wed, 17 Jan 2024 21:33:56 -0500 Subject: [PATCH] fix credits text having different codes (#7) --- ZAPD/ZTextMM.cpp | 119 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 31 deletions(-) diff --git a/ZAPD/ZTextMM.cpp b/ZAPD/ZTextMM.cpp index f9e8100..448f529 100644 --- a/ZAPD/ZTextMM.cpp +++ b/ZAPD/ZTextMM.cpp @@ -53,45 +53,102 @@ void ZTextMM::ParseMM() uint32_t msgPtr = msgEntry.msgOffset; - msgEntry.textboxType = (rawData[msgPtr + 0]); - msgEntry.textboxYPos = (rawData[msgPtr + 1]); - msgEntry.icon = (rawData[msgPtr + 2]); - msgEntry.nextMessageID = BitConverter::ToInt16BE(rawData, msgPtr + 3); - msgEntry.firstItemCost = BitConverter::ToInt16BE(rawData, msgPtr + 5); - msgEntry.secondItemCost = BitConverter::ToInt16BE(rawData, msgPtr + 7); - msgEntry.segmentId = (codeData[langPtr + 4]); - msgPtr += 11; + // NES and STAFF has different control codes and arg sizes, so we parse them separately + if (parent->GetName() == "staff_message_data_static") { // STAFF + // Credits has no header + // The textbox Type and Pos are in the code table just after the text ID as a single byte + uint8_t typePos = (codeData[currentPtr + 2]); + msgEntry.textboxType = (typePos & 0xF0) >> 4; + msgEntry.textboxYPos = typePos & 0x0F; + + // The rest of these are unused and not provided, so we set them to zero; + msgEntry.textboxType = 0; + msgEntry.icon = 0; + msgEntry.nextMessageID = 0; + msgEntry.firstItemCost = 0; + msgEntry.secondItemCost = 0; + + unsigned char c = rawData[msgPtr]; + + // Read until end marker (0x02) + while (true) { + msgEntry.msg += c; + + if (c == 0x02) { // End marker + break; + } + + switch (c) { + case 0x05: // Color: Change text color + case 0x06: // Shift: Print xx Spaces + case 0x0E: // Fade: Keep Text on Screen for xxxx Before Closing + case 0x13: // Item Icon: + case 0x14: // Text Speed: + case 0x1E: // Highscores: Prints xx highscore value + msgEntry.msg += rawData[msgPtr + 1]; + msgPtr++; + break; + case 0x07: // TextID: Open xxxx textID + case 0x0C: // Box Break Delay: Delay for xxxx Before Printing Remaining Text + case 0x11: // Fade2: Alternate delay + case 0x12: // SFX: Play Sound Effect xxxx + msgEntry.msg += rawData[msgPtr + 1]; + msgEntry.msg += rawData[msgPtr + 2]; + msgPtr += 2; + break; + case 0x15: // Background + msgEntry.msg += rawData[msgPtr + 1]; + msgEntry.msg += rawData[msgPtr + 2]; + msgEntry.msg += rawData[msgPtr + 3]; + msgPtr += 3; + break; + } + + msgPtr++; + c = rawData[msgPtr]; + } + } else { // NES + // NES has a header with extra information, parse that and move the ptr forward + msgEntry.textboxType = (rawData[msgPtr + 0]); + msgEntry.textboxYPos = (rawData[msgPtr + 1]); + msgEntry.icon = (rawData[msgPtr + 2]); + msgEntry.nextMessageID = BitConverter::ToInt16BE(rawData, msgPtr + 3); + msgEntry.firstItemCost = BitConverter::ToInt16BE(rawData, msgPtr + 5); + msgEntry.secondItemCost = BitConverter::ToInt16BE(rawData, msgPtr + 7); - unsigned char c = rawData[msgPtr]; + msgPtr += 11; - // Read until end marker (0xBF) - while (true) { - msgEntry.msg += c; + unsigned char c = rawData[msgPtr]; - if (c == 0xBF) { // End marker - break; - } + // Read until end marker (0xBF) + while (true) { + msgEntry.msg += c; - switch (c) { - case 0x14: // Print: xx Spaces - msgEntry.msg += rawData[msgPtr + 1]; - msgPtr++; - break; - case 0x1B: // Delay for xxxx Before Printing Remaining Text - case 0x1C: // Keep Text on Screen for xxxx Before Closing - case 0x1D: // Delay for xxxx Before Ending Conversation - case 0x1E: // Play Sound Effect xxxx - case 0x1F: // Delay for xxxx Before Resuming Text Flow - msgEntry.msg += rawData[msgPtr + 1]; - msgEntry.msg += rawData[msgPtr + 2]; - msgPtr += 2; + if (c == 0xBF) { // End marker break; + } + + switch (c) { + case 0x14: // Shift: Print xx Spaces + msgEntry.msg += rawData[msgPtr + 1]; + msgPtr++; + break; + case 0x1B: // Box Break Delay: Delay for xxxx Before Printing Remaining Text + case 0x1C: // Fade: Keep Text on Screen for xxxx Before Closing + case 0x1D: // Fade Skippable: Delay for xxxx Before Ending Conversation + case 0x1E: // SFX: Play Sound Effect xxxx + case 0x1F: // Delay: Delay for xxxx Before Resuming Text Flow + msgEntry.msg += rawData[msgPtr + 1]; + msgEntry.msg += rawData[msgPtr + 2]; + msgPtr += 2; + break; + } + + msgPtr++; + c = rawData[msgPtr]; } - - msgPtr++; - c = rawData[msgPtr]; } messages.push_back(msgEntry);