diff options
Diffstat (limited to 'engines')
141 files changed, 1702 insertions, 1148 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index bc5bc74f3a..c1c3820b10 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -56,11 +56,14 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) : _dumpFile(nullptr), _display(nullptr), _graphics(nullptr), + _speaker(nullptr), _isRestarting(false), _isRestoring(false), _isQuitting(false), _skipOneCommand(false), _gameDescription(gd), + _console(nullptr), + _messageIds(), _saveVerb(0), _saveNoun(0), _restoreVerb(0), @@ -427,6 +430,11 @@ void AdlEngine::initState() { initGameState(); } +void AdlEngine::switchRoom(byte roomNr) { + getCurRoom().curPicture = getCurRoom().picture; + _state.room = roomNr; +} + byte AdlEngine::roomArg(byte room) const { return room; } @@ -578,6 +586,60 @@ void AdlEngine::dropItem(byte noun) { printMessage(_messageIds.dontUnderstand); } +void AdlEngine::gameLoop() { + uint verb = 0, noun = 0; + _isRestarting = false; + + // When restoring from the launcher, we don't read + // input on the first iteration. This is needed to + // ensure that restoring from the launcher and + // restoring in-game brings us to the same game state. + // (Also see comment below.) + if (!_isRestoring) { + showRoom(); + + if (_isRestarting) + return; + + _canSaveNow = _canRestoreNow = true; + getInput(verb, noun); + _canSaveNow = _canRestoreNow = false; + + if (shouldQuit()) + return; + + // If we just restored from the GMM, we skip this command + // set, as no command has been input by the user + if (!_isRestoring) + checkInput(verb, noun); + } + + if (_isRestoring) { + // We restored from the GMM or launcher. As restoring + // with "RESTORE GAME" does not end command processing, + // we don't break it off here either. This essentially + // means that restoring a game will always run through + // the global commands and increase the move counter + // before the first user input. + _display->printAsciiString("\r"); + _isRestoring = false; + verb = _restoreVerb; + noun = _restoreNoun; + } + + // Restarting does end command processing + if (_isRestarting) + return; + + doAllCommands(_globalCommands, verb, noun); + + if (_isRestarting) + return; + + advanceClock(); + _state.moves++; +} + Common::Error AdlEngine::run() { initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true); @@ -603,59 +665,8 @@ Common::Error AdlEngine::run() { _display->setMode(DISPLAY_MODE_MIXED); - while (!_isQuitting) { - uint verb = 0, noun = 0; - _isRestarting = false; - - // When restoring from the launcher, we don't read - // input on the first iteration. This is needed to - // ensure that restoring from the launcher and - // restoring in-game brings us to the same game state. - // (Also see comment below.) - if (!_isRestoring) { - showRoom(); - - if (_isRestarting) - continue; - - _canSaveNow = _canRestoreNow = true; - getInput(verb, noun); - _canSaveNow = _canRestoreNow = false; - - if (shouldQuit()) - break; - - // If we just restored from the GMM, we skip this command - // set, as no command has been input by the user - if (!_isRestoring) - checkInput(verb, noun); - } - - if (_isRestoring) { - // We restored from the GMM or launcher. As restoring - // with "RESTORE GAME" does not end command processing, - // we don't break it off here either. This essentially - // means that restoring a game will always run through - // the global commands and increase the move counter - // before the first user input. - _display->printAsciiString("\r"); - _isRestoring = false; - verb = _restoreVerb; - noun = _restoreNoun; - } - - // Restarting does end command processing - if (_isRestarting) - continue; - - doAllCommands(_globalCommands, verb, noun); - - if (_isRestarting) - continue; - - advanceClock(); - _state.moves++; - } + while (!(_isQuitting || shouldQuit())) + gameLoop(); return Common::kNoError; } @@ -671,6 +682,49 @@ bool AdlEngine::hasFeature(EngineFeature f) const { } } +void AdlEngine::loadState(Common::ReadStream &stream) { + _state.room = stream.readByte(); + _state.moves = stream.readByte(); + _state.isDark = stream.readByte(); + _state.time.hours = stream.readByte(); + _state.time.minutes = stream.readByte(); + + uint32 size = stream.readUint32BE(); + if (size != _state.rooms.size()) + error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size); + + for (uint i = 0; i < size; ++i) { + _state.rooms[i].picture = stream.readByte(); + _state.rooms[i].curPicture = stream.readByte(); + _state.rooms[i].isFirstTime = stream.readByte(); + } + + // NOTE: _state.curPicture is part of the save state in the original engine. We + // reconstruct it instead. This is believed to be safe for at least hires 0-2, but + // this may need to be re-evaluated for later games. + _state.curPicture = getCurRoom().curPicture; + + size = stream.readUint32BE(); + if (size != _state.items.size()) + error("Item count mismatch (expected %i; found %i)", _state.items.size(), size); + + Common::List<Item>::iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + item->room = stream.readByte(); + item->picture = stream.readByte(); + item->position.x = stream.readByte(); + item->position.y = stream.readByte(); + item->state = stream.readByte(); + } + + size = stream.readUint32BE(); + if (size != _state.vars.size()) + error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size); + + for (uint i = 0; i < size; ++i) + _state.vars[i] = stream.readByte(); +} + Common::Error AdlEngine::loadGameState(int slot) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName); @@ -703,47 +757,7 @@ Common::Error AdlEngine::loadGameState(int slot) { Graphics::skipThumbnail(*inFile); initState(); - - _state.room = inFile->readByte(); - _state.moves = inFile->readByte(); - _state.isDark = inFile->readByte(); - _state.time.hours = inFile->readByte(); - _state.time.minutes = inFile->readByte(); - - uint32 size = inFile->readUint32BE(); - if (size != _state.rooms.size()) - error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size); - - for (uint i = 0; i < size; ++i) { - _state.rooms[i].picture = inFile->readByte(); - _state.rooms[i].curPicture = inFile->readByte(); - _state.rooms[i].isFirstTime = inFile->readByte(); - } - - // NOTE: _state.curPicture is part of the save state in the original engine. We - // reconstruct it instead. This is believed to be safe for at least hires 0-2, but - // this may need to be re-evaluated for later games. - _state.curPicture = getCurRoom().curPicture; - - size = inFile->readUint32BE(); - if (size != _state.items.size()) - error("Item count mismatch (expected %i; found %i)", _state.items.size(), size); - - Common::List<Item>::iterator item; - for (item = _state.items.begin(); item != _state.items.end(); ++item) { - item->room = inFile->readByte(); - item->picture = inFile->readByte(); - item->position.x = inFile->readByte(); - item->position.y = inFile->readByte(); - item->state = inFile->readByte(); - } - - size = inFile->readUint32BE(); - if (size != _state.vars.size()) - error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size); - - for (uint i = 0; i < size; ++i) - _state.vars[i] = inFile->readByte(); + loadState(*inFile); if (inFile->err() || inFile->eos()) error("Failed to load game '%s'", fileName.c_str()); @@ -760,6 +774,35 @@ bool AdlEngine::canLoadGameStateCurrently() { return _canRestoreNow; } +void AdlEngine::saveState(Common::WriteStream &stream) { + stream.writeByte(_state.room); + stream.writeByte(_state.moves); + stream.writeByte(_state.isDark); + stream.writeByte(_state.time.hours); + stream.writeByte(_state.time.minutes); + + stream.writeUint32BE(_state.rooms.size()); + for (uint i = 0; i < _state.rooms.size(); ++i) { + stream.writeByte(_state.rooms[i].picture); + stream.writeByte(_state.rooms[i].curPicture); + stream.writeByte(_state.rooms[i].isFirstTime); + } + + stream.writeUint32BE(_state.items.size()); + Common::List<Item>::const_iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + stream.writeByte(item->room); + stream.writeByte(item->picture); + stream.writeByte(item->position.x); + stream.writeByte(item->position.y); + stream.writeByte(item->state); + } + + stream.writeUint32BE(_state.vars.size()); + for (uint i = 0; i < _state.vars.size(); ++i) + stream.writeByte(_state.vars[i]); +} + Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName); @@ -797,34 +840,7 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) { outFile->writeUint32BE(playTime); _display->saveThumbnail(*outFile); - - outFile->writeByte(_state.room); - outFile->writeByte(_state.moves); - outFile->writeByte(_state.isDark); - outFile->writeByte(_state.time.hours); - outFile->writeByte(_state.time.minutes); - - outFile->writeUint32BE(_state.rooms.size()); - for (uint i = 0; i < _state.rooms.size(); ++i) { - outFile->writeByte(_state.rooms[i].picture); - outFile->writeByte(_state.rooms[i].curPicture); - outFile->writeByte(_state.rooms[i].isFirstTime); - } - - outFile->writeUint32BE(_state.items.size()); - Common::List<Item>::const_iterator item; - for (item = _state.items.begin(); item != _state.items.end(); ++item) { - outFile->writeByte(item->room); - outFile->writeByte(item->picture); - outFile->writeByte(item->position.x); - outFile->writeByte(item->position.y); - outFile->writeByte(item->state); - } - - outFile->writeUint32BE(_state.vars.size()); - for (uint i = 0; i < _state.vars.size(); ++i) - outFile->writeByte(_state.vars[i]); - + saveState(*outFile); outFile->finalize(); if (outFile->err()) { @@ -1073,8 +1089,7 @@ int AdlEngine::o1_moveItem(ScriptEnv &e) { int AdlEngine::o1_setRoom(ScriptEnv &e) { OP_DEBUG_1("\tROOM = %d", e.arg(1)); - getCurRoom().curPicture = getCurRoom().picture; - _state.room = e.arg(1); + switchRoom(e.arg(1)); return 1; } @@ -1228,8 +1243,8 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const { return false; if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) { - op_debug("IF\n\tROOM == %s", roomStr(env.getCommand().room).c_str()); - op_debug("\t&& SAID(%s, %s)", verbStr(env.getCommand().verb).c_str(), nounStr(env.getCommand().noun).c_str()); + (void)op_debug("IF\n\tROOM == %s", roomStr(env.getCommand().room).c_str()); + (void)op_debug("\t&& SAID(%s, %s)", verbStr(env.getCommand().verb).c_str(), nounStr(env.getCommand().noun).c_str()); } for (uint i = 0; i < env.getCondCount(); ++i) { @@ -1242,7 +1257,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const { if (numArgs < 0) { if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) - op_debug("FAIL\n"); + (void)op_debug("FAIL\n"); return false; } @@ -1254,7 +1269,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const { void AdlEngine::doActions(ScriptEnv &env) { if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) - op_debug("THEN"); + (void)op_debug("THEN"); for (uint i = 0; i < env.getActCount(); ++i) { byte op = env.op(); @@ -1266,7 +1281,7 @@ void AdlEngine::doActions(ScriptEnv &env) { if (numArgs < 0) { if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) - op_debug("ABORT\n"); + (void)op_debug("ABORT\n"); return; } @@ -1274,7 +1289,7 @@ void AdlEngine::doActions(ScriptEnv &env) { } if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) - op_debug("END\n"); + (void)op_debug("END\n"); } bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) { diff --git a/engines/adl/adl.h b/engines/adl/adl.h index 87e99a5537..62c5ea1b8e 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -42,6 +42,7 @@ namespace Common { class ReadStream; +class WriteStream; class SeekableReadStream; class File; struct Event; @@ -84,7 +85,8 @@ struct Room { Room() : description(0), picture(0), - curPicture(0) { + curPicture(0), + isFirstTime(true) { memset(connections, 0, sizeof(connections)); } @@ -152,6 +154,8 @@ struct Item { byte description; Common::Array<byte> roomPictures; bool isOnScreen; + + Item() : id(0), noun(0), region(0), room(0), picture(0), isLineArt(false), state(0), description(0), isOnScreen(false) { } }; struct Time { @@ -235,6 +239,9 @@ protected: Common::Error loadGameState(int slot); Common::Error saveGameState(int slot, const Common::String &desc); + virtual void gameLoop(); + virtual void loadState(Common::ReadStream &stream); + virtual void saveState(Common::WriteStream &stream); Common::String readString(Common::ReadStream &stream, byte until = 0) const; Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const; void openFile(Common::File &file, const Common::String &name) const; @@ -247,6 +254,7 @@ protected: Common::String inputString(byte prompt = 0) const; byte inputKey(bool showCursor = true) const; + void getInput(uint &verb, uint &noun); virtual Common::String formatVerbError(const Common::String &verb) const; virtual Common::String formatNounError(const Common::String &verb, const Common::String &noun) const; @@ -262,6 +270,7 @@ protected: virtual void setupOpcodeTables(); virtual void initState(); + virtual void switchRoom(byte roomNr); virtual byte roomArg(byte room) const; virtual void advanceClock() { } void loadDroppedItemOffsets(Common::ReadStream &stream, byte count); @@ -381,6 +390,7 @@ protected: State _state; bool _isRestarting, _isRestoring, _isQuitting; + bool _canSaveNow, _canRestoreNow; bool _skipOneCommand; const AdlGameDescription *_gameDescription; @@ -393,6 +403,7 @@ private: virtual void drawItem(Item &item, const Common::Point &pos) = 0; virtual void loadRoom(byte roomNr) = 0; virtual void showRoom() = 0; + virtual void switchRegion(byte region) { } // Engine Common::Error run(); @@ -404,12 +415,10 @@ private: byte convertKey(uint16 ascii) const; Common::String getLine() const; Common::String getWord(const Common::String &line, uint &index) const; - void getInput(uint &verb, uint &noun); Console *_console; GUI::Debugger *getDebugger() { return _console; } byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun; - bool _canSaveNow, _canRestoreNow; }; } // End of namespace Adl diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp index 8670bd08df..c3e82117d8 100644 --- a/engines/adl/adl_v2.cpp +++ b/engines/adl/adl_v2.cpp @@ -367,7 +367,8 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const { void AdlEngine_v2::loadItems(Common::ReadStream &stream) { byte id; while ((id = stream.readByte()) != 0xff && !stream.eos() && !stream.err()) { - Item item = Item(); + Item item; + item.id = id; item.noun = stream.readByte(); item.room = stream.readByte(); diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h index fe0c781f44..f0af9eba22 100644 --- a/engines/adl/adl_v2.h +++ b/engines/adl/adl_v2.h @@ -59,6 +59,7 @@ protected: void loadPictures(Common::ReadStream &stream); void loadItemPictures(Common::ReadStream &stream, byte count); virtual bool isInventoryFull() { return false; } + int askForSlot(const Common::String &question); void checkTextOverflow(char c); @@ -91,8 +92,6 @@ protected: byte _roomOnScreen, _picOnScreen, _itemsOnScreen; private: - int askForSlot(const Common::String &question); - Common::RandomSource *_random; }; diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp index 456ee10dca..dcf0f997c9 100644 --- a/engines/adl/adl_v4.cpp +++ b/engines/adl/adl_v4.cpp @@ -21,6 +21,7 @@ */ #include "adl/adl_v4.h" +#include "adl/display.h" #include "adl/detection.h" namespace Adl { @@ -36,6 +37,143 @@ AdlEngine_v4::~AdlEngine_v4() { delete _itemPicIndex; } +void AdlEngine_v4::gameLoop() { + uint verb = 0, noun = 0; + _isRestarting = false; + + if (_isRestoring) { + // Game restored from launcher. As this version of ADL long jumps to + // the game loop after restoring, no special action is required. + _isRestoring = false; + } + + showRoom(); + + if (_isRestarting || shouldQuit()) + return; + + _canSaveNow = _canRestoreNow = true; + getInput(verb, noun); + _canSaveNow = _canRestoreNow = false; + + if (_isRestoring) { + // Game restored from GMM. Move cursor to next line and jump to + // start of game loop. + _display->printAsciiString("\r"); + _isRestoring = false; + return; + } + + if (_isRestarting || shouldQuit()) + return; + + _linesPrinted = 0; + + checkInput(verb, noun); + + if (_isRestarting || shouldQuit()) + return; + + doAllCommands(_globalCommands, verb, noun); + + if (_isRestarting || shouldQuit()) + return; + + _state.moves++; +} + +void AdlEngine_v4::loadState(Common::ReadStream &stream) { + _state.room = stream.readByte(); + _state.region = stream.readByte(); + _state.prevRegion = stream.readByte(); + + uint32 size = stream.readUint32BE(); + if (size != _state.regions.size()) + error("Region count mismatch (expected %i; found %i)", _state.regions.size(), size); + + Common::Array<Region>::iterator region; + for (region = _state.regions.begin(); region != _state.regions.end(); ++region) { + size = stream.readUint32BE(); + if (size != region->rooms.size()) + error("Room count mismatch (expected %i; found %i)", region->rooms.size(), size); + + Common::Array<RoomState>::iterator room; + for (room = region->rooms.begin(); room != region->rooms.end(); ++room) { + room->picture = stream.readByte(); + room->isFirstTime = stream.readByte(); + } + + size = stream.readUint32BE(); + if (size != region->vars.size()) + error("Variable count mismatch (expected %i; found %i)", region->vars.size(), size); + + for (uint i = 0; i < region->vars.size(); ++i) + region->vars[i] = stream.readByte(); + } + + size = stream.readUint32BE(); + if (size != _state.items.size()) + error("Item count mismatch (expected %i; found %i)", _state.items.size(), size); + + Common::List<Item>::iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + item->room = stream.readByte(); + item->region = stream.readByte(); + item->state = stream.readByte(); + } + + size = stream.readUint32BE(); + const uint expectedSize = _state.vars.size() - getRegion(1).vars.size(); + if (size != expectedSize) + error("Variable count mismatch (expected %i; found %i)", expectedSize, size); + + for (uint i = getRegion(1).vars.size(); i < size; ++i) + _state.vars[i] = stream.readByte(); + + if (stream.err() || stream.eos()) + return; + + loadRegion(_state.region); + restoreRoomState(_state.room); + _roomOnScreen = _picOnScreen = 0; +} + +void AdlEngine_v4::saveState(Common::WriteStream &stream) { + backupVars(); + backupRoomState(_state.room); + + stream.writeByte(_state.room); + stream.writeByte(_state.region); + stream.writeByte(_state.prevRegion); + + stream.writeUint32BE(_state.regions.size()); + Common::Array<Region>::const_iterator region; + for (region = _state.regions.begin(); region != _state.regions.end(); ++region) { + stream.writeUint32BE(region->rooms.size()); + Common::Array<RoomState>::const_iterator room; + for (room = region->rooms.begin(); room != region->rooms.end(); ++room) { + stream.writeByte(room->picture); + stream.writeByte(room->isFirstTime); + } + + stream.writeUint32BE(region->vars.size()); + for (uint i = 0; i < region->vars.size(); ++i) + stream.writeByte(region->vars[i]); + } + + stream.writeUint32BE(_state.items.size()); + Common::List<Item>::const_iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + stream.writeByte(item->room); + stream.writeByte(item->region); + stream.writeByte(item->state); + } + + stream.writeUint32BE(_state.vars.size() - getRegion(1).vars.size()); + for (uint i = getRegion(1).vars.size(); i < _state.vars.size(); ++i) + stream.writeByte(_state.vars[i]); +} + Common::String AdlEngine_v4::loadMessage(uint idx) const { Common::String str = AdlEngine_v3::loadMessage(idx); @@ -268,6 +406,14 @@ void AdlEngine_v4::switchRegion(byte region) { _picOnScreen = _roomOnScreen = 0; } +void AdlEngine_v4::switchRoom(byte roomNr) { + getCurRoom().curPicture = getCurRoom().picture; + getCurRoom().isFirstTime = false; + backupRoomState(_state.room); + _state.room = roomNr; + restoreRoomState(_state.room); +} + int AdlEngine_v4::o4_isItemInRoom(ScriptEnv &e) { OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str()); @@ -297,17 +443,6 @@ int AdlEngine_v4::o4_moveItem(ScriptEnv &e) { return 2; } -int AdlEngine_v4::o4_setRoom(ScriptEnv &e) { - OP_DEBUG_1("\tROOM = %d", e.arg(1)); - - getCurRoom().curPicture = getCurRoom().picture; - getCurRoom().isFirstTime = false; - backupRoomState(_state.room); - _state.room = e.arg(1); - restoreRoomState(_state.room); - return 1; -} - int AdlEngine_v4::o4_setRegionToPrev(ScriptEnv &e) { OP_DEBUG_0("\tREGION = PREV_REGION"); @@ -363,6 +498,68 @@ int AdlEngine_v4::o4_setRegion(ScriptEnv &e) { return -1; } +int AdlEngine_v4::o4_save(ScriptEnv &e) { + OP_DEBUG_0("\tSAVE_GAME()"); + + _display->printString(_strings_v2.saveReplace); + const char key = inputKey(); + + if (shouldQuit()) + return -1; + + if (key != APPLECHAR('Y')) + return 0; + + const int slot = askForSlot(_strings_v2.saveInsert); + + if (slot < 0) + return -1; + + saveGameState(slot, ""); + return 0; +} + +int AdlEngine_v4::o4_restore(ScriptEnv &e) { + OP_DEBUG_0("\tRESTORE_GAME()"); + + const int slot = askForSlot(_strings_v2.restoreInsert); + + if (slot < 0) + return -1; + + loadGameState(slot); + _isRestoring = false; + + _picOnScreen = 0; + _roomOnScreen = 0; + + // Long jump + _isRestarting = true; + return -1; +} + +int AdlEngine_v4::o4_restart(ScriptEnv &e) { + OP_DEBUG_0("\tRESTART_GAME()"); + + while (true) { + _display->printString(_strings.playAgain); + const Common::String input(inputString()); + + if (shouldQuit()) + return -1; + + if (input.firstChar() == APPLECHAR('N')) { + return o1_quit(e); + } else if (input.firstChar() == APPLECHAR('Y')) { + // The original game loads a special save game from volume 3 + initState(); + // Long jump + _isRestarting = true; + return -1; + } + } +} + int AdlEngine_v4::o4_setRegionRoom(ScriptEnv &e) { OP_DEBUG_2("\tSET_REGION_ROOM(%d, %d)", e.arg(1), e.arg(2)); diff --git a/engines/adl/adl_v4.h b/engines/adl/adl_v4.h index 1bc7664d58..4e87530673 100644 --- a/engines/adl/adl_v4.h +++ b/engines/adl/adl_v4.h @@ -49,8 +49,13 @@ protected: AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd); // AdlEngine + virtual void gameLoop(); + virtual void loadState(Common::ReadStream &stream); + virtual void saveState(Common::WriteStream &stream); virtual Common::String loadMessage(uint idx) const; virtual Common::String getItemDescription(const Item &item) const; + virtual void switchRegion(byte region); + virtual void switchRoom(byte roomNr); // AdlEngine_v2 virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const; @@ -67,15 +72,16 @@ protected: void restoreRoomState(byte room); void backupVars(); void restoreVars(); - void switchRegion(byte region); int o4_isItemInRoom(ScriptEnv &e); int o4_isVarGT(ScriptEnv &e); int o4_moveItem(ScriptEnv &e); - int o4_setRoom(ScriptEnv &e); int o4_setRegionToPrev(ScriptEnv &e); int o4_moveAllItems(ScriptEnv &e); int o4_setRegion(ScriptEnv &e); + int o4_save(ScriptEnv &e); + int o4_restore(ScriptEnv &e); + int o4_restart(ScriptEnv &e); int o4_setRegionRoom(ScriptEnv &e); int o4_setRoomPic(ScriptEnv &e); diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp index c35e8b02aa..7305ec8125 100644 --- a/engines/adl/console.cpp +++ b/engines/adl/console.cpp @@ -35,6 +35,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() { registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs)); registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts)); registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands)); + registerCmd("region", WRAP_METHOD(Console, Cmd_Region)); registerCmd("room", WRAP_METHOD(Console, Cmd_Room)); registerCmd("items", WRAP_METHOD(Console, Cmd_Items)); registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem)); @@ -112,35 +113,55 @@ bool Console::Cmd_ValidCommands(int argc, const char **argv) { return true; } -bool Console::Cmd_DumpScripts(int argc, const char **argv) { - if (argc != 1) { - debugPrintf("Usage: %s\n", argv[0]); - return true; - } - - bool oldFlag = DebugMan.isDebugChannelEnabled(kDebugChannelScript); - - DebugMan.enableDebugChannel("Script"); - - _engine->_dumpFile = new Common::DumpFile(); - +void Console::dumpScripts(const Common::String &prefix) { for (byte roomNr = 1; roomNr <= _engine->_state.rooms.size(); ++roomNr) { _engine->loadRoom(roomNr); if (_engine->_roomData.commands.size() != 0) { - _engine->_dumpFile->open(Common::String::format("%03d.ADL", roomNr).c_str()); + _engine->_dumpFile->open(prefix + Common::String::format("%03d.ADL", roomNr).c_str()); _engine->doAllCommands(_engine->_roomData.commands, IDI_ANY, IDI_ANY); _engine->_dumpFile->close(); } } _engine->loadRoom(_engine->_state.room); - _engine->_dumpFile->open("GLOBAL.ADL"); + _engine->_dumpFile->open(prefix + "GLOBAL.ADL"); _engine->doAllCommands(_engine->_globalCommands, IDI_ANY, IDI_ANY); _engine->_dumpFile->close(); - _engine->_dumpFile->open("RESPONSE.ADL"); + _engine->_dumpFile->open(prefix + "RESPONSE.ADL"); _engine->doAllCommands(_engine->_roomCommands, IDI_ANY, IDI_ANY); _engine->_dumpFile->close(); +} + +bool Console::Cmd_DumpScripts(int argc, const char **argv) { + if (argc != 1) { + debugPrintf("Usage: %s\n", argv[0]); + return true; + } + + bool oldFlag = DebugMan.isDebugChannelEnabled(kDebugChannelScript); + + DebugMan.enableDebugChannel("Script"); + + _engine->_dumpFile = new Common::DumpFile(); + + if (_engine->_state.regions.empty()) { + dumpScripts(); + } else { + const byte oldRegion = _engine->_state.region; + const byte oldPrevRegion = _engine->_state.prevRegion; + const byte oldRoom = _engine->_state.room; + + for (byte regionNr = 1; regionNr <= _engine->_state.regions.size(); ++regionNr) { + _engine->switchRegion(regionNr); + dumpScripts(Common::String::format("%03d-", regionNr)); + } + + _engine->switchRegion(oldRegion); + _engine->_state.prevRegion = oldPrevRegion; + _engine->_state.room = oldRoom; + _engine->loadRoom(oldRoom); + } delete _engine->_dumpFile; _engine->_dumpFile = nullptr; @@ -151,6 +172,42 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) { return true; } +void Console::prepareGame() { + _engine->clearScreen(); + _engine->loadRoom(_engine->_state.room); + _engine->showRoom(); + _engine->_display->updateTextScreen(); + _engine->_display->updateHiResScreen(); +} + +bool Console::Cmd_Region(int argc, const char **argv) { + if (argc > 2) { + debugPrintf("Usage: %s [<new_region>]\n", argv[0]); + return true; + } + + if (argc == 2) { + if (!_engine->_canRestoreNow) { + debugPrintf("Cannot change regions right now\n"); + return true; + } + + uint regionCount = _engine->_state.regions.size(); + uint region = strtoul(argv[1], NULL, 0); + if (region < 1 || region > regionCount) { + debugPrintf("Region %u out of valid range [1, %u]\n", region, regionCount); + return true; + } + + _engine->switchRegion(region); + prepareGame(); + } + + debugPrintf("Current region: %u\n", _engine->_state.region); + + return true; +} + bool Console::Cmd_Room(int argc, const char **argv) { if (argc > 2) { debugPrintf("Usage: %s [<new_room>]\n", argv[0]); @@ -170,12 +227,8 @@ bool Console::Cmd_Room(int argc, const char **argv) { return true; } - _engine->_state.room = room; - _engine->clearScreen(); - _engine->loadRoom(_engine->_state.room); - _engine->showRoom(); - _engine->_display->updateTextScreen(); - _engine->_display->updateHiResScreen(); + _engine->switchRoom(room); + prepareGame(); } debugPrintf("Current room: %u\n", _engine->_state.room); diff --git a/engines/adl/console.h b/engines/adl/console.h index a8c6adc1cc..68787e148a 100644 --- a/engines/adl/console.h +++ b/engines/adl/console.h @@ -48,6 +48,7 @@ private: bool Cmd_Verbs(int argc, const char **argv); bool Cmd_DumpScripts(int argc, const char **argv); bool Cmd_ValidCommands(int argc, const char **argv); + bool Cmd_Region(int argc, const char **argv); bool Cmd_Room(int argc, const char **argv); bool Cmd_Items(int argc, const char **argv); bool Cmd_GiveItem(int argc, const char **argv); @@ -56,6 +57,8 @@ private: void printItem(const Item &item); void printWordMap(const Common::HashMap<Common::String, uint> &wordMap); + void dumpScripts(const Common::String &prefix = Common::String()); + void prepareGame(); AdlEngine *_engine; }; diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp index 2cf50f72fc..feef8fb2a4 100644 --- a/engines/adl/display.cpp +++ b/engines/adl/display.cpp @@ -130,7 +130,7 @@ Display::Display() : _frameBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8()); _textBuf = new byte[TEXT_BUF_SIZE]; - memset(_textBuf, APPLECHAR(' '), TEXT_BUF_SIZE); + memset(_textBuf, (byte)APPLECHAR(' '), TEXT_BUF_SIZE); _textBufSurface = new Graphics::Surface; // For ease of copying, also use 2x scaling here _textBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8()); @@ -267,7 +267,7 @@ void Display::clear(byte color) { } void Display::home() { - memset(_textBuf, APPLECHAR(' '), TEXT_BUF_SIZE); + memset(_textBuf, (byte)APPLECHAR(' '), TEXT_BUF_SIZE); _cursorPos = 0; } @@ -546,7 +546,7 @@ void Display::createFont() { void Display::scrollUp() { memmove(_textBuf, _textBuf + TEXT_WIDTH, TEXT_BUF_SIZE - TEXT_WIDTH); - memset(_textBuf + TEXT_BUF_SIZE - TEXT_WIDTH, APPLECHAR(' '), TEXT_WIDTH); + memset(_textBuf + TEXT_BUF_SIZE - TEXT_WIDTH, (byte)APPLECHAR(' '), TEXT_WIDTH); if (_cursorPos >= TEXT_WIDTH) _cursorPos -= TEXT_WIDTH; } diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp index 8bd49c75b4..e811b747c3 100644 --- a/engines/adl/hires1.cpp +++ b/engines/adl/hires1.cpp @@ -318,7 +318,8 @@ void HiRes1Engine::initGameState() { stream->seek(IDI_HR1_OFS_ITEMS); byte id; while ((id = stream->readByte()) != 0xff) { - Item item = Item(); + Item item; + item.id = id; item.noun = stream->readByte(); item.room = stream->readByte(); diff --git a/engines/adl/hires5.cpp b/engines/adl/hires5.cpp index a3ed6d890e..c1ada9e7d3 100644 --- a/engines/adl/hires5.cpp +++ b/engines/adl/hires5.cpp @@ -100,7 +100,7 @@ void HiRes5Engine::setupOpcodeTables() { // 0x04 Opcode(o1_listInv); Opcode(o4_moveItem); - Opcode(o4_setRoom); + Opcode(o1_setRoom); Opcode(o2_setCurPic); // 0x08 Opcode(o2_setPic); @@ -111,10 +111,10 @@ void HiRes5Engine::setupOpcodeTables() { Opcode(o4_moveAllItems); Opcode(o1_quit); Opcode(o4_setRegion); - Opcode(o2_save); // TODO + Opcode(o4_save); // 0x10 - Opcode(o2_restore); // TODO - Opcode(o1_restart); // TODO + Opcode(o4_restore); + Opcode(o4_restart); Opcode(o4_setRegionRoom); Opcode(o_startAnimation); // 0x14 @@ -244,7 +244,11 @@ void HiRes5Engine::init() { stream.reset(_disk->createReadStream(0x7, 0xc)); _strings.lineFeeds = readString(*stream); - // TODO: opcode strings + stream.reset(_disk->createReadStream(0x8, 0x3, 0x00, 2)); + _strings_v2.saveInsert = readStringAt(*stream, 0x66); + _strings_v2.saveReplace = readStringAt(*stream, 0x112); + _strings_v2.restoreInsert = readStringAt(*stream, 0x180); + _strings.playAgain = readStringAt(*stream, 0x247, 0xff); _messageIds.cantGoThere = 110; _messageIds.dontUnderstand = 112; diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp index 8f4de11e79..e22bcd3d50 100644 --- a/engines/fullpipe/detection.cpp +++ b/engines/fullpipe/detection.cpp @@ -25,6 +25,8 @@ #include "engines/advancedDetector.h" #include "common/file.h" +#include "graphics/surface.h" + #include "fullpipe/fullpipe.h" #include "fullpipe/gameloader.h" diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp index 10c1744dd9..9c474d111b 100644 --- a/engines/fullpipe/fullpipe.cpp +++ b/engines/fullpipe/fullpipe.cpp @@ -28,6 +28,7 @@ #include "audio/mixer.h" #include "engines/util.h" +#include "graphics/surface.h" #include "fullpipe/fullpipe.h" #include "fullpipe/gameloader.h" @@ -285,7 +286,8 @@ Common::Error FullpipeEngine::run() { // Initialize backend initGraphics(800, 600, true, &format); - _backgroundSurface.create(800, 600, format); + _backgroundSurface = new Graphics::Surface; + _backgroundSurface->create(800, 600, format); _origFormat = new Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); @@ -502,7 +504,9 @@ void FullpipeEngine::cleanup() { stopAllSoundStreams(); delete _origFormat; - _backgroundSurface.free(); + _backgroundSurface->free(); + + delete _backgroundSurface; } void FullpipeEngine::updateScreen() { diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h index b00da629fe..3733bed65d 100644 --- a/engines/fullpipe/fullpipe.h +++ b/engines/fullpipe/fullpipe.h @@ -30,8 +30,6 @@ #include "common/savefile.h" #include "common/system.h" -#include "graphics/transparent_surface.h" - #include "engines/engine.h" #include "gui/debugger.h" @@ -123,7 +121,7 @@ public: void updateEvents(); - Graphics::Surface _backgroundSurface; + Graphics::Surface *_backgroundSurface; Graphics::PixelFormat *_origFormat; GameLoader *_gameLoader; diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp index 4dec4b640c..619f41d6da 100644 --- a/engines/fullpipe/gfx.cpp +++ b/engines/fullpipe/gfx.cpp @@ -30,6 +30,7 @@ #include "fullpipe/gameloader.h" #include "common/memstream.h" +#include "graphics/transparent_surface.h" namespace Fullpipe { @@ -478,7 +479,7 @@ void Picture::freePicture() { if (_bitmap) { if (testFlags() && !_field_54) { freeData(); - //free(_bitmap); + free(_bitmap); _bitmap = 0; } } @@ -677,8 +678,8 @@ void Picture::displayPicture() { if (!_dataSize) return; - g_fp->_backgroundSurface.fillRect(Common::Rect(0, 0, 800, 600), 0); - g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(0, 0), g_fp->_backgroundSurface.pitch, 0, 0, 800, 600); + g_fp->_backgroundSurface->fillRect(Common::Rect(0, 0, 800, 600), 0); + g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(0, 0), g_fp->_backgroundSurface->pitch, 0, 0, 800, 600); draw(0, 0, 0, 0); @@ -771,6 +772,7 @@ Bitmap::Bitmap() { _flags = 0; _surface = 0; _flipping = Graphics::FLIP_NONE; + _copied_surface = false; } Bitmap::Bitmap(Bitmap *src) { @@ -783,15 +785,16 @@ Bitmap::Bitmap(Bitmap *src) { _height = src->_height; _pixels = src->_pixels; _surface = new Graphics::TransparentSurface(*src->_surface); + _copied_surface = true; _flipping = src->_flipping; } Bitmap::~Bitmap() { - if (_pixels) - free(_pixels); - _surface->free(); + if (!_copied_surface) + _surface->free(); delete _surface; + _surface = 0; _pixels = 0; } @@ -858,8 +861,8 @@ void Bitmap::putDib(int x, int y, int32 *palette, byte alpha) { int alphac = TS_ARGB(0xff, alpha, 0xff, 0xff); - _surface->blit(g_fp->_backgroundSurface, x1, y1, _flipping, &sub, alphac); - g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(x1, y1), g_fp->_backgroundSurface.pitch, x1, y1, sub.width(), sub.height()); + _surface->blit(*g_fp->_backgroundSurface, x1, y1, _flipping, &sub, alphac); + g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(x1, y1), g_fp->_backgroundSurface->pitch, x1, y1, sub.width(), sub.height()); } bool Bitmap::putDibRB(int32 *palette) { @@ -1255,7 +1258,7 @@ DynamicPhase *Shadows::findSize(int width, int height) { void FullpipeEngine::drawAlphaRectangle(int x1, int y1, int x2, int y2, int alpha) { for (int y = y1; y < y2; y++) { - uint32 *ptr = (uint32 *)g_fp->_backgroundSurface.getBasePtr(x1, y); + uint32 *ptr = (uint32 *)g_fp->_backgroundSurface->getBasePtr(x1, y); for (int x = x1; x < x2; x++) { uint32 color = *ptr; @@ -1274,8 +1277,8 @@ void FullpipeEngine::sceneFade(Scene *sc, bool direction) { int ticks = g_fp->_system->getMillis(); sc->draw(); - drawAlphaRectangle(0, 0, g_fp->_backgroundSurface.w, g_fp->_backgroundSurface.h, direction ? dim : 255 - dim); - g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(0, 0), g_fp->_backgroundSurface.pitch, 0, 0, 800, 600); + drawAlphaRectangle(0, 0, g_fp->_backgroundSurface->w, g_fp->_backgroundSurface->h, direction ? dim : 255 - dim); + g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface->getBasePtr(0, 0), g_fp->_backgroundSurface->pitch, 0, 0, 800, 600); g_fp->_system->updateScreen(); ticks = g_fp->_system->getMillis() - ticks; diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h index 566586fb48..43c23b49bc 100644 --- a/engines/fullpipe/gfx.h +++ b/engines/fullpipe/gfx.h @@ -23,6 +23,11 @@ #ifndef FULLPIPE_GFX_H #define FULLPIPE_GFX_H +namespace Graphics { + struct Surface; + struct TransparentSurface; +} + namespace Fullpipe { class DynamicPhase; @@ -40,6 +45,7 @@ struct Bitmap { int _flags; Graphics::TransparentSurface *_surface; int _flipping; + bool _copied_surface; Bitmap(); Bitmap(Bitmap *src); diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp index 41c1ba368b..3faa035c60 100644 --- a/engines/fullpipe/modal.cpp +++ b/engines/fullpipe/modal.cpp @@ -33,6 +33,7 @@ #include "fullpipe/objectnames.h" #include "graphics/palette.h" +#include "graphics/surface.h" #include "video/avi_decoder.h" #include "engines/savestate.h" @@ -2397,8 +2398,7 @@ bool ModalDemo::init(int counterDiff) { if (_clickedQuit == -1) return true; - // open URL - // http://www.amazon.de/EuroVideo-Bildprogramm-GmbH-Full-Pipe/dp/B003TO51YE/ref=sr_1_1?ie=UTF8&s=videogames&qid=1279207213&sr=8-1 + g_system->openUrl("http://www.amazon.de/EuroVideo-Bildprogramm-GmbH-Full-Pipe/dp/B003TO51YE/ref=sr_1_1?ie=UTF8&s=videogames&qid=1279207213&sr=8-1"); g_fp->_gameContinue = false; @@ -2407,8 +2407,7 @@ bool ModalDemo::init(int counterDiff) { bool ModalDemo::init2(int counterDiff) { if (_clickedQuit) { - // open URL - // http://pipestudio.ru/fullpipe/ + g_system->openUrl("http://pipestudio.ru/fullpipe/"); g_fp->_gameContinue = false; diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp index d560703fa5..4e3678bfb4 100644 --- a/engines/fullpipe/scene.cpp +++ b/engines/fullpipe/scene.cpp @@ -31,6 +31,7 @@ #include "fullpipe/constants.h" #include "common/algorithm.h" +#include "graphics/surface.h" namespace Fullpipe { @@ -534,7 +535,7 @@ void Scene::draw() { updateScrolling(); // Clean previous stuff - g_fp->_backgroundSurface.fillRect(Common::Rect(0, 0, 800, 600), 0); + g_fp->_backgroundSurface->fillRect(Common::Rect(0, 0, 800, 600), 0); drawContent(60000, 0, true); diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp index ece4f43e9f..bc66ebf40b 100644 --- a/engines/fullpipe/statics.cpp +++ b/engines/fullpipe/statics.cpp @@ -552,6 +552,8 @@ void Movement::draw(bool flipFlag, int angle) { } else { bmp->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData, _currDynamicPhase->_alpha); } + //Prevent memory leak after new was used to create bmp in reverseImage() + delete bmp; if (_currDynamicPhase->_rect->top) { if (!_currDynamicPhase->_convertedBitmap) { diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 0709bd4606..98dab7b176 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -840,16 +840,12 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_GK1_MAC }, -#define GUIO_GK2_DEMO GUIO5(GUIO_NOSPEECH, \ +#define GUIO_GK2_DEMO GUIO3(GUIO_NOSPEECH, \ GUIO_NOASPECT, \ - GAMEOPTION_PREFER_DIGITAL_SFX, \ - GAMEOPTION_ORIGINAL_SAVELOAD, \ - GAMEOPTION_FB01_MIDI) -#define GUIO_GK2 GUIO5(GAMEOPTION_ENABLE_BLACK_LINED_VIDEO, \ + GAMEOPTION_ORIGINAL_SAVELOAD) +#define GUIO_GK2 GUIO3(GAMEOPTION_ENABLE_BLACK_LINED_VIDEO, \ GUIO_NOASPECT, \ - GAMEOPTION_PREFER_DIGITAL_SFX, \ - GAMEOPTION_ORIGINAL_SAVELOAD, \ - GAMEOPTION_FB01_MIDI) + GAMEOPTION_ORIGINAL_SAVELOAD) #define GUIO_GK2_MAC GUIO_GK2 // Gabriel Knight 2 - English Windows Non-Interactive Demo diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 0e29ccf783..77ef92b349 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -102,15 +102,9 @@ reg_t kLock(EngineState *s, int argc, reg_t *argv) { } reg_t kResCheck(EngineState *s, int argc, reg_t *argv) { - Resource *res = NULL; + Resource *res = nullptr; ResourceType restype = g_sci->getResMan()->convertResType(argv[0].toUint16()); - if (restype == kResourceTypeVMD) { - char fileName[10]; - sprintf(fileName, "%d.vmd", argv[1].toUint16()); - return make_reg(0, Common::File::exists(fileName)); - } - if ((restype == kResourceTypeAudio36) || (restype == kResourceTypeSync36)) { if (argc >= 6) { uint noun = argv[2].toUint16() & 0xff; @@ -124,7 +118,16 @@ reg_t kResCheck(EngineState *s, int argc, reg_t *argv) { res = g_sci->getResMan()->testResource(ResourceId(restype, argv[1].toUint16())); } - return make_reg(0, res != NULL); +#ifdef ENABLE_SCI32 + // GK2 stores some VMDs inside of resource volumes, but usually they are + // streamed from the filesystem + if (res == nullptr && restype == kResourceTypeVMD) { + const Common::String fileName = Common::String::format("%u.vmd", argv[1].toUint16()); + return make_reg(0, Common::File::exists(fileName)); + } +#endif + + return make_reg(0, res != nullptr); } reg_t kClone(EngineState *s, int argc, reg_t *argv) { diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index dcefa219f7..0c4f0da959 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -1488,6 +1488,7 @@ static const uint16 kq6CDPatchAudioTextSupport2[] = { // Additional patch specifically for King's Quest 6 // Fixes special windows, used for example in the Pawn shop (room 280), // when the man in a robe complains about no more mints. +// Or also in room 300 at the cliffs (aka copy protection), when Alexander falls down the cliffs. // We have to change even more code, because the game uses PODialog class for // text windows and myDialog class for audio. Both are saved to KQ6Print::dialog // Sadly PODialog is created during KQ6Print::addText, myDialog is set during @@ -1514,13 +1515,34 @@ static const uint16 kq6CDSignatureAudioTextSupport3[] = { }; static const uint16 kq6CDPatchAudioTextSupport3[] = { - 0x31, 0x5c, // adjust jump to reuse audio mode addText-calling code - PATCH_ADDTOOFFSET(102), - 0x48, // ret - 0x48, // ret (waste byte) + 0x31, 0x68, // adjust jump to reuse audio mode addText-calling code + PATCH_ADDTOOFFSET(+85), // right at the MAGIC_DWORD + // check, if text is supposed to be shown. If yes, skip the follow-up check (param[1]) + 0x89, 0x5a, // lsg global[5Ah] + 0x35, 0x01, // ldi 01 + 0x12, // and + 0x2f, 0x07, // bt [skip over param check] + // original code, checks param[1] + 0x8f, 0x01, // lsp param[1] + 0x35, 0x01, // ldi 01 + 0x1a, // eq? + 0x31, 0x10, // bnt [code to set property repressText to 1], adjusted + // use myDialog class, so that text box automatically disappears (this is not done for text only mode, like in the original) 0x72, 0x0e, 0x00, // lofsa myDialog 0x65, 0x12, // aTop dialog - 0x33, 0xed, // jump back to audio mode addText-calling code + // followed by original addText-calling code + 0x38, + PATCH_GETORIGINALBYTE(+95), + PATCH_GETORIGINALBYTE(+96), // pushi addText + 0x78, // push1 + 0x8f, 0x02, // lsp param[2] + 0x59, 0x03, // &rest 03 + 0x54, 0x06, // self 06 + 0x48, // ret + + 0x35, 0x01, // ldi 01 + 0x65, 0x2e, // aTop repressText + 0x48, // ret PATCH_END }; diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index ed3c604f38..f3e22b7c51 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -521,7 +521,8 @@ const SciWorkaroundEntry kDisplay_workarounds[] = { { GID_LONGBOW, 220, 220, 0, "moveOn", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during second room "Outwit and outfight..." { GID_LONGBOW, 210, 210, 0, "mama", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during third room "Fall under the spell..." { GID_LONGBOW, 320, 320, 0, "flyin", "changeState", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during fourth room "Conspiracies, love..." - { GID_PQ2, 23, 23, 0, "rm23Script", "elements", sig_kDisplay_pq2_1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of pate's file - 0x75 as id - bug #5223 + { GID_PQ2, 23, 23, 0, "rm23Script", "elements", sig_kDisplay_pq2_1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of files in jail - 0x75 as id - bug #5223 + { GID_PQ2, 23, 23, 0, "rm23Script", "handleEvent", sig_kDisplay_pq2_1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the 2nd page of file in jail - 0x75 as id - bug #9670 { GID_QFG1, 11, 11, 0, "battle", "init", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When entering battle, 0x75 as id { GID_SQ4, 397, 0, 0, "", "export 12", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // FLOPPY: when going into the computer store - bug #5227 { GID_SQ4, 391, 391, 0, "doCatalog", "changeState", sig_kDisplay_sq4_1, 0, { WORKAROUND_IGNORE, 0 } }, // CD: clicking on catalog in roboter sale - a parameter is an object diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp index c3aafb62bf..4af1e76ed9 100644 --- a/engines/sci/graphics/video32.cpp +++ b/engines/sci/graphics/video32.cpp @@ -39,6 +39,7 @@ #include "sci/graphics/palette32.h" // for GfxPalette32 #include "sci/graphics/plane32.h" // for Plane, PlanePictureCodes::kP... #include "sci/graphics/screen_item32.h" // for ScaleInfo, ScreenItem, Scale... +#include "sci/resource.h" // for ResourceManager, ResourceId,... #include "sci/sci.h" // for SciEngine, g_sci, getSciVersion #include "sci/sound/audio32.h" // for Audio32 #include "sci/video/seq_decoder.h" // for SEQDecoder @@ -492,6 +493,7 @@ VMDPlayer::VMDPlayer(SegManager *segMan, EventManager *eventMan) : _isOpen(false), _isInitialized(false), + _bundledVmd(nullptr), _yieldFrame(0), _yieldInterval(0), _lastYieldedFrameNo(0), @@ -536,15 +538,29 @@ VMDPlayer::IOStatus VMDPlayer::open(const Common::String &fileName, const OpenFl g_sci->_audio32->stop(kAllChannels); } - if (_decoder->loadFile(fileName)) { + Resource *bundledVmd = g_sci->getResMan()->findResource(ResourceId(kResourceTypeVMD, fileName.asUint64()), true); + + if (bundledVmd != nullptr) { + Common::SeekableReadStream *stream = bundledVmd->makeStream(); + if (_decoder->loadStream(stream)) { + _bundledVmd = bundledVmd; + _isOpen = true; + } else { + delete stream; + g_sci->getResMan()->unlockResource(bundledVmd); + } + } else if (_decoder->loadFile(fileName)) { + _isOpen = true; + } + + if (_isOpen) { if (flags & kOpenFlagMute) { _decoder->setVolume(0); } - _isOpen = true; return kIOSuccess; - } else { - return kIOError; } + + return kIOError; } void VMDPlayer::init(const int16 x, const int16 y, const PlayFlags flags, const int16 boostPercent, const int16 boostStartColor, const int16 boostEndColor) { @@ -571,6 +587,11 @@ VMDPlayer::IOStatus VMDPlayer::close() { _isInitialized = false; _ignorePalettes = false; + if (_bundledVmd) { + g_sci->getResMan()->unlockResource(_bundledVmd); + _bundledVmd = nullptr; + } + _segMan->freeBitmap(_screenItem->_celInfo.bitmap); if (!_planeIsOwned && _screenItem != nullptr) { diff --git a/engines/sci/graphics/video32.h b/engines/sci/graphics/video32.h index 69acdf2fce..5ed8fd954a 100644 --- a/engines/sci/graphics/video32.h +++ b/engines/sci/graphics/video32.h @@ -321,6 +321,13 @@ private: bool _isInitialized; /** + * The Resource object for VMDs that are read out + * of a resource bundle instead of being streamed + * from the filesystem. + */ + Resource *_bundledVmd; + + /** * For VMDs played with the `kEventFlagToFrame` flag, * the target frame for yielding back to the SCI VM. */ diff --git a/engines/titanic/carry/bridge_piece.cpp b/engines/titanic/carry/bridge_piece.cpp index 487ea32df6..f90f7cbd4d 100644 --- a/engines/titanic/carry/bridge_piece.cpp +++ b/engines/titanic/carry/bridge_piece.cpp @@ -77,7 +77,7 @@ bool CBridgePiece::UseWithOtherMsg(CUseWithOtherMsg *msg) { } else if (name == "SeasonBridge") { frameMsg._frameNumber = 3; } else if (name == "BeamBridge") { - frameMsg._frameNumber = 0; + frameMsg._frameNumber = 4; } frameMsg.execute(shipSetting); diff --git a/engines/titanic/carry/carry_parrot.cpp b/engines/titanic/carry/carry_parrot.cpp index ed86384147..8b332610e2 100644 --- a/engines/titanic/carry/carry_parrot.cpp +++ b/engines/titanic/carry/carry_parrot.cpp @@ -42,13 +42,13 @@ BEGIN_MESSAGE_MAP(CCarryParrot, CCarry) ON_MESSAGE(ActMsg) END_MESSAGE_MAP() -CCarryParrot::CCarryParrot() : CCarry(), _string6("PerchedParrot"), +CCarryParrot::CCarryParrot() : CCarry(), _parrotName("PerchedParrot"), _timerId(0), _freeCounter(0), _feathersFlag(false) { } void CCarryParrot::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeQuotedLine(_string6, indent); + file->writeQuotedLine(_parrotName, indent); file->writeNumberLine(_timerId, indent); file->writeNumberLine(_freeCounter, indent); file->writeNumberLine(_feathersFlag, indent); @@ -58,7 +58,7 @@ void CCarryParrot::save(SimpleFile *file, int indent) { void CCarryParrot::load(SimpleFile *file) { file->readNumber(); - _string6 = file->readString(); + _parrotName = file->readString(); _timerId = file->readNumber(); _freeCounter = file->readNumber(); _feathersFlag = file->readNumber(); @@ -67,7 +67,7 @@ void CCarryParrot::load(SimpleFile *file) { } bool CCarryParrot::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { - CParrot::_v4 = 4; + CParrot::_state = PARROT_4; CActMsg actMsg("Shut"); actMsg.execute("ParrotCage"); @@ -75,7 +75,7 @@ bool CCarryParrot::PETGainedObjectMsg(CPETGainedObjectMsg *msg) { } bool CCarryParrot::TimerMsg(CTimerMsg *msg) { - if (CParrot::_v4 == 1 || CParrot::_v4 == 4) { + if (CParrot::_state == PARROT_1 || CParrot::_state == PARROT_4) { if (++_freeCounter >= 30) { CActMsg actMsg("FreeParrot"); actMsg.execute(this); @@ -94,7 +94,7 @@ bool CCarryParrot::LeaveViewMsg(CLeaveViewMsg *msg) { if (_visible) { setVisible(false); _fieldE0 = 0; - CParrot::_v4 = 2; + CParrot::_state = PARROT_ESCAPED; } return true; @@ -105,10 +105,7 @@ bool CCarryParrot::MouseDragEndMsg(CMouseDragEndMsg *msg) { if (msg->_mousePos.y >= 360) { petAddToInventory(); - return true; - } - - if (compareViewNameTo("ParrotLobby.Node 1.N")) { + } else if (compareViewNameTo("ParrotLobby.Node 1.N")) { if (msg->_mousePos.x >= 75 && msg->_mousePos.x <= 565 && !CParrot::_v2 && !CCage::_open) { setVisible(false); @@ -123,7 +120,7 @@ bool CCarryParrot::MouseDragEndMsg(CMouseDragEndMsg *msg) { } else { setVisible(false); _fieldE0 = 0; - CParrot::_v4 = 2; + CParrot::_state = PARROT_ESCAPED; playSound("z#475.wav"); sound8(true); moveUnder(findRoom()); @@ -150,7 +147,7 @@ bool CCarryParrot::MouseDragEndMsg(CMouseDragEndMsg *msg) { } bool CCarryParrot::PassOnDragStartMsg(CPassOnDragStartMsg *msg) { - if (CParrot::_v4 != 3) { + if (CParrot::_state != PARROT_MAILED) { moveToView(); setPosition(Point(0, 0)); setVisible(true); @@ -161,21 +158,22 @@ bool CCarryParrot::PassOnDragStartMsg(CPassOnDragStartMsg *msg) { _timerId = addTimer(1000, 1000); _freeCounter = 0; - CParrot::_v4 = 1; + CParrot::_state = PARROT_1; msg->_value3 = 1; return CCarry::PassOnDragStartMsg(msg); } - CTrueTalkNPC *npc = dynamic_cast<CTrueTalkNPC *>(getRoot()->findByName(_string6)); + CTrueTalkNPC *npc = dynamic_cast<CTrueTalkNPC *>(getRoot()->findByName(_parrotName)); if (npc) startTalking(npc, 0x446BF); _fieldE0 = 0; playSound("z#475.wav"); moveUnder(findRoom()); - msg->_value4 = 1; + CParrot::_state = PARROT_ESCAPED; + msg->_value4 = 1; return true; } @@ -191,24 +189,21 @@ bool CCarryParrot::PreEnterViewMsg(CPreEnterViewMsg *msg) { bool CCarryParrot::UseWithCharMsg(CUseWithCharMsg *msg) { CSuccUBus *succubus = dynamic_cast<CSuccUBus *>(msg->_character); if (succubus) - CParrot::_v4 = 3; + CParrot::_state = PARROT_MAILED; return CCarry::UseWithCharMsg(msg); } bool CCarryParrot::ActMsg(CActMsg *msg) { - if (msg->_action == "FreeParrot" && (CParrot::_v4 == 4 || CParrot::_v4 == 1)) { - CTrueTalkNPC *npc = dynamic_cast<CTrueTalkNPC *>(getRoot()->findByName(_string6)); + if (msg->_action == "FreeParrot" && (CParrot::_state == PARROT_4 || CParrot::_state == PARROT_1)) { + CTrueTalkNPC *npc = dynamic_cast<CTrueTalkNPC *>(getRoot()->findByName(_parrotName)); if (npc) startTalking(npc, 0x446BF); setVisible(false); _fieldE0 = 0; - if (CParrot::_v4 == 4) { - CActMsg actMsg("Shut"); - actMsg.execute("ParrotCage"); - } else { + if (CParrot::_state == PARROT_4) { playSound("z#475.wav"); if (!_feathersFlag) { @@ -221,13 +216,17 @@ bool CCarryParrot::ActMsg(CActMsg *msg) { _feathersFlag = true; } - getPetControl()->removeFromInventory(this); - getPetControl()->setAreaChangeType(1); + CPetControl *pet = getPetControl(); + pet->removeFromInventory(this); + pet->setAreaChangeType(1); moveUnder(getRoom()); + } else { + CActMsg actMsg("Shut"); + actMsg.execute("ParrotCage"); } - CParrot::_v4 = 2; - stopTimer(_timerId); + CParrot::_state = PARROT_ESCAPED; + stopAnimTimer(_timerId); _timerId = 0; } diff --git a/engines/titanic/carry/carry_parrot.h b/engines/titanic/carry/carry_parrot.h index c42475e5f0..e165482edc 100644 --- a/engines/titanic/carry/carry_parrot.h +++ b/engines/titanic/carry/carry_parrot.h @@ -42,7 +42,7 @@ class CCarryParrot : public CCarry { bool UseWithCharMsg(CUseWithCharMsg *msg); bool ActMsg(CActMsg *msg); private: - CString _string6; + CString _parrotName; int _timerId; int _freeCounter; bool _feathersFlag; diff --git a/engines/titanic/continue_save_dialog.h b/engines/titanic/continue_save_dialog.h index 58c7deef00..b6d9aebfac 100644 --- a/engines/titanic/continue_save_dialog.h +++ b/engines/titanic/continue_save_dialog.h @@ -28,7 +28,7 @@ #include "titanic/support/image.h" #include "titanic/support/rect.h" #include "titanic/support/string.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { @@ -43,7 +43,7 @@ class CContinueSaveDialog : public CEventTarget { }; private: Common::Array<SaveEntry> _saves; - CPetText _slotNames[5]; + CTextControl _slotNames[5]; int _highlightedSlot, _selectedSlot; Point _mousePos; bool _evilTwinShown; diff --git a/engines/titanic/core/drop_target.cpp b/engines/titanic/core/drop_target.cpp index f02efeee5d..ffeab03545 100644 --- a/engines/titanic/core/drop_target.cpp +++ b/engines/titanic/core/drop_target.cpp @@ -34,7 +34,7 @@ BEGIN_MESSAGE_MAP(CDropTarget, CGameObject) END_MESSAGE_MAP() CDropTarget::CDropTarget() : CGameObject(), _itemFrame(0), - _itemMatchSize(0), _showItem(false), _fieldF4(0), _dropFrame(0), + _itemMatchSize(0), _showItem(false), _dropEnabled(false), _dropFrame(0), _dragFrame(0), _dragCursorId(CURSOR_ARROW), _dropCursorId(CURSOR_HAND), _clipFlags(20) { } @@ -48,7 +48,7 @@ void CDropTarget::save(SimpleFile *file, int indent) { file->writeQuotedLine(_soundName, indent); file->writeNumberLine(_showItem, indent); file->writeQuotedLine(_itemName, indent); - file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_dropEnabled, indent); file->writeNumberLine(_dropFrame, indent); file->writeNumberLine(_dragFrame, indent); file->writeQuotedLine(_clipName, indent); @@ -68,7 +68,7 @@ void CDropTarget::load(SimpleFile *file) { _soundName = file->readString(); _showItem = file->readNumber(); _itemName = file->readString(); - _fieldF4 = file->readNumber(); + _dropEnabled = file->readNumber(); _dropFrame = file->readNumber(); _dragFrame = file->readNumber(); _clipName = file->readString(); @@ -119,7 +119,7 @@ bool CDropTarget::MouseDragStartMsg(CMouseDragStartMsg *msg) { msg->_dragItem = dragItem; CGameObject *obj = dynamic_cast<CGameObject *>(findByName(_itemName)); - if (_itemName.empty() || _fieldF4 || !obj) + if (_itemName.empty() || _dropEnabled || !obj) return false; CDropZoneLostObjectMsg lostMsg; @@ -161,7 +161,7 @@ bool CDropTarget::EnterViewMsg(CEnterViewMsg *msg) { bool CDropTarget::VisibleMsg(CVisibleMsg *msg) { setVisible(msg->_visible); - _fieldF4 = !msg->_visible; + _dropEnabled = !msg->_visible; return true; } diff --git a/engines/titanic/core/drop_target.h b/engines/titanic/core/drop_target.h index e07b640c9f..bdf8891789 100644 --- a/engines/titanic/core/drop_target.h +++ b/engines/titanic/core/drop_target.h @@ -42,7 +42,7 @@ protected: CString _soundName; bool _showItem; CString _itemName; - int _fieldF4; + bool _dropEnabled; int _dropFrame; int _dragFrame; CString _clipName; diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp index bfcfa9fbff..0a0b3b1c42 100644 --- a/engines/titanic/core/game_object.cpp +++ b/engines/titanic/core/game_object.cpp @@ -63,7 +63,7 @@ CGameObject::CGameObject(): CNamedItem() { _field44 = 0xF0; _field48 = 0xF0; _field4C = 0xFF; - _isMail = false; + _isPendingMail = false; _destRoomFlags = 0; _roomFlags = 0; _visible = true; @@ -119,7 +119,7 @@ void CGameObject::save(SimpleFile *file, int indent) { file->writeNumberLine(_field4C, indent + 1); file->writeNumberLine(_fieldB8, indent + 1); file->writeNumberLine(_visible, indent + 1); - file->writeNumberLine(_isMail, indent + 1); + file->writeNumberLine(_isPendingMail, indent + 1); file->writeNumberLine(_destRoomFlags, indent + 1); file->writeNumberLine(_roomFlags, indent + 1); @@ -174,7 +174,7 @@ void CGameObject::load(SimpleFile *file) { _field4C = file->readNumber(); _fieldB8 = file->readNumber(); _visible = file->readNumber() != 0; - _isMail = file->readNumber(); + _isPendingMail = file->readNumber(); _destRoomFlags = file->readNumber(); _roomFlags = file->readNumber(); @@ -1081,10 +1081,11 @@ void CGameObject::setMovieFrameRate(double rate) { void CGameObject::setText(const CString &str, int border, int borderRight) { if (!_text) - _text = new CPetText(); + _text = new CTextControl(); _textBorder = border; _textBorderRight = borderRight; + setTextBounds(); _text->setText(str); CScreenManager *screenManager = getGameManager()->setScreenManager(); _text->scrollToTop(screenManager); @@ -1092,7 +1093,7 @@ void CGameObject::setText(const CString &str, int border, int borderRight) { void CGameObject::setTextHasBorders(bool hasBorders) { if (!_text) - _text = new CPetText(); + _text = new CTextControl(); _text->setHasBorder(hasBorders); } @@ -1108,14 +1109,14 @@ void CGameObject::setTextBounds() { void CGameObject::setTextColor(byte r, byte g, byte b) { if (!_text) - _text = new CPetText(); + _text = new CTextControl(); _text->setColor(r, g, b); } void CGameObject::setTextFontNumber(int fontNumber) { if (!_text) - _text = new CPetText(); + _text = new CTextControl(); _text->setFontNumber(fontNumber); } @@ -1132,11 +1133,13 @@ CTextCursor *CGameObject::getTextCursor() const { void CGameObject::scrollTextUp() { if (_text) _text->scrollUp(CScreenManager::_screenManagerPtr); + makeDirty(); } void CGameObject::scrollTextDown() { if (_text) _text->scrollDown(CScreenManager::_screenManagerPtr); + makeDirty(); } void CGameObject::lockMouse() { @@ -1451,10 +1454,10 @@ CGameObject *CGameObject::findMail(uint roomFlags) const { return mailMan ? mailMan->findMail(roomFlags) : nullptr; } -void CGameObject::removeMail(uint destRoomFlags, uint newRoomFlags) { +void CGameObject::sendMail(uint currRoomFlags, uint newRoomFlags) { CMailMan *mailMan = getMailMan(); if (mailMan) - mailMan->removeMail(destRoomFlags, newRoomFlags); + mailMan->sendMail(currRoomFlags, newRoomFlags); } void CGameObject::resetMail() { diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h index 8702b5f522..629c6a038d 100644 --- a/engines/titanic/core/game_object.h +++ b/engines/titanic/core/game_object.h @@ -34,7 +34,7 @@ #include "titanic/support/strings.h" #include "titanic/support/movie_clip.h" #include "titanic/pet_control/pet_section.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" #include "titanic/game_state.h" namespace Titanic { @@ -87,7 +87,7 @@ protected: int _initialFrame; CMovieRangeInfoList _movieRangeInfoList; int _frameNumber; - CPetText *_text; + CTextControl *_text; uint _textBorder; uint _textBorderRight; int _field9C; @@ -519,57 +519,12 @@ protected: void setMovieFrameRate(double rate); /** - * Set up the text and borders for the object - */ - void setText(const CString &str, int border = 0, int borderRight = 0); - - /** - * Sets whether the text will use borders - */ - void setTextHasBorders(bool hasBorders); - - /** - * Sets the bounds for a previously defined text area - */ - void setTextBounds(); - - /** - * Sets the color for the object's text - */ - void setTextColor(byte r, byte g, byte b); - - /** - * Sets the font number to use for text - */ - void setTextFontNumber(int fontNumber); - - /** - * Gets the width of the text contents - */ - int getTextWidth() const; - - /** - * Returns the text cursor - */ - CTextCursor *getTextCursor() const; - - /** - * Scroll text up - */ - void scrollTextUp(); - - /** - * Scroll text down - */ - void scrollTextDown(); - - /** * Gets a new random number */ int getRandomNumber(int max, int *oldVal = nullptr); public: Rect _bounds; - bool _isMail; + bool _isPendingMail; uint _destRoomFlags; uint _roomFlags; int _field60; @@ -748,11 +703,6 @@ public: CGameObject *getHiddenObject(const CString &name) const; /** - * Sets up credits text - */ - void createCredits(); - - /** * Support function for drag moving */ void dragMove(const Point &pt); @@ -764,6 +714,58 @@ public: bool compareRoomFlags(int mode, uint flags1, uint flags2); + /*--- Text display methods ---*/ + + /** + * Sets up credits text + */ + void createCredits(); + + /** + * Set up the text and borders for the object + */ + void setText(const CString &str, int border = 0, int borderRight = 0); + + /** + * Sets whether the text will use borders + */ + void setTextHasBorders(bool hasBorders); + + /** + * Sets the bounds for a previously defined text area + */ + void setTextBounds(); + + /** + * Sets the color for the object's text + */ + void setTextColor(byte r, byte g, byte b); + + /** + * Sets the font number to use for text + */ + void setTextFontNumber(int fontNumber); + + /** + * Gets the width of the text contents + */ + int getTextWidth() const; + + /** + * Scroll text up + */ + void scrollTextUp(); + + /** + * Scroll text down + */ + void scrollTextDown(); + + /** + * Returns the text cursor + */ + CTextCursor *getTextCursor() const; + /*--- CGameManager Methods ---*/ /** @@ -797,9 +799,9 @@ public: void addMail(uint destRoomFlags); /** - * Remove an object from the mail list + * Sends a pending mail object to a given destination */ - void removeMail(uint destRoomFlags, uint newRoomFlags); + void sendMail(uint currRoomFlags, uint newRoomFlags); /** * Return the full Id of the current view in a diff --git a/engines/titanic/core/mail_man.cpp b/engines/titanic/core/mail_man.cpp index 851e52694d..a34c69674b 100644 --- a/engines/titanic/core/mail_man.cpp +++ b/engines/titanic/core/mail_man.cpp @@ -56,22 +56,22 @@ void CMailMan::addMail(CGameObject *obj, uint destRoomFlags) { void CMailMan::setMailDest(CGameObject *obj, uint roomFlags) { obj->_destRoomFlags = roomFlags; obj->_roomFlags = 0; - obj->_isMail = true; + obj->_isPendingMail = true; } CGameObject *CMailMan::findMail(uint roomFlags) const { for (CGameObject *obj = getFirstObject(); obj; obj = getNextObject(obj)) { - if (obj->_isMail && obj->_destRoomFlags == roomFlags) + if (obj->_isPendingMail && obj->_destRoomFlags == roomFlags) return obj; } return nullptr; } -void CMailMan::removeMail(uint destRoomFlags, uint newRoomFlags) { +void CMailMan::sendMail(uint currRoomFlags, uint newRoomFlags) { for (CGameObject *obj = getFirstObject(); obj; obj = getNextObject(obj)) { - if (obj->_isMail && obj->_destRoomFlags == destRoomFlags) { - obj->_isMail = false; + if (obj->_isPendingMail && obj->_destRoomFlags == currRoomFlags) { + obj->_isPendingMail = false; obj->_roomFlags = newRoomFlags; break; } diff --git a/engines/titanic/core/mail_man.h b/engines/titanic/core/mail_man.h index 0a8d5fa90a..b5d6a153fc 100644 --- a/engines/titanic/core/mail_man.h +++ b/engines/titanic/core/mail_man.h @@ -71,9 +71,9 @@ public: CGameObject *findMail(uint roomFlags) const; /** - * Remove a mail item + * Sends a pending mail object to a given destination */ - void removeMail(uint destRoomFlags, uint newRoomFlags); + void sendMail(uint currRoomFlags, uint newRoomFlags); void resetValue() { _value = 0; } }; diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp index af67f69580..1093a5c6e7 100644 --- a/engines/titanic/core/project_item.cpp +++ b/engines/titanic/core/project_item.cpp @@ -158,8 +158,8 @@ void CProjectItem::loadGame(int slotId) { CompressedFile file; // Clear any existing project contents and call preload code - clear(); preLoad(); + clear(); // Open either an existing savegame slot or the new game template if (slotId >= 0) { @@ -309,6 +309,10 @@ void CProjectItem::saveData(SimpleFile *file, CTreeItem *item) const { void CProjectItem::preLoad() { if (_gameManager) _gameManager->preLoad(); + + CScreenManager *scrManager = CScreenManager::_currentScreenManagerPtr; + if (scrManager) + scrManager->preLoad(); } void CProjectItem::postLoad() { diff --git a/engines/titanic/core/saveable_object.cpp b/engines/titanic/core/saveable_object.cpp index 73b4bf861f..f718ba79b3 100644 --- a/engines/titanic/core/saveable_object.cpp +++ b/engines/titanic/core/saveable_object.cpp @@ -1473,6 +1473,9 @@ void CSaveableObject::initClassList() { ADDFN(CEnterNodeMsg, CMessage); ADDFN(CEnterRoomMsg, CMessage); ADDFN(CEnterViewMsg, CMessage); + ADDFN(CPreEnterNodeMsg, CMessage); + ADDFN(CPreEnterRoomMsg, CMessage); + ADDFN(CPreEnterViewMsg, CMessage); ADDFN(CPreSaveMsg, CMessage); ADDFN(CProdMaitreDMsg, CMessage); ADDFN(CPumpingMsg, CMessage); diff --git a/engines/titanic/core/view_item.cpp b/engines/titanic/core/view_item.cpp index c25461f5cc..9109bcc5b2 100644 --- a/engines/titanic/core/view_item.cpp +++ b/engines/titanic/core/view_item.cpp @@ -195,6 +195,8 @@ bool CViewItem::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { linkItem = dynamic_cast<CLinkItem *>( findNextInstanceOf(CLinkItem::_type, linkItem)); } + + handleMouseMsg(msg, false); } } } diff --git a/engines/titanic/events.cpp b/engines/titanic/events.cpp index 97f9a86eb3..d29a19dec6 100644 --- a/engines/titanic/events.cpp +++ b/engines/titanic/events.cpp @@ -127,7 +127,7 @@ bool Events::checkForNextFrameCounter() { } uint32 Events::getTicksCount() const { - return g_system->getMillis(); + return _frameCounter * GAME_FRAME_TIME; } void Events::sleep(uint time) { diff --git a/engines/titanic/game/announce.cpp b/engines/titanic/game/announce.cpp index 74c126476f..16298f7b99 100644 --- a/engines/titanic/game/announce.cpp +++ b/engines/titanic/game/announce.cpp @@ -30,14 +30,14 @@ BEGIN_MESSAGE_MAP(CAnnounce, CGameObject) ON_MESSAGE(ActMsg) END_MESSAGE_MAP() -CAnnounce::CAnnounce() : _nameIndex(0), _soundHandle(0), _leaveFlag(1), _enabled(false) { +CAnnounce::CAnnounce() : _nameIndex(0), _soundHandle(0), _notActivatedFlag(true), _enabled(false) { } void CAnnounce::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); file->writeNumberLine(_nameIndex, indent); file->writeNumberLine(_soundHandle, indent); - file->writeNumberLine(_leaveFlag, indent); + file->writeNumberLine(_notActivatedFlag, indent); file->writeNumberLine(_enabled, indent); CGameObject::save(file, indent); @@ -47,7 +47,7 @@ void CAnnounce::load(SimpleFile *file) { file->readNumber(); _nameIndex = file->readNumber(); _soundHandle = file->readNumber(); - _leaveFlag = file->readNumber(); + _notActivatedFlag = file->readNumber(); _enabled = file->readNumber(); CGameObject::load(file); @@ -97,6 +97,7 @@ bool CAnnounce::TimerMsg(CTimerMsg *msg) { break; } + // Schedule another announcement for a random future time addTimer(1, 300000 + getRandomNumber(30000), 0); if (getRandomNumber(3) == 0) addTimer(2, 4000, 0); @@ -111,9 +112,10 @@ bool CAnnounce::TimerMsg(CTimerMsg *msg) { } bool CAnnounce::LeaveRoomMsg(CLeaveRoomMsg *msg) { - if (_leaveFlag) { + // The very first time the player leaves the Embarklation Lobby, start announcements + if (_notActivatedFlag) { addTimer(1, 1000, 0); - _leaveFlag = 0; + _notActivatedFlag = false; _enabled = true; } @@ -121,6 +123,7 @@ bool CAnnounce::LeaveRoomMsg(CLeaveRoomMsg *msg) { } bool CAnnounce::ActMsg(CActMsg *msg) { + // Handle enabling or disabling announcements if (msg->_action == "Enable") _enabled = true; else if (msg->_action == "Disable") diff --git a/engines/titanic/game/announce.h b/engines/titanic/game/announce.h index 9bf060daae..caacb8ffa1 100644 --- a/engines/titanic/game/announce.h +++ b/engines/titanic/game/announce.h @@ -35,7 +35,7 @@ class CAnnounce : public CGameObject { private: int _nameIndex; int _soundHandle; - bool _leaveFlag; + bool _notActivatedFlag; bool _enabled; public: CLASSDEF; diff --git a/engines/titanic/game/broken_pell_base.cpp b/engines/titanic/game/broken_pell_base.cpp index 02c2d873ac..a3825d503e 100644 --- a/engines/titanic/game/broken_pell_base.cpp +++ b/engines/titanic/game/broken_pell_base.cpp @@ -33,7 +33,7 @@ void CBrokenPellBase::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); file->writeNumberLine(_v1, indent); file->writeNumberLine(_v2, indent); - file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_exitAction, indent); CBackground::save(file, indent); } @@ -41,7 +41,7 @@ void CBrokenPellBase::load(SimpleFile *file) { file->readNumber(); _v1 = file->readNumber(); _v2 = file->readNumber(); - _fieldE0 = file->readNumber(); + _exitAction = file->readNumber(); CBackground::load(file); } diff --git a/engines/titanic/game/broken_pell_base.h b/engines/titanic/game/broken_pell_base.h index 4ca7eddd20..c5b27d88bf 100644 --- a/engines/titanic/game/broken_pell_base.h +++ b/engines/titanic/game/broken_pell_base.h @@ -33,10 +33,10 @@ protected: static bool _v1; static int _v2; - int _fieldE0; + int _exitAction; public: CLASSDEF; - CBrokenPellBase() : CBackground(), _fieldE0(0) {} + CBrokenPellBase() : CBackground(), _exitAction(0) {} /** * Save the data for the class to file diff --git a/engines/titanic/game/broken_pellerator.cpp b/engines/titanic/game/broken_pellerator.cpp index 8fb7244b7e..d3664acccd 100644 --- a/engines/titanic/game/broken_pellerator.cpp +++ b/engines/titanic/game/broken_pellerator.cpp @@ -34,8 +34,8 @@ END_MESSAGE_MAP() void CBrokenPellerator::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeQuotedLine(_string2, indent); - file->writeQuotedLine(_string3, indent); + file->writeQuotedLine(_exitLeftView, indent); + file->writeQuotedLine(_exitRightView, indent); file->writeQuotedLine(_string4, indent); file->writeQuotedLine(_string5, indent); @@ -44,8 +44,8 @@ void CBrokenPellerator::save(SimpleFile *file, int indent) { void CBrokenPellerator::load(SimpleFile *file) { file->readNumber(); - _string2 = file->readString(); - _string3 = file->readString(); + _exitLeftView = file->readString(); + _exitRightView = file->readString(); _string4 = file->readString(); _string5 = file->readString(); @@ -86,15 +86,15 @@ bool CBrokenPellerator::ActMsg(CActMsg *msg) { CStatusChangeMsg statusMsg; statusMsg.execute("PickupHose"); } else { - _fieldE0 = 0; + _exitAction = 0; bool closeFlag = msg->_action == "Close"; if (msg->_action == "CloseLeft") { closeFlag = true; - _fieldE0 = 1; + _exitAction = 1; } if (msg->_action == "CloseRight") { closeFlag = true; - _fieldE0 = 2; + _exitAction = 2; } if (closeFlag) { @@ -105,18 +105,18 @@ bool CBrokenPellerator::ActMsg(CActMsg *msg) { else playMovie(14, 28, MOVIE_NOTIFY_OBJECT); } else { - switch (_fieldE0) { + switch (_exitAction) { case 1: - changeView(_string2); + changeView(_exitLeftView); break; case 2: - changeView(_string3); + changeView(_exitRightView); break; default: break; } - _fieldE0 = 0; + _exitAction = 0; } } } @@ -126,23 +126,25 @@ bool CBrokenPellerator::ActMsg(CActMsg *msg) { bool CBrokenPellerator::MovieEndMsg(CMovieEndMsg *msg) { if (msg->_endFrame == 14) { + // Pellerator has been opened, so let the hose be picked up (if it's still there) CStatusChangeMsg statusMsg; statusMsg._newStatus = 1; statusMsg.execute("PickUpHose"); } if (msg->_endFrame == 28) { + // Pellerator has been closed, so disable the hose (if it's still there) CStatusChangeMsg statusMsg; statusMsg._newStatus = 0; statusMsg.execute("PickUpHose"); } - switch (_fieldE0) { + switch (_exitAction) { case 1: - changeView(_string2); + changeView(_exitLeftView); break; case 2: - changeView(_string3); + changeView(_exitRightView); break; default: break; diff --git a/engines/titanic/game/broken_pellerator.h b/engines/titanic/game/broken_pellerator.h index 3b8c3ba587..f243f4ebfe 100644 --- a/engines/titanic/game/broken_pellerator.h +++ b/engines/titanic/game/broken_pellerator.h @@ -34,8 +34,8 @@ class CBrokenPellerator : public CBrokenPellBase { bool ActMsg(CActMsg *msg); bool MovieEndMsg(CMovieEndMsg *msg); private: - CString _string2; - CString _string3; + CString _exitLeftView; + CString _exitRightView; CString _string4; CString _string5; public: diff --git a/engines/titanic/game/broken_pellerator_froz.cpp b/engines/titanic/game/broken_pellerator_froz.cpp index 690ab76820..7025b37a0c 100644 --- a/engines/titanic/game/broken_pellerator_froz.cpp +++ b/engines/titanic/game/broken_pellerator_froz.cpp @@ -85,15 +85,15 @@ bool CBrokenPelleratorFroz::ActMsg(CActMsg *msg) { statusMsg._newStatus = 0; statusMsg.execute("FPickUpHose"); } else { - _fieldE0 = 0; + _exitAction = 0; bool closeFlag = msg->_action == "Close"; if (msg->_action == "CloseLeft") { closeFlag = true; - _fieldE0 = 1; + _exitAction = 1; } if (msg->_action == "CloseRight") { closeFlag = true; - _fieldE0 = 2; + _exitAction = 2; } if (closeFlag) { @@ -104,7 +104,7 @@ bool CBrokenPelleratorFroz::ActMsg(CActMsg *msg) { else playMovie(72, 84, MOVIE_NOTIFY_OBJECT); } else { - switch (_fieldE0) { + switch (_exitAction) { case 1: changeView(_string2); break; @@ -115,7 +115,7 @@ bool CBrokenPelleratorFroz::ActMsg(CActMsg *msg) { break; } - _fieldE0 = 0; + _exitAction = 0; } } } @@ -136,12 +136,12 @@ bool CBrokenPelleratorFroz::MovieEndMsg(CMovieEndMsg *msg) { statusMsg.execute("FPickUpHose"); } - if (_fieldE0 == 1) { + if (_exitAction == 1) { changeView(_string2); - _fieldE0 = 0; - } else if (_fieldE0 == 2) { + _exitAction = 0; + } else if (_exitAction == 2) { changeView(_string3); - _fieldE0 = 0; + _exitAction = 0; } return true; diff --git a/engines/titanic/game/cage.cpp b/engines/titanic/game/cage.cpp index bbac384cea..11f5837e4c 100644 --- a/engines/titanic/game/cage.cpp +++ b/engines/titanic/game/cage.cpp @@ -53,7 +53,7 @@ void CCage::load(SimpleFile *file) { } bool CCage::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { - if (CParrot::_v4 && !CParrot::_v5) { + if (CParrot::_state != PARROT_IN_CAGE && !CParrot::_v5) { CActMsg actMsg(_open ? "Open" : "Shut"); actMsg.execute(this); } @@ -88,7 +88,7 @@ bool CCage::MovieEndMsg(CMovieEndMsg *msg) { _open = clipExistsByEnd("Shut", msg->_endFrame); CStatusChangeMsg statusMsg; - statusMsg._newStatus = _open ? 1 : (CParrot::_v4 == 0 ? 1 : 0); + statusMsg._newStatus = _open ? 1 : (CParrot::_state == PARROT_IN_CAGE ? 1 : 0); statusMsg.execute("PerchCoreHolder"); return true; @@ -96,14 +96,14 @@ bool CCage::MovieEndMsg(CMovieEndMsg *msg) { bool CCage::PreEnterViewMsg(CPreEnterViewMsg *msg) { loadSurface(); - _open = CParrot::_v4 != 0; + _open = CParrot::_state != PARROT_IN_CAGE; loadFrame(_open ? 8 : 0); return true; } bool CCage::MouseMoveMsg(CMouseMoveMsg *msg) { - _cursorId = CParrot::_v4 && !CParrot::_v5 ? CURSOR_ACTIVATE : CURSOR_ARROW; + _cursorId = CParrot::_state != PARROT_IN_CAGE && !CParrot::_v5 ? CURSOR_ACTIVATE : CURSOR_ARROW; return true; } diff --git a/engines/titanic/game/fan_control.cpp b/engines/titanic/game/fan_control.cpp index b3c3b2e816..ca664764ea 100644 --- a/engines/titanic/game/fan_control.cpp +++ b/engines/titanic/game/fan_control.cpp @@ -32,17 +32,17 @@ BEGIN_MESSAGE_MAP(CFanControl, CGameObject) ON_MESSAGE(TimerMsg) END_MESSAGE_MAP() -CFanControl::CFanControl() : CGameObject(), _state(-1), - _enabled(false), _fieldC4(0), _fieldC8(false), _fieldCC(0) { +CFanControl::CFanControl() : CGameObject(), _state(-1), _enabled(false), + _starlings(false), _fanOn(false), _starlingsDying(false) { } void CFanControl::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); file->writeNumberLine(_state, indent); file->writeNumberLine(_enabled, indent); - file->writeNumberLine(_fieldC4, indent); - file->writeNumberLine(_fieldC8, indent); - file->writeNumberLine(_fieldCC, indent); + file->writeNumberLine(_starlings, indent); + file->writeNumberLine(_fanOn, indent); + file->writeNumberLine(_starlingsDying, indent); CGameObject::save(file, indent); } @@ -51,9 +51,9 @@ void CFanControl::load(SimpleFile *file) { file->readNumber(); _state = file->readNumber(); _enabled = file->readNumber(); - _fieldC4 = file->readNumber(); - _fieldC8 = file->readNumber(); - _fieldCC = file->readNumber(); + _starlings = file->readNumber(); + _fanOn = file->readNumber(); + _starlingsDying = file->readNumber(); CGameObject::load(file); } @@ -64,22 +64,23 @@ bool CFanControl::ActMsg(CActMsg *msg) { else if (msg->_action == "DisableObject") _enabled = false; else if (msg->_action == "StarlingsDead") { - _fieldC4 = 0; + _starlings = false; decTransitions(); - _fieldCC = 0; + _starlingsDying = false; } return true; } bool CFanControl::StatusChangeMsg(CStatusChangeMsg *msg) { - if (!_fieldCC) { + if (!_starlingsDying) { playSound("z#42.wav"); if (_enabled) { switch (msg->_newStatus) { case 1: - _fieldC8 = !_fieldC8; - if (_fieldC8) { + // Fan Power button + _fanOn = !_fanOn; + if (_fanOn) { playMovie(6, 8, 0); _state = 0; } else { @@ -104,7 +105,8 @@ bool CFanControl::StatusChangeMsg(CStatusChangeMsg *msg) { break; case 2: - if (_fieldC8) { + // Fan Speed button + if (_fanOn) { _state = (_state + 1) % 4; switch (_state) { case 0: @@ -115,9 +117,10 @@ bool CFanControl::StatusChangeMsg(CStatusChangeMsg *msg) { playMovie(8, 12, 0); break; case 2: - if (_fieldC4) { + if (_starlings) { + // It's puret time incTransitions(); - _fieldCC = 1; + _starlingsDying = true; playMovie(12, 18, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); } else { playMovie(12, 18, 0); @@ -146,16 +149,20 @@ bool CFanControl::StatusChangeMsg(CStatusChangeMsg *msg) { bool CFanControl::EnterViewMsg(CEnterViewMsg *msg) { switch (_state) { - case 0: + case -1: + // Fan off loadFrame(6); break; - case 1: + case 0: + // Low speed loadFrame(4); break; - case 2: + case 1: + // Medium speed loadFrame(0); break; - case 3: + case 2: + // High speed loadFrame(18); break; default: diff --git a/engines/titanic/game/fan_control.h b/engines/titanic/game/fan_control.h index 1f7402db12..063243c164 100644 --- a/engines/titanic/game/fan_control.h +++ b/engines/titanic/game/fan_control.h @@ -37,9 +37,9 @@ class CFanControl : public CGameObject { public: int _state; bool _enabled; - int _fieldC4; - bool _fieldC8; - int _fieldCC; + bool _starlings; + bool _fanOn; + bool _starlingsDying; public: CLASSDEF; CFanControl(); diff --git a/engines/titanic/game/hammer_dispensor.cpp b/engines/titanic/game/hammer_dispensor.cpp index bc6a3d5ad8..2450868b14 100644 --- a/engines/titanic/game/hammer_dispensor.cpp +++ b/engines/titanic/game/hammer_dispensor.cpp @@ -32,13 +32,13 @@ BEGIN_MESSAGE_MAP(CHammerDispensor, CBackground) END_MESSAGE_MAP() CHammerDispensor::CHammerDispensor() : CBackground(), - _fieldE0(false), _fieldE4(true), _state(0) { + _isOpen(false), _panUp(true), _state(0) { } void CHammerDispensor::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_fieldE0, indent); - file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_isOpen, indent); + file->writeNumberLine(_panUp, indent); file->writeNumberLine(_state, indent); CBackground::save(file, indent); @@ -46,44 +46,44 @@ void CHammerDispensor::save(SimpleFile *file, int indent) { void CHammerDispensor::load(SimpleFile *file) { file->readNumber(); - _fieldE0 = file->readNumber(); - _fieldE4 = file->readNumber(); + _isOpen = file->readNumber(); + _panUp = file->readNumber(); _state = file->readNumber(); CBackground::load(file); } bool CHammerDispensor::ActMsg(CActMsg *msg) { - if (msg->_action == "DispenseHammer" && !_fieldE0) { + if (msg->_action == "DispenseHammer" && !_isOpen) { _state = 1; playMovie(15, 31, MOVIE_NOTIFY_OBJECT); - _fieldE0 = true; + _isOpen = true; } - if (msg->_action == "HammerTaken" && _fieldE0) + if (msg->_action == "HammerTaken" && _isOpen) loadFrame(32); return true; } bool CHammerDispensor::EnterViewMsg(CEnterViewMsg *msg) { - if (_fieldE4) { + if (_panUp) { playMovie(7, 14, 0); - _fieldE4 = false; + _panUp = false; } return true; } bool CHammerDispensor::LeaveViewMsg(CLeaveViewMsg *msg) { - _fieldE4 = true; - _fieldE0 = 0; - _state = 2; - - if (_fieldE0) + if (_isOpen) playMovie(32, 50, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); else playMovie(0, 7, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + + _panUp = true; + _isOpen = false; + _state = 2; return true; } diff --git a/engines/titanic/game/hammer_dispensor.h b/engines/titanic/game/hammer_dispensor.h index 2383a3349e..f93f4141ab 100644 --- a/engines/titanic/game/hammer_dispensor.h +++ b/engines/titanic/game/hammer_dispensor.h @@ -34,8 +34,8 @@ class CHammerDispensor : public CBackground { bool LeaveViewMsg(CLeaveViewMsg *msg); bool MovieEndMsg(CMovieEndMsg *msg); private: - bool _fieldE0; - bool _fieldE4; + bool _isOpen; + bool _panUp; int _state; public: CLASSDEF; diff --git a/engines/titanic/game/hammer_dispensor_button.cpp b/engines/titanic/game/hammer_dispensor_button.cpp index 89d37a0476..661a92eb17 100644 --- a/engines/titanic/game/hammer_dispensor_button.cpp +++ b/engines/titanic/game/hammer_dispensor_button.cpp @@ -34,36 +34,36 @@ BEGIN_MESSAGE_MAP(CHammerDispensorButton, CStartAction) END_MESSAGE_MAP() CHammerDispensorButton::CHammerDispensorButton() : CStartAction(), - _fieldF8(0), _fieldFC(0), _field100(0), _btnPos(Point(56, 6)), - _field10C(nullptr), _field110(0) { + _active(false), _open(false), _hitCounter(0), _btnPos(Point(56, 6)), + _perch(nullptr), _hammerTaken(0) { } void CHammerDispensorButton::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_fieldF8, indent); - file->writeNumberLine(_fieldFC, indent); - file->writeNumberLine(_field100, indent); + file->writeNumberLine(_active, indent); + file->writeNumberLine(_open, indent); + file->writeNumberLine(_hitCounter, indent); file->writeNumberLine(_btnPos.x, indent); file->writeNumberLine(_btnPos.y, indent); - file->writeNumberLine(_field110, indent); + file->writeNumberLine(_hammerTaken, indent); CStartAction::save(file, indent); } void CHammerDispensorButton::load(SimpleFile *file) { file->readNumber(); - _fieldF8 = file->readNumber(); - _fieldFC = file->readNumber(); - _field100 = file->readNumber(); + _active = file->readNumber(); + _open = file->readNumber(); + _hitCounter = file->readNumber(); _btnPos.x = file->readNumber(); _btnPos.y = file->readNumber(); - _field110 = file->readNumber(); + _hammerTaken = file->readNumber(); CStartAction::load(file); } bool CHammerDispensorButton::PuzzleSolvedMsg(CPuzzleSolvedMsg *msg) { - _fieldF8 = 1; + _active = true; return true; } @@ -75,54 +75,47 @@ bool CHammerDispensorButton::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { bool CHammerDispensorButton::ActMsg(CActMsg *msg) { if (msg->_action == "HammerTaken") - _field110 = true; + _hammerTaken = true; return true; } bool CHammerDispensorButton::FrameMsg(CFrameMsg *msg) { - if (!_fieldF8) + if (!_active) return true; - if (!_field10C) { + if (!_perch) { CGameObject *obj = getDraggingObject(); if (obj) { if (obj->isEquals("Perch") && getView() == findView()) - _field10C = obj; + _perch = static_cast<CPerch *>(obj); } } - if (_field10C) { - Point pt(_btnPos.x + _bounds.left, _btnPos.y + _bounds.top); + if (_perch) { + Point pt(_btnPos.x + _perch->_bounds.left, _btnPos.y + _perch->_bounds.top); bool flag = checkPoint(pt, true); - switch (_fieldFC) { - case 0: + if (!_open) { if (flag) { playSound("z#93.wav"); - if (++_field100 == 5) { - if (!_field110) { + if (++_hitCounter == 5) { + if (!_hammerTaken) { CActMsg actMsg(_msgAction); actMsg.execute(_msgTarget); } setVisible(false); - _fieldF8 = 0; - _field100 = 0; + _active = false; + _hitCounter = 0; } - _fieldFC = 1; + _open = true; } - break; - - case 1: + } else { if (!flag) { - _fieldFC = 0; - ++_field100; + _open = false; + ++_hitCounter; } - break; - - default: - break; } } @@ -130,15 +123,15 @@ bool CHammerDispensorButton::FrameMsg(CFrameMsg *msg) { } bool CHammerDispensorButton::LeaveViewMsg(CLeaveViewMsg *msg) { - _field10C = nullptr; - _field100 = 0; - _fieldFC = 0; + _perch = nullptr; + _hitCounter = 0; + _open = false; return true; } bool CHammerDispensorButton::EnterViewMsg(CEnterViewMsg *msg) { setVisible(true); - _fieldF8 = 1; + _active = true; return true; } diff --git a/engines/titanic/game/hammer_dispensor_button.h b/engines/titanic/game/hammer_dispensor_button.h index f497b9dae1..0194021943 100644 --- a/engines/titanic/game/hammer_dispensor_button.h +++ b/engines/titanic/game/hammer_dispensor_button.h @@ -24,6 +24,7 @@ #define TITANIC_HAMMER_DISPENSOR_BUTTON_H #include "titanic/game/start_action.h" +#include "titanic/carry/perch.h" namespace Titanic { @@ -36,12 +37,12 @@ class CHammerDispensorButton : public CStartAction { bool LeaveViewMsg(CLeaveViewMsg *msg); bool EnterViewMsg(CEnterViewMsg *msg); private: - int _fieldF8; - int _fieldFC; - int _field100; + bool _active; + bool _open; + int _hitCounter; Point _btnPos; - CGameObject *_field10C; - int _field110; + CPerch *_perch; + bool _hammerTaken; public: CLASSDEF; CHammerDispensorButton(); diff --git a/engines/titanic/game/maitred/maitred_arm_holder.cpp b/engines/titanic/game/maitred/maitred_arm_holder.cpp index 75d95640d2..51c19561a7 100644 --- a/engines/titanic/game/maitred/maitred_arm_holder.cpp +++ b/engines/titanic/game/maitred/maitred_arm_holder.cpp @@ -40,7 +40,7 @@ void CMaitreDArmHolder::load(SimpleFile *file) { } bool CMaitreDArmHolder::MaitreDArmHolder(CMaitreDArmHolder *msg) { - _fieldF4 = 0; + _dropEnabled = false; return true; } diff --git a/engines/titanic/game/missiveomat.cpp b/engines/titanic/game/missiveomat.cpp index 8f7845bc3f..fa0a9d7c74 100644 --- a/engines/titanic/game/missiveomat.cpp +++ b/engines/titanic/game/missiveomat.cpp @@ -34,8 +34,8 @@ BEGIN_MESSAGE_MAP(CMissiveOMat, CGameObject) ON_MESSAGE(LeaveViewMsg) END_MESSAGE_MAP() -CMissiveOMat::CMissiveOMat() : CGameObject(), _mode(1), - _totalMessages(0), _messageNum(0), _personIndex(-1) { +CMissiveOMat::CMissiveOMat() : CGameObject(), _mode(MMODE_USERNAME), + _totalMessages(0), _messageNum(0), _account(NO_ACCOUNT) { // Load data for the messages, their from and to names loadArray(_welcomeMessages, "TEXT/MISSIVEOMAT/WELCOME", 3); loadArray(_messages, "TEXT/MISSIVEOMAT/MESSAGES", 58); @@ -55,129 +55,150 @@ void CMissiveOMat::save(SimpleFile *file, int indent) { file->writeNumberLine(_mode, indent); file->writeNumberLine(_totalMessages, indent); file->writeNumberLine(_messageNum, indent); - file->writeQuotedLine(_string1, indent); - file->writeQuotedLine(_string2, indent); - file->writeNumberLine(_personIndex, indent); + file->writeQuotedLine(_username, indent); + file->writeQuotedLine(_password, indent); + file->writeNumberLine(_account, indent); CGameObject::save(file, indent); } void CMissiveOMat::load(SimpleFile *file) { file->readNumber(); - _mode = file->readNumber(); + _mode = (MissiveOMatMode)file->readNumber(); _totalMessages = file->readNumber(); _messageNum = file->readNumber(); - _string1 = file->readString(); - _string2 = file->readString(); - _personIndex = file->readNumber(); + _username = file->readString(); + _password = file->readString(); + _account = (MissiveOMatAccount)file->readNumber(); CGameObject::load(file); } bool CMissiveOMat::EnterViewMsg(CEnterViewMsg *msg) { - CMissiveOMatActionMsg actionMsg(9); + CMissiveOMatActionMsg actionMsg(MESSAGE_9); actionMsg.execute(this); return true; } bool CMissiveOMat::KeyCharMsg(CKeyCharMsg *msg) { CTreeItem *loginControl = findRoom()->findByName("MissiveOMat Login Control"); - CTreeItem *welcome = findRoom()->findByName("MissiveOMat Welcome"); - CTreeItem *scrollUp = findRoom()->findByName("MissiveOMat ScrollUp Button"); CEditControlMsg editMsg; switch (_mode) { - case 1: { + case MMODE_USERNAME: + if (!msg->_key) + return true; + playSound("z#228.wav"); - editMsg._mode = 6; + editMsg._mode = EDIT_KEYPRESS; editMsg._param = msg->_key; editMsg.execute(loginControl); if (editMsg._param == 1000) { - editMsg._mode = 3; + // Get the username + editMsg._mode = EDIT_GET_TEXT; editMsg.execute(loginControl); + _username = editMsg._text; + _username.toLowercase(); - _string1 = editMsg._text; - if (!_string1.empty()) { + // Next ask for the password + if (!_username.empty()) { loadFrame(2); - _mode = 2; + _mode = MMODE_PASSWORD; - editMsg._mode = 1; + editMsg._mode = EDIT_CLEAR; editMsg.execute(loginControl); - editMsg._mode = 10; + editMsg._mode = EDIT_BORDERS; editMsg._param = 24; editMsg.execute(loginControl); } } break; - } - case 2: { + case MMODE_PASSWORD: + if (!msg->_key) + return true; + playSound("z#228.wav"); - editMsg._mode = 6; + editMsg._mode = EDIT_KEYPRESS; editMsg._param = msg->_key; editMsg.execute(loginControl); - _string2 = editMsg._text; - if (_string1 == "Droot Scraliontis") { - _string1 = "Scraliontis"; - } else if (_string1 == "Antar Brobostigon") { - _string1 = "Brobostigon"; - } else if (_string1 == "colin") { - _string1 = "Leovinus"; - } - - bool flag = false; - if (_string1 == "Leovinus") { - if (_string2 == "Other") { - flag = true; - _personIndex = 0; - } - } else if (_string1 == "Scraliontis") { - if (_string2 == "This") { - flag = true; - _personIndex = 1; + if (editMsg._param == 1000) { + // Get the password + editMsg._mode = EDIT_GET_TEXT; + editMsg.execute(loginControl); + _password = editMsg._text; + _password.toLowercase(); + + // Handle special variations of the names + if (_username == "droot scraliontis") { + _username = "scraliontis"; + } else if (_username == "antar brobostigon") { + _username = "brobostigon"; + } else if (_username == "colin") { + _username = "leovinus"; } - } else if (_string1 == "Brobostigon") { - if (_string2 == "That") { - flag = true; - _personIndex = 2; + + // Check whether a valid username and password has been entered + static const char *const PASSWORDS_EN[3] = { "other", "this", "that" }; + static const char *const PASSWORDS_DE[3] = { "t'ok", "t'ik", "t'ak" }; + static const char *const *pwds = g_vm->isGerman() ? PASSWORDS_DE : PASSWORDS_EN; + + bool validFlag = false; + if ((_username == "leovinus" && _password == pwds[0]) || + (_username == "scummvm")) { + validFlag = true; + _account = LEOVINUS; + } else if (_username == "scraliontis" && _password == pwds[1]) { + validFlag = true; + _account = SCRALIONTIS; + } else if (_username == "brobostigon" && _password == pwds[2]) { + validFlag = true; + _account = BROBOSTIGON; } - } - if (flag) { - _mode = 4; - loadFrame(4); - editMsg._mode = 1; - editMsg.execute(loginControl); + if (validFlag) { + // Credentials were valid, so log in + _mode = MMODE_LOGGED_IN; + loadFrame(4); + editMsg._mode = EDIT_CLEAR; + editMsg.execute(loginControl); - getTextCursor()->hide(); - editMsg._mode = 13; - editMsg.execute(loginControl); + CRoomItem *room = findRoom(); + CTreeItem *welcome = room->findByName("MissiveOMat Welcome"); + CTreeItem *scrollUp = room->findByName("MissiveOMat ScrollUp Button"); + CTreeItem *scrollDown = room->findByName("MissiveOMat ScrollDown Button"); + CTreeItem *ok = room->findByName("MissiveOMat OK Button"); - editMsg._mode = 12; - editMsg.execute(welcome); + getTextCursor()->hide(); + editMsg._mode = EDIT_HIDE; + editMsg.execute(loginControl); - editMsg._mode = 2; - editMsg._text = _welcomeMessages[_personIndex]; - editMsg.execute(welcome); + editMsg._mode = EDIT_SHOW; + editMsg.execute(welcome); - editMsg._mode = 12; - editMsg._text = "MissiveOMat OK Button"; - editMsg.execute(welcome); - editMsg.execute(scrollUp); - } else { - _mode = 3; - loadFrame(3); - addTimer(1500); + editMsg._mode = EDIT_SET_TEXT; + editMsg._text = _welcomeMessages[_account]; + editMsg.execute(welcome); - editMsg._mode = 1; - editMsg.execute(loginControl); + editMsg._mode = EDIT_SHOW; + editMsg.execute(ok); + editMsg.execute(scrollUp); + editMsg.execute(scrollDown); + } else { + // Credentials were invalid, so access denied + _mode = MMODE_DENIED; + loadFrame(3); + addTimer(1500); + + editMsg._mode = EDIT_CLEAR; + editMsg.execute(loginControl); - getTextCursor()->hide(); + getTextCursor()->hide(); + } } break; - } default: break; @@ -187,10 +208,14 @@ bool CMissiveOMat::KeyCharMsg(CKeyCharMsg *msg) { } bool CMissiveOMat::TimerMsg(CTimerMsg *msg) { - if (_mode == 3) { + if (_mode == MMODE_DENIED) { + // Reset back to asking for a login username + _mode = MMODE_USERNAME; + loadFrame(1); + CTreeItem *loginControl = findRoom()->findByName("MissiveOMat Login Control"); CEditControlMsg editMsg; - editMsg._mode = 10; + editMsg._mode = EDIT_BORDERS; editMsg._param = 8; editMsg.execute(loginControl); } @@ -199,16 +224,17 @@ bool CMissiveOMat::TimerMsg(CTimerMsg *msg) { } bool CMissiveOMat::MissiveOMatActionMsg(CMissiveOMatActionMsg *msg) { - CTreeItem *welcome = findByName("MissiveOMat Welcome"); + CGameObject *welcome = static_cast<CGameObject *>(findByName("MissiveOMat Welcome")); switch (msg->_action) { case MESSAGE_SHOW: { - CTreeItem *btnOk = findRoom()->findByName("MissiveOMat OK Button"); - CTreeItem *btnNext = findRoom()->findByName("MissiveOMat Next Button"); - CTreeItem *btnPrev = findRoom()->findByName("MissiveOMat Prev Button"); - CTreeItem *btnLogout = findRoom()->findByName("MissiveOMat Logout Button"); + CRoomItem *room = findRoom(); + CTreeItem *btnOk = room->findByName("MissiveOMat OK Button"); + CTreeItem *btnNext = room->findByName("MissiveOMat Next Button"); + CTreeItem *btnPrev = room->findByName("MissiveOMat Prev Button"); + CTreeItem *btnLogout = room->findByName("MissiveOMat Logout Button"); - _mode = MESSAGE_5; + _mode = MMODE_5; CVisibleMsg visibleMsg; visibleMsg._visible = false; visibleMsg.execute(btnOk); @@ -219,7 +245,7 @@ bool CMissiveOMat::MissiveOMatActionMsg(CMissiveOMatActionMsg *msg) { _messageNum = 0; _totalMessages = 0; - CString *strP = &_messages[_personIndex * 19]; + CString *strP = &_messages[_account * 19]; for (_totalMessages = 0; !strP->empty(); ++strP, ++_totalMessages) ; @@ -256,58 +282,58 @@ bool CMissiveOMat::MissiveOMatActionMsg(CMissiveOMatActionMsg *msg) { case MESSAGE_DOWN: if (welcome) - scrollTextDown(); + welcome->scrollTextDown(); break; case MESSAGE_UP: if (welcome) - scrollTextUp(); + welcome->scrollTextUp(); break; case REDRAW_MESSAGE: if (welcome) { CString str = CString::format( "Missive %d of %d.\nFrom: %s\nTo: %s\n\n%s\n", - _messageNum + 1, _totalMessages, _from[_messageNum].c_str(), - _to[_messageNum].c_str(), _messages[_messageNum].c_str()); + _messageNum + 1, _totalMessages, _from[_account * 19 + _messageNum].c_str(), + _to[_account * 19 + _messageNum].c_str(), _messages[_account * 19 + _messageNum].c_str()); - setText(str); + welcome->setText(str); } break; case MESSAGE_9: { loadFrame(1); - _mode = MESSAGE_NONE; - _personIndex = -1; - - static const char *const WIDGETS[7] = { - "MissiveOMat Login Control", "MissiveOMat OK Button", - "MissiveOMat Next Button", "MissiveOMat Prev Button", - "MissiveOMat Logout Button", "MissiveOMat ScrollDown Button", - "MissiveOMat ScrollUp Button" + _mode = MMODE_USERNAME; + _account = NO_ACCOUNT; + + static const char *const WIDGETS[8] = { + "MissiveOMat Login Control", "MissiveOMat Welcome", + "MissiveOMat OK Button", "MissiveOMat Next Button", + "MissiveOMat Prev Button", "MissiveOMat Logout Button", + "MissiveOMat ScrollDown Button", "MissiveOMat ScrollUp Button" }; CEditControlMsg editMsg; - for (int idx = 0; idx < 7; ++idx) { - editMsg._mode = 0; + for (int idx = 0; idx < 8; ++idx) { + editMsg._mode = EDIT_INIT; editMsg._param = 12; editMsg.execute(WIDGETS[idx]); - editMsg._mode = 1; + editMsg._mode = EDIT_CLEAR; editMsg.execute(WIDGETS[idx]); - editMsg._mode = 13; + editMsg._mode = EDIT_HIDE; editMsg.execute(WIDGETS[idx]); } - editMsg._mode = 12; + editMsg._mode = EDIT_SHOW; editMsg.execute("MissiveOMat Login Control"); - editMsg._mode = 10; + editMsg._mode = EDIT_BORDERS; editMsg._param = 8; editMsg.execute("MissiveOMat Login Control"); - editMsg._mode = 8; + editMsg._mode = EDIT_SHOW_CURSOR; editMsg.execute("MissiveOMat Login Control"); - _string1.clear(); - _string2.clear(); + _username.clear(); + _password.clear(); break; } @@ -320,7 +346,7 @@ bool CMissiveOMat::MissiveOMatActionMsg(CMissiveOMatActionMsg *msg) { bool CMissiveOMat::LeaveViewMsg(CLeaveViewMsg *msg) { CEditControlMsg editMsg; - editMsg._mode = 9; + editMsg._mode = EDIT_HIDE_CURSOR; editMsg.execute("MissiveOMat Login Control"); petShowCursor(); diff --git a/engines/titanic/game/missiveomat.h b/engines/titanic/game/missiveomat.h index 9810fcc403..c8441edff2 100644 --- a/engines/titanic/game/missiveomat.h +++ b/engines/titanic/game/missiveomat.h @@ -27,10 +27,16 @@ namespace Titanic { -enum MissiveOMatAction { - MESSAGE_NONE = 1, MESSAGE_SHOW = 2, NEXT_MESSAGE = 3, PRIOR_MESSAGE = 4, - MESSAGE_5 = 5, MESSAGE_DOWN = 6, MESSAGE_UP = 7, REDRAW_MESSAGE = 8, - MESSAGE_9 = 9 +enum MissiveOMatMode { + MMODE_USERNAME = 1, + MMODE_PASSWORD = 2, + MMODE_DENIED = 3, + MMODE_LOGGED_IN = 4, + MMODE_5 = 5 +}; + +enum MissiveOMatAccount { + NO_ACCOUNT = -1, LEOVINUS = 0, SCRALIONTIS = 1, BROBOSTIGON = 2 }; class CMissiveOMat : public CGameObject { @@ -48,12 +54,12 @@ private: private: void loadArray(CString *arr, const CString &resName, int count); public: - int _mode; + MissiveOMatMode _mode; int _totalMessages; int _messageNum; - CString _string1; - CString _string2; - int _personIndex; + CString _username; + CString _password; + MissiveOMatAccount _account; public: CLASSDEF; CMissiveOMat(); diff --git a/engines/titanic/game/missiveomat_button.cpp b/engines/titanic/game/missiveomat_button.cpp index b7ad7f8f6f..8c1f6c51c6 100644 --- a/engines/titanic/game/missiveomat_button.cpp +++ b/engines/titanic/game/missiveomat_button.cpp @@ -40,7 +40,7 @@ void CMissiveOMatButton::save(SimpleFile *file, int indent) { void CMissiveOMatButton::load(SimpleFile *file) { file->readNumber(); - _buttonId = file->readNumber(); + _buttonId = (MissiveOMatAction)file->readNumber(); CEditControl::load(file); } diff --git a/engines/titanic/game/missiveomat_button.h b/engines/titanic/game/missiveomat_button.h index 6dbfd4cd56..b029f6ce85 100644 --- a/engines/titanic/game/missiveomat_button.h +++ b/engines/titanic/game/missiveomat_button.h @@ -24,6 +24,7 @@ #define TITANIC_MISSIVEOMAT_BUTTON_H #include "titanic/gfx/edit_control.h" +#include "titanic/messages/messages.h" namespace Titanic { @@ -33,10 +34,10 @@ class CMissiveOMatButton : public CEditControl { bool VisibleMsg(CVisibleMsg *msg); bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); public: - int _buttonId; + MissiveOMatAction _buttonId; public: CLASSDEF; - CMissiveOMatButton() : CEditControl(), _buttonId(2) {} + CMissiveOMatButton() : CEditControl(), _buttonId(MESSAGE_SHOW) {} /** * Save the data for the class to file diff --git a/engines/titanic/game/nose_holder.cpp b/engines/titanic/game/nose_holder.cpp index ac6c10dafd..d00c7b372e 100644 --- a/engines/titanic/game/nose_holder.cpp +++ b/engines/titanic/game/nose_holder.cpp @@ -33,25 +33,25 @@ BEGIN_MESSAGE_MAP(CNoseHolder, CDropTarget) END_MESSAGE_MAP() CNoseHolder::CNoseHolder() : CDropTarget(), _dragObject(nullptr), - _field11C(0) { + _draggingFeather(false) { } void CNoseHolder::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_field11C, indent); + file->writeNumberLine(_draggingFeather, indent); CDropTarget::save(file, indent); } void CNoseHolder::load(SimpleFile *file) { file->readNumber(); - _field11C = file->readNumber(); + _draggingFeather = file->readNumber(); CDropTarget::load(file); } bool CNoseHolder::ActMsg(CActMsg *msg) { - if (msg->_action == "Sneeze" && !_itemName.empty() && _fieldF4) { + if (msg->_action == "Sneeze" && !_itemName.empty() && _dropEnabled) { CProximity prox; prox._positioningMode = POSMODE_VECTOR; playSound("z#35.wav", prox); @@ -78,13 +78,12 @@ bool CNoseHolder::FrameMsg(CFrameMsg *msg) { } if (_dragObject) { - if (!checkPoint(Point(_dragObject->_bounds.left, - _dragObject->_bounds.top))) { - _field11C = false; - } else if (!_field11C) { + if (!checkPoint(Point(_dragObject->_bounds.left, _dragObject->_bounds.top), true)) { + _draggingFeather = false; + } else if (!_draggingFeather) { CActMsg actMsg("Sneeze"); actMsg.execute(this); - _field11C = true; + _draggingFeather = true; } } @@ -92,9 +91,9 @@ bool CNoseHolder::FrameMsg(CFrameMsg *msg) { } bool CNoseHolder::LeaveViewMsg(CLeaveViewMsg *msg) { - _field11C = false; + _draggingFeather = false; _dragObject = nullptr; - if (_fieldF4) { + if (_dropEnabled) { loadFrame(_dropFrame); setVisible(false); } @@ -103,7 +102,7 @@ bool CNoseHolder::LeaveViewMsg(CLeaveViewMsg *msg) { } bool CNoseHolder::MovieEndMsg(CMovieEndMsg *msg) { - if (_fieldF4) { + if (_dropEnabled) { loadFrame(_dropFrame); setVisible(false); } @@ -112,7 +111,7 @@ bool CNoseHolder::MovieEndMsg(CMovieEndMsg *msg) { } bool CNoseHolder::EnterViewMsg(CEnterViewMsg *msg) { - if (_fieldF4) + if (_dropEnabled) setVisible(false); return CDropTarget::EnterViewMsg(msg); diff --git a/engines/titanic/game/nose_holder.h b/engines/titanic/game/nose_holder.h index 7b3fbba625..ef20b6f78e 100644 --- a/engines/titanic/game/nose_holder.h +++ b/engines/titanic/game/nose_holder.h @@ -36,7 +36,7 @@ class CNoseHolder : public CDropTarget { bool EnterViewMsg(CEnterViewMsg *msg); private: CGameObject *_dragObject; - int _field11C; + bool _draggingFeather; public: CLASSDEF; CNoseHolder(); diff --git a/engines/titanic/game/parrot/parrot_nut_eater.cpp b/engines/titanic/game/parrot/parrot_nut_eater.cpp index 49b8de509f..b9697d7b61 100644 --- a/engines/titanic/game/parrot/parrot_nut_eater.cpp +++ b/engines/titanic/game/parrot/parrot_nut_eater.cpp @@ -66,6 +66,7 @@ bool CParrotNutEater::ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg) { bool CParrotNutEater::NutPuzzleMsg(CNutPuzzleMsg *msg) { if (msg->_value == "Jiggle") { + setVisible(true); playMovie(MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); movieEvent(68); movieEvent(132); diff --git a/engines/titanic/game/parrot/parrot_perch_holder.cpp b/engines/titanic/game/parrot/parrot_perch_holder.cpp index 205995cf1c..557f70437a 100644 --- a/engines/titanic/game/parrot/parrot_perch_holder.cpp +++ b/engines/titanic/game/parrot/parrot_perch_holder.cpp @@ -48,7 +48,7 @@ bool CParrotPerchHolder::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { if (!CParrot::_v1) { if (CCage::_open) { petDisplayMessage(CANNOT_TAKE_CAGE_LOCKED); - } else if (!CParrot::_v4) { + } else if (CParrot::_state == PARROT_IN_CAGE) { CTrueTalkTriggerActionMsg triggerMsg(280252, 0, 0); triggerMsg.execute(getRoot(), CParrot::_type, MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN); @@ -59,7 +59,7 @@ bool CParrotPerchHolder::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { } bool CParrotPerchHolder::StatusChangeMsg(CStatusChangeMsg *msg) { - _fieldF4 = msg->_newStatus; + _dropEnabled = msg->_newStatus; return true; } diff --git a/engines/titanic/game/pickup/pick_up_hose.cpp b/engines/titanic/game/pickup/pick_up_hose.cpp index d07088cefd..442c43f9b0 100644 --- a/engines/titanic/game/pickup/pick_up_hose.cpp +++ b/engines/titanic/game/pickup/pick_up_hose.cpp @@ -72,13 +72,13 @@ bool CPickUpHose::MouseDragStartMsg(CMouseDragStartMsg *msg) { if (hose) { CVisibleMsg visibleMsg; - visibleMsg.execute(this); - moveUnder(view); + visibleMsg.execute(hose); + hose->moveUnder(view); CPassOnDragStartMsg passMsg(msg->_mousePos, 1); passMsg.execute("Hose"); - msg->_dragItem = getRoot()->findByName("Hose"); + msg->_dragItem = hose; _cursorId = CURSOR_IGNORE; CActMsg actMsg("PlayerGetsHose"); @@ -91,7 +91,7 @@ bool CPickUpHose::MouseDragStartMsg(CMouseDragStartMsg *msg) { bool CPickUpHose::StatusChangeMsg(CStatusChangeMsg *msg) { _cursorId = msg->_newStatus == 1 ? CURSOR_HAND : CURSOR_IGNORE; - return true; + return CPickUp::StatusChangeMsg(msg); } bool CPickUpHose::EnterViewMsg(CEnterViewMsg *msg) { diff --git a/engines/titanic/game/restaurant_cylinder_holder.cpp b/engines/titanic/game/restaurant_cylinder_holder.cpp index adf029d8f7..5fb8c97cde 100644 --- a/engines/titanic/game/restaurant_cylinder_holder.cpp +++ b/engines/titanic/game/restaurant_cylinder_holder.cpp @@ -71,7 +71,7 @@ bool CRestaurantCylinderHolder::EjectCylinderMsg(CEjectCylinderMsg *msg) { if (_field118) { playClip(hasCylinder ? "CloseHolder_Full" : "CloseHolder_Empty", MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); - _fieldF4 = 1; + _dropEnabled = true; } else { playClip(hasCylinder ? "OpenHolder_Full" : "OpenHolder_Empty", MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); @@ -109,7 +109,7 @@ bool CRestaurantCylinderHolder::MovieEndMsg(CMovieEndMsg *msg) { readyMsg.execute(_target); } else { _field118 = true; - _fieldF4 = false; + _dropEnabled = false; _cursorId = findByName("Phonograph Cylinder") ? _dropCursorId : _dragCursorId; } diff --git a/engines/titanic/game/start_action.cpp b/engines/titanic/game/start_action.cpp index ab356ea1f4..c4f8db8190 100644 --- a/engines/titanic/game/start_action.cpp +++ b/engines/titanic/game/start_action.cpp @@ -50,14 +50,13 @@ void CStartAction::load(SimpleFile *file) { } bool CStartAction::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { - // Dispatch the desired action to the desired target - CActMsg actMsg(_msgAction); - actMsg.execute(_msgTarget); - return true; } bool CStartAction::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + // Dispatch the desired action to the desired target + CActMsg actMsg(_msgAction); + actMsg.execute(_msgTarget); return true; } diff --git a/engines/titanic/game/sweet_bowl.cpp b/engines/titanic/game/sweet_bowl.cpp index 29d8044a85..7a3832e7c2 100644 --- a/engines/titanic/game/sweet_bowl.cpp +++ b/engines/titanic/game/sweet_bowl.cpp @@ -48,7 +48,7 @@ bool CSweetBowl::MovieEndMsg(CMovieEndMsg *msg) { bool CSweetBowl::EnterViewMsg(CEnterViewMsg *msg) { setVisible(false); loadSound("b#43.wav"); - playSound("b#42.wav"); + loadSound("b#42.wav"); return true; } diff --git a/engines/titanic/game/television.cpp b/engines/titanic/game/television.cpp index 390d8553a6..a0499f1d39 100644 --- a/engines/titanic/game/television.cpp +++ b/engines/titanic/game/television.cpp @@ -246,7 +246,7 @@ bool CTelevision::MovieEndMsg(CMovieEndMsg *msg) { debugC(kDebugScripts, "Assigned room - %d", roomFlags); magazine->addMail(roomFlags); - magazine->removeMail(roomFlags, roomFlags); + magazine->sendMail(roomFlags, roomFlags); } loadFrame(561); diff --git a/engines/titanic/game/tow_parrot_nav.cpp b/engines/titanic/game/tow_parrot_nav.cpp index 57f1649add..b8a99a5f1b 100644 --- a/engines/titanic/game/tow_parrot_nav.cpp +++ b/engines/titanic/game/tow_parrot_nav.cpp @@ -44,7 +44,7 @@ bool CTOWParrotNav::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { actMsg.execute("PerchedParrot"); CString clipString = "_EXIT,36,1,N,9,3,N"; - if (CParrot::_v4) + if (CParrot::_state != PARROT_IN_CAGE) clipString += 'a'; changeView("ParrotLobby.Node 3.N", clipString); diff --git a/engines/titanic/game_state.cpp b/engines/titanic/game_state.cpp index 26a4297358..49779ad745 100644 --- a/engines/titanic/game_state.cpp +++ b/engines/titanic/game_state.cpp @@ -83,11 +83,11 @@ void CGameState::setMode(GameStateMode newMode) { _gameManager->lockInputHandler(); if (sm && sm->_mouseCursor) - sm->_mouseCursor->hide(); + sm->_mouseCursor->setBusy(); } else if (newMode != GSMODE_CUTSCENE && _mode == GSMODE_CUTSCENE) { if (sm && sm->_mouseCursor) - sm->_mouseCursor->show(); + sm->_mouseCursor->clearBusy(); if (_gameManager) _gameManager->unlockInputHandler(); diff --git a/engines/titanic/gfx/edit_control.cpp b/engines/titanic/gfx/edit_control.cpp index 3f3c4d4035..33707f93f6 100644 --- a/engines/titanic/gfx/edit_control.cpp +++ b/engines/titanic/gfx/edit_control.cpp @@ -26,15 +26,16 @@ namespace Titanic { BEGIN_MESSAGE_MAP(CEditControl, CGameObject) ON_MESSAGE(EditControlMsg) + ON_MESSAGE(MouseWheelMsg) END_MESSAGE_MAP() -CEditControl::CEditControl() : CGameObject(), _fieldBC(false), _fontNumber(0), _fieldD4(2), - _textR(0), _textG(0), _textB(0), _fieldF0(0), _fieldF4(0) { +CEditControl::CEditControl() : CGameObject(), _showCursor(false), _fontNumber(0), _fieldD4(2), + _textR(0), _textG(0), _textB(0), _fieldF0(0), _isPassword(false) { } void CEditControl::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_showCursor, indent); file->writeNumberLine(_editLeft, indent); file->writeNumberLine(_editBottom, indent); file->writeNumberLine(_editHeight, indent); @@ -46,14 +47,14 @@ void CEditControl::save(SimpleFile *file, int indent) { file->writeNumberLine(_textB, indent); file->writeQuotedLine(_text, indent); file->writeNumberLine(_fieldF0, indent); - file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_isPassword, indent); CGameObject::save(file, indent); } void CEditControl::load(SimpleFile *file) { file->readNumber(); - _fieldBC = file->readNumber(); + _showCursor = file->readNumber(); _editLeft = file->readNumber(); _editBottom = file->readNumber(); _editHeight = file->readNumber(); @@ -65,67 +66,68 @@ void CEditControl::load(SimpleFile *file) { _textB = file->readNumber(); _text = file->readString(); _fieldF0 = file->readNumber(); - _fieldF4 = file->readNumber(); + _isPassword = file->readNumber(); CGameObject::load(file); } bool CEditControl::EditControlMsg(CEditControlMsg *msg) { switch (msg->_mode) { - case 0: - if (!_editLeft) { - _editHeight = _bounds.height(); - _editBottom = _bounds.bottom; - _editLeft = _bounds.left + _bounds.width() / 2; - _maxTextChars = msg->_param; - setTextFontNumber(_fontNumber); + case EDIT_INIT: { + // WORKAROUND: Fix original bug where MissiveOMat username & password + // text weren't initialised after the first time you use the MissiveOMat + _editHeight = _bounds.height(); + _editBottom = _bounds.bottom; + _editLeft = _bounds.left + _bounds.width() / 2; + _maxTextChars = msg->_param; + setTextFontNumber(_fontNumber); - CEditControlMsg ctlMsg; - ctlMsg._mode = 10; - ctlMsg._param = _fieldD4; - ctlMsg.execute(this); + CEditControlMsg ctlMsg; + ctlMsg._mode = EDIT_BORDERS; + ctlMsg._param = _fieldD4; + ctlMsg.execute(this); - ctlMsg._mode = 11; - ctlMsg._textR = _textR; - ctlMsg._textG = _textG; - ctlMsg._textB = _textB; - ctlMsg.execute(this); - } + ctlMsg._mode = EDIT_SET_COLOR; + ctlMsg._textR = _textR; + ctlMsg._textG = _textG; + ctlMsg._textB = _textB; + ctlMsg.execute(this); break; + } - case 1: { + case EDIT_CLEAR: { _text = ""; CEditControlMsg ctlMsg; - ctlMsg._mode = 14; + ctlMsg._mode = EDIT_RENDER; ctlMsg.execute(this); break; } - case 2: { + case EDIT_SET_TEXT: { _text = msg->_text; CEditControlMsg ctlMsg; - ctlMsg._mode = 14; + ctlMsg._mode = EDIT_RENDER; ctlMsg.execute(this); break; } - case 3: + case EDIT_GET_TEXT: msg->_text = _text; break; - case 4: + case EDIT_LENGTH: msg->_param = _text.size(); break; - case 5: + case EDIT_MAX_LENGTH: _maxTextChars = msg->_param; break; - case 6: + case EDIT_KEYPRESS: if (msg->_param == 8 && !_text.empty()) { _text = _text.left(_text.size() - 1); CEditControlMsg ctlMsg; - ctlMsg._mode = 14; + ctlMsg._mode = EDIT_RENDER; ctlMsg.execute(this); } else if (msg->_param == 13) { msg->_param = 1000; @@ -135,32 +137,32 @@ bool CEditControl::EditControlMsg(CEditControlMsg *msg) { _text += c; CEditControlMsg ctlMsg; - ctlMsg._mode = 14; + ctlMsg._mode = EDIT_RENDER; ctlMsg.execute(this); } break; - case 7: + case EDIT_SET_FONT: setTextFontNumber(msg->_param); break; - case 8: - if (!_fieldBC) { - _fieldBC = true; + case EDIT_SHOW_CURSOR: + if (!_showCursor) { + _showCursor = true; CEditControlMsg ctlMsg; - ctlMsg._mode = 14; + ctlMsg._mode = EDIT_RENDER; ctlMsg.execute(this); } break; - case 9: - if (_fieldBC) { - _fieldBC = false; + case EDIT_HIDE_CURSOR: + if (_showCursor) { + _showCursor = false; getTextCursor()->hide(); } break; - case 10: { + case EDIT_BORDERS: { setTextHasBorders((msg->_param & 1) != 0); if (msg->_param & 4) _fieldF0 = 1; @@ -169,28 +171,28 @@ bool CEditControl::EditControlMsg(CEditControlMsg *msg) { else _fieldF0 = 0; - _fieldF4 = msg->_param & 0x10; + _isPassword = (msg->_param & 0x10) != 0; CEditControlMsg ctlMsg; - ctlMsg._mode = 14; + ctlMsg._mode = EDIT_RENDER; ctlMsg.execute(this); break; } - case 11: + case EDIT_SET_COLOR: setTextColor(msg->_textR, msg->_textG, msg->_textB); break; - case 12: + case EDIT_SHOW: setVisible(true); break; - case 13: + case EDIT_HIDE: setVisible(false); break; - case 14: { + case EDIT_RENDER: { makeDirty(); - CString str = _fieldF4 ? CString('*', _text.size()) : _text; + CString str = _isPassword ? CString('*', _text.size()) : _text; setText(str); int textWidth = getTextWidth(); @@ -201,7 +203,7 @@ bool CEditControl::EditControlMsg(CEditControlMsg *msg) { makeDirty(); } - if (_fieldBC) { + if (_showCursor) { CTextCursor *textCursor = getTextCursor(); textCursor->show(); textCursor->setPos(Point(_bounds.left + textWidth + 1, _bounds.top + 3)); @@ -219,4 +221,15 @@ bool CEditControl::EditControlMsg(CEditControlMsg *msg) { return true; } +bool CEditControl::MouseWheelMsg(CMouseWheelMsg *msg) { + if (_name != "MissiveOMat Welcome") + return false; + + if (msg->_wheelUp) + scrollTextUp(); + else + scrollTextDown(); + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/gfx/edit_control.h b/engines/titanic/gfx/edit_control.h index 6c02f7afb9..5ed91c9e84 100644 --- a/engines/titanic/gfx/edit_control.h +++ b/engines/titanic/gfx/edit_control.h @@ -30,8 +30,9 @@ namespace Titanic { class CEditControl : public CGameObject { DECLARE_MESSAGE_MAP; bool EditControlMsg(CEditControlMsg *msg); + bool MouseWheelMsg(CMouseWheelMsg *msg); protected: - bool _fieldBC; + bool _showCursor; int _editLeft; int _editBottom; int _editHeight; @@ -43,7 +44,7 @@ protected: byte _textB; CString _text; int _fieldF0; - int _fieldF4; + bool _isPassword; public: CLASSDEF; CEditControl(); diff --git a/engines/titanic/pet_control/pet_text.cpp b/engines/titanic/gfx/text_control.cpp index 05038d2fd0..f731dbb340 100644 --- a/engines/titanic/pet_control/pet_text.cpp +++ b/engines/titanic/gfx/text_control.cpp @@ -20,12 +20,12 @@ * */ -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" #include "titanic/titanic.h" namespace Titanic { -CPetText::CPetText(uint count) : +CTextControl::CTextControl(uint count) : _stringsMerged(false), _maxCharsPerLine(-1), _lineCount(0), _displayEndCharIndex(-1), _unused1(0), _unused2(0), _unused3(0), _backR(0xff), _backG(0xff), _backB(0xff), @@ -35,18 +35,18 @@ CPetText::CPetText(uint count) : setupArrays(count); } -void CPetText::setupArrays(int count) { +void CTextControl::setupArrays(int count) { freeArrays(); if (count < 10 || count > 60) count = 10; _array.resize(count); } -void CPetText::freeArrays() { +void CTextControl::freeArrays() { _array.clear(); } -void CPetText::setup() { +void CTextControl::setup() { for (int idx = 0; idx < (int)_array.size(); ++idx) { _array[idx]._line.clear(); setLineColor(idx, _textR, _textG, _textB); @@ -57,16 +57,16 @@ void CPetText::setup() { _stringsMerged = false; } -void CPetText::setLineColor(uint lineNum, uint col) { +void CTextControl::setLineColor(uint lineNum, uint col) { setLineColor(lineNum, col & 0xff, (col >> 8) & 0xff, (col >> 16) & 0xff); } -void CPetText::setLineColor(uint lineNum, byte r, byte g, byte b) { +void CTextControl::setLineColor(uint lineNum, byte r, byte g, byte b) { _array[lineNum]._rgb = getColorText(r, g, b); _stringsMerged = false; } -CString CPetText::getColorText(byte r, byte g, byte b) { +CString CTextControl::getColorText(byte r, byte g, byte b) { char buffer[6]; if (!r) r = 1; @@ -85,7 +85,7 @@ CString CPetText::getColorText(byte r, byte g, byte b) { return CString(buffer); } -void CPetText::load(SimpleFile *file, int param) { +void CTextControl::load(SimpleFile *file, int param) { if (!param) { uint numLines = file->readNumber(); int charsPerLine = file->readNumber(); @@ -116,7 +116,7 @@ void CPetText::load(SimpleFile *file, int param) { } } -void CPetText::save(SimpleFile *file, int indent) { +void CTextControl::save(SimpleFile *file, int indent) { int numLines = _lineCount + 1; file->writeNumberLine(_array.size(), indent); @@ -143,7 +143,7 @@ void CPetText::save(SimpleFile *file, int indent) { } } -void CPetText::draw(CScreenManager *screenManager) { +void CTextControl::draw(CScreenManager *screenManager) { Rect tempRect = _bounds; if (_hasBorder) { @@ -179,7 +179,7 @@ void CPetText::draw(CScreenManager *screenManager) { screenManager->setFontNumber(oldFontNumber); } -void CPetText::mergeStrings() { +void CTextControl::mergeStrings() { if (!_stringsMerged) { _lines.clear(); @@ -193,14 +193,14 @@ void CPetText::mergeStrings() { } } -void CPetText::resize(uint count) { +void CTextControl::resize(uint count) { if (!count || _array.size() == count) return; _array.clear(); _array.resize(count); } -CString CPetText::getText() const { +CString CTextControl::getText() const { CString result = ""; for (int idx = 0; idx <= _lineCount; ++idx) result += _array[idx]._line; @@ -208,16 +208,16 @@ CString CPetText::getText() const { return result; } -void CPetText::setText(const CString &str) { +void CTextControl::setText(const CString &str) { setup(); appendText(str); } -void CPetText::setText(StringId stringId) { +void CTextControl::setText(StringId stringId) { setText(g_vm->_strings[stringId]); } -void CPetText::appendText(const CString &str) { +void CTextControl::appendText(const CString &str) { int lineSize = _array[_lineCount]._line.size(); int strSize = str.size(); @@ -236,19 +236,19 @@ void CPetText::appendText(const CString &str) { _stringsMerged = false; } -void CPetText::setColor(uint col) { +void CTextControl::setColor(uint col) { _textR = col & 0xff; _textG = (col >> 8) & 0xff; _textB = (col >> 16) & 0xff; } -void CPetText::setColor(byte r, byte g, byte b) { +void CTextControl::setColor(byte r, byte g, byte b) { _textR = r; _textG = g; _textB = b; } -void CPetText::remapColors(uint count, uint *srcColors, uint *destColors) { +void CTextControl::remapColors(uint count, uint *srcColors, uint *destColors) { for (int lineNum = 0; lineNum <= _lineCount; ++lineNum) { if (_array[lineNum]._rgb.empty()) continue; @@ -271,12 +271,12 @@ void CPetText::remapColors(uint count, uint *srcColors, uint *destColors) { _stringsMerged = false; } -void CPetText::setMaxCharsPerLine(int maxChars) { +void CTextControl::setMaxCharsPerLine(int maxChars) { if (maxChars >= -1 && maxChars < 257) _maxCharsPerLine = maxChars; } -void CPetText::updateStr3(int lineNum) { +void CTextControl::updateStr3(int lineNum) { if (_npcFlag > 0 && _npcId > 0) { char line[5]; line[0] = line[3] = TEXTCMD_NPC; @@ -290,7 +290,7 @@ void CPetText::updateStr3(int lineNum) { } } -int CPetText::getTextWidth(CScreenManager *screenManager) { +int CTextControl::getTextWidth(CScreenManager *screenManager) { mergeStrings(); int oldFontNumber = screenManager->setFontNumber(_fontNumber); int textWidth = screenManager->stringWidth(_lines); @@ -299,7 +299,7 @@ int CPetText::getTextWidth(CScreenManager *screenManager) { return textWidth; } -int CPetText::getTextHeight(CScreenManager *screenManager) { +int CTextControl::getTextHeight(CScreenManager *screenManager) { mergeStrings(); int oldFontNumber = screenManager->setFontNumber(_fontNumber); int textHeight = screenManager->getTextBounds(_lines, _bounds.width() - 4); @@ -308,63 +308,63 @@ int CPetText::getTextHeight(CScreenManager *screenManager) { return textHeight; } -void CPetText::deleteLastChar() { +void CTextControl::deleteLastChar() { if (!_array[_lineCount]._line.empty()) { _array[_lineCount]._line.deleteLastChar(); _stringsMerged = false; } } -void CPetText::setNPC(int npcFlag, int npcId) { +void CTextControl::setNPC(int npcFlag, int npcId) { _npcFlag = npcFlag; _npcId = npcId; } -void CPetText::scrollUp(CScreenManager *screenManager) { +void CTextControl::scrollUp(CScreenManager *screenManager) { int oldFontNumber = screenManager->setFontNumber(_fontNumber); _scrollTop -= screenManager->getFontHeight(); constrainScrollUp(screenManager); screenManager->setFontNumber(oldFontNumber); } -void CPetText::scrollDown(CScreenManager *screenManager) { +void CTextControl::scrollDown(CScreenManager *screenManager) { int oldFontNumber = screenManager->setFontNumber(_fontNumber); _scrollTop += screenManager->getFontHeight(); constrainScrollDown(screenManager); screenManager->setFontNumber(oldFontNumber); } -void CPetText::scrollUpPage(CScreenManager *screenManager) { +void CTextControl::scrollUpPage(CScreenManager *screenManager) { int oldFontNumber = screenManager->setFontNumber(_fontNumber); _scrollTop -= getPageHeight(screenManager); constrainScrollUp(screenManager); screenManager->setFontNumber(oldFontNumber); } -void CPetText::scrollDownPage(CScreenManager *screenManager) { +void CTextControl::scrollDownPage(CScreenManager *screenManager) { int oldFontNumber = screenManager->setFontNumber(_fontNumber); _scrollTop += getPageHeight(screenManager); constrainScrollDown(screenManager); screenManager->setFontNumber(oldFontNumber); } -void CPetText::scrollToTop(CScreenManager *screenManager) { +void CTextControl::scrollToTop(CScreenManager *screenManager) { _scrollTop = 0; } -void CPetText::scrollToBottom(CScreenManager *screenManager) { +void CTextControl::scrollToBottom(CScreenManager *screenManager) { int oldFontNumber = screenManager->setFontNumber(_fontNumber); _scrollTop = getTextHeight(screenManager); constrainScrollDown(screenManager); screenManager->setFontNumber(oldFontNumber); } -void CPetText::constrainScrollUp(CScreenManager *screenManager) { +void CTextControl::constrainScrollUp(CScreenManager *screenManager) { if (_scrollTop < 0) _scrollTop = 0; } -void CPetText::constrainScrollDown(CScreenManager *screenManager) { +void CTextControl::constrainScrollDown(CScreenManager *screenManager) { // Figure out the maximum scroll amount allowed int maxScroll = getTextHeight(screenManager) - _bounds.height() - 4; if (maxScroll < 0) @@ -374,7 +374,7 @@ void CPetText::constrainScrollDown(CScreenManager *screenManager) { _scrollTop = maxScroll; } -int CPetText::getPageHeight(CScreenManager *screenManager) { +int CTextControl::getPageHeight(CScreenManager *screenManager) { int textHeight = _bounds.height(); int oldFontNumber = screenManager->setFontNumber(_fontNumber); int fontHeight = screenManager->getFontHeight(); @@ -390,16 +390,16 @@ int CPetText::getPageHeight(CScreenManager *screenManager) { } } -void CPetText::addLine(const CString &str) { +void CTextControl::addLine(const CString &str) { addLine(str, _textR, _textG, _textB); } -void CPetText::addLine(const CString &str, uint color) { +void CTextControl::addLine(const CString &str, uint color) { addLine(str, color & 0xff, (color >> 8) & 0xff, (color >> 16) & 0xff); } -void CPetText::addLine(const CString &str, byte r, byte g, byte b) { +void CTextControl::addLine(const CString &str, byte r, byte g, byte b) { if (_lineCount == ((int)_array.size() - 1)) { // Lines array is full if (_array.size() > 1) { @@ -416,7 +416,7 @@ void CPetText::addLine(const CString &str, byte r, byte g, byte b) { ++_lineCount; } -bool CPetText::handleKey(char c) { +bool CTextControl::handleKey(char c) { switch (c) { case (char)Common::KEYCODE_BACKSPACE: deleteLastChar(); @@ -434,7 +434,7 @@ bool CPetText::handleKey(char c) { return false; } -void CPetText::showCursor(int mode) { +void CTextControl::showCursor(int mode) { CScreenManager *screenManager = CScreenManager::setCurrent(); _textCursor = screenManager->_textCursor; if (_textCursor) { @@ -448,7 +448,7 @@ void CPetText::showCursor(int mode) { } } -void CPetText::hideCursor() { +void CTextControl::hideCursor() { if (_textCursor) { _textCursor->setMode(-1); _textCursor->hide(); @@ -456,7 +456,7 @@ void CPetText::hideCursor() { } } -int CPetText::getNPCNum(uint ident, uint startIndex) { +int CTextControl::getNPCNum(uint ident, uint startIndex) { if (!_stringsMerged) { mergeStrings(); if (!_stringsMerged) @@ -483,7 +483,7 @@ int CPetText::getNPCNum(uint ident, uint startIndex) { return -1; } -void CPetText::setFontNumber(int fontNumber) { +void CTextControl::setFontNumber(int fontNumber) { if (fontNumber >= 0 && fontNumber <= 2) _fontNumber = fontNumber; } diff --git a/engines/titanic/pet_control/pet_text.h b/engines/titanic/gfx/text_control.h index 9b2f47274c..d4ef19a7cf 100644 --- a/engines/titanic/pet_control/pet_text.h +++ b/engines/titanic/gfx/text_control.h @@ -20,8 +20,8 @@ * */ -#ifndef TITANIC_PET_TEXT_H -#define TITANIC_PET_TEXT_H +#ifndef TITANIC_TEXT_CONTROL_H +#define TITANIC_TEXT_CONTROL_H #include "common/keyboard.h" #include "titanic/support/simple_file.h" @@ -30,7 +30,7 @@ namespace Titanic { -class CPetText { +class CTextControl { struct ArrayEntry { CString _line; CString _rgb; @@ -91,7 +91,7 @@ private: */ int getPageHeight(CScreenManager *screenManager); public: - CPetText(uint count = 10); + CTextControl(uint count = 10); /** * Set up the control @@ -282,4 +282,4 @@ public: } // End of namespace Titanic -#endif /* TITANIC_PET_TEXT_H */ +#endif /* TITANIC_TEXT_CONTROL_H */ diff --git a/engines/titanic/input_handler.cpp b/engines/titanic/input_handler.cpp index ba2c08ed89..481224141d 100644 --- a/engines/titanic/input_handler.cpp +++ b/engines/titanic/input_handler.cpp @@ -32,7 +32,7 @@ namespace Titanic { CInputHandler::CInputHandler(CGameManager *owner) : _gameManager(owner), _inputTranslator(nullptr), _dragging(false), _buttonDown(false), _dragItem(nullptr), _lockCount(0), - _singleton(false) { + _abortMessage(false) { CScreenManager::_screenManagerPtr->_inputHandler = this; } @@ -59,7 +59,7 @@ void CInputHandler::decLockCount() { } _buttonDown = _inputTranslator->isMousePressed(); - _singleton = true; + _abortMessage = true; } } @@ -75,11 +75,11 @@ void CInputHandler::handleMessage(CMessage &msg, bool respectLock) { void CInputHandler::processMessage(CMessage *msg) { const CMouseMsg *mouseMsg = dynamic_cast<const CMouseMsg *>(msg); - _singleton = false; + _abortMessage = false; dispatchMessage(msg); - if (_singleton) { - _singleton = false; + if (_abortMessage) { + _abortMessage = false; } else if (mouseMsg) { // Keep the game state mouse position up to date if (_mousePos != mouseMsg->_mousePos) { diff --git a/engines/titanic/input_handler.h b/engines/titanic/input_handler.h index d5f29b7921..5f0be04f1a 100644 --- a/engines/titanic/input_handler.h +++ b/engines/titanic/input_handler.h @@ -56,7 +56,7 @@ public: Point _dragStartPos; Point _mousePos; int _lockCount; - bool _singleton; + bool _abortMessage; public: CInputHandler(CGameManager *owner); ~CInputHandler(); diff --git a/engines/titanic/messages/messages.h b/engines/titanic/messages/messages.h index a40477a702..0cbb4b0e76 100644 --- a/engines/titanic/messages/messages.h +++ b/engines/titanic/messages/messages.h @@ -87,6 +87,7 @@ class CRoomItem; class CNodeItem; class CViewItem; class CMusicPlayer; +class CMovePlayerTo; class CMessage : public CSaveableObject { private: @@ -148,9 +149,27 @@ public: virtual bool isLeaveViewMsg() const; }; +enum EditControlAction { + EDIT_INIT = 0, + EDIT_CLEAR = 1, + EDIT_SET_TEXT = 2, + EDIT_GET_TEXT = 3, + EDIT_LENGTH = 4, + EDIT_MAX_LENGTH = 5, + EDIT_KEYPRESS = 6, + EDIT_SET_FONT = 7, + EDIT_SHOW_CURSOR = 8, + EDIT_HIDE_CURSOR = 9, + EDIT_BORDERS = 10, + EDIT_SET_COLOR = 11, + EDIT_SHOW = 12, + EDIT_HIDE = 13, + EDIT_RENDER = 14 +}; + class CEditControlMsg : public CMessage { public: - int _mode; + EditControlAction _mode; int _param; CString _text; byte _textR; @@ -158,7 +177,7 @@ public: byte _textB; public: CLASSDEF; - CEditControlMsg() : _mode(0), _param(0), _textR(0), _textG(0), _textB(0) {} + CEditControlMsg() : _mode(EDIT_INIT), _param(0), _textR(0), _textG(0), _textB(0) {} static bool isSupportedBy(const CTreeItem *item) { return CMessage::supports(item, _type); @@ -197,6 +216,12 @@ public: } }; +enum MissiveOMatAction { + MESSAGE_NONE = 1, MESSAGE_SHOW = 2, NEXT_MESSAGE = 3, PRIOR_MESSAGE = 4, + MESSAGE_5 = 5, MESSAGE_DOWN = 6, MESSAGE_UP = 7, REDRAW_MESSAGE = 8, + MESSAGE_9 = 9 +}; + MESSAGE1(CActMsg, CString, action, ""); MESSAGE1(CActivationmsg, CString, value, ""); MESSAGE1(CAddHeadPieceMsg, CString, value, "NULL"); @@ -260,7 +285,7 @@ MESSAGE1(CLoadSuccessMsg, int, ticks, 0); MESSAGE1(CLockPhonographMsg, int, value, 0); MESSAGE0(CMaitreDDefeatedMsg); MESSAGE0(CMaitreDHappyMsg); -MESSAGE1(CMissiveOMatActionMsg, int, action, 0); +MESSAGE1(CMissiveOMatActionMsg, MissiveOMatAction, action, MESSAGE_NONE); MESSAGE0(CMoveToStartPosMsg); MESSAGE2(CMovieEndMsg, int, startFrame, 0, int, endFrame, 0); MESSAGE2(CMovieFrameMsg, int, frameNumber, 0, int, value2, 0); @@ -274,7 +299,7 @@ MESSAGE0(CNPCQueueIdleAnimMsg); MESSAGE1(CNutPuzzleMsg, CString, value, ""); MESSAGE1(COnSummonBotMsg, int, value, 0); MESSAGE0(COpeningCreditsMsg); -MESSAGE1(CPanningAwayFromParrotMsg, CTreeItem *, target, nullptr); +MESSAGE1(CPanningAwayFromParrotMsg, CMovePlayerTo *, target, nullptr); MESSAGE2(CParrotSpeakMsg, CString, target, "", CString, action, ""); MESSAGE2(CParrotTriesChickenMsg, int, value1, 0, int, value2, 0); MESSAGE1(CPhonographPlayMsg, int, value, 0); diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk index e802456c5a..51c77ba1dd 100644 --- a/engines/titanic/module.mk +++ b/engines/titanic/module.mk @@ -280,6 +280,7 @@ MODULE_OBJS := \ gfx/chev_right_on.o \ gfx/chev_send_rec_switch.o \ gfx/edit_control.o \ + gfx/text_control.o \ gfx/elevator_button.o \ gfx/get_from_succ.o \ gfx/helmet_on_off.o \ @@ -398,7 +399,6 @@ MODULE_OBJS := \ pet_control/pet_show_translation.o \ pet_control/pet_slider.o \ pet_control/pet_sound.o \ - pet_control/pet_text.o \ sound/auto_music_player.o \ sound/auto_music_player_base.o \ sound/auto_sound_player.o \ diff --git a/engines/titanic/npcs/bilge_succubus.cpp b/engines/titanic/npcs/bilge_succubus.cpp index d0a5dc17ae..36627842a5 100644 --- a/engines/titanic/npcs/bilge_succubus.cpp +++ b/engines/titanic/npcs/bilge_succubus.cpp @@ -42,26 +42,26 @@ BEGIN_MESSAGE_MAP(CBilgeSuccUBus, CSuccUBus) END_MESSAGE_MAP() CBilgeSuccUBus::CBilgeSuccUBus() : CSuccUBus(), - _bilgeStartFrame1(-1), _bilgeEndFrame1(-1), - _bilgeStartFrame2(-1), _bilgeEndFrame2(-1) { + _sneezing2StartFrame(-1), _sneezing2EndFrame(-1), + _sneezing1StartFrame(-1), _sneezing1EndFrame(-1) { } void CBilgeSuccUBus::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_bilgeStartFrame1, indent); - file->writeNumberLine(_bilgeEndFrame1, indent); - file->writeNumberLine(_bilgeStartFrame2, indent); - file->writeNumberLine(_bilgeEndFrame2, indent); + file->writeNumberLine(_sneezing2StartFrame, indent); + file->writeNumberLine(_sneezing2EndFrame, indent); + file->writeNumberLine(_sneezing1StartFrame, indent); + file->writeNumberLine(_sneezing1EndFrame, indent); CSuccUBus::save(file, indent); } void CBilgeSuccUBus::load(SimpleFile *file) { file->readNumber(); - _bilgeStartFrame1 = file->readNumber(); - _bilgeEndFrame1 = file->readNumber(); - _bilgeStartFrame2 = file->readNumber(); - _bilgeEndFrame2 = file->readNumber(); + _sneezing2StartFrame = file->readNumber(); + _sneezing2EndFrame = file->readNumber(); + _sneezing1StartFrame = file->readNumber(); + _sneezing1EndFrame = file->readNumber(); CSuccUBus::load(file); } @@ -74,10 +74,10 @@ bool CBilgeSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) { CPetControl *pet = getPetControl(); if (_v2) { - if (_startFrame4 >= 0) - playMovie(_startFrame4, _endFrame4, MOVIE_GAMESTATE); - if (_startFrame5 >= 0) - playMovie(_startFrame5, _endFrame5, MOVIE_GAMESTATE); + if (_receiveStartFrame >= 0) + playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_GAMESTATE); + if (_afterReceiveStartFrame >= 0) + playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, MOVIE_GAMESTATE); playSound("z#28.wav", 70); } else if (!_enabled) { @@ -93,8 +93,8 @@ bool CBilgeSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) { if (mailObject) { _mailP = mailObject; - if (_startFrame4 >= 0) - playMovie(_startFrame4, _endFrame4, MOVIE_GAMESTATE); + if (_receiveStartFrame >= 0) + playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_GAMESTATE); } else { petDisplayMessage(2, NOTHING_TO_DELIVER); } @@ -116,14 +116,13 @@ bool CBilgeSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { return true; } - _field19C = 0; + _sendLost = false; _mailP = mailObject; uint roomFlags = _roomFlags; - if (!pet->testRooms5(roomFlags) || - getPassengerClass() > pet->getMailDest(roomFlags)) { + if (!pet->isSuccUBusDest(roomFlags) || pet->getMailDestClass(roomFlags) < getPassengerClass()) { roomFlags = pet->getSpecialRoomFlags("BilgeRoom"); - _field19C = 1; + _sendLost = true; } _isChicken = mailObject->getName() == "Chicken"; @@ -135,42 +134,42 @@ bool CBilgeSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { startTalking(this, 230022); _field158 = 1; - if (_startFrame3 >= 0) - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT); + if (_sendStartFrame >= 0) + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT); - if (_bilgeStartFrame1 >= 0) { - playMovie(_startFrame12, _endFrame12, MOVIE_GAMESTATE); - playMovie(_bilgeStartFrame2, _bilgeEndFrame2, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); - playMovie(_bilgeStartFrame1, _bilgeEndFrame1, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + if (_sneezing2StartFrame >= 0) { + playMovie(_trayOutStartFrame, _trayOutEndFrame, MOVIE_GAMESTATE); + playMovie(_sneezing1StartFrame, _sneezing1EndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + playMovie(_sneezing2StartFrame, _sneezing2EndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); incTransitions(); } } else { startTalking(this, 230012); _field158 = 2; - if (_startFrame3 >= 0) - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); - if (_startFrame4 >= 0) - playMovie(_startFrame4, _endFrame4, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); - if (_startFrame5 >= 0) - playMovie(_startFrame5, _endFrame5, MOVIE_GAMESTATE); + if (_sendStartFrame >= 0) + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + if (_receiveStartFrame >= 0) + playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + if (_afterReceiveStartFrame >= 0) + playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, MOVIE_GAMESTATE); } } else { if (_isFeathers) { startTalking(this, 230022); _field158 = 3; - if (_startFrame3 >= 0) - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); - if (_startFrame4 >= 0) - playMovie(_startFrame4, _endFrame4, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); - if (_startFrame5 >= 0) - playMovie(_startFrame5, _endFrame5, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + if (_sendStartFrame >= 0) + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + if (_receiveStartFrame >= 0) + playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + if (_afterReceiveStartFrame >= 0) + playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); } else { - removeMail(petRoomFlags, roomFlags); + sendMail(petRoomFlags, roomFlags); startTalking(this, 230012); - if (_startFrame3 >= 0) { + if (_sendStartFrame >= 0) { _field158 = 4; - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); } } } @@ -181,14 +180,14 @@ bool CBilgeSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { CPetControl *pet = getPetControl(); - if (msg->_endFrame == _endFrame12) { - if (_startFrame10 >= 0) + if (msg->_endFrame == _trayOutEndFrame) { + if (_offStartFrame >= 0) playSound("z#27.wav"); - } else if (msg->_endFrame == _endFrame10) { + } else if (msg->_endFrame == _offEndFrame) { if (_startFrame11 >= 0) playSound("z#30.wav"); } else { - if (_endFrame9 == _endFrame10 && pet) { + if (msg->_endFrame == _onEndFrame && pet) { if (_v2) { startTalking(this, getRandomNumber(1) ? 230062 : 230063); } else if (!findMail(pet->getRoomFlags())) { @@ -206,9 +205,8 @@ bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { break; } } - } - if (msg->_endFrame == _endFrame3) { + } else if (msg->_endFrame == _sendEndFrame) { switch (_field158) { case 1: stopSound(_soundHandle); @@ -236,11 +234,7 @@ bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { CSUBTransition transMsg; transMsg.execute(this); - } else if (msg->_endFrame == _bilgeEndFrame2) { - playSound("z#25.wav", 70); - playSound("z#24.wav", 70); - - } else if (msg->_endFrame == _endFrame4) { + } else if (msg->_endFrame == _receiveEndFrame) { if (_mailP) { _mailP->petAddToInventory(); CVisibleMsg visibleMsg(true); @@ -253,7 +247,11 @@ bool CBilgeSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { transMsg.execute(this); } - } else if (msg->_endFrame == _bilgeEndFrame1) { + } else if (msg->_endFrame == _sneezing1EndFrame) { + playSound("z#25.wav", 70); + playSound("z#24.wav", 70); + + } else if (msg->_endFrame == _sneezing2EndFrame) { changeView("BilgeRoomWith.Node 1.N", ""); _v2 = 0; resetMail(); @@ -342,14 +340,14 @@ bool CBilgeSuccUBus::SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg) { bool chickenFlag = chicken ? chicken->_string6 == "None" : false; if (chickenFlag) { - if (_startFrame2 >= 0) { + if (_okStartFrame >= 0) { startTalking(this, 70219); - playMovie(_startFrame2, _endFrame2, 0); + playMovie(_okStartFrame, _okEndFrame, 0); } - if (_startFrame3 >= 0) { + if (_sendStartFrame >= 0) { _field158 = 5; - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT); + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT); } CViewItem *view = parseView(item->_fullViewName); @@ -365,8 +363,8 @@ bool CBilgeSuccUBus::SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg) { } } else { item->addMail(petRoomFlags); - if (_startFrame2 >= 0) - playMovie(_startFrame2, _endFrame2, 0); + if (_okStartFrame >= 0) + playMovie(_okStartFrame, _okEndFrame, 0); petSetArea(PET_REMOTE); CSUBTransition transMsg; @@ -397,7 +395,7 @@ bool CBilgeSuccUBus::LeaveViewMsg(CLeaveViewMsg *msg) { if (_enabled) { _enabled = false; - if (_startFrame10 >= 0) + if (_offStartFrame >= 0) playSound("z#27.wav"); } @@ -419,13 +417,13 @@ bool CBilgeSuccUBus::TurnOn(CTurnOn *msg) { CPetControl *pet = getPetControl(); if (pet) { - if (_startFrame9 >= 0) { - playMovie(_startFrame9, _endFrame9, MOVIE_NOTIFY_OBJECT); + if (_onStartFrame >= 0) { + playMovie(_onStartFrame, _onEndFrame, MOVIE_NOTIFY_OBJECT); playSound("z#26.wav"); } - if (mailExists(pet->getRoomFlags()) && _startFrame2 >= 0) - playMovie(_startFrame2, _endFrame2, 0); + if (mailExists(pet->getRoomFlags()) && _okStartFrame >= 0) + playMovie(_okStartFrame, _okEndFrame, 0); _enabled = true; CSUBTransition transMsg; @@ -442,18 +440,18 @@ bool CBilgeSuccUBus::TurnOn(CTurnOn *msg) { bool CBilgeSuccUBus::TurnOff(CTurnOff *msg) { CPetControl *pet = getPetControl(); - if (pet && mailExists(pet->getRoomFlags()) && _startFrame12 >= 0) - playMovie(_startFrame12, _endFrame12, MOVIE_NOTIFY_OBJECT); - else if (_endFrame12 >= 0) - playMovie(_endFrame12, _endFrame12, MOVIE_NOTIFY_OBJECT); + if (pet && mailExists(pet->getRoomFlags()) && _trayOutStartFrame >= 0) + playMovie(_trayOutStartFrame, _trayOutEndFrame, MOVIE_NOTIFY_OBJECT); + else if (_trayOutEndFrame >= 0) + playMovie(_trayOutEndFrame, _trayOutEndFrame, MOVIE_NOTIFY_OBJECT); if (_soundHandle != -1) { stopSound(_soundHandle); _soundHandle = -1; } - if (_startFrame10 >= 0) - playMovie(_startFrame10, _endFrame10, MOVIE_NOTIFY_OBJECT); + if (_offStartFrame >= 0) + playMovie(_offStartFrame, _offEndFrame, MOVIE_NOTIFY_OBJECT); _enabled = false; performAction(true); diff --git a/engines/titanic/npcs/bilge_succubus.h b/engines/titanic/npcs/bilge_succubus.h index 754949a306..b56716d110 100644 --- a/engines/titanic/npcs/bilge_succubus.h +++ b/engines/titanic/npcs/bilge_succubus.h @@ -41,10 +41,10 @@ class CBilgeSuccUBus : public CSuccUBus { bool TurnOn(CTurnOn *msg); bool TurnOff(CTurnOff *msg); public: - int _bilgeStartFrame1; - int _bilgeEndFrame1; - int _bilgeStartFrame2; - int _bilgeEndFrame2; + int _sneezing2StartFrame; + int _sneezing2EndFrame; + int _sneezing1StartFrame; + int _sneezing1EndFrame; public: CLASSDEF; CBilgeSuccUBus(); diff --git a/engines/titanic/npcs/parrot.cpp b/engines/titanic/npcs/parrot.cpp index e9aeba11cd..e039b15dfe 100644 --- a/engines/titanic/npcs/parrot.cpp +++ b/engines/titanic/npcs/parrot.cpp @@ -48,7 +48,7 @@ END_MESSAGE_MAP() int CParrot::_v1; int CParrot::_v2; int CParrot::_v3; -int CParrot::_v4; +ParrotState CParrot::_state; int CParrot::_v5; CParrot::CParrot() : CTrueTalkNPC() { @@ -56,12 +56,12 @@ CParrot::CParrot() : CTrueTalkNPC() { _string2 = "CarryParrot"; _field118 = 1; _field11C = 25; - _field120 = 0; - _field124 = 73; - _field128 = 58; + _lastSpeakTime = 0; + _newXp = 73; + _newXc = 58; _field12C = 0; _field130 = 0; - _field134 = nullptr; + _panTarget = nullptr; _field138 = 851; _field13C = 851; _field140 = 265; @@ -126,12 +126,12 @@ void CParrot::save(SimpleFile *file, int indent) { file->writeQuotedLine(_string2, indent); file->writeNumberLine(_field118, indent); file->writeNumberLine(_field11C, indent); - file->writeNumberLine(_field120, indent); - file->writeNumberLine(_field124, indent); - file->writeNumberLine(_field128, indent); + file->writeNumberLine(_lastSpeakTime, indent); + file->writeNumberLine(_newXp, indent); + file->writeNumberLine(_newXc, indent); file->writeNumberLine(_field12C, indent); file->writeNumberLine(_field130, indent); - file->writeNumberLine(_v4, indent); + file->writeNumberLine(_state, indent); file->writeNumberLine(_v5, indent); CTrueTalkNPC::save(file, indent); @@ -150,12 +150,12 @@ void CParrot::load(SimpleFile *file) { _string2 = file->readString(); _field118 = file->readNumber(); _field11C = file->readNumber(); - _field120 = file->readNumber(); - _field124 = file->readNumber(); - _field128 = file->readNumber(); + _lastSpeakTime = file->readNumber(); + _newXp = file->readNumber(); + _newXc = file->readNumber(); _field12C = file->readNumber(); _field130 = file->readNumber(); - _v4 = file->readNumber(); + _state = (ParrotState)file->readNumber(); _v5 = file->readNumber(); CTrueTalkNPC::load(file); @@ -175,13 +175,13 @@ bool CParrot::ActMsg(CActMsg *msg) { statusMsg.execute("PerchCoreHolder"); } } else if (msg->_action == "StartChickenDrag") { - if (!_v4) { + if (_state == PARROT_IN_CAGE) { stopMovie(); startTalking(this, 280275, findView()); _field12C = 0; } } else if (msg->_action == "EnteringFromTOW" && - (_v4 == 0 || _v4 == 2)) { + (_state == PARROT_IN_CAGE || _state == PARROT_ESCAPED)) { if (_v2) { _v2 = 2; } else { @@ -190,7 +190,7 @@ bool CParrot::ActMsg(CActMsg *msg) { detach(); attach(cageBar); - _v4 = 0; + _state = PARROT_IN_CAGE; CActMsg actMsg1("OpenNow"); actMsg1.execute("ParrotCage"); CActMsg actMsg2("GainParrot"); @@ -219,17 +219,17 @@ bool CParrot::MovieEndMsg(CMovieEndMsg *msg) { CActMsg actMsg1("LoseParrot"); actMsg1.execute("ParrotLobbyController"); - if (_field134) { + if (_panTarget) { CActMsg actMsg2("PanAwayFromParrot"); - actMsg2.execute(_field134); - _field134 = nullptr; + actMsg2.execute(_panTarget); + _panTarget = nullptr; } else { CActMsg actMsg2("Shut"); actMsg2.execute("ParrotCage"); } _npcFlags &= ~NPCFLAG_2000000; - _v4 = 2; + _state = PARROT_ESCAPED; } else if (_npcFlags & NPCFLAG_10000) { if (_npcFlags & NPCFLAG_20000) { _npcFlags = (_npcFlags & ~NPCFLAG_20000) | NPCFLAG_40000; @@ -243,7 +243,7 @@ bool CParrot::MovieEndMsg(CMovieEndMsg *msg) { int xp = _bounds.left + _bounds.width() / 2; if (_npcFlags & NPCFLAG_100000) { - if ((xp - _field128) > 32) { + if ((xp - _newXc) > 32) { setPosition(Point(_bounds.left - 40, _bounds.top)); playClip("Walk Left Loop", MOVIE_NOTIFY_OBJECT); movieEvent(236); @@ -253,7 +253,7 @@ bool CParrot::MovieEndMsg(CMovieEndMsg *msg) { _npcFlags = (_npcFlags & ~NPCFLAG_40000) | NPCFLAG_80000; } } else { - if ((_field128 - xp) > 32) { + if ((_newXc - xp) > 32) { playClip("Walk Right Loop", MOVIE_NOTIFY_OBJECT); movieEvent(244); } else { @@ -347,8 +347,8 @@ bool CParrot::EnterViewMsg(CEnterViewMsg *msg) { "Talking5", "Talking6", "Talking7", nullptr }; - if (!_v4) { - setPosition(Point(_field124, _bounds.top)); + if (_state == PARROT_IN_CAGE) { + setPosition(Point(_newXp, _bounds.top)); _field118 = 1; _npcFlags &= ~(NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000); loadFrame(0); @@ -369,7 +369,7 @@ bool CParrot::EnterViewMsg(CEnterViewMsg *msg) { } bool CParrot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) { - if (_v4 != 3) { + if (_state != PARROT_MAILED) { CViewItem *view = msg->_param2 ? findView() : nullptr; startTalking(this, msg->_action, view); } @@ -378,7 +378,7 @@ bool CParrot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) { } bool CParrot::MouseDragStartMsg(CMouseDragStartMsg *msg) { - if (_field118 && !_v4 && checkPoint(msg->_mousePos, false, true)) { + if (_field118 && _state == PARROT_IN_CAGE && checkPoint(msg->_mousePos, false, true)) { setVisible(false); CRoomItem *room = findRoom(); @@ -416,7 +416,7 @@ bool CParrot::ParrotSpeakMsg(CParrotSpeakMsg *msg) { "Lift", "ServiceElevator", "Dome", "Home", "MoonEmbLobby", nullptr }; - if (!stateGetParrotMet() || _v4 == 3 || compareViewNameTo("Titania.Node 18.N")) + if (!stateGetParrotMet() || _state == PARROT_MAILED || compareViewNameTo("Titania.Node 18.N")) return true; // Check for rooms not to speak in @@ -426,7 +426,7 @@ bool CParrot::ParrotSpeakMsg(CParrotSpeakMsg *msg) { } // Don't have the parrot speak too often - if ((getTicksCount() - _field120) < 20000 || _speechCounter) + if ((getTicksCount() - _lastSpeakTime) < 20000 || _speechCounter) return true; playSound("z#475.wav", 50); @@ -473,7 +473,7 @@ bool CParrot::ParrotSpeakMsg(CParrotSpeakMsg *msg) { } } - _field120 = getTicksCount(); + _lastSpeakTime = getTicksCount(); return true; } @@ -484,7 +484,7 @@ bool CParrot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) { }; if (!(_npcFlags & (NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000)) - && _visible && !_v4) { + && _visible && _state == PARROT_IN_CAGE) { if (!compareViewNameTo("ParrotLobby.Node 1.N")) msg->_names = NAMES; } @@ -499,7 +499,7 @@ bool CParrot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) { }; if (!(_npcFlags & (NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000)) - && _visible && !_v4 && !compareViewNameTo("ParrotLobby.Node 1.N")) { + && _visible && _state == PARROT_IN_CAGE && !compareViewNameTo("ParrotLobby.Node 1.N")) { CGameObject *dragItem = getDraggingObject(); if (!dragItem || dragItem->getName() == "Chicken") { if (!_v5 ||getRandomNumber(3) != 0) { @@ -564,9 +564,9 @@ bool CParrot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) { } bool CParrot::FrameMsg(CFrameMsg *msg) { - if (compareViewNameTo("ParrotLobby.Node 1.N")) + if (!compareViewNameTo("ParrotLobby.Node 1.N")) return false; - if (_v4) + if (_state != PARROT_IN_CAGE) return true; Point pt = getMousePos(); @@ -574,12 +574,14 @@ bool CParrot::FrameMsg(CFrameMsg *msg) { int xp = _bounds.left + _bounds.width() / 2; if ((_npcFlags & NPCFLAG_400000) && !hasActiveMovie()) { - _field128 = xp - (_field124 + _bounds.width() / 2); + _newXc = _newXp + _bounds.width() / 2; + int xDiff = ABS(xp - _newXc); - if (xp < 64) { - if (_field134) { + if (xDiff < 64) { + if (_panTarget) { CActMsg actMsg("PanAwayFromParrot"); - actMsg.execute(_field134); + actMsg.execute(_panTarget); + _panTarget = nullptr; } _npcFlags &= ~(NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 @@ -601,14 +603,14 @@ bool CParrot::FrameMsg(CFrameMsg *msg) { return false; } - _field128 = CLIP((int)pt.x, 230, 480); + _newXc = CLIP((int)pt.x, 230, 480); if ((_npcFlags & NPCFLAG_10000) || hasActiveMovie()) return true; - if (_field128 > 64) { + if (_newXc > 64) { _npcFlags |= NPCFLAG_10000 | NPCFLAG_20000; - if (_field128 >= xp) { + if (_newXc >= xp) { setPosition(Point(_bounds.left + 30, _bounds.top)); _npcFlags |= NPCFLAG_200000; playClip("Walk Right Intro", MOVIE_NOTIFY_OBJECT); @@ -707,7 +709,7 @@ bool CParrot::PutParrotBackMsg(CPutParrotBackMsg *msg) { int xp = CLIP(msg->_value, 230, 480); setVisible(true); moveToView(); - _v4 = 0; + _state = PARROT_IN_CAGE; setPosition(Point(xp - _bounds.width() / 2, _bounds.top)); playRandomClip(NAMES, MOVIE_NOTIFY_OBJECT); @@ -719,7 +721,7 @@ bool CParrot::PutParrotBackMsg(CPutParrotBackMsg *msg) { } bool CParrot::PreEnterViewMsg(CPreEnterViewMsg *msg) { - if (!_v4) { + if (_state == PARROT_IN_CAGE) { loadMovie("z167.avi", false); loadFrame(0); } @@ -728,19 +730,19 @@ bool CParrot::PreEnterViewMsg(CPreEnterViewMsg *msg) { } bool CParrot::PanningAwayFromParrotMsg(CPanningAwayFromParrotMsg *msg) { - if (_v4) { + if (_state != PARROT_IN_CAGE) { CActMsg actMsg("PanAwayFromParrot"); actMsg.execute(msg->_target); - _field134 = 0; + _panTarget = nullptr; } else if (_v2) { - _field134 = msg->_target; + _panTarget = msg->_target; loadMovie("z168.avi", false); stopMovie(); playClip("Take Off", MOVIE_NOTIFY_OBJECT); _npcFlags |= NPCFLAG_2000000; } else { _npcFlags |= NPCFLAG_400000; - _field134 = msg->_target; + _panTarget = msg->_target; stopMovie(); } @@ -748,7 +750,7 @@ bool CParrot::PanningAwayFromParrotMsg(CPanningAwayFromParrotMsg *msg) { } bool CParrot::LeaveRoomMsg(CLeaveRoomMsg *msg) { - if (!_v4) + if (_state == PARROT_IN_CAGE) startTalking(this, 280259); return true; diff --git a/engines/titanic/npcs/parrot.h b/engines/titanic/npcs/parrot.h index 93e0643857..ce0397fb71 100644 --- a/engines/titanic/npcs/parrot.h +++ b/engines/titanic/npcs/parrot.h @@ -24,9 +24,15 @@ #define TITANIC_PARROT_H #include "titanic/npcs/true_talk_npc.h" +#include "titanic/moves/move_player_to.h" namespace Titanic { +enum ParrotState { + PARROT_IN_CAGE = 0, PARROT_1 = 1, PARROT_ESCAPED = 2, + PARROT_MAILED = 3, PARROT_4 = 4 +}; + class CParrot : public CTrueTalkNPC { DECLARE_MESSAGE_MAP; bool ActMsg(CActMsg *msg); @@ -49,19 +55,19 @@ public: static int _v1; static int _v2; static int _v3; - static int _v4; + static ParrotState _state; static int _v5; private: int _field108; CString _string2; int _field118; int _field11C; - int _field120; - int _field124; - int _field128; + uint _lastSpeakTime; + int _newXp; + int _newXc; int _field12C; int _field130; - CTreeItem *_field134; + CMovePlayerTo *_panTarget; int _field138; int _field13C; int _field140; diff --git a/engines/titanic/npcs/parrot_succubus.cpp b/engines/titanic/npcs/parrot_succubus.cpp index 657bde5b66..08866f187d 100644 --- a/engines/titanic/npcs/parrot_succubus.cpp +++ b/engines/titanic/npcs/parrot_succubus.cpp @@ -78,7 +78,7 @@ bool CParrotSuccUBus::HoseConnectedMsg(CHoseConnectedMsg *msg) { if (_enabled) { _enabled = false; } else { - playMovie(_startFrame9, _endFrame9, 0); + playMovie(_onStartFrame, _onEndFrame, 0); playSound("z#26.wav"); } diff --git a/engines/titanic/npcs/starlings.cpp b/engines/titanic/npcs/starlings.cpp index 7e5907f577..ff1c40cf29 100644 --- a/engines/titanic/npcs/starlings.cpp +++ b/engines/titanic/npcs/starlings.cpp @@ -29,34 +29,39 @@ BEGIN_MESSAGE_MAP(CStarlings, CCharacter) ON_MESSAGE(StatusChangeMsg) END_MESSAGE_MAP() -CStarlings::CStarlings() : CCharacter(), _enabled(false) { +bool CStarlings::_dead; + +CStarlings::CStarlings() : CCharacter() { } void CStarlings::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_enabled, indent); + file->writeNumberLine(_dead, indent); CCharacter::save(file, indent); } void CStarlings::load(SimpleFile *file) { file->readNumber(); - _enabled = file->readNumber(); + _dead = file->readNumber(); CCharacter::load(file); } bool CStarlings::EnterViewMsg(CEnterViewMsg *msg) { - if (_enabled) + if (_dead) + // Tis but a flesh wound setVisible(false); else + // Repeatedly play the starlings flying playMovie(MOVIE_REPEAT); return true; } bool CStarlings::StatusChangeMsg(CStatusChangeMsg *msg) { - _enabled = msg->_newStatus == 1; - setVisible(!_enabled); + // I'm not dead.. I'm getting better. + _dead = msg->_newStatus == 1; + setVisible(!_dead); return true; } diff --git a/engines/titanic/npcs/starlings.h b/engines/titanic/npcs/starlings.h index 1998e6490d..4885777087 100644 --- a/engines/titanic/npcs/starlings.h +++ b/engines/titanic/npcs/starlings.h @@ -32,7 +32,8 @@ class CStarlings : public CCharacter { bool EnterViewMsg(CEnterViewMsg *msg); bool StatusChangeMsg(CStatusChangeMsg *msg); private: - bool _enabled; + // This needs to be static to be shared across all starling instances + static bool _dead; public: CLASSDEF; CStarlings(); diff --git a/engines/titanic/npcs/succubus.cpp b/engines/titanic/npcs/succubus.cpp index af859f9f3c..a05cc71d00 100644 --- a/engines/titanic/npcs/succubus.cpp +++ b/engines/titanic/npcs/succubus.cpp @@ -57,22 +57,22 @@ CSuccUBus::CSuccUBus() : CTrueTalkNPC() { _endFrame8 = -1; _startFrame11 = -1; _endFrame11 = -1; - _startFrame3 = 68; - _endFrame3 = 168; - _startFrame4 = 168; - _endFrame4 = 248; - _startFrame9 = 0; - _endFrame9 = 0x0E; - _startFrame10 = 0x0E; - _endFrame10 = 27; - _startFrame2 = 40; - _endFrame2 = 68; + _sendStartFrame = 68; + _sendEndFrame = 168; + _receiveStartFrame = 168; + _receiveEndFrame = 248; + _onStartFrame = 0; + _onEndFrame = 0x0E; + _offStartFrame = 0x0E; + _offEndFrame = 27; + _okStartFrame = 40; + _okEndFrame = 68; _field140 = 1; _mailP = nullptr; - _startFrame5 = 0; - _endFrame5 = 0; - _startFrame12 = 224; - _endFrame12 = 248; + _afterReceiveStartFrame = 0; + _afterReceiveEndFrame = 0; + _trayOutStartFrame = 224; + _trayOutEndFrame = 248; _field158 = 0; _field15C = 0; _string2 = "NULL"; @@ -82,16 +82,16 @@ CSuccUBus::CSuccUBus() : CTrueTalkNPC() { _field184 = 15; _field188 = 0; _rect2 = Rect(0, 0, 240, 340); - _field19C = 0; + _sendLost = false; _soundHandle = -1; _isChicken = false; _isFeathers = false; _field1AC = 0; _field1B0 = 0; - _startFrame6 = 303; - _endFrame6 = 312; - _startFrame7 = 313; - _endFrame7 = 325; + _emptyStartFrame = 303; + _emptyEndFrame = 312; + _smokeStartFrame = 313; + _smokeEndFrame = 325; _field1C4 = 326; _field1C8 = 347; _field1CC = 348; @@ -108,23 +108,23 @@ void CSuccUBus::save(SimpleFile *file, int indent) { file->writeNumberLine(_endFrame8, indent); file->writeNumberLine(_startFrame11, indent); file->writeNumberLine(_endFrame11, indent); - file->writeNumberLine(_startFrame3, indent); - file->writeNumberLine(_endFrame3, indent); - file->writeNumberLine(_startFrame4, indent); - file->writeNumberLine(_endFrame4, indent); - file->writeNumberLine(_startFrame9, indent); - file->writeNumberLine(_endFrame9, indent); - file->writeNumberLine(_startFrame10, indent); - file->writeNumberLine(_endFrame10, indent); - file->writeNumberLine(_startFrame2, indent); - file->writeNumberLine(_endFrame2, indent); + file->writeNumberLine(_sendStartFrame, indent); + file->writeNumberLine(_sendEndFrame, indent); + file->writeNumberLine(_receiveStartFrame, indent); + file->writeNumberLine(_receiveEndFrame, indent); + file->writeNumberLine(_onStartFrame, indent); + file->writeNumberLine(_onEndFrame, indent); + file->writeNumberLine(_offStartFrame, indent); + file->writeNumberLine(_offEndFrame, indent); + file->writeNumberLine(_okStartFrame, indent); + file->writeNumberLine(_okEndFrame, indent); file->writeNumberLine(_field140, indent); file->writeNumberLine(_v2, indent); - file->writeNumberLine(_startFrame5, indent); - file->writeNumberLine(_endFrame5, indent); - file->writeNumberLine(_startFrame12, indent); - file->writeNumberLine(_endFrame12, indent); + file->writeNumberLine(_afterReceiveStartFrame, indent); + file->writeNumberLine(_afterReceiveEndFrame, indent); + file->writeNumberLine(_trayOutStartFrame, indent); + file->writeNumberLine(_trayOutEndFrame, indent); file->writeNumberLine(_field158, indent); file->writeNumberLine(_field15C, indent); @@ -141,16 +141,16 @@ void CSuccUBus::save(SimpleFile *file, int indent) { file->writeNumberLine(_rect2.top, indent); file->writeNumberLine(_rect2.right, indent); file->writeNumberLine(_rect2.bottom, indent); - file->writeNumberLine(_field19C, indent); + file->writeNumberLine(_sendLost, indent); file->writeNumberLine(_soundHandle, indent); file->writeNumberLine(_isChicken, indent); file->writeNumberLine(_isFeathers, indent); file->writeNumberLine(_field1AC, indent); file->writeNumberLine(_field1B0, indent); - file->writeNumberLine(_startFrame6, indent); - file->writeNumberLine(_endFrame6, indent); - file->writeNumberLine(_startFrame7, indent); - file->writeNumberLine(_endFrame7, indent); + file->writeNumberLine(_emptyStartFrame, indent); + file->writeNumberLine(_emptyEndFrame, indent); + file->writeNumberLine(_smokeStartFrame, indent); + file->writeNumberLine(_smokeEndFrame, indent); file->writeNumberLine(_field1C4, indent); file->writeNumberLine(_field1C8, indent); file->writeNumberLine(_field1CC, indent); @@ -172,23 +172,23 @@ void CSuccUBus::load(SimpleFile *file) { _endFrame8 = file->readNumber(); _startFrame11 = file->readNumber(); _endFrame11 = file->readNumber(); - _startFrame3 = file->readNumber(); - _endFrame3 = file->readNumber(); - _startFrame4 = file->readNumber(); - _endFrame4 = file->readNumber(); - _startFrame9 = file->readNumber(); - _endFrame9 = file->readNumber(); - _startFrame10 = file->readNumber(); - _endFrame10 = file->readNumber(); - _startFrame2 = file->readNumber(); - _endFrame2 = file->readNumber(); + _sendStartFrame = file->readNumber(); + _sendEndFrame = file->readNumber(); + _receiveStartFrame = file->readNumber(); + _receiveEndFrame = file->readNumber(); + _onStartFrame = file->readNumber(); + _onEndFrame = file->readNumber(); + _offStartFrame = file->readNumber(); + _offEndFrame = file->readNumber(); + _okStartFrame = file->readNumber(); + _okEndFrame = file->readNumber(); _field140 = file->readNumber(); _v2 = file->readNumber(); - _startFrame5 = file->readNumber(); - _endFrame5 = file->readNumber(); - _startFrame12 = file->readNumber(); - _endFrame12 = file->readNumber(); + _afterReceiveStartFrame = file->readNumber(); + _afterReceiveEndFrame = file->readNumber(); + _trayOutStartFrame = file->readNumber(); + _trayOutEndFrame = file->readNumber(); _field158 = file->readNumber(); _field15C = file->readNumber(); @@ -205,16 +205,16 @@ void CSuccUBus::load(SimpleFile *file) { _rect2.top = file->readNumber(); _rect2.right = file->readNumber(); _rect2.bottom = file->readNumber(); - _field19C = file->readNumber(); + _sendLost = file->readNumber(); _soundHandle = file->readNumber(); _isChicken = file->readNumber(); _isFeathers = file->readNumber(); _field1AC = file->readNumber(); _field1B0 = file->readNumber(); - _startFrame6 = file->readNumber(); - _endFrame6 = file->readNumber(); - _startFrame7 = file->readNumber(); - _endFrame7 = file->readNumber(); + _emptyStartFrame = file->readNumber(); + _emptyEndFrame = file->readNumber(); + _smokeStartFrame = file->readNumber(); + _smokeEndFrame = file->readNumber(); _field1C4 = file->readNumber(); _field1C8 = file->readNumber(); _field1CC = file->readNumber(); @@ -297,13 +297,13 @@ bool CSuccUBus::SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg) { CSUBTransition transMsg; transMsg.execute(this); } else { - if (_startFrame2 >= 0) { + if (_okStartFrame >= 0) { startTalking(this, 70219, findView()); - playMovie(_startFrame2, _endFrame2, 0); + playMovie(_okStartFrame, _okEndFrame, 0); } - if (_startFrame3 >= 0) { - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT); + if (_sendStartFrame >= 0) { + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT); _field158 = 2; } @@ -340,8 +340,8 @@ bool CSuccUBus::LeaveViewMsg(CLeaveViewMsg *msg) { petDisplayMessage(2, BLANK); if (_startFrame8 >= 0) loadFrame(_startFrame8); - else if (!_field15C && _startFrame9 >= 0) - loadFrame(_startFrame9); + else if (!_field15C && _onStartFrame >= 0) + loadFrame(_onStartFrame); petClear(); if (_soundHandle != -1) { @@ -351,7 +351,7 @@ bool CSuccUBus::LeaveViewMsg(CLeaveViewMsg *msg) { if (_enabled) { _enabled = false; - if (_startFrame10 >= 0) + if (_offStartFrame >= 0) playSound("z#27.wav", 100); if (_field15C) @@ -397,14 +397,12 @@ bool CSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { petDisplayMessage(2, NOTHING_IN_SUCCUBUS_TRAY); } else { - _field19C = 0; + _sendLost = false; CRoomFlags roomFlags = _roomFlags; - if (!pet->testRooms5(roomFlags) || getPassengerClass() > 0) { + if (!pet->isSuccUBusDest(roomFlags) || pet->getMailDestClass(roomFlags) < getPassengerClass()) { roomFlags = pet->getSpecialRoomFlags("BilgeRoom"); - _field19C = 1; - } else { - pet->getMailDest(roomFlags); + _sendLost = true; } _isFeathers = mailObject->getName() == "Feathers"; @@ -415,38 +413,40 @@ bool CSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) { incTransitions(); if (_isFeathers) { - _field19C = 0; - removeMail(destRoomFlags, roomFlags); + // The feather has special handling to be rejected by the SuccUBus + _sendLost = false; + sendMail(destRoomFlags, roomFlags); pet->phonographAction(""); - if (_startFrame2 >= 0) { - playMovie(_startFrame2, _endFrame2, 0); + if (_okStartFrame >= 0) { + playMovie(_okStartFrame, _okEndFrame, 0); startTalking(this, 230022, findView()); } _field158 = 1; - if (_startFrame3 >= 0) - playMovie(_startFrame3, _endFrame3, 0); + if (_sendStartFrame >= 0) + playMovie(_sendStartFrame, _sendEndFrame, 0); - if (_startFrame4 >= 0) { + if (_receiveStartFrame >= 0) { _mailP = mailObject; - playMovie(_startFrame4, _endFrame4, MOVIE_NOTIFY_OBJECT); + playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT); } - if (_startFrame5 >= 0) { - playMovie(_startFrame5, _endFrame5, 0); + if (_afterReceiveStartFrame >= 0) { + playMovie(_afterReceiveStartFrame, _afterReceiveEndFrame, 0); } } else { - removeMail(pet->getRoomFlags(), roomFlags); + // Send the mail to the destination + sendMail(pet->getRoomFlags(), roomFlags); pet->phonographAction(""); - if (_startFrame2 >= 0) { - playMovie(_startFrame2, _endFrame2, 0); + if (_okStartFrame >= 0) { + playMovie(_okStartFrame, _okEndFrame, 0); startTalking(this, 230012, findView()); } - if (_startFrame3 >= 0) - playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT); + if (_sendStartFrame >= 0) + playMovie(_sendStartFrame, _sendEndFrame, MOVIE_NOTIFY_OBJECT); } } @@ -465,6 +465,7 @@ bool CSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) { uint petRoomFlags = pet->getRoomFlags(); if (mailExists(petRoomFlags)) { + // There's already something to send in the tray, so you can't receive switch (getRandomNumber(2)) { case 0: startTalking(this, 70080, findView()); @@ -482,24 +483,26 @@ bool CSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) { CGameObject *mailObject = findMailByFlags( _v3 && compareRoomNameTo("Titania") ? 3 : _field140, petRoomFlags); if (!mailObject) { + // No mail for this SuccUBus if (getRandomNumber(1) == 0) { startTalking(this, 70104, findView()); } else { startTalking(this, 70105, findView()); } - playMovie(_startFrame6, _endFrame6, 0); - playMovie(_startFrame7, _endFrame7, 0); + playMovie(_emptyStartFrame, _emptyEndFrame, 0); + playMovie(_smokeStartFrame, _smokeEndFrame, 0); petDisplayMessage(2, NOTHING_TO_DELIVER); } else { + // Receive the mail addressed to this SuccUBus _mailP = mailObject; startTalking(this, 230004, findView()); - if (_startFrame4 >= 0) { + if (_receiveStartFrame >= 0) { _field158 = 1; _field1D8 = 1; incTransitions(); - playMovie(_startFrame4, _endFrame4, MOVIE_NOTIFY_OBJECT); + playMovie(_receiveStartFrame, _receiveEndFrame, MOVIE_NOTIFY_OBJECT); } } } @@ -511,7 +514,7 @@ bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { CPetControl *pet = getPetControl(); uint petRoomFlags = pet ? pet->getRoomFlags() : 0; - if (msg->_endFrame == _endFrame10) { + if (msg->_endFrame == _offEndFrame) { if (_startFrame11 >= 0) playSound("z#30.wav", 100); @@ -524,7 +527,7 @@ bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { } } - if (msg->_endFrame == _endFrame9) { + if (msg->_endFrame == _onEndFrame) { bool flag = false; if (pet && !mailExists(petRoomFlags)) { @@ -585,14 +588,14 @@ bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { } } - if (msg->_endFrame == _endFrame3) { + if (msg->_endFrame == _sendEndFrame) { if (_field158 == 1) { startTalking(this, 230022, findView()); } else if (_field158 == 2) { startTalking(this, 230017, findView()); - } else if (_field19C) { + } else if (_sendLost) { startTalking(this, 230019, findView()); - _field19C = 0; + _sendLost = false; } else if (_isChicken) { startTalking(this, 230018, findView()); _isChicken = false; @@ -609,7 +612,7 @@ bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) { transMsg.execute(this); } - if (msg->_endFrame == _endFrame4) { + if (msg->_endFrame == _receiveEndFrame) { // SuccUBus disgorged mail if (pet && _mailP) { _mailP->setMailDest(petRoomFlags); @@ -661,8 +664,8 @@ bool CSuccUBus::TurnOn(CTurnOn *msg) { playSound("z#30.wav", 100); } - if (_startFrame9 >= 0) { - playMovie(_startFrame9, _endFrame9, MOVIE_NOTIFY_OBJECT); + if (_onStartFrame >= 0) { + playMovie(_onStartFrame, _onEndFrame, MOVIE_NOTIFY_OBJECT); playSound("z#26.wav", 100); } @@ -689,9 +692,9 @@ bool CSuccUBus::TurnOff(CTurnOff *msg) { _soundHandle = -1; } - if (_startFrame10 >= 0) { + if (_offStartFrame >= 0) { playSound("z#27.wav", 100); - playMovie(_startFrame10, _endFrame10, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + playMovie(_offStartFrame, _offEndFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); } if (!_field15C && _startFrame11 >= 0) diff --git a/engines/titanic/npcs/succubus.h b/engines/titanic/npcs/succubus.h index 7ca8037a0a..d996bcdc68 100644 --- a/engines/titanic/npcs/succubus.h +++ b/engines/titanic/npcs/succubus.h @@ -56,22 +56,22 @@ protected: int _endFrame8; int _startFrame11; int _endFrame11; - int _startFrame3; - int _endFrame3; - int _startFrame4; - int _endFrame4; - int _startFrame9; - int _endFrame9; - int _startFrame10; - int _endFrame10; - int _startFrame2; - int _endFrame2; + int _sendStartFrame; + int _sendEndFrame; + int _receiveStartFrame; + int _receiveEndFrame; + int _onStartFrame; + int _onEndFrame; + int _offStartFrame; + int _offEndFrame; + int _okStartFrame; + int _okEndFrame; int _field140; CGameObject *_mailP; - int _startFrame5; - int _endFrame5; - int _startFrame12; - int _endFrame12; + int _afterReceiveStartFrame; + int _afterReceiveEndFrame; + int _trayOutStartFrame; + int _trayOutEndFrame; int _field158; bool _field15C; CString _string2; @@ -84,16 +84,16 @@ protected: int _field190; int _field194; int _field198; - int _field19C; + bool _sendLost; int _soundHandle; bool _isChicken; bool _isFeathers; int _field1AC; int _field1B0; - int _startFrame6; - int _endFrame6; - int _startFrame7; - int _endFrame7; + int _emptyStartFrame; + int _emptyEndFrame; + int _smokeStartFrame; + int _smokeEndFrame; int _field1C4; int _field1C8; int _field1CC; diff --git a/engines/titanic/pet_control/pet_control.cpp b/engines/titanic/pet_control/pet_control.cpp index b7fece7569..55b2ecc24b 100644 --- a/engines/titanic/pet_control/pet_control.cpp +++ b/engines/titanic/pet_control/pet_control.cpp @@ -699,11 +699,11 @@ void CPetControl::resetDials0() { _conversations.resetDials0(); } -int CPetControl::getMailDest(const CRoomFlags &roomFlags) const { +PassengerClass CPetControl::getMailDestClass(const CRoomFlags &roomFlags) const { if (!roomFlags.isSuccUBusRoomFlags()) - return (int)roomFlags.getPassengerClassNum(); + return roomFlags.getPassengerClassNum(); - return roomFlags.getSuccUBusNum(roomFlags.getSuccUBusRoomName()); + return roomFlags.getSuccUBusClass(roomFlags.getSuccUBusRoomName()); } void CPetControl::starsSetButtons(int val1, int val2) { diff --git a/engines/titanic/pet_control/pet_control.h b/engines/titanic/pet_control/pet_control.h index 0a8b6295be..a63c29d6b3 100644 --- a/engines/titanic/pet_control/pet_control.h +++ b/engines/titanic/pet_control/pet_control.h @@ -522,11 +522,14 @@ public: } /** - * Get mail destination given the specified flags + * Get the passenger class of the specified room flags */ - int getMailDest(const CRoomFlags &roomFlags) const; + PassengerClass getMailDestClass(const CRoomFlags &roomFlags) const; - bool testRooms5(uint roomFlags) { + /** + * Returns whether the given room flags specify a location with a SuccUBus + */ + bool isSuccUBusDest(uint roomFlags) { return CRoomFlags(roomFlags).not5(); } diff --git a/engines/titanic/pet_control/pet_conversations.h b/engines/titanic/pet_control/pet_conversations.h index c3508f62a8..37d216ed2f 100644 --- a/engines/titanic/pet_control/pet_conversations.h +++ b/engines/titanic/pet_control/pet_conversations.h @@ -24,7 +24,7 @@ #define TITANIC_PET_CONVERSATIONS_H #include "titanic/pet_control/pet_section.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" #include "titanic/pet_control/pet_gfx_element.h" #include "titanic/true_talk/true_talk_manager.h" @@ -48,8 +48,8 @@ private: CPetGfxElement _splitter; CPetGfxElement _npcIcons[9]; int _npcNum; - CPetText _log; - CPetText _textInput; + CTextControl _log; + CTextControl _textInput; bool _logChanged; int _field418; CString _npcName; diff --git a/engines/titanic/pet_control/pet_drag_chev.cpp b/engines/titanic/pet_control/pet_drag_chev.cpp index 957fe5295c..4b54d3e69c 100644 --- a/engines/titanic/pet_control/pet_drag_chev.cpp +++ b/engines/titanic/pet_control/pet_drag_chev.cpp @@ -59,6 +59,7 @@ bool CPetDragChev::MouseDragEndMsg(CMouseDragEndMsg *msg) { if (succubus) { CSetChevRoomBits chevMsg(_destRoomFlags); chevMsg.execute(succubus); + petMoveToHiddenRoom(); } else { CPetControl *petControl = getPetControl(); if (!petControl || !petControl->contains(msg->_mousePos) diff --git a/engines/titanic/pet_control/pet_glyphs.cpp b/engines/titanic/pet_control/pet_glyphs.cpp index ed043811ce..b42b87199b 100644 --- a/engines/titanic/pet_control/pet_glyphs.cpp +++ b/engines/titanic/pet_control/pet_glyphs.cpp @@ -39,7 +39,7 @@ void CPetGlyph::drawAt(CScreenManager *screenManager, const Point &pt, bool isHi } void CPetGlyph::updateTooltip() { - CPetText *petText = getPetSection()->getText(); + CTextControl *petText = getPetSection()->getText(); if (petText) { petText->setColor(getPetSection()->getColor(0)); getTooltip(petText); diff --git a/engines/titanic/pet_control/pet_glyphs.h b/engines/titanic/pet_control/pet_glyphs.h index ac008c5ab0..6229d17994 100644 --- a/engines/titanic/pet_control/pet_glyphs.h +++ b/engines/titanic/pet_control/pet_glyphs.h @@ -35,7 +35,7 @@ namespace Titanic { class CPetGlyphs; class CPetSection; -class CPetText; +class CTextControl; enum GlyphActionMode { ACTION_REMOVE = 0, ACTION_REMOVED = 1, ACTION_CHANGE = 2 }; @@ -177,7 +177,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text) {} + virtual void getTooltip(CTextControl *text) {} /** * Saves the data for the glyph diff --git a/engines/titanic/pet_control/pet_inventory.cpp b/engines/titanic/pet_control/pet_inventory.cpp index c1eb0754a2..aa1bb31809 100644 --- a/engines/titanic/pet_control/pet_inventory.cpp +++ b/engines/titanic/pet_control/pet_inventory.cpp @@ -94,6 +94,15 @@ bool CPetInventory::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { return _items.VirtualKeyCharMsg(msg); } +bool CPetInventory::MouseWheelMsg(CMouseWheelMsg *msg) { + if (msg->_wheelUp) + _items.scrollLeft(); + else + _items.scrollRight(); + + return true; +} + CGameObject *CPetInventory::dragEnd(const Point &pt) const { return _items.getObjectAt(pt); } diff --git a/engines/titanic/pet_control/pet_inventory.h b/engines/titanic/pet_control/pet_inventory.h index 5433feae95..7efc0755d8 100644 --- a/engines/titanic/pet_control/pet_inventory.h +++ b/engines/titanic/pet_control/pet_inventory.h @@ -26,7 +26,7 @@ #include "titanic/support/simple_file.h" #include "titanic/pet_control/pet_section.h" #include "titanic/pet_control/pet_inventory_glyphs.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { @@ -35,7 +35,7 @@ namespace Titanic { */ class CPetInventory : public CPetSection { private: - CPetText _text; + CTextControl _text; CPetInventoryGlyphs _items; CGameObject *_itemBackgrounds[46]; CGameObject *_itemGlyphs[46]; @@ -94,6 +94,7 @@ public: virtual bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); virtual bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); virtual bool VirtualKeyCharMsg(CVirtualKeyCharMsg *msg); + virtual bool MouseWheelMsg(CMouseWheelMsg *msg); /** * Returns item a drag-drop operation has dropped on, if any @@ -133,7 +134,7 @@ public: /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText() { return &_text; } + virtual CTextControl *getText() { return &_text; } /** * Special retrieval of glyph background image diff --git a/engines/titanic/pet_control/pet_inventory_glyphs.cpp b/engines/titanic/pet_control/pet_inventory_glyphs.cpp index 74d769af6d..9d745d8806 100644 --- a/engines/titanic/pet_control/pet_inventory_glyphs.cpp +++ b/engines/titanic/pet_control/pet_inventory_glyphs.cpp @@ -143,7 +143,7 @@ bool CPetInventoryGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg } } -void CPetInventoryGlyph::getTooltip(CPetText *text) { +void CPetInventoryGlyph::getTooltip(CTextControl *text) { if (text) { text->setText(""); diff --git a/engines/titanic/pet_control/pet_inventory_glyphs.h b/engines/titanic/pet_control/pet_inventory_glyphs.h index 508db67f2d..e843cf53f9 100644 --- a/engines/titanic/pet_control/pet_inventory_glyphs.h +++ b/engines/titanic/pet_control/pet_inventory_glyphs.h @@ -106,7 +106,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); /** * Return whether the glyph is currently valid diff --git a/engines/titanic/pet_control/pet_load.cpp b/engines/titanic/pet_control/pet_load.cpp index 3d67cf6d71..81ea85874f 100644 --- a/engines/titanic/pet_control/pet_load.cpp +++ b/engines/titanic/pet_control/pet_load.cpp @@ -50,7 +50,7 @@ bool CPetLoad::MouseButtonUpMsg(const Point &pt) { } } -void CPetLoad::getTooltip(CPetText *text) { +void CPetLoad::getTooltip(CTextControl *text) { text->setText("Load the game."); } diff --git a/engines/titanic/pet_control/pet_load.h b/engines/titanic/pet_control/pet_load.h index 5669991b59..103477a2f5 100644 --- a/engines/titanic/pet_control/pet_load.h +++ b/engines/titanic/pet_control/pet_load.h @@ -47,7 +47,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); /** * Highlights a save slot diff --git a/engines/titanic/pet_control/pet_load_save.h b/engines/titanic/pet_control/pet_load_save.h index 26ddec0ff9..5bdb2b5485 100644 --- a/engines/titanic/pet_control/pet_load_save.h +++ b/engines/titanic/pet_control/pet_load_save.h @@ -24,7 +24,7 @@ #define TITANIC_PET_LOAD_SAVE_H #include "titanic/pet_control/pet_glyphs.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { @@ -52,7 +52,7 @@ private: */ bool isSlotHighlighted(int index, const Point &pt); protected: - CPetText _slotNames[SAVEGAME_SLOTS_COUNT]; + CTextControl _slotNames[SAVEGAME_SLOTS_COUNT]; bool _slotInUse[SAVEGAME_SLOTS_COUNT]; CPetGfxElement _btnLoadSave; CPetGfxElement _gutter; diff --git a/engines/titanic/pet_control/pet_quit.cpp b/engines/titanic/pet_control/pet_quit.cpp index a6fb22d7e1..0d94474f99 100644 --- a/engines/titanic/pet_control/pet_quit.cpp +++ b/engines/titanic/pet_control/pet_quit.cpp @@ -83,7 +83,7 @@ bool CPetQuit::MouseButtonUpMsg(const Point &pt) { } } -void CPetQuit::getTooltip(CPetText *text) { +void CPetQuit::getTooltip(CTextControl *text) { text->setText("Quit the game."); } diff --git a/engines/titanic/pet_control/pet_quit.h b/engines/titanic/pet_control/pet_quit.h index b775000933..7eeedaf701 100644 --- a/engines/titanic/pet_control/pet_quit.h +++ b/engines/titanic/pet_control/pet_quit.h @@ -25,13 +25,13 @@ #include "titanic/pet_control/pet_gfx_element.h" #include "titanic/pet_control/pet_glyphs.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { class CPetQuit : public CPetGlyph { private: - CPetText _text; + CTextControl _text; CPetGfxElement _btnYes; public: /** @@ -62,12 +62,12 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText() { return &_text; } + virtual CTextControl *getText() { return &_text; } }; } // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_real_life.h b/engines/titanic/pet_control/pet_real_life.h index 7c7101a84b..294f9a3f9f 100644 --- a/engines/titanic/pet_control/pet_real_life.h +++ b/engines/titanic/pet_control/pet_real_life.h @@ -25,7 +25,7 @@ #include "titanic/pet_control/pet_section.h" #include "titanic/pet_control/pet_glyphs.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { @@ -35,7 +35,7 @@ class CPetSaveGlyphs : public CPetGlyphs { class CPetRealLife : public CPetSection { private: CPetGlyphs _glyphs; - CPetText _text; + CTextControl _text; private: /** * Does setup @@ -124,7 +124,7 @@ public: /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText() { return &_text; } + virtual CTextControl *getText() { return &_text; } }; diff --git a/engines/titanic/pet_control/pet_remote.cpp b/engines/titanic/pet_control/pet_remote.cpp index 3f00ce5066..0293ec93a1 100644 --- a/engines/titanic/pet_control/pet_remote.cpp +++ b/engines/titanic/pet_control/pet_remote.cpp @@ -202,7 +202,7 @@ void CPetRemote::enterRoom(CRoomItem *room) { } } -CPetText *CPetRemote::getText() { +CTextControl *CPetRemote::getText() { return &_text; } diff --git a/engines/titanic/pet_control/pet_remote.h b/engines/titanic/pet_control/pet_remote.h index 9cd9c1e9d7..008c6459df 100644 --- a/engines/titanic/pet_control/pet_remote.h +++ b/engines/titanic/pet_control/pet_remote.h @@ -27,7 +27,7 @@ #include "titanic/pet_control/pet_section.h" #include "titanic/pet_control/pet_glyphs.h" #include "titanic/pet_control/pet_remote_glyphs.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { @@ -45,7 +45,7 @@ private: CPetGfxElement _send; CPetGfxElement _receive; CPetGfxElement _call; - CPetText _text; + CTextControl _text; private: /** * Setup the control @@ -137,7 +137,7 @@ public: /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText(); + virtual CTextControl *getText(); /** * Get an element from the section by a designated Id diff --git a/engines/titanic/pet_control/pet_remote_glyphs.cpp b/engines/titanic/pet_control/pet_remote_glyphs.cpp index f0e71d31ee..7f52ca7ee9 100644 --- a/engines/titanic/pet_control/pet_remote_glyphs.cpp +++ b/engines/titanic/pet_control/pet_remote_glyphs.cpp @@ -81,7 +81,7 @@ bool CBasicRemoteGlyph::MouseButtonUpMsg(const Point &pt) { return false; } -void CBasicRemoteGlyph::getTooltip(CPetText *text) { +void CBasicRemoteGlyph::getTooltip(CTextControl *text) { text->setText(_tooltip); } @@ -160,7 +160,7 @@ bool CRemoteGotoGlyph::MouseButtonUpMsg(const Point &pt) { return true; } -void CRemoteGotoGlyph::getTooltip(CPetText *text) { +void CRemoteGotoGlyph::getTooltip(CTextControl *text) { text->setText(_tooltip); } @@ -216,7 +216,7 @@ bool CTelevisionControlGlyph::MouseButtonUpMsg(const Point &pt) { return false; } -void CTelevisionControlGlyph::getTooltip(CPetText *text) { +void CTelevisionControlGlyph::getTooltip(CTextControl *text) { text->setText(TELEVISION_CONTROL); } @@ -280,7 +280,7 @@ bool CEntertainmentDeviceGlyph::MouseButtonUpMsg(const Point &pt) { return false; } -void CEntertainmentDeviceGlyph::getTooltip(CPetText *text) { +void CEntertainmentDeviceGlyph::getTooltip(CTextControl *text) { text->setText(OPERATE_ENTERTAINMENT); } @@ -334,7 +334,7 @@ bool COperateLightsGlyph::MouseButtonUpMsg(const Point &pt) { return true; } -void COperateLightsGlyph::getTooltip(CPetText *text) { +void COperateLightsGlyph::getTooltip(CTextControl *text) { text->setText(OPERATE_LIGHTS); } @@ -346,7 +346,7 @@ bool CDeployFloralGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { return true; } -void CDeployFloralGlyph::getTooltip(CPetText *text) { +void CDeployFloralGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_FLORAL_ENHANCEMENT); } @@ -359,7 +359,7 @@ bool CDeployFullyRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *own return true; } -void CDeployFullyRelaxationGlyph::getTooltip(CPetText *text) { +void CDeployFullyRelaxationGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_FULLY_RELAXATION); } @@ -371,7 +371,7 @@ bool CDeployComfortGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { return true; } -void CDeployComfortGlyph::getTooltip(CPetText *text) { +void CDeployComfortGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_COMFORT_WORKSTATION); } @@ -383,7 +383,7 @@ bool CDeployMinorStorageGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) return true; } -void CDeployMinorStorageGlyph::getTooltip(CPetText *text) { +void CDeployMinorStorageGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_MINOR_STORAGE); } @@ -395,7 +395,7 @@ bool CDeployMajorRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *own return true; } -void CDeployMajorRelaxationGlyph::getTooltip(CPetText *text) { +void CDeployMajorRelaxationGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_MAJOR_RELAXATION); } @@ -407,7 +407,7 @@ bool CInflateRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) return true; } -void CInflateRelaxationGlyph::getTooltip(CPetText *text) { +void CInflateRelaxationGlyph::getTooltip(CTextControl *text) { text->setText(INFLATE_RELAXATION_DEVICE); } @@ -419,7 +419,7 @@ bool CDeployMaintenanceGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) return true; } -void CDeployMaintenanceGlyph::getTooltip(CPetText *text) { +void CDeployMaintenanceGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_MAINTENANCE_HUB); } @@ -431,7 +431,7 @@ bool CDeployWorkSurfaceGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) return true; } -void CDeployWorkSurfaceGlyph::getTooltip(CPetText *text) { +void CDeployWorkSurfaceGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_EXECUTIVE_SURFACE); } @@ -443,7 +443,7 @@ bool CDeployMinorRelaxationGlyph::setup(CPetControl *petControl, CPetGlyphs *own return true; } -void CDeployMinorRelaxationGlyph::getTooltip(CPetText *text) { +void CDeployMinorRelaxationGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_MINOR_RELAXATION); } @@ -455,7 +455,7 @@ bool CDeploySinkGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) { return true; } -void CDeploySinkGlyph::getTooltip(CPetText *text) { +void CDeploySinkGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_SINK); } @@ -467,7 +467,7 @@ bool CDeployMajorStorageGlyph::setup(CPetControl *petControl, CPetGlyphs *owner) return true; } -void CDeployMajorStorageGlyph::getTooltip(CPetText *text) { +void CDeployMajorStorageGlyph::getTooltip(CTextControl *text) { text->setText(DEPLOY_MAJOR_STORAGE); } @@ -515,7 +515,7 @@ bool CSuccubusDeliveryGlyph::MouseButtonUpMsg(const Point &pt) { return true; } -void CSuccubusDeliveryGlyph::getTooltip(CPetText *text) { +void CSuccubusDeliveryGlyph::getTooltip(CTextControl *text) { text->setText(SUCCUBUS_DELIVERY_SYSTEM); } @@ -554,7 +554,7 @@ bool CNavigationControllerGlyph::MouseButtonUpMsg(const Point &pt) { return true; } -void CNavigationControllerGlyph::getTooltip(CPetText *text) { +void CNavigationControllerGlyph::getTooltip(CTextControl *text) { text->setText(NAVIGATION_CONTROLLER); } diff --git a/engines/titanic/pet_control/pet_remote_glyphs.h b/engines/titanic/pet_control/pet_remote_glyphs.h index 691a70f609..0a035ec03a 100644 --- a/engines/titanic/pet_control/pet_remote_glyphs.h +++ b/engines/titanic/pet_control/pet_remote_glyphs.h @@ -116,7 +116,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CToggleRemoteGlyph : public CPetRemoteGlyph { @@ -181,7 +181,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CSummonElevatorGlyph : public CBasicRemoteGlyph { @@ -225,7 +225,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CEntertainmentDeviceGlyph : public CToggleRemoteGlyph { @@ -259,7 +259,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; @@ -293,7 +293,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployFloralGlyph : public CToggleRemoteGlyph { @@ -320,7 +320,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployFullyRelaxationGlyph : public CToggleRemoteGlyph { @@ -347,7 +347,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployComfortGlyph : public CToggleRemoteGlyph { @@ -374,7 +374,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployMinorStorageGlyph : public CToggleRemoteGlyph { @@ -401,7 +401,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployMajorRelaxationGlyph : public CToggleRemoteGlyph { @@ -428,7 +428,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CInflateRelaxationGlyph : public CToggleRemoteGlyph { @@ -455,7 +455,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployMaintenanceGlyph : public CToggleRemoteGlyph { @@ -482,7 +482,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployWorkSurfaceGlyph : public CToggleRemoteGlyph { @@ -509,7 +509,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployMinorRelaxationGlyph : public CToggleRemoteGlyph { @@ -536,7 +536,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeploySinkGlyph : public CToggleRemoteGlyph { @@ -563,7 +563,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CDeployMajorStorageGlyph : public CToggleRemoteGlyph { @@ -590,7 +590,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CSuccubusDeliveryGlyph : public CPetRemoteGlyph { @@ -623,7 +623,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CNavigationControllerGlyph : public CPetRemoteGlyph { @@ -657,7 +657,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; class CGotoBottomOfWellGlyph : public CRemoteGotoGlyph { diff --git a/engines/titanic/pet_control/pet_rooms.cpp b/engines/titanic/pet_control/pet_rooms.cpp index f8017373ec..88d9df15cd 100644 --- a/engines/titanic/pet_control/pet_rooms.cpp +++ b/engines/titanic/pet_control/pet_rooms.cpp @@ -97,8 +97,8 @@ bool CPetRooms::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { } bool CPetRooms::checkDragEnd(CGameObject *item) { - // Ignore any item drops except valid mail items - if (!item->_isMail) + // Ignore any item drops except onto mail items + if (!item->_isPendingMail) return false; uint roomFlags = item->_destRoomFlags; @@ -170,7 +170,7 @@ void CPetRooms::enterRoom(CRoomItem *room) { resetHighlight(); } -CPetText *CPetRooms::getText() { +CTextControl *CPetRooms::getText() { return &_text; } diff --git a/engines/titanic/pet_control/pet_rooms.h b/engines/titanic/pet_control/pet_rooms.h index 19c97c0d4e..6b71359ce6 100644 --- a/engines/titanic/pet_control/pet_rooms.h +++ b/engines/titanic/pet_control/pet_rooms.h @@ -24,7 +24,7 @@ #define TITANIC_PET_ROOMS_H #include "titanic/pet_control/pet_section.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" #include "titanic/pet_control/pet_rooms_glyphs.h" #include "titanic/game_location.h" @@ -43,7 +43,7 @@ private: CGameObject *_chevRightOnLit; CGameObject *_chevRightOffLit; CPetGfxElement _plinth; - CPetText _text; + CTextControl _text; int _floorNum; int _elevatorNum; int _roomNum; @@ -141,7 +141,7 @@ public: /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText(); + virtual CTextControl *getText(); /** * Special retrieval of glyph background image diff --git a/engines/titanic/pet_control/pet_rooms_glyphs.cpp b/engines/titanic/pet_control/pet_rooms_glyphs.cpp index e911759f25..a69704c7a5 100644 --- a/engines/titanic/pet_control/pet_rooms_glyphs.cpp +++ b/engines/titanic/pet_control/pet_rooms_glyphs.cpp @@ -124,7 +124,7 @@ bool CPetRoomsGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) { if (chevron) { chevron->_destRoomFlags = _roomFlags; - chevron->_isMail = _mailFlag != 0; + chevron->_isPendingMail = _mailFlag != 0; petControl->removeFromInventory(chevron, false, false); chevron->loadSurface(); @@ -141,19 +141,19 @@ bool CPetRoomsGlyph::dragGlyph(const Point &topLeft, CMouseDragStartMsg *msg) { return false; } -void CPetRoomsGlyph::getTooltip(CPetText *text) { +void CPetRoomsGlyph::getTooltip(CTextControl *text) { CRoomFlags roomFlags(_roomFlags); CPetRooms *owner = static_cast<CPetRooms *>(getPetSection()); - CString msg; + CString prefix; if (isCurrentlyAssigned()) { - msg = "Your assigned room: "; + prefix = "Your assigned room: "; } else if (isPreviouslyAssigned()) { - msg = "A previously assigned room: "; + prefix = "A previously assigned room: "; } else if (!_mailFlag) { - msg = "Saved Chevron: "; + prefix = "Saved Chevron: "; } else if (_mailFlag == 1 && owner->getRoomFlags() == _roomFlags) { - msg = "Current location: "; + prefix = "Current location: "; } // Get the room description @@ -165,7 +165,7 @@ void CPetRoomsGlyph::getTooltip(CPetText *text) { } roomStr += " (shift-click edits)"; - text->setText(roomStr); + text->setText(prefix + roomStr); } void CPetRoomsGlyph::saveGlyph(SimpleFile *file, int indent) { diff --git a/engines/titanic/pet_control/pet_rooms_glyphs.h b/engines/titanic/pet_control/pet_rooms_glyphs.h index 6c51b6f875..3a43bdc06c 100644 --- a/engines/titanic/pet_control/pet_rooms_glyphs.h +++ b/engines/titanic/pet_control/pet_rooms_glyphs.h @@ -89,7 +89,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); /** * Saves the data for the glyph diff --git a/engines/titanic/pet_control/pet_save.cpp b/engines/titanic/pet_control/pet_save.cpp index 60afa11ab4..00dbfa6b4a 100644 --- a/engines/titanic/pet_control/pet_save.cpp +++ b/engines/titanic/pet_control/pet_save.cpp @@ -64,7 +64,7 @@ void CPetSave::highlightCurrent(const Point &pt) { highlightSave(_savegameSlotNum); } -void CPetSave::getTooltip(CPetText *text) { +void CPetSave::getTooltip(CTextControl *text) { text->setText("Save the game."); } diff --git a/engines/titanic/pet_control/pet_save.h b/engines/titanic/pet_control/pet_save.h index 39a25eb087..9b3c11566f 100644 --- a/engines/titanic/pet_control/pet_save.h +++ b/engines/titanic/pet_control/pet_save.h @@ -57,7 +57,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); /** * Called on a highlighted item when PET area is entered diff --git a/engines/titanic/pet_control/pet_section.cpp b/engines/titanic/pet_control/pet_section.cpp index aced697705..2c2238e3f9 100644 --- a/engines/titanic/pet_control/pet_section.cpp +++ b/engines/titanic/pet_control/pet_section.cpp @@ -39,7 +39,7 @@ static const uint PALETTE3[5] = { }; void CPetSection::displayMessage(const CString &msg) { - CPetText *text = getText(); + CTextControl *text = getText(); if (text) { text->setColor(getColor(1)); @@ -64,7 +64,7 @@ void CPetSection::removeText(int duration) { } void CPetSection::removeText() { - CPetText *text = getText(); + CTextControl *text = getText(); if (text) text->setup(); } diff --git a/engines/titanic/pet_control/pet_section.h b/engines/titanic/pet_control/pet_section.h index c68aa90411..e245d5176b 100644 --- a/engines/titanic/pet_control/pet_section.h +++ b/engines/titanic/pet_control/pet_section.h @@ -35,7 +35,7 @@ enum PetArea { class CPetControl; class CPetElement; -class CPetText; +class CTextControl; class CScreenManager; class CRoomItem; @@ -170,7 +170,7 @@ public: /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText() { return nullptr; } + virtual CTextControl *getText() { return nullptr; } /** * Removes text after a given duration diff --git a/engines/titanic/pet_control/pet_sound.cpp b/engines/titanic/pet_control/pet_sound.cpp index e9958c67be..f4d45038e9 100644 --- a/engines/titanic/pet_control/pet_sound.cpp +++ b/engines/titanic/pet_control/pet_sound.cpp @@ -275,7 +275,7 @@ bool CPetSound::MouseButtonUpMsg(const Point &pt) { return true; } -void CPetSound::getTooltip(CPetText *text) { +void CPetSound::getTooltip(CTextControl *text) { text->setText("Change the volume settings."); } diff --git a/engines/titanic/pet_control/pet_sound.h b/engines/titanic/pet_control/pet_sound.h index c4b663ad44..fed4f43f92 100644 --- a/engines/titanic/pet_control/pet_sound.h +++ b/engines/titanic/pet_control/pet_sound.h @@ -25,7 +25,7 @@ #include "titanic/pet_control/pet_glyphs.h" #include "titanic/pet_control/pet_gfx_element.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" #include "titanic/pet_control/pet_slider.h" namespace Titanic { @@ -39,10 +39,10 @@ private: CPetSlider _musicVolume; CPetSlider _parrotVolume; CPetSlider _speechVolume; - CPetText _textMasterVolume; - CPetText _textMusicVolume; - CPetText _textParrotVolume; - CPetText _textSpeechVolume; + CTextControl _textMasterVolume; + CTextControl _textMusicVolume; + CTextControl _textParrotVolume; + CTextControl _textSpeechVolume; CPetSlider *_draggingSlider; int _draggingSliderNum; private: @@ -96,7 +96,7 @@ public: /** * Returns the tooltip text for when the glyph is selected */ - virtual void getTooltip(CPetText *text); + virtual void getTooltip(CTextControl *text); }; } // End of namespace Titanic diff --git a/engines/titanic/pet_control/pet_starfield.h b/engines/titanic/pet_control/pet_starfield.h index 6c47f47d67..ec96fb93ef 100644 --- a/engines/titanic/pet_control/pet_starfield.h +++ b/engines/titanic/pet_control/pet_starfield.h @@ -24,7 +24,7 @@ #define TITANIC_PET_STARFIELD_H #include "titanic/pet_control/pet_section.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" #include "titanic/pet_control/pet_gfx_element.h" namespace Titanic { @@ -39,7 +39,7 @@ private: CPetGfxElement _leds[6]; Rect _rect1; int _field18C; - CPetText _text; + CTextControl _text; bool _photoOn; bool _hasReference; private: diff --git a/engines/titanic/pet_control/pet_translation.cpp b/engines/titanic/pet_control/pet_translation.cpp index fe6c37c8ab..9509047325 100644 --- a/engines/titanic/pet_control/pet_translation.cpp +++ b/engines/titanic/pet_control/pet_translation.cpp @@ -61,8 +61,8 @@ void CPetTranslation::clearTranslation() { void CPetTranslation::addTranslation(const CString &str1, const CString &str2) { CString msg = CString::format("%s%s - %s%s", - CPetText::getColorText(0, 0x80, 0).c_str(), str1.c_str(), - CPetText::getColorText(0, 0, 0).c_str(), str2.c_str()); + CTextControl::getColorText(0, 0x80, 0).c_str(), str1.c_str(), + CTextControl::getColorText(0, 0, 0).c_str(), str2.c_str()); _message.addLine(msg); _petControl->makeDirty(); } diff --git a/engines/titanic/pet_control/pet_translation.h b/engines/titanic/pet_control/pet_translation.h index 26070d6e59..ce12be454e 100644 --- a/engines/titanic/pet_control/pet_translation.h +++ b/engines/titanic/pet_control/pet_translation.h @@ -24,14 +24,14 @@ #define TITANIC_PET_TRANSLATION_H #include "titanic/pet_control/pet_section.h" -#include "titanic/pet_control/pet_text.h" +#include "titanic/gfx/text_control.h" namespace Titanic { class CPetTranslation : public CPetSection { private: - CPetText _message; - CPetText _tooltip; + CTextControl _message; + CTextControl _tooltip; private: /** * Setup the control @@ -87,7 +87,7 @@ public: /** * Get a reference to the tooltip text associated with the section */ - virtual CPetText *getText() { return &_tooltip; } + virtual CTextControl *getText() { return &_tooltip; } /** * Clear any current translation text diff --git a/engines/titanic/room_flags.cpp b/engines/titanic/room_flags.cpp index 25c604ba93..57156f0655 100644 --- a/engines/titanic/room_flags.cpp +++ b/engines/titanic/room_flags.cpp @@ -41,7 +41,7 @@ struct TransportFlagsEntry { struct SuccUBusFlagsEntry { const char *const _roomName; uint _roomFlags; - uint _succubusNum; + PassengerClass _classNum; }; #define TRANSPORT_ROOMS_SIZE 6 @@ -56,23 +56,23 @@ const TransportFlagsEntry TRANSPORT_ROOMS[TRANSPORT_ROOMS_SIZE] = { #define SUCCUBUS_ROOMS_SIZE 17 const SuccUBusFlagsEntry SUCCUBUS_ROOMS[SUCCUBUS_ROOMS_SIZE] = { - { "ParrotLobby", 0x1D0D9, 3 }, - { "SculptureChamber", 0x465FB, 2 }, - { "Bar", 0x0B3D97, 2 }, - { "EmbLobby", 0x0CC971, 3 }, - { "MoonEmbLobby", 0x0CC971, 3 }, - { "MusicRoom", 0x0F34DB, 2 }, - { "MusicRoomLobby", 0x0F34DB, 2 }, - { "Titania", 0x8A397, 3 }, - { "BottomOfWell", 0x59FAD, 3 }, - { "Arboretum", 0x4D6AF, 1 }, - { "PromenadeDeck", 0x79C45, 2 }, - { "1stClassRestaurant", 0x896B9, 1 }, - { "CreatorsChamber", 0x2F86D, 2 }, - { "CreatorsChamberOn", 0x2F86D, 2 }, - { "BilgeRoom", 0x3D94B, 3 }, - { "BilgeRoomWith", 0x3D94B, 3 }, - { "Bridge", 0x39FCB, 3 } + { "ParrotLobby", 0x1D0D9, THIRD_CLASS }, + { "SculptureChamber", 0x465FB, SECOND_CLASS }, + { "Bar", 0x0B3D97, SECOND_CLASS }, + { "EmbLobby", 0x0CC971, THIRD_CLASS }, + { "MoonEmbLobby", 0x0CC971, THIRD_CLASS }, + { "MusicRoom", 0x0F34DB, SECOND_CLASS }, + { "MusicRoomLobby", 0x0F34DB, SECOND_CLASS }, + { "Titania", 0x8A397, THIRD_CLASS }, + { "BottomOfWell", 0x59FAD, THIRD_CLASS }, + { "Arboretum", 0x4D6AF, FIRST_CLASS }, + { "PromenadeDeck", 0x79C45, SECOND_CLASS }, + { "1stClassRestaurant", 0x896B9, FIRST_CLASS }, + { "CreatorsChamber", 0x2F86D, SECOND_CLASS }, + { "CreatorsChamberOn", 0x2F86D, SECOND_CLASS }, + { "BilgeRoom", 0x3D94B, THIRD_CLASS }, + { "BilgeRoomWith", 0x3D94B, THIRD_CLASS }, + { "Bridge", 0x39FCB, THIRD_CLASS } }; int CRoomFlags::getConditionally() const { @@ -355,13 +355,13 @@ uint CRoomFlags::getSpecialRoomFlags(const CString &roomName) { return 0; } -uint CRoomFlags::getSuccUBusNum(const CString &roomName) const { +PassengerClass CRoomFlags::getSuccUBusClass(const CString &roomName) const { for (int idx = 0; idx < SUCCUBUS_ROOMS_SIZE; ++idx) { if (roomName == SUCCUBUS_ROOMS[idx]._roomName) - return SUCCUBUS_ROOMS[idx]._succubusNum; + return SUCCUBUS_ROOMS[idx]._classNum; } - return 0; + return NO_CLASS; } CString CRoomFlags::getSuccUBusRoomName() const { @@ -472,7 +472,7 @@ bool CRoomFlags::compareLocation(uint flags1, uint flags2) { CRoomFlags f1(flags1); CRoomFlags f2(flags2); - return f1.getElevatorNum() == f2.getElevatorBits() && + return f1.getElevatorNum() == f2.getElevatorNum() && f1.getFloorNum() == f2.getFloorNum() && f1.getRoomNum() == f2.getRoomNum(); } diff --git a/engines/titanic/room_flags.h b/engines/titanic/room_flags.h index 8e86bf707e..e2fb91015a 100644 --- a/engines/titanic/room_flags.h +++ b/engines/titanic/room_flags.h @@ -209,9 +209,9 @@ public: void setRandomLocation(PassengerClass classNum, bool flag); /** - * Gets the succubus number associated with a given room + * Gets the passenger class for a succubus associated with a given room */ - uint getSuccUBusNum(const CString &roomName) const; + PassengerClass getSuccUBusClass(const CString &roomName) const; /** * Gets the succubus room name associated with the current room flags diff --git a/engines/titanic/sound/auto_music_player_base.cpp b/engines/titanic/sound/auto_music_player_base.cpp index 49ae906e91..b000d8f90d 100644 --- a/engines/titanic/sound/auto_music_player_base.cpp +++ b/engines/titanic/sound/auto_music_player_base.cpp @@ -90,7 +90,7 @@ bool CAutoMusicPlayerBase::ChangeMusicMsg(CChangeMusicMsg *msg) { } } - if (_isRepeated && msg->_flags == 2) { + if (!_isRepeated && msg->_flags == 2) { _isRepeated = true; playGlobalSound(_filename, _volumeMode, _initialMute, true, 0); } diff --git a/engines/titanic/sound/season_noises.cpp b/engines/titanic/sound/season_noises.cpp index 14689d5337..5f139e728f 100644 --- a/engines/titanic/sound/season_noises.cpp +++ b/engines/titanic/sound/season_noises.cpp @@ -31,7 +31,7 @@ BEGIN_MESSAGE_MAP(CSeasonNoises, CViewAutoSoundPlayer) ON_MESSAGE(LoadSuccessMsg) END_MESSAGE_MAP() -CSeasonNoises::CSeasonNoises() : CViewAutoSoundPlayer(), _seasonNumber(0), +CSeasonNoises::CSeasonNoises() : CViewAutoSoundPlayer(), _seasonNumber(SEASON_SUMMER), _springName("NULL"), _summerName("NULL"), _autumnName("NULL"), _winterName("NULL") { } @@ -48,7 +48,7 @@ void CSeasonNoises::save(SimpleFile *file, int indent) { void CSeasonNoises::load(SimpleFile *file) { file->readNumber(); - _seasonNumber = file->readNumber(); + _seasonNumber = (Season)file->readNumber(); _springName = file->readString(); _summerName = file->readString(); _autumnName = file->readString(); @@ -58,7 +58,7 @@ void CSeasonNoises::load(SimpleFile *file) { } bool CSeasonNoises::ChangeSeasonMsg(CChangeSeasonMsg *msg) { - _seasonNumber = (_seasonNumber + 1) % 4; + _seasonNumber = (Season)(((int)_seasonNumber + 1) % 4); CActMsg actMsg("Update"); actMsg.execute(this); @@ -67,6 +67,7 @@ bool CSeasonNoises::ChangeSeasonMsg(CChangeSeasonMsg *msg) { bool CSeasonNoises::EnterViewMsg(CEnterViewMsg *msg) { CActMsg actMsg("Update"); + actMsg.execute(this); return true; } @@ -74,18 +75,18 @@ bool CSeasonNoises::ActMsg(CActMsg *msg) { msg->_action = "Update"; switch (_seasonNumber) { - case 0: - _filename = _springName; - break; - case 1: + case SEASON_SUMMER: _filename = _summerName; break; - case 2: + case SEASON_AUTUMN: _filename = _autumnName; break; - case 3: + case SEASON_WINTER: _filename = _winterName; break; + case SEASON_SPRING: + _filename = _springName; + break; default: break; } diff --git a/engines/titanic/sound/season_noises.h b/engines/titanic/sound/season_noises.h index 796628d10d..cab8d5907f 100644 --- a/engines/titanic/sound/season_noises.h +++ b/engines/titanic/sound/season_noises.h @@ -34,7 +34,7 @@ class CSeasonNoises : public CViewAutoSoundPlayer { bool ActMsg(CActMsg *msg); bool LoadSuccessMsg(CLoadSuccessMsg *msg); private: - int _seasonNumber; + Season _seasonNumber; CString _springName; CString _summerName; CString _autumnName; diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index de7b9abe3e..22b3e98c16 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -273,12 +273,14 @@ void AVISurface::setupDecompressor() { } void AVISurface::copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest) { - assert(src.w == dest.w && src.h == dest.h); + // WORKAROUND: A bad video in the Promenade has a frame with a width slightly larger + // than the defined width for the movie it's in. Hence the assert below is >= + assert(src.w >= dest.w && src.h == dest.h); if (src.format.bytesPerPixel == 1) { // Paletted 8-bit, so convert to 16-bit and copy over Graphics::Surface *s = src.convertTo(dest.format, _decoder->getPalette()); - dest.blitFrom(*s); + dest.blitFrom(*s, Common::Rect(0, 0, dest.w, dest.h), Common::Point(0, 0)); s->free(); delete s; } else if (src.format.bytesPerPixel == 2) { diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 216d4f8837..4ee6cc6e0b 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -179,11 +179,6 @@ public: int getFrame() const { return _currentFrame; } /** - * Returns true if the surface is playing in reverse - */ - bool isReversed() const { return _isReversed; } - - /** * Add a movie event */ bool addEvent(int frameNumber, CGameObject *obj); diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 6300f65a3b..c6942510cc 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -192,6 +192,14 @@ void CMouseCursor::enableControl() { CScreenManager::_screenManagerPtr->_inputHandler->decLockCount(); } +void CMouseCursor::setBusy() { + setCursor(CURSOR_HOURGLASS); +} + +void CMouseCursor::clearBusy() { + setCursor(CURSOR_ARROW); +} + void CMouseCursor::setPosition(const Point &pt, double duration) { _moveStartPos = g_vm->_events->getMousePos(); _moveDestPos = pt; diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 1662ce743d..d61e5fe0bc 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -144,6 +144,17 @@ public: void enableControl(); /** + * Shows the busy cursor + */ + void setBusy(); + + /** + * Resets the cursor back to normal + */ + void clearBusy(); + + + /** * Move the mouse to a new position */ void setPosition(const Point &pt, double duration); diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index 553486d094..cc9054e688 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -73,6 +73,11 @@ int CScreenManager::setFontNumber(int fontNumber) { return oldFontNumber; } +void CScreenManager::preLoad() { + if (_textCursor) + _textCursor->hide(); +} + /*------------------------------------------------------------------------*/ OSScreenManager::OSScreenManager(TitanicEngine *vm): CScreenManager(vm), diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index a7c929fb5f..7140001bd4 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -228,6 +228,11 @@ public: * Set the current font number */ int setFontNumber(int fontNumber); + + /** + * Called when a game is about to be loaded + */ + void preLoad(); }; class OSScreenManager: CScreenManager { diff --git a/engines/titanic/support/strings.h b/engines/titanic/support/strings.h index e82f882028..97928dc6e8 100644 --- a/engines/titanic/support/strings.h +++ b/engines/titanic/support/strings.h @@ -162,6 +162,10 @@ enum StringId { CLASS_2, CLASS_3, CLASS_NONE, + YOUR_ASSIGNED_ROOM, + PREVIOUSLY_ASSIGNED_ROOM, + SAVED_CHEVRON, + CURRENT_LOCATION, // German version only DE_SUMMER, diff --git a/engines/titanic/true_talk/true_talk_manager.cpp b/engines/titanic/true_talk/true_talk_manager.cpp index 8b1cd8cc9a..446a32eaae 100644 --- a/engines/titanic/true_talk/true_talk_manager.cpp +++ b/engines/titanic/true_talk/true_talk_manager.cpp @@ -538,9 +538,10 @@ void CTrueTalkManager::playSpeech(TTtalker *talker, TTroomScript *roomScript, CV if (!milli) continue; +#ifdef SPATIAL_SOUND if (idx == 0) g_vm->_events->sleep(milli); -#ifdef SPATIAL_SOUND + // TODO: Figure out if these below are needed. It kinda looks like they were // simply playing the same speech at different spatial co-ordinates. And since // we don't support spatial processing in ScummVM yet, they're being left disabled diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index ef3cc2d84f..24779b9793 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -361,6 +361,12 @@ bool BaseGame::initConfManSettings() { _debugShowFPS = false; } + if (ConfMan.hasKey("bilinear_filtering")) { + _bilinearFiltering = ConfMan.getBool("bilinear_filtering"); + } else { + _bilinearFiltering = false; + } + if (ConfMan.hasKey("disable_smartcache")) { _smartCache = ConfMan.getBool("disable_smartcache"); } else { diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index 6aacc1feab..46484cc5ca 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -101,7 +101,7 @@ public: virtual bool displayDebugInfo(); void setShowFPS(bool enabled) { _debugShowFPS = enabled; } - + bool getBilinearFiltering() { return _bilinearFiltering; } bool getSuspendedRendering() const { return _suspendedRendering; } TTextEncoding _textEncoding; @@ -279,6 +279,7 @@ protected: VideoTheoraPlayer *_theoraPlayer; private: bool _debugShowFPS; + bool _bilinearFiltering; void *_debugLogFile; void DEBUG_DebugDisable(); void DEBUG_DebugEnable(const char *filename = nullptr); diff --git a/engines/wintermute/base/file/base_disk_file.cpp b/engines/wintermute/base/file/base_disk_file.cpp index d0c51616f4..0684b3f591 100644 --- a/engines/wintermute/base/file/base_disk_file.cpp +++ b/engines/wintermute/base/file/base_disk_file.cpp @@ -29,6 +29,7 @@ #include "engines/wintermute/dcgf.h" #include "engines/wintermute/base/file/base_disk_file.h" #include "engines/wintermute/base/base_file_manager.h" +#include "engines/wintermute/utils/path_util.h" #include "common/stream.h" #include "common/memstream.h" #include "common/file.h" @@ -37,6 +38,7 @@ #include "common/tokenizer.h" #include "common/config-manager.h" + namespace Wintermute { void correctSlashes(Common::String &fileName) { @@ -150,7 +152,7 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) { } // File wasn't found in SearchMan, try to parse the path as a relative path. if (!file) { - Common::FSNode searchNode = getNodeForRelativePath(filename); + Common::FSNode searchNode = getNodeForRelativePath(PathUtil::normalizeFileName(filename)); if (searchNode.exists() && !searchNode.isDirectory() && searchNode.isReadable()) { file = searchNode.createReadStream(); } diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp index afe884300a..acc9530684 100644 --- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp +++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp @@ -27,6 +27,7 @@ */ +#include "engines/wintermute/base/base_game.h" #include "engines/wintermute/base/gfx/osystem/render_ticket.h" #include "engines/wintermute/base/gfx/osystem/base_surface_osystem.h" #include "graphics/transform_tools.h" @@ -59,7 +60,12 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s // TransformTools.) if (_transform._angle != Graphics::kDefaultAngle) { Graphics::TransparentSurface src(*_surface, false); - Graphics::Surface *temp = src.rotoscale(transform); + Graphics::Surface *temp; + if (owner->_gameRef->getBilinearFiltering()) { + temp = src.rotoscaleT<Graphics::FILTER_BILINEAR>(transform); + } else { + temp = src.rotoscaleT<Graphics::FILTER_NEAREST>(transform); + } _surface->free(); delete _surface; _surface = temp; @@ -67,7 +73,12 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s dstRect->height() != srcRect->height()) && _transform._numTimesX * _transform._numTimesY == 1) { Graphics::TransparentSurface src(*_surface, false); - Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height()); + Graphics::Surface *temp; + if (owner->_gameRef->getBilinearFiltering()) { + temp = src.scaleT<Graphics::FILTER_BILINEAR>(dstRect->width(), dstRect->height()); + } else { + temp = src.scaleT<Graphics::FILTER_NEAREST>(dstRect->width(), dstRect->height()); + } _surface->free(); delete _surface; _surface = temp; diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h index 90340f437d..571ce21931 100644 --- a/engines/wintermute/dctypes.h +++ b/engines/wintermute/dctypes.h @@ -37,9 +37,6 @@ namespace Wintermute { -//typedef std::string AnsiString; -//typedef std::string Utf8String; -//typedef std::wstring WideString; typedef Common::String AnsiString; typedef Common::String Utf8String; typedef Common::U32String WideString; diff --git a/engines/wintermute/detection.cpp b/engines/wintermute/detection.cpp index 4e8eab505f..9ccb75d62f 100644 --- a/engines/wintermute/detection.cpp +++ b/engines/wintermute/detection.cpp @@ -59,8 +59,19 @@ static const ADExtraGuiOptionsMap gameGuiOptions[] = { _s("Show the current number of frames per second in the upper left corner"), "show_fps", false + }, + }, + + { + GAMEOPTION_BILINEAR, + { + _s("Sprite bilinear filtering (SLOW)"), + _s("Apply bilinear filtering to individual sprites"), + "bilinear_filtering", + false } }, + AD_EXTRA_GUI_OPTIONS_TERMINATOR }; @@ -76,7 +87,7 @@ class WintermuteMetaEngine : public AdvancedMetaEngine { public: WintermuteMetaEngine() : AdvancedMetaEngine(Wintermute::gameDescriptions, sizeof(WMEGameDescription), Wintermute::wintermuteGames, gameGuiOptions) { _singleId = "wintermute"; - _guiOptions = GUIO2(GUIO_NOMIDI, GAMEOPTION_SHOW_FPS); + _guiOptions = GUIO3(GUIO_NOMIDI, GAMEOPTION_SHOW_FPS, GAMEOPTION_BILINEAR); _maxScanDepth = 2; _directoryGlobs = directoryGlobs; } diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index 68985d8d0c..5b87dd439c 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -23,6 +23,7 @@ namespace Wintermute { #define GAMEOPTION_SHOW_FPS GUIO_GAMEOPTIONS1 +#define GAMEOPTION_BILINEAR GUIO_GAMEOPTIONS2 static const PlainGameDescriptor wintermuteGames[] = { {"5ld", "Five Lethal Demons"}, @@ -42,6 +43,8 @@ static const PlainGameDescriptor wintermuteGames[] = { {"conspiracao", "Conspiracao Dumont"}, {"corrosion", "Corrosion: Cold Winter Waiting"}, {"deadcity", "Dead City"}, + {"dfafadventure", "DFAF Adventure"}, + {"dreamcat", "Dreamcat"}, {"dreaming", "Des Reves Elastiques Avec Mille Insectes Nommes Georges"}, {"dirtysplit", "Dirty Split"}, {"dreamscape", "Dreamscape"}, @@ -60,6 +63,7 @@ static const PlainGameDescriptor wintermuteGames[] = { {"mirage", "Mirage"}, {"nighttrain", "Night Train"}, {"oknytt", "Oknytt"}, + {"openquest", "Open Quest"}, {"paintaria", "Paintaria"}, {"pigeons", "Pigeons in the Park"}, {"projectdoom", "Project: Doom"}, @@ -237,6 +241,9 @@ static const WMEGameDescription gameDescriptions[] = { WME_WINENTRY("deadcity", "", WME_ENTRY2s("russian.dcp", "a0ae71e9e1185596fffb07ad2c951eb9", 653317, "data.dcp", "7ebfd50d1a22370ed7b079bcaa631d62", 9070205), Common::RU_RUS, ADGF_UNSTABLE, LATEST_VERSION), + // DFAF Adventure + WME_WINENTRY("dfafadventure", "", + WME_ENTRY1s("data.dcp","5704ebef961176f647742aa66bd09352", 10083417), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Dirty Split (Czech) WME_WINENTRY("dirtysplit", "", WME_ENTRY2s("czech.dcp", "08a71446467cf8f9444cfea446b46ad6", 127697934, @@ -262,6 +269,9 @@ static const WMEGameDescription gameDescriptions[] = { // Des Reves Elastiques Avec Mille Insectes Nommes Georges WME_WINENTRY("dreaming", "", WME_ENTRY1s("data.dcp", "4af26d97ea063fc1277ce30ae431de90", 8804073), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), + // Dreamcat + WME_WINENTRY("dreamcat", "", + WME_ENTRY1s("data.dcp","189bd4eef29034f4ff4ed30120eaac4e", 7758040), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), // Dreamscape WME_WINENTRY("dreamscape", "", WME_ENTRY1s("data.dcp", "7a5752ed4446c862be9f02d7932acf54", 17034377), Common::EN_ANY, ADGF_UNSTABLE, LATEST_VERSION), @@ -366,6 +376,9 @@ static const WMEGameDescription gameDescriptions[] = { WME_WINENTRY("oknytt", "Version 1.13", WME_ENTRY2s("spanish.dcp", "10c46152cb29581671f3b6b7c229c957", 319406572, "d_sounds.dcp", "7d04dff8ca11174486bd4b7a80fdcabb", 154943401), Common::ES_ESP, ADGF_UNSTABLE, LATEST_VERSION), + // Open Quest + WME_WINENTRY("openquest", "", + WME_ENTRY1s("data.dcp", "16893e3fc15a211a49654ae66f684f28", 82281736), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), // Night Train Demo WME_WINENTRY("nighttrain", "", WME_ENTRY1s("data.dcp", "5a027ef84b083a730c9a4c85ec1d3a32", 131760816), Common::EN_ANY, ADGF_UNSTABLE | ADGF_DEMO, LATEST_VERSION), diff --git a/engines/wintermute/utils/path_util.cpp b/engines/wintermute/utils/path_util.cpp index 71311713af..8518f8968f 100644 --- a/engines/wintermute/utils/path_util.cpp +++ b/engines/wintermute/utils/path_util.cpp @@ -32,8 +32,8 @@ namespace Wintermute { ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::unifySeparators(const AnsiString &path) { - AnsiString newPath = path; +Common::String PathUtil::unifySeparators(const Common::String &path) { + Common::String newPath = path; for (uint32 i = 0; i < newPath.size(); i++) { if (newPath[i] == '\\') { @@ -45,16 +45,16 @@ AnsiString PathUtil::unifySeparators(const AnsiString &path) { } ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::normalizeFileName(const AnsiString &path) { - AnsiString newPath = unifySeparators(path); +Common::String PathUtil::normalizeFileName(const Common::String &path) { + Common::String newPath = unifySeparators(path); newPath.toLowercase(); return newPath; } ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::combine(const AnsiString &path1, const AnsiString &path2) { - AnsiString newPath1 = unifySeparators(path1); - AnsiString newPath2 = unifySeparators(path2); +Common::String PathUtil::combine(const Common::String &path1, const Common::String &path2) { + Common::String newPath1 = unifySeparators(path1); + Common::String newPath2 = unifySeparators(path2); if (!newPath1.hasSuffix("/") && !newPath2.hasPrefix("/")) { newPath1 += "/"; @@ -63,29 +63,37 @@ AnsiString PathUtil::combine(const AnsiString &path1, const AnsiString &path2) { return newPath1 + newPath2; } +bool PathUtil::hasTrailingSlash(const Common::String &path) { + return (path.size() > 0 && path[path.size() - 1 ] == '/'); +} + ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::getDirectoryName(const AnsiString &path) { - AnsiString newPath = unifySeparators(path); +Common::String PathUtil::getDirectoryName(const Common::String &path) { + Common::String newPath = unifySeparators(path); Common::String filename = getFileName(path); - return Common::String(path.c_str(), path.size() - filename.size()); + if (hasTrailingSlash(newPath)) { + return path; + } else { + return Common::String(path.c_str(), path.size() - filename.size()); + } } ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::getFileName(const AnsiString &path) { - AnsiString newPath = unifySeparators(path); +Common::String PathUtil::getFileName(const Common::String &path) { + Common::String newPath = unifySeparators(path); Common::String lastPart = Common::lastPathComponent(newPath, '/'); - if (lastPart[lastPart.size() - 1 ] != '/') { - return lastPart; + if (hasTrailingSlash(newPath)) { + return Common::String(""); } else { - return path; + return lastPart; } } ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::getFileNameWithoutExtension(const AnsiString &path) { - AnsiString fileName = getFileName(path); +Common::String PathUtil::getFileNameWithoutExtension(const Common::String &path) { + Common::String fileName = getFileName(path); // TODO: Prettify this. - AnsiString extension = Common::lastPathComponent(fileName, '.'); + Common::String extension = Common::lastPathComponent(fileName, '.'); for (uint32 i = 0; i < extension.size() + 1; i++) { fileName.deleteLastChar(); } @@ -93,8 +101,8 @@ AnsiString PathUtil::getFileNameWithoutExtension(const AnsiString &path) { } ////////////////////////////////////////////////////////////////////////// -AnsiString PathUtil::getExtension(const AnsiString &path) { - AnsiString fileName = getFileName(path); +Common::String PathUtil::getExtension(const Common::String &path) { + Common::String fileName = getFileName(path); return Common::lastPathComponent(path, '.'); } diff --git a/engines/wintermute/utils/path_util.h b/engines/wintermute/utils/path_util.h index 264dc5d241..8050cdfae2 100644 --- a/engines/wintermute/utils/path_util.h +++ b/engines/wintermute/utils/path_util.h @@ -35,13 +35,14 @@ namespace Wintermute { class PathUtil { public: - static AnsiString unifySeparators(const AnsiString &path); - static AnsiString normalizeFileName(const AnsiString &path); - static AnsiString combine(const AnsiString &path1, const AnsiString &path2); - static AnsiString getDirectoryName(const AnsiString &path); - static AnsiString getFileName(const AnsiString &path); - static AnsiString getFileNameWithoutExtension(const AnsiString &path); - static AnsiString getExtension(const AnsiString &path); + static Common::String unifySeparators(const Common::String &path); + static Common::String normalizeFileName(const Common::String &path); + static Common::String combine(const Common::String &path1, const Common::String &path2); + static Common::String getDirectoryName(const Common::String &path); + static Common::String getFileName(const Common::String &path); + static Common::String getFileNameWithoutExtension(const Common::String &path); + static Common::String getExtension(const Common::String &path); + static bool hasTrailingSlash(const Common::String &path); }; } // End of namespace Wintermute |