From 2846ce14f35afc029fe058b3ed50c229ef856615 Mon Sep 17 00:00:00 2001 From: Arnaud Boutonné Date: Tue, 25 Jan 2011 00:32:48 +0000 Subject: HUGO: Move text arrays to a separate class svn-id: r55507 --- dists/engine-data/hugo.dat | Bin 189600 -> 189600 bytes engines/hugo/file.cpp | 11 +- engines/hugo/file_v1d.cpp | 9 +- engines/hugo/file_v2d.cpp | 3 +- engines/hugo/file_v3d.cpp | 5 +- engines/hugo/hugo.cpp | 186 ++------------------------------- engines/hugo/hugo.h | 20 +--- engines/hugo/intro.cpp | 13 +-- engines/hugo/module.mk | 1 + engines/hugo/mouse.cpp | 11 +- engines/hugo/object.cpp | 27 ++--- engines/hugo/parser.cpp | 33 +++--- engines/hugo/parser_v1d.cpp | 77 +++++++------- engines/hugo/parser_v1w.cpp | 23 ++-- engines/hugo/parser_v2d.cpp | 19 ++-- engines/hugo/parser_v3d.cpp | 81 +++++++------- engines/hugo/schedule.cpp | 13 +-- engines/hugo/sound.cpp | 3 +- engines/hugo/text.cpp | 215 ++++++++++++++++++++++++++++++++++++++ engines/hugo/text.h | 75 +++++++++++++ engines/hugo/util.cpp | 3 +- tools/create_hugo/create_hugo.cpp | 40 +++---- tools/create_hugo/create_hugo.h | 2 +- 23 files changed, 498 insertions(+), 372 deletions(-) create mode 100644 engines/hugo/text.cpp create mode 100644 engines/hugo/text.h diff --git a/dists/engine-data/hugo.dat b/dists/engine-data/hugo.dat index 902dcfa1f0..c404a1b456 100644 Binary files a/dists/engine-data/hugo.dat and b/dists/engine-data/hugo.dat differ diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index 086c13e70a..effa00001b 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -42,6 +42,7 @@ #include "hugo/display.h" #include "hugo/util.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { FileManager::FileManager(HugoEngine *vm) : _vm(vm) { @@ -170,10 +171,10 @@ void FileManager::readImage(int objNum, object_t *objPtr) { _objectsArchive.seek(objBlock.objOffset, SEEK_SET); } else { char *buf = (char *) malloc(2048 + 1); // Buffer for file access - strcat(strcat(strcpy(buf, _vm->_picDir), _vm->_arrayNouns[objPtr->nounIndex][0]), ".PIX"); + strcat(strcat(strcpy(buf, _vm->_picDir), _vm->_text->getNoun(objPtr->nounIndex, 0)), ".PIX"); if (!_objectsArchive.open(buf)) { - warning("File %s not found, trying again with %s%s", buf, _vm->_arrayNouns[objPtr->nounIndex][0], ".PIX"); - strcat(strcpy(buf, _vm->_arrayNouns[objPtr->nounIndex][0]), ".PIX"); + warning("File %s not found, trying again with %s%s", buf, _vm->_text->getNoun(objPtr->nounIndex, 0), ".PIX"); + strcat(strcpy(buf, _vm->_text->getNoun(objPtr->nounIndex, 0)), ".PIX"); if (!_objectsArchive.open(buf)) error("File not found: %s", buf); } @@ -188,12 +189,12 @@ void FileManager::readImage(int objNum, object_t *objPtr) { for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image if (k == 0) { // First image // Read this image - allocate both seq and image memory - seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]); + seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_text->getNoun(objPtr->nounIndex, 0)); objPtr->seqList[j].seqPtr = seqPtr; firstFl = false; } else { // Subsequent image // Read this image - allocate both seq and image memory - seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]); + seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_text->getNoun(objPtr->nounIndex, 0)); seqPtr = seqPtr->nextSeqPtr; } diff --git a/engines/hugo/file_v1d.cpp b/engines/hugo/file_v1d.cpp index 49543eea49..4ed3ec3bd8 100644 --- a/engines/hugo/file_v1d.cpp +++ b/engines/hugo/file_v1d.cpp @@ -35,6 +35,7 @@ #include "hugo/hugo.h" #include "hugo/file.h" #include "hugo/display.h" +#include "hugo/text.h" #include "hugo/util.h" namespace Hugo { @@ -61,7 +62,7 @@ void FileManager_v1d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy const char *ovl_ext[] = {".b", ".o", ".ob"}; char *buf = (char *) malloc(2048 + 1); // Buffer for file access - strcat(strcpy(buf, _vm->_screenNames[screenNum]), ovl_ext[overlayType]); + strcat(strcpy(buf, _vm->_text->getScreenNames(screenNum)), ovl_ext[overlayType]); if (!fileExists(buf)) { for (int i = 0; i < kOvlSize; i++) @@ -87,12 +88,12 @@ void FileManager_v1d::readBackground(int screenIndex) { debugC(1, kDebugFile, "readBackground(%d)", screenIndex); char *buf = (char *) malloc(2048 + 1); // Buffer for file access - strcat(strcpy(buf, _vm->_screenNames[screenIndex]), ".ART"); + strcat(strcpy(buf, _vm->_text->getScreenNames(screenIndex)), ".ART"); if (!_sceneryArchive1.open(buf)) error("File not found: %s", buf); // Read the image into dummy seq and static dib_a seq_t *dummySeq; // Image sequence structure for Read_pcx - dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]); + dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); free(dummySeq); _sceneryArchive1.close(); free(buf); @@ -101,7 +102,7 @@ void FileManager_v1d::readBackground(int screenIndex) { char *FileManager_v1d::fetchString(int index) { debugC(1, kDebugFile, "fetchString(%d)", index); - return _vm->_stringtData[index]; + return _vm->_text->getStringtData(index); } /** diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp index 5dcac59742..ceff07286b 100644 --- a/engines/hugo/file_v2d.cpp +++ b/engines/hugo/file_v2d.cpp @@ -36,6 +36,7 @@ #include "hugo/file.h" #include "hugo/schedule.h" #include "hugo/display.h" +#include "hugo/text.h" #include "hugo/util.h" namespace Hugo { @@ -92,7 +93,7 @@ void FileManager_v2d::readBackground(int screenIndex) { // Read the image into dummy seq and static dib_a seq_t *dummySeq; // Image sequence structure for Read_pcx - dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]); + dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); free(dummySeq); } diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp index 45ed225c85..26d7b4e4ad 100644 --- a/engines/hugo/file_v3d.cpp +++ b/engines/hugo/file_v3d.cpp @@ -35,6 +35,7 @@ #include "hugo/hugo.h" #include "hugo/file.h" #include "hugo/display.h" +#include "hugo/text.h" #include "hugo/util.h" namespace Hugo { @@ -66,11 +67,11 @@ void FileManager_v3d::readBackground(int screenIndex) { if (screenIndex < 20) { _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET); // Read the image into dummy seq and static dib_a - dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]); + dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); } else { _sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET); // Read the image into dummy seq and static dib_a - dummySeq = readPCX(_sceneryArchive2, 0, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]); + dummySeq = readPCX(_sceneryArchive2, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); } free(dummySeq); } diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index b01ec2ee28..60b96d9275 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -42,6 +42,7 @@ #include "hugo/sound.h" #include "hugo/intro.h" #include "hugo/object.h" +#include "hugo/text.h" #include "engines/util.h" @@ -58,9 +59,8 @@ maze_t _maze; // Default to not in maze hugo_boot_t _boot; // Boot info structure file HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd), _mouseX(0), _mouseY(0), - _textData(0), _stringtData(0), _screenNames(0), _textEngine(0), _textIntro(0), _textMouse(0), _textParser(0), _textUtil(0), - _arrayNouns(0), _arrayVerbs(0), _arrayReqs(0), _hotspots(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0), - _points(0), _cmdList(0), _screenActs(0), _hero(0), _heroImage(0), _defltTunes(0), _introX(0), _introY(0), _maxInvent(0), _numBonuses(0), + _arrayReqs(0), _hotspots(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0), _points(0), _cmdList(0), + _screenActs(0), _hero(0), _heroImage(0), _defltTunes(0), _introX(0), _introY(0), _maxInvent(0), _numBonuses(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0), _screenStates(0), _score(0), _maxscore(0), _backgroundObjectsSize(0), _screenActsSize(0), _usesSize(0) @@ -84,30 +84,11 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy HugoEngine::~HugoEngine() { shutdown(); - freeTexts(_textData); - freeTexts(_stringtData); - - if (_arrayNouns) { - for (int i = 0; _arrayNouns[i]; i++) - freeTexts(_arrayNouns[i]); - free(_arrayNouns); - } - - if (_arrayVerbs) { - for (int i = 0; _arrayVerbs[i]; i++) - freeTexts(_arrayVerbs[i]); - free(_arrayVerbs); - } - - freeTexts(_screenNames); _screen->freePalette(); - freeTexts(_textEngine); - freeTexts(_textIntro); + _text->freeAllTexts(); + free(_introX); free(_introY); - freeTexts(_textMouse); - freeTexts(_textParser); - freeTexts(_textUtil); if (_arrayReqs) { for (int i = 0; _arrayReqs[i] != 0; i++) @@ -192,6 +173,7 @@ Common::Error HugoEngine::run() { _inventory = new InventoryHandler(this); _route = new Route(this); _sound = new SoundHandler(this); + _text = new TextHandler(this); _topMenu = new TopMenu(this); @@ -426,29 +408,9 @@ bool HugoEngine::loadHugoDat() { _numVariant = in.readUint16BE(); - // Read textData - _textData = loadTextsVariante(in, 0); - - // Read stringtData - // Only Hugo 1 DOS should use this array - _stringtData = loadTextsVariante(in, 0); - - // Read arrayNouns - _arrayNouns = loadTextsArray(in); - - // Read arrayVerbs - _arrayVerbs = loadTextsArray(in); - - // Read screenNames - _screenNames = loadTextsVariante(in, &_numScreens); - _screen->loadPalette(in); - // Read textEngine - _textEngine = loadTexts(in); - - // Read textIntro - _textIntro = loadTextsVariante(in, 0); + _text->loadAllTexts(in); // Read x_intro and y_intro for (int varnt = 0; varnt < _numVariant; varnt++) { @@ -469,15 +431,6 @@ bool HugoEngine::loadHugoDat() { } } - // Read textMouse - _textMouse = loadTexts(in); - - // Read textParser - _textParser = loadTexts(in); - - // Read textUtil - _textUtil = loadTextsVariante(in, 0); - // Read _arrayReqs _arrayReqs = loadLongArray(in); @@ -757,49 +710,6 @@ bool HugoEngine::loadHugoDat() { return true; } -char **HugoEngine::loadTextsVariante(Common::File &in, uint16 *arraySize) { - int numTexts; - int entryLen; - int len; - char **res = 0; - char *pos = 0; - char *posBck = 0; - - for (int varnt = 0; varnt < _numVariant; varnt++) { - numTexts = in.readUint16BE(); - entryLen = in.readUint16BE(); - pos = (char *)malloc(entryLen); - if (varnt == _gameVariant) { - if (arraySize) - *arraySize = numTexts; - res = (char **)malloc(sizeof(char *) * numTexts); - res[0] = pos; - in.read(res[0], entryLen); - res[0] += DATAALIGNMENT; - } else { - in.read(pos, entryLen); - posBck = pos; - } - - pos += DATAALIGNMENT; - - for (int i = 1; i < numTexts; i++) { - pos -= 2; - - len = READ_BE_UINT16(pos); - pos += 2 + len; - - if (varnt == _gameVariant) - res[i] = pos; - } - - if (varnt != _gameVariant) - free(posBck); - } - - return res; -} - uint16 **HugoEngine::loadLongArray(Common::File &in) { uint16 **resArray = 0; @@ -825,82 +735,6 @@ uint16 **HugoEngine::loadLongArray(Common::File &in) { return resArray; } -char ***HugoEngine::loadTextsArray(Common::File &in) { - char ***resArray = 0; - uint16 arraySize; - - for (int varnt = 0; varnt < _numVariant; varnt++) { - arraySize = in.readUint16BE(); - if (varnt == _gameVariant) { - resArray = (char ***)malloc(sizeof(char **) * (arraySize + 1)); - resArray[arraySize] = 0; - } - for (int i = 0; i < arraySize; i++) { - int numTexts = in.readUint16BE(); - int entryLen = in.readUint16BE(); - char *pos = (char *)malloc(entryLen); - char *posBck = 0; - char **res = 0; - if (varnt == _gameVariant) { - res = (char **)malloc(sizeof(char *) * numTexts); - res[0] = pos; - in.read(res[0], entryLen); - res[0] += DATAALIGNMENT; - } else { - in.read(pos, entryLen); - posBck = pos; - } - - pos += DATAALIGNMENT; - - for (int j = 0; j < numTexts; j++) { - if (varnt == _gameVariant) - res[j] = pos; - - pos -= 2; - int len = READ_BE_UINT16(pos); - pos += 2 + len; - } - - if (varnt == _gameVariant) - resArray[i] = res; - else - free(posBck); - } - } - - return resArray; -} - -char **HugoEngine::loadTexts(Common::File &in) { - int numTexts = in.readUint16BE(); - char **res = (char **)malloc(sizeof(char *) * numTexts); - int entryLen = in.readUint16BE(); - char *pos = (char *)malloc(entryLen); - - in.read(pos, entryLen); - - pos += DATAALIGNMENT; - res[0] = pos; - - for (int i = 1; i < numTexts; i++) { - pos -= 2; - int len = READ_BE_UINT16(pos); - pos += 2 + len; - res[i] = pos; - } - - return res; -} - -void HugoEngine::freeTexts(char **ptr) { - if (!ptr) - return; - - free(*ptr - DATAALIGNMENT); - free(ptr); -} - /** * Sets the playlist to be the default tune selection */ @@ -1198,10 +1032,10 @@ char *HugoEngine::useBG(char *name) { objectList_t p = _backgroundObjects[*_screen_p]; for (int i = 0; p[i].verbIndex != 0; i++) { - if ((name == _arrayNouns[p[i].nounIndex][0] && + if ((name == _text->getNoun(p[i].nounIndex, 0) && p[i].verbIndex != _look) && ((p[i].roomState == kStateDontCare) || (p[i].roomState == _screenStates[*_screen_p]))) - return _arrayVerbs[p[i].verbIndex][0]; + return _text->getVerb(p[i].verbIndex, 0); } return 0; @@ -1285,7 +1119,7 @@ void HugoEngine::endGame() { debugC(1, kDebugEngine, "endGame"); if (!_boot.registered) - Utils::Box(kBoxAny, "%s", _textEngine[kEsAdvertise]); + Utils::Box(kBoxAny, "%s", _text->getTextEngine(kEsAdvertise)); Utils::Box(kBoxAny, "%s\n%s", _episode, getCopyrightString()); _status.viewState = kViewExit; } diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index ee4f331458..13ef74fe3a 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -36,7 +36,7 @@ #include "hugo/file.h" #define HUGO_DAT_VER_MAJ 0 // 1 byte -#define HUGO_DAT_VER_MIN 40 // 1 byte +#define HUGO_DAT_VER_MIN 41 // 1 byte #define DATAALIGNMENT 4 namespace Common { @@ -246,7 +246,7 @@ class Route; class SoundHandler; class IntroHandler; class ObjectHandler; - +class TextHandler; class HugoEngine : public Engine { public: @@ -272,16 +272,6 @@ public: byte *_introX; byte *_introY; byte *_screenStates; - char **_textData; - char **_stringtData; - char **_screenNames; - char **_textEngine; - char **_textIntro; - char **_textMouse; - char **_textParser; - char **_textUtil; - char ***_arrayNouns; - char ***_arrayVerbs; command_t _line; // Line of user text input config_t _config; // User's config uint16 **_arrayReqs; @@ -418,6 +408,7 @@ public: SoundHandler *_sound; IntroHandler *_intro; ObjectHandler *_object; + TextHandler *_text; TopMenu *_topMenu; @@ -457,13 +448,8 @@ private: int _score; // Holds current score int _maxscore; // Holds maximum score - char **loadTextsVariante(Common::File &in, uint16 *arraySize); - char ***loadTextsArray(Common::File &in); - char **loadTexts(Common::File &in); - uint16 **loadLongArray(Common::File &in); - void freeTexts(char **ptr); void initPlaylist(bool playlist[kMaxTunes]); void initConfig(); void initialize(); diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp index 54dfa37e00..bc9f2d1394 100644 --- a/engines/hugo/intro.cpp +++ b/engines/hugo/intro.cpp @@ -37,6 +37,7 @@ #include "hugo/util.h" #include "hugo/display.h" #include "hugo/sound.h" +#include "hugo/text.h" namespace Hugo { @@ -299,13 +300,13 @@ bool intro_v3d::introPlay() { // Text boxes at various times switch (introTicks) { case 4: - Utils::Box(kBoxOk, "%s", _vm->_textIntro[kIntro1]); + Utils::Box(kBoxOk, "%s", _vm->_text->getTextIntro(kIntro1)); break; case 9: - Utils::Box(kBoxOk, "%s", _vm->_textIntro[kIntro2]); + Utils::Box(kBoxOk, "%s", _vm->_text->getTextIntro(kIntro2)); break; case 35: - Utils::Box(kBoxOk, "%s", _vm->_textIntro[kIntro3]); + Utils::Box(kBoxOk, "%s", _vm->_text->getTextIntro(kIntro3)); break; } } @@ -392,13 +393,13 @@ bool intro_v3w::introPlay() { // Text boxes at various times switch (introTicks) { case 4: - Utils::Box(kBoxOk, "%s", _vm->_textIntro[kIntro1]); + Utils::Box(kBoxOk, "%s", _vm->_text->getTextIntro(kIntro1)); break; case 9: - Utils::Box(kBoxOk, "%s", _vm->_textIntro[kIntro2]); + Utils::Box(kBoxOk, "%s", _vm->_text->getTextIntro(kIntro2)); break; case 35: - Utils::Box(kBoxOk, "%s", _vm->_textIntro[kIntro3]); + Utils::Box(kBoxOk, "%s", _vm->_text->getTextIntro(kIntro3)); break; } } diff --git a/engines/hugo/module.mk b/engines/hugo/module.mk index ab64116ec7..3a1ceded73 100644 --- a/engines/hugo/module.mk +++ b/engines/hugo/module.mk @@ -28,6 +28,7 @@ MODULE_OBJS := \ route.o \ schedule.o \ sound.o \ + text.o \ util.o # This module can be built as a plugin diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index 3d023b46e1..298ab4e26e 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -43,6 +43,7 @@ #include "hugo/route.h" #include "hugo/util.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { @@ -129,7 +130,7 @@ void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) { if (_vm->_hero->cycling == kCycleInvisible) // If invisible do _vm->_object->useObject(objId); // immediate use else - Utils::Box(kBoxAny, "%s", _vm->_textMouse[kMsNoWayText]); // Can't get there + Utils::Box(kBoxAny, "%s", _vm->_text->getTextMouse(kMsNoWayText)); // Can't get there } break; } @@ -183,7 +184,7 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) { else if (_vm->_hotspots[i].direction == Common::KEYCODE_LEFT) x += kHeroMaxWidth; if (!_vm->_route->startRoute(kRouteExit, i, x, y)) - Utils::Box(kBoxAny, "%s", _vm->_textMouse[kMsNoWayText]); // Can't get there + Utils::Box(kBoxAny, "%s", _vm->_text->getTextMouse(kMsNoWayText)); // Can't get there } // Get rid of any attached icon @@ -213,7 +214,7 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) { if (_vm->_hero->cycling == kCycleInvisible) // If invisible do _vm->_object->lookObject(obj); // immediate decription else - Utils::Box(kBoxAny, "%s", _vm->_textMouse[kMsNoWayText]); // Can't get there + Utils::Box(kBoxAny, "%s", _vm->_text->getTextMouse(kMsNoWayText)); // Can't get there } break; } @@ -260,7 +261,7 @@ void MouseHandler::mouseHandler() { if (objId >= 0) { // Got a match // Display object name next to cursor (unless CURSOR_NOCHAR) // Note test for swapped hero name - char *name = _vm->_arrayNouns[_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId].nounIndex][kCursorNameIndex]; + char *name = _vm->_text->getNoun(_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId].nounIndex, kCursorNameIndex); if (name[0] != kCursorNochar) cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE); @@ -274,7 +275,7 @@ void MouseHandler::mouseHandler() { int i = findExit(cx, cy); if (i != -1 && _vm->_hotspots[i].viewx >= 0) { objId = kExitHotspot; - cursorText(_vm->_textMouse[kMsExit], cx, cy, U_FONT8, _TBRIGHTWHITE); + cursorText(_vm->_text->getTextMouse(kMsExit), cx, cy, U_FONT8, _TBRIGHTWHITE); } } } diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp index 18306c8808..2f14df7b55 100644 --- a/engines/hugo/object.cpp +++ b/engines/hugo/object.cpp @@ -42,6 +42,7 @@ #include "hugo/util.h" #include "hugo/parser.h" #include "hugo/schedule.h" +#include "hugo/text.h" namespace Hugo { @@ -98,19 +99,19 @@ void ObjectHandler::useObject(int16 objId) { if (_vm->getGameStatus().inventoryObjId == -1) { // Get or use objid directly if ((obj->genericCmd & TAKE) || obj->objValue) // Get collectible item - sprintf(_vm->_line, "%s %s", _vm->_arrayVerbs[_vm->_take][0], _vm->_arrayNouns[obj->nounIndex][0]); + sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->nounIndex, 0)); else if (obj->cmdIndex != 0) // Use non-collectible item if able - sprintf(_vm->_line, "%s %s", _vm->_arrayVerbs[_vm->_cmdList[obj->cmdIndex][0].verbIndex][0], _vm->_arrayNouns[obj->nounIndex][0]); - else if ((verb = _vm->useBG(_vm->_arrayNouns[obj->nounIndex][0])) != 0) - sprintf(_vm->_line, "%s %s", verb, _vm->_arrayNouns[obj->nounIndex][0]); + sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_cmdList[obj->cmdIndex][0].verbIndex, 0), _vm->_text->getNoun(obj->nounIndex, 0)); + else if ((verb = _vm->useBG(_vm->_text->getNoun(obj->nounIndex, 0))) != 0) + sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->nounIndex, 0)); else return; // Can't use object directly } else { // Use status.objid on objid // Default to first cmd verb - sprintf(_vm->_line, "%s %s %s", _vm->_arrayVerbs[_vm->_cmdList[_objects[_vm->getGameStatus().inventoryObjId].cmdIndex][0].verbIndex][0], - _vm->_arrayNouns[_objects[_vm->getGameStatus().inventoryObjId].nounIndex][0], - _vm->_arrayNouns[obj->nounIndex][0]); + sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_cmdList[_objects[_vm->getGameStatus().inventoryObjId].cmdIndex][0].verbIndex, 0), + _vm->_text->getNoun(_objects[_vm->getGameStatus().inventoryObjId].nounIndex, 0), + _vm->_text->getNoun(obj->nounIndex, 0)); // Check valid use of objects and override verb if necessary for (uses_t *use = _vm->_uses; use->objId != _numObj; use++) { @@ -121,9 +122,9 @@ void ObjectHandler::useObject(int16 objId) { for (target_t *target = use->targets; target->nounIndex != 0; target++) if (target->nounIndex == obj->nounIndex) { foundFl = true; - sprintf(_vm->_line, "%s %s %s", _vm->_arrayVerbs[target->verbIndex][0], - _vm->_arrayNouns[_objects[_vm->getGameStatus().inventoryObjId].nounIndex][0], - _vm->_arrayNouns[obj->nounIndex][0]); + sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->verbIndex, 0), + _vm->_text->getNoun(_objects[_vm->getGameStatus().inventoryObjId].nounIndex, 0), + _vm->_text->getNoun(obj->nounIndex, 0)); } // No valid use of objects found, print failure string @@ -131,7 +132,7 @@ void ObjectHandler::useObject(int16 objId) { // Deselect dragged icon if inventory not active if (_vm->getGameStatus().inventoryState != kInventoryActive) _vm->_screen->resetInventoryObjId(); - Utils::Box(kBoxAny, "%s", _vm->_textData[use->dataIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(use->dataIndex)); return; } } @@ -200,7 +201,7 @@ void ObjectHandler::lookObject(object_t *obj) { // Hero swapped - look at other obj = &_objects[_vm->_heroImage]; - _vm->_parser->command("%s %s", _vm->_arrayVerbs[_vm->_look][0], _vm->_arrayNouns[obj->nounIndex][0]); + _vm->_parser->command("%s %s", _vm->_text->getVerb(_vm->_look, 0), _vm->_text->getNoun(obj->nounIndex, 0)); } /** @@ -297,7 +298,7 @@ void ObjectHandler::showTakeables() { if ((obj->cycling != kCycleInvisible) && (obj->screenIndex == *_vm->_screen_p) && (((TAKE & obj->genericCmd) == TAKE) || obj->objValue)) { - Utils::Box(kBoxAny, "You can also see:\n%s.", _vm->_arrayNouns[obj->nounIndex][LOOK_NAME]); + Utils::Box(kBoxAny, "You can also see:\n%s.", _vm->_text->getNoun(obj->nounIndex, LOOK_NAME)); } } } diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp index 98d85b888b..10a328de51 100644 --- a/engines/hugo/parser.cpp +++ b/engines/hugo/parser.cpp @@ -42,6 +42,7 @@ #include "hugo/route.h" #include "hugo/sound.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { @@ -304,10 +305,10 @@ bool Parser::isWordPresent(char **wordArr) { char *Parser::findNoun() { debugC(1, kDebugParser, "findNoun()"); - for (int i = 0; _vm->_arrayNouns[i]; i++) { - for (int j = 0; strlen(_vm->_arrayNouns[i][j]); j++) { - if (strstr(_vm->_line, _vm->_arrayNouns[i][j])) - return _vm->_arrayNouns[i][0]; + for (int i = 0; _vm->_text->getNounArray(i); i++) { + for (int j = 0; strlen(_vm->_text->getNoun(i, j)); j++) { + if (strstr(_vm->_line, _vm->_text->getNoun(i, j))) + return _vm->_text->getNoun(i, 0); } } return 0; @@ -319,10 +320,10 @@ char *Parser::findNoun() { char *Parser::findVerb() { debugC(1, kDebugParser, "findVerb()"); - for (int i = 0; _vm->_arrayVerbs[i]; i++) { - for (int j = 0; strlen(_vm->_arrayVerbs[i][j]); j++) { - if (strstr(_vm->_line, _vm->_arrayVerbs[i][j])) - return _vm->_arrayVerbs[i][0]; + for (int i = 0; _vm->_text->getVerbArray(i); i++) { + for (int j = 0; strlen(_vm->_text->getVerb(i, j)); j++) { + if (strstr(_vm->_line, _vm->_text->getVerb(i, j))) + return _vm->_text->getVerb(i, 0); } } return 0; @@ -338,7 +339,7 @@ void Parser::showDosInventory() { for (int i = 0; i < _vm->_object->_numObj; i++) { // Find widths of 2 columns if (_vm->_object->isCarried(i)) { - uint16 len = strlen(_vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]); + uint16 len = strlen(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 1)); if (index++ & 1) // Right hand column len2 = (len > len2) ? len : len2; else @@ -347,24 +348,24 @@ void Parser::showDosInventory() { } len1 += 1; // For gap between columns - if (len1 + len2 < (uint16)strlen(_vm->_textParser[kTBOutro])) - len1 = strlen(_vm->_textParser[kTBOutro]); + if (len1 + len2 < (uint16)strlen(_vm->_text->getTextParser(kTBOutro))) + len1 = strlen(_vm->_text->getTextParser(kTBOutro)); char buffer[kCompLineSize * kMaxTextRows] = "\0"; - strncat(buffer, blanks, (len1 + len2 - strlen(_vm->_textParser[kTBIntro])) / 2); - strcat(strcat(buffer, _vm->_textParser[kTBIntro]), "\n"); + strncat(buffer, blanks, (len1 + len2 - strlen(_vm->_text->getTextParser(kTBIntro))) / 2); + strcat(strcat(buffer, _vm->_text->getTextParser(kTBIntro)), "\n"); index = 0; for (int i = 0; i < _vm->_object->_numObj; i++) { // Assign strings if (_vm->_object->isCarried(i)) { if (index++ & 1) - strcat(strcat(buffer, _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]), "\n"); + strcat(strcat(buffer, _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 1)), "\n"); else - strncat(strcat(buffer, _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]), blanks, len1 - strlen(_vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1])); + strncat(strcat(buffer, _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 1)), blanks, len1 - strlen(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 1))); } } if (index & 1) strcat(buffer, "\n"); - strcat(buffer, _vm->_textParser[kTBOutro]); + strcat(buffer, _vm->_text->getTextParser(kTBOutro)); Utils::Box(kBoxAny, "%s", buffer); } diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp index 5d78a3d8be..6cde8af2ff 100644 --- a/engines/hugo/parser_v1d.cpp +++ b/engines/hugo/parser_v1d.cpp @@ -41,6 +41,7 @@ #include "hugo/util.h" #include "hugo/sound.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { @@ -59,15 +60,15 @@ char *Parser_v1d::findNextNoun(char *noun) { int currNounIndex = -1; if (noun) { // If noun not NULL, find index - for (currNounIndex = 0; _vm->_arrayNouns[currNounIndex]; currNounIndex++) { - if (noun == _vm->_arrayNouns[currNounIndex][0]) + for (currNounIndex = 0; _vm->_text->getNounArray(currNounIndex); currNounIndex++) { + if (noun == _vm->_text->getNoun(currNounIndex, 0)) break; } } - for (int i = currNounIndex + 1; _vm->_arrayNouns[i]; i++) { - for (int j = 0; strlen(_vm->_arrayNouns[i][j]); j++) { - if (strstr(_vm->_line, _vm->_arrayNouns[i][j])) - return _vm->_arrayNouns[i][0]; + for (int i = currNounIndex + 1; _vm->_text->getNounArray(i); i++) { + for (int j = 0; strlen(_vm->_text->getNoun(i, j)); j++) { + if (strstr(_vm->_line, _vm->_text->getNoun(i, j))) + return _vm->_text->getNoun(i, 0); } } return 0; @@ -84,19 +85,19 @@ bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) { if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive return false; - } else if (noun && (noun != _vm->_arrayNouns[obj->nounIndex][0])) { // Noun specified & not same as object + } else if (noun && (noun != _vm->_text->getNoun(obj->nounIndex, 0))) { // Noun specified & not same as object return false; } else if (obj->carriedFl) { // Object is being carried return true; } else if (obj->screenIndex != *_vm->_screen_p) { // Not in same screen if (obj->objValue) - strcpy (comment, _vm->_textParser[kCmtAny4]); + strcpy (comment, _vm->_text->getTextParser(kCmtAny4)); return false; } if (obj->cycling == kCycleInvisible) { if (obj->seqNumb) { // There is an image - strcpy(comment, _vm->_textParser[kCmtAny5]); + strcpy(comment, _vm->_text->getTextParser(kCmtAny5)); return false; } else { // No image, assume visible if ((obj->radius < 0) || @@ -107,10 +108,10 @@ bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) { // User is either not close enough (stationary, valueless objects) // or is not carrying it (small, portable objects of value) if (noun) { // Don't say unless object specified - if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0])) - strcpy(comment, _vm->_textParser[kCmtAny4]); + if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + strcpy(comment, _vm->_text->getTextParser(kCmtAny4)); else - strcpy(comment, _vm->_textParser[kCmtClose]); + strcpy(comment, _vm->_text->getTextParser(kCmtClose)); } return false; } @@ -125,10 +126,10 @@ bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) { // User is either not close enough (stationary, valueless objects) // or is not carrying it (small, portable objects of value) if (noun) { // Don't say unless object specified - if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0])) - strcpy(comment, _vm->_textParser[kCmtAny4]); + if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + strcpy(comment, _vm->_text->getTextParser(kCmtAny4)); else - strcpy(comment, _vm->_textParser[kCmtClose]); + strcpy(comment, _vm->_text->getTextParser(kCmtClose)); } return false; } @@ -148,27 +149,27 @@ bool Parser_v1d::isGenericVerb(char *word, object_t *obj) { return false; // Following is equivalent to switch, but couldn't do one - if (word == _vm->_arrayVerbs[_vm->_look][0]) { + if (word == _vm->_text->getVerb(_vm->_look, 0)) { if ((LOOK & obj->genericCmd) == LOOK) - Utils::Box(kBoxAny, "%s", _vm->_textData[obj->dataIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(obj->dataIndex)); else - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBUnusual_1d]); - } else if (word == _vm->_arrayVerbs[_vm->_take][0]) { + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBUnusual_1d)); + } else if (word == _vm->_text->getVerb(_vm->_take, 0)) { if (obj->carriedFl) - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBHave]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBHave)); else if ((TAKE & obj->genericCmd) == TAKE) takeObject(obj); else if (!obj->verbOnlyFl) // Make sure not taking object in context! - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoUse]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoUse)); else return false; - } else if (word == _vm->_arrayVerbs[_vm->_drop][0]) { + } else if (word == _vm->_text->getVerb(_vm->_drop, 0)) { if (!obj->carriedFl) - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBDontHave]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBDontHave)); else if ((DROP & obj->genericCmd) == DROP) dropObject(obj); else - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNeed]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNeed)); } else { // It was not a generic cmd return false; } @@ -192,7 +193,7 @@ bool Parser_v1d::isObjectVerb(char *word, object_t *obj) { int i; for (i = 0; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd - if (!strcmp(word, _vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex][0])) // Is this verb catered for? + if (!strcmp(word, _vm->_text->getVerb(_vm->_cmdList[cmdIndex][i].verbIndex, 0))) // Is this verb catered for? break; } @@ -205,7 +206,7 @@ bool Parser_v1d::isObjectVerb(char *word, object_t *obj) { uint16 *reqs = _vm->_arrayReqs[cmnd->reqIndex]; // ptr to list of required objects for (i = 0; reqs[i]; i++) { // for each obj if (!_vm->_object->isCarrying(reqs[i])) { - Utils::Box(kBoxAny, "%s", _vm->_textData[cmnd->textDataNoCarryIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex)); return true; } } @@ -213,17 +214,17 @@ bool Parser_v1d::isObjectVerb(char *word, object_t *obj) { // Required objects are present, now check state is correct if ((obj->state != cmnd->reqState) && (cmnd->reqState != kStateDontCare)){ - Utils::Box(kBoxAny, "%s", _vm->_textData[cmnd->textDataWrongIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataWrongIndex)); return true; } // Everything checked. Change the state and carry out any actions if (cmnd->reqState != kStateDontCare) // Don't change new state if required state didn't care obj->state = cmnd->newState; - Utils::Box(kBoxAny, "%s", _vm->_textData[cmnd->textDataDoneIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataDoneIndex)); _vm->_scheduler->insertActionList(cmnd->actIndex); // Special case if verb is Take or Drop. Assume additional generic actions - if ((word == _vm->_arrayVerbs[_vm->_take][0]) || (word == _vm->_arrayVerbs[_vm->_drop][0])) + if ((word == _vm->_text->getVerb(_vm->_take, 0)) || (word == _vm->_text->getVerb(_vm->_drop, 0))) isGenericVerb(word, obj); return true; } @@ -239,7 +240,7 @@ bool Parser_v1d::isBackgroundWord(char *noun, char *verb, objectList_t obj) { return false; for (int i = 0; obj[i].verbIndex; i++) { - if ((verb == _vm->_arrayVerbs[obj[i].verbIndex][0]) && (noun == _vm->_arrayNouns[obj[i].nounIndex][0])) { + if ((verb == _vm->_text->getVerb(obj[i].verbIndex, 0)) && (noun == _vm->_text->getNoun(obj[i].nounIndex, 0))) { Utils::Box(kBoxAny, "%s", _vm->_file->fetchString(obj[i].commentIndex)); return true; } @@ -259,7 +260,7 @@ void Parser_v1d::takeObject(object_t *obj) { _vm->adjustScore(obj->objValue); - Utils::Box(kBoxAny, TAKE_TEXT, _vm->_arrayNouns[obj->nounIndex][TAKE_NAME]); + Utils::Box(kBoxAny, TAKE_TEXT, _vm->_text->getNoun(obj->nounIndex, TAKE_NAME)); } /** @@ -275,7 +276,7 @@ void Parser_v1d::dropObject(object_t *obj) { obj->x = _vm->_hero->x - 1; obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; _vm->adjustScore(-obj->objValue); - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBOk]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBOk)); } /** @@ -289,7 +290,7 @@ bool Parser_v1d::isCatchallVerb(bool testNounFl, char *noun, char *verb, objectL return false; for (int i = 0; obj[i].verbIndex; i++) { - if ((verb == _vm->_arrayVerbs[obj[i].verbIndex][0]) && ((noun == _vm->_arrayNouns[obj[i].nounIndex][0]) || (obj[i].nounIndex == 0))) { + if ((verb == _vm->_text->getVerb(obj[i].verbIndex, 0)) && ((noun == _vm->_text->getNoun(obj[i].nounIndex, 0)) || (obj[i].nounIndex == 0))) { Utils::Box(kBoxAny, "%s", _vm->_file->fetchString(obj[i].commentIndex)); return true; } @@ -323,7 +324,7 @@ void Parser_v1d::lineHandler() { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_screenNames[i])) { + if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_text->getScreenNames(i))) { _vm->_scheduler->newScreen(i); return; } @@ -341,7 +342,7 @@ void Parser_v1d::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -351,7 +352,7 @@ void Parser_v1d::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); return; } @@ -360,7 +361,7 @@ void Parser_v1d::lineHandler() { } if (!strcmp("exit", _vm->_line) || strstr(_vm->_line, "quit")) { - if (Utils::Box(kBoxYesNo, "%s", _vm->_textParser[kTBExit_1d]) != 0) + if (Utils::Box(kBoxYesNo, "%s", _vm->_text->getTextParser(kTBExit_1d)) != 0) _vm->endGame(); return; } @@ -419,7 +420,7 @@ void Parser_v1d::lineHandler() { else if (!isCatchallVerb(true, noun, verb, _vm->_catchallList) && !isCatchallVerb(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p]) && !isCatchallVerb(false, noun, verb, _vm->_catchallList)) - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBEh_1d]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh_1d)); } void Parser_v1d::showInventory() { diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp index 8bceaeb144..40366f6f48 100644 --- a/engines/hugo/parser_v1w.cpp +++ b/engines/hugo/parser_v1w.cpp @@ -44,6 +44,7 @@ #include "hugo/util.h" #include "hugo/sound.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser_v3d(vm) { @@ -78,7 +79,7 @@ void Parser_v1w::lineHandler() { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_screenNames[i])) { + if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_text->getScreenNames(i))) { _vm->_scheduler->newScreen(i); return; } @@ -96,7 +97,7 @@ void Parser_v1w::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -106,7 +107,7 @@ void Parser_v1w::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); return; } @@ -117,7 +118,7 @@ void Parser_v1w::lineHandler() { // Special meta commands // EXIT/QUIT if (!strcmp("exit", _vm->_line) || strstr(_vm->_line, "quit")) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBExit]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBExit)); return; } @@ -151,7 +152,7 @@ void Parser_v1w::lineHandler() { // Test for nearby objects referenced explicitly for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; - if (isWordPresent(_vm->_arrayNouns[obj->nounIndex])) { + if (isWordPresent(_vm->_text->getNounArray(obj->nounIndex))) { if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment)) return; } @@ -187,17 +188,17 @@ void Parser_v1w::lineHandler() { // Nothing matches. Report recognition success to user. char *verb = findVerb(); char *noun = findNoun(); - if (verb == _vm->_arrayVerbs[_vm->_look][0] && _maze.enabledFl) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBMaze]); + if (verb == _vm->_text->getVerb(_vm->_look, 0) && _maze.enabledFl) { + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBMaze)); _vm->_object->showTakeables(); } else if (verb && noun) { // A combination I didn't think of - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoPoint]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoPoint)); } else if (noun) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoun]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoun)); } else if (verb) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBVerb]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBVerb)); } else { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBEh]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh)); } } diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp index c2a5704a49..8e38f5d0d8 100644 --- a/engines/hugo/parser_v2d.cpp +++ b/engines/hugo/parser_v2d.cpp @@ -41,6 +41,7 @@ #include "hugo/util.h" #include "hugo/sound.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { @@ -76,7 +77,7 @@ void Parser_v2d::lineHandler() { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_screenNames[i])) { + if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_text->getScreenNames(i))) { _vm->_scheduler->newScreen(i); return; } @@ -94,7 +95,7 @@ void Parser_v2d::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -104,7 +105,7 @@ void Parser_v2d::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); return; } @@ -113,7 +114,7 @@ void Parser_v2d::lineHandler() { } if (!strcmp("exit", _vm->_line) || strstr(_vm->_line, "quit")) { - if (Utils::Box(kBoxYesNo, "%s", _vm->_textParser[kTBExit_1d]) != 0) + if (Utils::Box(kBoxYesNo, "%s", _vm->_text->getTextParser(kTBExit_1d)) != 0) _vm->endGame(); else return; @@ -177,15 +178,15 @@ void Parser_v2d::lineHandler() { && !isCatchallVerb(false, noun, verb, _vm->_catchallList)) { if (*farComment != '\0') { // An object matched but not near enough Utils::Box(kBoxAny, "%s", farComment); - } else if (_maze.enabledFl && (verb == _vm->_arrayVerbs[_vm->_look][0])) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBMaze]); + } else if (_maze.enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) { + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBMaze)); _vm->_object->showTakeables(); } else if (verb && noun) { // A combination I didn't think of - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoUse_2d]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoUse_2d)); } else if (verb || noun) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoun]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoun)); } else { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBEh_2d]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh_2d)); } } } diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp index 2ab13eaed3..63508a2742 100644 --- a/engines/hugo/parser_v3d.cpp +++ b/engines/hugo/parser_v3d.cpp @@ -41,6 +41,7 @@ #include "hugo/util.h" #include "hugo/sound.h" #include "hugo/object.h" +#include "hugo/text.h" namespace Hugo { @@ -76,7 +77,7 @@ void Parser_v3d::lineHandler() { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_screenNames[i])) { + if (!scumm_stricmp(&_vm->_line[strlen("goto") + 1], _vm->_text->getScreenNames(i))) { _vm->_scheduler->newScreen(i); return; } @@ -94,7 +95,7 @@ void Parser_v3d::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -104,7 +105,7 @@ void Parser_v3d::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) { + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); return; } @@ -115,7 +116,7 @@ void Parser_v3d::lineHandler() { // Special meta commands // EXIT/QUIT if (!strcmp("exit", _vm->_line) || strstr(_vm->_line, "quit")) { - if (Utils::Box(kBoxYesNo, "%s", _vm->_textParser[kTBExit_1d]) != 0) + if (Utils::Box(kBoxYesNo, "%s", _vm->_text->getTextParser(kTBExit_1d)) != 0) _vm->endGame(); else return; @@ -156,7 +157,7 @@ void Parser_v3d::lineHandler() { // Test for nearby objects referenced explicitly for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; - if (isWordPresent(_vm->_arrayNouns[obj->nounIndex])) { + if (isWordPresent(_vm->_text->getNounArray(obj->nounIndex))) { if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment)) return; } @@ -194,13 +195,13 @@ void Parser_v3d::lineHandler() { char *noun = findNoun(); if (verb && noun) { // A combination I didn't think of - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoPoint]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoPoint)); } else if (noun) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoun]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoun)); } else if (verb) { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBVerb]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBVerb)); } else { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBEh]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh)); } } @@ -219,7 +220,7 @@ bool Parser_v3d::isObjectVerb(object_t *obj, char *comment) { int i; for (i = 0; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd - if (isWordPresent(_vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex])) // Was this verb used? + if (isWordPresent(_vm->_text->getVerbArray(_vm->_cmdList[cmdIndex][i].verbIndex))) // Was this verb used? break; } @@ -227,7 +228,7 @@ bool Parser_v3d::isObjectVerb(object_t *obj, char *comment) { return false; // Verb match found. Check if object is Near - char *verb = *_vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex]; + char *verb = *_vm->_text->getVerbArray(_vm->_cmdList[cmdIndex][i].verbIndex); if (!isNear(obj, verb, comment)) return false; @@ -237,7 +238,7 @@ bool Parser_v3d::isObjectVerb(object_t *obj, char *comment) { uint16 *reqs = _vm->_arrayReqs[cmnd->reqIndex]; // ptr to list of required objects for (i = 0; reqs[i]; i++) { // for each obj if (!_vm->_object->isCarrying(reqs[i])) { - Utils::Box(kBoxAny, "%s", _vm->_textData[cmnd->textDataNoCarryIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex)); return true; } } @@ -245,18 +246,18 @@ bool Parser_v3d::isObjectVerb(object_t *obj, char *comment) { // Required objects are present, now check state is correct if ((obj->state != cmnd->reqState) && (cmnd->reqState != kStateDontCare)) { - Utils::Box(kBoxAny, "%s", _vm->_textData[cmnd->textDataWrongIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataWrongIndex)); return true; } // Everything checked. Change the state and carry out any actions if (cmnd->reqState != kStateDontCare) // Don't change new state if required state didn't care obj->state = cmnd->newState; - Utils::Box(kBoxAny, "%s", _vm->_textData[cmnd->textDataDoneIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataDoneIndex)); _vm->_scheduler->insertActionList(cmnd->actIndex); // See if any additional generic actions - if ((verb == _vm->_arrayVerbs[_vm->_look][0]) || (verb == _vm->_arrayVerbs[_vm->_take][0]) || (verb == _vm->_arrayVerbs[_vm->_drop][0])) + if ((verb == _vm->_text->getVerb(_vm->_look, 0)) || (verb == _vm->_text->getVerb(_vm->_take, 0)) || (verb == _vm->_text->getVerb(_vm->_drop, 0))) isGenericVerb(obj, comment); return true; } @@ -271,38 +272,38 @@ bool Parser_v3d::isGenericVerb(object_t *obj, char *comment) { return false; // Following is equivalent to switch, but couldn't do one - if (isWordPresent(_vm->_arrayVerbs[_vm->_look]) && isNear(obj, _vm->_arrayVerbs[_vm->_look][0], comment)) { + if (isWordPresent(_vm->_text->getVerbArray(_vm->_look)) && isNear(obj, _vm->_text->getVerb(_vm->_look, 0), comment)) { // Test state-dependent look before general look if ((obj->genericCmd & LOOK_S) == LOOK_S) { - Utils::Box(kBoxAny, "%s", _vm->_textData[obj->stateDataIndex[obj->state]]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(obj->stateDataIndex[obj->state])); } else { if ((LOOK & obj->genericCmd) == LOOK) { if (obj->dataIndex != 0) - Utils::Box(kBoxAny, "%s", _vm->_textData[obj->dataIndex]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(obj->dataIndex)); else return false; } else { - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBUnusual]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBUnusual)); } } - } else if (isWordPresent(_vm->_arrayVerbs[_vm->_take]) && isNear(obj, _vm->_arrayVerbs[_vm->_take][0], comment)) { + } else if (isWordPresent(_vm->_text->getVerbArray(_vm->_take)) && isNear(obj, _vm->_text->getVerb(_vm->_take, 0), comment)) { if (obj->carriedFl) - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBHave]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBHave)); else if ((TAKE & obj->genericCmd) == TAKE) takeObject(obj); else if (obj->cmdIndex) // No comment if possible commands return false; else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context! - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNoUse]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNoUse)); else return false; - } else if (isWordPresent(_vm->_arrayVerbs[_vm->_drop])) { + } else if (isWordPresent(_vm->_text->getVerbArray(_vm->_drop))) { if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP)) - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBDontHave]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBDontHave)); else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP)) dropObject(obj); else if (obj->cmdIndex == 0) - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBNeed]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBNeed)); else return false; } else { // It was not a generic cmd @@ -327,16 +328,16 @@ bool Parser_v3d::isNear(object_t *obj, char *verb, char *comment) { if (obj->screenIndex != *_vm->_screen_p) { // Not in same screen if (obj->objValue) - strcpy(comment, _vm->_textParser[kCmtAny1]); + strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); else - strcpy(comment, _vm->_textParser[kCmtAny2]); + strcpy(comment, _vm->_text->getTextParser(kCmtAny2)); return false; } if (obj->cycling == kCycleInvisible) { if (obj->seqNumb) { // There is an image - strcpy(comment, _vm->_textParser[kCmtAny3]); + strcpy(comment, _vm->_text->getTextParser(kCmtAny3)); return false; } else { // No image, assume visible @@ -346,10 +347,10 @@ bool Parser_v3d::isNear(object_t *obj, char *verb, char *comment) { return true; } else { // User is not close enough - if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0])) - strcpy(comment, _vm->_textParser[kCmtAny1]); + if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); else - strcpy(comment, _vm->_textParser[kCmtClose]); + strcpy(comment, _vm->_text->getTextParser(kCmtClose)); return false; } } @@ -361,10 +362,10 @@ bool Parser_v3d::isNear(object_t *obj, char *verb, char *comment) { return true; } else { // User is not close enough - if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0])) - strcpy(comment, _vm->_textParser[kCmtAny1]); + if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); else - strcpy(comment, _vm->_textParser[kCmtClose]); + strcpy(comment, _vm->_text->getTextParser(kCmtClose)); return false; } return true; @@ -384,7 +385,7 @@ void Parser_v3d::takeObject(object_t *obj) { if (obj->seqNumb > 0) // If object has an image, force walk to dropped obj->viewx = -1; // (possibly moved) object next time taken! - Utils::Box(kBoxAny, TAKE_TEXT, _vm->_arrayNouns[obj->nounIndex][TAKE_NAME]); + Utils::Box(kBoxAny, TAKE_TEXT, _vm->_text->getNoun(obj->nounIndex, TAKE_NAME)); } /** @@ -403,7 +404,7 @@ void Parser_v3d::dropObject(object_t *obj) { obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; obj->y = (obj->y + obj->currImagePtr->y2 < kYPix) ? obj->y : kYPix - obj->currImagePtr->y2 - 10; _vm->adjustScore(-obj->objValue); - Utils::Box(kBoxAny, "%s", _vm->_textParser[kTBOk]); + Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBOk)); } /** @@ -416,7 +417,7 @@ bool Parser_v3d::isCatchallVerb(objectList_t obj) { debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)"); for (int i = 0; obj[i].verbIndex != 0; i++) { - if (isWordPresent(_vm->_arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 && + if (isWordPresent(_vm->_text->getVerbArray(obj[i].verbIndex)) && obj[i].nounIndex == 0 && (!obj[i].matchFl || !findNoun()) && ((obj[i].roomState == kStateDontCare) || (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) { @@ -424,7 +425,7 @@ bool Parser_v3d::isCatchallVerb(objectList_t obj) { _vm->_scheduler->processBonus(obj[i].bonusIndex); // If this is LOOK (without a noun), show any takeable objects - if (*(_vm->_arrayVerbs[obj[i].verbIndex]) == _vm->_arrayVerbs[_vm->_look][0]) + if (*(_vm->_text->getVerbArray(obj[i].verbIndex)) == _vm->_text->getVerb(_vm->_look, 0)) _vm->_object->showTakeables(); return true; @@ -441,8 +442,8 @@ bool Parser_v3d::isBackgroundWord(objectList_t obj) { debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)"); for (int i = 0; obj[i].verbIndex != 0; i++) { - if (isWordPresent(_vm->_arrayVerbs[obj[i].verbIndex]) && - isWordPresent(_vm->_arrayNouns[obj[i].nounIndex]) && + if (isWordPresent(_vm->_text->getVerbArray(obj[i].verbIndex)) && + isWordPresent(_vm->_text->getNounArray(obj[i].nounIndex)) && ((obj[i].roomState == kStateDontCare) || (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) { Utils::Box(kBoxAny, "%s", _vm->_file->fetchString(obj[i].commentIndex)); diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index f8e5dc49dd..948feec4d1 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -42,6 +42,7 @@ #include "hugo/object.h" #include "hugo/sound.h" #include "hugo/parser.h" +#include "hugo/text.h" namespace Hugo { @@ -161,9 +162,9 @@ void Scheduler::newScreen(int screenIndex) { // Make sure the background file exists! if (!_vm->isPacked()) { char line[32]; - if (!_vm->_file->fileExists(strcat(strncat(strcpy(line, _vm->_picDir), _vm->_screenNames[screenIndex], kFilenameLength), ".PCX")) && - !_vm->_file->fileExists(strcat(strcpy(line, _vm->_screenNames[screenIndex]), ".ART"))) { - error("Unable to find background file for %s", _vm->_screenNames[screenIndex]); + if (!_vm->_file->fileExists(strcat(strncat(strcpy(line, _vm->_picDir), _vm->_text->getScreenNames(screenIndex), kFilenameLength), ".PCX")) && + !_vm->_file->fileExists(strcat(strcpy(line, _vm->_text->getScreenNames(screenIndex)), ".ART"))) { + error("Unable to find background file for %s", _vm->_text->getScreenNames(screenIndex)); return; } } @@ -1156,7 +1157,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_screen->remapPal(action->a35.oldColorIndex, action->a35.newColorIndex); break; case COND_NOUN: // act36: Conditional on noun mentioned - if (_vm->_parser->isWordPresent(_vm->_arrayNouns[action->a36.nounIndex])) + if (_vm->_parser->isWordPresent(_vm->_text->getNounArray(action->a36.nounIndex))) insertActionList(action->a36.actPassIndex); else insertActionList(action->a36.actFailIndex); @@ -1189,7 +1190,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { insertActionList(action->a41.actFailIndex); break; case TEXT_TAKE: // act42: Text box with "take" message - Utils::Box(kBoxAny, TAKE_TEXT, _vm->_arrayNouns[_vm->_object->_objects[action->a42.objIndex].nounIndex][TAKE_NAME]); + Utils::Box(kBoxAny, TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->a42.objIndex].nounIndex, TAKE_NAME)); break; case YESNO: // act43: Prompt user for Yes or No if (Utils::Box(kBoxYesNo, "%s", _vm->_file->fetchString(action->a43.promptIndex)) != 0) @@ -1226,7 +1227,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { break; case OLD_SONG: // Replaces ACT26 for DOS games. - _vm->_sound->DOSSongPtr = _vm->_textData[action->a49.songIndex]; + _vm->_sound->DOSSongPtr = _vm->_text->getTextData(action->a49.songIndex); break; default: error("An error has occurred: %s", "doAction"); diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp index 3099cd3866..190145b0f5 100644 --- a/engines/hugo/sound.cpp +++ b/engines/hugo/sound.cpp @@ -42,6 +42,7 @@ #include "hugo/game.h" #include "hugo/file.h" #include "hugo/sound.h" +#include "hugo/text.h" namespace Hugo { @@ -478,7 +479,7 @@ void SoundHandler::loadIntroSong(Common::File &in) { for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { uint16 numBuf = in.readUint16BE(); if (varnt == _vm->_gameVariant) - DOSIntroSong = _vm->_textData[numBuf]; + DOSIntroSong = _vm->_text->getTextData(numBuf); } } diff --git a/engines/hugo/text.cpp b/engines/hugo/text.cpp new file mode 100644 index 0000000000..8ba70b7a45 --- /dev/null +++ b/engines/hugo/text.cpp @@ -0,0 +1,215 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ +#include "common/system.h" + +#include "hugo/hugo.h" +#include "hugo/text.h" + +namespace Hugo { + +TextHandler::TextHandler(HugoEngine *vm) : _vm(vm), _textData(0), _stringtData(0), + _textEngine(0), _textIntro(0), _textMouse(0), _textParser(0), _textUtil(0), _screenNames(0) { +} + +TextHandler::~TextHandler() { +} + +char **TextHandler::loadTextsVariante(Common::File &in, uint16 *arraySize) { + int numTexts; + int entryLen; + int len; + char **res = 0; + char *pos = 0; + char *posBck = 0; + + for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { + numTexts = in.readUint16BE(); + entryLen = in.readUint16BE(); + pos = (char *)malloc(entryLen); + if (varnt == _vm->_gameVariant) { + if (arraySize) + *arraySize = numTexts; + res = (char **)malloc(sizeof(char *) * numTexts); + res[0] = pos; + in.read(res[0], entryLen); + res[0] += DATAALIGNMENT; + } else { + in.read(pos, entryLen); + posBck = pos; + } + + pos += DATAALIGNMENT; + + for (int i = 1; i < numTexts; i++) { + pos -= 2; + + len = READ_BE_UINT16(pos); + pos += 2 + len; + + if (varnt == _vm->_gameVariant) + res[i] = pos; + } + + if (varnt != _vm->_gameVariant) + free(posBck); + } + + return res; +} + +char ***TextHandler::loadTextsArray(Common::File &in) { + char ***resArray = 0; + uint16 arraySize; + + for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { + arraySize = in.readUint16BE(); + if (varnt == _vm->_gameVariant) { + resArray = (char ***)malloc(sizeof(char **) * (arraySize + 1)); + resArray[arraySize] = 0; + } + for (int i = 0; i < arraySize; i++) { + int numTexts = in.readUint16BE(); + int entryLen = in.readUint16BE(); + char *pos = (char *)malloc(entryLen); + char *posBck = 0; + char **res = 0; + if (varnt == _vm->_gameVariant) { + res = (char **)malloc(sizeof(char *) * numTexts); + res[0] = pos; + in.read(res[0], entryLen); + res[0] += DATAALIGNMENT; + } else { + in.read(pos, entryLen); + posBck = pos; + } + + pos += DATAALIGNMENT; + + for (int j = 0; j < numTexts; j++) { + if (varnt == _vm->_gameVariant) + res[j] = pos; + + pos -= 2; + int len = READ_BE_UINT16(pos); + pos += 2 + len; + } + + if (varnt == _vm->_gameVariant) + resArray[i] = res; + else + free(posBck); + } + } + + return resArray; +} + +char **TextHandler::loadTexts(Common::File &in) { + int numTexts = in.readUint16BE(); + char **res = (char **)malloc(sizeof(char *) * numTexts); + int entryLen = in.readUint16BE(); + char *pos = (char *)malloc(entryLen); + + in.read(pos, entryLen); + + pos += DATAALIGNMENT; + res[0] = pos; + + for (int i = 1; i < numTexts; i++) { + pos -= 2; + int len = READ_BE_UINT16(pos); + pos += 2 + len; + res[i] = pos; + } + + return res; +} + +void TextHandler::loadAllTexts(Common::File &in) { + // Read textData + _textData = loadTextsVariante(in, 0); + + // Read stringtData + // Only Hugo 1 DOS should use this array + _stringtData = loadTextsVariante(in, 0); + + // Read arrayNouns + _arrayNouns = loadTextsArray(in); + + // Read arrayVerbs + _arrayVerbs = loadTextsArray(in); + + // Read screenNames + _screenNames = loadTextsVariante(in, &_vm->_numScreens); + + // Read textEngine + _textEngine = loadTexts(in); + + // Read textIntro + _textIntro = loadTextsVariante(in, 0); + + // Read textMouse + _textMouse = loadTexts(in); + + // Read textParser + _textParser = loadTexts(in); + + // Read textUtil + _textUtil = loadTextsVariante(in, 0); +} + +void TextHandler::freeTexts(char **ptr) { + if (!ptr) + return; + + free(*ptr - DATAALIGNMENT); + free(ptr); +} + +void TextHandler::freeAllTexts() { + freeTexts(_textData); + freeTexts(_stringtData); + + if (_arrayNouns) { + for (int i = 0; _arrayNouns[i]; i++) + freeTexts(_arrayNouns[i]); + free(_arrayNouns); + } + + if (_arrayVerbs) { + for (int i = 0; _arrayVerbs[i]; i++) + freeTexts(_arrayVerbs[i]); + free(_arrayVerbs); + } + + freeTexts(_screenNames); + freeTexts(_textEngine); + freeTexts(_textIntro); + freeTexts(_textMouse); + freeTexts(_textParser); + freeTexts(_textUtil); +} + +} // End of namespace Hugo diff --git a/engines/hugo/text.h b/engines/hugo/text.h new file mode 100644 index 0000000000..1244b7d3f9 --- /dev/null +++ b/engines/hugo/text.h @@ -0,0 +1,75 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ +#ifndef TEXT_H +#define TEXT_H + +namespace Hugo { + +class TextHandler { +public: + TextHandler(HugoEngine *vm); + ~TextHandler(); + + char *getScreenNames(int screenIndex) { return _screenNames[screenIndex]; } + char *getTextData(int textIndex) { return _textData[textIndex]; } + char *getStringtData(int stringIndex) { return _stringtData[stringIndex]; } + char *getTextEngine(int engineIndex) { return _textEngine[engineIndex]; } + char *getTextIntro(int introIndex) { return _textIntro[introIndex]; } + char *getTextMouse(int mouseIndex) { return _textMouse[mouseIndex]; } + char *getTextParser(int parserIndex) { return _textParser[parserIndex]; } + char *getTextUtil(int utilIndex) { return _textUtil[utilIndex]; } + char *getNoun(int idx1, int idx2) { return _arrayNouns[idx1][idx2]; } + char **getNounArray(int idx1) { return _arrayNouns[idx1]; } + char *getVerb(int idx1, int idx2) { return _arrayVerbs[idx1][idx2]; } + char **getVerbArray(int idx1) { return _arrayVerbs[idx1]; } + + void loadAllTexts(Common::File &in); + void freeAllTexts(); + +private: + HugoEngine *_vm; + + char ***_arrayNouns; + char ***_arrayVerbs; + + char **_screenNames; + char **_stringtData; + char **_textData; + char **_textEngine; + char **_textIntro; + char **_textMouse; + char **_textParser; + char **_textUtil; + + char ***loadTextsArray(Common::File &in); + char **loadTextsVariante(Common::File &in, uint16 *arraySize); + char **loadTexts(Common::File &in); + + void freeTexts(char **ptr); + +}; + +} // End of namespace Hugo +#endif // TEXT_H diff --git a/engines/hugo/util.cpp b/engines/hugo/util.cpp index 212f10b36d..f8f9f5a0a5 100644 --- a/engines/hugo/util.cpp +++ b/engines/hugo/util.cpp @@ -37,6 +37,7 @@ #include "hugo/hugo.h" #include "hugo/util.h" #include "hugo/sound.h" +#include "hugo/text.h" namespace Hugo { @@ -143,7 +144,7 @@ char *Utils::Box(box_t dismiss, const char *s, ...) { * Print options for user when dead */ void Utils::gameOverMsg(void) { - Utils::Box(kBoxOk, "%s", HugoEngine::get()._textUtil[kGameOver]); + Utils::Box(kBoxOk, "%s", HugoEngine::get()._text->getTextUtil(kGameOver)); } char *Utils::strlwr(char *buffer) { diff --git a/tools/create_hugo/create_hugo.cpp b/tools/create_hugo/create_hugo.cpp index c10a8e2da2..01b6d915f0 100644 --- a/tools/create_hugo/create_hugo.cpp +++ b/tools/create_hugo/create_hugo.cpp @@ -97,6 +97,12 @@ int main(int argc, char *argv[]) { // game versions/variantes writeUint16BE(outFile, NUM_VARIANTE); + // Write palette + writeUint16BE(outFile, SIZE_PAL_ARRAY); + for (i = 0; i < SIZE_PAL_ARRAY; i++) { + writeByte(outFile, _palette[i]); + } + // Write textData // textData_1w nbrElem = sizeof(textData_1w) / sizeof(char *); @@ -304,12 +310,6 @@ int main(int argc, char *argv[]) { nbrElem = sizeof(screenNames_3d) / sizeof(char *); writeTextArray(outFile, screenNames_3d, nbrElem); - // Write palette - writeUint16BE(outFile, SIZE_PAL_ARRAY); - for (i = 0; i < SIZE_PAL_ARRAY; i++) { - writeByte(outFile, _palette[i]); - } - // Write textEngine writeTextArray(outFile, textEngine, NUM_ENGINE_TEXT); @@ -321,6 +321,20 @@ int main(int argc, char *argv[]) { writeTextArray(outFile, textIntro_dummy, NUM_INTRO_TEXT_DUMMY); writeTextArray(outFile, textIntro_v3, NUM_INTRO_TEXT_V3); + // Write textMouse + writeTextArray(outFile, textMouse, NUM_MOUSE_TEXT); + + // Write textParser + writeTextArray(outFile, textParser, NUM_PARSER_TEXT); + + // Write textUtil + writeTextArray(outFile, textUtil_v1w, NUM_UTIL_TEXT); + writeTextArray(outFile, textUtil_v1w, NUM_UTIL_TEXT); + writeTextArray(outFile, textUtil_v1w, NUM_UTIL_TEXT); + writeTextArray(outFile, textUtil_v1d, NUM_UTIL_TEXT); + writeTextArray(outFile, textUtil_v1d, NUM_UTIL_TEXT); + writeTextArray(outFile, textUtil_v1d, NUM_UTIL_TEXT); + // Write x_intro and y_intro writeUint16BE(outFile, NUM_INTRO_TICK_DUMMY); for (i = 0; i < NUM_INTRO_TICK_DUMMY; i++) { @@ -358,20 +372,6 @@ int main(int argc, char *argv[]) { writeByte(outFile, y_intro_v3[i]); } - // Write textMouse - writeTextArray(outFile, textMouse, NUM_MOUSE_TEXT); - - // Write textParser - writeTextArray(outFile, textParser, NUM_PARSER_TEXT); - - // Write textUtil - writeTextArray(outFile, textUtil_v1w, NUM_UTIL_TEXT); - writeTextArray(outFile, textUtil_v1w, NUM_UTIL_TEXT); - writeTextArray(outFile, textUtil_v1w, NUM_UTIL_TEXT); - writeTextArray(outFile, textUtil_v1d, NUM_UTIL_TEXT); - writeTextArray(outFile, textUtil_v1d, NUM_UTIL_TEXT); - writeTextArray(outFile, textUtil_v1d, NUM_UTIL_TEXT); - // arrayReqs_1w nbrElem = sizeof(arrayReqs_1w) / sizeof(uint16 *); writeUint16Array(outFile, arrayReqs_1w, nbrElem); diff --git a/tools/create_hugo/create_hugo.h b/tools/create_hugo/create_hugo.h index 26b2ecb291..7fb5d761ba 100644 --- a/tools/create_hugo/create_hugo.h +++ b/tools/create_hugo/create_hugo.h @@ -31,7 +31,7 @@ #define DATAALIGNMENT 4 #define HUGO_DAT_VER_MAJ 0 // 1 byte -#define HUGO_DAT_VER_MIN 40 // 1 byte +#define HUGO_DAT_VER_MIN 41 // 1 byte typedef unsigned char uint8; typedef unsigned char byte; -- cgit v1.2.3