From 18d6c501fc8f1af50e0e945406233af7ae94a75a Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 5 Oct 2016 10:47:22 +0300 Subject: CHEWY: Add support for in-game texts --- engines/chewy/console.cpp | 22 ++++++++++++++-- engines/chewy/console.h | 1 + engines/chewy/resource.cpp | 1 - engines/chewy/text.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++---- engines/chewy/text.h | 32 ++++++++++++++--------- 5 files changed, 99 insertions(+), 20 deletions(-) diff --git a/engines/chewy/console.cpp b/engines/chewy/console.cpp index 7fefe45ad0..cb2d5e21c1 100644 --- a/engines/chewy/console.cpp +++ b/engines/chewy/console.cpp @@ -42,6 +42,7 @@ Console::Console(ChewyEngine *vm) : GUI::Debugger(), _vm(vm) { registerCmd("video_info", WRAP_METHOD(Console, Cmd_VideoInfo)); registerCmd("error_message", WRAP_METHOD(Console, Cmd_ErrorMessage)); registerCmd("dialog", WRAP_METHOD(Console, Cmd_Dialog)); + registerCmd("text", WRAP_METHOD(Console, Cmd_Text)); } Console::~Console() { @@ -205,9 +206,9 @@ bool Console::Cmd_Dialog(int argc, const char **argv) { int dialogNum = atoi(argv[1]); int entryNum = atoi(argv[2]); uint cur = 0; - DialogList *d = _vm->_text->getDialog(dialogNum, entryNum); + TextEntryList *d = _vm->_text->getDialog(dialogNum, entryNum); - for (DialogList::iterator it = d->begin(); it != d->end(); ++it) { + for (TextEntryList::iterator it = d->begin(); it != d->end(); ++it) { this->debugPrintf("Entry %d: speech %d, text '%s'\n", cur, (*it).speechId, (*it).text.c_str()); } @@ -217,4 +218,21 @@ bool Console::Cmd_Dialog(int argc, const char **argv) { return true; } +bool Console::Cmd_Text(int argc, const char **argv) { + if (argc < 3) { + debugPrintf("Usage: text \n"); + return true; + } + + int dialogNum = atoi(argv[1]); + int entryNum = atoi(argv[2]); + TextEntry *d = _vm->_text->getText(dialogNum, entryNum); + + debugPrintf("Speech %d, text '%s'\n", d->speechId, d->text.c_str()); + + delete d; + + return true; +} + } // End of namespace Chewy diff --git a/engines/chewy/console.h b/engines/chewy/console.h index 122f79cf51..4953480644 100644 --- a/engines/chewy/console.h +++ b/engines/chewy/console.h @@ -47,6 +47,7 @@ private: bool Cmd_VideoInfo(int argc, const char **argv); bool Cmd_ErrorMessage(int argc, const char **argv); bool Cmd_Dialog(int argc, const char **argv); + bool Cmd_Text(int argc, const char **argv); }; } // End of namespace Chewy diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp index 07af79825c..c1164f193b 100644 --- a/engines/chewy/resource.cpp +++ b/engines/chewy/resource.cpp @@ -40,7 +40,6 @@ namespace Chewy { // misc/inventar.iib // misc/inventar.sib // room/test.rdi -// txt/atds.tap (game texts) // txt/diah.adh // txt/inv_st.s and txt/room_st.s (inventory/room control bytes) // txt/inv_use.idx diff --git a/engines/chewy/text.cpp b/engines/chewy/text.cpp index da7b2279f4..e877b99f83 100644 --- a/engines/chewy/text.cpp +++ b/engines/chewy/text.cpp @@ -34,11 +34,11 @@ Text::Text() : Resource("atds.tap") { Text::~Text() { } -DialogList *Text::getDialog(uint dialogNum, uint entryNum) { - DialogList *l = new DialogList(); - +TextEntryList *Text::getDialog(uint dialogNum, uint entryNum) { if (dialogNum >= kADSTextMax) - error("getDialog(): Invalid entry number requested, %d (max %d)", dialogNum, kADSTextMax); + error("getDialog(): Invalid entry number requested, %d (max %d)", dialogNum, kADSTextMax - 1); + + TextEntryList *l = new TextEntryList(); byte *data = getChunkData(dialogNum); byte *ptr = data; @@ -51,7 +51,7 @@ DialogList *Text::getDialog(uint dialogNum, uint entryNum) { for (uint i = 0; i <= entryNum; i++) { do { - Dialog curDialog; + TextEntry curDialog; ptr++; // current entry ptr += 2; curDialog.speechId = READ_LE_UINT16(ptr) - VOICE_OFFSET; ptr += 2; @@ -81,6 +81,59 @@ DialogList *Text::getDialog(uint dialogNum, uint entryNum) { return l; } +TextEntry *Text::getText(uint dialogNum, uint entryNum) { + if (dialogNum < kADSTextMax) + error("getText(): Invalid entry number requested, %d (min %d)", dialogNum, kADSTextMax); + + TextEntry *d = new TextEntry(); + bool isText = (dialogNum >= kADSTextMax && dialogNum < kADSTextMax + kATSTextMax); + bool isAutoDialog = (dialogNum >= kADSTextMax + kATSTextMax && dialogNum < kADSTextMax + kATSTextMax + kAADTextMax); + //bool isInvText = (dialogNum >= kADSTextMax + kATSTextMax + kAADTextMax && dialogNum < kADSTextMax + kATSTextMax + kAADTextMax + kINVTextMax); + + byte *data = getChunkData(dialogNum); + byte *ptr = data; + + if (isAutoDialog) + ptr += 3; + + for (uint i = 0; i <= entryNum; i++) { + ptr += 13; + d->speechId = READ_LE_UINT16(ptr) - VOICE_OFFSET; ptr += 2; + + do { + if (i == entryNum) + d->text += *ptr++; + else + ptr++; + + if (*ptr == 0 && *(ptr + 1) != kEndText) { + // TODO: Split lines + *ptr = ' '; + } + } while (*ptr); + + if (*(ptr + 1) != kEndText || *(ptr + 2) != kEndChunk) + error("Invalid text resource - %d", dialogNum); + + if (!isText) + ptr += 3; // 0, kEndText, kEndChunk + if (isAutoDialog) + ptr += 3; + + if (i == entryNum) { + // Found + delete[] data; + return d; + } + } + + // Not found + delete[] data; + delete d; + + return nullptr; +} + Font::Font(Common::String filename) { const uint32 headerFont = MKTAG('T', 'F', 'F', '\0'); Common::File stream; diff --git a/engines/chewy/text.h b/engines/chewy/text.h index fe3e1da8b9..f729205a93 100644 --- a/engines/chewy/text.h +++ b/engines/chewy/text.h @@ -38,11 +38,11 @@ namespace Chewy { * USE - use action texts, 100 entries max */ enum MaxTextTypes { - kADSTextMax = 500, - kATSTextMax = 100, - kAADTextMax = 100, - kINVTextMax = 100, - kUSETextMax = 100 + kADSTextMax = 500, // 0 - 499 + kATSTextMax = 100, // 500 - 599 + kAADTextMax = 100, // 600 - 699 + kINVTextMax = 100, // 700 - 799 + kUSETextMax = 100 // 800 - 899 }; /** @@ -59,12 +59,12 @@ enum TextEntryMarkers { #define VOICE_OFFSET 20 -struct Dialog { +struct TextEntry { uint16 speechId; Common::String text; }; -typedef Common::List DialogList; +typedef Common::List TextEntryList; class Text : public Resource { @@ -72,11 +72,19 @@ public: Text(); virtual ~Text(); - DialogList *getDialog(uint dialogNum, uint entryNum); - // TODO: getText() - // TODO: getAutoDialog() - // TODO: getInvDesc() - // TODO: getUseText() + /** + * Gets a list of lines for a specific dialog entry + */ + TextEntryList *getDialog(uint dialogNum, uint entryNum); + + /** + * Gets a line of text of the following types: + * - text (ATS) - 500 - 599 + * - auto dialog (AAD) - 600 - 699 + * - inventory text (INV) - 700 - 799 + * - use text (USE) - 800 - 899 + */ + TextEntry *getText(uint dialogNum, uint entryNum); }; class ErrorMessage : public Resource { -- cgit v1.2.3