diff options
Diffstat (limited to 'engines')
302 files changed, 9705 insertions, 4970 deletions
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h index 9a6b5e4ef7..c31c8bd66e 100644 --- a/engines/advancedDetector.h +++ b/engines/advancedDetector.h @@ -101,7 +101,7 @@ typedef Common::Array<const ADGameDescription *> ADGameDescList; * terminate a list to be passed to the AdvancedDetector API. */ #define AD_TABLE_END_MARKER \ - { NULL, NULL, { { NULL, 0, NULL, 0 } }, Common::UNK_LANG, Common::kPlatformUnknown, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) } + { NULL, NULL, { { NULL, 0, NULL, 0 } }, Common::UNK_LANG, Common::kPlatformUnknown, ADGF_NO_FLAGS, GUIO0() } struct ADFileBasedFallback { /** diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index 9cbab1f3c4..99649fb437 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -200,10 +200,11 @@ int AgiEngine::mainCycle() { // vars in every interpreter cycle. // // We run AGIMOUSE always as a side effect - if (getFeatures() & GF_AGIMOUSE || true) { + //if (getFeatures() & GF_AGIMOUSE) { _game.vars[28] = _mouse.x / 2; _game.vars[29] = _mouse.y; - } + //} + if (key == KEY_PRIORITY) { _sprites->eraseBoth(); _debug.priority = !_debug.priority; @@ -315,7 +316,7 @@ int AgiEngine::playGame() { _game.lineUserInput = 22; // We run AGIMOUSE always as a side effect - if (getFeatures() & GF_AGIMOUSE || true) + //if (getFeatures() & GF_AGIMOUSE) debug(1, "Using AGI Mouse 1.0 protocol"); if (getFeatures() & GF_AGIPAL) diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h index 081cb39668..ab0e9a1fe4 100644 --- a/engines/agi/detection_tables.h +++ b/engines/agi/detection_tables.h @@ -30,7 +30,7 @@ namespace Agi { lang, \ platform, \ ADGF_NO_FLAGS, \ - GUIO1(GUIO_NONE) \ + GUIO0() \ }, \ gid, \ interp, \ @@ -46,7 +46,7 @@ namespace Agi { lang, \ platform, \ ADGF_USEEXTRAASTITLE, \ - GUIO1(GUIO_NONE) \ + GUIO0() \ }, \ gid, \ interp, \ @@ -130,7 +130,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_BC, GType_V1, @@ -151,7 +151,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_BC, GType_V1, @@ -172,7 +172,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_BC, GType_V1, @@ -252,7 +252,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_GOLDRUSH, GType_V3, @@ -570,7 +570,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_SQ2, GType_V2, @@ -859,7 +859,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_USEEXTRAASTITLE, - GUIO1(GUIO_NONE) + GUIO0() }, GID_FANMADE, GType_V3, @@ -887,7 +887,7 @@ static AGIGameDescription g_fallbackDesc = { Common::UNK_LANG, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_FANMADE, GType_V2, diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp index 074e5570d5..4bb3877f7d 100644 --- a/engines/agi/graphics.cpp +++ b/engines/agi/graphics.cpp @@ -1083,7 +1083,7 @@ void GfxMgr::putPixelsA(int x, int y, int n, uint8 *p) { // Choose the correct screen to read from. If AGI256 or AGI256-2 is used and we're not trying to show the priority information, // then choose the 256 color screen, otherwise choose the 16 color screen (Which also has the priority information). - p += _vm->getFeatures() & (GF_AGI256 | GF_AGI256_2) && !_vm->_debug.priority ? FROM_SBUF16_TO_SBUF256_OFFSET : 0; + p += ((_vm->getFeatures() & (GF_AGI256 | GF_AGI256_2)) && !_vm->_debug.priority) ? FROM_SBUF16_TO_SBUF256_OFFSET : 0; if (_vm->_renderMode == Common::kRenderCGA) { for (x *= 2; n--; p++, x += 2) { @@ -1091,7 +1091,7 @@ void GfxMgr::putPixelsA(int x, int y, int n, uint8 *p) { *(uint16 *)&_agiScreen[x + y * GFX_WIDTH] = (q >> rShift) & 0x0f0f; } } else { - const uint16 mask = _vm->getFeatures() & (GF_AGI256 | GF_AGI256_2) && !_vm->_debug.priority ? 0xffff : 0x0f0f; + const uint16 mask = ((_vm->getFeatures() & (GF_AGI256 | GF_AGI256_2)) && !_vm->_debug.priority) ? 0xffff : 0x0f0f; for (x *= 2; n--; p++, x += 2) { register uint16 q = ((uint16)*p << 8) | *p; *(uint16 *)&_agiScreen[x + y * GFX_WIDTH] = (q >> rShift) & mask; diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index 72f60e2516..41d9cc3ac9 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -1622,15 +1622,15 @@ void cmdPrintAtV(AgiGame *state, uint8 *p) { void cmdPushScript(AgiGame *state, uint8 *p) { // We run AGIMOUSE always as a side effect - if (getFeatures() & GF_AGIMOUSE || true) { + //if (getFeatures() & GF_AGIMOUSE || true) { state->vars[27] = state->_vm->_mouse.button; state->vars[28] = state->_vm->_mouse.x / 2; state->vars[29] = state->_vm->_mouse.y; - } else { + /*} else { if (getVersion() >= 0x2915) { debug(0, "push.script"); } - } + }*/ } void cmdSetPriBase(AgiGame *state, uint8 *p) { diff --git a/engines/agi/opcodes.cpp b/engines/agi/opcodes.cpp index d1baab93e1..29fb860635 100644 --- a/engines/agi/opcodes.cpp +++ b/engines/agi/opcodes.cpp @@ -360,7 +360,7 @@ AgiInstruction insV2[] = { void AgiEngine::setupOpcodes() { if (getVersion() >= 0x2000) { - for (int i = 0; i <= ARRAYSIZE(insV2Test); ++i) + for (int i = 0; i < ARRAYSIZE(insV2Test); ++i) _agiCondCommands[i] = insV2Test[i].func; for (int i = 0; i < ARRAYSIZE(insV2); ++i) _agiCommands[i] = insV2[i].func; @@ -368,7 +368,7 @@ void AgiEngine::setupOpcodes() { logicNamesTest = insV2Test; logicNamesCmd = insV2; } else { - for (int i = 0; i <= ARRAYSIZE(insV1Test); ++i) + for (int i = 0; i < ARRAYSIZE(insV1Test); ++i) _agiCondCommands[i] = insV1Test[i].func; for (int i = 0; i < ARRAYSIZE(insV1); ++i) _agiCommands[i] = insV1[i].func; diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp index 3cebbf50c8..1bcabd507f 100644 --- a/engines/agi/saveload.cpp +++ b/engines/agi/saveload.cpp @@ -300,7 +300,7 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) { _game.state = (State)in->readByte(); in->read(loadId, 8); - if (strcmp(loadId, _game.id) && checkId) { + if (strcmp(loadId, _game.id) != 0 && checkId) { delete in; warning("This save seems to be from a different AGI game (save from %s, running %s), not loaded", loadId, _game.id); return errBadFileOpen; @@ -331,7 +331,7 @@ int AgiEngine::loadGame(const Common::String &fileName, bool checkId) { warning("Since your game was only detected via the fallback detector, there is no possibility to assure the save is compatible with your game version"); debug(0, "The game used for saving is \"%s\".", md5); - } else if (strcmp(md5, getGameMD5())) { + } else if (strcmp(md5, getGameMD5()) != 0) { warning("Game was saved with different gamedata - you may encounter problems"); debug(0, "Your game is \"%s\" and save is \"%s\".", getGameMD5(), md5); diff --git a/engines/agi/sound_2gs.cpp b/engines/agi/sound_2gs.cpp index c5cfa125d6..b15950f31d 100644 --- a/engines/agi/sound_2gs.cpp +++ b/engines/agi/sound_2gs.cpp @@ -719,7 +719,10 @@ bool SoundGen2GS::loadInstrumentHeaders(Common::String &exePath, const IIgsExeIn } // Read the whole executable file into memory - Common::SharedPtr<Common::SeekableReadStream> data(file.readStream(file.size())); + // CHECKME: Why do we read the file into memory first? It does not seem to be + // kept outside of this function. Is the processing of the data too slow + // otherwise? + Common::ScopedPtr<Common::SeekableReadStream> data(file.readStream(file.size())); file.close(); // Check that we got enough data to be able to parse the instruments @@ -769,8 +772,11 @@ bool SoundGen2GS::loadWaveFile(Common::String &wavePath, const IIgsExeInfo &exeI Common::File file; // Open the wave file and read it into memory + // CHECKME: Why do we read the file into memory first? It does not seem to be + // kept outside of this function. Is the processing of the data too slow + // otherwise? file.open(wavePath); - Common::SharedPtr<Common::SeekableReadStream> uint8Wave(file.readStream(file.size())); + Common::ScopedPtr<Common::SeekableReadStream> uint8Wave(file.readStream(file.size())); file.close(); // Check that we got the whole wave file diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp index d5027588f9..3247862e32 100644 --- a/engines/agi/text.cpp +++ b/engines/agi/text.cpp @@ -240,7 +240,6 @@ char *AgiEngine::wordWrapString(const char *s, int *len) { while (*s) { pWord = s; - wLen = 0; while (*s != '\0' && *s != ' ' && *s != '\n' && *s != '\r') s++; diff --git a/engines/agos/agos.h b/engines/agos/agos.h index cf75842cdd..03feafa70f 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -197,6 +197,7 @@ public: void registerArchive(const Common::String &filename, int priority); #endif + bool hasFile(const Common::String &name); Common::SeekableReadStream *open(const Common::String &filename); private: diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index d9d6b71a2a..db2cff328c 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -525,25 +525,25 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name) { memcpy(shortName, baseName, 6); sprintf(filename, "%s~1.dxa", shortName); - if (Common::File::exists(filename)) { + if (vm->_archives.hasFile(filename)) { memset(baseName, 0, sizeof(baseName)); memcpy(baseName, filename, 8); } sprintf(filename, "%s~1.smk", shortName); - if (Common::File::exists(filename)) { + if (vm->_archives.hasFile(filename)) { memset(baseName, 0, sizeof(baseName)); memcpy(baseName, filename, 8); } } sprintf(filename, "%s.dxa", baseName); - if (Common::File::exists(filename)) { + if (vm->_archives.hasFile(filename)) { return new MoviePlayerDXA(vm, baseName); } sprintf(filename, "%s.smk", baseName); - if (Common::File::exists(filename)) { + if (vm->_archives.hasFile(filename)) { return new MoviePlayerSMK(vm, baseName); } diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index a006766728..7fe6df5f17 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -1591,7 +1591,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON1, @@ -1616,7 +1616,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON1, @@ -1666,7 +1666,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::HE_ISR, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON1, @@ -1691,7 +1691,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON1, @@ -1717,7 +1717,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON1, @@ -1742,7 +1742,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON1, @@ -1942,7 +1942,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -1967,7 +1967,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -1992,7 +1992,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2017,7 +2017,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2042,7 +2042,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2067,7 +2067,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2092,7 +2092,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2117,7 +2117,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2142,7 +2142,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::HE_ISR, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2168,7 +2168,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2193,7 +2193,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2218,7 +2218,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::CZ_CZE, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2243,7 +2243,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2268,7 +2268,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2293,7 +2293,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, @@ -2318,7 +2318,7 @@ static const AGOSGameDescription gameDescriptions[] = { Common::PL_POL, Common::kPlatformWindows, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_SIMON2, diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index 9fc5cedbf9..cf3a12ceb8 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -776,7 +776,7 @@ void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) { void AGOSEngine::displayScreen() { if (_fastFadeInFlag == 0 && _paletteFlag == 1) { _paletteFlag = 0; - if (memcmp(_displayPalette, _currentPalette, sizeof(_currentPalette))) { + if (memcmp(_displayPalette, _currentPalette, sizeof(_currentPalette)) != 0) { memcpy(_currentPalette, _displayPalette, sizeof(_displayPalette)); _system->getPaletteManager()->setPalette(_displayPalette, 0, 256); } diff --git a/engines/agos/installshield_cab.cpp b/engines/agos/installshield_cab.cpp index f7b49a64c5..ac4e40d1d1 100644 --- a/engines/agos/installshield_cab.cpp +++ b/engines/agos/installshield_cab.cpp @@ -162,7 +162,6 @@ InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _in } bool InstallShieldCabinet::hasFile(const Common::String &name) { - warning("hasFile: Filename %s", name.c_str()); return _map.contains(name); } diff --git a/engines/agos/midi.cpp b/engines/agos/midi.cpp index 431f080bf2..b3ade91107 100644 --- a/engines/agos/midi.cpp +++ b/engines/agos/midi.cpp @@ -478,7 +478,7 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) { // Make sure there's a MThd in->read(buf, 4); - if (memcmp(buf, "MThd", 4)) { + if (memcmp(buf, "MThd", 4) != 0) { warning("Expected MThd but found '%c%c%c%c' instead", buf[0], buf[1], buf[2], buf[3]); return; } @@ -487,7 +487,7 @@ void MidiPlayer::loadMultipleSMF(Common::File *in, bool sfx) { // Now skip all the MTrk blocks while (true) { in->read(buf, 4); - if (memcmp(buf, "MTrk", 4)) + if (memcmp(buf, "MTrk", 4) != 0) break; in->seek(in->readUint32BE(), SEEK_CUR); } @@ -524,7 +524,7 @@ void MidiPlayer::loadXMIDI(Common::File *in, bool sfx) { memcpy(buf, &buf[2], 2); in->read(&buf[2], 2); } - if (memcmp(buf, "CAT ", 4)) { + if (memcmp(buf, "CAT ", 4) != 0) { error("Could not find 'CAT ' tag to determine resource size"); } size += 4 + in->readUint32BE(); diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp index 69447f4b83..62197340d2 100644 --- a/engines/agos/res.cpp +++ b/engines/agos/res.cpp @@ -47,6 +47,13 @@ void ArchiveMan::registerArchive(const Common::String &filename, int priority) { } #endif +bool ArchiveMan::hasFile(const Common::String &name) { + if (_fallBack && SearchMan.hasFile(name)) + return true; + + return Common::SearchSet::hasFile(name); +} + Common::SeekableReadStream *ArchiveMan::open(const Common::String &filename) { if (_fallBack && SearchMan.hasFile(filename)) { return SearchMan.createReadStreamForMember(filename); diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp index b5612d710d..e9a7ea4de9 100644 --- a/engines/agos/res_snd.cpp +++ b/engines/agos/res_snd.cpp @@ -495,7 +495,7 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) { } if (getPlatform() == Common::kPlatformAmiga) - sprintf(filename, "sfx%d.wav", file); + sprintf(filename, "sfx%u.wav", file); else sprintf(filename, "effects.wav"); @@ -606,7 +606,7 @@ void AGOSEngine::loadVoice(uint speechId) { } if (getPlatform() == Common::kPlatformAmiga) - sprintf(filename, "sp%d.wav", file); + sprintf(filename, "sp%u.wav", file); else sprintf(filename, "speech.wav"); diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp index 11a1cd792e..4917aefa4d 100644 --- a/engines/agos/sound.cpp +++ b/engines/agos/sound.cpp @@ -606,8 +606,6 @@ void Sound::playVoice(uint sound) { _voice->playSound(sound, sound + 1, Audio::Mixer::kMusicSoundType, &_voiceHandle, true, -1500); else _voice->playSound(sound, sound, Audio::Mixer::kMusicSoundType, &_voiceHandle, true); - } else if (_vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32) { - _voice->playSound(sound, Audio::Mixer::kSpeechSoundType, &_voiceHandle, false); } else { _voice->playSound(sound, Audio::Mixer::kSpeechSoundType, &_voiceHandle, false); } @@ -799,12 +797,12 @@ void Sound::switchVoiceFile(const GameSpecificSettings *gss, uint disc) { Common::File *file = new Common::File(); if (!_hasVoiceFile) { - sprintf(filename, "%s%d", gss->speech_filename, disc); + sprintf(filename, "%s%u", gss->speech_filename, disc); _voice = makeCompressedSound(_mixer, file, filename); _hasVoiceFile = (_voice != 0); } if (!_hasVoiceFile) { - sprintf(filename, "%s%d.wav", gss->speech_filename, disc); + sprintf(filename, "%s%u.wav", gss->speech_filename, disc); file->open(filename); if (file->isOpen() == false) { error("switchVoiceFile: Can't load voice file %s", filename); diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index 10c1c1aaf9..45cb370057 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -558,7 +558,6 @@ restart: while ((byte *)sl != (byte *)sub) { _currentLine = sl; if (checkIfToRunSubroutineLine(sl, sub)) { - result = 0; _codePtr = (byte *)sl; if (sub->id) _codePtr += 2; diff --git a/engines/cge/cge.cpp b/engines/cge/cge.cpp index 4ed2932cd9..87654c53f4 100644 --- a/engines/cge/cge.cpp +++ b/engines/cge/cge.cpp @@ -53,9 +53,7 @@ CGEEngine::CGEEngine(OSystem *syst, const ADGameDescription *gameDescription) _oldLev = 0; _pocPtr = 0; _bitmapPalette = NULL; - - - + _quitFlag = false; } void CGEEngine::initSceneValues() { @@ -144,7 +142,6 @@ void CGEEngine::deinit() { DebugMan.clearAllDebugChannels(); delete _console; - _midiPlayer->killMidi(); // Delete engine objects delete _vga; @@ -161,8 +158,9 @@ void CGEEngine::deinit() { delete _keyboard; delete _mouse; delete _eventManager; - delete _fx; delete _sound; + delete _fx; + delete _midiPlayer; delete _font; delete _commandHandler; delete _commandHandlerTurbo; @@ -214,7 +212,8 @@ bool CGEEngine::canLoadGameStateCurrently() { } bool CGEEngine::canSaveGameStateCurrently() { - return (_startupMode == 0) && _mouse->_active; + return (_startupMode == 0) && _mouse->_active && + _commandHandler->idle() && !_hero->_flags._hide; } } // End of namespace CGE diff --git a/engines/cge/cge.h b/engines/cge/cge.h index 2ce154a4fb..2aada420ed 100644 --- a/engines/cge/cge.h +++ b/engines/cge/cge.h @@ -140,6 +140,7 @@ public: virtual Common::Error saveGameState(int slot, const Common::String &desc); static const int _maxSceneArr[5]; + bool _quitFlag; const ADGameDescription *_gameDescription; int _startupMode; diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp index 1c2759bd97..e5831400ee 100644 --- a/engines/cge/cge_main.cpp +++ b/engines/cge/cge_main.cpp @@ -185,7 +185,7 @@ void CGEEngine::syncHeader(Common::Serializer &s) { s.syncAsUint16LE(checksum); } else { // Read checksum and validate it - uint16 checksum; + uint16 checksum = 0; s.syncAsUint16LE(checksum); if (checksum != kSavegameCheckSum) error("%s", _text->getText(kBadSVG)); @@ -200,7 +200,7 @@ bool CGEEngine::loadGame(int slotNumber, SavegameHeader *header, bool tiny) { if (slotNumber == -1) { // Loading the data for the initial game state - kSavegame0File file = kSavegame0File(this, kSavegame0Name); + EncryptedStream file = EncryptedStream(this, kSavegame0Name); int size = file.size(); byte *dataBuffer = (byte *)malloc(size); file.read(dataBuffer, size); @@ -277,6 +277,7 @@ Common::String CGEEngine::generateSaveName(int slot) { Common::Error CGEEngine::loadGameState(int slot) { // Clear current game activity sceneDown(); + _hero->park(); resetGame(); // Load the game @@ -295,6 +296,7 @@ void CGEEngine::resetGame() { Common::Error CGEEngine::saveGameState(int slot, const Common::String &desc) { sceneDown(); + _hero->park(); _oldLev = _lev; // Write out the user's progress @@ -692,6 +694,7 @@ void CGEEngine::qGame() { debugC(1, kCGEDebugEngine, "CGEEngine::qGame()"); sceneDown(); + _hero->park(); _oldLev = _lev; // Write out the user's progress @@ -920,7 +923,7 @@ void CGEEngine::optionTouch(int opt, uint16 mask) { if (mask & kMouseLeftUp) switchMusic(); else if (mask & kMouseRightUp) - warning("TODO: Use ScummVM sound dialog"); + openMainMenuDialog(); break; case 3: if (mask & kMouseLeftUp) @@ -1252,12 +1255,15 @@ void CGEEngine::mainLoop() { // Handle any pending events _eventManager->poll(); + + // Check shouldQuit() + _quitFlag = shouldQuit(); } void CGEEngine::handleFrame() { // Game frame delay uint32 millis = g_system->getMillis(); - while (!_eventManager->_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) { + while (!_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) { // Handle any pending events _eventManager->poll(); @@ -1306,7 +1312,7 @@ void CGEEngine::loadUser() { } void CGEEngine::runGame() { - if (_eventManager->_quitFlag) + if (_quitFlag) return; loadHeroXY(); @@ -1336,9 +1342,7 @@ void CGEEngine::runGame() { _vga->_showQ->append(_mouse); -// ___________ loadUser(); -// ~~~~~~~~~~~ if ((_sprite = _vga->_spareQ->locate(121)) != NULL) _commandHandlerTurbo->addCommand(kCmdSeq, -1, _vga->_mono, _sprite); @@ -1406,7 +1410,7 @@ void CGEEngine::runGame() { _keyboard->setClient(_sys); // main loop - while (!_finis && !_eventManager->_quitFlag) { + while (!_finis && !_quitFlag) { if (_flag[3]) _commandHandler->addCallback(kCmdExec, -1, 0, kQGame); mainLoop(); @@ -1429,7 +1433,7 @@ void CGEEngine::runGame() { void CGEEngine::movie(const char *ext) { assert(ext); - if (_eventManager->_quitFlag) + if (_quitFlag) return; char fn[12]; @@ -1441,7 +1445,7 @@ void CGEEngine::movie(const char *ext) { feedSnail(_vga->_showQ->locate(999), kTake); _vga->_showQ->append(_mouse); _keyboard->setClient(_sys); - while (!_commandHandler->idle() && !_eventManager->_quitFlag) + while (!_commandHandler->idle() && !_quitFlag) mainLoop(); _keyboard->setClient(NULL); @@ -1453,7 +1457,7 @@ void CGEEngine::movie(const char *ext) { } bool CGEEngine::showTitle(const char *name) { - if (_eventManager->_quitFlag) + if (_quitFlag) return false; _bitmapPalette = _vga->_sysPal; @@ -1486,7 +1490,7 @@ bool CGEEngine::showTitle(const char *name) { _mouse->on(); for (; !_commandHandler->idle() || Vmenu::_addr;) { mainLoop(); - if (_eventManager->_quitFlag) + if (_quitFlag) return false; } diff --git a/engines/cge/cge_main.h b/engines/cge/cge_main.h index bdb3121d63..87199ee524 100644 --- a/engines/cge/cge_main.h +++ b/engines/cge/cge_main.h @@ -56,10 +56,8 @@ namespace CGE { #define kSystemRate 6 // 12 Hz #define kHeroFun0 (40 * 12) #define kHeroFun1 ( 2 * 12) -#define kGetNamePrompt 50 -#define kGetNameTitle 51 +#define kShowScummVMVersion 15 #define kTSeq 96 -#define kNoMusic 98 #define kBadSVG 99 #define kSeqHTalk (kTSeq + 4) #define kSeqTooFar (kTSeq + 5) @@ -82,7 +80,6 @@ namespace CGE { #define kStackSize 2048 #define kSavegameCheckSum (1956 + _now + _oldLev + _game + _music + _demoText) #define kSavegame0Name ("{{INIT}}" kSvgExt) -#define kSavegame0File EncryptedStream #define kSavegameStrSize 11 #define kGameFrameDelay (1000 / 50) #define kGameTickDelay (1000 / 62) diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp index f2f5764e54..3fa3dbd7ff 100644 --- a/engines/cge/detection.cpp +++ b/engines/cge/detection.cpp @@ -44,7 +44,7 @@ static const ADGameDescription gameDescriptions[] = { {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572}, AD_LISTEND }, - Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, { "soltys", "Soltys Freeware", @@ -53,17 +53,7 @@ static const ADGameDescription gameDescriptions[] = { {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676}, AD_LISTEND }, - Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) - }, - // English ScummVM version - { - "soltys", "", - { - {"vol.cat", 0, "bd08969b5f1acea0f92d195f750c17d5", 50176}, - {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8428832}, - AD_LISTEND - }, - Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, { "soltys", "Soltys Demo (not supported)", @@ -72,7 +62,7 @@ static const ADGameDescription gameDescriptions[] = { {"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710}, AD_LISTEND }, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO , GUIO1(GUIO_NONE) + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO , GUIO0() }, { "soltys", "Soltys Demo (not supported)", @@ -81,7 +71,25 @@ static const ADGameDescription gameDescriptions[] = { {"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272}, AD_LISTEND }, - Common::PL_POL, Common::kPlatformPC, ADGF_DEMO , GUIO1(GUIO_NONE) + Common::PL_POL, Common::kPlatformPC, ADGF_DEMO , GUIO0() + }, + { + "soltys", "Soltys Freeware v1.0", + { + {"vol.cat", 0, "f1675684c68ab90272f5776f8f2c3974", 50176}, + {"vol.dat", 0, "4ffeff4abc99ac5999b55ccfc56ab1df", 8430868}, + AD_LISTEND + }, + Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS , GUIO0() + }, + { + "soltys", "Soltys Freeware v1.0", + { + {"vol.cat", 0, "20fdce799adb618100ef9ee2362be875", 50176}, + {"vol.dat", 0, "0e43331c846094d77f5dd201827e0a3b", 8439339}, + AD_LISTEND + }, + Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, AD_TABLE_END_MARKER }; diff --git a/engines/cge/events.cpp b/engines/cge/events.cpp index cc22d9075a..73bef63129 100644 --- a/engines/cge/events.cpp +++ b/engines/cge/events.cpp @@ -86,7 +86,7 @@ const uint16 Keyboard::_scummVmCodes[0x60] = { }; Keyboard::Keyboard(CGEEngine *vm) : _client(NULL), _vm(vm) { - Common::set_to(&_key[0], &_key[0x60], false); + Common::fill(&_key[0], &_key[0x60], false); _current = 0; } @@ -112,8 +112,14 @@ bool Keyboard::getKey(Common::Event &event, int &cgeCode) { cgeCode = 28; return true; } - if (keycode == Common::KEYCODE_F5) { - warning("keycode %d", event.kbd.ascii); + if (keycode == Common::KEYCODE_F1) { + if (event.type == Common::EVENT_KEYUP) + return false; + // Display ScummVM version and translation strings + for (int i = 0; i < 5; i++) + _vm->_commandHandler->addCommand(kCmdInf, 1, kShowScummVMVersion + i, NULL); + return false; + } else if (keycode == Common::KEYCODE_F5) { if (_vm->canSaveGameStateCurrently()) { const EnginePlugin *plugin = NULL; EngineMan.findGame(_vm->_gameDescription->gameid, &plugin); @@ -123,7 +129,9 @@ bool Keyboard::getKey(Common::Event &event, int &cgeCode) { int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); Common::String savegameDescription = dialog->getResultString(); delete dialog; - _vm->saveGameState(savegameId, savegameDescription); + + if (savegameId != -1) + _vm->saveGameState(savegameId, savegameDescription); } return false; } else if (keycode == Common::KEYCODE_F7) { @@ -135,7 +143,9 @@ bool Keyboard::getKey(Common::Event &event, int &cgeCode) { dialog->setSaveMode(false); int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); delete dialog; - _vm->loadGameState(savegameId); + + if (savegameId != -1) + _vm->loadGameState(savegameId); } return false; } @@ -272,7 +282,6 @@ void Mouse::newMouse(Common::Event &event) { /*----------------- EventManager interface -----------------*/ EventManager::EventManager(CGEEngine *vm) : _vm(vm){ - _quitFlag = false; _eventQueueHead = 0; _eventQueueTail = 0; memset(&_eventQueue, 0, kEventMax * sizeof(CGEEvent)); @@ -282,10 +291,6 @@ EventManager::EventManager(CGEEngine *vm) : _vm(vm){ void EventManager::poll() { while (g_system->getEventManager()->pollEvent(_event)) { switch (_event.type) { - case Common::EVENT_QUIT: - // Signal to quit - _quitFlag = true; - return; case Common::EVENT_KEYDOWN: case Common::EVENT_KEYUP: // Handle keyboard events diff --git a/engines/cge/events.h b/engines/cge/events.h index a4cdfed793..ac1e6231fe 100644 --- a/engines/cge/events.h +++ b/engines/cge/events.h @@ -140,8 +140,6 @@ private: void handleEvents(); public: - bool _quitFlag; - EventManager(CGEEngine *vm); void poll(); void clearEvent(Sprite *spr); diff --git a/engines/cge/snail.cpp b/engines/cge/snail.cpp index cbc463ced2..5ab8f6314b 100644 --- a/engines/cge/snail.cpp +++ b/engines/cge/snail.cpp @@ -406,7 +406,7 @@ void CGEEngine::snGame(Sprite *spr, int num) { Stage++; if (hand && Stage > kDressed) ++hand; - if (i >= 0 || (dup[i] == spr && newRandom(3) == 0)) { + if (i >= 0 && (dup[i] == spr && newRandom(3) == 0)) { _commandHandler->addCommand(kCmdSeq, -1, 3, dup[0]); // Yes _commandHandler->addCommand(kCmdSeq, -1, 3, dup[1]); // Yes _commandHandler->addCommand(kCmdSeq, -1, 3, dup[2]); // Yes diff --git a/engines/cge/text.cpp b/engines/cge/text.cpp index 58acb5548c..d426787ed4 100644 --- a/engines/cge/text.cpp +++ b/engines/cge/text.cpp @@ -135,6 +135,13 @@ char *Text::getText(int ref) { void Text::say(const char *text, Sprite *spr) { _vm->killText(); + + if (!text) + return; + + if (*text == 0) + return; + _vm->_talk = new Talk(_vm, text, kTBRound); if (!_vm->_talk) return; @@ -177,6 +184,11 @@ void Text::say(const char *text, Sprite *spr) { void CGEEngine::inf(const char *text) { debugC(1, kCGEDebugEngine, "CGEEngine::inf(%s)", text); + if (!text) + return; + + if (*text == 0) + return; killText(); _talk = new Talk(this, text, kTBRect); diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp index 49cfcd3084..47b77688f7 100644 --- a/engines/cge/vga13h.cpp +++ b/engines/cge/vga13h.cpp @@ -492,7 +492,7 @@ void Sprite::sync(Common::Serializer &s) { _flags._near = flags & 0x0002 ? true : false; _flags._drag = flags & 0x0004 ? true : false; _flags._hold = flags & 0x0008 ? true : false; - _flags._____ = flags & 0x0010 ? true : false; + _flags._dummy = flags & 0x0010 ? true : false; _flags._slav = flags & 0x0020 ? true : false; _flags._syst = flags & 0x0040 ? true : false; _flags._kill = flags & 0x0080 ? true : false; @@ -516,7 +516,7 @@ void Sprite::sync(Common::Serializer &s) { flags = (flags << 1) | _flags._kill; flags = (flags << 1) | _flags._syst; flags = (flags << 1) | _flags._slav; - flags = (flags << 1) | _flags._____; + flags = (flags << 1) | _flags._dummy; flags = (flags << 1) | _flags._hold; flags = (flags << 1) | _flags._drag; flags = (flags << 1) | _flags._near; diff --git a/engines/cge/vga13h.h b/engines/cge/vga13h.h index 0c514c4a66..559fa78cdb 100644 --- a/engines/cge/vga13h.h +++ b/engines/cge/vga13h.h @@ -91,7 +91,7 @@ public: uint16 _near : 1; // Near action lock uint16 _drag : 1; // sprite is moveable uint16 _hold : 1; // sprite is held with mouse - uint16 _____ : 1; // intrrupt driven animation + uint16 _dummy : 1; // intrrupt driven animation uint16 _slav : 1; // slave object uint16 _syst : 1; // system object uint16 _kill : 1; // dispose memory after remove diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index 6f34b0f860..6b94c33c31 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -141,11 +141,11 @@ void CineEngine::initialize() { // Resize zone data table to its correct size and reset all its elements g_cine->_zoneData.resize(NUM_MAX_ZONE); - Common::set_to(g_cine->_zoneData.begin(), g_cine->_zoneData.end(), 0); + Common::fill(g_cine->_zoneData.begin(), g_cine->_zoneData.end(), 0); // Resize zone query table to its correct size and reset all its elements g_cine->_zoneQuery.resize(NUM_MAX_ZONE); - Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0); + Common::fill(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0); _timerDelayMultiplier = 12; // Set default speed setupOpcodes(); diff --git a/engines/cine/detection_tables.h b/engines/cine/detection_tables.h index c8ab63edaf..ddb63c960b 100644 --- a/engines/cine/detection_tables.h +++ b/engines/cine/detection_tables.h @@ -31,7 +31,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -51,7 +51,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, GF_CD | GF_CRYPTED_BOOT_PRC, @@ -66,7 +66,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -80,7 +80,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, GF_ALT_FONT, @@ -94,7 +94,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, GF_ALT_FONT, @@ -108,7 +108,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -122,7 +122,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -136,7 +136,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -150,7 +150,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, GF_ALT_FONT, @@ -164,7 +164,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -178,7 +178,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -192,7 +192,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -210,7 +210,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -224,7 +224,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -238,7 +238,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_FW, 0, @@ -252,7 +252,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -268,7 +268,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -282,7 +282,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -296,7 +296,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, GF_CD, @@ -310,7 +310,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -324,7 +324,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -342,7 +342,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, GF_CD, @@ -356,7 +356,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -370,7 +370,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -384,7 +384,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -398,7 +398,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -412,7 +412,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -426,7 +426,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -440,7 +440,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -454,7 +454,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -468,7 +468,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAmiga, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, GF_DEMO, @@ -482,7 +482,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, @@ -496,7 +496,7 @@ static const CINEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_OS, 0, diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp index bb0545db72..971830ce8f 100644 --- a/engines/cine/main_loop.cpp +++ b/engines/cine/main_loop.cpp @@ -345,7 +345,7 @@ void CineEngine::mainLoop(int bootScriptIdx) { // Clear the zoneQuery table (Operation Stealth specific) if (g_cine->getGameType() == Cine::GType_OS) { - Common::set_to(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0); + Common::fill(g_cine->_zoneQuery.begin(), g_cine->_zoneQuery.end(), 0); } if (g_cine->getGameType() == Cine::GType_OS) { diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp index 0ea1a23e8f..223099a587 100644 --- a/engines/cine/saveload.cpp +++ b/engines/cine/saveload.cpp @@ -1034,7 +1034,7 @@ void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGam } // Alright, the animation entry looks to be valid so let's start handling it... - if (strcmp(currentPartName, name)) { + if (strcmp(currentPartName, name) != 0) { closePart(); loadPart(name); } diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp index 0c3541fae7..48c5e3d0a5 100644 --- a/engines/cine/sound.cpp +++ b/engines/cine/sound.cpp @@ -602,7 +602,7 @@ bool PCSoundFxPlayer::load(const char *song) { memcpy(instrument, _sfxData + 20 + i * 30, 12); instrument[63] = '\0'; - if (strlen(instrument) != 0) { + if (instrument[0] != '\0') { char *dot = strrchr(instrument, '.'); if (dot) { *dot = '\0'; diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp index 085ce815dd..556dad7e94 100644 --- a/engines/composer/composer.cpp +++ b/engines/composer/composer.cpp @@ -32,6 +32,7 @@ #include "graphics/cursorman.h" #include "graphics/surface.h" #include "graphics/pixelformat.h" +#include "graphics/wincursor.h" #include "engines/util.h" #include "engines/advancedDetector.h" @@ -52,6 +53,11 @@ ComposerEngine::ComposerEngine(OSystem *syst, const ComposerGameDescription *gam ComposerEngine::~ComposerEngine() { DebugMan.clearAllDebugChannels(); + stopPipes(); + for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) + delete *i; + for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) + delete *i; for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) delete i->_archive; for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) @@ -99,6 +105,11 @@ Common::Error ComposerEngine::run() { _surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8()); _needsUpdate = true; + Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor(); + CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), + cursor->getHotspotY(), cursor->getKeyColor()); + CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount()); + loadLibrary(0); _currentTime = 0; @@ -150,6 +161,7 @@ Common::Error ComposerEngine::run() { redraw(); + tickOldScripts(); processAnimFrame(); } else if (_needsUpdate) { redraw(); @@ -213,11 +225,13 @@ void ComposerEngine::onMouseDown(const Common::Point &pos) { if (!button) return; + debug(3, "mouseDown on button id %d", button->_id); + // TODO: other buttons? uint16 buttonsDown = 1; // MK_LBUTTON uint16 spriteId = sprite ? sprite->_id : 0; - runScript(button->_scriptId, button->_id, buttonsDown, spriteId); + runScript(button->_scriptId, (getGameType() == GType_ComposerV1) ? 0 : button->_id, buttonsDown, spriteId); } void ComposerEngine::onMouseMove(const Common::Point &pos) { @@ -233,21 +247,48 @@ void ComposerEngine::onMouseMove(const Common::Point &pos) { const Button *button = getButtonFor(sprite, pos); if (_lastButton != button) { if (_lastButton && _lastButton->_scriptIdRollOff) - runScript(_lastButton->_scriptIdRollOff, _lastButton->_id, buttonsDown, 0); + runScript(_lastButton->_scriptIdRollOff, (getGameType() == GType_ComposerV1) ? 0 : _lastButton->_id, buttonsDown, 0); _lastButton = button; if (_lastButton && _lastButton->_scriptIdRollOn) - runScript(_lastButton->_scriptIdRollOn, _lastButton->_id, buttonsDown, 0); + runScript(_lastButton->_scriptIdRollOn, (getGameType() == GType_ComposerV1) ? 0 : _lastButton->_id, buttonsDown, 0); } if (_mouseSpriteId) { addSprite(_mouseSpriteId, 0, 0, _lastMousePos - _mouseOffset); - _needsUpdate = true; } + _needsUpdate = true; } void ComposerEngine::onKeyDown(uint16 keyCode) { runEvent(kEventKeyDown, keyCode, 0, 0); runEvent(kEventChar, keyCode, 0, 0); + + for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) { + for (Common::List<KeyboardHandler>::iterator j = i->_keyboardHandlers.begin(); j != i->_keyboardHandlers.end(); j++) { + const KeyboardHandler &handler = *j; + if (keyCode != handler.keyId) + continue; + + int modifiers = g_system->getEventManager()->getModifierState(); + switch (handler.modifierId) { + case 0x10: // shift + if (!(modifiers & Common::KBD_SHIFT)) + continue; + break; + case 0x11: // control + if (!(modifiers & Common::KBD_CTRL)) + continue; + break; + case 0: + break; + default: + warning("unknown keyb modifier %d", handler.modifierId); + continue; + } + + runScript(handler.scriptId); + } + } } void ComposerEngine::setCursor(uint16 id, const Common::Point &offset) { @@ -269,11 +310,15 @@ void ComposerEngine::setCursorVisible(bool visible) { _mouseVisible = true; if (_mouseSpriteId) addSprite(_mouseSpriteId, 0, 0, _lastMousePos - _mouseOffset); + else + CursorMan.showMouse(true); onMouseMove(_lastMousePos); } else if (!visible && _mouseVisible) { _mouseVisible = false; if (_mouseSpriteId) removeSprite(_mouseSpriteId, 0); + else + CursorMan.showMouse(false); } } @@ -316,9 +361,42 @@ Common::String ComposerEngine::mangleFilename(Common::String filename) { } void ComposerEngine::loadLibrary(uint id) { - if (!id) - id = atoi(getStringFromConfig("Common", "StartUp").c_str()); - Common::String filename = getFilename("Libs", id); + if (getGameType() == GType_ComposerV1 && !_libraries.empty()) { + // kill the previous page, starting with any scripts running on it + + for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) + delete *i; + _oldScripts.clear(); + + Library *library = &_libraries.front(); + unloadLibrary(library->_id); + } + + Common::String filename; + + if (getGameType() == GType_ComposerV1) { + if (!id || _bookGroup.empty()) + filename = getStringFromConfig("Common", "StartPage"); + else + filename = getStringFromConfig(_bookGroup, Common::String::format("%d", id)); + filename = mangleFilename(filename); + + _bookGroup.clear(); + for (uint i = 0; i < filename.size(); i++) { + if (filename[i] == '\\' || filename[i] == ':') + continue; + for (uint j = 0; j < filename.size(); j++) { + if (filename[j] == '.') + break; + _bookGroup += filename[j]; + } + break; + } + } else { + if (!id) + id = atoi(getStringFromConfig("Common", "StartUp").c_str()); + filename = getFilename("Libs", id); + } Library library; @@ -348,6 +426,37 @@ void ComposerEngine::loadLibrary(uint id) { newLib._buttons.push_back(button); } + Common::Array<uint16> ambientResources = library._archive->getResourceIDList(ID_AMBI); + for (uint i = 0; i < ambientResources.size(); i++) { + Common::SeekableReadStream *stream = library._archive->getResource(ID_AMBI, ambientResources[i]); + Button button(stream); + newLib._buttons.insert(newLib._buttons.begin(), button); + } + + Common::Array<uint16> accelResources = library._archive->getResourceIDList(ID_ACEL); + for (uint i = 0; i < accelResources.size(); i++) { + Common::SeekableReadStream *stream = library._archive->getResource(ID_ACEL, accelResources[i]); + KeyboardHandler handler; + handler.keyId = stream->readUint16LE(); + handler.modifierId = stream->readUint16LE(); + handler.scriptId = stream->readUint16LE(); + newLib._keyboardHandlers.push_back(handler); + } + + Common::Array<uint16> randResources = library._archive->getResourceIDList(ID_RAND); + for (uint i = 0; i < randResources.size(); i++) { + Common::SeekableReadStream *stream = library._archive->getResource(ID_RAND, randResources[i]); + Common::Array<RandomEvent> &events = _randomEvents[randResources[i]]; + uint16 count = stream->readUint16LE(); + for (uint j = 0; j < count; j++) { + RandomEvent random; + random.scriptId = stream->readUint16LE(); + random.weight = stream->readUint16LE(); + events.push_back(random); + } + delete stream; + } + // add background sprite, if it exists if (hasResource(ID_BMAP, 1000)) setBackground(1000); @@ -373,10 +482,9 @@ void ComposerEngine::unloadLibrary(uint id) { delete *j; } _anims.clear(); - for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) { - delete *j; - } - _pipes.clear(); + stopPipes(); + + _randomEvents.clear(); for (Common::List<Sprite>::iterator j = _sprites.begin(); j != _sprites.end(); j++) { j->_surface.free(); @@ -426,13 +534,14 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) { _type = stream->readUint16LE(); _active = (_type & 0x8000) ? true : false; + bool hasRollover = (gameType == GType_ComposerV1) && (_type & 0x4000); _type &= 0xfff; debug(9, "button %d: type %d, active %d", id, _type, _active); - uint16 flags = 0; uint16 size = 4; if (gameType == GType_ComposerV1) { - flags = stream->readUint16LE(); + stream->skip(2); + _zorder = 0; _scriptId = stream->readUint16LE(); _scriptIdRollOn = 0; @@ -469,7 +578,7 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) { error("unknown button type %d", _type); } - if (flags & 0x40) { + if (hasRollover) { _scriptIdRollOn = stream->readUint16LE(); _scriptIdRollOff = stream->readUint16LE(); } @@ -477,6 +586,26 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) { delete stream; } +// AMBI-style button +Button::Button(Common::SeekableReadStream *stream) { + _id = 0; + _zorder = 0; + _active = true; + _type = kButtonSprites; + _scriptIdRollOn = 0; + _scriptIdRollOff = 0; + + _scriptId = stream->readUint16LE(); + + uint16 count = stream->readUint16LE(); + for (uint j = 0; j < count; j++) { + uint16 spriteId = stream->readUint16LE(); + _spriteIds.push_back(spriteId); + } + + delete stream; +} + bool Button::contains(const Common::Point &pos) const { switch (_type) { case kButtonRect: @@ -524,4 +653,16 @@ const Button *ComposerEngine::getButtonFor(const Sprite *sprite, const Common::P return NULL; } +void ComposerEngine::setButtonActive(uint16 id, bool active) { + for (Common::List<Library>::iterator l = _libraries.begin(); l != _libraries.end(); l++) { + for (Common::List<Button>::iterator i = l->_buttons.begin(); i != l->_buttons.end(); i++) { + if (i->_id != id) + continue; + i->_active = active; + } + } + + onMouseMove(_lastMousePos); +} + } // End of namespace Composer diff --git a/engines/composer/composer.h b/engines/composer/composer.h index 03e895b59e..0f53258289 100644 --- a/engines/composer/composer.h +++ b/engines/composer/composer.h @@ -69,6 +69,7 @@ class Button { public: Button() { } Button(Common::SeekableReadStream *stream, uint16 id, uint gameType); + Button(Common::SeekableReadStream *stream); bool contains(const Common::Point &pos) const; @@ -94,11 +95,23 @@ enum { kEventKeyUp = 7 }; +struct KeyboardHandler { + uint16 keyId; + uint16 modifierId; + uint16 scriptId; +}; + +struct RandomEvent { + uint16 weight; + uint16 scriptId; +}; + struct Library { uint _id; Archive *_archive; Common::List<Button> _buttons; + Common::List<KeyboardHandler> _keyboardHandlers; }; struct QueuedScript { @@ -116,6 +129,19 @@ struct PendingPageChange { bool _remove; }; +struct OldScript { + OldScript(uint16 id, Common::SeekableReadStream *stream); + ~OldScript(); + + uint16 _id; + + uint32 _size; + Common::SeekableReadStream *_stream; + + uint16 _zorder; + uint32 _currDelay; +}; + class ComposerEngine : public Engine { protected: Common::Error run(); @@ -149,15 +175,20 @@ private: uint _directoriesToStrip; Common::ConfigFile _bookIni; + Common::String _bookGroup; Common::List<Library> _libraries; Common::Array<PendingPageChange> _pendingPageChanges; Common::Array<uint16> _stack; Common::Array<uint16> _vars; + Common::List<OldScript *> _oldScripts; Common::Array<QueuedScript> _queuedScripts; Common::List<Animation *> _anims; Common::List<Pipe *> _pipes; + Common::Array<Common::SeekableReadStream *> _pipeStreams; + + Common::HashMap<uint16, Common::Array<RandomEvent> > _randomEvents; void onMouseDown(const Common::Point &pos); void onMouseMove(const Common::Point &pos); @@ -188,17 +219,25 @@ private: void setArg(uint16 arg, uint16 type, uint16 val); void runScript(uint16 id); int16 scriptFuncCall(uint16 id, int16 param1, int16 param2, int16 param3); + void runOldScript(uint16 id, uint16 wait); + void stopOldScript(uint16 id); + void tickOldScripts(); + bool tickOldScript(OldScript *script); void playAnimation(uint16 animId, int16 param1, int16 param2, int16 param3); void stopAnimation(Animation *anim, bool localOnly = false, bool pipesOnly = false); void playWaveForAnim(uint16 id, uint16 priority, bool bufferingOnly); void processAnimFrame(); + void playPipe(uint16 id); + void stopPipes(); + bool spriteVisible(uint16 id, uint16 animId); Sprite *addSprite(uint16 id, uint16 animId, uint16 zorder, const Common::Point &pos); void removeSprite(uint16 id, uint16 animId); const Sprite *getSpriteAtPos(const Common::Point &pos); const Button *getButtonFor(const Sprite *sprite, const Common::Point &pos); + void setButtonActive(uint16 id, bool active); void dirtySprite(const Sprite &sprite); void redraw(); diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp index f253d85ad7..1314e903ae 100644 --- a/engines/composer/graphics.cpp +++ b/engines/composer/graphics.cpp @@ -123,8 +123,10 @@ void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventP // If the resource is a pipe itself, then load the pipe // and then fish the requested animation out of it. if (type != 1) { + _pipeStreams.push_back(stream); newPipe = new Pipe(stream); _pipes.push_front(newPipe); + newPipe->nextFrame(); stream = newPipe->getResource(ID_ANIM, animId, false); } } @@ -187,8 +189,10 @@ void ComposerEngine::playWaveForAnim(uint16 id, uint16 priority, bool bufferingO } } Common::SeekableReadStream *stream = NULL; + bool fromPipe = true; if (!bufferingOnly && hasResource(ID_WAVE, id)) { stream = getResource(ID_WAVE, id); + fromPipe = false; } else { for (Common::List<Pipe *>::iterator k = _pipes.begin(); k != _pipes.end(); k++) { Pipe *pipe = *k; @@ -200,12 +204,18 @@ void ComposerEngine::playWaveForAnim(uint16 id, uint16 priority, bool bufferingO } if (!stream) return; - // FIXME: non-pipe buffers have fixed wav header (data at +44, size at +40) - byte *buffer = (byte *)malloc(stream->size()); - stream->read(buffer, stream->size()); + + uint32 size = stream->size(); + if (!fromPipe) { + // non-pipe buffers have fixed wav header (data at +44, size at +40) + stream->skip(40); + size = stream->readUint32LE(); + } + byte *buffer = (byte *)malloc(size); + stream->read(buffer, size); if (!_audioStream) _audioStream = Audio::makeQueuingAudioStream(22050, false); - _audioStream->queueBuffer(buffer, stream->size(), DisposeAfterUse::YES, Audio::FLAG_UNSIGNED); + _audioStream->queueBuffer(buffer, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED); _currSoundPriority = priority; delete stream; if (!_mixer->isSoundHandleActive(_soundHandle)) @@ -351,9 +361,50 @@ void ComposerEngine::processAnimFrame() { for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) { Pipe *pipe = *j; pipe->nextFrame(); + + // V1 pipe audio; see OldPipe + if (pipe->hasResource(ID_WAVE, 0xffff)) + playWaveForAnim(0xffff, 0, false); } } +void ComposerEngine::playPipe(uint16 id) { + stopPipes(); + + if (!hasResource(ID_PIPE, id)) { + error("couldn't find pipe %d", id); + } + + Common::SeekableReadStream *stream = getResource(ID_PIPE, id); + OldPipe *pipe = new OldPipe(stream); + _pipes.push_front(pipe); + //pipe->nextFrame(); + + const Common::Array<uint16> *scripts = pipe->getScripts(); + if (scripts && !scripts->empty()) + runScript((*scripts)[0], 1, 0, 0); +} + +void ComposerEngine::stopPipes() { + for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) { + const Common::Array<uint16> *scripts = (*j)->getScripts(); + if (scripts) { + for (uint i = 0; i < scripts->size(); i++) { + removeSprite((*scripts)[i], 0); + stopOldScript((*scripts)[i]); + } + } + delete *j; + } + + _pipes.clear(); + + // substreams may need to remain valid until the end of a page + for (uint i = 0; i < _pipeStreams.size(); i++) + delete _pipeStreams[i]; + _pipeStreams.clear(); +} + bool ComposerEngine::spriteVisible(uint16 id, uint16 animId) { for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) { if (i->_id != id) @@ -375,7 +426,10 @@ Sprite *ComposerEngine::addSprite(uint16 id, uint16 animId, uint16 zorder, const for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) { if (i->_id != id) continue; - if (i->_animId && animId && (i->_animId != animId)) + if (getGameType() == GType_ComposerV1) { + if (i->_animId != animId) + continue; + } else if (i->_animId && animId && (i->_animId != animId)) continue; dirtySprite(*i); @@ -425,7 +479,10 @@ void ComposerEngine::removeSprite(uint16 id, uint16 animId) { for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) { if (!i->_id || (id && i->_id != id)) continue; - if (i->_animId && animId && (i->_animId != animId)) + if (getGameType() == GType_ComposerV1) { + if (i->_animId != animId) + continue; + } else if (i->_animId && animId && (i->_animId != animId)) continue; dirtySprite(*i); i->_surface.free(); @@ -499,8 +556,8 @@ void ComposerEngine::loadCTBL(uint16 id, uint fadePercent) { uint16 numEntries = stream->readUint16LE(); debug(1, "CTBL: %d entries", numEntries); - assert(numEntries <= 256); - assert(stream->size() == 2 + (numEntries * 3)); + if ((numEntries > 256) || (stream->size() < 2 + (numEntries * 3))) + error("CTBL %d was invalid (%d entries, size %d)", id, numEntries, stream->size()); byte buffer[256 * 3]; stream->read(buffer, numEntries * 3); diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp index b40bdb379b..a4e292747c 100644 --- a/engines/composer/resource.cpp +++ b/engines/composer/resource.cpp @@ -252,8 +252,9 @@ Pipe::Pipe(Common::SeekableReadStream *stream) { _offset = 0; _stream = stream; _anim = NULL; +} - nextFrame(); +Pipe::~Pipe() { } void Pipe::nextFrame() { @@ -334,4 +335,69 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES); } +OldPipe::OldPipe(Common::SeekableReadStream *stream) : Pipe(stream), _currFrame(0) { + uint32 tag = _stream->readUint32BE(); + if (tag != ID_PIPE) + error("invalid tag for pipe (%08x)", tag); + + _numFrames = _stream->readUint32LE(); + uint16 scriptCount = _stream->readUint16LE(); + _scripts.reserve(scriptCount); + for (uint i = 0; i < scriptCount; i++) + _scripts.push_back(_stream->readUint16LE()); + + _offset = _stream->pos(); +} + +void OldPipe::nextFrame() { + if (_currFrame >= _numFrames) + return; + + _stream->seek(_offset, SEEK_SET); + + uint32 tag = _stream->readUint32BE(); + if (tag != ID_FRME) + error("invalid tag for pipe (%08x)", tag); + + uint16 spriteCount = _stream->readUint16LE(); + uint32 spriteSize = _stream->readUint32LE(); + uint32 audioSize = _stream->readUint32LE(); + + Common::Array<uint16> spriteIds; + Common::Array<PipeResourceEntry> spriteEntries; + for (uint i = 0; i < spriteCount; i++) { + spriteIds.push_back(_stream->readUint16LE()); + PipeResourceEntry entry; + entry.size = _stream->readUint32LE(); + entry.offset = _stream->readUint32LE(); + spriteEntries.push_back(entry); + } + + uint32 spriteDataOffset = _stream->pos(); + _stream->skip(spriteSize); + + ResourceMap &spriteResMap = _types[ID_BMAP]; + spriteResMap.clear(); + for (uint i = 0; i < spriteIds.size(); i++) { + PipeResourceEntry &entry = spriteEntries[i]; + entry.offset += spriteDataOffset; + spriteResMap[spriteIds[i]].entries.push_back(entry); + } + + ResourceMap &audioResMap = _types[ID_WAVE]; + audioResMap.clear(); + + if (audioSize > 0) { + PipeResourceEntry entry; + entry.size = audioSize; + entry.offset = _stream->pos(); + // we use 0xffff for per-frame pipe audio + audioResMap[0xffff].entries.push_back(entry); + _stream->skip(audioSize); + } + + _offset = _stream->pos(); + _currFrame++; +} + } // End of namespace Composer diff --git a/engines/composer/resource.h b/engines/composer/resource.h index 9408cdffb8..e0052cd868 100644 --- a/engines/composer/resource.h +++ b/engines/composer/resource.h @@ -35,16 +35,21 @@ struct Animation; #define ID_LBRC MKTAG('L','B','R','C') // Main FourCC +#define ID_ACEL MKTAG('A','C','E','L') // Keyboard Accelerator (v1) +#define ID_AMBI MKTAG('A','M','B','I') // Ambient (v1 sprite button) #define ID_ANIM MKTAG('A','N','I','M') // Animation #define ID_BMAP MKTAG('B','M','A','P') // Bitmap #define ID_BUTN MKTAG('B','U','T','N') // Button #define ID_CTBL MKTAG('C','T','B','L') // Color Table #define ID_EVNT MKTAG('E','V','N','T') // Event #define ID_PIPE MKTAG('P','I','P','E') // Pipe +#define ID_RAND MKTAG('R','A','N','D') // Random Object #define ID_SCRP MKTAG('S','C','R','P') // Script #define ID_VARI MKTAG('V','A','R','I') // Variables #define ID_WAVE MKTAG('W','A','V','E') // Wave +#define ID_FRME MKTAG('F','R','M','E') // Frame + class Archive { public: Archive(); @@ -102,13 +107,16 @@ struct PipeResource { class Pipe { public: Pipe(Common::SeekableReadStream *stream); - void nextFrame(); + virtual ~Pipe(); + virtual void nextFrame(); Animation *_anim; bool hasResource(uint32 tag, uint16 id) const; Common::SeekableReadStream *getResource(uint32 tag, uint16 id, bool buffering); + virtual const Common::Array<uint16> *getScripts() { return NULL; } + protected: Common::SeekableReadStream *_stream; @@ -119,6 +127,18 @@ protected: uint32 _offset; }; +class OldPipe : public Pipe { +public: + OldPipe(Common::SeekableReadStream *stream); + void nextFrame(); + + const Common::Array<uint16> *getScripts() { return &_scripts; } + +protected: + uint32 _currFrame, _numFrames; + Common::Array<uint16> _scripts; +}; + } // End of namespace Composer #endif diff --git a/engines/composer/scripting.cpp b/engines/composer/scripting.cpp index 1989919233..3a201c841a 100644 --- a/engines/composer/scripting.cpp +++ b/engines/composer/scripting.cpp @@ -122,6 +122,11 @@ void ComposerEngine::runEvent(uint16 id, int16 param1, int16 param2, int16 param } int16 ComposerEngine::runScript(uint16 id, int16 param1, int16 param2, int16 param3) { + if (getGameType() == GType_ComposerV1) { + runOldScript(id, param1); + return 0; + } + _vars[1] = param1; _vars[2] = param2; _vars[3] = param3; @@ -155,10 +160,14 @@ void ComposerEngine::setArg(uint16 arg, uint16 type, uint16 val) { default: error("invalid argument type %d (setting arg %d)", type, arg); } - } void ComposerEngine::runScript(uint16 id) { + if (getGameType() == GType_ComposerV1) { + runOldScript(id, 0); + return; + } + if (!hasResource(ID_SCRP, id)) { debug(1, "ignoring attempt to run script %d, because it doesn't exist", id); return; @@ -561,25 +570,11 @@ int16 ComposerEngine::scriptFuncCall(uint16 id, int16 param1, int16 param2, int1 return 0; case kFuncActivateButton: debug(3, "kFuncActivateButton(%d)", param1); - for (Common::List<Library>::iterator l = _libraries.begin(); l != _libraries.end(); l++) { - for (Common::List<Button>::iterator i = l->_buttons.begin(); i != l->_buttons.end(); i++) { - if (i->_id != param1) - continue; - i->_active = true; - } - } - onMouseMove(_lastMousePos); + setButtonActive(param1, true); return 1; case kFuncDeactivateButton: debug(3, "kFuncDeactivateButton(%d)", param1); - for (Common::List<Library>::iterator l = _libraries.begin(); l != _libraries.end(); l++) { - for (Common::List<Button>::iterator i = l->_buttons.begin(); i != l->_buttons.end(); i++) { - if (i->_id != param1) - continue; - i->_active = false; - } - } - onMouseMove(_lastMousePos); + setButtonActive(param1, false); return 1; case kFuncNewPage: debug(3, "kFuncNewPage(%d, %d)", param1, param2); @@ -726,4 +721,235 @@ int16 ComposerEngine::scriptFuncCall(uint16 id, int16 param1, int16 param2, int1 } } +OldScript::OldScript(uint16 id, Common::SeekableReadStream *stream) : _id(id), _stream(stream) { + _size = _stream->readUint32LE(); + _stream->skip(2); + _currDelay = 0; + _zorder = 10; +} + +OldScript::~OldScript() { + delete _stream; +} + +void ComposerEngine::runOldScript(uint16 id, uint16 wait) { + stopOldScript(id); + + Common::SeekableReadStream *stream = getResource(ID_SCRP, id); + OldScript *script = new OldScript(id, stream); + script->_currDelay = wait; + _oldScripts.push_back(script); +} + +void ComposerEngine::stopOldScript(uint16 id) { + // FIXME: this could potentially (in the case of buggy script) be called on an in-use script + + for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) { + if ((*i)->_id == id) { + delete *i; + i = _oldScripts.reverse_erase(i); + } + } +} + +void ComposerEngine::tickOldScripts() { + for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) { + if (!tickOldScript(*i)) { + delete *i; + i = _oldScripts.reverse_erase(i); + } + } +} + +enum { + kOldOpNoOp = 0, + kOldOpReplaceSprite = 1, + kOldOpPlayWav = 2, + kOldOpRunScript = 3, + kOldOpStopScript = 4, + kOldOpActivateButton = 5, + kOldOpDeactivateButton = 6, + kOldOpDrawSprite = 7, + kOldOpRemoveSprite = 8, + kOldOpDisableMouseInput = 9, + kOldOpEnableMouseInput = 10, + kOldOpWait = 11, + kOldOpRandWait = 12, + kOldOpDrawGlobalSprite = 13, + kOldOpRemoveGlobalSprite = 14, + kOldOpSetZOrder = 15, + kOldOpPlayPipe = 16, + kOldOpStopPipe = 17, + kOldOpNewScreen = 20, + kOldOpRunRandom = 22 +}; + +bool ComposerEngine::tickOldScript(OldScript *script) { + if (script->_currDelay) { + script->_currDelay--; + return true; + } + + bool running = true; + bool erasedOldSprite = false; + while (running && script->_stream->pos() < (int)script->_size) { + uint16 spriteId, scriptId, buttonId, pipeId; + Common::Point spritePos; + + script->_stream->skip(0); + byte op = script->_stream->readByte(); + switch (op) { + case kOldOpNoOp: + debug(3, "kOldOpNoOp()"); + running = false; + break; + case kOldOpReplaceSprite: + if (!erasedOldSprite) { + removeSprite(0, script->_id); + erasedOldSprite = true; + } + + spriteId = script->_stream->readUint16LE(); + spritePos.x = script->_stream->readSint16LE(); + spritePos.y = script->_stream->readSint16LE(); + debug(3, "kOldOpReplaceSprite(%d, %d, %d)", spriteId, spritePos.x, spritePos.y); + addSprite(spriteId, script->_id, script->_zorder, spritePos); + break; + case kOldOpPlayWav: + uint16 wavId, prio; + wavId = script->_stream->readUint16LE(); + prio = script->_stream->readUint16LE(); + debug(3, "kOldOpPlayWav(%d, %d)", wavId, prio); + playWaveForAnim(wavId, prio, false); + break; + case kOldOpRunScript: + scriptId = script->_stream->readUint16LE(); + debug(3, "kOldOpRunScript(%d)", scriptId); + if (scriptId == script->_id) { + // reset ourselves + removeSprite(0, script->_id); + script->_stream->seek(6); + } else { + runScript(scriptId); + } + break; + case kOldOpStopScript: + scriptId = script->_stream->readUint16LE(); + debug(3, "kOldOpStopScript(%d)", scriptId); + removeSprite(0, scriptId); + stopOldScript(scriptId); + break; + case kOldOpActivateButton: + buttonId = script->_stream->readUint16LE(); + debug(3, "kOldOpActivateButton(%d)", buttonId); + setButtonActive(buttonId, true); + break; + case kOldOpDeactivateButton: + buttonId = script->_stream->readUint16LE(); + debug(3, "kOldOpDeactivateButton(%d)", buttonId); + setButtonActive(buttonId, false); + break; + case kOldOpDrawSprite: + spriteId = script->_stream->readUint16LE(); + spritePos.x = script->_stream->readSint16LE(); + spritePos.y = script->_stream->readSint16LE(); + debug(3, "kOldOpDrawSprite(%d, %d, %d)", spriteId, spritePos.x, spritePos.y); + addSprite(spriteId, script->_id, script->_zorder, spritePos); + break; + case kOldOpRemoveSprite: + spriteId = script->_stream->readUint16LE(); + debug(3, "kOldOpRemoveSprite(%d)", spriteId); + removeSprite(spriteId, script->_id); + break; + case kOldOpDisableMouseInput: + debug(3, "kOldOpDisableMouseInput()"); + setCursorVisible(false); + break; + case kOldOpEnableMouseInput: + debug(3, "kOldOpEnableMouseInput()"); + setCursorVisible(true); + break; + case kOldOpWait: + script->_currDelay = script->_stream->readUint16LE(); + debug(3, "kOldOpWait(%d)", script->_currDelay); + break; + case kOldOpRandWait: + uint16 min, max; + min = script->_stream->readUint16LE(); + max = script->_stream->readUint16LE(); + debug(3, "kOldOpRandWait(%d, %d)", min, max); + script->_currDelay = _rnd->getRandomNumberRng(min, max); + break; + case kOldOpDrawGlobalSprite: + spriteId = script->_stream->readUint16LE(); + spritePos.x = script->_stream->readSint16LE(); + spritePos.y = script->_stream->readSint16LE(); + debug(3, "kOldOpDrawGlobalSprite(%d, %d, %d)", spriteId, spritePos.x, spritePos.y); + addSprite(spriteId, 0, script->_zorder, spritePos); + break; + case kOldOpRemoveGlobalSprite: + spriteId = script->_stream->readUint16LE(); + debug(3, "kOldOpRemoveGlobalSprite(%d)", spriteId); + removeSprite(spriteId, 0); + break; + case kOldOpSetZOrder: + script->_zorder = script->_stream->readUint16LE(); + debug(3, "kOldOpSetZOrder(%d)", script->_zorder); + break; + case kOldOpPlayPipe: + pipeId = script->_stream->readUint16LE(); + debug(3, "kOldOpPlayPipe(%d)", pipeId); + playPipe(pipeId); + break; + case kOldOpStopPipe: + pipeId = script->_stream->readUint16LE(); + debug(3, "kOldOpStopPipe(%d)", pipeId); + // yes, pipeId is ignored here.. + stopPipes(); + break; + case kOldOpNewScreen: + uint16 newScreenId; + newScreenId = script->_stream->readUint16LE(); + debug(3, "kOldOpNewScreen(%d)", newScreenId); + if (!newScreenId) { + quitGame(); + } else { + _pendingPageChanges.clear(); + _pendingPageChanges.push_back(PendingPageChange(newScreenId, false)); + } + break; + case kOldOpRunRandom: + uint16 randomId; + randomId = script->_stream->readUint16LE(); + debug(3, "kOldOpRunRandom(%d)", randomId); + if (!_randomEvents.contains(randomId)) { + warning("kOldOpRunRandom found no entries for id %d", randomId); + } else { + uint32 randValue = _rnd->getRandomNumberRng(0, 32767); + const Common::Array<RandomEvent> &events = _randomEvents[randomId]; + uint i = 0; + for (i = 0; i < events.size(); i++) { + if ((i + 1 == events.size()) || (randValue <= events[i].weight)) { + runScript(events[i].scriptId); + break; + } else { + randValue -= events[i].weight; + } + } + } + break; + default: + error("unknown oldScript op %d", op); + } + } + + if (script->_stream->pos() >= (int)script->_size) { + // stop running if we ran out of script + removeSprite(0, script->_id); + return false; + } + + return true; +} + } // End of namespace Composer diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp index d0340238cd..a1337aefa7 100644 --- a/engines/cruise/cruise_main.cpp +++ b/engines/cruise/cruise_main.cpp @@ -998,7 +998,7 @@ bool findRelation(int objOvl, int objIdx, int x, int y) { ovlDataStruct *ovl2 = NULL; ovlDataStruct *ovl3 = NULL; - ovlDataStruct *ovl4 = NULL; + //ovlDataStruct *ovl4 = NULL; if (verbeOvl > 0) ovl2 = overlayTable[verbeOvl].ovlData; @@ -1006,8 +1006,8 @@ bool findRelation(int objOvl, int objIdx, int x, int y) { if (obj1Ovl > 0) ovl3 = overlayTable[obj1Ovl].ovlData; - if (obj2Ovl > 0) - ovl4 = overlayTable[obj2Ovl].ovlData; + //if (obj2Ovl > 0) + // ovl4 = overlayTable[obj2Ovl].ovlData; if ((ovl3) && (ptrHead->obj1Number >= 0)) { testState = ptrHead->obj1OldState; diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp index a482e263a2..eb7c1c524f 100644 --- a/engines/cruise/detection.cpp +++ b/engines/cruise/detection.cpp @@ -75,7 +75,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::EN_GRB, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -88,7 +88,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -101,7 +101,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -114,7 +114,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -127,7 +127,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -140,7 +140,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -153,7 +153,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -166,7 +166,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -179,7 +179,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformAtariST, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -192,7 +192,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, @@ -205,7 +205,7 @@ static const CRUISEGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GType_CRUISE, 0, diff --git a/engines/cruise/gfxModule.cpp b/engines/cruise/gfxModule.cpp index 7bbcae2259..aa2dbc5370 100644 --- a/engines/cruise/gfxModule.cpp +++ b/engines/cruise/gfxModule.cpp @@ -326,7 +326,7 @@ void flip() { void drawSolidBox(int32 x1, int32 y1, int32 x2, int32 y2, uint8 color) { for (int y = y1; y < y2; ++y) { byte *p = &gfxModuleData.pPage00[y * 320 + x1]; - Common::set_to(p, p + (x2 - x1), color); + Common::fill(p, p + (x2 - x1), color); } } diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp index 14b6daf4bb..9a5df69cae 100644 --- a/engines/cruise/mainDraw.cpp +++ b/engines/cruise/mainDraw.cpp @@ -621,11 +621,9 @@ void buildSegment() { unsigned char *drawPolyMode1(unsigned char *dataPointer, int linesToDraw) { int index; - int16 *pBufferDest; + int16 *pBufferDest = polyBuffer4 + nbseg * 2; - pBufferDest = polyBuffer4 + nbseg * 2; nbseg = linesToDraw; - A2ptr = polyBuffer4; index = *(dataPointer++); polyXMin = polyXMax = pBufferDest[-2] = pBufferDest[-2 + linesToDraw * 2] = polyBuffer2[index * 2]; diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp index 2f4b375865..d618ab5599 100644 --- a/engines/cruise/overlay.cpp +++ b/engines/cruise/overlay.cpp @@ -185,11 +185,10 @@ int loadOverlay(const char *scriptName) { // This memory block will be later passed to a MemoryReadStream, which will dispose of it unpackedBuffer = (byte *)malloc(unpackedSize); - memset(unpackedBuffer, 0, unpackedSize); - if (!unpackedBuffer) { return (-2); } + memset(unpackedBuffer, 0, unpackedSize); if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) { char *pakedBuffer = @@ -566,11 +565,10 @@ int loadOverlay(const char *scriptName) { // This memory block will be later passed to a MemoryReadStream, which will dispose of it unpackedBuffer = (byte *)malloc(unpackedSize); - memset(unpackedBuffer, 0, unpackedSize); - if (!unpackedBuffer) { return (-2); } + memset(unpackedBuffer, 0, unpackedSize); if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) { diff --git a/engines/cruise/volume.cpp b/engines/cruise/volume.cpp index 773a146b9a..4b64d4ff77 100644 --- a/engines/cruise/volume.cpp +++ b/engines/cruise/volume.cpp @@ -326,7 +326,7 @@ int closeCnf() { int16 readVolCnf() { int i; Common::File fileHandle; - short int sizeHEntry; + //short int sizeHEntry; volumeDataLoaded = 0; @@ -344,7 +344,7 @@ int16 readVolCnf() { } numOfDisks = fileHandle.readSint16BE(); - sizeHEntry = fileHandle.readSint16BE(); // size of one header entry - 20 bytes + /*sizeHEntry =*/ fileHandle.readSint16BE(); // size of one header entry - 20 bytes for (i = 0; i < numOfDisks; i++) { // fread(&volumeData[i],20,1,fileHandle); diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp index e483e8ca9f..de76eb83e0 100644 --- a/engines/draci/detection.cpp +++ b/engines/draci/detection.cpp @@ -43,7 +43,7 @@ const ADGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { @@ -53,7 +53,7 @@ const ADGameDescription gameDescriptions[] = { Common::CZ_CZE, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { @@ -63,7 +63,7 @@ const ADGameDescription gameDescriptions[] = { Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { @@ -73,7 +73,7 @@ const ADGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, AD_TABLE_END_MARKER diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index 67e043632e..6aa8477887 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -359,10 +359,11 @@ void DraciEngine::handleEvents() { DraciEngine::~DraciEngine() { // Dispose your resources here - // If the common library supported STL's scoped_ptr<>, then wrapping + // If the common library supported Boost's scoped_ptr<>, then wrapping // all the following pointers and many more would be appropriate. So // far, there is only SharedPtr, which I feel being an overkill for // easy deallocation. + // TODO: We have ScopedPtr nowadays. Maybe should adapt this code then? delete _smallFont; delete _bigFont; diff --git a/engines/draci/saveload.cpp b/engines/draci/saveload.cpp index b3bf0cbcd8..e3551c78b3 100644 --- a/engines/draci/saveload.cpp +++ b/engines/draci/saveload.cpp @@ -41,7 +41,7 @@ bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) { // Validate the header Id in->read(saveIdentBuffer, 6); - if (strcmp(saveIdentBuffer, draciIdentString)) + if (strcmp(saveIdentBuffer, draciIdentString) != 0) return false; header.version = in->readByte(); diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp index 6f028e6e12..7abbb3214b 100644 --- a/engines/drascula/converse.cpp +++ b/engines/drascula/converse.cpp @@ -197,7 +197,7 @@ void DrasculaEngine::converse(int index) { // from 1(top) to 31 color_abc(kColorLightGreen); - while (breakOut == 0) { + while (breakOut == 0 && !shouldQuit()) { updateRoom(); if (musicStatus() == 0 && roomMusic != 0) { diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp index 0969ad4131..3310ac0598 100644 --- a/engines/drascula/detection.cpp +++ b/engines/drascula/detection.cpp @@ -73,7 +73,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -93,7 +93,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -110,7 +110,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -127,7 +127,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -140,7 +140,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -153,7 +153,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -166,7 +166,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -179,7 +179,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -192,7 +192,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, { @@ -204,7 +204,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -221,7 +221,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -238,7 +238,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -255,7 +255,7 @@ static const DrasculaGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, }, diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp index b4f009eb44..1b3c4038f0 100644 --- a/engines/drascula/drascula.cpp +++ b/engines/drascula/drascula.cpp @@ -789,7 +789,7 @@ void DrasculaEngine::delay(int ms) { _system->delayMillis(10); updateEvents(); _system->updateScreen(); - } while (_system->getMillis() < end); + } while (_system->getMillis() < end && !shouldQuit()); } void DrasculaEngine::pause(int duration) { @@ -882,7 +882,7 @@ bool DrasculaEngine::loadDrasculaDat() { in.read(buf, 8); buf[8] = '\0'; - if (strcmp(buf, "DRASCULA")) { + if (strcmp(buf, "DRASCULA") != 0) { Common::String errorMessage = "File 'drascula.dat' is corrupt. Get it from the ScummVM website"; GUIErrorMessage(errorMessage); warning("%s", errorMessage.c_str()); diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp index 9ea20e3e12..f9f6c1f58c 100644 --- a/engines/drascula/graphics.cpp +++ b/engines/drascula/graphics.cpp @@ -361,7 +361,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) { curWord = strtok(msg, " "); while (curWord != NULL) { // Check if the word and the current line fit on screen - if (strlen(tmpMessageLine) > 0) + if (tmpMessageLine[0] != '\0') strcat(tmpMessageLine, " "); strcat(tmpMessageLine, curWord); if (textFitsCentered(tmpMessageLine, textX)) { @@ -643,7 +643,7 @@ void DrasculaEngine::waitFrameSSN() { } bool DrasculaEngine::animate(const char *animationFile, int FPS) { - int NFrames = 1; + int NFrames; int cnt = 2; Common::SeekableReadStream *stream = _archives.open(animationFile); diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp index e3a97087c0..5e4f7a1541 100644 --- a/engines/drascula/interface.cpp +++ b/engines/drascula/interface.cpp @@ -100,9 +100,18 @@ bool DrasculaEngine::confirmExit() { key = getScan(); if (key != 0) break; + + // This gives a better feedback to the user when he is asked to + // confirm whether he wants to quit. It now still updates the room and + // shows mouse cursor movement. Hopefully it will work in all + // locations of the game. + updateRoom(); + color_abc(kColorRed); + centerText(_textsys[1], 160, 87); + updateScreen(); } - if (key == Common::KEYCODE_ESCAPE) { + if (key == Common::KEYCODE_ESCAPE || shouldQuit()) { stopMusic(); return false; } diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp index c8622f3c92..35e3821dc4 100644 --- a/engines/drascula/saveload.cpp +++ b/engines/drascula/saveload.cpp @@ -123,7 +123,7 @@ bool DrasculaEngine::saveLoadScreen() { if (mouseX > 115 && mouseY > y + (9 * n) && mouseX < 115 + 175 && mouseY < y + 10 + (9 * n)) { strcpy(select, _saveNames[n]); - if (strcmp(select, "*")) + if (strcmp(select, "*") != 0) selectionMade = 1; else { enterName(); diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp index 413a631118..112f6fd06c 100644 --- a/engines/drascula/sound.cpp +++ b/engines/drascula/sound.cpp @@ -26,6 +26,7 @@ #include "common/config-manager.h" #include "common/textconsole.h" +#include "common/substream.h" #include "backends/audiocd/audiocd.h" @@ -78,6 +79,8 @@ void DrasculaEngine::volumeControls() { ; if (rightMouseButton == 1) { + // Clear this to avoid going straight to the inventory + rightMouseButton = 0; delay(100); break; } @@ -163,29 +166,28 @@ void DrasculaEngine::MusicFadeout() { void DrasculaEngine::playFile(const char *fname) { Common::SeekableReadStream *stream = _archives.open(fname); if (stream) { - int soundSize = stream->size(); - byte *soundData = (byte *)malloc(soundSize); + int startOffset = 0; + int soundSize = stream->size() - startOffset; - if (!(!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish)) { - stream->seek(32); - } else { + if (!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish) { // WORKAROUND: File 3.als with English speech files has a big silence at // its beginning and end. We seek past the silence at the beginning, // and ignore the silence at the end // Fixes bug #2111815 - "DRASCULA: Voice delayed" - stream->seek(73959, SEEK_SET); - soundSize = 117158 - 73959; + startOffset = 73959; + soundSize = soundSize - startOffset - 26306; } - stream->read(soundData, soundSize); - delete stream; - - _subtitlesDisabled = !ConfMan.getBool("subtitles"); - if (ConfMan.getBool("speech_mute")) - memset(soundData, 0x80, soundSize); // Mute speech but keep the pause + Common::SeekableReadStream *subStream = new Common::SeekableSubReadStream( + stream, startOffset, startOffset + soundSize, DisposeAfterUse::YES); + if (!subStream) { + warning("playFile: Out of memory"); + delete stream; + return; + } - Audio::AudioStream *sound = Audio::makeRawStream(soundData, soundSize - 64, - 11025, Audio::FLAG_UNSIGNED); + Audio::AudioStream *sound = Audio::makeRawStream(subStream, 11025, + Audio::FLAG_UNSIGNED); _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, sound); } else warning("playFile: Could not open %s", fname); diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp index 6d1509fe3c..c97191fc0a 100644 --- a/engines/drascula/talk.cpp +++ b/engines/drascula/talk.cpp @@ -34,6 +34,11 @@ void DrasculaEngine::talkInit(const char *filename) { } bool DrasculaEngine::isTalkFinished() { + if (shouldQuit()) { + stopSound(); + return true; + } + if (getScan() != 0) stopSound(); if (soundIsActive()) diff --git a/engines/dreamweb/detection_tables.h b/engines/dreamweb/detection_tables.h index 0902236916..75f5786268 100644 --- a/engines/dreamweb/detection_tables.h +++ b/engines/dreamweb/detection_tables.h @@ -39,7 +39,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -56,7 +56,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -73,7 +73,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::EN_USA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -90,7 +90,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -107,7 +107,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -124,7 +124,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -141,7 +141,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -158,7 +158,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, @@ -175,7 +175,7 @@ static const DreamWebGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, }, diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp index 8f4b4cea21..24c804e51d 100644 --- a/engines/dreamweb/dreamgen.cpp +++ b/engines/dreamweb/dreamgen.cpp @@ -1716,179 +1716,6 @@ void DreamGenContext::priesttext() { setuptimeduse(); } -void DreamGenContext::textforend() { - STACK_CHECK; - _cmp(data.byte(kIntrocount), 20); - if (!flags.z()) - goto notendtext1; - al = 0; - bl = 34; - bh = 20; - cx = 60; - goto gotendtext; -notendtext1: - _cmp(data.byte(kIntrocount), 50); - if (!flags.z()) - goto notendtext2; - al = 1; - bl = 34; - bh = 20; - cx = 60; - goto gotendtext; -notendtext2: - _cmp(data.byte(kIntrocount), 85); - if (!flags.z()) - return /* (notendtext3) */; - al = 2; - bl = 34; - bh = 20; - cx = 60; - goto gotendtext; - return; -gotendtext: - dx = 1; - ah = 83; - setuptimedtemp(); -} - -void DreamGenContext::textformonk() { - STACK_CHECK; - _cmp(data.byte(kIntrocount), 1); - if (!flags.z()) - goto notmonktext1; - al = 19; - bl = 68; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext1: - _cmp(data.byte(kIntrocount), 5); - if (!flags.z()) - goto notmonktext2; - al = 20; - bl = 68; - bh = 38; - cx = 120; - goto gotmonktext; -notmonktext2: - _cmp(data.byte(kIntrocount), 9); - if (!flags.z()) - goto notmonktext3; - al = 21; - bl = 48; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext3: - _cmp(data.byte(kIntrocount), 13); - if (!flags.z()) - goto notmonktext4; - al = 22; - bl = 68; - bh = 38; - cx = 120; - goto gotmonktext; -notmonktext4: - _cmp(data.byte(kIntrocount), 15); - if (!flags.z()) - goto notmonktext5; - al = 23; - bl = 68; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext5: - _cmp(data.byte(kIntrocount), 21); - if (!flags.z()) - goto notmonktext6; - al = 24; - bl = 68; - bh = 38; - cx = 120; - goto gotmonktext; -notmonktext6: - _cmp(data.byte(kIntrocount), 25); - if (!flags.z()) - goto notmonktext7; - al = 25; - bl = 68; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext7: - _cmp(data.byte(kIntrocount), 29); - if (!flags.z()) - goto notmonktext8; - al = 26; - bl = 68; - bh = 38; - cx = 120; - goto gotmonktext; -notmonktext8: - _cmp(data.byte(kIntrocount), 33); - if (!flags.z()) - goto notmonktext9; - al = 27; - bl = 68; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext9: - _cmp(data.byte(kIntrocount), 37); - if (!flags.z()) - goto notmonktext10; - al = 28; - bl = 68; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext10: - _cmp(data.byte(kIntrocount), 41); - if (!flags.z()) - goto notmonktext11; - al = 29; - bl = 68; - bh = 38; - cx = 120; - goto gotmonktext; -notmonktext11: - _cmp(data.byte(kIntrocount), 45); - if (!flags.z()) - goto notmonktext12; - al = 30; - bl = 68; - bh = 154; - cx = 120; - goto gotmonktext; -notmonktext12: - _cmp(data.byte(kIntrocount), 52); - if (!flags.z()) - goto notmonktext13; - al = 31; - bl = 68; - bh = 154; - cx = 220; - goto gotmonktext; -notmonktext13: - _cmp(data.byte(kIntrocount), 53); - if (!flags.z()) - return /* (notendtitles) */; - fadescreendowns(); - data.byte(kVolumeto) = 7; - data.byte(kVolumedirection) = 1; - return; -gotmonktext: - dx = 1; - ah = 82; - _cmp(data.byte(kCh1playing), 255); - if (flags.z()) - goto oktalk; - _dec(data.byte(kIntrocount)); - return; -oktalk: - setuptimedtemp(); -} - void DreamGenContext::drunk() { STACK_CHECK; _cmp(data.byte(kGeneraldead), 0); @@ -2262,129 +2089,6 @@ forgotone: setuptimeduse(); } -void DreamGenContext::initrain() { - STACK_CHECK; - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30)); - bx = offset_rainlocations; -checkmorerain: - al = cs.byte(bx); - _cmp(al, 255); - if (flags.z()) - goto finishinitrain; - _cmp(al, data.byte(kReallocation)); - if (!flags.z()) - goto checkrain; - al = cs.byte(bx+1); - _cmp(al, data.byte(kMapx)); - if (!flags.z()) - goto checkrain; - al = cs.byte(bx+2); - _cmp(al, data.byte(kMapy)); - if (!flags.z()) - goto checkrain; - al = cs.byte(bx+3); - data.byte(kRainspace) = al; - goto dorain; -checkrain: - _add(bx, 4); - goto checkmorerain; -dorain: - cx = 4; -initraintop: - randomnumber(); - _and(al, 31); - _add(al, 3); - _cmp(al, data.byte(kRainspace)); - if (!flags.c()) - goto initraintop; - _add(cl, al); - _cmp(cl, data.byte(kMapxsize)); - if (!flags.c()) - goto initrainside; - push(cx); - splitintolines(); - cx = pop(); - goto initraintop; -initrainside: - cl = data.byte(kMapxsize); - _dec(cl); -initrainside2: - randomnumber(); - _and(al, 31); - _add(al, 3); - _cmp(al, data.byte(kRainspace)); - if (!flags.c()) - goto initrainside2; - _add(ch, al); - _cmp(ch, data.byte(kMapysize)); - if (!flags.c()) - goto finishinitrain; - push(cx); - splitintolines(); - cx = pop(); - goto initrainside2; -finishinitrain: - al = 255; - _stosb(); -} - -void DreamGenContext::splitintolines() { - STACK_CHECK; -lookforlinestart: - getblockofpixel(); - _cmp(al, 0); - if (!flags.z()) - goto foundlinestart; - _dec(cl); - _inc(ch); - _cmp(cl, 0); - if (flags.z()) - return /* (endofthisline) */; - _cmp(ch, data.byte(kMapysize)); - if (!flags.c()) - return /* (endofthisline) */; - goto lookforlinestart; -foundlinestart: - es.word(di) = cx; - bh = 1; -lookforlineend: - getblockofpixel(); - _cmp(al, 0); - if (flags.z()) - goto foundlineend; - _dec(cl); - _inc(ch); - _cmp(cl, 0); - if (flags.z()) - goto foundlineend; - _cmp(ch, data.byte(kMapysize)); - if (!flags.c()) - goto foundlineend; - _inc(bh); - goto lookforlineend; -foundlineend: - push(cx); - es.byte(di+2) = bh; - randomnumber(); - es.byte(di+3) = al; - randomnumber(); - es.byte(di+4) = al; - randomnumber(); - _and(al, 3); - _add(al, 4); - es.byte(di+5) = al; - _add(di, 6); - cx = pop(); - _cmp(cl, 0); - if (flags.z()) - return /* (endofthisline) */; - _cmp(ch, data.byte(kMapysize)); - if (!flags.c()) - return /* (endofthisline) */; - goto lookforlinestart; -} - void DreamGenContext::liftnoise() { STACK_CHECK; _cmp(data.byte(kReallocation), 5); @@ -2528,45 +2232,6 @@ bigroom: _add(data.byte(kMapysize), 8); } -void DreamGenContext::loadpalfromiff() { - STACK_CHECK; - dx = 2481; - openfile(); - cx = 2000; - ds = data.word(kMapstore); - dx = 0; - readfromfile(); - closefile(); - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768); - ds = data.word(kMapstore); - si = 0x30; - cx = 768; -palloop: - _lodsb(); - _shr(al, 1); - _shr(al, 1); - _cmp(data.byte(kBrightness), 1); - if (!flags.z()) - goto nought; - _cmp(al, 0); - if (flags.z()) - goto nought; - ah = al; - _shr(ah, 1); - _add(al, ah); - _shr(ah, 1); - _add(al, ah); - _cmp(al, 64); - if (flags.c()) - goto nought; - al = 63; -nought: - _stosb(); - if (--cx) - goto palloop; -} - void DreamGenContext::createpanel() { STACK_CHECK; di = 0; @@ -2683,15 +2348,6 @@ void DreamGenContext::dofade() { fadecalculation(); } -void DreamGenContext::clearendpal() { - STACK_CHECK; - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - cx = 768; - al = 0; - _stosb(cx, true); -} - void DreamGenContext::clearpalette() { STACK_CHECK; data.byte(kFadedirection) = 0; @@ -2813,20 +2469,6 @@ void DreamGenContext::fadescreendowns() { data.byte(kNumtofade) = 64; } -void DreamGenContext::clearstartpal() { - STACK_CHECK; - es = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)); - cx = 256; -wholeloop1: - ax = 0; - _stosw(); - al = 0; - _stosb(); - if (--cx) - goto wholeloop1; -} - void DreamGenContext::showgun() { STACK_CHECK; data.byte(kAddtored) = 0; @@ -2980,45 +2622,6 @@ endearly2: cx = pop(); } -void DreamGenContext::fadecalculation() { - STACK_CHECK; - _cmp(data.byte(kFadecount), 0); - if (flags.z()) - goto nomorefading; - bl = data.byte(kFadecount); - es = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - cx = 768; -fadecolloop: - al = es.byte(si); - ah = es.byte(di); - _cmp(al, ah); - if (flags.z()) - goto gotthere; - if (flags.c()) - goto lesscolour; - _dec(es.byte(si)); - goto gotthere; -lesscolour: - _cmp(bl, ah); - if (flags.z()) - goto withit; - if (!flags.c()) - goto gotthere; -withit: - _inc(es.byte(si)); -gotthere: - _inc(si); - _inc(di); - if (--cx) - goto fadecolloop; - _dec(data.byte(kFadecount)); - return; -nomorefading: - data.byte(kFadedirection) = 0; -} - void DreamGenContext::greyscalesum() { STACK_CHECK; es = data.word(kBuffers); @@ -3077,46 +2680,6 @@ noaddb: goto greysumloop1; } -void DreamGenContext::paltostartpal() { - STACK_CHECK; - es = data.word(kBuffers); - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)); - cx = 768/2; - _movsw(cx, true); -} - -void DreamGenContext::endpaltostart() { - STACK_CHECK; - es = data.word(kBuffers); - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)); - cx = 768/2; - _movsw(cx, true); -} - -void DreamGenContext::startpaltoend() { - STACK_CHECK; - es = data.word(kBuffers); - ds = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)); - cx = 768/2; - _movsw(cx, true); -} - -void DreamGenContext::paltoendpal() { - STACK_CHECK; - es = data.word(kBuffers); - ds = data.word(kBuffers); - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768); - cx = 768/2; - _movsw(cx, true); -} - void DreamGenContext::allpalette() { STACK_CHECK; es = data.word(kBuffers); @@ -3851,81 +3414,6 @@ findopen2a: goto findopen1a; } -void DreamGenContext::examineob() { - STACK_CHECK; - data.byte(kPointermode) = 0; - data.word(kTimecount) = 0; -examineagain: - data.byte(kInmaparea) = 0; - data.byte(kExamagain) = 0; - data.byte(kOpenedob) = 255; - data.byte(kOpenedtype) = 255; - data.byte(kInvopen) = 0; - al = data.byte(kCommandtype); - data.byte(kObjecttype) = al; - data.byte(kItemframe) = 0; - data.byte(kPointerframe) = 0; - createpanel(); - showpanel(); - showman(); - showexit(); - obicons(); - obpicture(); - describeob(); - undertextline(); - data.byte(kCommandtype) = 255; - readmouse(); - showpointer(); - worktoscreen(); - delpointer(); -waitexam: - readmouse(); - showpointer(); - vsync(); - dumppointer(); - dumptextline(); - delpointer(); - data.byte(kGetback) = 0; - bx = offset_examlist; - _cmp(data.byte(kInvopen), 0); - if (flags.z()) - goto notuseinv; - bx = offset_invlist1; - _cmp(data.byte(kInvopen), 1); - if (flags.z()) - goto notuseinv; - bx = offset_withlist1; -notuseinv: - checkcoords(); - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - goto stopwaiting; - _cmp(data.byte(kExamagain), 0); - if (flags.z()) - goto norex; - goto examineagain; -norex: - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto waitexam; -stopwaiting: - data.byte(kPickup) = 0; - _cmp(data.word(kWatchingtime), 0); - if (!flags.z()) - goto iswatching; - _cmp(data.byte(kNewlocation), 255); - if (!flags.z()) - goto justgetback; -iswatching: - makemainscreen(); - data.byte(kInvopen) = 0; - data.byte(kOpenedob) = 255; - return; -justgetback: - data.byte(kInvopen) = 0; - data.byte(kOpenedob) = 255; -} - void DreamGenContext::makemainscreen() { STACK_CHECK; createpanel(); @@ -4233,126 +3721,6 @@ foundmatch: bx = pop(); } -void DreamGenContext::inventory() { - STACK_CHECK; - _cmp(data.byte(kMandead), 1); - if (flags.z()) - goto iswatchinv; - _cmp(data.word(kWatchingtime), 0); - if (flags.z()) - goto notwatchinv; -iswatchinv: - blank(); - return; -notwatchinv: - _cmp(data.byte(kCommandtype), 239); - if (flags.z()) - goto alreadyopinv; - data.byte(kCommandtype) = 239; - al = 32; - commandonly(); -alreadyopinv: - ax = data.word(kMousebutton); - _cmp(ax, data.word(kOldbutton)); - if (flags.z()) - return /* (cantopinv) */; - _and(ax, 1); - if (!flags.z()) - goto doopeninv; - return; -doopeninv: - data.word(kTimecount) = 0; - data.byte(kPointermode) = 0; - data.byte(kInmaparea) = 0; - animpointer(); - createpanel(); - showpanel(); - examicon(); - showman(); - showexit(); - undertextline(); - data.byte(kPickup) = 0; - data.byte(kInvopen) = 2; - openinv(); - readmouse(); - showpointer(); - worktoscreen(); - delpointer(); - data.byte(kOpenedob) = 255; - goto waitexam; - return; -/*continuing to unbounded code: examineagain from examineob:3-69*/ -examineagain: - data.byte(kInmaparea) = 0; - data.byte(kExamagain) = 0; - data.byte(kOpenedob) = 255; - data.byte(kOpenedtype) = 255; - data.byte(kInvopen) = 0; - al = data.byte(kCommandtype); - data.byte(kObjecttype) = al; - data.byte(kItemframe) = 0; - data.byte(kPointerframe) = 0; - createpanel(); - showpanel(); - showman(); - showexit(); - obicons(); - obpicture(); - describeob(); - undertextline(); - data.byte(kCommandtype) = 255; - readmouse(); - showpointer(); - worktoscreen(); - delpointer(); -waitexam: - readmouse(); - showpointer(); - vsync(); - dumppointer(); - dumptextline(); - delpointer(); - data.byte(kGetback) = 0; - bx = offset_examlist; - _cmp(data.byte(kInvopen), 0); - if (flags.z()) - goto notuseinv; - bx = offset_invlist1; - _cmp(data.byte(kInvopen), 1); - if (flags.z()) - goto notuseinv; - bx = offset_withlist1; -notuseinv: - checkcoords(); - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - goto stopwaiting; - _cmp(data.byte(kExamagain), 0); - if (flags.z()) - goto norex; - goto examineagain; -norex: - _cmp(data.byte(kGetback), 0); - if (flags.z()) - goto waitexam; -stopwaiting: - data.byte(kPickup) = 0; - _cmp(data.word(kWatchingtime), 0); - if (!flags.z()) - goto iswatching; - _cmp(data.byte(kNewlocation), 255); - if (!flags.z()) - goto justgetback; -iswatching: - makemainscreen(); - data.byte(kInvopen) = 0; - data.byte(kOpenedob) = 255; - return; -justgetback: - data.byte(kInvopen) = 0; - data.byte(kOpenedob) = 255; -} - void DreamGenContext::setpickup() { STACK_CHECK; _cmp(data.byte(kObjecttype), 1); @@ -5479,35 +4847,6 @@ void DreamGenContext::transfercontoex() { ds.byte(si+2) = 255; } -void DreamGenContext::transfertext() { - STACK_CHECK; - es = data.word(kExtras); - al = data.byte(kExpos); - ah = 0; - _add(ax, ax); - bx = (0+2080+30000+(16*114)); - _add(bx, ax); - di = data.word(kExtextpos); - es.word(bx) = di; - _add(di, (0+2080+30000+(16*114)+((114+2)*2))); - al = data.byte(kItemtotran); - ah = 0; - _add(ax, ax); - ds = data.word(kFreedesc); - bx = (0); - _add(bx, ax); - si = (0+(82*2)); - ax = ds.word(bx); - _add(si, ax); -moretext: - _lodsb(); - _stosb(); - _inc(data.word(kExtextpos)); - _cmp(al, 0); - if (!flags.z()) - goto moretext; -} - void DreamGenContext::purgealocation() { STACK_CHECK; push(ax); @@ -5950,31 +5289,6 @@ notnexttalk: data.byte(kVolumeto) = 0; } -void DreamGenContext::convicons() { - STACK_CHECK; - al = data.byte(kCharacter); - _and(al, 127); - getpersframe(); - di = 234; - bx = 2; - data.word(kCurrentframe) = ax; - findsource(); - ax = data.word(kCurrentframe); - _sub(ax, data.word(kTakeoff)); - ah = 0; - showframe(); -} - -void DreamGenContext::getpersframe() { - STACK_CHECK; - ah = 0; - _add(ax, ax); - bx = ax; - es = data.word(kPeople); - _add(bx, (0)); - ax = es.word(bx); -} - void DreamGenContext::starttalk() { STACK_CHECK; data.byte(kTalkmode) = 0; @@ -6377,23 +5691,6 @@ quittravel: deallocatemem(); } -void DreamGenContext::showcity() { - STACK_CHECK; - clearwork(); - ds = data.word(kTempgraphics); - di = 57; - bx = 32; - al = 0; - ah = 0; - showframe(); - ds = data.word(kTempgraphics); - di = 120+57; - bx = 32; - al = 1; - ah = 0; - showframe(); -} - void DreamGenContext::lookatplace() { STACK_CHECK; _cmp(data.byte(kCommandtype), 224); @@ -7997,63 +7294,6 @@ void DreamGenContext::triggermessage() { data.byte(kLasttrigger) = 0; } -void DreamGenContext::printcurs() { - STACK_CHECK; - push(si); - push(di); - push(ds); - push(dx); - push(bx); - push(es); - di = data.word(kCurslocx); - bx = data.word(kCurslocy); - cl = 6; - ch = 8; - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto _tmp1; - _sub(bx, 3); - ch = 11; -_tmp1: - ds = data.word(kBuffers); - si = (0); - push(di); - push(bx); - multiget(); - bx = pop(); - di = pop(); - push(bx); - push(di); - _inc(data.word(kMaintimer)); - ax = data.word(kMaintimer); - _and(al, 16); - if (!flags.z()) - goto flashcurs; - al = '/'; - _sub(al, 32); - ah = 0; - ds = data.word(kTempcharset); - showframe(); -flashcurs: - di = pop(); - bx = pop(); - _sub(di, 6); - cl = 12; - ch = 8; - _cmp(data.byte(kForeignrelease), 0); - if (flags.z()) - goto _tmp2; - ch = 11; -_tmp2: - multidump(); - es = pop(); - bx = pop(); - dx = pop(); - ds = pop(); - di = pop(); - si = pop(); -} - void DreamGenContext::delcurs() { STACK_CHECK; push(es); @@ -11248,56 +10488,6 @@ void DreamGenContext::dumpmenu() { multidump(); } -void DreamGenContext::getundermenu() { - STACK_CHECK; - di = (80+40); - bx = (60); - cl = 48; - ch = 48; - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)); - multiget(); -} - -void DreamGenContext::putundermenu() { - STACK_CHECK; - di = (80+40); - bx = (60); - cl = 48; - ch = 48; - ds = data.word(kBuffers); - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)); - multiput(); -} - -void DreamGenContext::showoutermenu() { - STACK_CHECK; - al = 40; - ah = 0; - di = (80+40)-34; - bx = (60)-40; - ds = data.word(kTempgraphics); - showframe(); - al = 41; - ah = 0; - di = (80+40)+64-34; - bx = (60)-40; - ds = data.word(kTempgraphics); - showframe(); - al = 42; - ah = 0; - di = (80+40)-26; - bx = (60)+57-40; - ds = data.word(kTempgraphics); - showframe(); - al = 43; - ah = 0; - di = (80+40)+64-26; - bx = (60)+57-40; - ds = data.word(kTempgraphics); - showframe(); -} - void DreamGenContext::showmenu() { STACK_CHECK; _inc(data.byte(kMenucount)); @@ -12931,26 +12121,6 @@ afterprintname: goto shownameloop; } -void DreamGenContext::namestoold() { - STACK_CHECK; - ds = cs; - si = 8579; - di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)); - es = data.word(kBuffers); - cx = 17*4; - _movsb(cx, true); -} - -void DreamGenContext::oldtonames() { - STACK_CHECK; - es = cs; - di = 8579; - si = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)); - ds = data.word(kBuffers); - cx = 17*4; - _movsb(cx, true); -} - void DreamGenContext::saveposition() { STACK_CHECK; makeheader(); @@ -13682,16 +12852,6 @@ void DreamGenContext::checkforemm() { STACK_CHECK; } -void DreamGenContext::checkbasemem() { - STACK_CHECK; - bx = data.word(kHowmuchalloc); - _cmp(bx, 0x9360); - if (!flags.c()) - return /* (enoughmem) */; - data.byte(kGameerror) = 5; - { quickquit(); return; }; -} - void DreamGenContext::allocatebuffers() { STACK_CHECK; bx = (0+2080+30000+(16*114)+((114+2)*2)+18000)/16; @@ -13880,6 +13040,9 @@ void DreamGenContext::screenupdate() { STACK_CHECK; newplace(); mainscreen(); + _cmp(data.byte(kQuitrequested), 0); + if (!flags.z()) + return /* (finishearly) */; animpointer(); showpointer(); _cmp(data.word(kWatchingtime), 0); @@ -14019,115 +13182,6 @@ void DreamGenContext::checkforshake() { data.byte(kShakecounter) = -1; } -void DreamGenContext::watchcount() { - STACK_CHECK; - _cmp(data.byte(kWatchon), 0); - if (flags.z()) - return /* (nowatchworn) */; - _inc(data.byte(kTimercount)); - _cmp(data.byte(kTimercount), 9); - if (flags.z()) - goto flashdots; - _cmp(data.byte(kTimercount), 18); - if (flags.z()) - goto uptime; - return; -flashdots: - ax = 91*3+21; - di = 268+4; - bx = 21; - ds = data.word(kCharset1); - showframe(); - goto finishwatch; -uptime: - data.byte(kTimercount) = 0; - _add(data.byte(kSecondcount), 1); - _cmp(data.byte(kSecondcount), 60); - if (!flags.z()) - goto finishtime; - data.byte(kSecondcount) = 0; - _inc(data.byte(kMinutecount)); - _cmp(data.byte(kMinutecount), 60); - if (!flags.z()) - goto finishtime; - data.byte(kMinutecount) = 0; - _inc(data.byte(kHourcount)); - _cmp(data.byte(kHourcount), 24); - if (!flags.z()) - goto finishtime; - data.byte(kHourcount) = 0; -finishtime: - showtime(); -finishwatch: - data.byte(kWatchdump) = 1; -} - -void DreamGenContext::showtime() { - STACK_CHECK; - _cmp(data.byte(kWatchon), 0); - if (flags.z()) - return /* (nowatch) */; - al = data.byte(kSecondcount); - cl = 0; - twodigitnum(); - push(ax); - al = ah; - ah = 0; - _add(ax, 91*3+10); - ds = data.word(kCharset1); - di = 282+5; - bx = 21; - showframe(); - ax = pop(); - ah = 0; - _add(ax, 91*3+10); - ds = data.word(kCharset1); - di = 282+9; - bx = 21; - showframe(); - al = data.byte(kMinutecount); - cl = 0; - twodigitnum(); - push(ax); - al = ah; - ah = 0; - _add(ax, 91*3); - ds = data.word(kCharset1); - di = 270+5; - bx = 21; - showframe(); - ax = pop(); - ah = 0; - _add(ax, 91*3); - ds = data.word(kCharset1); - di = 270+11; - bx = 21; - showframe(); - al = data.byte(kHourcount); - cl = 0; - twodigitnum(); - push(ax); - al = ah; - ah = 0; - _add(ax, 91*3); - ds = data.word(kCharset1); - di = 256+5; - bx = 21; - showframe(); - ax = pop(); - ah = 0; - _add(ax, 91*3); - ds = data.word(kCharset1); - di = 256+11; - bx = 21; - showframe(); - ax = 91*3+20; - ds = data.word(kCharset1); - di = 267+5; - bx = 21; - showframe(); -} - void DreamGenContext::dumpwatch() { STACK_CHECK; _cmp(data.byte(kWatchdump), 1); @@ -14169,19 +13223,6 @@ morethan10: _add(dl, 'A'); } -void DreamGenContext::twodigitnum() { - STACK_CHECK; - ah = cl; - _dec(ah); -numloop1: - _inc(ah); - _sub(al, 10); - if (!flags.c()) - goto numloop1; - _add(al, 10); - _add(al, cl); -} - void DreamGenContext::showword() { STACK_CHECK; ch = 0; @@ -14245,22 +13286,6 @@ notzeronum: ch = 1; } -void DreamGenContext::mainscreen() { - STACK_CHECK; - data.byte(kInmaparea) = 0; - bx = offset_mainlist; - _cmp(data.byte(kWatchon), 1); - if (flags.z()) - goto checkmain; - bx = offset_mainlist2; -checkmain: - checkcoords(); - _cmp(data.byte(kWalkandexam), 0); - if (flags.z()) - return /* (finishmain) */; - walkandexamine(); -} - void DreamGenContext::madmanrun() { STACK_CHECK; _cmp(data.byte(kLocation), 14); @@ -14750,57 +13775,6 @@ success: data.byte(kTurndirection) = 0; } -void DreamGenContext::showicon() { - STACK_CHECK; - _cmp(data.byte(kReallocation), 50); - if (!flags.c()) - goto isdream1; - showpanel(); - showman(); - roomname(); - panelicons1(); - zoomicon(); - return; -isdream1: - ds = data.word(kTempsprites); - di = 72; - bx = 2; - al = 45; - ah = 0; - showframe(); - ds = data.word(kTempsprites); - di = 72+47; - bx = 2; - al = 46; - ah = 0; - showframe(); - ds = data.word(kTempsprites); - di = 69-10; - bx = 21; - al = 49; - ah = 0; - showframe(); - ds = data.word(kTempsprites); - di = 160+88; - bx = 2; - al = 45; - ah = 4; - showframe(); - ds = data.word(kTempsprites); - di = 160+43; - bx = 2; - al = 46; - ah = 4; - showframe(); - ds = data.word(kTempsprites); - di = 160+101; - bx = 21; - al = 49; - ah = 4; - showframe(); - middlepanel(); -} - void DreamGenContext::middlepanel() { STACK_CHECK; ds = data.word(kTempsprites); @@ -14854,42 +13828,6 @@ void DreamGenContext::showman() { showframe(); } -void DreamGenContext::roomname() { - STACK_CHECK; - di = 88; - bx = 18; - al = 53; - dl = 240; - printmessage(); - bl = data.byte(kRoomnum); - _cmp(bl, 32); - if (flags.c()) - goto notover32; - _sub(bl, 32); -notover32: - bh = 0; - _add(bx, bx); - es = data.word(kRoomdesc); - _add(bx, (0)); - ax = es.word(bx); - _add(ax, (0+(38*2))); - si = ax; - data.word(kLinespacing) = 7; - di = 88; - bx = 25; - dl = 120; - _cmp(data.byte(kWatchon), 1); - if (flags.z()) - goto gotpl; - dl = 160; -gotpl: - al = 0; - ah = 0; - printdirect(); - data.word(kLinespacing) = 10; - usecharset1(); -} - void DreamGenContext::usecharset1() { STACK_CHECK; ax = data.word(kCharset1); @@ -14943,33 +13881,6 @@ zoomisoff: showwatch(); } -void DreamGenContext::showwatch() { - STACK_CHECK; - _cmp(data.byte(kWatchon), 0); - if (flags.z()) - return /* (nowristwatch) */; - ds = data.word(kIcons1); - di = 250; - bx = 1; - al = 6; - ah = 0; - showframe(); - showtime(); -} - -void DreamGenContext::zoomicon() { - STACK_CHECK; - _cmp(data.byte(kZoomon), 0); - if (flags.z()) - return /* (nozoom1) */; - ds = data.word(kIcons1); - di = (8); - bx = (132)-1; - al = 8; - ah = 0; - showframe(); -} - void DreamGenContext::worktoscreenm() { STACK_CHECK; animpointer(); @@ -15130,97 +14041,12 @@ void DreamGenContext::loadtraveltext() { data.word(kTraveltext) = ax; } -void DreamGenContext::loadintotemp() { - STACK_CHECK; - ds = cs; - standardload(); - data.word(kTempgraphics) = ax; -} - -void DreamGenContext::loadintotemp2() { - STACK_CHECK; - ds = cs; - standardload(); - data.word(kTempgraphics2) = ax; -} - -void DreamGenContext::loadintotemp3() { - STACK_CHECK; - ds = cs; - standardload(); - data.word(kTempgraphics3) = ax; -} - -void DreamGenContext::loadtempcharset() { - STACK_CHECK; - standardload(); - data.word(kTempcharset) = ax; -} - -void DreamGenContext::standardload() { - STACK_CHECK; - openfile(); - readheader(); - bx = es.word(di); - push(bx); - cl = 4; - _shr(bx, cl); - allocatemem(); - ds = ax; - cx = pop(); - push(ax); - dx = 0; - readfromfile(); - closefile(); - ax = pop(); -} - void DreamGenContext::loadtemptext() { STACK_CHECK; standardload(); data.word(kTextfile1) = ax; } -void DreamGenContext::loadroom() { - STACK_CHECK; - data.byte(kRoomloaded) = 1; - data.word(kTimecount) = 0; - data.word(kMaintimer) = 0; - data.word(kMapoffsetx) = 104; - data.word(kMapoffsety) = 38; - data.word(kTextaddressx) = 13; - data.word(kTextaddressy) = 182; - data.byte(kTextlen) = 240; - al = data.byte(kNewlocation); - data.byte(kLocation) = al; - getroomdata(); - startloading(); - loadroomssample(); - switchryanon(); - drawflags(); - getdimension(); -} - -void DreamGenContext::loadroomssample() { - STACK_CHECK; - al = data.byte(kRoomssample); - _cmp(al, 255); - if (flags.z()) - return /* (loadedalready) */; - _cmp(al, data.byte(kCurrentsample)); - if (flags.z()) - return /* (loadedalready) */; - data.byte(kCurrentsample) = al; - al = data.byte(kCurrentsample); - cl = '0'; - twodigitnum(); - di = 1896; - _xchg(al, ah); - cs.word(di+10) = ax; - dx = di; - loadsecondsample(); -} - void DreamGenContext::getridofreels() { STACK_CHECK; _cmp(data.byte(kRoomloaded), 0); @@ -15374,29 +14200,6 @@ void DreamGenContext::restoreall() { setallchanges(); } -void DreamGenContext::sortoutmap() { - STACK_CHECK; - push(es); - push(di); - ds = data.word(kWorkspace); - si = 0; - es = data.word(kMapdata); - di = 0; - cx = (60); -blimey: - push(cx); - push(si); - cx = (66); - _movsb(cx, true); - si = pop(); - cx = pop(); - _add(si, 132); - if (--cx) - goto blimey; - di = pop(); - es = pop(); -} - void DreamGenContext::disablepath() { STACK_CHECK; push(cx); @@ -15498,40 +14301,6 @@ void DreamGenContext::getridoftempsp() { deallocatemem(); } -void DreamGenContext::readsetdata() { - STACK_CHECK; - dx = 1857; - standardload(); - data.word(kCharset1) = ax; - dx = 1922; - standardload(); - data.word(kIcons1) = ax; - dx = 1935; - standardload(); - data.word(kIcons2) = ax; - dx = 1819; - standardload(); - data.word(kMainsprites) = ax; - dx = 2221; - standardload(); - data.word(kPuzzletext) = ax; - dx = 2273; - standardload(); - data.word(kCommandtext) = ax; - ax = data.word(kCharset1); - data.word(kCurrentset) = ax; - _cmp(data.byte(kSoundint), 255); - if (flags.z()) - return /* (novolumeload) */; - dx = 2286; - openfile(); - cx = 2048-256; - ds = data.word(kSoundbuffer); - dx = 16384; - readfromfile(); - closefile(); -} - void DreamGenContext::__start() { @@ -16732,8 +15501,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_madmanstelly: madmanstelly(); break; case addr_madman: madman(); break; case addr_priesttext: priesttext(); break; - case addr_textforend: textforend(); break; - case addr_textformonk: textformonk(); break; case addr_drunk: drunk(); break; case addr_advisor: advisor(); break; case addr_copper: copper(); break; @@ -16747,8 +15514,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_adjustleft: adjustleft(); break; case addr_adjustright: adjustright(); break; case addr_reminders: reminders(); break; - case addr_initrain: initrain(); break; - case addr_splitintolines: splitintolines(); break; case addr_backobject: backobject(); break; case addr_liftnoise: liftnoise(); break; case addr_random: random(); break; @@ -16759,7 +15524,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_reconstruct: reconstruct(); break; case addr_deleverything: deleverything(); break; case addr_showpcx: showpcx(); break; - case addr_loadpalfromiff: loadpalfromiff(); break; case addr_setmode: setmode(); break; case addr_createpanel: createpanel(); break; case addr_createpanel2: createpanel2(); break; @@ -16768,7 +15532,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_transfermap: transfermap(); break; case addr_fadedos: fadedos(); break; case addr_dofade: dofade(); break; - case addr_clearendpal: clearendpal(); break; case addr_clearpalette: clearpalette(); break; case addr_fadescreenup: fadescreenup(); break; case addr_fadetowhite: fadetowhite(); break; @@ -16778,17 +15541,11 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_fadescreenuphalf: fadescreenuphalf(); break; case addr_fadescreendown: fadescreendown(); break; case addr_fadescreendowns: fadescreendowns(); break; - case addr_clearstartpal: clearstartpal(); break; case addr_showgun: showgun(); break; case addr_rollendcredits2: rollendcredits2(); break; case addr_rollem: rollem(); break; - case addr_fadecalculation: fadecalculation(); break; case addr_greyscalesum: greyscalesum(); break; case addr_showgroup: showgroup(); break; - case addr_paltostartpal: paltostartpal(); break; - case addr_endpaltostart: endpaltostart(); break; - case addr_startpaltoend: startpaltoend(); break; - case addr_paltoendpal: paltoendpal(); break; case addr_allpalette: allpalette(); break; case addr_dumpcurrent: dumpcurrent(); break; case addr_fadedownmon: fadedownmon(); break; @@ -16814,7 +15571,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_monprint: monprint(); break; case addr_fillopen: fillopen(); break; case addr_findallopen: findallopen(); break; - case addr_examineob: examineob(); break; case addr_makemainscreen: makemainscreen(); break; case addr_getbackfromob: getbackfromob(); break; case addr_incryanpage: incryanpage(); break; @@ -16858,7 +15614,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_transfertoex: transfertoex(); break; case addr_pickupconts: pickupconts(); break; case addr_transfercontoex: transfercontoex(); break; - case addr_transfertext: transfertext(); break; case addr_purgealocation: purgealocation(); break; case addr_emergencypurge: emergencypurge(); break; case addr_purgeanitem: purgeanitem(); break; @@ -16873,8 +15628,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_redrawmainscrn: redrawmainscrn(); break; case addr_getback1: getback1(); break; case addr_talk: talk(); break; - case addr_convicons: convicons(); break; - case addr_getpersframe: getpersframe(); break; case addr_starttalk: starttalk(); break; case addr_getpersontext: getpersontext(); break; case addr_moretalk: moretalk(); break; @@ -16883,7 +15636,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_redes: redes(); break; case addr_newplace: newplace(); break; case addr_selectlocation: selectlocation(); break; - case addr_showcity: showcity(); break; case addr_lookatplace: lookatplace(); break; case addr_getundercentre: getundercentre(); break; case addr_putundercentre: putundercentre(); break; @@ -16933,7 +15685,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_monmessage: monmessage(); break; case addr_processtrigger: processtrigger(); break; case addr_triggermessage: triggermessage(); break; - case addr_printcurs: printcurs(); break; case addr_delcurs: delcurs(); break; case addr_useobject: useobject(); break; case addr_wheelsound: wheelsound(); break; @@ -17058,9 +15809,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_dumpkeypad: dumpkeypad(); break; case addr_usemenu: usemenu(); break; case addr_dumpmenu: dumpmenu(); break; - case addr_getundermenu: getundermenu(); break; - case addr_putundermenu: putundermenu(); break; - case addr_showoutermenu: showoutermenu(); break; case addr_showmenu: showmenu(); break; case addr_loadmenu: loadmenu(); break; case addr_viewfolder: viewfolder(); break; @@ -17116,8 +15864,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_shownames: shownames(); break; case addr_dosreturn: dosreturn(); break; case addr_error: error(); break; - case addr_namestoold: namestoold(); break; - case addr_oldtonames: oldtonames(); break; case addr_savefilewrite: savefilewrite(); break; case addr_savefileread: savefileread(); break; case addr_saveposition: saveposition(); break; @@ -17165,7 +15911,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_setupemm: setupemm(); break; case addr_removeemm: removeemm(); break; case addr_checkforemm: checkforemm(); break; - case addr_checkbasemem: checkbasemem(); break; case addr_allocatebuffers: allocatebuffers(); break; case addr_clearbuffers: clearbuffers(); break; case addr_clearchanges: clearchanges(); break; @@ -17179,12 +15924,9 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_screenupdate: screenupdate(); break; case addr_watchreel: watchreel(); break; case addr_checkforshake: checkforshake(); break; - case addr_watchcount: watchcount(); break; - case addr_showtime: showtime(); break; case addr_dumpwatch: dumpwatch(); break; case addr_showbyte: showbyte(); break; case addr_onedigit: onedigit(); break; - case addr_twodigitnum: twodigitnum(); break; case addr_showword: showword(); break; case addr_convnum: convnum(); break; case addr_mainscreen: mainscreen(); break; @@ -17199,17 +15941,13 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_printmessage2: printmessage2(); break; case addr_setwalk: setwalk(); break; case addr_workoutframes: workoutframes(); break; - case addr_showicon: showicon(); break; case addr_middlepanel: middlepanel(); break; case addr_showman: showman(); break; - case addr_roomname: roomname(); break; case addr_usecharset1: usecharset1(); break; case addr_usetempcharset: usetempcharset(); break; case addr_showexit: showexit(); break; case addr_panelicons1: panelicons1(); break; - case addr_showwatch: showwatch(); break; case addr_gettime: gettime(); break; - case addr_zoomicon: zoomicon(); break; case addr_worktoscreenm: worktoscreenm(); break; case addr_blank: blank(); break; case addr_allpointer: allpointer(); break; @@ -17225,19 +15963,11 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_randomnum1: randomnum1(); break; case addr_randomnum2: randomnum2(); break; case addr_loadtraveltext: loadtraveltext(); break; - case addr_loadintotemp: loadintotemp(); break; - case addr_loadintotemp2: loadintotemp2(); break; - case addr_loadintotemp3: loadintotemp3(); break; - case addr_loadtempcharset: loadtempcharset(); break; - case addr_standardload: standardload(); break; case addr_loadtemptext: loadtemptext(); break; - case addr_loadroom: loadroom(); break; - case addr_loadroomssample: loadroomssample(); break; case addr_getridofreels: getridofreels(); break; case addr_getridofall: getridofall(); break; case addr_restorereels: restorereels(); break; case addr_restoreall: restoreall(); break; - case addr_sortoutmap: sortoutmap(); break; case addr_disablepath: disablepath(); break; case addr_findroominloc: findroominloc(); break; case addr_dontloadseg: dontloadseg(); break; @@ -17248,7 +15978,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_getridoftemp3: getridoftemp3(); break; case addr_getridoftempcharset: getridoftempcharset(); break; case addr_getridoftempsp: getridoftempsp(); break; - case addr_readsetdata: readsetdata(); break; case addr_createfile: createfile(); break; case addr_openfile: openfile(); break; case addr_openfilefromc: openfilefromc(); break; diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h index f3a763fbd8..512f7e6193 100644 --- a/engines/dreamweb/dreamgen.h +++ b/engines/dreamweb/dreamgen.h @@ -49,7 +49,6 @@ public: static const uint16 addr_openfilefromc = 0xcb94; static const uint16 addr_openfile = 0xcb90; static const uint16 addr_createfile = 0xcb8c; - static const uint16 addr_readsetdata = 0xcb88; static const uint16 addr_getridoftempsp = 0xcb84; static const uint16 addr_getridoftempcharset = 0xcb80; static const uint16 addr_getridoftemp3 = 0xcb7c; @@ -60,19 +59,11 @@ public: static const uint16 addr_dontloadseg = 0xcb64; static const uint16 addr_findroominloc = 0xcb58; static const uint16 addr_disablepath = 0xcb50; - static const uint16 addr_sortoutmap = 0xcb48; static const uint16 addr_restoreall = 0xcb44; static const uint16 addr_restorereels = 0xcb40; static const uint16 addr_getridofall = 0xcb3c; static const uint16 addr_getridofreels = 0xcb38; - static const uint16 addr_loadroomssample = 0xcb34; - static const uint16 addr_loadroom = 0xcb30; static const uint16 addr_loadtemptext = 0xcb2c; - static const uint16 addr_standardload = 0xcb28; - static const uint16 addr_loadtempcharset = 0xcb24; - static const uint16 addr_loadintotemp3 = 0xcb20; - static const uint16 addr_loadintotemp2 = 0xcb1c; - static const uint16 addr_loadintotemp = 0xcb18; static const uint16 addr_loadtraveltext = 0xcb14; static const uint16 addr_randomnum2 = 0xcb08; static const uint16 addr_randomnum1 = 0xcb04; @@ -88,17 +79,13 @@ public: static const uint16 addr_allpointer = 0xcaa4; static const uint16 addr_blank = 0xcaa0; static const uint16 addr_worktoscreenm = 0xca9c; - static const uint16 addr_zoomicon = 0xca90; static const uint16 addr_gettime = 0xca8c; - static const uint16 addr_showwatch = 0xca88; static const uint16 addr_panelicons1 = 0xca84; static const uint16 addr_showexit = 0xca80; static const uint16 addr_usetempcharset = 0xca7c; static const uint16 addr_usecharset1 = 0xca78; - static const uint16 addr_roomname = 0xca74; static const uint16 addr_showman = 0xca6c; static const uint16 addr_middlepanel = 0xca68; - static const uint16 addr_showicon = 0xca64; static const uint16 addr_workoutframes = 0xca54; static const uint16 addr_setwalk = 0xca44; static const uint16 addr_printmessage2 = 0xca30; @@ -113,12 +100,9 @@ public: static const uint16 addr_mainscreen = 0xc9c8; static const uint16 addr_convnum = 0xc9c4; static const uint16 addr_showword = 0xc9c0; - static const uint16 addr_twodigitnum = 0xc9bc; static const uint16 addr_onedigit = 0xc9b8; static const uint16 addr_showbyte = 0xc9b4; static const uint16 addr_dumpwatch = 0xc9b0; - static const uint16 addr_showtime = 0xc9ac; - static const uint16 addr_watchcount = 0xc9a8; static const uint16 addr_checkforshake = 0xc9a4; static const uint16 addr_watchreel = 0xc9a0; static const uint16 addr_screenupdate = 0xc99c; @@ -132,7 +116,6 @@ public: static const uint16 addr_clearchanges = 0xc974; static const uint16 addr_clearbuffers = 0xc970; static const uint16 addr_allocatebuffers = 0xc96c; - static const uint16 addr_checkbasemem = 0xc968; static const uint16 addr_checkforemm = 0xc964; static const uint16 addr_removeemm = 0xc960; static const uint16 addr_setupemm = 0xc95c; @@ -180,8 +163,6 @@ public: static const uint16 addr_saveposition = 0xc898; static const uint16 addr_savefileread = 0xc894; static const uint16 addr_savefilewrite = 0xc890; - static const uint16 addr_oldtonames = 0xc88c; - static const uint16 addr_namestoold = 0xc888; static const uint16 addr_error = 0xc884; static const uint16 addr_generalerror = 0xcbbc; static const uint16 addr_dosreturn = 0xc880; @@ -238,9 +219,6 @@ public: static const uint16 addr_viewfolder = 0xc7b4; static const uint16 addr_loadmenu = 0xc7b0; static const uint16 addr_showmenu = 0xc7ac; - static const uint16 addr_showoutermenu = 0xc7a8; - static const uint16 addr_putundermenu = 0xc7a4; - static const uint16 addr_getundermenu = 0xc7a0; static const uint16 addr_dumpmenu = 0xc79c; static const uint16 addr_usemenu = 0xc798; static const uint16 addr_dumpkeypad = 0xc794; @@ -365,7 +343,6 @@ public: static const uint16 addr_wheelsound = 0xc588; static const uint16 addr_useobject = 0xc580; static const uint16 addr_delcurs = 0xc57c; - static const uint16 addr_printcurs = 0xc578; static const uint16 addr_triggermessage = 0xc574; static const uint16 addr_processtrigger = 0xc570; static const uint16 addr_monmessage = 0xc56c; @@ -415,7 +392,6 @@ public: static const uint16 addr_putundercentre = 0xc4b8; static const uint16 addr_getundercentre = 0xc4b4; static const uint16 addr_lookatplace = 0xc4b0; - static const uint16 addr_showcity = 0xc4ac; static const uint16 addr_selectlocation = 0xc4a8; static const uint16 addr_newplace = 0xc4a4; static const uint16 addr_redes = 0xc4a0; @@ -424,8 +400,6 @@ public: static const uint16 addr_moretalk = 0xc494; static const uint16 addr_getpersontext = 0xc490; static const uint16 addr_starttalk = 0xc48c; - static const uint16 addr_getpersframe = 0xc488; - static const uint16 addr_convicons = 0xc484; static const uint16 addr_talk = 0xc480; static const uint16 addr_getback1 = 0xc47c; static const uint16 addr_redrawmainscrn = 0xc478; @@ -440,7 +414,6 @@ public: static const uint16 addr_purgeanitem = 0xc414; static const uint16 addr_emergencypurge = 0xc410; static const uint16 addr_purgealocation = 0xc40c; - static const uint16 addr_transfertext = 0xc404; static const uint16 addr_transfercontoex = 0xc400; static const uint16 addr_pickupconts = 0xc3fc; static const uint16 addr_transfertoex = 0xc3f8; @@ -484,7 +457,6 @@ public: static const uint16 addr_incryanpage = 0xc348; static const uint16 addr_getbackfromob = 0xc344; static const uint16 addr_makemainscreen = 0xc340; - static const uint16 addr_examineob = 0xc33c; static const uint16 addr_findallopen = 0xc32c; static const uint16 addr_fillopen = 0xc324; static const uint16 addr_monprint = 0xc314; @@ -510,17 +482,11 @@ public: static const uint16 addr_fadedownmon = 0xc2ac; static const uint16 addr_dumpcurrent = 0xc2a8; static const uint16 addr_allpalette = 0xc2a4; - static const uint16 addr_paltoendpal = 0xc2a0; - static const uint16 addr_startpaltoend = 0xc29c; - static const uint16 addr_endpaltostart = 0xc298; - static const uint16 addr_paltostartpal = 0xc294; static const uint16 addr_showgroup = 0xc290; static const uint16 addr_greyscalesum = 0xc28c; - static const uint16 addr_fadecalculation = 0xc288; static const uint16 addr_rollem = 0xc284; static const uint16 addr_rollendcredits2 = 0xc280; static const uint16 addr_showgun = 0xc27c; - static const uint16 addr_clearstartpal = 0xc278; static const uint16 addr_fadescreendowns = 0xc274; static const uint16 addr_fadescreendown = 0xc270; static const uint16 addr_fadescreenuphalf = 0xc26c; @@ -530,7 +496,6 @@ public: static const uint16 addr_fadetowhite = 0xc25c; static const uint16 addr_fadescreenup = 0xc258; static const uint16 addr_clearpalette = 0xc254; - static const uint16 addr_clearendpal = 0xc250; static const uint16 addr_dofade = 0xc24c; static const uint16 addr_fadedos = 0xc248; static const uint16 addr_transfermap = 0xc244; @@ -539,7 +504,6 @@ public: static const uint16 addr_createpanel2 = 0xc200; static const uint16 addr_createpanel = 0xc1fc; static const uint16 addr_setmode = 0xc1dc; - static const uint16 addr_loadpalfromiff = 0xc1d8; static const uint16 addr_showpcx = 0xc1cc; static const uint16 addr_deleverything = 0xc1c0; static const uint16 addr_reconstruct = 0xc1ac; @@ -550,8 +514,6 @@ public: static const uint16 addr_random = 0xc17c; static const uint16 addr_liftnoise = 0xc178; static const uint16 addr_backobject = 0xc170; - static const uint16 addr_splitintolines = 0xc164; - static const uint16 addr_initrain = 0xc160; static const uint16 addr_reminders = 0xc15c; static const uint16 addr_adjustright = 0xc158; static const uint16 addr_adjustleft = 0xc154; @@ -565,8 +527,6 @@ public: static const uint16 addr_copper = 0xc0fc; static const uint16 addr_advisor = 0xc0f8; static const uint16 addr_drunk = 0xc0f4; - static const uint16 addr_textformonk = 0xc0f0; - static const uint16 addr_textforend = 0xc0ec; static const uint16 addr_priesttext = 0xc0e8; static const uint16 addr_madman = 0xc0dc; static const uint16 addr_madmanstelly = 0xc0d8; @@ -660,12 +620,11 @@ public: static const uint16 offset_speechfilename = 0x13eb; static const uint16 offset_rootdir = 0x0b8c; static const uint16 offset_gameerror3 = 0x1003; - static const uint16 offset_rainlocations = 0x0459; + static const uint16 offset_facelist = 0x0451; static const uint16 offset_diarylist = 0x0e9c; static const uint16 offset_decidelist = 0x13c1; static const uint16 offset_symbollist = 0x0e5e; static const uint16 offset_folderlist = 0x0e34; - static const uint16 offset_facelist = 0x0451; static const uint16 offset_operand1 = 0x0b7e; static const uint16 offset_keypadlist = 0x0d9a; static const uint16 kStartvars = 0; @@ -1242,7 +1201,7 @@ public: void usewire(); void getnamepos(); void loadtemptext(); - void clearstartpal(); + //void clearstartpal(); void femalefan(); //void showgamereel(); void identifyob(); @@ -1253,7 +1212,6 @@ public: void startdmablock(); void useopenbox(); void clearbuffers(); - //void getyad(); void neterror(); void storeit(); //void lockeddoorway(); @@ -1268,7 +1226,7 @@ public: //void frameoutbh(); void getobtextstart(); void loadfolder(); - void decide(); + void dumpdiarykeys(); //void dumppointer(); void reelsonscreen(); void getridofreels(); @@ -1294,6 +1252,7 @@ public: void mainscreen(); void watchreel(); void showfolder(); + void dosreturn(); //void turnanypathoff(); void openfilefromc(); void gettime(); @@ -1303,14 +1262,13 @@ public: //void getexpos(); void fadedos(); //void fillspace(); - void selectlocation(); //void multiget(); //void autosetwalk(); void fadeupmonfirst(); void drawfloor(); void loadkeypad(); //void findsource(); - void clearendpal(); + //void clearendpal(); void findtext1(); void isryanholding(); void showslots(); @@ -1327,7 +1285,7 @@ public: void showsaveops(); void intromonks1(); void resetlocation(); - void oldtonames(); + //void oldtonames(); void showdiscops(); void advisor(); void additionaltext(); @@ -1347,7 +1305,7 @@ public: //void deltextline(); void entercode(); void getopenedsize(); - void getpersframe(); + //void getpersframe(); void doshake(); void resetkeyboard(); //void showpanel(); @@ -1360,26 +1318,26 @@ public: void slabdoord(); void adjustup(); void slabdoorf(); - void loadintotemp(); + void findroominloc(); void loadintroroom(); void saveseg(); //void showblink(); void mousecall(); void train(); - void watchcount(); + //void checkiffree(); void fadedownmon(); void loadcart(); - //void calcfrframe(); + //void splitintolines(); void bartender(); void eden(); void showdiary(); - void purgealocation(); + //void loadroomssample(); //void updatepeople(); //void addtopeoplelist(); void hangoncurs(); //void getblockofpixel(); //void kernchars(); - void printcurs(); + //void printcurs(); //void convertkey(); void outofopen(); //void dealwithspecial(); @@ -1390,21 +1348,21 @@ public: void showsymbol(); void endgameseq(); //void cancelch0(); - void setbotleft(); + void turnonpower(); void findfirstpath(); //void cancelch1(); void loadold(); - void loadtempcharset(); + //void loadtempcharset(); void useslab(); void dumpzoom(); //void aboutturn(); void usealtar(); void createpanel2(); - void turnonpower(); + void setbotleft(); void manasleep2(); void moretalk(); //void printslow(); - void loadroom(); + //void loadroom(); void starttalk(); void delchar(); void getanyad(); @@ -1426,7 +1384,7 @@ public: void getridoftemp2(); void usebalcony(); void runendseq(); - void dumpdiarykeys(); + void decide(); void disablesoundint(); void priesttext(); //void showallex(); @@ -1473,7 +1431,7 @@ public: void fadescreenuphalf(); void getridoftempcharset(); void heavy(); - void endpaltostart(); + //void endpaltostart(); void showkeys(); void usekey(); void locklighton(); @@ -1522,7 +1480,7 @@ public: void placefreeobject(); void allpalette(); //void loopchannel0(); - void initrain(); + //void initrain(); void showleftpage(); void rockstar(); void adjustright(); @@ -1538,9 +1496,10 @@ public: void dumpsymbox(); void loadgame(); void getridoftemp(); - void showcity(); + //void showcity(); void dumpsymbol(); void disablepath(); + //void convicons(); void buttonsix(); void intro2text(); void showouterpad(); @@ -1564,8 +1523,9 @@ public: void openfilenocheck(); //void readoneblock(); void fadeupmon(); - void paltoendpal(); + //void paltoendpal(); void fadetowhite(); + //void textformonk(); void loadsavebox(); void soundend(); void redes(); @@ -1573,7 +1533,7 @@ public: void clearchanges(); void errormessage3(); //void deletetaken(); - void putundermenu(); + //void putundermenu(); void intromonks2(); void intromagic2(); void intromagic3(); @@ -1587,7 +1547,6 @@ public: void transfertoex(); void playchannel1(); void playchannel0(); - void usemon(); void steady(); //void pixelcheckset(); void reexfrominv(); @@ -1607,16 +1566,14 @@ public: void mainman(); void mansatstill(); void channel1only(); - void checkbasemem(); + //void checkbasemem(); void lastfolder(); void transfermap(); - //void showreelframe(); void showmonk(); void diarykeyn(); void set16colpalette(); - void convicons(); - void interviewer(); void sparky(); + void interviewer(); void purgeanitem(); void madman(); void createpanel(); @@ -1624,9 +1581,9 @@ public: void enablesoundint(); void madmanstelly(); void constant(); - void loadroomssample(); + void purgealocation(); void sparkydrip(); - void paltostartpal(); + //void paltostartpal(); void bossman(); void getridofpit(); void convnum(); @@ -1634,7 +1591,7 @@ public: void nothelderror(); //void readheader(); void getsetad(); - void textformonk(); + //void getyad(); void reconstruct(); void soldier1(); //void animpointer(); @@ -1655,18 +1612,19 @@ public: void hangonpq(); void startup(); void savegame(); - void startpaltoend(); - void showicon(); + //void startpaltoend(); + //void showicon(); void findopenpos(); void describeob(); void deleteexframe(); + //void readsetdata(); void folderexit(); - void dosreturn(); + void usemon(); void wheelsound(); void actualsave(); void autolook(); void playguitar(); - void transfertext(); + //void showreelframe(); void searchforsame(); void showmainops(); void getback1(); @@ -1680,12 +1638,12 @@ public: void deleverything(); void fadescreendown(); //void findxyfrompath(); - void namestoold(); + void poolguard(); //void getxad(); void openinv(); void lookatplace(); void useaxe(); - void examineob(); + //void examineob(); void buttonnought(); void useelvdoor(); void putbackobstuff(); @@ -1697,10 +1655,10 @@ public: //void printundermon(); void buttonnine(); void findallopen(); - void loadintotemp3(); - void loadintotemp2(); + //void doorway(); + //void loadintotemp2(); void gamer(); - void poolguard(); + //void namestoold(); void readfromfile(); void initialinv(); void quitsymbol(); @@ -1724,14 +1682,14 @@ public: void trapdoor(); void openlouis(); void buttonthree(); - void getundermenu(); + //void getundermenu(); //void randomnumber(); void lookatcard(); void helicopter(); void scrollmonitor(); void setsoundoff(); void setpickup(); - //void doorway(); + //void loadintotemp3(); void dropobject(); void isitright(); void reexfromopen(); @@ -1760,22 +1718,22 @@ public: //void walkandexamine(); void dmaend(); //void quickquit2(); - void twodigitnum(); + //void twodigitnum(); //void madmantext(); void dumpcurrent(); - void textforend(); + //void textforend(); void showdiarykeys(); void dontloadseg(); //void madmode(); void intro3text(); void allocatemem(); - void sortoutmap(); + //void sortoutmap(); //void showrain(); void useopened(); void inventory(); void powerlightoff(); void fillopen(); - void showoutermenu(); + //void showoutermenu(); void signon(); void deleteextext(); void foghornsound(); @@ -1796,19 +1754,20 @@ public: //void plotreel(); void swapwithopen(); //void makesprite(); + //void transfertext(); void dreamweb(); void droperror(); void edenscdplayer(); void calledensdlift(); void checkinside(); void gates(); - void newgame(); - void showwatch(); + void selectlocation(); + //void showwatch(); //void turnanypathon(); void restorereels(); void setwalk(); //void useroutine(); - void zoomicon(); + //void zoomicon(); //void findlen(); void findpathofpoint(); void issetobonmap(); @@ -1825,7 +1784,7 @@ public: void fadescreenups(); //void checkdest(); //void hangon(); - void loadpalfromiff(); + //void loadpalfromiff(); //void facerightway(); void startup1(); void hotelcontrol(); @@ -1875,12 +1834,12 @@ public: void usechurchhole(); void searchforfiles(); void monkspeaking(); - void fadecalculation(); + //void fadecalculation(); //void waitframes(); void clearrest(); //void getreelframeax(); void barwoman(); - void roomname(); + //void roomname(); void credits(); void madmanrun(); void randomnum1(); @@ -1891,7 +1850,7 @@ public: void closefile(); void delcurs(); void randomaccess(); - void splitintolines(); + //void calcfrframe(); //void checkifex(); //void findobname(); void initialmoncols(); @@ -1947,7 +1906,7 @@ public: void readcitypic(); void getpersontext(); void intoinv(); - void showtime(); + //void showtime(); void parser(); void hangonw(); void intro(); @@ -1957,11 +1916,11 @@ public: void getridoftempsp(); void scanfornames(); //void setallchanges(); - void readsetdata(); + void newgame(); //void printboth(); - void standardload(); + //void standardload(); void undertextline(); - void findroominloc(); + //void loadintotemp(); void sitdowninbar(); void shownames(); void savefileread(); @@ -1974,7 +1933,7 @@ public: void quitkey(); void processtrigger(); void monmessage(); - void readdesticon(); + void volumeadjust(); void randomnum2(); void loadsecondsample(); void transfercontoex(); @@ -1992,8 +1951,8 @@ public: void accesslightoff(); void usehole(); void useobject(); - void volumeadjust(); - //void checkiffree(); + void readdesticon(); + //void watchcount(); }; } diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index 0e43f18db6..192019d4c9 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -442,9 +442,9 @@ void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) { sample.size, 22050, Audio::FLAG_UNSIGNED); } else { uint8 *buffer = (uint8 *)malloc(_speechData.size()); - memcpy(buffer, _speechData.begin(), _speechData.size()); if (!buffer) error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size()); + memcpy(buffer, _speechData.begin(), _speechData.size()); raw = Audio::makeRawStream( buffer, _speechData.size(), 22050, Audio::FLAG_UNSIGNED); diff --git a/engines/dreamweb/keypad.cpp b/engines/dreamweb/keypad.cpp new file mode 100644 index 0000000000..de5a560af1 --- /dev/null +++ b/engines/dreamweb/keypad.cpp @@ -0,0 +1,36 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "dreamweb/dreamweb.h" + +namespace DreamGen { + +void DreamGenContext::getundermenu() { + multiget(segRef(data.word(kBuffers)).ptr(kUndertimedtext, 0), kMenux, kMenuy, 48, 48); +} + +void DreamGenContext::putundermenu() { + multiput(segRef(data.word(kBuffers)).ptr(kUndertimedtext, 0), kMenux, kMenuy, 48, 48); +} + +} /*namespace dreamgen */ + diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk index 21429dc960..d3efc3a917 100644 --- a/engines/dreamweb/module.mk +++ b/engines/dreamweb/module.mk @@ -6,13 +6,16 @@ MODULE_OBJS := \ detection.o \ dreamweb.o \ dreamgen.o \ + keypad.o \ object.o \ pathfind.o \ print.o \ saveload.o \ sprite.o \ stubs.o \ + talk.o \ use.o \ + vgafades.o \ vgagrafx.o # This module can be built as a plugin diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp index e2da902465..d887f1c564 100644 --- a/engines/dreamweb/object.cpp +++ b/engines/dreamweb/object.cpp @@ -103,12 +103,160 @@ void DreamGenContext::obpicture() { void DreamGenContext::obicons() { uint8 value1, value2; getanyad(&value1, &value2); - if (value1 == 0xff) { - showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 260, 1, 1, 0); - } else { + if (value1 != 0xff) { + // can open it showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 210, 1, 4, 0); } + + showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 260, 1, 1, 0); +} + +void DreamGenContext::examineob(bool examineAgain) { + data.byte(kPointermode) = 0; + data.word(kTimecount) = 0; + while (true) { + if (examineAgain) { + data.byte(kInmaparea) = 0; + data.byte(kExamagain) = 0; + data.byte(kOpenedob) = 255; + data.byte(kOpenedtype) = 255; + data.byte(kInvopen) = 0; + al = data.byte(kCommandtype); + data.byte(kObjecttype) = al; + data.byte(kItemframe) = 0; + data.byte(kPointerframe) = 0; + createpanel(); + showpanel(); + showman(); + showexit(); + obicons(); + obpicture(); + describeob(); + undertextline(); + data.byte(kCommandtype) = 255; + readmouse(); + showpointer(); + worktoscreen(); + delpointer(); + examineAgain = false; + } + + readmouse(); + showpointer(); + vsync(); + dumppointer(); + dumptextline(); + delpointer(); + data.byte(kGetback) = 0; + switch (data.byte(kInvopen)) { + case 0: { + RectWithCallback examlist[] = { + { 273,320,157,198,&DreamGenContext::getbackfromob }, + { 260,300,0,44,&DreamGenContext::useobject }, + { 210,254,0,44,&DreamGenContext::selectopenob }, + { 144,176,64,96,&DreamGenContext::setpickup }, + { 0,50,50,200,&DreamGenContext::examinventory }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(examlist); + break; + } + case 1: { + // NB: This table contains the non-constant openchangesize! + RectWithCallback invlist1[] = { + { 273,320,157,198,&DreamGenContext::getbackfromob }, + { 255,294,0,24,&DreamGenContext::dropobject }, + { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incryanpage }, + { kInventx, cs.word(offset_openchangesize),kInventy+100,kInventy+100+kItempicsize,&DreamGenContext::useopened }, + { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::intoinv }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(invlist1); + break; + } + default: { + RectWithCallback withlist1[] = { + { 273,320,157,198,&DreamGenContext::getbackfromob }, + { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incryanpage }, + { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::selectob }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(withlist1); + break; + } + } + if (data.byte(kQuitrequested) != 0) + break; + if (data.byte(kExamagain) != 0) + examineAgain = true; + else if (data.byte(kGetback) != 0) + break; + } + + data.byte(kPickup) = 0; + if (data.word(kWatchingtime) != 0 || data.byte(kNewlocation) == 255) { + // iswatching + makemainscreen(); + } + + data.byte(kInvopen) = 0; + data.byte(kOpenedob) = 255; +} + +void DreamGenContext::inventory() { + if (data.byte(kMandead) == 1 || data.word(kWatchingtime) != 0) { + blank(); + return; + } + + if (data.byte(kCommandtype) != 239) { + data.byte(kCommandtype) = 239; + al = 32; + commandonly(); + } + + if (data.word(kMousebutton) == data.word(kOldbutton)) + return; + if (!(data.word(kMousebutton) & 1)) // only on left mouse button + return; + + + data.word(kTimecount) = 0; + data.byte(kPointermode) = 0; + data.byte(kInmaparea) = 0; + animpointer(); + createpanel(); + showpanel(); + examicon(); + showman(); + showexit(); + undertextline(); + data.byte(kPickup) = 0; + data.byte(kInvopen) = 2; + openinv(); + readmouse(); + showpointer(); + worktoscreen(); + delpointer(); + data.byte(kOpenedob) = 255; + examineob(false); } +void DreamGenContext::transfertext() { + segRef(data.word(kExtras)).word(kExtextdat + data.byte(kExpos) * 2) = data.word(kExtextpos); + uint16 freeTextOffset = data.byte(kItemtotran) * 2; + uint16 srcOffset = segRef(data.word(kFreedesc)).word(kFreetextdat + freeTextOffset); + const char *src = (const char *)segRef(data.word(kFreedesc)).ptr(kFreetext + srcOffset, 0); + char *dst = (char *)segRef(data.word(kExtras)).ptr(kExtext + data.word(kExtextpos), 0); + + size_t len = strlen(src); + memcpy(dst, src, len + 1); + data.word(kExtextpos) += len + 1; +} + + } /*namespace dreamgen */ diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index 636182dc83..6faab5554f 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -72,8 +72,14 @@ void DreamGenContext::doload() { vsync(); dumppointer(); dumptextline(); - bx = offset_loadlist; - checkcoords(); + RectWithCallback loadlist[] = { + { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getbacktoops }, + { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamGenContext::actualload }, + { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamGenContext::selectslot }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(loadlist); if (data.byte(kGetback) == 1) break; if (data.byte(kGetback) == 2) @@ -156,8 +162,8 @@ void DreamGenContext::doload() { dx = data; es = dx; - bx = kMadeuproomdat; - startloading(); + const Room *room = (Room *)cs.ptr(kMadeuproomdat, sizeof(Room)); + startloading(room); loadroomssample(); data.byte(kRoomloaded) = 1; data.byte(kNewlocation) = 255; @@ -213,8 +219,15 @@ void DreamGenContext::savegame() { vsync(); dumppointer(); dumptextline(); - bx = offset_savelist; - checkcoords(); + + RectWithCallback savelist[] = { + { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getbacktoops }, + { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamGenContext::actualsave }, + { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamGenContext::selectslot }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(savelist); _cmp(data.byte(kGetback), 0); if (flags.z()) continue; @@ -339,5 +352,12 @@ void DreamGenContext::savegame() { } } +void DreamGenContext::namestoold() { + memcpy(segRef(data.word(kBuffers)).ptr(kZoomspace, 0), cs.ptr(kSavenames, 0), 17*4); +} + +void DreamGenContext::oldtonames() { + memcpy(cs.ptr(kSavenames, 0), segRef(data.word(kBuffers)).ptr(kZoomspace, 0), 17*4); +} } /*namespace dreamgen */ diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp index 3b67bfbd72..a03de8caf1 100644 --- a/engines/dreamweb/sprite.cpp +++ b/engines/dreamweb/sprite.cpp @@ -295,76 +295,61 @@ void DreamGenContext::random(Sprite *sprite, SetObject *objData) { } void DreamGenContext::doorway(Sprite *sprite, SetObject *objData) { - data.byte(kDoorcheck1) = (uint8)-24; - data.byte(kDoorcheck2) = 10; - data.byte(kDoorcheck3) = (uint8)-30; - data.byte(kDoorcheck4) = 10; - dodoor(sprite, objData); + Common::Rect check(-24, -30, 10, 10); + dodoor(sprite, objData, check); } void DreamGenContext::widedoor(Sprite *sprite, SetObject *objData) { - data.byte(kDoorcheck1) = (uint8)-24; - data.byte(kDoorcheck2) = 24; - data.byte(kDoorcheck3) = (uint8)-30; - data.byte(kDoorcheck4) = 24; - dodoor(sprite, objData); + Common::Rect check(-24, -30, 24, 24); + dodoor(sprite, objData, check); } -void DreamGenContext::dodoor() { - Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); - SetObject *objData = (SetObject *)ds.ptr(di, 0); - dodoor(sprite, objData); -} +void DreamGenContext::dodoor(Sprite *sprite, SetObject *objData, Common::Rect check) { + + int ryanx = data.byte(kRyanx); + int ryany = data.byte(kRyany); + + // Automatically opening doors: check if Ryan is in range + + check.translate(sprite->x, sprite->y); + bool openDoor = check.contains(ryanx, ryany); + + if (openDoor) { + + if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) + sprite->frame = 6; + + ++sprite->frame; + if (sprite->frame == 1) { // doorsound2 + if (data.byte(kReallocation) == 5) // hoteldoor2 + al = 13; + else + al = 0; + playchannel1(); + } + if (objData->b18[sprite->frame] == 255) + --sprite->frame; + + sprite->b15 = objData->index = objData->b18[sprite->frame]; + data.byte(kThroughdoor) = 1; -void DreamGenContext::dodoor(Sprite *sprite, SetObject *objData) { - uint8 ryanx = data.byte(kRyanx); - uint8 ryany = data.byte(kRyany); - if (ryanx < sprite->x) { - if (ryanx < sprite->x + (int8)data.byte(kDoorcheck1)) - goto shutdoor; - } else { - if (ryanx >= sprite->x + data.byte(kDoorcheck2)) - goto shutdoor; - } - if (ryany < sprite->y) { - if (ryany < sprite->y + (int8)data.byte(kDoorcheck3)) - goto shutdoor; } else { - if (ryany >= sprite->y + data.byte(kDoorcheck4)) - goto shutdoor; - } -//opendoor: - if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) - sprite->frame = 6; + // shut door - ++sprite->frame; - if (sprite->frame == 1) { //doorsound2 - if (data.byte(kReallocation) == 5) //hoteldoor2 - al = 13; - else - al = 0; - playchannel1(); - } - if (objData->b18[sprite->frame] == 255) { - --sprite->frame; - } - sprite->b15 = objData->index = objData->b18[sprite->frame]; - data.byte(kThroughdoor) = 1; - return; -shutdoor: - if (sprite->frame == 5) { //doorsound1; - if (data.byte(kReallocation) == 5) //hoteldoor1 - al = 13; - else - al = 1; - playchannel1(); - } - if (sprite->frame != 0) { - --sprite->frame; + if (sprite->frame == 5) { // doorsound1; + if (data.byte(kReallocation) == 5) // hoteldoor1 + al = 13; + else + al = 1; + playchannel1(); + } + if (sprite->frame != 0) + --sprite->frame; + + sprite->b15 = objData->index = objData->b18[sprite->frame]; + if (sprite->frame == 5) // nearly + data.byte(kThroughdoor) = 0; } - sprite->b15 = objData->index = objData->b18[sprite->frame]; - if (sprite->frame == 5) //nearly - data.byte(kThroughdoor) = 0; } void DreamGenContext::steady(Sprite *sprite, SetObject *objData) { @@ -374,66 +359,56 @@ void DreamGenContext::steady(Sprite *sprite, SetObject *objData) { } void DreamGenContext::lockeddoorway(Sprite *sprite, SetObject *objData) { - if (data.byte(kRyanx) < sprite->x) { - if (sprite->x - data.byte(kRyanx) > 24) - goto shutdoor2; - } else { - if (data.byte(kRyanx) - sprite->x >= 10) - goto shutdoor2; - } - if (data.byte(kRyany) < sprite->y) { - if (sprite->y - data.byte(kRyany) > 30) - goto shutdoor2; - } else { - if (data.byte(kRyany) - sprite->y >= 12) - goto shutdoor2; - } + int ryanx = data.byte(kRyanx); + int ryany = data.byte(kRyany); - if (data.byte(kThroughdoor) != 1) { - if (data.byte(kLockstatus) == 1) - goto shutdoor2; - } + Common::Rect check(-24, -30, 10, 12); + check.translate(sprite->x, sprite->y); + bool openDoor = check.contains(ryanx, ryany); - if (sprite->frame == 1) { - al = 0; - playchannel1(); - } + if (data.byte(kThroughdoor) != 1 && data.byte(kLockstatus) == 1) + openDoor = false; - if (sprite->frame == 6) { - turnpathon(data.byte(kDoorpath)); - } + if (openDoor) { - if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) { - sprite->frame = 6; - } + if (sprite->frame == 1) { + al = 0; + playchannel1(); + } - ++sprite->frame; - if (objData->b18[sprite->frame] == 255) { - --sprite->frame; - } + if (sprite->frame == 6) + turnpathon(data.byte(kDoorpath)); - sprite->b15 = objData->index = objData->b18[sprite->frame]; - if (sprite->frame == 5) - data.byte(kThroughdoor) = 1; - return; + if (data.byte(kThroughdoor) == 1 && sprite->frame == 0) + sprite->frame = 6; -shutdoor2: - if (sprite->frame == 5) { - al = 1; - playchannel1(); - } + ++sprite->frame; + if (objData->b18[sprite->frame] == 255) + --sprite->frame; - if (sprite->frame != 0) { - --sprite->frame; - } + sprite->b15 = objData->index = objData->b18[sprite->frame]; + if (sprite->frame == 5) + data.byte(kThroughdoor) = 1; - data.byte(kThroughdoor) = 0; - sprite->b15 = objData->index = objData->b18[sprite->frame]; + } else { + // shut door - if (sprite->frame == 0) { - turnpathoff(data.byte(kDoorpath)); - data.byte(kLockstatus) = 1; + if (sprite->frame == 5) { + al = 1; + playchannel1(); + } + + if (sprite->frame != 0) + --sprite->frame; + + data.byte(kThroughdoor) = 0; + sprite->b15 = objData->index = objData->b18[sprite->frame]; + + if (sprite->frame == 0) { + turnpathoff(data.byte(kDoorpath)); + data.byte(kLockstatus) = 1; + } } } @@ -494,43 +469,30 @@ void DreamGenContext::facerightway() { data.byte(kLeavedirection) = dir; } -void DreamGenContext::findsource() { +Frame *DreamGenContext::findsource() { uint16 currentFrame = data.word(kCurrentframe); if (currentFrame < 160) { - ds = data.word(kReel1); data.word(kTakeoff) = 0; + return (Frame *)segRef(data.word(kReel1)).ptr(0, 0); } else if (currentFrame < 320) { - ds = data.word(kReel2); data.word(kTakeoff) = 160; + return (Frame *)segRef(data.word(kReel2)).ptr(0, 0); } else { - ds = data.word(kReel3); data.word(kTakeoff) = 320; + return (Frame *)segRef(data.word(kReel3)).ptr(0, 0); } } -Frame *DreamGenContext::findsourceCPP() { - push(ds); - findsource(); - Frame *result = (Frame *)ds.ptr(0, 0); - ds = pop(); - return result; -} - Reel *DreamGenContext::getreelstart() { Reel *reel = (Reel *)segRef(data.word(kReels)).ptr(kReellist + data.word(kReelpointer) * sizeof(Reel) * 8, sizeof(Reel)); return reel; } -void DreamGenContext::showreelframe() { - Reel *reel = (Reel *)es.ptr(si, sizeof(Reel)); - showreelframe(reel); -} - void DreamGenContext::showreelframe(Reel *reel) { uint16 x = reel->x + data.word(kMapadx); uint16 y = reel->y + data.word(kMapady); data.word(kCurrentframe) = reel->frame(); - Frame *source = findsourceCPP(); + Frame *source = findsource(); uint16 frame = data.word(kCurrentframe) - data.word(kTakeoff); showframe(source, x, y, frame, 8); } @@ -550,7 +512,7 @@ void DreamGenContext::showgamereel(ReelRoutine *routine) { const Frame *DreamGenContext::getreelframeax(uint16 frame) { data.word(kCurrentframe) = frame; - Frame *source = findsourceCPP(); + Frame *source = findsource(); uint16 offset = data.word(kCurrentframe) - data.word(kTakeoff); return source + offset; } @@ -598,148 +560,57 @@ void DreamGenContext::showrain() { } } +static void (DreamGenContext::*reelCallbacks[])() = { + &DreamGenContext::gamer, &DreamGenContext::sparkydrip, + &DreamGenContext::eden, &DreamGenContext::edeninbath, + &DreamGenContext::sparky, &DreamGenContext::smokebloke, + &DreamGenContext::manasleep, &DreamGenContext::drunk, + &DreamGenContext::receptionist, &DreamGenContext::malefan, + &DreamGenContext::femalefan, &DreamGenContext::louis, + &DreamGenContext::louischair, &DreamGenContext::soldier1, + &DreamGenContext::bossman, &DreamGenContext::interviewer, + &DreamGenContext::heavy, &DreamGenContext::manasleep2, + &DreamGenContext::mansatstill, &DreamGenContext::drinker, + &DreamGenContext::bartender, &DreamGenContext::othersmoker, + &DreamGenContext::tattooman, &DreamGenContext::attendant, + &DreamGenContext::keeper, &DreamGenContext::candles1, + &DreamGenContext::smallcandle, &DreamGenContext::security, + &DreamGenContext::copper, &DreamGenContext::poolguard, + &DreamGenContext::rockstar, &DreamGenContext::businessman, + &DreamGenContext::train, &DreamGenContext::aide, + &DreamGenContext::mugger, &DreamGenContext::helicopter, + &DreamGenContext::intromagic1, &DreamGenContext::intromusic, + &DreamGenContext::intromagic2, &DreamGenContext::candles2, + &DreamGenContext::gates, &DreamGenContext::intromagic3, + &DreamGenContext::intromonks1, &DreamGenContext::candles, + &DreamGenContext::intromonks2, &DreamGenContext::handclap, + &DreamGenContext::monkandryan, &DreamGenContext::endgameseq, + &DreamGenContext::priest, &DreamGenContext::madman, + &DreamGenContext::madmanstelly, &DreamGenContext::alleybarksound, + &DreamGenContext::foghornsound, &DreamGenContext::carparkdrip, + &DreamGenContext::carparkdrip, &DreamGenContext::carparkdrip, + &DreamGenContext::carparkdrip +}; + + void DreamGenContext::updatepeople() { data.word(kListpos) = kPeoplelist; memset(segRef(data.word(kBuffers)).ptr(kPeoplelist, 12 * sizeof(People)), 0xff, 12 * sizeof(People)); ++data.word(kMaintimer); + + // The callbacks are called with es:bx pointing to their reelRoutine entry. + // They use some of the fields in it to store state. + es = cs; - bx = kReelroutines; - const ReelRoutine *reelRoutine = (const ReelRoutine *)cs.ptr(bx, 0); - const uint16 *callbacks = (const uint16 *)cs.ptr(kReelcalls, 0); - while (true) { - uint8 realLocation = reelRoutine->reallocation; - if (realLocation == 255) - return; - if ((realLocation == data.byte(kReallocation)) && - (reelRoutine->mapX == data.byte(kMapx)) && - (reelRoutine->mapY == data.byte(kMapy))) { - uint16 callback = READ_LE_UINT16(callbacks); - //dw gamer,sparkydrip,eden,edeninbath,sparky,smokebloke - if (callback == addr_gamer) - gamer(); - else if (callback == addr_sparkydrip) - sparkydrip(); - else if (callback == addr_eden) - eden(); - else if (callback == addr_edeninbath) - edeninbath(); - else if (callback == addr_sparky) - sparky(); - else if (callback == addr_smokebloke) - smokebloke(); - //dw manasleep,drunk,receptionist,malefan,femalefan - else if (callback == addr_manasleep) - manasleep(); - else if (callback == addr_drunk) - drunk(); - else if (callback == addr_receptionist) - receptionist(); - else if (callback == addr_malefan) - malefan(); - else if (callback == addr_femalefan) - femalefan(); - //dw louis,louischair,soldier1,bossman,interviewer - else if (callback == addr_louis) - louis(); - else if (callback == addr_louischair) - louischair(); - else if (callback == addr_soldier1) - soldier1(); - else if (callback == addr_bossman) - bossman(); - else if (callback == addr_interviewer) - interviewer(); - //dw heavy,manasleep2,mansatstill,drinker,bartender - else if (callback == addr_heavy) - heavy(); - else if (callback == addr_manasleep2) - manasleep2(); - else if (callback == addr_mansatstill) - mansatstill(); - else if (callback == addr_drinker) - drinker(); - else if (callback == addr_bartender) - bartender(); - //dw othersmoker,tattooman,attendant,keeper,candles1 - else if (callback == addr_othersmoker) - othersmoker(); - else if (callback == addr_tattooman) - tattooman(); - else if (callback == addr_attendant) - attendant(); - else if (callback == addr_keeper) - keeper(); - else if (callback == addr_candles1) - candles1(); - //dw smallcandle,security,copper,poolguard,rockstar - else if (callback == addr_smallcandle) - smallcandle(); - else if (callback == addr_security) - security(); - else if (callback == addr_copper) - copper(); - else if (callback == addr_poolguard) - poolguard(); - else if (callback == addr_rockstar) - rockstar(); - //dw businessman,train,aide,mugger,helicopter - else if (callback == addr_businessman) - businessman(); - else if (callback == addr_train) - train(); - else if (callback == addr_aide) - aide(); - else if (callback == addr_mugger) - mugger(); - else if (callback == addr_helicopter) - helicopter(); - //dw intromagic1,intromusic,intromagic2,candles2,gates - else if (callback == addr_intromagic1) - intromagic1(); - else if (callback == addr_intromusic) - intromusic(); - else if (callback == addr_intromagic2) - intromagic2(); - else if (callback == addr_candles2) - candles2(); - else if (callback == addr_gates) - gates(); - //dw intromagic3,intromonks1,candles,intromonks2 - else if (callback == addr_intromagic3) - intromagic3(); - else if (callback == addr_intromonks1) - intromonks1(); - else if (callback == addr_candles) - candles(); - else if (callback == addr_intromonks2) - intromonks2(); - //dw handclap,monkandryan,endgameseq,priest,madman - else if (callback == addr_handclap) - handclap(); - else if (callback == addr_monkandryan) - monkandryan(); - else if (callback == addr_endgameseq) - endgameseq(); - else if (callback == addr_priest) - priest(); - else if (callback == addr_madman) - madman(); - //dw madmanstelly,alleybarksound,foghornsound - else if (callback == addr_madmanstelly) - madmanstelly(); - else if (callback == addr_alleybarksound) - alleybarksound(); - else if (callback == addr_foghornsound) - foghornsound(); - //dw carparkdrip,carparkdrip,carparkdrip,carparkdrip - else if (callback == addr_carparkdrip) - carparkdrip(); - else - assert(false); // Oops I forgot something in the dispatch table + const ReelRoutine *r = (const ReelRoutine *)cs.ptr(kReelroutines, 0); + + for (int i = 0; r[i].reallocation != 255; ++i) { + bx = kReelroutines + 8*i; + if (r[i].reallocation == data.byte(kReallocation) && + r[i].mapX == data.byte(kMapx) && + r[i].mapY == data.byte(kMapy)) { + (this->*(reelCallbacks[i]))(); } - bx += 8; - ++reelRoutine; - ++callbacks; } } @@ -903,5 +774,236 @@ void DreamGenContext::addtopeoplelist(ReelRoutine *routine) { data.word(kListpos) += sizeof(People); } +Rain *DreamGenContext::splitintolines(uint8 x, uint8 y, Rain *rain) { + do { + // Look for line start + while (!getblockofpixel(x, y)) { + --x; + ++y; + if (x == 0 || y >= data.byte(kMapysize)) + return rain; + } + + rain->x = x; + rain->y = y; + + uint8 length = 1; + + // Look for line end + while (getblockofpixel(x, y)) { + --x; + ++y; + if (x == 0 || y >= data.byte(kMapysize)) + break; + ++length; + } + + rain->size = length; + rain->w3_lo = engine->randomNumber(); + rain->w3_hi = engine->randomNumber(); + rain->b5 = (engine->randomNumber() & 3) + 4; + ++rain; + } while (x > 0 && y < data.byte(kMapysize)); + + return rain; +} + +struct RainLocation { + uint8 location; + uint8 x, y; + uint8 rainSpacing; +}; + +static const RainLocation rainLocationList[] = { + { 1,44,10,16 }, + { 4,11,30,14 }, + { 4,22,30,14 }, + { 3,33,10,14 }, + { 10,33,30,14 }, + { 10,22,30,24 }, + { 9,22,10,14 }, + { 2,33,0,14 }, + { 2,22,0,14 }, + { 6,11,30,14 }, + { 7,11,20,18 }, + { 7,0,20,18 }, + { 7,0,30,18 }, + { 55,44,0,14 }, + { 5,22,30,14 }, + + { 8,0,10,18 }, + { 8,11,10,18 }, + { 8,22,10,18 }, + { 8,33,10,18 }, + { 8,33,20,18 }, + { 8,33,30,18 }, + { 8,33,40,18 }, + { 8,22,40,18 }, + { 8,11,40,18 }, + + { 21,44,20,18 }, + { 255,0,0,0 } +}; + +void DreamGenContext::initrain() { + const RainLocation *r = rainLocationList; + Rain *rainList = (Rain *)segRef(data.word(kBuffers)).ptr(kRainlist, 0); + Rain *rain = rainList; + + uint8 rainSpacing = 0; + + // look up location in rainLocationList to determine rainSpacing + for (r = rainLocationList; r->location != 0xff; ++r) { + if (r->location == data.byte(kReallocation) && + r->x == data.byte(kMapx) && r->y == data.byte(kMapy)) { + rainSpacing = r->rainSpacing; + break; + } + } + + if (rainSpacing == 0) { + // location not found in rainLocationList: no rain + rain->x = 0xff; + return; + } + + // start lines of rain from top of screen + uint8 x = 4; + do { + uint8 delta; + do { + delta = (engine->randomNumber() & 31) + 3; + } while (delta >= rainSpacing); + + x += delta; + if (x >= data.byte(kMapxsize)) + break; + + rain = splitintolines(x, 0, rain); + } while (true); + + // start lines of rain from side of screen + uint8 y = 0; + do { + uint8 delta; + do { + delta = (engine->randomNumber() & 31) + 3; + } while (delta >= rainSpacing); + + y += delta; + if (y >= data.byte(kMapysize)) + break; + + rain = splitintolines(data.byte(kMapxsize) - 1, y, rain); + } while (true); + + rain->x = 0xff; +} + +void DreamGenContext::textforend() { + if (data.byte(kIntrocount) == 20) + al = 0; + else if (data.byte(kIntrocount) == (isCD() ? 50 : 65)) + al = 1; + else if (data.byte(kIntrocount) == (isCD() ? 85 : 110)) + al = 2; + else + return; + + bl = 34; + bh = 20; + cx = 60; + dx = 1; + ah = 83; + setuptimedtemp(); +} + +void DreamGenContext::textformonk() { + if (data.byte(kIntrocount) == 1) { + al = 19; + bl = 68; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == 5) { + al = 20; + bl = 68; + bh = 38; + cx = 120; + } else if (data.byte(kIntrocount) == 9) { + al = 21; + bl = 48; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == 13) { + al = 22; + bl = 68; + bh = 38; + cx = 120; + } else if (data.byte(kIntrocount) == (isCD() ? 15 : 17)) { + al = 23; + bl = 68; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == 21) { + al = 24; + bl = 68; + bh = 38; + cx = 120; + } else if (data.byte(kIntrocount) == 25) { + al = 25; + bl = 68; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == 29) { + al = 26; + bl = 68; + bh = 38; + cx = 120; + } else if (data.byte(kIntrocount) == 33) { + al = 27; + bl = 68; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == 37) { + al = 28; + bl = 68; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == 41) { + al = 29; + bl = 68; + bh = 38; + cx = 120; + } else if (data.byte(kIntrocount) == 45) { + al = 30; + bl = 68; + bh = 154; + cx = 120; + } else if (data.byte(kIntrocount) == (isCD() ? 52 : 49)) { + al = 31; + bl = 68; + bh = 154; + cx = 220; + } else if (data.byte(kIntrocount) == 53) { + fadescreendowns(); + if (isCD()) { + data.byte(kVolumeto) = 7; + data.byte(kVolumedirection) = 1; + } + return; + } else { + return; + } + + dx = 1; + ah = 82; + if (isCD() && data.byte(kCh1playing) != 255) { + data.byte(kIntrocount)--; + return; + } + + setuptimedtemp(); +} + } /*namespace dreamgen */ diff --git a/engines/dreamweb/structs.h b/engines/dreamweb/structs.h index 0d7bbb6cbf..c0adbe6823 100644 --- a/engines/dreamweb/structs.h +++ b/engines/dreamweb/structs.h @@ -21,6 +21,7 @@ */ #include "common/endian.h" +#include "common/rect.h" struct Sprite { uint16 _updateCallback; @@ -54,19 +55,15 @@ struct Sprite { uint8 hidden; }; +class DreamGenContext; + struct RectWithCallback { uint16 _xMin, _xMax; uint16 _yMin, _yMax; - uint16 _callback; - - uint16 xMin() const { return READ_LE_UINT16(&_xMin); } - uint16 xMax() const { return READ_LE_UINT16(&_xMax); } - uint16 yMin() const { return READ_LE_UINT16(&_yMin); } - uint16 yMax() const { return READ_LE_UINT16(&_yMax); } - uint16 callback() const { return READ_LE_UINT16(&_callback); } + void (DreamGenContext::*_callback)(); bool contains(uint16 x, uint16 y) const { - return (x >= xMin()) && (x < xMax()) && (y >= yMin()) && (y < yMax()); + return (x >= _xMin) && (x < _xMax) && (y >= _yMin) && (y < _yMax); } }; @@ -185,7 +182,7 @@ struct People { }; struct Room { - uint8 name[10]; + char name[10]; uint8 b10; uint8 b11; uint8 b12; diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index bfa22f431c..eb8f2b8218 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -28,8 +28,19 @@ namespace DreamGen { void DreamGenContext::dreamweb() { STACK_CHECK; + + switch(engine->getLanguage()) { + case Common::EN_ANY: + case Common::EN_GRB: + case Common::EN_USA: + // Implicit data.byte(kForeignrelease) = 0 + break; + default: + data.byte(kForeignrelease) = 1; + break; + } + seecommandtail(); - checkbasemem(); soundstartup(); setkeyboardint(); setupemm(); @@ -140,6 +151,9 @@ void DreamGenContext::dreamweb() { screenupdate(); + if (data.byte(kQuitrequested)) + return; // exit game + if (data.byte(kWongame) != 0) { // "endofgame" clearbeforeload(); @@ -190,12 +204,70 @@ void DreamGenContext::dreamweb() { } static Common::String getFilename(Context &context) { - uint16 name_ptr = context.dx; - Common::String name; - uint8 c; - while((c = context.cs.byte(name_ptr++)) != 0) - name += (char)c; - return name; + const char *name = (const char *)context.cs.ptr(context.dx, 0); + return Common::String(name); +} + +uint16 DreamGenContext::standardload(const char *fileName) { + engine->openFile(fileName); + engine->readFromFile(cs.ptr(kFileheader, kHeaderlen), kHeaderlen); + uint16 sizeInBytes = cs.word(kFiledata); + uint16 result = allocatemem((sizeInBytes + 15) / 16); + engine->readFromFile(segRef(result).ptr(0, 0), sizeInBytes); + engine->closeFile(); + return result; +} + +void DreamGenContext::standardload() { + ax = standardload((const char *)cs.ptr(dx, 0)); +} + +void DreamGenContext::loadintotemp() { + loadintotemp((const char *)cs.ptr(dx, 0)); +} + +void DreamGenContext::loadintotemp2() { + loadintotemp2((const char *)cs.ptr(dx, 0)); +} + +void DreamGenContext::loadintotemp3() { + loadintotemp3((const char *)cs.ptr(dx, 0)); +} + +void DreamGenContext::loadintotemp(const char *fileName) { + data.word(kTempgraphics) = standardload(fileName); +} + +void DreamGenContext::loadintotemp2(const char *fileName) { + data.word(kTempgraphics2) = standardload(fileName); +} + +void DreamGenContext::loadintotemp3(const char *fileName) { + data.word(kTempgraphics3) = standardload(fileName); +} + +void DreamGenContext::loadtempcharset() { + loadtempcharset((const char *)cs.ptr(dx, 0)); +} + +void DreamGenContext::loadtempcharset(const char *fileName) { + data.word(kTempcharset) = standardload(fileName); +} + +void DreamGenContext::printcurs() { + uint16 x = data.word(kCurslocx); + uint16 y = data.word(kCurslocy); + uint16 height; + if (data.byte(kForeignrelease)) { + y -= 3; + height = 11; + } else + height = 8; + multiget(segRef(data.word(kBuffers)).ptr(kTextunder, 0), x, y, 6, height); + ++data.word(kMaintimer); + if ((data.word(kMaintimer) & 16) == 0) + showframe((Frame *)segRef(data.word(kTempcharset)).ptr(0, 0), x, y, '/' - 32, 0); + multidump(x - 6, y, 12, height); } void DreamGenContext::seecommandtail() { @@ -412,6 +484,7 @@ void DreamGenContext::setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, dh = voiceIndex; cl = 'T'; ah = 0; + al = textIndex; loadspeech(); if (data.byte(kSpeechloaded) == 1) { al = 50+12; @@ -421,6 +494,10 @@ void DreamGenContext::setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, cx = pop(); bx = pop(); ax = pop(); + + // FIXME: This fallthrough does not properly support subtitles+speech + // mode. The parameters to setuptimedtemp() are sometimes different + // for speech and for subtitles. See e.g., madmantext() if ((data.byte(kSpeechloaded) == 1) && (data.byte(kSubtitles) != 1)) return; } @@ -502,15 +579,6 @@ void DreamGenContext::removeemm() { } void DreamGenContext::setupemm() { - //good place for early initialization - switch(engine->getLanguage()) { - case Common::EN_ANY: - case Common::EN_GRB: - case Common::EN_USA: - return; - default: - data.byte(kForeignrelease) = 1; - } } void DreamGenContext::pitinterupt() { @@ -669,7 +737,7 @@ void DreamGenContext::eraseoldobs() { return; Sprite *sprites = spritetable(); - for (size_t i=0; i < 16; ++i) { + for (size_t i = 0; i < 16; ++i) { Sprite &sprite = sprites[i]; if (sprite.objData() != 0xffff) { memset(&sprite, 0xff, sizeof(Sprite)); @@ -741,12 +809,12 @@ void DreamGenContext::makebackob(SetObject *objData) { } void DreamGenContext::getroomdata() { - bx = kRoomdata + sizeof(Room) * al; + Room *room = getroomdata(al); + bx = (uint8 *)room - cs.ptr(0, 0); } -void DreamGenContext::startloading() { - const Room *room = (Room *)cs.ptr(bx, sizeof(Room)); - startloading(room); +Room *DreamGenContext::getroomdata(uint8 room) { + return (Room *)cs.ptr(kRoomdata, 0) + room; } void DreamGenContext::readheader() { @@ -775,8 +843,7 @@ void DreamGenContext::startloading(const Room *room) { al = room->b31; ah = data.byte(kReallocation); data.byte(kReallocation) = al; - dx = bx; - Common::String name = getFilename(*this); + Common::String name = room->name; engine->openFile(name); cs.word(kHandle) = 1; //only one handle flags._c = false; @@ -784,10 +851,10 @@ void DreamGenContext::startloading(const Room *room) { allocateload(); ds = ax; data.word(kBackdrop) = ax; - dx = (0); + dx = kFlags; loadseg(); ds = data.word(kWorkspace); - dx = (0); + dx = kMap; cx = 132*66; al = 0; fillspace(); @@ -796,11 +863,11 @@ void DreamGenContext::startloading(const Room *room) { allocateload(); data.word(kSetframes) = ax; ds = ax; - dx = (0); + dx = kFramedata; loadseg(); ds = data.word(kSetdat); dx = 0; - cx = (64*128); + cx = kSetdatlen; al = 255; fillspace(); loadseg(); @@ -851,22 +918,22 @@ void DreamGenContext::startloading(const Room *room) { loadseg(); ds = data.word(kFreedat); dx = 0; - cx = (16*80); + cx = kFreedatlen; al = 255; fillspace(); loadseg(); allocateload(); data.word(kFreedesc) = ax; ds = ax; - dx = (0); + dx = kFreetextdat; loadseg(); closefile(); findroominloc(); deletetaken(); setallchanges(); autoappear(); - al = data.byte(kNewlocation); - getroomdata(); + Room *newRoom = getroomdata(data.byte(kNewlocation)); + bx = (uint8 *)newRoom - cs.ptr(0, 0); data.byte(kLastweapon) = (uint8)-1; data.byte(kMandead) = 0; data.word(kLookcounter) = 160; @@ -917,11 +984,7 @@ void DreamGenContext::dealwithspecial(uint8 firstParam, uint8 secondParam) { void DreamGenContext::plotreel() { Reel *reel = getreelstart(); - while (true) { - if (reel->x < 220) - break; - if (reel->x == 255) - break; + while (reel->x >= 220 && reel->x != 255) { dealwithspecial(reel->x, reel->y); ++data.word(kReelpointer); reel += 8; @@ -1144,29 +1207,24 @@ void DreamGenContext::findormake() { void DreamGenContext::findormake(uint8 index, uint8 value, uint8 type) { Change *change = (Change *)segRef(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change)); - while (true) { - if (change->index == 0xff) { - change->index = index; - change->location = data.byte(kReallocation); + for (; change->index != 0xff; ++change) { + if (index == change->index && data.byte(kReallocation) == change->location && type == change->type) { change->value = value; - change->type = type; return; } - if ((index == change->index) && (data.byte(kReallocation) == change->location) && (type == change->type)) { - change->value = value; - return; - } - ++change; } + + change->index = index; + change->location = data.byte(kReallocation); + change->value = value; + change->type = type; } void DreamGenContext::setallchanges() { Change *change = (Change *)segRef(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change)); - while (change->index != 0xff) { + for (; change->index != 0xff; ++change) if (change->location == data.byte(kReallocation)) dochange(change->index, change->value, change->type); - ++change; - } } DynObject *DreamGenContext::getfreead(uint8 index) { @@ -1301,7 +1359,7 @@ void DreamGenContext::getflagunderp(uint8 *flag, uint8 *flagEx) { } void DreamGenContext::walkandexamine() { - if (! finishedwalkingCPP()) + if (!finishedwalkingCPP()) return; data.byte(kCommandtype) = data.byte(kWalkexamtype); data.byte(kCommand) = data.byte(kWalkexamnum); @@ -1434,160 +1492,160 @@ void DreamGenContext::dumppointer() { } void DreamGenContext::checkcoords() { - checkcoords((const RectWithCallback *)cs.ptr(bx, 0)); + + // FIXME: Move all these lists to the callers + + switch ((uint16)bx) { + case offset_talklist: { + RectWithCallback talklist[] = { + { 273,320,157,198,&DreamGenContext::getback1 }, + { 240,290,2,44,&DreamGenContext::moretalk }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(talklist); + break; + } + case offset_quitlist: { + RectWithCallback quitlist[] = { + { 273,320,157,198,&DreamGenContext::getback1 }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(quitlist); + break; + } + case offset_destlist: { + RectWithCallback destlist[] = { + { 238,258,4,44,&DreamGenContext::nextdest }, + { 104,124,4,44,&DreamGenContext::lastdest }, + { 280,308,4,44,&DreamGenContext::lookatplace }, + { 104,216,138,192,&DreamGenContext::destselect }, + { 273,320,157,198,&DreamGenContext::getback1 }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(destlist); + break; + } + case offset_keypadlist: { + RectWithCallback keypadlist[] = { + { kKeypadx+9,kKeypadx+30,kKeypady+9,kKeypady+22,&DreamGenContext::buttonone }, + { kKeypadx+31,kKeypadx+52,kKeypady+9,kKeypady+22,&DreamGenContext::buttontwo }, + { kKeypadx+53,kKeypadx+74,kKeypady+9,kKeypady+22,&DreamGenContext::buttonthree }, + { kKeypadx+9,kKeypadx+30,kKeypady+23,kKeypady+40,&DreamGenContext::buttonfour }, + { kKeypadx+31,kKeypadx+52,kKeypady+23,kKeypady+40,&DreamGenContext::buttonfive }, + { kKeypadx+53,kKeypadx+74,kKeypady+23,kKeypady+40,&DreamGenContext::buttonsix }, + { kKeypadx+9,kKeypadx+30,kKeypady+41,kKeypady+58,&DreamGenContext::buttonseven }, + { kKeypadx+31,kKeypadx+52,kKeypady+41,kKeypady+58,&DreamGenContext::buttoneight }, + { kKeypadx+53,kKeypadx+74,kKeypady+41,kKeypady+58,&DreamGenContext::buttonnine }, + { kKeypadx+9,kKeypadx+30,kKeypady+59,kKeypady+73,&DreamGenContext::buttonnought }, + { kKeypadx+31,kKeypadx+74,kKeypady+59,kKeypady+73,&DreamGenContext::buttonenter }, + { kKeypadx+72,kKeypadx+86,kKeypady+80,kKeypady+94,&DreamGenContext::quitkey }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(keypadlist); + break; + } + case offset_menulist: { + RectWithCallback menulist[] = { + { kMenux+54,kMenux+68,kMenuy+72,kMenuy+88,&DreamGenContext::quitkey }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(menulist); + break; + } + case offset_folderlist: { + RectWithCallback folderlist[] = { + { 280,320,160,200,&DreamGenContext::quitkey }, + { 143,300,6,194,&DreamGenContext::nextfolder }, + { 0,143,6,194,&DreamGenContext::lastfolder }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(folderlist); + break; + } + case offset_symbollist: { + RectWithCallback symbollist[] = { + { kSymbolx+40,kSymbolx+64,kSymboly+2,kSymboly+16,&DreamGenContext::quitsymbol }, + { kSymbolx,kSymbolx+52,kSymboly+20,kSymboly+50,&DreamGenContext::settopleft }, + { kSymbolx+52,kSymbolx+104,kSymboly+20,kSymboly+50,&DreamGenContext::settopright }, + { kSymbolx,kSymbolx+52,kSymboly+50,kSymboly+80,&DreamGenContext::setbotleft }, + { kSymbolx+52,kSymbolx+104,kSymboly+50,kSymboly+80,&DreamGenContext::setbotright }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(symbollist); + + break; + } + case offset_diarylist: { + RectWithCallback diarylist[] = { + { kDiaryx+94,kDiaryx+110,kDiaryy+97,kDiaryy+113,&DreamGenContext::diarykeyn }, + { kDiaryx+151,kDiaryx+167,kDiaryy+71,kDiaryy+87,&DreamGenContext::diarykeyp }, + { kDiaryx+176,kDiaryx+192,kDiaryy+108,kDiaryy+124,&DreamGenContext::quitkey }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(diarylist); + break; + } + case offset_opslist: { + RectWithCallback opslist[] = { + { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamGenContext::getbackfromops }, + { kOpsx+10,kOpsx+77,kOpsy+10,kOpsy+59,&DreamGenContext::dosreturn }, + { kOpsx+128,kOpsx+190,kOpsy+16,kOpsy+100,&DreamGenContext::discops }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(opslist); + break; + } + case offset_discopslist: { + RectWithCallback discopslist[] = { + { kOpsx+59,kOpsx+114,kOpsy+30,kOpsy+76,&DreamGenContext::loadgame }, + { kOpsx+10,kOpsx+79,kOpsy+10,kOpsy+59,&DreamGenContext::savegame }, + { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getbacktoops }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(discopslist); + break; + } + case offset_decidelist: { + RectWithCallback decidelist[] = { + { kOpsx+69,kOpsx+124,kOpsy+30,kOpsy+76,&DreamGenContext::newgame }, + { kOpsx+20,kOpsx+87,kOpsy+10,kOpsy+59,&DreamGenContext::dosreturn }, + { kOpsx+123,kOpsx+190,kOpsy+10,kOpsy+59,&DreamGenContext::loadold }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(decidelist); + break; + } + default: + ::error("Unimplemented checkcoords() call"); + } } + void DreamGenContext::checkcoords(const RectWithCallback *rectWithCallbacks) { if (data.byte(kNewlocation) != 0xff) return; - const RectWithCallback *rectWithCallback = rectWithCallbacks; - while (rectWithCallback->xMin() != 0xffff) { - if (rectWithCallback->contains(data.word(kMousex), data.word(kMousey))) { - uint16 callback = rectWithCallback->callback(); - - // common - if(callback == addr_blank) - blank(); - else if(callback == addr_getbackfromob) - getbackfromob(); - else if(callback == addr_incryanpage) - incryanpage(); - else if(callback == addr_getback1) - getback1(); - else if(callback == addr_quitkey) - quitkey(); - else if(callback == addr_dosreturn) - dosreturn(); - else if(callback == addr_getbacktoops) - getbacktoops(); - else if(callback == addr_selectslot) - selectslot(); - // examlist - else if(callback == addr_useobject) - useobject(); - else if(callback == addr_selectopenob) - selectopenob(); - else if(callback == addr_setpickup) - setpickup(); - else if(callback == addr_examinventory) - examinventory(); - // invlist1 - else if(callback == addr_dropobject) - dropobject(); - else if(callback == addr_useopened) - useopened(); - else if(callback == addr_setpickup) - setpickup(); - else if(callback == addr_intoinv) - intoinv(); - // withlist1 - else if(callback == addr_selectob) - selectob(); - // talklist - else if(callback == addr_moretalk) - moretalk(); - // quitlist - // destlist - else if(callback == addr_nextdest) - nextdest(); - else if(callback == addr_lastdest) - lastdest(); - else if(callback == addr_lookatplace) - lookatplace(); - else if(callback == addr_destselect) - destselect(); - // keypadlist - else if(callback == addr_buttonone) - buttonone(); - else if(callback == addr_buttontwo) - buttontwo(); - else if(callback == addr_buttonthree) - buttonthree(); - else if(callback == addr_buttonfour) - buttonfour(); - else if(callback == addr_buttonfive) - buttonfive(); - else if(callback == addr_buttonsix) - buttonsix(); - else if(callback == addr_buttonseven) - buttonseven(); - else if(callback == addr_buttoneight) - buttoneight(); - else if(callback == addr_buttonnine) - buttonnine(); - else if(callback == addr_buttonnought) - buttonnought(); - else if(callback == addr_buttonenter) - buttonenter(); - // menulist - // folderlist - else if(callback == addr_nextfolder) - nextfolder(); - else if(callback == addr_lastfolder) - lastfolder(); - // symbollist - else if(callback == addr_quitsymbol) - quitsymbol(); - else if(callback == addr_settopleft) - settopleft(); - else if(callback == addr_settopright) - settopright(); - else if(callback == addr_setbotleft) - setbotleft(); - else if(callback == addr_setbotright) - setbotright(); - // diarylist - else if(callback == addr_diarykeyn) - diarykeyn(); - else if(callback == addr_diarykeyp) - diarykeyp(); - else if(callback == addr_quitkey) - quitkey(); - // opslist - else if(callback == addr_getbackfromops) - getbackfromops(); - else if(callback == addr_discops) - discops(); - // discopslist - else if(callback == addr_loadgame) - loadgame(); - else if(callback == addr_savegame) - savegame(); - // mainlist, mainlist2 - else if(callback == addr_look) - look(); - else if(callback == addr_inventory) - inventory(); - else if(callback == addr_zoomonoff) - zoomonoff(); - else if(callback == addr_saveload) - saveload(); - else if(callback == addr_madmanrun) - madmanrun(); - else if(callback == addr_identifyob) - identifyob(); - // decidelist - else if(callback == addr_newgame) - newgame(); - else if(callback == addr_loadold) - loadold(); - // loadlist - else if(callback == addr_actualload) - actualload(); - // savelist - else if(callback == addr_actualsave) - actualsave(); - else { - debug("__dispatch_call remaining in checkcoords! %d", (int)callback); - __dispatch_call(callback); - } + const RectWithCallback *r; + for (r = rectWithCallbacks; r->_xMin != 0xffff; ++r) { + if (r->contains(data.word(kMousex), data.word(kMousey))) { + (this->*(r->_callback))(); return; } - ++rectWithCallback; } } + void DreamGenContext::showpointer() { showblink(); const Frame *icons1 = ((const Frame *)segRef(data.word(kIcons1)).ptr(0, 0)); @@ -1725,6 +1783,25 @@ bool DreamGenContext::isCD() { return (data.byte(kSpeechloaded) == 1); } +void DreamGenContext::showicon() { + if (data.byte(kReallocation) < 50) { + showpanel(); + showman(); + roomname(); + panelicons1(); + zoomicon(); + } else { + Frame *tempSprites = (Frame *)segRef(data.word(kTempsprites)).ptr(0, 0); + showframe(tempSprites, 72, 2, 45, 0); + showframe(tempSprites, 72+47, 2, 46, 0); + showframe(tempSprites, 69-10, 21, 49, 0); + showframe(tempSprites, 160+88, 2, 45, 4 & 0xfe); + showframe(tempSprites, 160+43, 2, 46, 4 & 0xfe); + showframe(tempSprites, 160+101, 21, 49, 4 & 0xfe); + middlepanel(); + } +} + void DreamGenContext::checkifset() { flags._z = !checkifset(al, ah); } @@ -1886,5 +1963,174 @@ void DreamGenContext::zoomonoff() { worktoscreenm(); } +void DreamGenContext::sortoutmap() { + const uint8 *src = (const uint8 *)segRef(data.word(kWorkspace)).ptr(0, 0); + uint8 *dst = (uint8 *)segRef(data.word(kMapdata)).ptr(0, 0); + for (uint16 y = 0; y < kMaplength; ++y) { + memcpy(dst, src, kMapwidth); + dst += kMapwidth; + src += 132; + } +} + +void DreamGenContext::showcity() { + clearwork(); + Frame *tempGraphics = (Frame *)segRef(data.word(kTempgraphics)).ptr(0, 0); + showframe(tempGraphics, 57, 32, 0, 0); + showframe(tempGraphics, 120+57, 32, 1, 0); +} + +void DreamGenContext::mainscreen() { + data.byte(kInmaparea) = 0; + if (data.byte(kWatchon) == 1) { + RectWithCallback mainlist[] = { + { 44,70,32,46,&DreamGenContext::look }, + { 0,50,0,180,&DreamGenContext::inventory }, + { 226,244,10,26,&DreamGenContext::zoomonoff }, + { 226,244,26,40,&DreamGenContext::saveload }, + { 240,260,100,124,&DreamGenContext::madmanrun }, + { 0,320,0,200,&DreamGenContext::identifyob }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(mainlist); + } else { + RectWithCallback mainlist2[] = { + { 44,70,32,46,&DreamGenContext::look }, + { 0,50,0,180,&DreamGenContext::inventory }, + { 226+48,244+48,10,26,&DreamGenContext::zoomonoff }, + { 226+48,244+48,26,40,&DreamGenContext::saveload }, + { 240,260,100,124,&DreamGenContext::madmanrun }, + { 0,320,0,200,&DreamGenContext::identifyob }, + { 0xFFFF,0,0,0,0 } + }; + checkcoords(mainlist2); + } + + if (data.byte(kWalkandexam) != 0) + walkandexamine(); +} + +void DreamGenContext::showwatch() { + if (data.byte(kWatchon)) { + showframe((Frame *)segRef(data.word(kIcons1)).ptr(0, 0), 250, 1, 6, 0); + showtime(); + } +} + +void DreamGenContext::showtime() { + if (data.byte(kWatchon) == 0) + return; + Frame *charset = (Frame *)segRef(data.word(kCharset1)).ptr(0, 0); + + int seconds = data.byte(kSecondcount); + int minutes = data.byte(kMinutecount); + int hours = data.byte(kHourcount); + + showframe(charset, 282+5, 21, 91*3+10 + seconds / 10, 0); + showframe(charset, 282+9, 21, 91*3+10 + seconds % 10, 0); + + showframe(charset, 270+5, 21, 91*3 + minutes / 10, 0); + showframe(charset, 270+11, 21, 91*3 + minutes % 10, 0); + + showframe(charset, 256+5, 21, 91*3 + hours / 10, 0); + showframe(charset, 256+11, 21, 91*3 + hours % 10, 0); + + showframe(charset, 267+5, 21, 91*3+20, 0); +} + +void DreamGenContext::watchcount() { + if (data.byte(kWatchon) == 0) + return; + ++data.byte(kTimercount); + if (data.byte(kTimercount) == 9) { + showframe((Frame *)segRef(data.word(kCharset1)).ptr(0, 0), 268+4, 21, 91*3+21, 0); + data.byte(kWatchdump) = 1; + } else if (data.byte(kTimercount) == 18) { + data.byte(kTimercount) = 0; + ++data.byte(kSecondcount); + if (data.byte(kSecondcount) == 60) { + data.byte(kSecondcount) = 0; + ++data.byte(kMinutecount); + if (data.byte(kMinutecount) == 60) { + data.byte(kMinutecount) = 0; + ++data.byte(kHourcount); + if (data.byte(kHourcount) == 24) + data.byte(kHourcount) = 0; + } + } + showtime(); + data.byte(kWatchdump) = 1; + } +} + +void DreamGenContext::roomname() { + printmessage(88, 18, 53, 240, false); + uint16 textIndex = data.byte(kRoomnum); + if (textIndex >= 32) + textIndex -= 32; + data.word(kLinespacing) = 7; + uint8 maxWidth = (data.byte(kWatchon) == 1) ? 120 : 160; + uint16 descOffset = segRef(data.word(kRoomdesc)).word(kIntextdat + textIndex * 2); + const uint8 *string = segRef(data.word(kRoomdesc)).ptr(kIntext + descOffset, 0); + printdirect(string, 88, 25, maxWidth, false); + data.word(kLinespacing) = 10; + usecharset1(); +} + +void DreamGenContext::zoomicon() { + if (data.byte(kZoomon) == 0) + return; + showframe((Frame *)segRef(data.word(kIcons1)).ptr(0, 0), kZoomx, kZoomy-1, 8, 0); +} + +void DreamGenContext::loadroom() { + data.byte(kRoomloaded) = 1; + data.word(kTimecount) = 0; + data.word(kMaintimer) = 0; + data.word(kMapoffsetx) = 104; + data.word(kMapoffsety) = 38; + data.word(kTextaddressx) = 13; + data.word(kTextaddressy) = 182; + data.byte(kTextlen) = 240; + data.byte(kLocation) = data.byte(kNewlocation); + Room *room = getroomdata(data.byte(kNewlocation)); + startloading(room); + loadroomssample(); + switchryanon(); + drawflags(); + getdimension(); +} + +void DreamGenContext::loadroomssample() { + uint8 sample = data.byte(kRoomssample); + + if (sample == 255 || data.byte(kCurrentsample) == sample) + return; // loaded already + + data.byte(kCurrentsample) = sample; + cs.byte(kSamplename+10) = '0' + sample / 10; + cs.byte(kSamplename+11) = '0' + sample % 10; + dx = kSamplename; + loadsecondsample(); +} + +void DreamGenContext::readsetdata() { + data.word(kCharset1) = standardload((const char *)cs.ptr(kCharacterset1, 0)); + data.word(kIcons1) = standardload((const char *)cs.ptr(kIcongraphics0, 0)); + data.word(kIcons2) = standardload((const char *)cs.ptr(kIcongraphics1, 0)); + data.word(kMainsprites) = standardload((const char *)cs.ptr(kSpritename1, 0)); + data.word(kPuzzletext) = standardload((const char *)cs.ptr(kPuzzletextname, 0)); + data.word(kCommandtext) = standardload((const char *)cs.ptr(kCommandtextname, 0)); + ax = data.word(kCharset1); + data.word(kCurrentset) = ax; + if (data.byte(kSoundint) == 0xff) + return; + Common::String name((const char*)cs.ptr(kVolumetabname, 0)); + engine->openFile(name); + uint8 *volumeTab = segRef(data.word(kSoundbuffer)).ptr(16384, 0); + engine->readFromFile(volumeTab, 2048-256); + engine->closeFile(); +} + } /*namespace dreamgen */ diff --git a/engines/dreamweb/stubs.h b/engines/dreamweb/stubs.h index ac7e1a5b91..ca7b74f19b 100644 --- a/engines/dreamweb/stubs.h +++ b/engines/dreamweb/stubs.h @@ -23,6 +23,17 @@ uint8 *workspace(); void allocatework(); void clearwork(); + void standardload(); + uint16 standardload(const char *fileName); // Returns a segment handle which needs to be freed with deallocatemem for symmetry + void loadintotemp(); + void loadintotemp2(); + void loadintotemp3(); + void loadintotemp(const char *fileName); + void loadintotemp2(const char *fileName); + void loadintotemp3(const char *fileName); + void loadtempcharset(); + void loadtempcharset(const char *fileName); + void printcurs(); void multidump(); void multidump(uint16 x, uint16 y, uint8 width, uint8 height); void frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, int16 x, int16 y); @@ -62,10 +73,13 @@ void getnumber(); uint8 getnumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16 *offset); uint8 kernchars(uint8 firstChar, uint8 secondChar, uint8 width); + void oldtonames(); + void namestoold(); + void loadpalfromiff(); void getroomdata(); + Room *getroomdata(uint8 room); void readheader(); void fillspace(); - void startloading(); void startloading(const Room *room); Sprite *spritetable(); void showframe(); @@ -90,17 +104,14 @@ void constant(Sprite *sprite, SetObject *objData); void steady(Sprite *sprite, SetObject *objData); void random(Sprite *sprite, SetObject *objData); - void dodoor(); - void dodoor(Sprite *sprite, SetObject *objData); + void dodoor(Sprite *sprite, SetObject *objData, Common::Rect check); void doorway(Sprite *sprite, SetObject *objData); void widedoor(Sprite *sprite, SetObject *objData); void lockeddoorway(Sprite *sprite, SetObject *objData); void liftsprite(Sprite *sprite, SetObject *objData); - void findsource(); - Frame *findsourceCPP(); + Frame *findsource(); void showgamereel(); void showgamereel(ReelRoutine *routine); - void showreelframe(); void showreelframe(Reel *reel); const Frame *getreelframeax(uint16 frame); void turnpathon(uint8 param); @@ -237,6 +248,7 @@ void hangon(uint16 frameCount); void hangonp(); void hangonp(uint16 count); + void showicon(); uint8 findnextcolon(uint8 **string); void findnextcolon(); uint8 *getobtextstartCPP(); @@ -246,4 +258,34 @@ uint8 getblockofpixel(uint8 x, uint8 y); void bresenhams(); void examineobtext(); + void sortoutmap(); + void showcity(); + uint16 getpersframe(uint8 index); + void convicons(); + void examineob(bool examineAgain = true); + void showwatch(); + void showtime(); + void roomname(); + void transfertext(); + void initrain(); + Rain *splitintolines(uint8 x, uint8 y, Rain *rain); + uint8 *mainPalette(); + uint8 *startPalette(); + uint8 *endPalette(); + void clearstartpal(); + void clearendpal(); + void paltostartpal(); + void endpaltostart(); + void startpaltoend(); + void paltoendpal(); + void fadecalculation(); + void watchcount(); + void zoomicon(); + void loadroom(); + void getundermenu(); + void putundermenu(); + void textformonk(); + void textforend(); + void readsetdata(); + void loadroomssample(); diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp new file mode 100644 index 0000000000..78b296afe6 --- /dev/null +++ b/engines/dreamweb/talk.cpp @@ -0,0 +1,40 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "dreamweb/dreamweb.h" + +namespace DreamGen { + +uint16 DreamGenContext::getpersframe(uint8 index) { + return segRef(data.word(kPeople)).word(kPersonframes + index * 2); +} + +void DreamGenContext::convicons() { + uint8 index = data.byte(kCharacter) & 127; + data.word(kCurrentframe) = getpersframe(index); + Frame *frame = findsource(); + uint16 frameNumber = (data.word(kCurrentframe) - data.word(kTakeoff)) & 0xff; + showframe(frame, 234, 2, frameNumber, 0); +} + +} /*namespace dreamgen */ + diff --git a/engines/dreamweb/use.cpp b/engines/dreamweb/use.cpp index d6648b556e..b090cbbca7 100644 --- a/engines/dreamweb/use.cpp +++ b/engines/dreamweb/use.cpp @@ -27,95 +27,98 @@ namespace DreamGen { typedef void (DreamGenContext::*UseCallback)(void); +// Note: The callback pointer has been placed before the +// ID to keep MSVC happy (otherwise, it throws warnings +// that alignment of a member was sensitive to packing) struct UseListEntry { - uint8 id[5]; // 0-terminal because it is easier syntatically to initialize the array UseCallback callback; + const char *id; }; void DreamGenContext::useroutine() { static const UseListEntry kUseList[] = { - { "NETW", &DreamGenContext::usemon }, - { "ELVA", &DreamGenContext::useelevator1 }, - { "ELVB", &DreamGenContext::useelevator2 }, - { "ELVC", &DreamGenContext::useelevator3 }, - { "ELVE", &DreamGenContext::useelevator4 }, - { "ELVF", &DreamGenContext::useelevator5 }, - { "CGAT", &DreamGenContext::usechurchgate }, - { "REMO", &DreamGenContext::usestereo }, - { "BUTA", &DreamGenContext::usebuttona }, - { "CBOX", &DreamGenContext::usewinch }, - { "LITE", &DreamGenContext::uselighter }, - { "PLAT", &DreamGenContext::useplate }, - { "LIFT", &DreamGenContext::usecontrol }, - { "WIRE", &DreamGenContext::usewire }, - { "HNDL", &DreamGenContext::usehandle }, - { "HACH", &DreamGenContext::usehatch }, - { "DOOR", &DreamGenContext::useelvdoor }, - { "CSHR", &DreamGenContext::usecashcard }, - { "GUNA", &DreamGenContext::usegun }, - { "CRAA", &DreamGenContext::usecardreader1 }, - { "CRBB", &DreamGenContext::usecardreader2 }, - { "CRCC", &DreamGenContext::usecardreader3 }, - { "SEAT", &DreamGenContext::sitdowninbar }, - { "MENU", &DreamGenContext::usemenu }, - { "COOK", &DreamGenContext::usecooker }, - { "ELCA", &DreamGenContext::callhotellift }, - { "EDCA", &DreamGenContext::calledenslift }, - { "DDCA", &DreamGenContext::calledensdlift }, - { "ALTR", &DreamGenContext::usealtar }, - { "LOKA", &DreamGenContext::openhoteldoor }, - { "LOKB", &DreamGenContext::openhoteldoor2 }, - { "ENTA", &DreamGenContext::openlouis }, - { "ENTB", &DreamGenContext::openryan }, - { "ENTE", &DreamGenContext::openpoolboss }, - { "ENTC", &DreamGenContext::openyourneighbour }, - { "ENTD", &DreamGenContext::openeden }, - { "ENTH", &DreamGenContext::opensarters }, - { "WWAT", &DreamGenContext::wearwatch }, - { "POOL", &DreamGenContext::usepoolreader }, - { "WSHD", &DreamGenContext::wearshades }, - { "GRAF", &DreamGenContext::grafittidoor }, - { "TRAP", &DreamGenContext::trapdoor }, - { "CDPE", &DreamGenContext::edenscdplayer }, - { "DLOK", &DreamGenContext::opentvdoor }, - { "HOLE", &DreamGenContext::usehole }, - { "DRYR", &DreamGenContext::usedryer }, - { "HOLY", &DreamGenContext::usechurchhole }, - { "WALL", &DreamGenContext::usewall }, - { "BOOK", &DreamGenContext::usediary }, - { "AXED", &DreamGenContext::useaxe }, - { "SHLD", &DreamGenContext::useshield }, - { "BCNY", &DreamGenContext::userailing }, - { "LIDC", &DreamGenContext::usecoveredbox }, - { "LIDU", &DreamGenContext::useclearbox }, - { "LIDO", &DreamGenContext::useopenbox }, - { "PIPE", &DreamGenContext::usepipe }, - { "BALC", &DreamGenContext::usebalcony }, - { "WIND", &DreamGenContext::usewindow }, - { "PAPR", &DreamGenContext::viewfolder }, - { "UWTA", &DreamGenContext::usetrainer }, - { "UWTB", &DreamGenContext::usetrainer }, - { "STAT", &DreamGenContext::entersymbol }, - { "TLID", &DreamGenContext::opentomb }, - { "SLAB", &DreamGenContext::useslab }, - { "CART", &DreamGenContext::usecart }, - { "FCAR", &DreamGenContext::usefullcart }, - { "SLBA", &DreamGenContext::slabdoora }, - { "SLBB", &DreamGenContext::slabdoorb }, - { "SLBC", &DreamGenContext::slabdoorc }, - { "SLBD", &DreamGenContext::slabdoord }, - { "SLBE", &DreamGenContext::slabdoore }, - { "SLBF", &DreamGenContext::slabdoorf }, - { "PLIN", &DreamGenContext::useplinth }, - { "LADD", &DreamGenContext::useladder }, - { "LADB", &DreamGenContext::useladderb }, - { "GUMA", &DreamGenContext::chewy }, - { "SQEE", &DreamGenContext::wheelsound }, - { "TAPP", &DreamGenContext::runtap }, - { "GUIT", &DreamGenContext::playguitar }, - { "CONT", &DreamGenContext::hotelcontrol }, - { "BELL", &DreamGenContext::hotelbell }, + { &DreamGenContext::usemon, "NETW" }, + { &DreamGenContext::useelevator1, "ELVA" }, + { &DreamGenContext::useelevator2, "ELVB" }, + { &DreamGenContext::useelevator3, "ELVC" }, + { &DreamGenContext::useelevator4, "ELVE" }, + { &DreamGenContext::useelevator5, "ELVF" }, + { &DreamGenContext::usechurchgate, "CGAT" }, + { &DreamGenContext::usestereo, "REMO" }, + { &DreamGenContext::usebuttona, "BUTA" }, + { &DreamGenContext::usewinch, "CBOX" }, + { &DreamGenContext::uselighter, "LITE" }, + { &DreamGenContext::useplate, "PLAT" }, + { &DreamGenContext::usecontrol, "LIFT" }, + { &DreamGenContext::usewire, "WIRE" }, + { &DreamGenContext::usehandle, "HNDL" }, + { &DreamGenContext::usehatch, "HACH" }, + { &DreamGenContext::useelvdoor, "DOOR" }, + { &DreamGenContext::usecashcard, "CSHR" }, + { &DreamGenContext::usegun, "GUNA" }, + { &DreamGenContext::usecardreader1, "CRAA" }, + { &DreamGenContext::usecardreader2, "CRBB" }, + { &DreamGenContext::usecardreader3, "CRCC" }, + { &DreamGenContext::sitdowninbar, "SEAT" }, + { &DreamGenContext::usemenu, "MENU" }, + { &DreamGenContext::usecooker, "COOK" }, + { &DreamGenContext::callhotellift, "ELCA" }, + { &DreamGenContext::calledenslift, "EDCA" }, + { &DreamGenContext::calledensdlift, "DDCA" }, + { &DreamGenContext::usealtar, "ALTR" }, + { &DreamGenContext::openhoteldoor, "LOKA" }, + { &DreamGenContext::openhoteldoor2, "LOKB" }, + { &DreamGenContext::openlouis, "ENTA" }, + { &DreamGenContext::openryan, "ENTB" }, + { &DreamGenContext::openpoolboss, "ENTE" }, + { &DreamGenContext::openyourneighbour, "ENTC" }, + { &DreamGenContext::openeden, "ENTD" }, + { &DreamGenContext::opensarters, "ENTH" }, + { &DreamGenContext::wearwatch, "WWAT" }, + { &DreamGenContext::usepoolreader, "POOL" }, + { &DreamGenContext::wearshades, "WSHD" }, + { &DreamGenContext::grafittidoor, "GRAF" }, + { &DreamGenContext::trapdoor, "TRAP" }, + { &DreamGenContext::edenscdplayer, "CDPE" }, + { &DreamGenContext::opentvdoor, "DLOK" }, + { &DreamGenContext::usehole, "HOLE" }, + { &DreamGenContext::usedryer, "DRYR" }, + { &DreamGenContext::usechurchhole, "HOLY" }, + { &DreamGenContext::usewall, "WALL" }, + { &DreamGenContext::usediary, "BOOK" }, + { &DreamGenContext::useaxe, "AXED" }, + { &DreamGenContext::useshield, "SHLD" }, + { &DreamGenContext::userailing, "BCNY" }, + { &DreamGenContext::usecoveredbox, "LIDC" }, + { &DreamGenContext::useclearbox, "LIDU" }, + { &DreamGenContext::useopenbox, "LIDO" }, + { &DreamGenContext::usepipe, "PIPE" }, + { &DreamGenContext::usebalcony, "BALC" }, + { &DreamGenContext::usewindow, "WIND" }, + { &DreamGenContext::viewfolder, "PAPR" }, + { &DreamGenContext::usetrainer, "UWTA" }, + { &DreamGenContext::usetrainer, "UWTB" }, + { &DreamGenContext::entersymbol, "STAT" }, + { &DreamGenContext::opentomb, "TLID" }, + { &DreamGenContext::useslab, "SLAB" }, + { &DreamGenContext::usecart, "CART" }, + { &DreamGenContext::usefullcart, "FCAR" }, + { &DreamGenContext::slabdoora, "SLBA" }, + { &DreamGenContext::slabdoorb, "SLBB" }, + { &DreamGenContext::slabdoorc, "SLBC" }, + { &DreamGenContext::slabdoord, "SLBD" }, + { &DreamGenContext::slabdoore, "SLBE" }, + { &DreamGenContext::slabdoorf, "SLBF" }, + { &DreamGenContext::useplinth, "PLIN" }, + { &DreamGenContext::useladder, "LADD" }, + { &DreamGenContext::useladderb, "LADB" }, + { &DreamGenContext::chewy, "GUMA" }, + { &DreamGenContext::wheelsound, "SQEE" }, + { &DreamGenContext::runtap, "TAPP" }, + { &DreamGenContext::playguitar, "GUIT" }, + { &DreamGenContext::hotelcontrol, "CONT" }, + { &DreamGenContext::hotelbell, "BELL" }, }; if (data.byte(kReallocation) >= 50) { diff --git a/engines/dreamweb/vgafades.cpp b/engines/dreamweb/vgafades.cpp new file mode 100644 index 0000000000..10857d2b44 --- /dev/null +++ b/engines/dreamweb/vgafades.cpp @@ -0,0 +1,87 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "dreamweb/dreamweb.h" + +namespace DreamGen { + +uint8 *DreamGenContext::mainPalette() { + return segRef(data.word(kBuffers)).ptr(kMaingamepal, 256*3); +} + +uint8 *DreamGenContext::startPalette() { + return segRef(data.word(kBuffers)).ptr(kStartpal, 256*3); +} + +uint8 *DreamGenContext::endPalette() { + return segRef(data.word(kBuffers)).ptr(kEndpal, 256*3); +} + +void DreamGenContext::clearstartpal() { + memset(startPalette(), 0, 256*3); +} + +void DreamGenContext::clearendpal() { + memset(endPalette(), 0, 256*3); +} + +void DreamGenContext::paltostartpal() { + memcpy(startPalette(), mainPalette(), 256*3); +} + +void DreamGenContext::endpaltostart() { + memcpy(startPalette(), endPalette(), 256*3); +} + +void DreamGenContext::startpaltoend() { + memcpy(endPalette(), startPalette(), 256*3); +} + +void DreamGenContext::paltoendpal() { + memcpy(endPalette(), mainPalette(), 256*3); +} + +void DreamGenContext::fadecalculation() { + if (data.byte(kFadecount) == 0) { + data.byte(kFadedirection) = 0; + return; + } + + uint8 *startPal = startPalette(); + const uint8 *endPal = endPalette(); + for (size_t i = 0; i < 256 * 3; ++i, ++si, ++di) { + uint8 s = startPal[i]; + uint8 e = endPal[i]; + if (s == e) + continue; + else if (s > e) + --startPal[i]; + else { + if (data.byte(kFadecount) <= e) + ++startPal[i]; + } + } + --data.byte(kFadecount); +} + +} /*namespace dreamgen */ + diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp index 53db811313..11ba45f7eb 100644 --- a/engines/dreamweb/vgagrafx.cpp +++ b/engines/dreamweb/vgagrafx.cpp @@ -464,5 +464,29 @@ bool DreamGenContext::pixelcheckset(const ObjPos *pos, uint8 x, uint8 y) { return *ptr != 0; } +void DreamGenContext::loadpalfromiff() { + dx = kPalettescreen; + openfile(); + cx = 2000; + ds = data.word(kMapstore); + dx = 0; + readfromfile(); + closefile(); + + const uint8 *src = segRef(data.word(kMapstore)).ptr(0x30, 0); + uint8 *dst = mainPalette(); + for (size_t i = 0; i < 256*3; ++i) { + uint8 c = src[i] / 4; + if (data.byte(kBrightness) == 1) { + if (c) { + c = c + c / 2 + c / 4; + if (c > 63) + c = 63; + } + } + dst[i] = c; + } +} + } /*namespace dreamgen */ diff --git a/engines/engine.cpp b/engines/engine.cpp index ee1d53fa9c..e4e4630841 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -479,10 +479,20 @@ void Engine::syncSoundSettings() { if (ConfMan.hasKey("mute")) mute = ConfMan.getBool("mute"); + // We need to handle the speech mute separately here. This is because the + // engine code should be able to rely on all speech sounds muted when the + // user specified subtitles only mode, which results in "speech_mute" to + // be set to "true". The global mute setting has precedence over the + // speech mute setting though. + bool speechMute = mute; + if (!speechMute) + speechMute = ConfMan.getBool("speech_mute"); + _mixer->muteSoundType(Audio::Mixer::kPlainSoundType, mute); _mixer->muteSoundType(Audio::Mixer::kMusicSoundType, mute); _mixer->muteSoundType(Audio::Mixer::kSFXSoundType, mute); - _mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, mute); + _mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, speechMute); + _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, Audio::Mixer::kMaxMixerVolume); _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic); _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSFX); diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index fb4b9e170f..a88ddcc734 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -4299,7 +4299,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdi2, kFeaturesNone, @@ -4341,7 +4341,7 @@ static const GOBGameDescription gameDescriptions[] = { EN_ANY, kPlatformAmiga, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdi2, kFeaturesNone, @@ -4669,7 +4669,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4683,7 +4683,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4697,7 +4697,7 @@ static const GOBGameDescription gameDescriptions[] = { DE_DEU, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4711,7 +4711,7 @@ static const GOBGameDescription gameDescriptions[] = { IT_ITA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4725,7 +4725,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4739,7 +4739,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4753,7 +4753,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4767,7 +4767,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4781,7 +4781,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, @@ -4795,7 +4795,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeAdibou2, kFeaturesNone, diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 8cb88b522c..fb15fdbc19 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -251,7 +251,7 @@ void Draw_v1::printTotText(int16 id) { cmd = ptrEnd[17] & 0x7F; if (cmd == 0) { val = READ_LE_UINT16(ptrEnd + 18) * 4; - sprintf(buf, "%d", VAR_OFFSET(val)); + sprintf(buf, "%d", (int32)VAR_OFFSET(val)); } else if (cmd == 1) { val = READ_LE_UINT16(ptrEnd + 18) * 4; @@ -259,7 +259,7 @@ void Draw_v1::printTotText(int16 id) { } else { val = READ_LE_UINT16(ptrEnd + 18) * 4; - sprintf(buf, "%d", VAR_OFFSET(val)); + sprintf(buf, "%d", (int32)VAR_OFFSET(val)); if (buf[0] == '-') { while (strlen(buf) - 1 < (uint32)ptrEnd[17]) { _vm->_util->insertStr("0", buf, 1); diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 6e64d6fd06..78702f2ec9 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -553,13 +553,13 @@ void Draw_v2::printTotText(int16 id) { cmd = ptrEnd[17] & 0x7F; if (cmd == 0) { val = READ_LE_UINT16(ptrEnd + 18) * 4; - sprintf(buf, "%d", VAR_OFFSET(val)); + sprintf(buf, "%d", (int32)VAR_OFFSET(val)); } else if (cmd == 1) { val = READ_LE_UINT16(ptrEnd + 18) * 4; Common::strlcpy(buf, GET_VARO_STR(val), 20); } else { val = READ_LE_UINT16(ptrEnd + 18) * 4; - sprintf(buf, "%d", VAR_OFFSET(val)); + sprintf(buf, "%d", (int32)VAR_OFFSET(val)); if (buf[0] == '-') { while (strlen(buf) - 1 < (uint32)ptrEnd[17]) { _vm->_util->insertStr("0", buf, 1); diff --git a/engines/gob/iniconfig.cpp b/engines/gob/iniconfig.cpp index 9b8f1c703e..bba531723c 100644 --- a/engines/gob/iniconfig.cpp +++ b/engines/gob/iniconfig.cpp @@ -90,7 +90,7 @@ bool INIConfig::openConfig(const Common::String &file, Config &config) { bool INIConfig::createConfig(const Common::String &file, Config &config) { config.config = new Common::ConfigFile(); - config.created = true;; + config.created = true; _configs.setVal(file, config); diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index e05cae354c..f76ba8e97b 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -148,7 +148,7 @@ void Inter_Playtoons::oPlaytoons_printText(OpFuncParams ¶ms) { case TYPE_VAR_INT32: case TYPE_ARRAY_INT32: sprintf(buf + i, "%d", - VAR_OFFSET(_vm->_game->_script->readVarIndex())); + (int32)VAR_OFFSET(_vm->_game->_script->readVarIndex())); break; case TYPE_VAR_STR: diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 0eb8be1a03..2d3f2ad731 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -945,7 +945,7 @@ void Inter_v1::o1_printText(OpFuncParams ¶ms) { case TYPE_VAR_INT32: case TYPE_ARRAY_INT32: sprintf(buf + i, "%d", - VAR_OFFSET(_vm->_game->_script->readVarIndex())); + (int32)VAR_OFFSET(_vm->_game->_script->readVarIndex())); break; case TYPE_VAR_STR: diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 2fea18343d..1e5b7bb24c 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1104,7 +1104,7 @@ void Inter_v2::o2_printText(OpFuncParams ¶ms) { case TYPE_VAR_INT32: case TYPE_ARRAY_INT32: sprintf(buf + i, "%d", - VAR_OFFSET(_vm->_game->_script->readVarIndex())); + (int32)VAR_OFFSET(_vm->_game->_script->readVarIndex())); break; case TYPE_VAR_STR: diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp index a36154fe5e..81547f7362 100644 --- a/engines/gob/inter_v7.cpp +++ b/engines/gob/inter_v7.cpp @@ -135,7 +135,7 @@ void Inter_v7::o7_intToString() { uint16 valueIndex = _vm->_game->_script->readVarIndex(); uint16 destIndex = _vm->_game->_script->readVarIndex(); - sprintf(GET_VARO_STR(destIndex), "%d", READ_VARO_UINT32(valueIndex)); + sprintf(GET_VARO_STR(destIndex), "%d", (int32)READ_VARO_UINT32(valueIndex)); } void Inter_v7::o7_callFunction() { diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp index 57f5f7af48..e58cd3c9a3 100644 --- a/engines/gob/map.cpp +++ b/engines/gob/map.cpp @@ -373,7 +373,7 @@ void Map::findNearestWalkable(int16 &gobDestX, int16 &gobDestY, int i; mapWidth = _screenWidth / _tilesWidth; - mapHeight = _vm->_width / _tilesHeight; + mapHeight = _vm->_height / _tilesHeight; direction = 0; for (i = 1; i <= gobDestX; i++) diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp index 43e688bba4..90708163f5 100644 --- a/engines/hugo/detection.cpp +++ b/engines/hugo/detection.cpp @@ -63,7 +63,7 @@ static const HugoGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeHugo1 }, @@ -75,7 +75,7 @@ static const HugoGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformWindows, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeHugo1 }, @@ -87,7 +87,7 @@ static const HugoGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeHugo2 }, @@ -99,7 +99,7 @@ static const HugoGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformWindows, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeHugo2 }, @@ -111,7 +111,7 @@ static const HugoGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeHugo3 }, @@ -123,7 +123,7 @@ static const HugoGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformWindows, GF_PACKED, - GUIO1(GUIO_NONE) + GUIO0() }, kGameTypeHugo3 }, diff --git a/engines/hugo/game.h b/engines/hugo/game.h index 5db57789dc..b1c5f407b3 100644 --- a/engines/hugo/game.h +++ b/engines/hugo/game.h @@ -66,7 +66,7 @@ enum cycle_t {kCycleInvisible, kCycleAlmostInvisible, kCycleNotCycling, kCycleFo /** * Enumerate sequence index matching direction of travel */ -enum {RIGHT, LEFT, DOWN, _UP}; +enum {SEQ_RIGHT, SEQ_LEFT, SEQ_DOWN, SEQ_UP}; enum font_t {LARGE_ROMAN, MED_ROMAN, NUM_GDI_FONTS, INIT_FONTS, DEL_FONTS}; diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp index ecdbb3b4c6..831dc88dea 100644 --- a/engines/hugo/object_v1d.cpp +++ b/engines/hugo/object_v1d.cpp @@ -205,15 +205,15 @@ void ObjectHandler_v1d::moveObjects() { if (!obj->vx) { // Got 4 directions if (obj->vx != obj->oldvx) {// vx just stopped if (dy > 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } } @@ -239,15 +239,15 @@ void ObjectHandler_v1d::moveObjects() { if (!obj->vx && (obj->seqNumb > 2)) { if (obj->vx != obj->oldvx) { // vx just stopped if (obj->vy > 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (obj->vx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } if (obj->vx || obj->vy) diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp index 11c09176e5..4388ef5520 100644 --- a/engines/hugo/object_v1w.cpp +++ b/engines/hugo/object_v1w.cpp @@ -208,24 +208,24 @@ void ObjectHandler_v1w::moveObjects() { if (!obj->vx) { // Got 4 directions if (obj->vx != obj->oldvx) { // vx just stopped if (dy >= 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } break; case 3: case 2: if (obj->vx != obj->oldvx) { // vx just stopped if (dx > 0) // Left & right only - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } break; } @@ -252,15 +252,15 @@ void ObjectHandler_v1w::moveObjects() { if (!obj->vx && (obj->seqNumb >= 4)) { if (obj->vx != obj->oldvx) { // vx just stopped if (obj->vy > 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (obj->vx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } } obj->oldvx = obj->vx; diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp index c9e5104972..4a22fab2c0 100644 --- a/engines/hugo/object_v2d.cpp +++ b/engines/hugo/object_v2d.cpp @@ -211,24 +211,24 @@ void ObjectHandler_v2d::moveObjects() { if (!obj->vx) { // Got 4 directions if (obj->vx != obj->oldvx) { // vx just stopped if (dy > 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } break; case 3: case 2: if (obj->vx != obj->oldvx) { // vx just stopped if (dx > 0) // Left & right only - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } break; } @@ -255,15 +255,15 @@ void ObjectHandler_v2d::moveObjects() { if (!obj->vx && (obj->seqNumb >= 4)) { if (obj->vx != obj->oldvx) { // vx just stopped if (obj->vy > 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (obj->vx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } } obj->oldvx = obj->vx; diff --git a/engines/hugo/object_v3d.cpp b/engines/hugo/object_v3d.cpp index 07bd5e0c7f..cde7f5fd62 100644 --- a/engines/hugo/object_v3d.cpp +++ b/engines/hugo/object_v3d.cpp @@ -92,24 +92,24 @@ void ObjectHandler_v3d::moveObjects() { if (!obj->vx) { // Got 4 directions if (obj->vx != obj->oldvx) { // vx just stopped if (dy >= 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } break; case 3: case 2: if (obj->vx != obj->oldvx) { // vx just stopped if (dx > 0) // Left & right only - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } break; } @@ -136,15 +136,15 @@ void ObjectHandler_v3d::moveObjects() { if (!obj->vx && (obj->seqNumb >= 4)) { if (obj->vx != obj->oldvx) { // vx just stopped if (obj->vy > 0) - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; else - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; } } else if (obj->vx != obj->oldvx) { if (obj->vx > 0) - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; else - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; } } obj->oldvx = obj->vx; diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index af8ec3427d..281aacf031 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -67,35 +67,35 @@ void Route::setDirection(const uint16 keyCode) { switch (keyCode) { case Common::KEYCODE_UP: case Common::KEYCODE_KP8: - obj->currImagePtr = obj->seqList[_UP].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; break; case Common::KEYCODE_DOWN: case Common::KEYCODE_KP2: - obj->currImagePtr = obj->seqList[DOWN].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; break; case Common::KEYCODE_LEFT: case Common::KEYCODE_KP4: - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; break; case Common::KEYCODE_RIGHT: case Common::KEYCODE_KP6: - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; break; case Common::KEYCODE_HOME: case Common::KEYCODE_KP7: - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; break; case Common::KEYCODE_END: case Common::KEYCODE_KP1: - obj->currImagePtr = obj->seqList[LEFT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; break; case Common::KEYCODE_PAGEUP: case Common::KEYCODE_KP9: - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; break; case Common::KEYCODE_PAGEDOWN: case Common::KEYCODE_KP3: - obj->currImagePtr = obj->seqList[RIGHT].seqPtr; + obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; break; } } @@ -231,48 +231,48 @@ void Route::segment(int16 x, int16 y) { if (_vm->_hero->x < x1) { // Hero x not in segment, search x1..x2 // Find all segments above current - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { + for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); } // Find all segments below current - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { + for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } } else if (_vm->_hero->x + kHeroMaxWidth > x2) { // Hero x not in segment, search x1..x2 // Find all segments above current - for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) { + for (x = x2; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x >= x1; x--) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); } // Find all segments below current - for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) { + for (x = x2; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x >= x1; x--) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } } else { // Organize search around hero x position - this gives // better chance for more direct route. - for (x = _vm->_hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { + for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); } - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm->_hero->x; x++) { + for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); } - for (x = _vm->_hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { + for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm->_hero->x; x++) { + for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 384b3ace8f..892c144393 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -1539,7 +1539,7 @@ void Scheduler_v1d::promptAction(act *action) { response.toLowercase(); char resp[256]; - strncpy(resp, response.c_str(), 256); + Common::strlcpy(resp, response.c_str(), 256); if (action->a3.encodedFl) decodeString(resp); @@ -1585,12 +1585,9 @@ void Scheduler_v2d::promptAction(act *action) { bool found = false; const char *tmpStr; // General purpose string ptr - char resp[256]; - strncpy(resp, response.c_str(), 256); - for (int dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) { tmpStr = _vm->_file->fetchString(action->a3.responsePtr[dx]); - if (strstr(Utils::strlwr(resp), tmpStr)) + if (response.contains(tmpStr)) found = true; } diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h index 5c1e9df408..ebf7c8eee7 100644 --- a/engines/kyra/detection_tables.h +++ b/engines/kyra/detection_tables.h @@ -361,7 +361,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, KYRA1_CD_FLAGS }, @@ -377,7 +377,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformMacintosh, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, KYRA1_CD_FLAGS }, @@ -393,7 +393,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformMacintosh, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, KYRA1_CD_FLAGS }, diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index 7fd9880dce..27f09b645e 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -388,6 +388,10 @@ void GUI::updateSaveList(bool excludeQuickSaves) { if (_saveSlots.begin() == _saveSlots.end()) return; + sortSaveSlots(); +} + +void GUI::sortSaveSlots() { Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>()); if (_saveSlots.size() > 2) Common::sort(_saveSlots.begin()+1, _saveSlots.end(), Common::Greater<int>()); diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index 1efbdde394..6e9606f1de 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -200,10 +200,15 @@ protected: void redrawText(const Menu &menu); void redrawHighlight(const Menu &menu); + // The engine expects a list of contiguous savegame indices. + // Since ScummVM's savegame indices aren't, we re-index them. + // The integers stored in _saveSlots are ScummVM savegame indices. Common::Array<int> _saveSlots; void updateSaveList(bool excludeQuickSaves = false); int getNextSavegameSlot(); + virtual void sortSaveSlots(); + uint32 _lastScreenUpdate; Common::KeyState _keyPressed; void checkTextfieldInput(); diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index 3ab52b9940..5bef3cd5b5 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -184,7 +184,7 @@ void LoLEngine::gui_displayCharInventory(int charNum) { static const uint16 statusFlags[] = { 0x0080, 0x0000, 0x1000, 0x0002, 0x100, 0x0001, 0x0000, 0x0000 }; - memset(_charStatusFlags, 0xffff, sizeof(_charStatusFlags)); + memset(_charStatusFlags, 0xFF, sizeof(_charStatusFlags)); int x = 0; int32 c = 0; @@ -2572,11 +2572,11 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) { slotOffs = 1; } - int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W'); - + int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W'); + for (int i = startSlot; i < num && _savegameOffset + i - slotOffs < _savegameListSize; ++i) { - if (_savegameList[_saveSlots[i + _savegameOffset - slotOffs]]) { - Common::strlcpy(s, _savegameList[_saveSlots[i + _savegameOffset - slotOffs]], 80); + if (_savegameList[i + _savegameOffset - slotOffs]) { + Common::strlcpy(s, _savegameList[i + _savegameOffset - slotOffs], 80); // Trim long GMM save descriptions to fit our save slots int fC = _screen->getTextWidth(s); @@ -2618,15 +2618,13 @@ void GUI_LoL::updateSavegameList() { _savegameListSize = _saveSlots.size(); if (_savegameListSize) { - Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>()); - LoLEngine::SaveHeader header; Common::InSaveFile *in; _savegameList = new char *[_savegameListSize]; for (int i = 0; i < _savegameListSize; i++) { - in = _vm->openSaveForReading(_vm->getSavegameFilename(i), header); + in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i]), header); if (in) { _savegameList[i] = new char[header.description.size() + 1]; Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1); @@ -2634,15 +2632,18 @@ void GUI_LoL::updateSavegameList() { delete in; } else { _savegameList[i] = 0; - error("GUI_LoL::updateSavegameList(): Unexpected missing save file for slot: %d.", i); + warning("GUI_LoL::updateSavegameList(): Unexpected missing save file for slot: %d.", _saveSlots[i]); } } - } else { _savegameList = 0; } } +void GUI_LoL::sortSaveSlots() { + Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>()); +} + void GUI_LoL::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags) { _screen->fprintString("%s", x, y, c0, c1, _vm->gameFlags().use16ColorMode ? (flags & 3) : flags , str); } diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h index 0686926534..af487402f6 100644 --- a/engines/kyra/gui_lol.h +++ b/engines/kyra/gui_lol.h @@ -175,6 +175,8 @@ private: char **_savegameList; int _savegameListSize; bool _savegameListUpdateNeeded; + + virtual void sortSaveSlots(); }; } // End of namespace Kyra diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp index 7e9ae439fc..0d6e99a696 100644 --- a/engines/kyra/items_lol.cpp +++ b/engines/kyra/items_lol.cpp @@ -127,14 +127,8 @@ Item LoLEngine::makeItem(int itemType, int curFrame, int flags) { continue; bool t = false; - Item ii = i; - while (ii && !t) { - t = testUnkItemFlags(ii); - if (t) - break; - else - ii = _itemsInPlay[ii - 1].nextAssignedObject; - } + for (Item ii = i; ii && !t; ii = _itemsInPlay[ii].nextAssignedObject) + t = isItemMoveable(ii); if (t) { cnt = diff; @@ -144,24 +138,20 @@ Item LoLEngine::makeItem(int itemType, int curFrame, int flags) { Item slot = i; if (cnt) { - slot = r; - if (testUnkItemFlags(r)) { + slot = 0; + if (isItemMoveable(r)) { if (_itemsInPlay[r].nextAssignedObject) _itemsInPlay[_itemsInPlay[r].nextAssignedObject].level = _itemsInPlay[r].level; deleteItem(r); slot = r; } else { - uint16 ii = _itemsInPlay[slot].nextAssignedObject; - while (ii) { - if (testUnkItemFlags(ii)) { - _itemsInPlay[slot].nextAssignedObject = _itemsInPlay[ii].nextAssignedObject; - deleteItem(ii); - slot = ii; - break; - } else { - slot = ii; - } - ii = _itemsInPlay[slot].nextAssignedObject; + for (uint16 ii = _itemsInPlay[r].nextAssignedObject; ii; ii = _itemsInPlay[ii].nextAssignedObject) { + if (!isItemMoveable(ii)) + continue; + _itemsInPlay[r].nextAssignedObject = _itemsInPlay[ii].nextAssignedObject; + deleteItem(ii); + slot = ii; + break; } } } @@ -219,7 +209,7 @@ bool LoLEngine::addItemToInventory(Item itemIndex) { return true; } -bool LoLEngine::testUnkItemFlags(Item itemIndex) { +bool LoLEngine::isItemMoveable(Item itemIndex) { if (!(_itemsInPlay[itemIndex].shpCurFrame_flg & 0x4000)) return false; @@ -304,7 +294,7 @@ bool LoLEngine::itemEquipped(int charNum, uint16 itemType) { return false; } -void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b) { +void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int moveable) { if (!flyingHeight) { x = (x & 0xffc0) | 0x40; y = (y & 0xffc0) | 0x40; @@ -316,7 +306,7 @@ void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, _itemsInPlay[item].block = block; _itemsInPlay[item].flyingHeight = flyingHeight; - if (b) + if (moveable) _itemsInPlay[item].shpCurFrame_flg |= 0x4000; else _itemsInPlay[item].shpCurFrame_flg &= 0xbfff; @@ -325,7 +315,7 @@ void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, assignItemToBlock(&_levelBlockProperties[block].assignedObjects, item); reassignDrawObjects(_currentDirection, item, &_levelBlockProperties[block], false); - if (b) + if (moveable) runLevelScriptCustom(block, 0x80, -1, item, 0, 0); checkSceneUpdateNeed(block); diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index 4497ab8019..e91f3ba6fc 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -1083,7 +1083,7 @@ void KyraEngine_HoF::loadNPCScript() { #pragma mark - void KyraEngine_HoF::resetScaleTable() { - Common::set_to(_scaleTable, ARRAYEND(_scaleTable), 0x100); + Common::fill(_scaleTable, ARRAYEND(_scaleTable), 0x100); } void KyraEngine_HoF::setScaleTableItem(int item, int data) { @@ -1473,7 +1473,7 @@ void KyraEngine_HoF::snd_playVoiceFile(int id) { char vocFile[9]; assert(id >= 0 && id <= 9999999); sprintf(vocFile, "%07d", id); - if (_sound->voiceFileIsPresent(vocFile)) { + if (_sound->isVoicePresent(vocFile)) { snd_stopVoice(); while (!_sound->voicePlay(vocFile, &_speechHandle)) { @@ -1673,7 +1673,7 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) { } void KyraEngine_HoF::clearCauldronTable() { - Common::set_to(_cauldronTable, ARRAYEND(_cauldronTable), -1); + Common::fill(_cauldronTable, ARRAYEND(_cauldronTable), -1); } void KyraEngine_HoF::addFrontCauldronTable(int item) { diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index 27d0849e5f..601ae8f10c 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -254,7 +254,7 @@ Common::Error KyraEngine_LoK::init() { _poisonDeathCounter = 0; memset(_itemHtDat, 0, sizeof(_itemHtDat)); - memset(_exitList, 0xFFFF, sizeof(_exitList)); + memset(_exitList, 0xFF, sizeof(_exitList)); _exitListPtr = 0; _pathfinderFlag = _pathfinderFlag2 = 0; _lastFindWayRet = 0; diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index 57e6bd39ab..db70d193ff 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -416,7 +416,7 @@ protected: Movie *_movieObjects[10]; - uint16 _entranceMouseCursorTracks[8]; + uint16 _entranceMouseCursorTracks[5]; uint16 _walkBlockNorth; uint16 _walkBlockEast; uint16 _walkBlockSouth; diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 584176e08c..5a9feb0054 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -52,14 +52,16 @@ class KyraMetaEngine; * * Status of this engine: * - * The KYRA engine supports all three Kyrandia games by Westwood. It also supports Westwood's - * Lands of Lore. There are various platform ports of the different games, almost all of them are - * fully supported. Only the Macintosh port of Kyrandia 1 makes a difference here, which lacks - * support for sound effects and music. + * The KYRA engine supports all three Kyrandia games by Westwood. It also + * supports Westwood's Lands of Lore. There are various platform ports of + * the different games, almost all of them are fully supported. Only the + * Macintosh port of Kyrandia 1 makes a difference here, which lacks support + * for sound effects and music. * - * The different translations of the games are mostly supported, since every translation - * requires some work for kyra.dat for example, it is almost impossible to support translations, - * without owning them. There a currently a few reported unsupported translations: + * The different translations of the games are mostly supported, since every + * translation requires some work for kyra.dat for example, it is almost + * impossible to support translations, without owning them. There a currently + * a few reported unsupported translations: * * - Official translations * None known. @@ -69,24 +71,30 @@ class KyraMetaEngine; * Kyrandia 1 Korean (feature request #1758252 "KYRA1: Add support for Korean/DOS version") * Kyrandia 2 Polish (feature request #2146192 "KYRA2: Add support for Polish floppy version") * - Fan translations: - * Kyrandia 1 Russian (no feature request) - * Kyrandia 2 Russian (no feature request) * Kyrandia 3 Russian (feature request #2812792 "Kyrandia3 Russian") * - * The engine is maintained by _athrxx. + * The primary maintainer for the engine is LordHoto, although some parts are + * maintained by _athrxx. If you have questions about parts of the code, the + * following rough description might help in determining who you should ask: + * _athrxx is the maintainer for the Lands of Lore subengine, he also + * maintains most of the FM-TOWNS and PC98 specific code (especially the sound + * code, also some ingame code) and the Kyrandia 2 sequence player code. + * LordHoto is responsible for the rest of the codebase, he also worked on the + * graphics output for 16 color PC98 games. * - * Other people who worked on this engine include cyx, who initially started to work on Kyrandia 1 - * support, vinterstum, who did various things for Kyrandia 1 and started to work on the Kyrandia 2 - * sequence player code and also on the TIM script code, and eriktorbjorn, who helped out naming - * our AdLib player code and also contributed a work around for a music bug in the "Pool of Sorrow" - * scene of Kyrandia 1, which is also present in the original. LordHoto worked on Kyrandia 1 to 3 - * support and graphics output for 16 color PC98 games and was a maintainer of the Kyrandia part. - * All mentioned developers are not actively working on KYRA anymore. + * Other people who worked on this engine include cyx, who initially started + * to work on Kyrandia 1 support. Vinterstum, who did various things for + * Kyrandia 1 and started to work on the Kyrandia 2 sequence player code and + * also on the TIM script code. Eriktorbjorn, who helped out naming our AdLib + * player code and also contributed a work around for a music bug in the + * "Pool of Sorrow" scene of Kyrandia 1, which is also present in the original. + * He also contributed the VQA player for Kyrandia 3. * - * The engine is mostly finished code wise. A possible remaining task is proper refactoring, - * which might help in reducing binary size and along with it runtime memory use, but of course - * might lead to regressions (since the current code makes no problems on our low end ports, it - * is pretty minor priority though, since the benefit would be mostly nicer code). The biggest + * The engine is mostly finished code wise. A possible remaining task is + * proper refactoring, which might help in reducing binary size and along with + * it runtime memory use, but of course might lead to regressions (since the + * current code makes no problems on our low end ports, it is pretty minor + * priority though, since the benefit would be mostly nicer code). The biggest * task left is the kyra.dat handling. * * Games using this engine: diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index f64e4f85f2..aed8f5c965 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -963,7 +963,7 @@ void LoLEngine::startupNew() { _availableSpells[0] = 0; setupScreenDims(); - memset(_globalScriptVars2, 0x100, 8); + Common::fill(_globalScriptVars2, ARRAYEND(_globalScriptVars2), 0x100); static const int selectIds[] = { -9, -1, -8, -5 }; assert(_charSelection >= 0); @@ -1060,6 +1060,10 @@ void LoLEngine::writeSettings() { void LoLEngine::readSettings() { _monsterDifficulty = ConfMan.getInt("monster_difficulty"); + if (_monsterDifficulty < 0 || _monsterDifficulty > 2) { + _monsterDifficulty = CLIP(_monsterDifficulty, 0, 2); + warning("LoLEngine: Config file contains invalid difficulty setting."); + } _smoothScrollingEnabled = ConfMan.getBool("smooth_scrolling"); _floatingCursorsEnabled = ConfMan.getBool("floating_cursors"); @@ -1989,8 +1993,7 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int restorePortrait stopPortraitSpeechAnim(); if (charId < 0) { - charId = ch = (_rnd.getRandomNumber(0x7fff) * countActiveCharacters()) / 0x8000; - ch = _rnd.getRandomNumber(countActiveCharacters() - 1); + charId = ch = _rnd.getRandomNumber(countActiveCharacters() - 1); } else if (charId > 0) { int i = 0; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 54f043fecf..eb2f6cf2d7 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -763,7 +763,7 @@ private: int olol_distanceAttack(EMCState *script); int olol_removeCharacterEffects(EMCState *script); int olol_checkInventoryFull(EMCState *script); - int olol_objectLeavesLevel(EMCState *script); + int olol_moveBlockObjects(EMCState *script); int olol_addSpellToScroll(EMCState *script); int olol_playDialogueText(EMCState *script); int olol_playDialogueTalkText(EMCState *script); @@ -1210,14 +1210,14 @@ private: Item makeItem(int itemType, int curFrame, int flags); void placeMoveLevelItem(Item itemIndex, int level, int block, int xOffs, int yOffs, int flyingHeight); bool addItemToInventory(Item itemIndex); - bool testUnkItemFlags(Item itemIndex); + bool isItemMoveable(Item itemIndex); void deleteItem(Item itemIndex); ItemInPlay *findObject(uint16 index); void runItemScript(int charNum, Item item, int flags, int next, int reg4); void setHandItem(Item itemIndex); bool itemEquipped(int charNum, uint16 itemType); - void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b); + void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int moveable); void removeLevelItem(Item item, int block); bool launchObject(int objectType, Item item, int startX, int startY, int flyingHeight, int direction, int, int attackerId, int c); void endObjectFlight(FlyingObject *t, int x, int y, int collisionObject); diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp index a926f8493f..ab1670ea6e 100644 --- a/engines/kyra/scene_lok.cpp +++ b/engines/kyra/scene_lok.cpp @@ -131,7 +131,7 @@ void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2, _emc->run(&_scriptClick); } - memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); + memset(_entranceMouseCursorTracks, 0xFF, sizeof(_entranceMouseCursorTracks)); _currentCharacter->sceneId = sceneId; assert(sceneId < _roomTableSize); diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp index 74d2e89e6e..d6df523f82 100644 --- a/engines/kyra/scene_mr.cpp +++ b/engines/kyra/scene_mr.cpp @@ -83,7 +83,7 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 } _specialExitCount = 0; - Common::set_to(_specialExitTable, ARRAYEND(_specialExitTable), 0xFFFF); + Common::fill(_specialExitTable, ARRAYEND(_specialExitTable), 0xFFFF); _mainCharacter.sceneId = sceneId; _sceneList[sceneId].flags &= ~1; @@ -388,7 +388,7 @@ void KyraEngine_MR::initSceneScript(int unk1) { strcat(filename, ".CPS"); _screen->loadBitmap(filename, 3, 3, 0); - Common::set_to(_specialSceneScriptState, ARRAYEND(_specialSceneScriptState), false); + Common::fill(_specialSceneScriptState, ARRAYEND(_specialSceneScriptState), false); _sceneEnterX1 = 160; _sceneEnterY1 = 0; _sceneEnterX2 = 296; diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp index 5319d4e657..bc90f49002 100644 --- a/engines/kyra/scene_v1.cpp +++ b/engines/kyra/scene_v1.cpp @@ -277,7 +277,7 @@ void KyraEngine_v1::changePosTowardsFacing(int &x, int &y, int facing) { } int KyraEngine_v1::getMoveTableSize(int *moveTable) { - int retValue = 0; + int tableSize = 0; if (moveTable[0] == 8) return 0; @@ -298,11 +298,11 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) { int *oldPosition = moveTable; int *tempPosition = moveTable; int *curPosition = moveTable + 1; - retValue = 1; + tableSize = 1; while (*curPosition != 8) { if (*oldPosition == facingTable[*curPosition]) { - retValue -= 2; + tableSize -= 2; *oldPosition = 9; *curPosition = 9; @@ -313,7 +313,7 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) { } if (tempPosition == moveTable && *tempPosition == 9) { - while (*tempPosition != 8 && *tempPosition == 9) + while (*tempPosition == 9) ++tempPosition; if (*tempPosition == 8) @@ -321,53 +321,40 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) { } oldPosition = tempPosition; - curPosition = oldPosition+1; + curPosition = oldPosition + 1; - while (*curPosition != 8 && *curPosition == 9) + while (*curPosition == 9) ++curPosition; - - continue; - } - - if (unkTable[*curPosition+((*oldPosition)*8)] != -1) { - --retValue; - *oldPosition = unkTable[*curPosition+((*oldPosition)*8)]; + } else if (unkTable[*curPosition + *oldPosition * 8] != -1) { + --tableSize; + *oldPosition = unkTable[*curPosition + *oldPosition * 8]; *curPosition = 9; if (tempPosition != oldPosition) { curPosition = oldPosition; oldPosition = tempPosition; - while (true) { - if (tempPosition == moveTable) - break; - + while (tempPosition != moveTable) { --tempPosition; if (*tempPosition != 9) break; - } } else { - while (true) { + do { ++curPosition; - if (*curPosition != 9) - break; - } + } while (*curPosition == 9); } - continue; - } - - tempPosition = oldPosition; - oldPosition = curPosition; - ++retValue; + } else { + tempPosition = oldPosition; + oldPosition = curPosition; + ++tableSize; - while (true) { - ++curPosition; - if (*curPosition != 9) - break; + do { + ++curPosition; + } while (*curPosition == 9); } } - return retValue; + return tableSize; } } // End of namespace Kyra diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index b4b8f00022..d8ba32ce09 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -124,7 +124,7 @@ int LoLEngine::olol_setWallType(EMCState *script) { int LoLEngine::olol_getWallType(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getWallType(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return _levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3]; + return (int8)_levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3]; } int LoLEngine::olol_drawScene(EMCState *script) { @@ -286,13 +286,13 @@ int LoLEngine::olol_makeItem(EMCState *script) { } int LoLEngine::olol_placeMoveLevelItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeMoveLevelItem(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); placeMoveLevelItem(stackPos(0), stackPos(1), stackPos(2), stackPos(3) & 0xff, stackPos(4) & 0xff, stackPos(5)); return 1; } int LoLEngine::olol_createLevelItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_createLevelItem(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); int item = makeItem(stackPos(0), stackPos(1), stackPos(2)); if (item == -1) return item; @@ -676,6 +676,8 @@ int LoLEngine::olol_getGlobalVar(EMCState *script) { return _drainMagic; case 13: return getVolume(kVolumeSpeech) - 2; + case 14: + return _tim->_abortFlag; default: break; } @@ -842,7 +844,7 @@ int LoLEngine::olol_initMonster(EMCState *script) { l->direction = l->facing << 1; l->hitPoints = (l->properties->hitPoints * _monsterModifiers[_monsterDifficulty]) >> 8; - if (_currentLevel == 12 && l->type == 2) + if (_currentLevel != 12 || l->type != 2) l->hitPoints = (l->hitPoints * (rollDice(1, 128) + 192)) >> 8; l->numDistAttacks = l->properties->numDistAttacks; @@ -859,7 +861,7 @@ int LoLEngine::olol_initMonster(EMCState *script) { l->destDirection = l->direction; for (int ii = 0; ii < 4; ii++) - l->equipmentShapes[ii] = stackPos(7 + ii); + l->equipmentShapes[ii] = stackPos(7 + ii) & 0xff; checkSceneUpdateNeed(l->block); return i; @@ -1538,12 +1540,12 @@ int LoLEngine::olol_checkInventoryFull(EMCState *script) { return 1; } -int LoLEngine::olol_objectLeavesLevel(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_objectLeavesLevel(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); +int LoLEngine::olol_moveBlockObjects(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveBlockObjects(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int o = _levelBlockProperties[stackPos(0)].assignedObjects; int res = 0; int level = stackPos(2); - int block = stackPos(1); + int destBlock = stackPos(1); int runScript = stackPos(4); int includeMonsters = stackPos(3); int includeItems = stackPos(5); @@ -1551,9 +1553,9 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) { // WORKAROUND for script bug // Items would vanish when thrown towards the stairs // in white tower level 3. - if (_currentLevel == 21 && level == 21 && block == 0x3e0) { + if (_currentLevel == 21 && level == 21 && destBlock == 0x3e0) { level = 20; - block = 0x0247; + destBlock = 0x0247; } while (o) { @@ -1577,15 +1579,13 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) { if (!(_itemsInPlay[l].shpCurFrame_flg & 0x4000) || !includeItems) continue; - placeMoveLevelItem(l, level, block, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight); + placeMoveLevelItem(l, level, destBlock, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight); + res = 1; - if (!runScript || level != _currentLevel) { - res = 1; - continue; - } + if (!runScript || level != _currentLevel) + continue; - runLevelScriptCustom(block, 0x80, -1, l, 0, 0); - res = 1; + runLevelScriptCustom(destBlock, 0x80, -1, l, 0, 0); } } @@ -2056,17 +2056,16 @@ int LoLEngine::olol_changeItemTypeOrFlag(EMCState *script) { return 0; ItemInPlay *i = &_itemsInPlay[stackPos(0)]; - int r = stackPos(2) & 0x1fff; + int16 val = stackPos(2); - if (stackPos(1) == 4) { - i->itemPropertyIndex = r; - return r; - } else if (stackPos(1) == 15) { - i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xe000) | r; - return r; - } + if (stackPos(1) == 4) + i->itemPropertyIndex = val; + else if (stackPos(1) == 15) + i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xe000) | (val & 0x1fff); + else + val = -1; - return -1; + return val; } int LoLEngine::olol_placeInventoryItemInHand(EMCState *script) { @@ -2881,7 +2880,7 @@ void LoLEngine::setupOpcodeTable() { // 0x74 Opcode(olol_checkInventoryFull); - Opcode(olol_objectLeavesLevel); + Opcode(olol_moveBlockObjects); OpcodeUnImpl(); OpcodeUnImpl(); diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp index 8ab094ac0c..afe11aba02 100644 --- a/engines/kyra/script_mr.cpp +++ b/engines/kyra/script_mr.cpp @@ -405,7 +405,7 @@ int KyraEngine_MR::o3_updateConversations(EMCState *script) { } int convs[4]; - Common::set_to(convs, convs+4, -1); + Common::fill(convs, convs+4, -1); if (_currentChapter == 1) { switch (_mainCharacter.dlgIndex) { diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 2de0565a74..99ae2ad7b3 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -1322,7 +1322,7 @@ void KyraEngine_LoK::seq_playCredits() { _screen->copyRegion(0, 32, 0, 32, 320, 128, 4, 2, Screen::CR_NO_P_CHECK); bottom = 0; - for (CreditsLineList::iterator it = lines.begin(); it != lines.end(); ++it) { + for (CreditsLineList::iterator it = lines.begin(); it != lines.end();) { if (it->y < 0) { it = lines.erase(it); continue; @@ -1338,6 +1338,8 @@ void KyraEngine_LoK::seq_playCredits() { it->y--; if (it->y > bottom) bottom = it->y; + + ++it; } _screen->copyRegion(0, 32, 0, 32, 320, 128, 2, 0, Screen::CR_NO_P_CHECK); diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp index 83d525d400..01db92c225 100644 --- a/engines/kyra/sequences_lol.cpp +++ b/engines/kyra/sequences_lol.cpp @@ -788,7 +788,7 @@ void HistoryPlayer::play() { for (; voiceFilename[3] <= '9' && !_vm->shouldQuit() && !_vm->skipFlag(); ++voiceFilename[3], voiceFilename[4] = 'a') { while (!_vm->shouldQuit() && !_vm->skipFlag()) { - if (!sound->voiceFileIsPresent(voiceFilename)) + if (!sound->isVoicePresent(voiceFilename)) break; if (data[part * 15] == voiceFilename[3] && data[part * 15 + 1] == voiceFilename[4]) { diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index 0e83c1cb1f..a1af1ad6f8 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -43,25 +43,30 @@ Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer) Sound::~Sound() { } -bool Sound::voiceFileIsPresent(const char *file) { - for (int i = 0; _supportedCodecs[i].fileext; ++i) { - Common::String f = file; - f += _supportedCodecs[i].fileext; - if (_vm->resource()->getFileSize(f.c_str()) > 0) - return true; - } +Sound::kType Sound::getSfxType() const { + return getMusicType(); +} +void Sound::setSoundList(const AudioDataStruct *list) { + _soundDataList = list; +} + +bool Sound::hasSoundFile(uint file) const { + return (fileListEntry(file) != 0); +} + +bool Sound::isPlaying() const { return false; } -bool Sound::isVoicePresent(const char *file) { - char filenamebuffer[25]; +bool Sound::isVoicePresent(const char *file) const { + Common::String filename; for (int i = 0; _supportedCodecs[i].fileext; ++i) { - strcpy(filenamebuffer, file); - strcat(filenamebuffer, _supportedCodecs[i].fileext); + filename = file; + filename += _supportedCodecs[i].fileext; - if (_vm->resource()->exists(filenamebuffer)) + if (_vm->resource()->exists(filename.c_str())) return true; } @@ -80,15 +85,15 @@ int32 Sound::voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volum return playTime; } -Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) { - char filenamebuffer[25]; +Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) const { + Common::String filename; Audio::SeekableAudioStream *audioStream = 0; for (int i = 0; _supportedCodecs[i].fileext; ++i) { - strcpy(filenamebuffer, file); - strcat(filenamebuffer, _supportedCodecs[i].fileext); + filename = file; + filename += _supportedCodecs[i].fileext; - Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filenamebuffer); + Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename); if (!stream) continue; @@ -136,7 +141,7 @@ void Sound::voiceStop(const Audio::SoundHandle *handle) { } } -bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) { +bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) const { if (!handle) { for (int h = 0; h < kNumChannelHandles; ++h) { if (_mixer->isSoundHandleActive(_soundChannels[h])) @@ -149,7 +154,7 @@ bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) { return false; } -bool Sound::allVoiceChannelsPlaying() { +bool Sound::allVoiceChannelsPlaying() const { for (int i = 0; i < kNumChannelHandles; ++i) if (!_mixer->isSoundHandleActive(_soundChannels[i])) return false; @@ -158,6 +163,91 @@ bool Sound::allVoiceChannelsPlaying() { #pragma mark - +MixedSoundDriver::MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) + : Sound(vm, mixer), _music(music), _sfx(sfx) { +} + +MixedSoundDriver::~MixedSoundDriver() { + delete _music; + delete _sfx; +} + +Sound::kType MixedSoundDriver::getMusicType() const { + return _music->getMusicType(); +} + +Sound::kType MixedSoundDriver::getSfxType() const { + return _sfx->getSfxType(); +} + +bool MixedSoundDriver::init() { + return (_music->init() && _sfx->init()); +} + +void MixedSoundDriver::process() { + _music->process(); + _sfx->process(); +} + +void MixedSoundDriver::updateVolumeSettings() { + _music->updateVolumeSettings(); + _sfx->updateVolumeSettings(); +} + +void MixedSoundDriver::setSoundList(const AudioDataStruct *list) { + _music->setSoundList(list); + _sfx->setSoundList(list); +} + +bool MixedSoundDriver::hasSoundFile(uint file) const { + return _music->hasSoundFile(file) && _sfx->hasSoundFile(file); +} + +void MixedSoundDriver::loadSoundFile(uint file) { + _music->loadSoundFile(file); + _sfx->loadSoundFile(file); +} + +void MixedSoundDriver::loadSoundFile(Common::String file) { + _music->loadSoundFile(file); + _sfx->loadSoundFile(file); +} + +void MixedSoundDriver::loadSfxFile(Common::String file) { + _sfx->loadSoundFile(file); +} + +void MixedSoundDriver::playTrack(uint8 track) { + _music->playTrack(track); +} + +void MixedSoundDriver::haltTrack() { + _music->haltTrack(); +} + +bool MixedSoundDriver::isPlaying() const { + return _music->isPlaying() | _sfx->isPlaying(); +} + +void MixedSoundDriver::playSoundEffect(uint8 track) { + _sfx->playSoundEffect(track); +} + +void MixedSoundDriver::stopAllSoundEffects() { + _sfx->stopAllSoundEffects(); +} + +void MixedSoundDriver::beginFadeOut() { + _music->beginFadeOut(); +} + +void MixedSoundDriver::pause(bool paused) { + _music->pause(paused); + _sfx->pause(paused); +} + +#pragma mark - + void KyraEngine_v1::snd_playTheme(int file, int track) { if (_curMusicTheme == file) return; @@ -244,16 +334,7 @@ namespace { // A simple wrapper to create VOC streams the way like creating MP3, OGG/Vorbis and FLAC streams. // Possible TODO: Think of making this complete and moving it to sound/voc.cpp ? Audio::SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) { - -#ifdef STREAM_AUDIO_FROM_DISK Audio::SeekableAudioStream *as = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, disposeAfterUse); -#else - Audio::SeekableAudioStream *as = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO); - - if (disposeAfterUse) - delete stream; -#endif - return as; } diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index c3c32331be..f3de56520e 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -58,7 +58,7 @@ public: }; virtual kType getMusicType() const = 0; - virtual kType getSfxType() const { return getMusicType(); } + virtual kType getSfxType() const; /** * Initializes the output device. @@ -83,7 +83,7 @@ public: * * @param list soundfile list */ - virtual void setSoundList(const AudioDataStruct *list) { _soundDataList = list; } + virtual void setSoundList(const AudioDataStruct *list); /** * Checks if a given sound file is present. @@ -91,7 +91,7 @@ public: * @param track track number * @return true if available, false otherwise */ - virtual bool hasSoundFile(uint file) const { return (fileListEntry(file) != 0); } + virtual bool hasSoundFile(uint file) const; /** * Load a specifc sound file for use of @@ -140,7 +140,7 @@ public: * * @return true if playing, false otherwise */ - virtual bool isPlaying() const { return false; } + virtual bool isPlaying() const; /** * Starts fading out the volume. @@ -163,15 +163,13 @@ public: void enableSFX(bool enable) { _sfxEnabled = enable; } bool sfxEnabled() const { return _sfxEnabled; } - virtual bool voiceFileIsPresent(const char *file); - /** * Checks whether a voice file with the given name is present * * @param file file name * @return true if available, false otherwise */ - bool isVoicePresent(const char *file); + bool isVoicePresent(const char *file) const; /** * Plays the specified voice file. @@ -188,7 +186,7 @@ public: */ virtual int32 voicePlay(const char *file, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false); - Audio::SeekableAudioStream *getVoiceStream(const char *file); + Audio::SeekableAudioStream *getVoiceStream(const char *file) const; bool playVoiceStream(Audio::AudioStream *stream, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false); @@ -197,21 +195,21 @@ public: * * @return true when playing, else false */ - bool voiceIsPlaying(const Audio::SoundHandle *handle = 0); + bool voiceIsPlaying(const Audio::SoundHandle *handle = 0) const; /** * Checks if all voice handles are used. * * @return false when a handle is free, else true */ - bool allVoiceChannelsPlaying(); + bool allVoiceChannelsPlaying() const; /** * Checks how long a voice has been playing * * @return time in milliseconds */ - uint32 voicePlayedTime(const Audio::SoundHandle &handle) { + uint32 voicePlayedTime(const Audio::SoundHandle &handle) const { return _mixer->getSoundElapsedTime(handle); } @@ -253,34 +251,34 @@ private: class MixedSoundDriver : public Sound { public: - MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) : Sound(vm, mixer), _music(music), _sfx(sfx) {} - ~MixedSoundDriver() { delete _music; delete _sfx; } + MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx); + ~MixedSoundDriver(); - kType getMusicType() const { return _music->getMusicType(); } - kType getSfxType() const { return _sfx->getSfxType(); } + virtual kType getMusicType() const; + virtual kType getSfxType() const; - bool init() { return (_music->init() && _sfx->init()); } - void process() { _music->process(); _sfx->process(); } + virtual bool init(); + virtual void process(); - void updateVolumeSettings() { _music->updateVolumeSettings(); _sfx->updateVolumeSettings(); } + virtual void updateVolumeSettings(); - void setSoundList(const AudioDataStruct * list) { _music->setSoundList(list); _sfx->setSoundList(list); } - bool hasSoundFile(uint file) const { return _music->hasSoundFile(file) && _sfx->hasSoundFile(file); } - void loadSoundFile(uint file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); } - void loadSoundFile(Common::String file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); } + virtual void setSoundList(const AudioDataStruct *list); + virtual bool hasSoundFile(uint file) const; + virtual void loadSoundFile(uint file); + virtual void loadSoundFile(Common::String file); - void loadSfxFile(Common::String file) { _sfx->loadSoundFile(file); } + virtual void loadSfxFile(Common::String file); - void playTrack(uint8 track) { _music->playTrack(track); } - void haltTrack() { _music->haltTrack(); } - bool isPlaying() const { return _music->isPlaying() | _sfx->isPlaying(); } + virtual void playTrack(uint8 track); + virtual void haltTrack(); + virtual bool isPlaying() const; - void playSoundEffect(uint8 track) { _sfx->playSoundEffect(track); } + virtual void playSoundEffect(uint8 track); - void stopAllSoundEffects() { _sfx->stopAllSoundEffects(); } + virtual void stopAllSoundEffects(); - void beginFadeOut() { _music->beginFadeOut(); } - void pause(bool paused) { _music->pause(paused); _sfx->pause(paused); } + virtual void beginFadeOut(); + virtual void pause(bool paused); private: Sound *_music, *_sfx; }; diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index 8976eba99c..b04abea080 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -42,6 +42,7 @@ #include "common/system.h" #include "common/mutex.h" +#include "common/config-manager.h" #include "audio/mixer.h" #include "audio/fmopl.h" @@ -59,7 +60,13 @@ public: AdLibDriver(Audio::Mixer *mixer, bool v2); ~AdLibDriver(); - int callback(int opcode, ...); + void initDriver(); + void setSoundData(uint8 *data); + void queueTrack(int track); + bool isChannelPlaying(int channel) const; + void stopAllChannels(); + int getSoundTrigger() const { return _soundTrigger; } + void callback(); // AudioStream API @@ -92,36 +99,10 @@ public: void setSyncJumpMask(uint16 mask) { _syncJumpMask = mask; } -private: - struct OpcodeEntry { - typedef int (AdLibDriver::*DriverOpcode)(va_list &list); - DriverOpcode function; - const char *name; - }; - - void setupOpcodeList(); - const OpcodeEntry *_opcodeList; - int _opcodesEntries; - - int snd_ret0x100(va_list &list); - int snd_ret0x1983(va_list &list); - int snd_initDriver(va_list &list); - int snd_deinitDriver(va_list &list); - int snd_setSoundData(va_list &list); - int snd_unkOpcode1(va_list &list); - int snd_startSong(va_list &list); - int snd_isChannelPlaying(va_list &list); - int snd_stopChannel(va_list &list); - int snd_readByte(va_list &list); - int snd_writeByte(va_list &list); - int snd_getSoundTrigger(va_list &list); - int snd_unkOpcode4(va_list &list); - int snd_dummy(va_list &list); - int snd_getNullvar4(va_list &list); - int snd_setNullvar3(va_list &list); - int snd_setFlag(va_list &list); - int snd_clearFlag(va_list &list); + void setMusicVolume(uint8 volume); + void setSfxVolume(uint8 volume); +private: // These variables have not yet been named, but some of them are partly // known nevertheless: // @@ -195,6 +176,7 @@ private: uint8 tempoReset; uint8 rawNote; int8 unk16; + uint8 volumeModifier; }; void primaryEffect1(Channel &channel); @@ -346,11 +328,8 @@ private: int32 _samplesTillCallback; int32 _samplesTillCallbackRemainder; - int _lastProcessed; - int8 _flagTrigger; int _curChannel; uint8 _soundTrigger; - int _soundsPlaying; uint16 _rnd; @@ -375,12 +354,19 @@ private: uint8 _unkValue19; uint8 _unkValue20; - int _flags; FM_OPL *_adlib; uint8 *_soundData; - uint8 _soundIdTable[0x10]; + int _programStartTimeout; + uint8 *_programQueue[16]; + int _programQueueStart, _programQueueEnd; + + void adjustSfxData(uint8 *data); + uint8 *_sfxPointer; + int _sfxPriority; + int _sfxVelocity; + Channel _channels[10]; uint8 _vibratoAndAMDepthBits; @@ -406,18 +392,18 @@ private: Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; + uint8 _musicVolume, _sfxVolume; + bool _v2; }; AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { - setupOpcodeList(); setupParserOpcodeTable(); _v2 = v2; _mixer = mixer; - _flags = 0; _adlib = makeAdLibOPL(getRate()); assert(_adlib); @@ -426,12 +412,12 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { _vibratoAndAMDepthBits = _curRegOffset = 0; - _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0; - _soundsPlaying = 0; + _curChannel = _rhythmSectionBits = 0; _rnd = 0x1234; _tempo = 0; _soundTrigger = 0; + _programStartTimeout = 0; _callbackTimer = 0xFF; _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0; @@ -441,14 +427,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { _tablePtr1 = _tablePtr2 = 0; - // HACK: We use MusicSoundType here for now so we can adjust the volume in the launcher dialog. - // This affects SFX too, but if we want to support different volumes for SFX and music we would - // have to change our player implementation, currently we setup the volume for an AdLib channel - // in AdLibDriver::adjustVolume, so if that would be called, we would have to know if the channel - // is used by SFX or music, and then adjust the volume accordingly. Since Kyrandia 2 supports - // different volumes for SFX and music, looking at the disasm and checking how the original does it - // would be a good idea. - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND; _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND; @@ -456,6 +435,13 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { _samplesTillCallbackRemainder = 0; _syncJumpMask = 0; + + _musicVolume = 0; + _sfxVolume = 0; + + _sfxPointer = 0; + + _programQueueStart = _programQueueEnd = 0; } AdLibDriver::~AdLibDriver() { @@ -464,100 +450,108 @@ AdLibDriver::~AdLibDriver() { _adlib = 0; } -int AdLibDriver::callback(int opcode, ...) { +void AdLibDriver::setMusicVolume(uint8 volume) { Common::StackLock lock(_mutex); - if (opcode >= _opcodesEntries || opcode < 0) { - warning("AdLibDriver: calling unknown opcode '%d'", opcode); - return 0; + + _musicVolume = volume; + + for (uint i = 0; i < 6; ++i) { + Channel &chan = _channels[i]; + chan.volumeModifier = volume; + + const uint8 regOffset = _regOffset[i]; + + // Level Key Scaling / Total Level + writeOPL(0x40 + regOffset, calculateOpLevel1(chan)); + writeOPL(0x43 + regOffset, calculateOpLevel2(chan)); } - debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode); + // For now we use the music volume for both sfx and music in Kyra1. + if (!_v2) { + _sfxVolume = volume; - va_list args; - va_start(args, opcode); - int returnValue = (this->*(_opcodeList[opcode].function))(args); - va_end(args); - return returnValue; -} + for (uint i = 6; i < 9; ++i) { + Channel &chan = _channels[i]; + chan.volumeModifier = volume; -// Opcodes + const uint8 regOffset = _regOffset[i]; -int AdLibDriver::snd_ret0x100(va_list &list) { - return 0x100; + // Level Key Scaling / Total Level + writeOPL(0x40 + regOffset, calculateOpLevel1(chan)); + writeOPL(0x43 + regOffset, calculateOpLevel2(chan)); + } + } } -int AdLibDriver::snd_ret0x1983(va_list &list) { - return 0x1983; -} +void AdLibDriver::setSfxVolume(uint8 volume) { + // We only support sfx volume in v2 games. + if (!_v2) + return; -int AdLibDriver::snd_initDriver(va_list &list) { - _lastProcessed = _soundsPlaying = 0; - resetAdLibState(); - return 0; + Common::StackLock lock(_mutex); + + _sfxVolume = volume; + + for (uint i = 6; i < 9; ++i) { + Channel &chan = _channels[i]; + chan.volumeModifier = volume; + + const uint8 regOffset = _regOffset[i]; + + // Level Key Scaling / Total Level + writeOPL(0x40 + regOffset, calculateOpLevel1(chan)); + writeOPL(0x43 + regOffset, calculateOpLevel2(chan)); + } } -int AdLibDriver::snd_deinitDriver(va_list &list) { +void AdLibDriver::initDriver() { + Common::StackLock lock(_mutex); resetAdLibState(); - return 0; } -int AdLibDriver::snd_setSoundData(va_list &list) { +void AdLibDriver::setSoundData(uint8 *data) { + Common::StackLock lock(_mutex); + + // Drop all tracks that are still queued. These would point to the old + // sound data. + _programQueueStart = _programQueueEnd = 0; + memset(_programQueue, 0, sizeof(_programQueue)); + if (_soundData) { delete[] _soundData; _soundData = 0; } - _soundData = va_arg(list, uint8 *); - return 0; -} -int AdLibDriver::snd_unkOpcode1(va_list &list) { - warning("unimplemented snd_unkOpcode1"); - return 0; + _soundData = data; } -int AdLibDriver::snd_startSong(va_list &list) { - int songId = va_arg(list, int); - _flags |= 8; - _flagTrigger = 1; +void AdLibDriver::queueTrack(int track) { + Common::StackLock lock(_mutex); - uint8 *ptr = getProgram(songId); - assert(ptr); - uint8 chan = *ptr; + uint8 *trackData = getProgram(track); + if (!trackData) + return; - if ((songId << 1) != 0) { - if (chan == 9) { - if (_flags & 2) - return 0; - } else { - if (_flags & 1) - return 0; - } + if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd] != 0) { + warning("AdLibDriver: Program queue full, dropping track %d", track); + return; } - _soundIdTable[_soundsPlaying++] = songId; - _soundsPlaying &= 0x0F; - - return 0; + _programQueue[_programQueueEnd++] = trackData; + _programQueueEnd &= 15; } -int AdLibDriver::snd_isChannelPlaying(va_list &list) { - int channel = va_arg(list, int); +bool AdLibDriver::isChannelPlaying(int channel) const { + Common::StackLock lock(_mutex); + assert(channel >= 0 && channel <= 9); - return (_channels[channel].dataptr != 0) ? 1 : 0; + return (_channels[channel].dataptr != 0); } -int AdLibDriver::snd_stopChannel(va_list &list) { - int channel = va_arg(list, int); - - int maxChannel; - if (channel < 0) { - channel = 0; - maxChannel = 9; - } else { - maxChannel = channel; - } +void AdLibDriver::stopAllChannels() { + Common::StackLock lock(_mutex); - for (; channel <= maxChannel; ++channel) { + for (int channel = 0; channel <= 9; ++channel) { _curChannel = channel; Channel &chan = _channels[_curChannel]; @@ -567,71 +561,16 @@ int AdLibDriver::snd_stopChannel(va_list &list) { if (channel != 9) noteOff(chan); } - - return 0; -} - -int AdLibDriver::snd_readByte(va_list &list) { - int a = va_arg(list, int); - int b = va_arg(list, int); - uint8 *ptr = getProgram(a) + b; - assert(ptr); - return *ptr; -} - -int AdLibDriver::snd_writeByte(va_list &list) { - int a = va_arg(list, int); - int b = va_arg(list, int); - uint8 value = va_arg(list, int); - uint8 *ptr = getProgram(a) + b; - assert(ptr); - SWAP(*ptr, value); - return value; -} - -int AdLibDriver::snd_getSoundTrigger(va_list &list) { - return _soundTrigger; -} - -int AdLibDriver::snd_unkOpcode4(va_list &list) { - warning("unimplemented snd_unkOpcode4"); - return 0; -} - -int AdLibDriver::snd_dummy(va_list &list) { - return 0; -} - -int AdLibDriver::snd_getNullvar4(va_list &list) { - warning("unimplemented snd_getNullvar4"); - return 0; -} - -int AdLibDriver::snd_setNullvar3(va_list &list) { - warning("unimplemented snd_setNullvar3"); - return 0; -} - -int AdLibDriver::snd_setFlag(va_list &list) { - int oldFlags = _flags; - _flags |= va_arg(list, int); - return oldFlags; -} - -int AdLibDriver::snd_clearFlag(va_list &list) { - int oldFlags = _flags; - _flags &= ~(va_arg(list, int)); - return oldFlags; } // timer callback void AdLibDriver::callback() { Common::StackLock lock(_mutex); - --_flagTrigger; - if (_flagTrigger < 0) - _flags &= ~8; - setupPrograms(); + if (_programStartTimeout) + --_programStartTimeout; + else + setupPrograms(); executePrograms(); uint8 temp = _callbackTimer; @@ -645,36 +584,86 @@ void AdLibDriver::callback() { } void AdLibDriver::setupPrograms() { - while (_lastProcessed != _soundsPlaying) { - uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]); - uint8 chan = *ptr++; - uint8 priority = *ptr++; - - // Only start this sound if its priority is higher than the one - // already playing. - - Channel &channel = _channels[chan]; - - if (priority >= channel.priority) { - initChannel(channel); - channel.priority = priority; - channel.dataptr = ptr; - channel.tempo = 0xFF; - channel.position = 0xFF; - channel.duration = 1; - unkOutput2(chan); - } + // If there is no program queued, we skip this. + if (_programQueueStart == _programQueueEnd) + return; + + uint8 *ptr = _programQueue[_programQueueStart]; + // Clear the queue entry + _programQueue[_programQueueStart] = 0; + _programQueueStart = (_programQueueStart + 1) & 15; + + // Adjust data in case we hit a sound effect. + adjustSfxData(ptr); + + const int chan = *ptr++; + const int priority = *ptr++; + + // Only start this sound if its priority is higher than the one + // already playing. + + Channel &channel = _channels[chan]; - // What we have set up now is, probably, the controlling - // channel for the sound. It is assumed that this program will - // set up all the other channels it needs, clearing their locks - // along the way. + if (priority >= channel.priority) { + initChannel(channel); + channel.priority = priority; + channel.dataptr = ptr; + channel.tempo = 0xFF; + channel.position = 0xFF; + channel.duration = 1; - ++_lastProcessed; - _lastProcessed &= 0x0F; + if (chan <= 5) + channel.volumeModifier = _musicVolume; + else + channel.volumeModifier = _sfxVolume; + + unkOutput2(chan); + + // We need to wait two callback calls till we can start another track. + // This is (probably) required to assure that the sfx are started with + // the correct priority and velocity. + _programStartTimeout = 2; } } +void AdLibDriver::adjustSfxData(uint8 *ptr) { + // Check whether we need to reset the data of an old sfx which has been + // started. + if (_sfxPointer) { + _sfxPointer[1] = _sfxPriority; + _sfxPointer[3] = _sfxVelocity; + _sfxPointer = 0; + } + + // Only music tracks are started on channel 9, thus we need to make sure + // we do not have a music track here. + if (*ptr == 9) + return; + + // Store the pointer so we can reset the data when a new program is started. + _sfxPointer = ptr; + + // Store the old values. + _sfxPriority = ptr[1]; + _sfxVelocity = ptr[3]; + + // In the cases I've seen, the mysterious fourth byte has been + // the parameter for the update_setExtraLevel3() callback. + // + // The extra level is part of the channels "total level", which + // is a six-bit value where larger values means softer volume. + // + // So what seems to be happening here is that sounds which are + // started by this function are given a slightly lower priority + // and a slightly higher (i.e. softer) extra level 3 than they + // would have if they were started from anywhere else. Strange. + + // Adjust the values. + int newVal = ((((ptr[3]) + 63) * 0xFF) >> 8) & 0xFF; + ptr[3] = -newVal + 63; + ptr[1] = ((ptr[1] * 0xFF) >> 8) & 0xFF; +} + // A few words on opcode parsing and timing: // // First of all, We simulate a timer callback 72 times per second. Each timeout @@ -1273,9 +1262,21 @@ uint8 AdLibDriver::calculateOpLevel1(Channel &channel) { if (channel.twoChan) { value += channel.opExtraLevel1; value += channel.opExtraLevel2; - value += channel.opExtraLevel3; + + uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier; + if (level3) { + level3 += 0x3F; + level3 >>= 8; + } + + value += level3 ^ 0x3F; } + value = CLIP<int8>(value, 0, 0x3F); + + if (!channel.volumeModifier) + value = 0x3F; + // Preserve the scaling level bits from opLevel1 return checkValue(value) | (channel.opLevel1 & 0xC0); @@ -1286,7 +1287,19 @@ uint8 AdLibDriver::calculateOpLevel2(Channel &channel) { value += channel.opExtraLevel1; value += channel.opExtraLevel2; - value += channel.opExtraLevel3; + + uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier; + if (level3) { + level3 += 0x3F; + level3 >>= 8; + } + + value += level3 ^ 0x3F; + + value = CLIP<int8>(value, 0, 0x3F); + + if (!channel.volumeModifier) + value = 0x3F; // Preserve the scaling level bits from opLevel2 @@ -1323,14 +1336,22 @@ int AdLibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 va Channel &channel2 = _channels[chan]; if (priority >= channel2.priority) { - _flagTrigger = 1; - _flags |= 8; + // We keep new tracks from being started for two further iterations of + // the callback. This assures the correct velocity is used for this + // program. + _programStartTimeout = 2; initChannel(channel2); channel2.priority = priority; channel2.dataptr = ptr; channel2.tempo = 0xFF; channel2.position = 0xFF; channel2.duration = 1; + + if (chan <= 5) + channel2.volumeModifier = _musicVolume; + else + channel2.volumeModifier = _sfxVolume; + unkOutput2(chan); } @@ -1911,32 +1932,6 @@ int AdLibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value #define COMMAND(x) { &AdLibDriver::x, #x } -void AdLibDriver::setupOpcodeList() { - static const OpcodeEntry opcodeList[] = { - COMMAND(snd_ret0x100), - COMMAND(snd_ret0x1983), - COMMAND(snd_initDriver), - COMMAND(snd_deinitDriver), - COMMAND(snd_setSoundData), - COMMAND(snd_unkOpcode1), - COMMAND(snd_startSong), - COMMAND(snd_isChannelPlaying), - COMMAND(snd_stopChannel), - COMMAND(snd_readByte), - COMMAND(snd_writeByte), - COMMAND(snd_getSoundTrigger), - COMMAND(snd_unkOpcode4), - COMMAND(snd_dummy), - COMMAND(snd_getNullvar4), - COMMAND(snd_setNullvar3), - COMMAND(snd_setFlag), - COMMAND(snd_clearFlag) - }; - - _opcodeList = opcodeList; - _opcodesEntries = ARRAYSIZE(opcodeList); -} - void AdLibDriver::setupParserOpcodeTable() { static const ParserOpcode parserOpcodeTable[] = { // 0 @@ -2266,13 +2261,12 @@ SoundAdLibPC::~SoundAdLibPC() { } bool SoundAdLibPC::init() { - _driver->callback(2); - _driver->callback(16, int(4)); + _driver->initDriver(); return true; } void SoundAdLibPC::process() { - uint8 trigger = _driver->callback(11); + int trigger = _driver->getSoundTrigger(); if (trigger < _numSoundTriggers) { int soundId = _soundTriggers[trigger]; @@ -2285,6 +2279,23 @@ void SoundAdLibPC::process() { } } +void SoundAdLibPC::updateVolumeSettings() { + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + int newMusicVolume = mute ? 0 : ConfMan.getInt("music_volume"); + //newMusicVolume = (newMusicVolume * 145) / Audio::Mixer::kMaxMixerVolume + 110; + newMusicVolume = CLIP(newMusicVolume, 0, 255); + + int newSfxVolume = mute ? 0 : ConfMan.getInt("sfx_volume"); + //newSfxVolume = (newSfxVolume * 200) / Audio::Mixer::kMaxMixerVolume + 55; + newSfxVolume = CLIP(newSfxVolume, 0, 255); + + _driver->setMusicVolume(newMusicVolume); + _driver->setSfxVolume(newSfxVolume); +} + void SoundAdLibPC::playTrack(uint8 track) { if (_musicEnabled) { // WORKAROUND: There is a bug in the Kyra 1 "Pool of Sorrow" @@ -2301,13 +2312,13 @@ void SoundAdLibPC::playTrack(uint8 track) { } void SoundAdLibPC::haltTrack() { - playSoundEffect(0); - playSoundEffect(0); + play(0); + play(0); //_vm->_system->delayMillis(3 * 60); } bool SoundAdLibPC::isPlaying() const { - return _driver->callback(7, int(0)) != 0; + return _driver->isChannelPlaying(0); } void SoundAdLibPC::playSoundEffect(uint8 track) { @@ -2326,60 +2337,11 @@ void SoundAdLibPC::play(uint8 track) { if ((soundId == 0xFFFF && _v2) || (soundId == 0xFF && !_v2) || !_soundDataPtr) return; - // HACK: Since we might call this when the engines is paused (on game load via GMM) - // we must unpause the engine here, so this will work properly - - int pauseCount = 0; - while (_vm->isPaused()) { - ++pauseCount; - _vm->pauseEngine(false); - } - - while ((_driver->callback(16, 0) & 8)) { - // We call the system delay and not the game delay to avoid concurrency issues. - _vm->_system->delayMillis(10); - } - - while (pauseCount--) - _vm->pauseEngine(true); - - if (_sfxPlayingSound != -1) { - // Restore the sounds's normal values. - _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority)); - _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong)); - _sfxPlayingSound = -1; - } - - int chan = _driver->callback(9, soundId, int(0)); - - if (chan != 9) { - _sfxPlayingSound = soundId; - _sfxPriority = _driver->callback(9, soundId, int(1)); - _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3)); - - // In the cases I've seen, the mysterious fourth byte has been - // the parameter for the update_setExtraLevel3() callback. - // - // The extra level is part of the channels "total level", which - // is a six-bit value where larger values means softer volume. - // - // So what seems to be happening here is that sounds which are - // started by this function are given a slightly lower priority - // and a slightly higher (i.e. softer) extra level 3 than they - // would have if they were started from anywhere else. Strange. - - int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF; - newVal = -newVal + 63; - _driver->callback(10, soundId, int(3), newVal); - newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF; - _driver->callback(10, soundId, int(1), newVal); - } - - _driver->callback(6, soundId); + _driver->queueTrack(soundId); } void SoundAdLibPC::beginFadeOut() { - playSoundEffect(1); + play(1); } void SoundAdLibPC::loadSoundFile(uint file) { @@ -2409,7 +2371,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) { playSoundEffect(0); playSoundEffect(0); - _driver->callback(8, int(-1)); + _driver->stopAllChannels(); _soundDataPtr = 0; int soundDataSize = fileSize; @@ -2434,7 +2396,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) { fileData = p = 0; fileSize = 0; - _driver->callback(4, _soundDataPtr); + _driver->setSoundData(_soundDataPtr); _soundFileLoaded = file; } diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h index c09fec997e..923a4cb75f 100644 --- a/engines/kyra/sound_adlib.h +++ b/engines/kyra/sound_adlib.h @@ -62,22 +62,23 @@ public: SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer); ~SoundAdLibPC(); - kType getMusicType() const { return kAdLib; } + virtual kType getMusicType() const { return kAdLib; } - bool init(); - void process(); + virtual bool init(); + virtual void process(); - void loadSoundFile(uint file); - void loadSoundFile(Common::String file); - void loadSoundFile(const uint8 *soundData, int dataSize) {} + virtual void updateVolumeSettings(); - void playTrack(uint8 track); - void haltTrack(); - bool isPlaying() const; + virtual void loadSoundFile(uint file); + virtual void loadSoundFile(Common::String file); - void playSoundEffect(uint8 track); + virtual void playTrack(uint8 track); + virtual void haltTrack(); + virtual bool isPlaying() const; - void beginFadeOut(); + virtual void playSoundEffect(uint8 track); + + virtual void beginFadeOut(); private: void internalLoadFile(Common::String file); @@ -92,9 +93,6 @@ private: Common::String _soundFileLoaded; - uint8 _sfxPriority; - uint8 _sfxFourthByteOfSong; - int _numSoundTriggers; const int *_soundTriggers; diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp index efa844968d..968488eef3 100644 --- a/engines/kyra/sound_lol.cpp +++ b/engines/kyra/sound_lol.cpp @@ -98,12 +98,12 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { _speechList = newSpeechList; _activeVoiceFileTotalTime = 0; - for (SpeechList::iterator i = _speechList.begin(); i != _speechList.end(); ++i) { + for (SpeechList::iterator i = _speechList.begin(); i != _speechList.end();) { // Just in case any file loading failed: Remove the bad streams here. if (!*i) i = _speechList.erase(i); else - _activeVoiceFileTotalTime += (*i)->getLength().msecs(); + _activeVoiceFileTotalTime += (*i++)->getLength().msecs(); } _sound->playVoiceStream(*_speechList.begin(), &_speechHandle); diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp index c5c6f2a44d..301c52e142 100644 --- a/engines/lastexpress/entities/abbot.cpp +++ b/engines/lastexpress/entities/abbot.cpp @@ -841,7 +841,7 @@ IMPLEMENT_FUNCTION(31, Abbot, function31) case kActionNone: if (params->param4 != kTimeInvalid && params->param2 < getState()->time) { - if (getState()->time < getState()->time) { + if (params->param3 < getState()->time) { params->param4 = kTimeInvalid; setCallback(1); diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp index eb3b09af59..cfde8a2d6f 100644 --- a/engines/lastexpress/entities/august.cpp +++ b/engines/lastexpress/entities/august.cpp @@ -2118,7 +2118,7 @@ IMPLEMENT_FUNCTION_II(41, August, function41, CarIndex, EntityPosition) && getEntities()->isDistanceBetweenEntities(kEntityAugust, kEntityPlayer, 1000) && !getEntities()->isInsideCompartments(kEntityPlayer) && !getEntities()->checkFields10(kEntityPlayer)) { - if (getData()->car == kCarGreenSleeping || getData()->car == kCarGreenSleeping) { + if (getData()->car == kCarGreenSleeping || getData()->car == kCarRedSleeping) { getAction()->playAnimation(kEventAugustMerchandise); getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp); diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp index 2b170d93a3..46cd790ffb 100644 --- a/engines/lastexpress/entities/francois.cpp +++ b/engines/lastexpress/entities/francois.cpp @@ -450,7 +450,7 @@ label_callback: if (isNight()) getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleNightD : kEventFrancoisWhistleNight); else - getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleD : kEventFrancoisWhistleD); + getAction()->playAnimation(getData()->entityPosition <= getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisWhistleD : kEventFrancoisWhistle); } getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + 750 * (getData()->direction == kDirectionUp ? -1 : 1)), getData()->direction == kDirectionUp); break; diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp index e222af4805..d88962fce2 100644 --- a/engines/lastexpress/entities/mertens.cpp +++ b/engines/lastexpress/entities/mertens.cpp @@ -390,7 +390,7 @@ IMPLEMENT_FUNCTION_II(10, Mertens, updateEntity, CarIndex, EntityPosition) break; case kActionDefault: - if ((!getProgress().eventCorpseFound && !getEvent(kEventMertensAskTylerCompartment) && !getEvent(kEventMertensAskTylerCompartment)) + if ((!getProgress().eventCorpseFound && !getEvent(kEventMertensAskTylerCompartment) && !getEvent(kEventMertensAskTylerCompartmentD)) || (ENTITY_PARAM(0, 4) && getProgress().jacket == kJacketGreen && !getEvent(kEventMertensDontMakeBed) && !getProgress().eventCorpseThrown)) params->param3 = 1; diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp index 2ef4c20d70..98d74dd1a7 100644 --- a/engines/lastexpress/game/action.cpp +++ b/engines/lastexpress/game/action.cpp @@ -1806,7 +1806,7 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const { if (getProgress().jacket != kJacketGreen) return kCursorNormal; - if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowDay) || getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) + if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowNight) || getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) && getProgress().isTrainRunning && (object != kObjectOutsideAnnaCompartment || (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840) && getObjects()->get(kObjectOutsideBetweenCompartments).location == 2)) && getInventory()->getSelectedItem() != kItemBriefcase && getInventory()->getSelectedItem() != kItemFirebird) diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp index 1b31339b7b..894663dda6 100644 --- a/engines/lastexpress/game/entities.cpp +++ b/engines/lastexpress/game/entities.cpp @@ -87,16 +87,15 @@ static const EntityPosition objectsPosition[8] = {kPosition_8200, kPosition_7500 kPosition_4840, kPosition_4070, kPosition_3050, kPosition_2740}; -static const EntityPosition entityPositions[41] = { - kPositionNone, kPosition_851, kPosition_1430, kPosition_2110, kPositionNone, - kPosition_2410, kPosition_2980, kPosition_3450, kPosition_3760, kPosition_4100, - kPosition_4680, kPosition_5140, kPosition_5440, kPosition_5810, kPosition_6410, - kPosition_6850, kPosition_7160, kPosition_7510, kPosition_8514, kPositionNone, - kPositionNone, kPositionNone, kPosition_2086, kPosition_2690, kPositionNone, - kPosition_3110, kPosition_3390, kPosition_3890, kPosition_4460, kPosition_4770, - kPosition_5090, kPosition_5610, kPosition_6160, kPosition_6460, kPosition_6800, - kPosition_7320, kPosition_7870, kPosition_8160, kPosition_8500, kPosition_9020, - kPosition_9269}; +static const EntityPosition entityPositions[41] = {kPositionNone, kPosition_851, kPosition_1430, kPosition_2110, kPositionNone, + kPosition_2410, kPosition_2980, kPosition_3450, kPosition_3760, kPosition_4100, + kPosition_4680, kPosition_5140, kPosition_5440, kPosition_5810, kPosition_6410, + kPosition_6850, kPosition_7160, kPosition_7510, kPosition_8514, kPositionNone, + kPositionNone, kPositionNone, kPosition_2086, kPosition_2690, kPositionNone, + kPosition_3110, kPosition_3390, kPosition_3890, kPosition_4460, kPosition_4770, + kPosition_5090, kPosition_5610, kPosition_6160, kPosition_6460, kPosition_6800, + kPosition_7320, kPosition_7870, kPosition_8160, kPosition_8500, kPosition_9020, + kPosition_9269}; #define ADD_ENTITY(class) \ _entities.push_back(new class(engine)); @@ -105,7 +104,7 @@ static const EntityPosition entityPositions[41] = { sequenceTo = sequenceFrom; \ for (int seqIdx = 0; seqIdx < 7; seqIdx++) \ sequenceTo.deleteLastChar(); \ - if (isInsideTrainCar(entityIndex, kCarGreenSleeping) || isInsideTrainCar(entityIndex, kCarGreenSleeping)) { \ + if (isInsideTrainCar(entityIndex, kCarGreenSleeping) || isInsideTrainCar(entityIndex, kCarRedSleeping)) { \ if (data->car < getData(kEntityPlayer)->car || (data->car == getData(kEntityPlayer)->car && data->entityPosition < getData(kEntityPlayer)->entityPosition)) \ sequenceTo += "R.SEQ"; \ else \ diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp index 57c18b5697..9c464feb6e 100644 --- a/engines/lastexpress/game/savegame.cpp +++ b/engines/lastexpress/game/savegame.cpp @@ -154,11 +154,11 @@ void SaveLoad::loadStream(GameId id) { error("[SaveLoad::loadStream] Savegame stream is invalid"); // Load all savegame data - uint8* buf = new uint8[8192]; + uint8 *buf = new uint8[8192]; while (!save->eos() && !save->err()) { _engine->pollEvents(); - uint32 count = save->read(buf, sizeof(buf)); + uint32 count = save->read(buf, 8192); if (count) { uint32 w = _savegame->write(buf, count); assert (w == count); diff --git a/engines/lure/detection.cpp b/engines/lure/detection.cpp index 276b2d77af..ab7615c265 100644 --- a/engines/lure/detection.cpp +++ b/engines/lure/detection.cpp @@ -72,7 +72,7 @@ static const LureGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY, }, @@ -85,7 +85,7 @@ static const LureGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY | GF_EGA, }, @@ -98,7 +98,7 @@ static const LureGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY, }, @@ -111,7 +111,7 @@ static const LureGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY | GF_EGA, }, @@ -124,7 +124,7 @@ static const LureGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY, }, @@ -137,7 +137,7 @@ static const LureGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY, }, @@ -150,7 +150,7 @@ static const LureGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY, }, @@ -163,7 +163,7 @@ static const LureGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GF_FLOPPY, }, diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp index 96e5e088ab..207c125a0c 100644 --- a/engines/lure/hotspots.cpp +++ b/engines/lure/hotspots.cpp @@ -179,7 +179,6 @@ Hotspot::Hotspot(): _pathFinder(NULL) { _walkFlag = false; _skipFlag = false; _roomNumber = 0; - _destHotspotId = 0; _startX = 0; _startY = 0; _destX = 0; diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp index fbf9f33b87..6328301233 100644 --- a/engines/lure/res.cpp +++ b/engines/lure/res.cpp @@ -408,7 +408,7 @@ byte *Resources::getCursor(uint8 cursorNum) { if (!LureEngine::getReference().isEGA()) return _cursors->data() + (cursorNum * CURSOR_SIZE); - Common::set_to(&_cursor[0], &_cursor[0] + CURSOR_SIZE, 0); + Common::fill(&_cursor[0], &_cursor[0] + CURSOR_SIZE, 0); byte *pSrc = _cursors->data() + (cursorNum * 64); byte *pDest = &_cursor[0]; diff --git a/engines/lure/room.cpp b/engines/lure/room.cpp index 2cb871d73f..219ed0263d 100644 --- a/engines/lure/room.cpp +++ b/engines/lure/room.cpp @@ -43,7 +43,7 @@ RoomLayer::RoomLayer(uint16 screenId, bool backgroundLayer): int cellIndex = 0; // Reset all the cells to unused - Common::set_to((uint8 *) _cells, (uint8 *) _cells + GRID_SIZE, 0xff); + Common::fill((uint8 *) _cells, (uint8 *) _cells + GRID_SIZE, 0xff); // Load up the screen data MemoryBlock *rawData = disk.getEntry(screenId); diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp index 22656dd3fe..df2f06df96 100644 --- a/engines/lure/scripts.cpp +++ b/engines/lure/scripts.cpp @@ -499,7 +499,7 @@ void Script::fixGoewin(uint16 v1, uint16 v2, uint16 v3) { hotspot->currentActions().clear(); hotspot->currentActions().addFront(DISPATCH_ACTION, entry, hotspot->roomNumber()); - hotspot->setActions(hotspot->resource()->actions & !(1 << (TELL - 1))); + hotspot->setActions(hotspot->resource()->actions & ~(1 << (TELL - 1))); hotspot->setActionCtr(0); hotspot->setDelayCtr(0); hotspot->setCharacterMode(CHARMODE_NONE); diff --git a/engines/lure/sound.cpp b/engines/lure/sound.cpp index 85b86a8400..0aecae22ec 100644 --- a/engines/lure/sound.cpp +++ b/engines/lure/sound.cpp @@ -53,7 +53,7 @@ SoundManager::SoundManager() { _isRoland = MidiDriver::getMusicType(dev) != MT_ADLIB; _nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); - Common::set_to(_channelsInUse, _channelsInUse + NUM_CHANNELS, false); + Common::fill(_channelsInUse, _channelsInUse + NUM_CHANNELS, false); _driver = MidiDriver::createMidi(dev); int statusCode = _driver->open(); @@ -182,7 +182,7 @@ void SoundManager::killSounds() { // Clear the active sounds _activeSounds.clear(); - Common::set_to(_channelsInUse, _channelsInUse + NUM_CHANNELS, false); + Common::fill(_channelsInUse, _channelsInUse + NUM_CHANNELS, false); } void SoundManager::addSound(uint8 soundIndex, bool tidyFlag) { @@ -221,7 +221,7 @@ void SoundManager::addSound(uint8 soundIndex, bool tidyFlag) { } // Mark the found channels as in use - Common::set_to(_channelsInUse+channelCtr, _channelsInUse+channelCtr + numChannels, true); + Common::fill(_channelsInUse+channelCtr, _channelsInUse+channelCtr + numChannels, true); SoundDescResource *newEntry = new SoundDescResource(); newEntry->soundNumber = rec.soundNumber; @@ -342,7 +342,7 @@ void SoundManager::tidySounds() { ++i; else { // Mark the channels that it used as now being free - Common::set_to(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, false); + Common::fill(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, false); i = _activeSounds.erase(i); } @@ -373,7 +373,7 @@ void SoundManager::restoreSounds() { SoundDescResource *rec = (*i).get(); if ((rec->numChannels != 0) && ((rec->flags & SF_RESTORE) != 0)) { - Common::set_to(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, true); + Common::fill(_channelsInUse+rec->channel, _channelsInUse+rec->channel+rec->numChannels, true); musicInterface_Play(rec->soundNumber, rec->channel, rec->numChannels); musicInterface_SetVolume(rec->channel, rec->volume); diff --git a/engines/m4/assets.cpp b/engines/m4/assets.cpp index d6cc71e133..e871218ec1 100644 --- a/engines/m4/assets.cpp +++ b/engines/m4/assets.cpp @@ -233,7 +233,7 @@ void SpriteAsset::loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStre RGB8 *palData = Palette::decodeMadsPalette(spriteStream, &numColors); Common::copy(palData, &palData[numColors], &_palette[0]); if (numColors < 256) - Common::set_to((byte *)&_palette[numColors], (byte *)&_palette[256], 0); + Common::fill((byte *)&_palette[numColors], (byte *)&_palette[256], 0); _colorCount = numColors; delete[] palData; delete spriteStream; @@ -301,11 +301,11 @@ void SpriteAsset::loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStre int32 SpriteAsset::parseSprite(bool isBigEndian) { - uint32 format, chunkType, chunkSize = 0; + uint32 chunkType, chunkSize = 0; _colorCount = 0; - format = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE(); + /*format = (!isBigEndian) ? _stream->readUint32LE() : */_stream->readUint32BE(); chunkType = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE(); diff --git a/engines/m4/converse.cpp b/engines/m4/converse.cpp index bdce7928ac..299fafb282 100644 --- a/engines/m4/converse.cpp +++ b/engines/m4/converse.cpp @@ -116,7 +116,7 @@ void ConversationView::setNode(int32 nodeIndex) { // Add node to active items list _activeItems.push_back(node->entries[i]); - if (node->entries[i]->autoSelect || strlen(node->entries[i]->text) == 0) { + if (node->entries[i]->autoSelect || node->entries[i]->text[0] == '\0') { //warning(kDebugConversations, "Auto selecting entry %i of node %i\n", i, nodeIndex); selectEntry(i); return; @@ -217,7 +217,7 @@ void ConversationView::selectEntry(int entryIndex) { _highlightedIndex = entryIndex; // Play the selected entry's voice - if (strlen(_activeItems[entryIndex]->voiceFile) > 0) { + if (_activeItems[entryIndex]->voiceFile[0] != '\0') { _currentHandle = _vm->_sound->getHandle(); _vm->_sound->playVoice(buffer, 255); } else { @@ -273,7 +273,7 @@ void ConversationView::playNextReply() { if (currentEntry->entryType != kWeightedReply) { sprintf(buffer, "%s.raw", currentEntry->voiceFile); - if (strlen(currentEntry->voiceFile) > 0) { + if (currentEntry->voiceFile[0] != '\0') { _currentHandle = _vm->_sound->getHandle(); _vm->_sound->playVoice(buffer, 255); // Remove reply from the list of replies @@ -293,7 +293,7 @@ void ConversationView::playNextReply() { currentWeight += currentEntry->entries[j]->weight; if (selectedWeight >= previousWeight && selectedWeight <= currentWeight) { sprintf(buffer, "%s.raw", currentEntry->entries[j]->voiceFile); - if (strlen(currentEntry->entries[j]->voiceFile) > 0) { + if (currentEntry->entries[j]->voiceFile[0] != '\0') { _currentHandle = _vm->_sound->getHandle(); _vm->_sound->playVoice(buffer, 255); // Remove reply from the list of replies diff --git a/engines/m4/detection.cpp b/engines/m4/detection.cpp index a10ac512ad..6b8af6b5f2 100644 --- a/engines/m4/detection.cpp +++ b/engines/m4/detection.cpp @@ -269,7 +269,7 @@ static const M4GameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, GType_RexNebular, kFeaturesDemo @@ -302,7 +302,7 @@ static const M4GameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, GType_DragonSphere, kFeaturesCD @@ -318,7 +318,7 @@ static const M4GameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, GType_DragonSphere, kFeaturesDemo @@ -350,7 +350,7 @@ static const M4GameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, GType_Phantom, kFeaturesCD @@ -366,7 +366,7 @@ static const M4GameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, - GUIO1(GUIO_NONE) + GUIO0() }, GType_Phantom, kFeaturesDemo diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp index 2b2c479673..2a36fa037c 100644 --- a/engines/m4/dialogs.cpp +++ b/engines/m4/dialogs.cpp @@ -80,7 +80,7 @@ void Dialog::writeChars(const char *srcLine) { while (*srcP) { bool wordEndedP = false, newlineP = false; char *destP = &wordStr[0]; - Common::set_to(&wordStr[0], &wordStr[80], 0); + Common::fill(&wordStr[0], &wordStr[80], 0); // Try and get the next word for (;;) { @@ -117,8 +117,6 @@ void Dialog::writeChars(const char *srcLine) { destP = &wordStr[0]; *destP = '\0'; - lineLen = strlen(wordStr); - strcpy(line, ""); if (_lineX > 0) strcat(line, " "); diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp index 4c272de32c..99130aee08 100644 --- a/engines/m4/graphics.cpp +++ b/engines/m4/graphics.cpp @@ -48,7 +48,7 @@ RGBList::RGBList(int numEntries, RGB8 *srcData, bool freeData) { } _palIndexes = new byte[numEntries]; - Common::set_to(&_palIndexes[0], &_palIndexes[numEntries], 0); + Common::fill(&_palIndexes[0], &_palIndexes[numEntries], 0); } RGBList::~RGBList() { @@ -337,7 +337,7 @@ void M4Surface::freeData() { } void M4Surface::clear() { - Common::set_to((byte *)pixels, (byte *)pixels + w * h, _vm->_palette->BLACK); + Common::fill((byte *)pixels, (byte *)pixels + w * h, _vm->_palette->BLACK); } void M4Surface::reset() { @@ -1029,7 +1029,7 @@ static void fadeRange(MadsM4Engine *vm, RGB8 *srcPal, RGB8 *destPal, int startI Palette::Palette(MadsM4Engine *vm) : _vm(vm) { reset(); _fading_in_progress = false; - Common::set_to(&_usageCount[0], &_usageCount[256], 0); + Common::fill(&_usageCount[0], &_usageCount[256], 0); } void Palette::setPalette(const byte *colors, uint start, uint num) { @@ -1166,7 +1166,7 @@ void Palette::fadeFromGreen(int numSteps, uint delayAmount, bool fadeToBlack) { RGB8 *destPalette = (RGB8 *) &_originalPalette[0]; if (fadeToBlack) { - Common::set_to((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0); + Common::fill((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0); destPalette = &blackPalette[0]; } @@ -1193,7 +1193,7 @@ void Palette::fadeIn(int numSteps, uint delayAmount, RGB8 *destPalette, int numC _fading_in_progress = true; RGB8 blackPalette[256]; - Common::set_to((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0); + Common::fill((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0); // Initially set the black palette _vm->_palette->setPalette(blackPalette, 0, numColors); @@ -1209,7 +1209,7 @@ RGB8 *Palette::decodeMadsPalette(Common::SeekableReadStream *palStream, int *num assert(*numColors <= 252); RGB8 *palData = new RGB8[*numColors]; - Common::set_to((byte *)&palData[0], (byte *)&palData[*numColors], 0); + Common::fill((byte *)&palData[0], (byte *)&palData[*numColors], 0); for (int i = 0; i < *numColors; ++i) { byte r = palStream->readByte(); @@ -1249,12 +1249,12 @@ void Palette::setMadsSystemPalette() { } void Palette::resetColorCounts() { - Common::set_to(&_usageCount[0], &_usageCount[256], 0); + Common::fill(&_usageCount[0], &_usageCount[256], 0); } void Palette::blockRange(int startIndex, int size) { // Use a reference count of -1 to signal a palette index shouldn't be used - Common::set_to(&_usageCount[startIndex], &_usageCount[startIndex + size], -1); + Common::fill(&_usageCount[startIndex], &_usageCount[startIndex + size], -1); } void Palette::addRange(RGBList *list) { diff --git a/engines/m4/hotspot.cpp b/engines/m4/hotspot.cpp index a585a9af3d..a424d9fa23 100644 --- a/engines/m4/hotspot.cpp +++ b/engines/m4/hotspot.cpp @@ -258,7 +258,7 @@ void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int ho hotspotStream->read(buffer, strLength); // prep str_upper(buffer); - if (strlen(buffer) > 0 && strcmp(buffer, "--") != 0 && strcmp(buffer, "ON") != 0) + if (buffer[0] != '\0' && strcmp(buffer, "--") != 0 && strcmp(buffer, "ON") != 0) currentHotSpot->setPrep(buffer); else currentHotSpot->setPrep(currentHotSpot->getVocab()); diff --git a/engines/m4/mads_anim.cpp b/engines/m4/mads_anim.cpp index 2ea576dfa4..aac21ae65d 100644 --- a/engines/m4/mads_anim.cpp +++ b/engines/m4/mads_anim.cpp @@ -87,7 +87,7 @@ void TextviewView::reset() { _panY = 0; _panSpeed = 0; _soundDriverLoaded = false; - Common::set_to(&_spareScreens[0], &_spareScreens[10], 0); + Common::fill(&_spareScreens[0], &_spareScreens[10], 0); _scrollCount = 0; _lineY = -1; _scrollTimeout = 0; @@ -211,7 +211,7 @@ void TextviewView::updateState() { byte *pixelsP = _textSurface.getBasePtr(0, 0); Common::copy(pixelsP + width(), pixelsP + _textSurface.width() * _textSurface.height(), pixelsP); pixelsP = _textSurface.getBasePtr(0, _textSurface.height() - 1); - Common::set_to(pixelsP, pixelsP + _textSurface.width(), _vm->_palette->BLACK); + Common::fill(pixelsP, pixelsP + _textSurface.width(), _vm->_palette->BLACK); if (_scrollCount > 0) { // Handling final scrolling of text off of screen diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp index 335127393e..a7838d0e26 100644 --- a/engines/m4/mads_logic.cpp +++ b/engines/m4/mads_logic.cpp @@ -33,7 +33,7 @@ namespace M4 { void MadsGameLogic::initializeGlobals() { // Clear the entire globals list - Common::set_to(&_madsVm->globals()->_globals[0], &_madsVm->globals()->_globals[TOTAL_NUM_VARIABLES], 0); + Common::fill(&_madsVm->globals()->_globals[0], &_madsVm->globals()->_globals[TOTAL_NUM_VARIABLES], 0); SET_GLOBAL(4, 8); SET_GLOBAL(33, 1); @@ -479,7 +479,7 @@ void MadsSceneLogic::selectScene(int sceneNum) { assert(sceneNum == 101); _sceneNumber = sceneNum; - Common::set_to(&_spriteIndexes[0], &_spriteIndexes[50], 0); + Common::fill(&_spriteIndexes[0], &_spriteIndexes[50], 0); // If debugging is turned on, show a debug warning if any of the scene methods aren't present if (gDebugLevel > 0) { @@ -751,7 +751,7 @@ void MadsSceneLogic::execute(uint32 subOffset) { if (gDebugLevel > 0) { if (param != UNUSED_VAL) - sprintf(opcodeBuffer + strlen(opcodeBuffer), "\t%d", param); + sprintf(opcodeBuffer + strlen(opcodeBuffer), "\t%u", param); debugC(2, kDebugScript, "%s", opcodeBuffer); } } diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp index 8a2ab67f11..ae16b00616 100644 --- a/engines/m4/mads_menus.cpp +++ b/engines/m4/mads_menus.cpp @@ -716,7 +716,7 @@ void RexDialogView::onRefresh(RectList *rects, M4Surface *destSurface) { bool RexDialogView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { static bool word_7F28C = false; int word_7FED2 = 0; - int word_8502A = 0; + //int word_8502A = 0; // If it's a keypress, handle it immediately if (eventType == KEVENT_KEY) { @@ -789,7 +789,7 @@ bool RexDialogView::onEvent(M4EventType eventType, int32 param1, int x, int y, b if (!word_7F28C || (objIndex <= 18)) _selectedLine = objIndex; - word_8502A = -1; + //word_8502A = -1; } return true; diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 5f160aa300..e2d034f6d1 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -176,7 +176,7 @@ void MadsScene::loadScene(int sceneNumber) { _sceneLogic.doEnterScene(); // Miscellaneous player setup - _madsVm->_player._destPos = _madsVm->_player._destPos; + //_madsVm->_player._destPos = _madsVm->_player._destPos; _madsVm->_player._newDirection = _madsVm->_player._direction; _madsVm->_player.setupFrame(); _madsVm->_player.updateFrame(); @@ -729,7 +729,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su } } else { // 8-bit depth pixels - Common::set_to(destP, destP + runLength, *srcP++); + Common::fill(destP, destP + runLength, *srcP++); destP += runLength; } } diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 0521903c95..c1d88d5741 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -77,7 +77,7 @@ void MadsAction::appendVocab(int vocabId, bool capitalise) { void MadsAction::set() { int hotspotCount = _madsVm->scene()->getSceneResources().hotspots->size(); - bool flag = false; + bool flag = false; // FIXME: unused strcpy(_statusText, ""); _currentAction = -1; @@ -228,7 +228,7 @@ void MadsAction::refresh() { _statusTextIndex = -1; } - if (strlen(_statusText) != 0) { + if (_statusText[0] != '\0') { if ((_owner._screenObjects._v832EC == 0) || (_owner._screenObjects._v832EC == 2)) { Font *font = _madsVm->_font->getFont(FONT_MAIN_MADS); int textSpacing = -1; diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp index d3da7012ef..2591e92af3 100644 --- a/engines/made/detection.cpp +++ b/engines/made/detection.cpp @@ -80,7 +80,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -98,7 +98,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -115,7 +115,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -132,7 +132,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -150,7 +150,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -167,7 +167,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -185,7 +185,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -203,7 +203,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -221,7 +221,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -239,7 +239,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -257,7 +257,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -275,7 +275,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -309,7 +309,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -327,7 +327,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::JA_JPN, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -363,7 +363,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::JA_JPN, Common::kPlatformPC98, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_RTZ, 0, @@ -508,7 +508,7 @@ static MadeGameDescription g_fallbackDesc = { Common::UNK_LANG, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, 0, 0, diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp index dbe2f1c7ba..168902d577 100644 --- a/engines/made/screen.cpp +++ b/engines/made/screen.cpp @@ -437,15 +437,15 @@ uint16 Screen::placeSprite(uint16 channelIndex, uint16 flexIndex, int16 x, int16 PictureResource *flex = _vm->_res->getPicture(flexIndex); if (flex) { - Graphics::Surface *surf = flex->getPicture(); + //Graphics::Surface *surf = flex->getPicture(); int16 state = 1; - int16 x1, y1, x2, y2; + /*int16 x1, y1, x2, y2; x1 = x; y1 = y; x2 = x + surf->w + 1; - y2 = y + surf->h + 1; + y2 = y + surf->h + 1;*/ if (_ground == 0) state |= 2; @@ -485,12 +485,12 @@ uint16 Screen::placeAnim(uint16 channelIndex, uint16 animIndex, int16 x, int16 y if (anim) { int16 state = 1; - int16 x1, y1, x2, y2; + /*int16 x1, y1, x2, y2; x1 = x; y1 = y; x2 = x + anim->getWidth(); - y2 = y + anim->getHeight(); + y2 = y + anim->getHeight();*/ if (anim->getFlags() == 1 || _ground == 0) state |= 2; @@ -543,7 +543,7 @@ uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, i Object *obj = _vm->_dat->getObject(textObjectIndex); const char *text = obj->getString(); - int16 x1, y1, x2, y2; + //int16 x1, y1, x2, y2; setFont(fontNum); @@ -557,10 +557,10 @@ uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, i y--; } - x1 = x; + /*x1 = x; y1 = y; x2 = x + textWidth; - y2 = y + textHeight; + y2 = y + textHeight;*/ if (textWidth > 0 && outlineColor != -1) { x++; diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp index b67b333a85..b6c0a3212f 100644 --- a/engines/mohawk/myst_stacks/myst.cpp +++ b/engines/mohawk/myst_stacks/myst.cpp @@ -2138,7 +2138,7 @@ void Myst::rocketSliderMove() { } uint16 Myst::rocketSliderGetSound(uint16 pos) { - return (uint16)(9530 + (pos - 216) * 35.0 * 0.01639344262295082); + return (uint16)(9530 + (pos - 216) * 35.0 / 61.0); } void Myst::rocketCheckSolution() { diff --git a/engines/mohawk/myst_stacks/stoneship.cpp b/engines/mohawk/myst_stacks/stoneship.cpp index e0c374a926..4c715b56e4 100644 --- a/engines/mohawk/myst_stacks/stoneship.cpp +++ b/engines/mohawk/myst_stacks/stoneship.cpp @@ -655,7 +655,7 @@ void Stoneship::o_compassButton(uint16 op, uint16 var, uint16 argc, uint16 *argv _state.generatorPowerAvailable = 2; _state.lightState = 0; _state.generatorDepletionTime = 0; - _state.generatorDepletionTime = 0; + _state.generatorDuration = 0; _batteryDepleting = false; } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 1da61b68ae..a006edf114 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -596,20 +596,22 @@ void Gfx::updateFloatingLabel() { Common::Rect r; _floatingLabel->getRect(0, r); + FloatingLabelTraits traits_NS = { + Common::Point(16 - r.width()/2, 34), + Common::Point(8 - r.width()/2, 21), + 0, 0, _vm->_screenWidth - r.width(), 190 + }; + + // FIXME: _maxY for BRA is not constant (390), but depends on _vm->_subtitleY + FloatingLabelTraits traits_BR = { + Common::Point(34 - r.width()/2, 70), + Common::Point(16 - r.width()/2, 37), + 0, 0, _vm->_screenWidth - r.width(), 390 + }; + if (_gameType == GType_Nippon) { - FloatingLabelTraits traits_NS = { - Common::Point(16 - r.width()/2, 34), - Common::Point(8 - r.width()/2, 21), - 0, 0, _vm->_screenWidth - r.width(), 190 - }; traits = &traits_NS; } else { - // FIXME: _maxY for BRA is not constant (390), but depends on _vm->_subtitleY - FloatingLabelTraits traits_BR = { - Common::Point(34 - r.width()/2, 70), - Common::Point(16 - r.width()/2, 37), - 0, 0, _vm->_screenWidth - r.width(), 390 - }; traits = &traits_BR; } diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 44a8899304..658a8e8795 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -289,7 +289,7 @@ void Parallaction_br::changeLocation() { _disk->selectArchive(_partNames[_part]); - memset(_counters, 0, ARRAYSIZE(_counters)); + memset(_counters, 0, sizeof(_counters)); _globalFlagsNames = _disk->loadTable("global"); _objectsNames = _disk->loadTable("objects"); diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 5a1daa256b..3ab25f203f 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -49,7 +49,7 @@ Common::String SaveLoad::genSaveFileName(uint slot) { assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT); char s[20]; - sprintf(s, "%s.%.3d", _saveFilePrefix.c_str(), slot); + sprintf(s, "%s.%.3u", _saveFilePrefix.c_str(), slot); return Common::String(s); } diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp index 1f8d9b29f9..307425b77b 100644 --- a/engines/queen/talk.cpp +++ b/engines/queen/talk.cpp @@ -96,7 +96,7 @@ void Talk::talk(const char *filename, int personInRoom, char *cutawayFilename) { } int16 oldLevel = 0; - bool personWalking = false; + bool personWalking = false; // FIXME: unused // Lines 828-846 in talk.c for (i = 1; i <= 4; i++) { @@ -373,7 +373,7 @@ byte *Talk::loadDialogFile(const char *filename) { void Talk::load(const char *filename) { int i; byte *ptr = _fileData = loadDialogFile(filename); - bool canQuit; + bool canQuit; // FIXME: unused // Load talk header diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp index 091ec8d427..d39ec34cc8 100644 --- a/engines/saga/detection.cpp +++ b/engines/saga/detection.cpp @@ -209,7 +209,7 @@ int SagaMetaEngine::getMaximumSaveSlot() const { return MAX_SAVES - 1; } void SagaMetaEngine::removeSaveState(const char *target, int slot) const { Common::String filename = target; - filename += Common::String::format(".s%02d", slot);; + filename += Common::String::format(".s%02d", slot); g_system->getSavefileManager()->removeSavefile(filename); } diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h index 10393c4a2a..234a10acfe 100644 --- a/engines/saga/detection_tables.h +++ b/engines/saga/detection_tables.h @@ -267,7 +267,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, @@ -293,7 +293,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, GF_8BIT_UNSIGNED_PCM, @@ -326,7 +326,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, GF_8BIT_UNSIGNED_PCM, @@ -350,7 +350,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, @@ -382,7 +382,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformUnknown, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, @@ -412,7 +412,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformUnknown, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, @@ -436,7 +436,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, GF_EXTRA_ITE_CREDITS, @@ -460,7 +460,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, @@ -484,7 +484,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, @@ -509,7 +509,7 @@ static const SAGAGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_ITE, 0, diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp index ab0c0f3e4c..8e98f0fbe7 100644 --- a/engines/saga/gfx.cpp +++ b/engines/saga/gfx.cpp @@ -123,7 +123,7 @@ void Surface::drawPolyLine(const Point *points, int count, int color) { drawLine(points[i].x, points[i].y, points[i - 1].x, points[i - 1].y, color); } - drawLine(points[count - 1].x, points[count - 1].y, points->x, points->y, color); + drawLine(points[count - 1].x, points[count - 1].y, points[0].x, points[0].y, color); } } diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp index e886f0df82..ec6b13f313 100644 --- a/engines/saga/isomap.cpp +++ b/engines/saga/isomap.cpp @@ -95,7 +95,7 @@ static const int16 directions[8][2] = { IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) { _viewScroll.x = (128 - 8) * 16; - _viewScroll.x = (128 - 8) * 16 - 64; + _viewScroll.y = (128 - 8) * 16 - 64; _viewDiff = 1; } diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp index 9e0789fdaf..6a5a7d8e14 100644 --- a/engines/saga/saveload.cpp +++ b/engines/saga/saveload.cpp @@ -44,7 +44,7 @@ static SaveFileData emptySlot = { char* SagaEngine::calcSaveFileName(uint slotNumber) { static char name[MAX_FILE_NAME]; - sprintf(name, "%s.s%02d", _targetName.c_str(), slotNumber); + sprintf(name, "%s.s%02u", _targetName.c_str(), slotNumber); return name; } diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index a44c661561..b852de74a9 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -1876,16 +1876,17 @@ bool Console::segmentInfo(int nr) { DebugPrintf(" Synonyms: %4d\n", scr->getSynonymsNr()); - if (scr->_localsBlock) - DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->_localsBlock->_locals.size(), scr->_localsSegment); + if (scr->getLocalsCount() > 0) + DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->getLocalsCount(), scr->getLocalsSegment()); else DebugPrintf(" Locals : none\n"); - DebugPrintf(" Objects: %4d\n", scr->_objects.size()); + ObjMap objects = scr->getObjectMap(); + DebugPrintf(" Objects: %4d\n", objects.size()); ObjMap::iterator it; - const ObjMap::iterator end = scr->_objects.end(); - for (it = scr->_objects.begin(); it != end; ++it) { + const ObjMap::iterator end = objects.end(); + for (it = objects.begin(); it != end; ++it) { DebugPrintf(" "); // Object header const Object *obj = _engine->_gamestate->_segMan->getObject(it->_value.getPos()); @@ -2942,9 +2943,10 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) { script = customSegMan->getScript(scriptSegment); // Iterate through all the script's objects + ObjMap objects = script->getObjectMap(); ObjMap::iterator it; - const ObjMap::iterator end = script->_objects.end(); - for (it = script->_objects.begin(); it != end; ++it) { + const ObjMap::iterator end = objects.end(); + for (it = objects.begin(); it != end; ++it) { const Object *obj = customSegMan->getObject(it->_value.getPos()); const char *objName = customSegMan->getObjectName(it->_value.getPos()); diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 2d567a7fde..80f45b4325 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -373,7 +373,7 @@ static ADGameDescription s_fallbackDesc = { Common::UNK_LANG, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }; static char s_fallbackGameIdBuf[256]; @@ -435,7 +435,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles, s_fallbackDesc.flags = ADGF_NO_FLAGS; s_fallbackDesc.platform = Common::kPlatformPC; // default to PC platform s_fallbackDesc.gameid = "sci"; - s_fallbackDesc.guioptions = GUIO1(GUIO_NONE); + s_fallbackDesc.guioptions = GUIO0(); if (allFiles.contains("resource.map") || allFiles.contains("Data1") || allFiles.contains("resmap.001") || allFiles.contains("resmap.001")) { diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 5da12d6695..63eda1c348 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -427,7 +427,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, {"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Eco Quest - English DOS CD 1.1 // SCI interpreter version 1.001.064 @@ -541,7 +541,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058}, {"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720) // Executable scanning reports "1.cfs.081" @@ -583,7 +583,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Freddy Pharkas - Spanish DOS (from jvprat) // Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" @@ -601,7 +601,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918}, {"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() }, // Freddy Pharkas - English Macintosh {"freddypharkas", "", { @@ -624,7 +624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490}, {"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() }, #ifdef ENABLE_SCI32 // Gabriel Knight - English DOS Floppy @@ -665,7 +665,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - English Windows CD (from jvprat) // Executable scanning reports "2.000.000", VERSION file reports "01.100.000" @@ -681,7 +681,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - Spanish DOS CD (from jvprat) // Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995" @@ -689,7 +689,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - French DOS CD (from Hkz) // VERSION file reports "1.000.000, May 3, 1994" @@ -697,7 +697,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "55f909ba93a2515042a08d8a2da8414e", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13325145}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - German Windows CD (from Tobis87) // SCI interpreter version 2.000.000 @@ -990,7 +990,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878}, {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Jones in the Fast Lane - English DOS CD // Same entry as the DOS version above. This one is used for the alternate @@ -1201,7 +1201,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, {"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // King's Quest 5 - English DOS CD (from the King's Quest Collection) // Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052" @@ -1382,7 +1382,13 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094}, {"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) }, + Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) }, + {"kq5", "", { + {"resource.map", 0, "20c7cd248ff1a349ed354568eebd972b", 12733}, + {"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094}, + {"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839}, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) }, // King's Quest 5 - Japanese PC-98 Floppy 0.000.015 (supplied by omer_mor in bug report #3073583) {"kq5", "", { @@ -1431,7 +1437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // King's Quest 6 - English Windows CD (from the King's Quest Collection) // Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G" @@ -1450,7 +1456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260}, {"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() }, // King's Quest 6 - English Macintosh Floppy // VERSION file reports "1.0" @@ -1605,7 +1611,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274}, {"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Laura Bow 2 v1.1 - French DOS Floppy (from Hkz) {"laurabow2", "", { @@ -1631,7 +1637,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 1 EGA Remake - English DOS (from spookypeanut) // SCI interpreter version 0.000.510 (or 0.000.577?) @@ -2064,7 +2070,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263}, {"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 6 - German DOS CD - LOWRES (provided by richiefs in bug report #2670691) // SCI interpreter version 1.001.115 @@ -2072,7 +2078,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 6 - French DOS CD - LOWRES (provided by richiefs in bug report #2670691) // SCI interpreter version 1.001.115 @@ -2080,7 +2086,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 6 - Spanish DOS - LOWRES (from the Leisure Suit Larry Collection) // Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93" @@ -2329,7 +2335,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Mixed-Up Mother Goose - English Windows Interactive Demo // Executable scanning reports "x.yyy.zzz" @@ -2345,6 +2351,11 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713}, AD_LISTEND}, Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) }, + {"mothergoose256", "", { + {"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772}, + {"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713}, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) }, #ifdef ENABLE_SCI32 // Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810) @@ -2660,7 +2671,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374}, {"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Police Quest 4 - German DOS CD (German text, English speech) // Supplied by markcoolio in bug report #3392955 @@ -2668,7 +2679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a398076371ed0e1e706c8f9fb9fc7ac5", 11386}, {"resource.000", 0, "6ff21954e0a2c5992279e7eb787c8d56", 18918747}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Police Quest 4 - English DOS // SCI interpreter version 2.000.000 (a guess?) @@ -3008,7 +3019,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098}, {"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NONE) }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO0() }, // Quest for Glory 3 - Italian DOS // Supplied by ghoost in bug report #3053457 @@ -3017,7 +3028,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, {"resource.msg", 0, "5a0a896ff3e4a628db38a75eb6c84114", 259018}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO1(GUIO_NONE) }, + Common::IT_ITA, Common::kPlatformPC, 0, GUIO0() }, // Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.069 (just a guess) @@ -3180,6 +3191,13 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, + // Slater & Charlie Go Camping - English Macintosh + {"slater", "", { + {"Data1", 0, "7243b4390e5f0182d8133fbcae4b50c5", 2298853}, + {"Data2", 0, "6b6f18f9b502dc0923eeae0ef47f02d5", 2276956}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) }, + // Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org) // SCI interpreter version 1.000.510 (just a guess) {"sq1sci", "SCI", { @@ -3488,7 +3506,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, {"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Space Quest 4 - English Windows CD (from the Space Quest Collection) // Executable scanning reports "1.001.064", VERSION file reports "1.0" @@ -3512,7 +3530,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752}, {"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NONE) }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO0() }, // Space Quest 4 - Spanish DOS Floppy (from jvprat, also includes english language) // Executable scanning reports "1.SQ4.056", VERSION file reports "1.000" @@ -3676,7 +3694,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NONE) }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO0() }, // The Island of Dr. Brain - English DOS (from Quietust) // Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93" diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 8cb294e166..e549c1f8ae 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -457,6 +457,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv); reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv); reg_t kInPolygon(EngineState *s, int argc, reg_t *argv); reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv); +reg_t kEditText(EngineState *s, int argc, reg_t *argv); // SCI2.1 Kernel Functions reg_t kText(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index afe6b176e5..d8d9f6bd82 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -499,6 +499,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL }, + { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL }, // SCI2 unmapped functions - TODO! @@ -523,13 +524,6 @@ static SciKernelMapEntry s_kernelMap[] = { // TODO: Implement once the original save/load menus are implemented. { MAP_DUMMY(MakeSaveFileName), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - // Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl, - // but it handles events on its own, using an internal loop, instead of using SCI - // scripts for event management like kEditControl does. Called by script 64914, - // DEdit::hilite(). - // TODO: Implement once the original save/load menus are implemented. - { MAP_DUMMY(EditText), SIG_EVERYWHERE, "o", NULL, NULL }, - // Unused / debug SCI2 unused functions, always mapped to kDummy // AddMagnify/DeleteMagnify are both called by script 64979 (the Magnifier diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 9e9441847d..ce903626e7 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -22,6 +22,7 @@ #include "common/archive.h" #include "common/config-manager.h" +#include "common/debug-channels.h" #include "common/file.h" #include "common/str.h" #include "common/savefile.h" @@ -52,9 +53,10 @@ struct SavegameDesc { * arbitrary data files, simply because many of our target platforms do not * support this. The only files one can create are savestates. But SCI has an * opcode to create and write to seemingly 'arbitrary' files. This is mainly - * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver) and - * in LSL5 for MEMORY.DRV (which is again a game data file and contains the - * game's password). + * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used + * for persisting the results of the "age quiz" across restarts) and in LSL5 + * for MEMORY.DRV (which is again a game data file and contains the game's + * password, XOR encrypted). * To implement that opcode, we combine the SaveFileManager with regular file * code, similarly to how the SCUMM HE engine does it. * @@ -115,20 +117,6 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u if (!inFile) inFile = SearchMan.createReadStreamForMember(englishName); - // Special case for LSL3: It tries to create a new dummy file, - // LARRY3.DRV. Apparently, if the file doesn't exist here, it should be - // created. The game scripts then go ahead and fill its contents with - // data. It seems to be a similar case as the dummy MEMORY.DRV file in - // LSL5, but LSL5 creates the file if it can't find it with a separate - // call to file_open(). - if (!inFile && englishName == "LARRY3.DRV") { - outFile = saveFileMan->openForSaving(wrappedName); - outFile->finalize(); - delete outFile; - outFile = 0; - inFile = SearchMan.createReadStreamForMember(wrappedName); - } - if (!inFile) debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); } else if (mode == _K_FILE_MODE_CREATE) { @@ -1060,6 +1048,18 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { exists = !saveFileMan->listSavefiles(wrappedName).empty(); } + // SCI2+ debug mode + if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) { + if (!exists && name == "1.scr") // PQ4 + exists = true; + if (!exists && name == "18.scr") // QFG4 + exists = true; + if (!exists && name == "99.scr") // GK1, KQ7 + exists = true; + if (!exists && name == "classes") // GK2, SQ6, LSL7 + exists = true; + } + // Special case for non-English versions of LSL5: The English version of // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if // memory.drv exists (which is where the game's password is stored). If diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 566f2a9a7d..76c6778f0a 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -49,6 +49,7 @@ #include "sci/graphics/text16.h" #include "sci/graphics/view.h" #ifdef ENABLE_SCI32 +#include "sci/graphics/controls32.h" #include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class #include "sci/graphics/text32.h" #include "sci/graphics/frameout.h" @@ -1665,8 +1666,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height); // Save totalWidth, totalHeight // TODO: Save the whole bitmap header, like SSCI does - WRITE_LE_UINT16((void *)memoryPtr, width); - WRITE_LE_UINT16((void *)(memoryPtr + 2), height); + WRITE_LE_UINT16(memoryPtr, width); + WRITE_LE_UINT16(memoryPtr + 2, height); return memoryId; } break; @@ -1692,8 +1693,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr); - uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2)); + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; GfxView *view = g_sci->_gfxCache->getView(viewNum); @@ -1733,8 +1734,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr); - uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2)); + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; GfxFont *font = g_sci->_gfxCache->getFont(fontId); @@ -1776,8 +1777,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr); - uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2)); + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); uint16 width = MIN<uint16>(totalWidth - x, fillWidth); uint16 height = MIN<uint16>(totalHeight - y, fillHeight); byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; @@ -1798,6 +1799,20 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +// Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl, +// but it handles events on its own, using an internal loop, instead of using SCI +// scripts for event management like kEditControl does. Called by script 64914, +// DEdit::hilite(). +reg_t kEditText(EngineState *s, int argc, reg_t *argv) { + reg_t controlObject = argv[0]; + + if (!controlObject.isNull()) { + g_sci->_gfxControls32->kernelTexteditChange(controlObject); + } + + return s->r_acc; +} + #endif } // End of namespace Sci diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 8500f08211..83e59c9c20 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -409,7 +409,7 @@ int sort_temp_cmp(const void *p1, const void *p2) { const sort_temp_t *st1 = (const sort_temp_t *)p1; const sort_temp_t *st2 = (const sort_temp_t *)p2; - if (st1->order.segment < st1->order.segment || (st1->order.segment == st1->order.segment && st1->order.offset < st2->order.offset)) + if (st1->order.segment < st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset < st2->order.offset)) return -1; if (st1->order.segment > st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset > st2->order.offset)) diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 33bef58e52..c469f775f9 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -195,6 +195,13 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 1); } else { int16 language = argv[1].toSint16(); + + // athrxx: It seems from disasm that the original KQ5 FM-Towns loads a default language (Japanese) audio map at the beginning + // right after loading the video and audio drivers. The -1 language argument in here simply means that the original will stick + // with Japanese. Instead of doing that we switch to the language selected in the launcher. + if (g_sci->getPlatform() == Common::kPlatformFMTowns && language == -1) + language = (g_sci->getLanguage() == Common::JA_JPN) ? K_LANG_JAPANESE : K_LANG_ENGLISH; + debugC(kDebugLevelSound, "kDoAudio: set language to %d", language); if (language != -1) diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 1a9359bb26..5ae18c1367 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -697,13 +697,15 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { case 6: { // Cpy const char *string2 = 0; uint32 string2Size = 0; + Common::String string; if (argv[3].segment == s->_segMan->getStringSegmentId()) { - SciString *string = s->_segMan->lookupString(argv[3]); - string2 = string->getRawData(); - string2Size = string->getSize(); + SciString *sstr; + sstr = s->_segMan->lookupString(argv[3]); + string2 = sstr->getRawData(); + string2Size = sstr->getSize(); } else { - Common::String string = s->_segMan->getString(argv[3]); + string = s->_segMan->getString(argv[3]); string2 = string.c_str(); string2Size = string.size() + 1; } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 030c0f3f54..f1c7133d01 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -203,7 +203,8 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { // Now, load the script itself scr->load(g_sci->getResMan()); - for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) + ObjMap objects = scr->getObjectMap(); + for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) it->_value.syncBaseObject(scr->getBuf(it->_value.getPos().offset)); } @@ -226,9 +227,10 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { continue; Script *scr = (Script *)_heap[i]; - scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(_heap[scr->_localsSegment]); + scr->syncLocalsBlock(this); - for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) { + ObjMap objects = scr->getObjectMap(); + for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) { reg_t addr = it->_value.getPos(); Object *obj = scr->scriptObjInit(addr, false); @@ -237,7 +239,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { // TODO/FIXME: This should not be happening at all. It might indicate a possible issue // with the garbage collector. It happens for example in LSL5 (German, perhaps English too). warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); - scr->_objects.erase(addr.toUint16()); + objects.erase(addr.toUint16()); } } } diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 01e1afe5ea..8b26969f4a 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -492,8 +492,29 @@ SegmentRef Script::dereference(reg_t pointer) { return ret; } +LocalVariables *Script::allocLocalsSegment(SegManager *segMan) { + if (!getLocalsCount()) { // No locals + return NULL; + } else { + LocalVariables *locals; + + if (_localsSegment) { + locals = (LocalVariables *)segMan->getSegment(_localsSegment, SEG_TYPE_LOCALS); + if (!locals || locals->getType() != SEG_TYPE_LOCALS || locals->script_id != getScriptNumber()) + error("Invalid script locals segment while allocating locals"); + } else + locals = (LocalVariables *)segMan->allocSegment(new LocalVariables(), &_localsSegment); + + _localsBlock = locals; + locals->script_id = getScriptNumber(); + locals->_locals.resize(getLocalsCount()); + + return locals; + } +} + void Script::initializeLocals(SegManager *segMan) { - LocalVariables *locals = segMan->allocLocalsSegment(this); + LocalVariables *locals = allocLocalsSegment(segMan); if (locals) { if (getSciVersion() > SCI_VERSION_0_EARLY) { const byte *base = (const byte *)(_buf + getLocalsOffset()); @@ -508,6 +529,10 @@ void Script::initializeLocals(SegManager *segMan) { } } +void Script::syncLocalsBlock(SegManager *segMan) { + _localsBlock = (_localsSegment == 0) ? NULL : (LocalVariables *)(segMan->getSegment(_localsSegment, SEG_TYPE_LOCALS)); +} + void Script::initializeClasses(SegManager *segMan) { const byte *seeker = 0; uint16 mult = 0; diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index ff061e0e36..1ebae3b7a8 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -62,23 +62,18 @@ private: const uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */ uint16 _numExports; /**< Number of entries in the exports table */ - const byte *_synonyms; /**< Synonyms block or 0 if not present*/ + const byte *_synonyms; /**< Synonyms block or 0 if not present */ uint16 _numSynonyms; /**< Number of entries in the synonyms block */ int _localsOffset; uint16 _localsCount; bool _markedAsDeleted; - -public: - /** - * Table for objects, contains property variables. - * Indexed by the TODO offset. - */ - ObjMap _objects; SegmentId _localsSegment; /**< The local variable segment */ LocalVariables *_localsBlock; + ObjMap _objects; /**< Table for objects, contains property variables */ + public: int getLocalsOffset() const { return _localsOffset; } uint16 getLocalsCount() const { return _localsCount; } @@ -89,6 +84,11 @@ public: const byte *getBuf(uint offset = 0) const { return _buf + offset; } int getScriptNumber() const { return _nr; } + SegmentId getLocalsSegment() const { return _localsSegment; } + reg_t *getLocalsBegin() { return _localsBlock ? _localsBlock->_locals.begin() : NULL; } + void syncLocalsBlock(SegManager *segMan); + ObjMap &getObjectMap() { return _objects; } + const ObjMap &getObjectMap() const { return _objects; } public: Script(); @@ -295,6 +295,8 @@ private: * @param segmentId The script's segment id */ void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId); + + LocalVariables *allocLocalsSegment(SegManager *segMan); }; } // End of namespace Sci diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 1510af8508..04c61f7b7c 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -151,8 +151,8 @@ void SegManager::deallocate(SegmentId seg) { if (mobj->getType() == SEG_TYPE_SCRIPT) { Script *scr = (Script *)mobj; _scriptSegMap.erase(scr->getScriptNumber()); - if (scr->_localsSegment) - deallocate(scr->_localsSegment); + if (scr->getLocalsSegment()) + deallocate(scr->getLocalsSegment()); } delete mobj; @@ -270,12 +270,13 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) { if (mobj->getType() == SEG_TYPE_SCRIPT) { // It's a script, scan all objects in it const Script *scr = (const Script *)mobj; - for (ObjMap::const_iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) { + const ObjMap &objects = scr->getObjectMap(); + for (ObjMap::const_iterator it = objects.begin(); it != objects.end(); ++it) { objpos.offset = it->_value.getPos().offset; if (name == getObjectName(objpos)) result.push_back(objpos); } - } else if (mobj->getType() == SEG_TYPE_CLONES) { + } else if (mobj->getType() == SEG_TYPE_CLONES) { // It's clone table, scan all objects in it const CloneTable *ct = (const CloneTable *)mobj; for (uint idx = 0; idx < ct->_table.size(); ++idx) { @@ -341,29 +342,6 @@ SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load) { return segment; } -LocalVariables *SegManager::allocLocalsSegment(Script *scr) { - if (!scr->getLocalsCount()) { // No locals - scr->_localsSegment = 0; - scr->_localsBlock = NULL; - return NULL; - } else { - LocalVariables *locals; - - if (scr->_localsSegment) { - locals = (LocalVariables *)_heap[scr->_localsSegment]; - if (!locals || locals->getType() != SEG_TYPE_LOCALS || locals->script_id != scr->getScriptNumber()) - error("Invalid script locals segment while allocating locals"); - } else - locals = (LocalVariables *)allocSegment(new LocalVariables(), &scr->_localsSegment); - - scr->_localsBlock = locals; - locals->script_id = scr->getScriptNumber(); - locals->_locals.resize(scr->getLocalsCount()); - - return locals; - } -} - DataStack *SegManager::allocateStack(int size, SegmentId *segid) { SegmentObj *mobj = allocSegment(new DataStack(), segid); DataStack *retval = (DataStack *)mobj; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index ab5aeacabf..62e711e686 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -463,8 +463,10 @@ private: SegmentId _stringSegId; #endif -private: +public: SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid); + +private: void deallocate(SegmentId seg); void createClassTable(); @@ -477,9 +479,6 @@ private: * 'seg' is a valid segment */ bool check(SegmentId seg); - -public: - LocalVariables *allocLocalsSegment(Script *scr); }; } // End of namespace Sci diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 3f11d6ff49..73d81baf3a 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -143,9 +143,11 @@ SegmentRef LocalVariables::dereference(reg_t pointer) { if (ret.maxSize > 0) { ret.reg = &_locals[pointer.offset / 2]; } else { - if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660) + if ((g_sci->getEngineState()->currentRoomNumber() == 160 || + g_sci->getEngineState()->currentRoomNumber() == 220) && g_sci->getGameId() == GID_LAURABOW2) { - // Happens in two places during the intro of LB2CD, both from kMemory(peek): + // WORKAROUND: Happens in two places during the intro of LB2CD, both + // from kMemory(peek): // - room 160: Heap 160 has 83 local variables (0-82), and the game // asks for variables at indices 83 - 90 too. // - room 220: Heap 220 has 114 local variables (0-113), and the diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index a9aca9e22f..a8b1cf7ec2 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -178,6 +178,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(dimmed); FIND_SELECTOR(fore); FIND_SELECTOR(back); + FIND_SELECTOR(skip); FIND_SELECTOR(fixPriority); FIND_SELECTOR(mirrored); FIND_SELECTOR(useInsetRect); diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index bbd86bb03e..4b913a866a 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -144,6 +144,7 @@ struct SelectorCache { Selector fore; Selector back; + Selector skip; Selector dimmed; Selector fixPriority; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 4ea9f72054..28818cddef 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -145,12 +145,12 @@ void EngineState::wait(int16 ticks) { void EngineState::initGlobals() { Script *script_000 = _segMan->getScript(1); - if (!script_000->_localsBlock) + if (script_000->getLocalsCount() == 0) error("Script 0 has no locals block"); - variablesSegment[VAR_GLOBAL] = script_000->_localsSegment; - variablesBase[VAR_GLOBAL] = variables[VAR_GLOBAL] = script_000->_localsBlock->_locals.begin(); - variablesMax[VAR_GLOBAL] = script_000->_localsBlock->_locals.size(); + variablesSegment[VAR_GLOBAL] = script_000->getLocalsSegment(); + variablesBase[VAR_GLOBAL] = variables[VAR_GLOBAL] = script_000->getLocalsBegin(); + variablesMax[VAR_GLOBAL] = script_000->getLocalsCount(); } uint16 EngineState::currentRoomNumber() const { diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index c94fdac034..6b3a3198ea 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -593,15 +593,9 @@ void run_vm(EngineState *s) { if (!local_script) { error("Could not find local script from segment %x", s->xs->local_segment); } else { - s->variablesSegment[VAR_LOCAL] = local_script->_localsSegment; - if (local_script->_localsBlock) - s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->_localsBlock->_locals.begin(); - else - s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = NULL; - if (local_script->_localsBlock) - s->variablesMax[VAR_LOCAL] = local_script->_localsBlock->_locals.size(); - else - s->variablesMax[VAR_LOCAL] = 0; + s->variablesSegment[VAR_LOCAL] = local_script->getLocalsSegment(); + s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->getLocalsBegin(); + s->variablesMax[VAR_LOCAL] = local_script->getLocalsCount(); s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp; s->variablesMax[VAR_PARAM] = s->xs->argc + 1; } diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp index c14cfada07..378e88b7df 100644 --- a/engines/sci/event.cpp +++ b/engines/sci/event.cpp @@ -253,14 +253,11 @@ SciEvent EventManager::getScummVMEvent() { if ((modifiers & Common::KBD_ALT) && input.character > 0 && input.character < 27) input.character += 96; // 0x01 -> 'a' - if (getSciVersion() <= SCI_VERSION_1_MIDDLE) { - // TODO: find out if altify is also not needed for sci1late+, couldnt find any game that uses those keys - // Scancodify if appropriate - if (modifiers & Common::KBD_ALT) - input.character = altify(input.character); - else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27) - input.character += 96; // 0x01 -> 'a' - } + // Scancodify if appropriate + if (modifiers & Common::KBD_ALT) + input.character = altify(input.character); + else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27) + input.character += 96; // 0x01 -> 'a' // If no actual key was pressed (e.g. if only a modifier key was pressed), // ignore the event diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp new file mode 100644 index 0000000000..ad1d9e8623 --- /dev/null +++ b/engines/sci/graphics/controls32.cpp @@ -0,0 +1,204 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/system.h" + +#include "sci/sci.h" +#include "sci/event.h" +#include "sci/engine/kernel.h" +#include "sci/engine/seg_manager.h" +#include "sci/graphics/cache.h" +#include "sci/graphics/compare.h" +#include "sci/graphics/controls32.h" +#include "sci/graphics/font.h" +#include "sci/graphics/screen.h" +#include "sci/graphics/text32.h" + +namespace Sci { + +GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text) + : _segMan(segMan), _cache(cache), _screen(screen), _text(text) { +} + +GfxControls32::~GfxControls32() { +} + +void GfxControls32::kernelTexteditChange(reg_t controlObject) { + SciEvent curEvent; + uint16 maxChars = 40; //readSelectorValue(_segMan, controlObject, SELECTOR(max)); // TODO + reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text)); + GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font))); + Common::String text; + uint16 textSize; + bool textChanged = false; + bool textAddChar = false; + Common::Rect rect; + + if (textReference.isNull()) + error("kEditControl called on object that doesnt have a text reference"); + text = _segMan->getString(textReference); + + // TODO: Finish this + warning("kEditText ('%s')", text.c_str()); + return; + + uint16 cursorPos = 0; + //uint16 oldCursorPos = cursorPos; + bool captureEvents = true; + EventManager* eventMan = g_sci->getEventManager(); + + while (captureEvents) { + curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK); + + if (curEvent.type == SCI_EVENT_NONE) { + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + } else { + textSize = text.size(); + + switch (curEvent.type) { + case SCI_EVENT_MOUSE_PRESS: + // TODO: Implement mouse support for cursor change + break; + case SCI_EVENT_KEYBOARD: + switch (curEvent.data) { + case SCI_KEY_BACKSPACE: + if (cursorPos > 0) { + cursorPos--; text.deleteChar(cursorPos); + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_DELETE: + if (cursorPos < textSize) { + text.deleteChar(cursorPos); + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_HOME: // HOME + cursorPos = 0; textChanged = true; + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_END: // END + cursorPos = textSize; textChanged = true; + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_LEFT: // LEFT + if (cursorPos > 0) { + cursorPos--; textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_RIGHT: // RIGHT + if (cursorPos + 1 <= textSize) { + cursorPos++; textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case 3: // returned in SCI1 late and newer when Control - C is pressed + if (curEvent.modifiers & SCI_KEYMOD_CTRL) { + // Control-C erases the whole line + cursorPos = 0; text.clear(); + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_UP: + case SCI_KEY_DOWN: + case SCI_KEY_ENTER: + case SCI_KEY_ESC: + case SCI_KEY_TAB: + case SCI_KEY_SHIFT_TAB: + captureEvents = false; + break; + default: + if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) { + // Control-C in earlier SCI games (SCI0 - SCI1 middle) + // Control-C erases the whole line + cursorPos = 0; text.clear(); + textChanged = true; + } else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) { + // insert pressed character + textAddChar = true; + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + } + break; + } + } + + if (textChanged) { + rect = g_sci->_gfxCompare->getNSRect(controlObject); + + if (textAddChar) { + const char *textPtr = text.c_str(); + + // We check if we are really able to add the new char + uint16 textWidth = 0; + while (*textPtr) + textWidth += font->getCharWidth((byte)*textPtr++); + textWidth += font->getCharWidth(curEvent.data); + + // Does it fit? + if (textWidth >= rect.width()) { + return; + } + + text.insertChar(curEvent.data, cursorPos++); + + // Note: the following checkAltInput call might make the text + // too wide to fit, but SSCI fails to check that too. + } + + reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap)); + Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject); + //texteditCursorErase(); // TODO: Cursor + + // Write back string + _segMan->strcpy(textReference, text.c_str()); + // Modify the buffer and show it + _text->createTextBitmap(controlObject, 0, 0, hunkId); + + _text->drawTextBitmap(0, 0, nsRect, controlObject); + //texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor + g_system->updateScreen(); + } else { + // TODO: Cursor + /* + if (g_system->getMillis() >= _texteditBlinkTime) { + _paint16->invertRect(_texteditCursorRect); + _paint16->bitsShow(_texteditCursorRect); + _texteditCursorVisible = !_texteditCursorVisible; + texteditSetBlinkTime(); + } + */ + } + + textAddChar = false; + textChanged = false; + g_sci->sleep(10); + } // while +} + +} // End of namespace Sci diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h new file mode 100644 index 0000000000..68dca59462 --- /dev/null +++ b/engines/sci/graphics/controls32.h @@ -0,0 +1,51 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCI_GRAPHICS_CONTROLS32_H +#define SCI_GRAPHICS_CONTROLS32_H + +namespace Sci { + +class GfxCache; +class GfxScreen; +class GfxText32; + +/** + * Controls class, handles drawing of controls in SCI32 (SCI2, SCI2.1, SCI3) games + */ +class GfxControls32 { +public: + GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text); + ~GfxControls32(); + + void kernelTexteditChange(reg_t controlObject); + +private: + SegManager *_segMan; + GfxCache *_cache; + GfxScreen *_screen; + GfxText32 *_text; +}; + +} // End of namespace Sci + +#endif diff --git a/engines/sci/graphics/coordadjuster.cpp b/engines/sci/graphics/coordadjuster.cpp index 2952d4da7b..1446888cf4 100644 --- a/engines/sci/graphics/coordadjuster.cpp +++ b/engines/sci/graphics/coordadjuster.cpp @@ -86,8 +86,8 @@ Common::Rect GfxCoordAdjuster16::pictureGetDisplayArea() { #ifdef ENABLE_SCI32 GfxCoordAdjuster32::GfxCoordAdjuster32(SegManager *segMan) : _segMan(segMan) { - scriptsRunningWidth = 0; - scriptsRunningHeight = 0; + _scriptsRunningWidth = 0; + _scriptsRunningHeight = 0; } GfxCoordAdjuster32::~GfxCoordAdjuster32() { @@ -109,18 +109,18 @@ void GfxCoordAdjuster32::kernelLocalToGlobal(int16 &x, int16 &y, reg_t planeObje } void GfxCoordAdjuster32::setScriptsResolution(uint16 width, uint16 height) { - scriptsRunningWidth = width; - scriptsRunningHeight = height; + _scriptsRunningWidth = width; + _scriptsRunningHeight = height; } void GfxCoordAdjuster32::fromDisplayToScript(int16 &y, int16 &x) { - y = ((y * scriptsRunningHeight) / g_sci->_gfxScreen->getHeight()); - x = ((x * scriptsRunningWidth) / g_sci->_gfxScreen->getWidth()); + y = ((y * _scriptsRunningHeight) / g_sci->_gfxScreen->getHeight()); + x = ((x * _scriptsRunningWidth) / g_sci->_gfxScreen->getWidth()); } void GfxCoordAdjuster32::fromScriptToDisplay(int16 &y, int16 &x) { - y = ((y * g_sci->_gfxScreen->getHeight()) / scriptsRunningHeight); - x = ((x * g_sci->_gfxScreen->getWidth()) / scriptsRunningWidth); + y = ((y * g_sci->_gfxScreen->getHeight()) / _scriptsRunningHeight); + x = ((x * g_sci->_gfxScreen->getWidth()) / _scriptsRunningWidth); } void GfxCoordAdjuster32::pictureSetDisplayArea(Common::Rect displayArea) { diff --git a/engines/sci/graphics/coordadjuster.h b/engines/sci/graphics/coordadjuster.h index 23cf79d209..63f608be6b 100644 --- a/engines/sci/graphics/coordadjuster.h +++ b/engines/sci/graphics/coordadjuster.h @@ -96,8 +96,8 @@ private: Common::Rect _pictureDisplayArea; - uint16 scriptsRunningWidth; - uint16 scriptsRunningHeight; + uint16 _scriptsRunningWidth; + uint16 _scriptsRunningHeight; }; #endif diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index a41efd6a9f..7bb4162020 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -56,8 +56,8 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd : _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) { _coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster; - scriptsRunningWidth = 320; - scriptsRunningHeight = 200; + _scriptsRunningWidth = 320; + _scriptsRunningHeight = 200; } GfxFrameout::~GfxFrameout() { @@ -80,11 +80,11 @@ void GfxFrameout::kernelAddPlane(reg_t object) { // The above can be 0 in SCI3 (e.g. Phantasmagoria 2) if (tmpRunningWidth > 0 && tmpRunningHeight > 0) { - scriptsRunningWidth = tmpRunningWidth; - scriptsRunningHeight = tmpRunningHeight; + _scriptsRunningWidth = tmpRunningWidth; + _scriptsRunningHeight = tmpRunningHeight; } - _coordAdjuster->setScriptsResolution(scriptsRunningWidth, scriptsRunningHeight); + _coordAdjuster->setScriptsResolution(_scriptsRunningWidth, _scriptsRunningHeight); } newPlane.object = object; @@ -118,14 +118,14 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) { } it->planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top)); it->planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left)); - it->planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1; - it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1; + it->planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)); + it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)); Common::Rect screenRect(_screen->getWidth(), _screen->getHeight()); - it->planeRect.top = (it->planeRect.top * screenRect.height()) / scriptsRunningHeight; - it->planeRect.left = (it->planeRect.left * screenRect.width()) / scriptsRunningWidth; - it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / scriptsRunningHeight; - it->planeRect.right = (it->planeRect.right * screenRect.width()) / scriptsRunningWidth; + it->planeRect.top = (it->planeRect.top * screenRect.height()) / _scriptsRunningHeight; + it->planeRect.left = (it->planeRect.left * screenRect.width()) / _scriptsRunningWidth; + it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / _scriptsRunningHeight; + it->planeRect.right = (it->planeRect.right * screenRect.width()) / _scriptsRunningWidth; // We get negative left in kq7 in scrolling rooms if (it->planeRect.left < 0) { @@ -185,15 +185,18 @@ void GfxFrameout::kernelDeletePlane(reg_t object) { Common::Rect planeRect; planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top)); planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left)); - planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1; - planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1; + planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)); + planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)); Common::Rect screenRect(_screen->getWidth(), _screen->getHeight()); - planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight; - planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth; - planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight; - planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth; + planeRect.top = (planeRect.top * screenRect.height()) / _scriptsRunningHeight; + planeRect.left = (planeRect.left * screenRect.width()) / _scriptsRunningWidth; + planeRect.bottom = (planeRect.bottom * screenRect.height()) / _scriptsRunningHeight; + planeRect.right = (planeRect.right * screenRect.width()) / _scriptsRunningWidth; planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321 + // FIXME: The code above incorrectly added 1 pixel to the plane's + // bottom and right, so probably the plane clipping code is no + // longer necessary // Blackout removed plane rect _paint32->fillRect(planeRect, 0); return; @@ -329,37 +332,149 @@ void GfxFrameout::sortPlanes() { Common::sort(_planes.begin(), _planes.end(), planeSortHelper); } -void GfxFrameout::kernelFrameout() { - if (g_sci->_robotDecoder->isVideoLoaded()) { - bool skipVideo = false; - RobotDecoder *videoDecoder = g_sci->_robotDecoder; - uint16 x = videoDecoder->getPos().x; - uint16 y = videoDecoder->getPos().y; +int16 GfxFrameout::upscaleHorizontalCoordinate(int16 coordinate) { + return ((coordinate * _screen->getWidth()) / _scriptsRunningWidth); +} - if (videoDecoder->hasDirtyPalette()) - videoDecoder->setSystemPalette(); +int16 GfxFrameout::upscaleVerticalCoordinate(int16 coordinate) { + return ((coordinate * _screen->getHeight()) / _scriptsRunningHeight); +} - while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { - if (videoDecoder->needsUpdate()) { - const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); - if (frame) { - g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h); +Common::Rect GfxFrameout::upscaleRect(Common::Rect &rect) { + rect.top = (rect.top * _scriptsRunningHeight) / _screen->getHeight(); + rect.left = (rect.left * _scriptsRunningWidth) / _screen->getWidth(); + rect.bottom = (rect.bottom * _scriptsRunningHeight) / _screen->getHeight(); + rect.right = (rect.right * _scriptsRunningWidth) / _screen->getWidth(); - if (videoDecoder->hasDirtyPalette()) - videoDecoder->setSystemPalette(); + return rect; +} - g_system->updateScreen(); - } +void GfxFrameout::showVideo() { + bool skipVideo = false; + RobotDecoder *videoDecoder = g_sci->_robotDecoder; + uint16 x = videoDecoder->getPos().x; + uint16 y = videoDecoder->getPos().y; + + if (videoDecoder->hasDirtyPalette()) + videoDecoder->setSystemPalette(); + + while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { + if (videoDecoder->needsUpdate()) { + const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); + if (frame) { + g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h); + + if (videoDecoder->hasDirtyPalette()) + videoDecoder->setSystemPalette(); + + g_system->updateScreen(); } + } - Common::Event event; - while (g_system->getEventManager()->pollEvent(event)) { - if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) - skipVideo = true; + Common::Event event; + while (g_system->getEventManager()->pollEvent(event)) { + if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) + skipVideo = true; + } + + g_system->delayMillis(10); + } +} + +void GfxFrameout::createPlaneItemList(reg_t planeObject, FrameoutList &itemList) { + // Copy screen items of the current frame to the list of items to be drawn + for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) { + reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane)); + if (planeObject == itemPlane) { + kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary? + itemList.push_back(*listIterator); + } + } + + for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) { + if (pictureIt->object == planeObject) { + GfxPicture *planePicture = pictureIt->picture; + // Allocate memory for picture cels + pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()]; + + // Add following cels to the itemlist + FrameoutEntry *picEntry = pictureIt->pictureCels; + int planePictureCels = planePicture->getSci32celCount(); + for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) { + picEntry->celNo = pictureCelNr; + picEntry->object = NULL_REG; + picEntry->picture = planePicture; + picEntry->y = planePicture->getSci32celY(pictureCelNr); + picEntry->x = planePicture->getSci32celX(pictureCelNr); + picEntry->picStartX = pictureIt->startX; + picEntry->picStartY = pictureIt->startY; + + picEntry->priority = planePicture->getSci32celPriority(pictureCelNr); + + itemList.push_back(picEntry); + picEntry++; } + } + } + + // Now sort our itemlist + Common::sort(itemList.begin(), itemList.end(), sortHelper); +} + +bool GfxFrameout::isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY) { + // Out of view horizontally (sanity checks) + int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x; + int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo); + int16 planeStartX = planeOffsetX; + int16 planeEndX = planeStartX + planeRect.width(); + if (pictureCelEndX < planeStartX) + return true; + if (pictureCelStartX > planeEndX) + return true; + + // Out of view vertically (sanity checks) + int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y; + int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo); + int16 planeStartY = planeOffsetY; + int16 planeEndY = planeStartY + planeRect.height(); + if (pictureCelEndY < planeStartY) + return true; + if (pictureCelStartY > planeEndY) + return true; + + return false; +} + +void GfxFrameout::drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored) { + int16 pictureOffsetX = planeOffsetX; + int16 pictureX = itemEntry->x; + if ((planeOffsetX) || (itemEntry->picStartX)) { + if (planeOffsetX <= itemEntry->picStartX) { + pictureX += itemEntry->picStartX - planeOffsetX; + pictureOffsetX = 0; + } else { + pictureOffsetX = planeOffsetX - itemEntry->picStartX; + } + } - g_system->delayMillis(10); + int16 pictureOffsetY = planeOffsetY; + int16 pictureY = itemEntry->y; + if ((planeOffsetY) || (itemEntry->picStartY)) { + if (planeOffsetY <= itemEntry->picStartY) { + pictureY += itemEntry->picStartY - planeOffsetY; + pictureOffsetY = 0; + } else { + pictureOffsetY = planeOffsetY - itemEntry->picStartY; } + } + + itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, planePictureMirrored); + // warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority); +} + +void GfxFrameout::kernelFrameout() { + if (g_sci->_robotDecoder->isVideoLoaded()) { + showVideo(); return; } @@ -393,43 +508,7 @@ void GfxFrameout::kernelFrameout() { FrameoutList itemList; - // Copy screen items of the current frame to the list of items to be drawn - for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) { - reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane)); - if (planeObject == itemPlane) { - kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary? - itemList.push_back(*listIterator); - } - } - - for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) { - if (pictureIt->object == planeObject) { - GfxPicture *planePicture = pictureIt->picture; - // Allocate memory for picture cels - pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()]; - - // Add following cels to the itemlist - FrameoutEntry *picEntry = pictureIt->pictureCels; - int planePictureCels = planePicture->getSci32celCount(); - for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) { - picEntry->celNo = pictureCelNr; - picEntry->object = NULL_REG; - picEntry->picture = planePicture; - picEntry->y = planePicture->getSci32celY(pictureCelNr); - picEntry->x = planePicture->getSci32celX(pictureCelNr); - picEntry->picStartX = pictureIt->startX; - picEntry->picStartY = pictureIt->startY; - - picEntry->priority = planePicture->getSci32celPriority(pictureCelNr); - - itemList.push_back(picEntry); - picEntry++; - } - } - } - - // Now sort our itemlist - Common::sort(itemList.begin(), itemList.end(), sortHelper); + createPlaneItemList(planeObject, itemList); // warning("Plane %s", _segMan->getObjectName(planeObject)); @@ -438,69 +517,24 @@ void GfxFrameout::kernelFrameout() { if (itemEntry->object.isNull()) { // Picture cel data - itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight); - itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth); - itemEntry->picStartX = ((itemEntry->picStartX * _screen->getWidth()) / scriptsRunningWidth); - itemEntry->picStartY = ((itemEntry->picStartY * _screen->getHeight()) / scriptsRunningHeight); - - // Out of view horizontally (sanity checks) - int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x; - int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo); - int16 planeStartX = it->planeOffsetX; - int16 planeEndX = planeStartX + it->planeRect.width(); - if (pictureCelEndX < planeStartX) - continue; - if (pictureCelStartX > planeEndX) - continue; + itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x); + itemEntry->y = upscaleVerticalCoordinate(itemEntry->y); + itemEntry->picStartX = upscaleHorizontalCoordinate(itemEntry->picStartX); + itemEntry->picStartY = upscaleVerticalCoordinate(itemEntry->picStartY); - // Out of view vertically (sanity checks) - int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y; - int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo); - int16 planeStartY = it->planeOffsetY; - int16 planeEndY = planeStartY + it->planeRect.height(); - if (pictureCelEndY < planeStartY) - continue; - if (pictureCelStartY > planeEndY) - continue; - - int16 pictureOffsetX = it->planeOffsetX; - int16 pictureX = itemEntry->x; - if ((it->planeOffsetX) || (itemEntry->picStartX)) { - if (it->planeOffsetX <= itemEntry->picStartX) { - pictureX += itemEntry->picStartX - it->planeOffsetX; - pictureOffsetX = 0; - } else { - pictureOffsetX = it->planeOffsetX - itemEntry->picStartX; - } - } - - int16 pictureOffsetY = it->planeOffsetY; - int16 pictureY = itemEntry->y; - if ((it->planeOffsetY) || (itemEntry->picStartY)) { - if (it->planeOffsetY <= itemEntry->picStartY) { - pictureY += itemEntry->picStartY - it->planeOffsetY; - pictureOffsetY = 0; - } else { - pictureOffsetY = it->planeOffsetY - itemEntry->picStartY; - } - } - - itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, it->planePictureMirrored); -// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority); - - } else if (itemEntry->viewId != 0xFFFF) { - GfxView *view = _cache->getView(itemEntry->viewId); - -// warning("view %s %04x:%04x", _segMan->getObjectName(itemEntry->object), PRINT_REG(itemEntry->object)); - - if (view->isSci2Hires()) { + if (!isPictureOutOfView(itemEntry, it->planeRect, it->planeOffsetX, it->planeOffsetY)) + drawPicture(itemEntry, it->planeOffsetX, it->planeOffsetY, it->planePictureMirrored); + } else { + GfxView *view = (itemEntry->viewId != 0xFFFF) ? _cache->getView(itemEntry->viewId) : NULL; + + if (view && view->isSci2Hires()) { int16 dummyX = 0; view->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x); view->adjustToUpscaledCoordinates(itemEntry->z, dummyX); } else if (getSciVersion() == SCI_VERSION_2_1) { - itemEntry->y = (itemEntry->y * _screen->getHeight()) / scriptsRunningHeight; - itemEntry->x = (itemEntry->x * _screen->getWidth()) / scriptsRunningWidth; - itemEntry->z = (itemEntry->z * _screen->getHeight()) / scriptsRunningHeight; + itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x); + itemEntry->y = upscaleVerticalCoordinate(itemEntry->y); + itemEntry->z = upscaleVerticalCoordinate(itemEntry->z); } // Adjust according to current scroll position @@ -511,33 +545,33 @@ void GfxFrameout::kernelFrameout() { if (useInsetRect) { itemEntry->celRect.top = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inTop)); itemEntry->celRect.left = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inLeft)); - itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)) + 1; - itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)) + 1; - if (view->isSci2Hires()) { + itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)); + itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)); + if (view && view->isSci2Hires()) { view->adjustToUpscaledCoordinates(itemEntry->celRect.top, itemEntry->celRect.left); view->adjustToUpscaledCoordinates(itemEntry->celRect.bottom, itemEntry->celRect.right); } itemEntry->celRect.translate(itemEntry->x, itemEntry->y); // TODO: maybe we should clip the cels rect with this, i'm not sure // the only currently known usage is game menu of gk1 - } else { - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) - view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect); - else - view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, itemEntry->celRect); + } else if (view) { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) + view->getCelRect(itemEntry->loopNo, itemEntry->celNo, + itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect); + else + view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, + itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, + itemEntry->scaleY, itemEntry->celRect); Common::Rect nsRect = itemEntry->celRect; // Translate back to actual coordinate within scrollable plane nsRect.translate(it->planeOffsetX, it->planeOffsetY); - if (view->isSci2Hires()) { + if (view && view->isSci2Hires()) { view->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left); view->adjustBackUpscaledCoordinates(nsRect.bottom, nsRect.right); } else if (getSciVersion() == SCI_VERSION_2_1) { - nsRect.top = (nsRect.top * scriptsRunningHeight) / _screen->getHeight(); - nsRect.left = (nsRect.left * scriptsRunningWidth) / _screen->getWidth(); - nsRect.bottom = (nsRect.bottom * scriptsRunningHeight) / _screen->getHeight(); - nsRect.right = (nsRect.right * scriptsRunningWidth) / _screen->getWidth(); + nsRect = upscaleRect(nsRect); } if (g_sci->getGameId() == GID_PHANTASMAGORIA2) { @@ -552,7 +586,7 @@ void GfxFrameout::kernelFrameout() { int16 screenHeight = _screen->getHeight(); int16 screenWidth = _screen->getWidth(); - if (view->isSci2Hires()) { + if (view && view->isSci2Hires()) { screenHeight = _screen->getDisplayHeight(); screenWidth = _screen->getDisplayWidth(); } @@ -565,7 +599,8 @@ void GfxFrameout::kernelFrameout() { Common::Rect clipRect, translatedClipRect; clipRect = itemEntry->celRect; - if (view->isSci2Hires()) { + + if (view && view->isSci2Hires()) { clipRect.clip(it->upscaledPlaneClipRect); translatedClipRect = clipRect; translatedClipRect.translate(it->upscaledPlaneRect.left, it->upscaledPlaneRect.top); @@ -575,16 +610,20 @@ void GfxFrameout::kernelFrameout() { translatedClipRect.translate(it->planeRect.left, it->planeRect.top); } - if (!clipRect.isEmpty()) { - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) - view->draw(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires()); - else - view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY); + if (view) { + if (!clipRect.isEmpty()) { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) + view->draw(itemEntry->celRect, clipRect, translatedClipRect, + itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires()); + else + view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, + itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY); + } } - } else { - // Most likely a text entry + + // Draw text, if it exists if (lookupSelector(_segMan, itemEntry->object, SELECTOR(text), NULL, NULL) == kSelectorVariable) { - g_sci->_gfxText32->drawTextBitmap(itemEntry->object); + g_sci->_gfxText32->drawTextBitmap(itemEntry->x, itemEntry->y, it->planeRect, itemEntry->object); } } } diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 160c343b05..a4a0a853e4 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -104,6 +104,14 @@ public: void clear(); private: + void showVideo(); + void createPlaneItemList(reg_t planeObject, FrameoutList &itemList); + bool isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY); + void drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored); + int16 upscaleHorizontalCoordinate(int16 coordinate); + int16 upscaleVerticalCoordinate(int16 coordinate); + Common::Rect upscaleRect(Common::Rect &rect); + SegManager *_segMan; ResourceManager *_resMan; GfxCoordAdjuster32 *_coordAdjuster; @@ -118,8 +126,8 @@ private: void sortPlanes(); - uint16 scriptsRunningWidth; - uint16 scriptsRunningHeight; + uint16 _scriptsRunningWidth; + uint16 _scriptsRunningHeight; }; } // End of namespace Sci diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index b52af38675..47d1647c6c 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -709,6 +709,13 @@ bool GfxPalette::palVaryLoadTargetPalette(GuiResourceId resourceId) { } void GfxPalette::palVaryInstallTimer() { + // Remove any possible leftover palVary timer callbacks. + // This happens for example in QFG1VGA, when sleeping at Erana's place + // (bug #3439240) - the nighttime to daytime effect clashes with the + // scene transition effect, as we load scene images too quickly for + // the SCI scripts in that case (also refer to kernelPalVaryInit). + palVaryRemoveTimer(); + int16 ticks = _palVaryTicks > 0 ? _palVaryTicks : 1; // Call signal increase every [ticks] g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this, "sciPalette"); @@ -966,7 +973,7 @@ void GfxPalette::loadMacIconBarPalette() { } bool GfxPalette::colorIsFromMacClut(byte index) { - return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 1] != 0); + return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 2] != 0); } #ifdef ENABLE_SCI32 diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index 029030165d..fd6637f313 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -41,6 +41,10 @@ namespace Sci { #define BITMAP_HEADER_SIZE 46 +#define SCI_TEXT32_ALIGNMENT_RIGHT -1 +#define SCI_TEXT32_ALIGNMENT_CENTER 1 +#define SCI_TEXT32_ALIGNMENT_LEFT 0 + GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen) : _segMan(segMan), _cache(fonts), _screen(screen) { } @@ -48,7 +52,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen) GfxText32::~GfxText32() { } -reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight) { +reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) { reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text)); // The object in the text selector of the item can be either a raw string @@ -58,13 +62,21 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); Common::String text = _segMan->getString(stringObject); - GfxFont *font = _cache->getFont(readSelectorValue(_segMan, textObject, SELECTOR(font))); + // HACK: The character offsets of the up and down arrow buttons are off by one + // in GK1, for some unknown reason. Fix them here. + if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) { + text.setChar(text[0] + 1, 0); + } + GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font)); + GfxFont *font = _cache->getFont(fontId); bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed)); + int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode)); uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore)); + uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back)); - Common::Rect planeRect = getPlaneRect(textObject); - uint16 width = planeRect.width() + 1; - uint16 height = planeRect.height() + 1; + Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject); + uint16 width = nsRect.width() + 1; + uint16 height = nsRect.height() + 1; // Limit rectangle dimensions, if requested if (maxWidth > 0) @@ -79,24 +91,74 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH } int entrySize = width * height + BITMAP_HEADER_SIZE; - reg_t memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize); - writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); + reg_t memoryId = NULL_REG; + if (prevHunk.isNull()) { + memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize); + writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); + } else { + memoryId = prevHunk; + } byte *memoryPtr = _segMan->getHunkPointer(memoryId); - memset(memoryPtr, 0, entrySize); + + if (prevHunk.isNull()) + memset(memoryPtr, 0, BITMAP_HEADER_SIZE); + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + memset(bitmap, backColor, width * height); + + // Save totalWidth, totalHeight + WRITE_LE_UINT16(memoryPtr, width); + WRITE_LE_UINT16(memoryPtr + 2, height); int16 charCount = 0; uint16 curX = 0, curY = 0; const char *txt = text.c_str(); + int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0; + uint16 start = 0; + // Calculate total text height while (*txt) { charCount = GetLongest(txt, width, font); if (charCount == 0) break; + Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true); + + totalHeight += textHeight; + txt += charCount; + while (*txt == ' ') + txt++; // skip over breaking spaces + } + + txt = text.c_str(); + + // Draw text in buffer + while (*txt) { + charCount = GetLongest(txt, width, font); + if (charCount == 0) + break; + Width(txt, start, charCount, fontId, textWidth, textHeight, true); + + switch (alignment) { + case SCI_TEXT32_ALIGNMENT_RIGHT: + offsetX = width - textWidth; + break; + case SCI_TEXT32_ALIGNMENT_CENTER: + // Center text both horizontally and vertically + offsetX = (width - textWidth) / 2; + offsetY = (height - totalHeight) / 2; + break; + case SCI_TEXT32_ALIGNMENT_LEFT: + offsetX = 0; + break; + + default: + warning("Invalid alignment %d used in TextBox()", alignment); + } + for (int i = 0; i < charCount; i++) { unsigned char curChar = txt[i]; - font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, width, height); + font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height); curX += font->getCharWidth(curChar); } @@ -114,7 +176,7 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) { _segMan->freeHunkEntry(hunkId); } -void GfxText32::drawTextBitmap(reg_t textObject) { +void GfxText32::drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject) { reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap)); // Sanity check: Check if the hunk is set. If not, either the game scripts // didn't set it, or an old saved game has been loaded, where it wasn't set. @@ -129,46 +191,28 @@ void GfxText32::drawTextBitmap(reg_t textObject) { byte *surface = memoryPtr + BITMAP_HEADER_SIZE; int curByte = 0; - Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject); - Common::Rect planeRect = getPlaneRect(textObject); - uint16 x = readSelectorValue(_segMan, textObject, SELECTOR(x)); - uint16 y = readSelectorValue(_segMan, textObject, SELECTOR(y)); + uint16 skipColor = readSelectorValue(_segMan, textObject, SELECTOR(skip)); uint16 textX = planeRect.left + x; uint16 textY = planeRect.top + y; - uint16 width = nsRect.width() + 1; - uint16 height = nsRect.height() + 1; + // Get totalWidth, totalHeight + uint16 width = READ_LE_UINT16(memoryPtr); + uint16 height = READ_LE_UINT16(memoryPtr + 2); // Upscale the coordinates/width if the fonts are already upscaled if (_screen->fontIsUpscaled()) { textX = textX * _screen->getDisplayWidth() / _screen->getWidth(); textY = textY * _screen->getDisplayHeight() / _screen->getHeight(); - width = width * _screen->getDisplayWidth() / _screen->getWidth(); - height = height * _screen->getDisplayHeight() / _screen->getHeight(); } for (int curY = 0; curY < height; curY++) { for (int curX = 0; curX < width; curX++) { byte pixel = surface[curByte++]; - if (pixel) + if (pixel != skipColor) _screen->putFontPixel(textY, curX + textX, curY, pixel); } } } -Common::Rect GfxText32::getPlaneRect(reg_t textObject) { - Common::Rect planeRect(0, 0, _screen->getWidth(), _screen->getHeight()); - - reg_t planeObject = readSelector(_segMan, textObject, SELECTOR(plane)); - if (!planeObject.isNull()) { - planeRect.top = readSelectorValue(_segMan, planeObject, SELECTOR(top)); - planeRect.left = readSelectorValue(_segMan, planeObject, SELECTOR(left)); - planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom)); - planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right)); - } - - return planeRect; -} - int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) { uint16 curChar = 0; int16 maxChars = 0, curCharCount = 0; diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h index dfcbf63ccf..3a411ce663 100644 --- a/engines/sci/graphics/text32.h +++ b/engines/sci/graphics/text32.h @@ -35,9 +35,9 @@ class GfxText32 { public: GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen); ~GfxText32(); - reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0); + reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG); void disposeTextBitmap(reg_t hunkId); - void drawTextBitmap(reg_t textObject); + void drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject); int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font); void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); @@ -46,7 +46,6 @@ private: int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth); void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont); void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); - Common::Rect getPlaneRect(reg_t textObject); SegManager *_segMan; GfxCache *_cache; diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index e095cde697..a77bcccc52 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -432,10 +432,11 @@ void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCo // Skip the next YYYYY pixels (i.e. transparency) if (literalPos && isMacSci11ViewData) { - // KQ6/Freddy Pharkas use byte lengths, all others use uint16 + // KQ6/Freddy Pharkas/Slater use byte lengths, all others use uint16 // The SCI devs must have realized that a max of 255 pixels wide // was not very good for 320 or 640 width games. - bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS); + bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS + || g_sci->getGameId() == GID_SLATER); // compression for SCI1.1+ Mac while (pixelNr < pixelCount) { diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 828a36298d..90a0f33f06 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -71,6 +71,7 @@ MODULE_OBJS := \ sound/drivers/amigamac.o \ sound/drivers/cms.o \ sound/drivers/fb01.o \ + sound/drivers/fmtowns.o \ sound/drivers/midi.o \ sound/drivers/pcjr.o \ video/seq_decoder.o @@ -78,6 +79,7 @@ MODULE_OBJS := \ ifdef ENABLE_SCI32 MODULE_OBJS += \ + graphics/controls32.o \ graphics/frameout.o \ graphics/paint32.o \ graphics/text32.o \ diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index c50d1b8d8a..9171e5e5d9 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -169,8 +169,11 @@ ResourceType ResourceManager::convertResType(byte type) { if (type < ARRAYSIZE(s_resTypeMapSci21)) { // LSL6 hires doesn't have the chunk resource type, to match // the resource types of the lowres version, thus we use the - // older resource types here - if (g_sci && g_sci->getGameId() == GID_LSL6HIRES) + // older resource types here. + // PQ4 CD and QFG4 CD are SCI2.1, but use the resource types of the + // corresponding SCI2 floppy disk versions. + if (g_sci && (g_sci->getGameId() == GID_LSL6HIRES || + g_sci->getGameId() == GID_QFG4 || g_sci->getGameId() == GID_PQ4)) return s_resTypeMapSci0[type]; else return s_resTypeMapSci21[type]; diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index f3a3c8dd5b..a3cf1b0c84 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -915,18 +915,23 @@ bool ResourceManager::addAudioSources() { void ResourceManager::changeAudioDirectory(Common::String path) { // Remove all of the audio map resource sources, as well as the audio resource sources - for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end();) { ResourceSource *source = *it; ResSourceType sourceType = source->getSourceType(); // Remove the resource source, if it's an audio map or an audio file if (sourceType == kSourceIntMap || sourceType == kSourceAudioVolume) { // Don't remove 65535.map (the SFX map) or resource.sfx - if (source->_volumeNumber == 65535 || source->getLocationName() == "RESOURCE.SFX") + if (source->_volumeNumber == 65535 || source->getLocationName() == "RESOURCE.SFX") { + ++it; continue; + } + // erase() will move the iterator to the next element it = _sources.erase(it); delete source; + } else { + ++it; } } diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 2dc8c95fec..6eeed66e4f 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -47,6 +47,7 @@ #include "sci/graphics/cache.h" #include "sci/graphics/compare.h" #include "sci/graphics/controls16.h" +#include "sci/graphics/controls32.h" #include "sci/graphics/coordadjuster.h" #include "sci/graphics/cursor.h" #include "sci/graphics/maciconbar.h" @@ -113,6 +114,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging"); DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging"); DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game"); + DebugMan.addDebugChannel(kDebugLevelDebugMode, "DebugMode", "Enable game debug mode at start of game"); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -147,6 +149,7 @@ SciEngine::~SciEngine() { DebugMan.clearAllDebugChannels(); #ifdef ENABLE_SCI32 + delete _gfxControls32; delete _gfxText32; delete _robotDecoder; delete _gfxFrameout; @@ -600,6 +603,7 @@ void SciEngine::initGraphics() { _gfxText16 = 0; _gfxTransitions = 0; #ifdef ENABLE_SCI32 + _gfxControls32 = 0; _gfxText32 = 0; _robotDecoder = 0; _gfxFrameout = 0; @@ -622,6 +626,7 @@ void SciEngine::initGraphics() { _gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette); _gfxPaint = _gfxPaint32; _gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen); + _gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxText32); _robotDecoder = new RobotDecoder(g_system->getMixer(), getPlatform() == Common::kPlatformMacintosh); _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32); } else { diff --git a/engines/sci/sci.h b/engines/sci/sci.h index e76b71b61e..9bead768a6 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -60,6 +60,7 @@ class GfxAnimate; class GfxCache; class GfxCompare; class GfxControls16; +class GfxControls32; class GfxCoordAdjuster; class GfxCursor; class GfxMacIconBar; @@ -101,7 +102,8 @@ enum kDebugLevels { kDebugLevelScripts = 1 << 17, kDebugLevelGC = 1 << 18, kDebugLevelResMan = 1 << 19, - kDebugLevelOnStartup = 1 << 20 + kDebugLevelOnStartup = 1 << 20, + kDebugLevelDebugMode = 1 << 21 }; enum SciGameId { @@ -304,6 +306,7 @@ public: GfxCache *_gfxCache; GfxCompare *_gfxCompare; GfxControls16 *_gfxControls16; // Controls for 16-bit gfx + GfxControls32 *_gfxControls32; // Controls for 32-bit gfx GfxCoordAdjuster *_gfxCoordAdjuster; GfxCursor *_gfxCursor; GfxMenu *_gfxMenu; // Menu for 16-bit gfx diff --git a/engines/sci/sound/drivers/adlib.cpp b/engines/sci/sound/drivers/adlib.cpp index add3d8851f..db9317e071 100644 --- a/engines/sci/sound/drivers/adlib.cpp +++ b/engines/sci/sound/drivers/adlib.cpp @@ -613,8 +613,6 @@ void MidiDriver_AdLib::setNote(int voice, int note, bool key) { _voices[voice].note = note; - delta = 0; - n = note % 12; if (bend < 8192) diff --git a/engines/sci/sound/drivers/fmtowns.cpp b/engines/sci/sound/drivers/fmtowns.cpp new file mode 100644 index 0000000000..6d8bb2e525 --- /dev/null +++ b/engines/sci/sound/drivers/fmtowns.cpp @@ -0,0 +1,652 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "sci/sci.h" + +#include "common/file.h" +#include "common/system.h" +#include "common/textconsole.h" + +#include "audio/softsynth/fmtowns_pc98/towns_audio.h" + +#include "sci/resource.h" +#include "sci/sound/drivers/mididriver.h" + +namespace Sci { + +class MidiDriver_FMTowns; + +class TownsChannel { +public: + TownsChannel(MidiDriver_FMTowns *driver, uint8 id); + ~TownsChannel() {} + + void noteOff(); + void noteOn(uint8 note, uint8 velo); + void pitchBend(int16 val); + void updateVolume(); + void updateDuration(); + + uint8 _assign; + uint8 _note; + uint8 _sustain; + uint16 _duration; + +private: + uint8 _id; + uint8 _velo; + uint8 _program; + + MidiDriver_FMTowns *_drv; +}; + +class TownsMidiPart { +friend class MidiDriver_FMTowns; +public: + TownsMidiPart(MidiDriver_FMTowns *driver, uint8 id); + ~TownsMidiPart() {} + + void noteOff(uint8 note); + void noteOn(uint8 note, uint8 velo); + void controlChangeVolume(uint8 vol); + void controlChangeSustain(uint8 sus); + void controlChangePolyphony(uint8 numChan); + void controlChangeAllNotesOff(); + void programChange(uint8 prg); + void pitchBend(int16 val); + + void addChannels(int num); + void dropChannels(int num); + + uint8 currentProgram() const; + +private: + int allocateChannel(); + + uint8 _id; + uint8 _program; + uint8 _volume; + uint8 _sustain; + uint8 _chanMissing; + int16 _pitchBend; + uint8 _outChan; + + MidiDriver_FMTowns *_drv; +}; + +class MidiDriver_FMTowns : public MidiDriver, public TownsAudioInterfacePluginDriver { +friend class TownsChannel; +friend class TownsMidiPart; +public: + MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version); + ~MidiDriver_FMTowns(); + + int open(); + void loadInstruments(const uint8 *data); + bool isOpen() const { return _isOpen; } + void close(); + + void send(uint32 b); + + uint32 property(int prop, uint32 param); + void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc); + + void setSoundOn(bool toggle); + + uint32 getBaseTempo(); + MidiChannel *allocateChannel() { return 0; } + MidiChannel *getPercussionChannel() { return 0; } + + uint8 currentProgram(); + + void timerCallback(int timerId); + +private: + int getChannelVolume(uint8 midiPart); + void addMissingChannels(); + + void updateParser(); + void updateChannels(); + + Common::TimerManager::TimerProc _timerProc; + void *_timerProcPara; + + TownsMidiPart **_parts; + TownsChannel **_out; + + uint8 _masterVolume; + + bool _soundOn; + + bool _isOpen; + bool _ready; + + const uint16 _baseTempo; + SciVersion _version; + + TownsAudioInterface *_intf; +}; + +class MidiPlayer_FMTowns : public MidiPlayer { +public: + MidiPlayer_FMTowns(SciVersion version); + ~MidiPlayer_FMTowns(); + + int open(ResourceManager *resMan); + + bool hasRhythmChannel() const; + byte getPlayId() const; + int getPolyphony() const; + void playSwitch(bool play); + +private: + MidiDriver_FMTowns *_townsDriver; +}; + +TownsChannel::TownsChannel(MidiDriver_FMTowns *driver, uint8 id) : _drv(driver), _id(id), _assign(0xff), _note(0xff), _velo(0), _sustain(0), _duration(0), _program(0xff) { +} + +void TownsChannel::noteOn(uint8 note, uint8 velo) { + _duration = 0; + + if (_drv->_version != SCI_VERSION_1_EARLY) { + if (_program != _drv->_parts[_assign]->currentProgram() && _drv->_soundOn) { + _program = _drv->_parts[_assign]->currentProgram(); + _drv->_intf->callback(4, _id, _program); + } + } + + _note = note; + _velo = velo; + _drv->_intf->callback(1, _id, _note, _velo); +} + +void TownsChannel::noteOff() { + if (_sustain) + return; + + _drv->_intf->callback(2, _id); + _note = 0xff; + _duration = 0; +} + +void TownsChannel::pitchBend(int16 val) { + _drv->_intf->callback(7, _id, val); +} + +void TownsChannel::updateVolume() { + if (_assign > 15 && _drv->_version != SCI_VERSION_1_EARLY) + return; + _drv->_intf->callback(8, _id, _drv->getChannelVolume((_drv->_version == SCI_VERSION_1_EARLY) ? 0 : _assign)); +} + +void TownsChannel::updateDuration() { + if (_note != 0xff) + _duration++; +} + +TownsMidiPart::TownsMidiPart(MidiDriver_FMTowns *driver, uint8 id) : _drv(driver), _id(id), _program(0), _volume(0x3f), _sustain(0), _chanMissing(0), _pitchBend(0x2000), _outChan(0) { +} + +void TownsMidiPart::noteOff(uint8 note) { + for (int i = 0; i < 6; i++) { + if ((_drv->_out[i]->_assign != _id && _drv->_version != SCI_VERSION_1_EARLY) || _drv->_out[i]->_note != note) + continue; + if (_sustain) + _drv->_out[i]->_sustain = 1; + else + _drv->_out[i]->noteOff(); + return; + } +} + +void TownsMidiPart::noteOn(uint8 note, uint8 velo) { + if (note < 12 || note > 107) + return; + + if (velo == 0) { + noteOff(note); + return; + } + + if (_drv->_version != SCI_VERSION_1_EARLY) + velo >>= 1; + + for (int i = 0; i < 6; i++) { + if ((_drv->_out[i]->_assign != _id && _drv->_version != SCI_VERSION_1_EARLY) || _drv->_out[i]->_note != note) + continue; + _drv->_out[i]->_sustain = 0; + _drv->_out[i]->noteOff(); + _drv->_out[i]->noteOn(note, velo); + return; + } + + int chan = allocateChannel(); + if (chan != -1) + _drv->_out[chan]->noteOn(note, velo); +} + +void TownsMidiPart::controlChangeVolume(uint8 vol) { + if (_drv->_version == SCI_VERSION_1_EARLY) + return; + + _volume = vol >> 1; + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign == _id) + _drv->_out[i]->updateVolume(); + } +} + +void TownsMidiPart::controlChangeSustain(uint8 sus) { + if (_drv->_version == SCI_VERSION_1_EARLY) + return; + + _sustain = sus; + if (_sustain) + return; + + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign == _id && _drv->_out[i]->_sustain) { + _drv->_out[i]->_sustain = 0; + _drv->_out[i]->noteOff(); + } + } +} + +void TownsMidiPart::controlChangePolyphony(uint8 numChan) { + if (_drv->_version == SCI_VERSION_1_EARLY) + return; + + uint8 numAssigned = 0; + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign == _id) + numAssigned++; + } + + numAssigned += _chanMissing; + if (numAssigned < numChan) { + addChannels(numChan - numAssigned); + } else if (numAssigned > numChan) { + dropChannels(numAssigned - numChan); + _drv->addMissingChannels(); + } +} + +void TownsMidiPart::controlChangeAllNotesOff() { + for (int i = 0; i < 6; i++) { + if ((_drv->_out[i]->_assign == _id || _drv->_version == SCI_VERSION_1_EARLY) && _drv->_out[i]->_note != 0xff) + _drv->_out[i]->noteOff(); + } +} + +void TownsMidiPart::programChange(uint8 prg) { + _program = prg; +} + +void TownsMidiPart::pitchBend(int16 val) { + _pitchBend = val; + val -= 0x2000; + for (int i = 0; i < 6; i++) { + // Strangely, the early version driver applies the setting to channel 0 only. + if (_drv->_out[i]->_assign == _id || (_drv->_version == SCI_VERSION_1_EARLY && i == 0)) + _drv->_out[i]->pitchBend(val); + } +} + +void TownsMidiPart::addChannels(int num) { + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign != 0xff) + continue; + + _drv->_out[i]->_assign = _id; + _drv->_out[i]->updateVolume(); + + if (_drv->_out[i]->_note != 0xff) + _drv->_out[i]->noteOff(); + + if (!--num) + break; + } + + _chanMissing += num; + programChange(_program); +} + +void TownsMidiPart::dropChannels(int num) { + if (_chanMissing == num) { + _chanMissing = 0; + return; + } else if (_chanMissing > num) { + _chanMissing -= num; + return; + } + + num -= _chanMissing; + _chanMissing = 0; + + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign != _id || _drv->_out[i]->_note != 0xff) + continue; + _drv->_out[i]->_assign = 0xff; + if (!--num) + return; + } + + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign != _id) + continue; + _drv->_out[i]->_sustain = 0; + _drv->_out[i]->noteOff(); + _drv->_out[i]->_assign = 0xff; + if (!--num) + return; + } +} + +uint8 TownsMidiPart::currentProgram() const { + return _program; +} + +int TownsMidiPart::allocateChannel() { + int chan = _outChan; + int ovrChan = 0; + int ld = 0; + bool found = false; + + for (bool loop = true; loop; ) { + if (++chan == 6) + chan = 0; + + if (chan == _outChan) + loop = false; + + if (_id == _drv->_out[chan]->_assign || _drv->_version == SCI_VERSION_1_EARLY) { + if (_drv->_out[chan]->_note == 0xff) { + found = true; + break; + } + + if (_drv->_out[chan]->_duration >= ld) { + ld = _drv->_out[chan]->_duration; + ovrChan = chan; + } + } + } + + if (!found) { + if (!ld) + return -1; + chan = ovrChan; + _drv->_out[chan]->_sustain = 0; + _drv->_out[chan]->noteOff(); + } + + _outChan = chan; + return chan; +} + +MidiDriver_FMTowns::MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version) : _version(version), _timerProc(0), _timerProcPara(0), _baseTempo(10080), _ready(false), _isOpen(false), _masterVolume(0x0f), _soundOn(true) { + _intf = new TownsAudioInterface(mixer, this, true); + _out = new TownsChannel*[6]; + for (int i = 0; i < 6; i++) + _out[i] = new TownsChannel(this, i); + _parts = new TownsMidiPart*[16]; + for (int i = 0; i < 16; i++) + _parts[i] = new TownsMidiPart(this, i); +} + +MidiDriver_FMTowns::~MidiDriver_FMTowns() { + delete _intf; + + if (_parts) { + for (int i = 0; i < 16; i++) { + delete _parts[i]; + _parts[i] = 0; + } + delete[] _parts; + _parts = 0; + } + + if (_out) { + for (int i = 0; i < 6; i++) { + delete _out[i]; + _out[i] = 0; + } + delete[] _out; + _out = 0; + } +} + +int MidiDriver_FMTowns::open() { + if (_isOpen) + return MERR_ALREADY_OPEN; + + if (!_ready) { + if (!_intf->init()) + return MERR_CANNOT_CONNECT; + + _intf->callback(0); + + _intf->callback(21, 255, 1); + _intf->callback(21, 0, 1); + _intf->callback(22, 255, 221); + + _intf->callback(33, 8); + _intf->setSoundEffectChanMask(~0x3f); + + _ready = true; + } + + _isOpen = true; + + return 0; +} + +void MidiDriver_FMTowns::loadInstruments(const uint8 *data) { + if (data) { + data += 6; + for (int i = 0; i < 128; i++) { + _intf->callback(5, 0, i, data); + data += 48; + } + } + _intf->callback(70, 3); + property(MIDI_PROP_MASTER_VOLUME, _masterVolume); +} + +void MidiDriver_FMTowns::close() { + _isOpen = false; +} + +void MidiDriver_FMTowns::send(uint32 b) { + if (!_isOpen) + return; + + byte para2 = (b >> 16) & 0xFF; + byte para1 = (b >> 8) & 0xFF; + byte cmd = b & 0xF0; + + TownsMidiPart *chan = _parts[b & 0x0F]; + + switch (cmd) { + case 0x80: + chan->noteOff(para1); + break; + case 0x90: + chan->noteOn(para1, para2); + break; + case 0xb0: + switch (para1) { + case 7: + chan->controlChangeVolume(para2); + break; + case 64: + chan->controlChangeSustain(para2); + break; + case SCI_MIDI_SET_POLYPHONY: + chan->controlChangePolyphony(para2); + break; + case SCI_MIDI_CHANNEL_NOTES_OFF: + chan->controlChangeAllNotesOff(); + break; + default: + break; + } + break; + case 0xc0: + chan->programChange(para1); + break; + case 0xe0: + chan->pitchBend(para1 | (para2 << 7)); + break; + default: + break; + } +} + +uint32 MidiDriver_FMTowns::property(int prop, uint32 param) { + switch(prop) { + case MIDI_PROP_MASTER_VOLUME: + if (param != 0xffff) { + _masterVolume = param; + for (int i = 0; i < 6; i++) + _out[i]->updateVolume(); + } + return _masterVolume; + default: + break; + } + return 0; +} + +void MidiDriver_FMTowns::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) { + _timerProc = timer_proc; + _timerProcPara = timer_param; +} + +void MidiDriver_FMTowns::setSoundOn(bool toggle) { + _soundOn = toggle; +} + +uint32 MidiDriver_FMTowns::getBaseTempo() { + return _baseTempo; +} + +void MidiDriver_FMTowns::timerCallback(int timerId) { + if (!_isOpen) + return; + + switch (timerId) { + case 1: + updateParser(); + updateChannels(); + break; + default: + break; + } +} + +int MidiDriver_FMTowns::getChannelVolume(uint8 midiPart) { + static const uint8 volumeTable[] = { 0x00, 0x0D, 0x1B, 0x28, 0x36, 0x43, 0x51, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73, 0x77, 0x7B, 0x7F }; + int tableIndex = (_version == SCI_VERSION_1_EARLY) ? _masterVolume : (_parts[midiPart]->_volume * (_masterVolume + 1)) >> 6; + assert(tableIndex < 16); + return volumeTable[tableIndex]; +} + +void MidiDriver_FMTowns::addMissingChannels() { + uint8 avlChan = 0; + for (int i = 0; i < 6; i++) { + if (_out[i]->_assign == 0xff) + avlChan++; + } + + if (!avlChan) + return; + + for (int i = 0; i < 16; i++) { + if (!_parts[i]->_chanMissing) + continue; + + if (_parts[i]->_chanMissing < avlChan) { + avlChan -= _parts[i]->_chanMissing; + uint8 m = _parts[i]->_chanMissing; + _parts[i]->_chanMissing = 0; + _parts[i]->addChannels(m); + } else { + _parts[i]->_chanMissing -= avlChan; + _parts[i]->addChannels(avlChan); + return; + } + } +} + +void MidiDriver_FMTowns::updateParser() { + if (_timerProc) + _timerProc(_timerProcPara); +} + +void MidiDriver_FMTowns::updateChannels() { + for (int i = 0; i < 6; i++) + _out[i]->updateDuration(); +} + +MidiPlayer_FMTowns::MidiPlayer_FMTowns(SciVersion version) : MidiPlayer(version) { + _driver = _townsDriver = new MidiDriver_FMTowns(g_system->getMixer(), version); +} + +MidiPlayer_FMTowns::~MidiPlayer_FMTowns() { + delete _driver; +} + +int MidiPlayer_FMTowns::open(ResourceManager *resMan) { + int result = MidiDriver::MERR_DEVICE_NOT_AVAILABLE; + if (_townsDriver) { + result = _townsDriver->open(); + if (!result && _version == SCI_VERSION_1_LATE) + _townsDriver->loadInstruments((resMan->findResource(ResourceId(kResourceTypePatch, 8), true))->data); + } + return result; +} + +bool MidiPlayer_FMTowns::hasRhythmChannel() const { + return false; +} + +byte MidiPlayer_FMTowns::getPlayId() const { + return (_version == SCI_VERSION_1_EARLY) ? 0x00 : 0x16; +} + +int MidiPlayer_FMTowns::getPolyphony() const { + return (_version == SCI_VERSION_1_EARLY) ? 1 : 6; +} + +void MidiPlayer_FMTowns::playSwitch(bool play) { + if (_townsDriver) + _townsDriver->setSoundOn(play); +} + +MidiPlayer *MidiPlayer_FMTowns_create(SciVersion _soundVersion) { + return new MidiPlayer_FMTowns(_soundVersion); +} + +} // End of namespace Sci + diff --git a/engines/sci/sound/drivers/mididriver.h b/engines/sci/sound/drivers/mididriver.h index ec66984bd4..8938eef62f 100644 --- a/engines/sci/sound/drivers/mididriver.h +++ b/engines/sci/sound/drivers/mididriver.h @@ -130,6 +130,7 @@ extern MidiPlayer *MidiPlayer_PCSpeaker_create(SciVersion version); extern MidiPlayer *MidiPlayer_CMS_create(SciVersion version); extern MidiPlayer *MidiPlayer_Midi_create(SciVersion version); extern MidiPlayer *MidiPlayer_Fb01_create(SciVersion version); +extern MidiPlayer *MidiPlayer_FMTowns_create(SciVersion version); } // End of namespace Sci diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index 9610b6f847..4ffa8d7590 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -44,8 +44,10 @@ SciMusic::SciMusic(SciVersion soundVersion) // operations _playList.reserve(10); - for (int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { _usedChannel[i] = 0; + _channelRemap[i] = -1; + } _queuedCommands.reserve(1000); } @@ -76,6 +78,13 @@ void SciMusic::init() { if (getSciVersion() >= SCI_VERSION_1_EGA_ONLY && getSciVersion() <= SCI_VERSION_1_1) deviceFlags |= MDT_CMS; + if (g_sci->getPlatform() == Common::kPlatformFMTowns) { + if (getSciVersion() > SCI_VERSION_1_EARLY) + deviceFlags = MDT_TOWNS; + else + deviceFlags |= MDT_TOWNS; + } + uint32 dev = MidiDriver::detectDevice(deviceFlags); _musicType = MidiDriver::getMusicType(dev); @@ -96,6 +105,9 @@ void SciMusic::init() { case MT_CMS: _pMidiDrv = MidiPlayer_CMS_create(_soundVersion); break; + case MT_TOWNS: + _pMidiDrv = MidiPlayer_FMTowns_create(_soundVersion); + break; default: if (ConfMan.getBool("native_fb01")) _pMidiDrv = MidiPlayer_Fb01_create(_soundVersion); @@ -349,6 +361,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { if (!_usedChannel[bestChannel]) { // currently unused, so give it to caller directly _usedChannel[bestChannel] = caller; + _channelRemap[bestChannel] = bestChannel; return bestChannel; } // otherwise look for unused channel @@ -357,6 +370,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { continue; if (!_usedChannel[channelNr]) { _usedChannel[channelNr] = caller; + _channelRemap[bestChannel] = channelNr; return channelNr; } } @@ -369,8 +383,24 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { void SciMusic::freeChannels(MusicEntry *caller) { // Remove used channels for (int i = 0; i < 15; i++) { - if (_usedChannel[i] == caller) + if (_usedChannel[i] == caller) { + if (_channelRemap[i] != -1) { + // athrxx: The original handles this differently. It seems to be checking for (and effecting) necessary + // remaps / resets etc. more or less all the time. There are several more tables to keep track of everything. + // I don't know whether all of that is needed and to which SCI versions it applies, though. + // At least it is necessary to release the allocated channels inside the driver. Otherwise these channels + // won't be available any more (e.g. after half of the KQ5 FM-Towns intro there will be no more music + // since the driver can't pick up any more channels). The channels also have to be reset to + // default values, since the original does the same (although in a different manny) and the music will be wrong + // otherwise (at least KQ5 FM-Towns). + + sendMidiCommand(0x4000e0 | _channelRemap[i]); // Reset pitch wheel + sendMidiCommand(0x0040b0 | _channelRemap[i]); // Release pedal + sendMidiCommand(0x004bb0 | _channelRemap[i]); // Release assigned driver channels + } _usedChannel[i] = 0; + _channelRemap[i] = -1; + } } // Also tell midiparser, that he lost ownership caller->pMidiParser->lostChannels(); @@ -446,9 +476,9 @@ void SciMusic::soundPlay(MusicEntry *pSnd) { // volume of the sound channels that the faded song occupies.. // Fixes bug #3266480 and partially fixes bug #3041738. for (uint i = 0; i < playListCount; i++) { - // Is another MIDI song being faded? If yes, stop it + // Is another MIDI song being faded down? If yes, stop it // immediately instead - if (_playList[i]->fadeStep && _playList[i]->pMidiParser) { + if (_playList[i]->fadeStep < 0 && _playList[i]->pMidiParser) { _playList[i]->status = kSoundStopped; if (_soundVersion <= SCI_VERSION_0_LATE) _playList[i]->isQueued = false; diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h index 8577ed7313..fa6f538a7e 100644 --- a/engines/sci/sound/music.h +++ b/engines/sci/sound/music.h @@ -219,6 +219,7 @@ private: bool _soundOn; byte _masterVolume; MusicEntry *_usedChannel[16]; + int8 _channelRemap[16]; int8 _globalReverb; MidiCommandQueue _queuedCommands; diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index 9cfdfbccc9..54f7fea97b 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -292,7 +292,7 @@ bool ScummDebugger::Cmd_ImportRes(int argc, const char** argv) { if (_vm->_game.features & GF_SMALL_HEADER) { size = file.readUint16LE(); file.seek(-2, SEEK_CUR); - } else if (_vm->_game.features & GF_SMALL_HEADER) { + } else if (_vm->_game.features & GF_SMALL_HEADER) { // FIXME: This never was executed if (_vm->_game.version == 4) file.seek(8, SEEK_CUR); size = file.readUint32LE(); diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index a1ad630815..2ae994040b 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -653,7 +653,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul if (strchr(dr.game.guioptions, GUIO_NOSPEECH[0]) != NULL) { if (g->id == GID_MONKEY || g->id == GID_MONKEY2) // TODO: This may need to be updated if something important gets added in the top detection table for these game ids - dr.game.guioptions = GUIO1(GUIO_NONE); + dr.game.guioptions = GUIO0(); else warning("FIXME: fix NOSPEECH fallback"); } diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 36a703f3bd..48a1a9d379 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -237,14 +237,14 @@ static const GameSettings gameVariantsTable[] = { {"monkey2", "", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)}, {"monkey2", "FM-TOWNS", 0, GID_MONKEY2, 5, 0, MDT_PCSPK | MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO5(GUIO_NOSPEECH, GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)}, - {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NONE)}, + {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO0()}, {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)}, {"atlantis", "FM-TOWNS", 0, GID_INDY4, 5, 0, MDT_TOWNS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, Common::kPlatformFMTowns, GUIO4(GUIO_MIDITOWNS, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_NOASPECT)}, - {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NONE)}, + {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO0()}, {"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NOSPEECH)}, - {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NONE)}, + {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO0()}, {"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NOSPEECH)}, #ifdef ENABLE_SCUMM_7_8 diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index 5c15a85929..85e2a2f1dd 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -770,24 +770,30 @@ void SoundHE::startHETalkSound(uint32 offset) { if (ConfMan.getBool("speech_mute")) return; - assert(_sfxFile); - if (!_sfxFile->isOpen()) { + if (_sfxFilename.empty()) { // This happens in the Pajama Sam's Lost & Found demo, on the // main menu screen, so don't make it a fatal error. - warning("startHETalkSound: Speech file is not open"); + warning("startHETalkSound: Speech file is not found"); return; } + ScummFile file; + if (!_vm->openFile(file, _sfxFilename)) { + warning("startHETalkSound: Could not open speech file %s", _sfxFilename.c_str()); + return; + } + file.setEnc(_sfxFileEncByte); + _sfxMode |= 2; _vm->_res->nukeResource(rtSound, 1); - _sfxFile->seek(offset + 4, SEEK_SET); - size = _sfxFile->readUint32BE(); - _sfxFile->seek(offset, SEEK_SET); + file.seek(offset + 4, SEEK_SET); + size = file.readUint32BE(); + file.seek(offset, SEEK_SET); _vm->_res->createResource(rtSound, 1, size); ptr = _vm->getResourceAddress(rtSound, 1); - _sfxFile->read(ptr, size); + file.read(ptr, size); int channel = (_vm->VAR_TALK_CHANNEL != 0xFF) ? _vm->VAR(_vm->VAR_TALK_CHANNEL) : 0; addSoundToQueue2(1, 0, channel, 0); diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp index 73be2174cd..53ccfb3734 100644 --- a/engines/scumm/imuse/imuse_player.cpp +++ b/engines/scumm/imuse/imuse_player.cpp @@ -592,6 +592,7 @@ bool Player::setLoop(uint count, uint tobeat, uint totick, uint frombeat, uint f if (tobeat == 0) tobeat = 1; + // FIXME: Thread safety? _loop_counter = 0; // Because of possible interrupts _loop_to_beat = tobeat; _loop_to_tick = totick; diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 6d9e1f3f72..ee2de49475 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -446,6 +446,23 @@ void ScummEngine_v6::processKeyboard(Common::KeyState lastKeyHit) { } void ScummEngine_v2::processKeyboard(Common::KeyState lastKeyHit) { + // RETURN is used to skip cutscenes in the Commodote 64 version of Zak McKracken + if (_game.id == GID_ZAK &&_game.platform == Common::kPlatformC64 && lastKeyHit.keycode == Common::KEYCODE_RETURN && lastKeyHit.hasFlags(0)) { + lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); + // F7 is used to skip cutscenes in the Commodote 64 version of Maniac Mansion + } else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformC64) { + if (lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0)) + lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); + // 'B' is used to skip cutscenes in the NES version of Maniac Mansion + } else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformNES) { + if (lastKeyHit.keycode == Common::KEYCODE_b && lastKeyHit.hasFlags(Common::KBD_SHIFT)) + lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); + // 'F4' is used to skip cutscenes in the other versions of Maniac Mansion + } else if (_game.id == GID_MANIAC) { + if (lastKeyHit.keycode == Common::KEYCODE_F4 && lastKeyHit.hasFlags(0)) + lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); + } + // Fall back to default behavior ScummEngine::processKeyboard(lastKeyHit); diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index ae4bbc45a6..da238dc517 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -1842,7 +1842,7 @@ void ScummEngine::loadFlObject(uint object, uint room) { if (_dumpScripts) { char buf[32]; const byte *ptr = foir.obcd; - sprintf(buf, "roomobj-%d-", room); + sprintf(buf, "roomobj-%u-", room); ptr = findResource(MKTAG('V','E','R','B'), ptr); dumpResource(buf, object, ptr); } diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp index 2c10758730..bd085dd4d5 100644 --- a/engines/scumm/palette.cpp +++ b/engines/scumm/palette.cpp @@ -823,7 +823,7 @@ void ScummEngine::setShadowPalette(int slot, int redScale, int greenScale, int b if (slot < 0 || slot >= NUM_SHADOW_PALETTE) error("setShadowPalette: invalid slot %d", slot); - if (startColor < 0 || startColor > 255 || endColor < 0 || startColor > 255 || endColor < startColor) + if (startColor < 0 || startColor > 255 || endColor < 0 || endColor > 255 || endColor < startColor) error("setShadowPalette: invalid range from %d to %d", startColor, endColor); table = _shadowPalette + slot * 256; diff --git a/engines/scumm/player_v2a.cpp b/engines/scumm/player_v2a.cpp index ed97c4098f..07fc77b301 100644 --- a/engines/scumm/player_v2a.cpp +++ b/engines/scumm/player_v2a.cpp @@ -31,7 +31,7 @@ namespace Scumm { static uint32 CRCtable[256]; -static void InitCRC () { +static void InitCRC() { const uint32 poly = 0xEDB88320; int i, j; uint32 n; @@ -44,7 +44,7 @@ static void InitCRC () { } } -static uint32 GetCRC (byte *data, int len) { +static uint32 GetCRC(byte *data, int len) { uint32 CRC = 0xFFFFFFFF; int i; for (i = 0; i < len; i++) @@ -131,7 +131,7 @@ public: _mod->stopChannel(_id | (_chan[i].chan << 8)); } else { _mod->setChannelVol(_id | (_chan[i].chan << 8), - READ_BE_UINT16(_data + _chan[i].volbase + (_chan[i].volptr++ << 1))); + READ_BE_UINT16(_data + _chan[i].volbase + (_chan[i].volptr++ << 1))); if (_chan[i].volptr == 0) { _mod->stopChannel(_id | (_chan[i].chan << 8)); _chan[i].dur = 0; @@ -163,7 +163,7 @@ public: _chan[i].volptr = 0; _chan[i].chan = READ_BE_UINT16(_data + _chan[i].dataptr + 6) & 0x3; - if (_chan[i].dur) // if there's something playing, stop it + if (_chan[i].dur) // if there's something playing, stop it _mod->stopChannel(_id | (_chan[i].chan << 8)); _chan[i].dur = READ_BE_UINT16(_data + _chan[i].dataptr + 4); @@ -173,7 +173,8 @@ public: int pan; if ((_chan[i].chan == 0) || (_chan[i].chan == 3)) pan = -127; - else pan = 127; + else + pan = 127; int offset = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x14); int len = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x18); int loopoffset = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x16); @@ -873,7 +874,7 @@ private: uint16 _freq4; int16 _step4; - void updatefreq (uint16 &freq, int16 &step, uint16 min, uint16 max) { + void updatefreq(uint16 &freq, int16 &step, uint16 min, uint16 max) { freq += step; if (freq <= min) { freq = min; @@ -1004,8 +1005,7 @@ public: if (_curvol == 0) return false; _mod->setChannelVol(_id, (_curvol << 2) | (_curvol >> 4)); - } - else { + } else { if (_freq1 < _freq2) _curfreq++; else @@ -1691,7 +1691,7 @@ public: assert(_id); const uint16 _minvol[2] = {0x2E, 0x32}; int i; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { _mod->setChannelFreq(_id | (i << 8), BASE_FREQUENCY / _freq[i]); _mod->setChannelVol(_id | (i << 8), _vol[i]); } @@ -1704,7 +1704,7 @@ public: _vol[i] = _minvol[i]; _volmod[i] = -_volmod[i]; } - _vol[i+2] = _vol[i]; + _vol[i + 2] = _vol[i]; } _freq[0] += _freqmod; if (_freq[0] > 0x2BC) { @@ -1731,113 +1731,113 @@ private: if (crc == CRC) \ return new SOUND -static V2A_Sound *findSound (unsigned long crc) { - CRCToSound(0x8FAB08C4, V2A_Sound_SingleLooped(0x006C,0x2B58,0x016E,0x3F)); // Maniac 17 - CRCToSound(0xB673160A, V2A_Sound_SingleLooped(0x006C,0x1E78,0x01C2,0x1E)); // Maniac 38 - CRCToSound(0x4DB1D0B2, V2A_Sound_MultiLooped(0x0072,0x1BC8,0x023D,0x3F,0x0224,0x3F)); // Maniac 20 - CRCToSound(0x754D75EF, V2A_Sound_Single(0x0076,0x0738,0x01FC,0x3F)); // Maniac 10 - CRCToSound(0x6E3454AF, V2A_Sound_Single(0x0076,0x050A,0x017C,0x3F)); // Maniac 12 - CRCToSound(0x92F0BBB6, V2A_Sound_Single(0x0076,0x3288,0x012E,0x3F)); // Maniac 41 - CRCToSound(0xE1B13982, V2A_Sound_MultiLoopedDuration(0x0078,0x0040,0x007C,0x3F,0x007B,0x3F,0x001E)); // Maniac 21 - CRCToSound(0x288B16CF, V2A_Sound_MultiLoopedDuration(0x007A,0x0040,0x007C,0x3F,0x007B,0x3F,0x000A)); // Maniac 11 - CRCToSound(0xA7565268, V2A_Sound_MultiLoopedDuration(0x007A,0x0040,0x00F8,0x3F,0x00F7,0x3F,0x000A)); // Maniac 19 - CRCToSound(0x7D419BFC, V2A_Sound_MultiLoopedDuration(0x007E,0x0040,0x012C,0x3F,0x0149,0x3F,0x001E)); // Maniac 22 - CRCToSound(0x1B52280C, V2A_Sound_Single(0x0098,0x0A58,0x007F,0x32)); // Maniac 6 - CRCToSound(0x38D4A810, V2A_Sound_Single(0x0098,0x2F3C,0x0258,0x32)); // Maniac 7 - CRCToSound(0x09F98FC2, V2A_Sound_Single(0x0098,0x0A56,0x012C,0x32)); // Maniac 16 - CRCToSound(0x90440A65, V2A_Sound_Single(0x0098,0x0208,0x0078,0x28)); // Maniac 28 - CRCToSound(0x985C76EF, V2A_Sound_Single(0x0098,0x0D6E,0x00C8,0x32)); // Maniac 30 - CRCToSound(0x76156137, V2A_Sound_Single(0x0098,0x2610,0x017C,0x39)); // Maniac 39 - CRCToSound(0x5D95F88C, V2A_Sound_Single(0x0098,0x0A58,0x007F,0x1E)); // Maniac 65 - CRCToSound(0x92D704EA, V2A_Sound_SingleLooped(0x009C,0x29BC,0x012C,0x3F,0x1BD4,0x0DE8)); // Maniac 15 - CRCToSound(0x92F5513C, V2A_Sound_Single(0x009E,0x0DD4,0x01F4,0x3F)); // Maniac 13 - CRCToSound(0xCC2F3B5A, V2A_Sound_Single(0x009E,0x00DE,0x01AC,0x3F)); // Maniac 43 - CRCToSound(0x153207D3, V2A_Sound_Single(0x009E,0x0E06,0x02A8,0x3F)); // Maniac 67 - CRCToSound(0xC4F370CE, V2A_Sound_Single(0x00AE,0x0330,0x01AC,0x3F)); // Maniac 8 - CRCToSound(0x928C4BAC, V2A_Sound_Single(0x00AE,0x08D6,0x01AC,0x3F)); // Maniac 9 - CRCToSound(0x62D5B11F, V2A_Sound_Single(0x00AE,0x165C,0x01CB,0x3F)); // Maniac 27 - CRCToSound(0x3AB22CB5, V2A_Sound_Single(0x00AE,0x294E,0x012A,0x3F)); // Maniac 62 - CRCToSound(0x2D70BBE9, V2A_Sound_SingleLoopedPitchbend(0x00B4,0x1702,0x03E8,0x0190,0x3F,5)); // Maniac 64 - CRCToSound(0xFA4C1B1C, V2A_Sound_Special_Maniac69(0x00B2,0x1702,0x0190,0x3F)); // Maniac 69 - CRCToSound(0x19D50D67, V2A_Sound_Special_ManiacDing(0x00B6,0x0020,0x00C8,16,2)); // Maniac 14 - CRCToSound(0x3E6FBE15, V2A_Sound_Special_ManiacTentacle(0x00B2,0x0010,0x007C,0x016D,1)); // Maniac 25 - CRCToSound(0x5305753C, V2A_Sound_Special_ManiacTentacle(0x00B2,0x0010,0x007C,0x016D,7)); // Maniac 36 - CRCToSound(0x28895106, V2A_Sound_Special_Maniac59(0x00C0,0x00FE,0x00E9,0x0111,4,0x0A)); // Maniac 59 - CRCToSound(0xB641ACF6, V2A_Sound_Special_Maniac61(0x00C8,0x0100,0x00C8,0x01C2)); // Maniac 61 - CRCToSound(0xE1A91583, V2A_Sound_Special_ManiacPhone(0x00D0,0x0040,0x007C,0x3F,0x007B,0x3F,0x3C,5,6)); // Maniac 23 - CRCToSound(0x64816ED5, V2A_Sound_Special_ManiacPhone(0x00D0,0x0040,0x00BE,0x37,0x00BD,0x37,0x3C,5,6)); // Maniac 24 - CRCToSound(0x639D72C2, V2A_Sound_Special_Maniac46(0x00D0,0x10A4,0x0080,0x3F,0x28,3)); // Maniac 46 - CRCToSound(0xE8826D92, V2A_Sound_Special_ManiacTypewriter(0x00EC,0x025A,0x023C,0x3F,8,(const uint8 *)"\x20\x41\x04\x21\x08\x10\x13\x07", true)); // Maniac 45 - CRCToSound(0xEDFF3D41, V2A_Sound_Single(0x00F8,0x2ADE,0x01F8,0x3F)); // Maniac 42 (this should echo, but it's barely noticeable and I don't feel like doing it) - CRCToSound(0x15606D06, V2A_Sound_Special_Maniac32(0x0148,0x0020,0x0168,0x0020,0x3F)); // Maniac 32 - CRCToSound(0x753EAFE3, V2A_Sound_Special_Maniac44(0x017C,0x0010,0x018C,0x0020,0x00C8,0x0080,0x3F)); // Maniac 44 - CRCToSound(0xB1AB065C, V2A_Sound_Music(0x0032,0x00B2,0x08B2,0x1222,0x1A52,0x23C2,0x3074,false)); // Maniac 50 - CRCToSound(0x091F5D9C, V2A_Sound_Music(0x0032,0x0132,0x0932,0x1802,0x23D2,0x3EA2,0x4F04,false)); // Maniac 58 - - CRCToSound(0x8E2C8AB3, V2A_Sound_SingleLooped(0x005C,0x0F26,0x0168,0x3C)); // Zak 41 - CRCToSound(0x3792071F, V2A_Sound_SingleLooped(0x0060,0x1A18,0x06A4,0x3F)); // Zak 88 - CRCToSound(0xF192EDE9, V2A_Sound_SingleLooped(0x0062,0x0054,0x01FC,0x1E)); // Zak 68 - CRCToSound(0xC43B0245, V2A_Sound_Special_Zak70(0x006C,0x166E,0x00C8,0x0190,0x0320,0x0640,0x32)); // Zak 70 - CRCToSound(0xCEB51670, V2A_Sound_SingleLooped(0x00AC,0x26DC,0x012C,0x3F)); // Zak 42 - CRCToSound(0x10347B51, V2A_Sound_SingleLooped(0x006C,0x00E0,0x0594,0x3F)); // Zak 18 - CRCToSound(0x9D2FADC0, V2A_Sound_MultiLooped(0x0072,0x1FC8,0x016A,0x3F,0x01CE,0x3F)); // Zak 80 - CRCToSound(0xFAD2C676, V2A_Sound_MultiLooped(0x0076,0x0010,0x0080,0x3F,0x0090,0x3B)); // Zak 40 - CRCToSound(0x01508B48, V2A_Sound_Single(0x0076,0x0D8C,0x017C,0x3F)); // Zak 90 - CRCToSound(0x9C18DC46, V2A_Sound_Single(0x0076,0x0D8C,0x015E,0x3F)); // Zak 91 - CRCToSound(0xF98F7EAC, V2A_Sound_Single(0x0076,0x0D8C,0x0140,0x3F)); // Zak 92 - CRCToSound(0xC925FBEF, V2A_Sound_MultiLoopedDuration(0x0080,0x0010,0x0080,0x3F,0x0090,0x3B,0x0168)); // Zak 53 - CRCToSound(0xCAB35257, V2A_Sound_Special_Zak101(0x00DA,0x425C,0x023C,0x08F0,0x0640,0x0478,0x3F,0x012C)); // Zak 101 - CRCToSound(0xA31FE4FD, V2A_Sound_Single(0x0094,0x036A,0x00E1,0x3F)); // Zak 97 - CRCToSound(0x0A1AE0F5, V2A_Sound_Single(0x009E,0x0876,0x0168,0x3F)); // Zak 5 - CRCToSound(0xD01A66CB, V2A_Sound_Single(0x009E,0x04A8,0x0168,0x3F)); // Zak 47 - CRCToSound(0x5497B912, V2A_Sound_Single(0x009E,0x0198,0x01F4,0x3F)); // Zak 39 - CRCToSound(0x2B50362F, V2A_Sound_Single(0x009E,0x09B6,0x023D,0x3F)); // Zak 67 - CRCToSound(0x7BFB6E72, V2A_Sound_Single(0x009E,0x0D14,0x0078,0x3F)); // Zak 69 - CRCToSound(0xB803A792, V2A_Sound_Single(0x009E,0x2302,0x02BC,0x3F)); // Zak 78 - CRCToSound(0x7AB82E39, V2A_Sound_SingleLooped(0x00A0,0x2A3C,0x016E,0x3F,0x1018,0x1A24)); // Zak 100 - CRCToSound(0x28057CEC, V2A_Sound_Single(0x0098,0x0FEC,0x0140,0x32)); // Zak 63 - CRCToSound(0x1180A2FC, V2A_Sound_Single(0x0098,0x0F06,0x0190,0x32)); // Zak 64 - CRCToSound(0x12616755, V2A_Sound_Single(0x0098,0x14C8,0x023C,0x14)); // Zak 9 - CRCToSound(0x642723AA, V2A_Sound_Special_Zak37(0x00A2,0x1702,0x01F4,0x3F)); // Zak 37 - CRCToSound(0xDEE56848, V2A_Sound_Single(0x009A,0x0F86,0x0100,0x3F)); // Zak 93 - CRCToSound(0xF9BE27B8, V2A_Sound_Special_Zak37(0x011C,0x1704,0x0228,0x3F)); // Zak 113 - CRCToSound(0xC73487B2, V2A_Sound_Single(0x00B0,0x18BA,0x0478,0x3F)); // Zak 81 - CRCToSound(0x32D8F925, V2A_Sound_Single(0x00B0,0x2E46,0x00F0,0x3F)); // Zak 94 - CRCToSound(0x988C83A5, V2A_Sound_Single(0x00B0,0x0DE0,0x025B,0x3F)); // Zak 106 - CRCToSound(0x8F1E3B3D, V2A_Sound_Single(0x00B0,0x05FE,0x04E2,0x3F)); // Zak 107 - CRCToSound(0x0A2A7646, V2A_Sound_Single(0x00B0,0x36FE,0x016E,0x3F)); // Zak 43 - CRCToSound(0x6F1FC435, V2A_Sound_Single(0x00B0,0x2808,0x044C,0x3F)); // Zak 108 - CRCToSound(0x870EFC29, V2A_Sound_SingleLoopedPitchbend(0x00BA,0x0100,0x03E8,0x00C8,0x3F,3)); // Zak 55 - CRCToSound(0xED773699, V2A_Sound_Special_ManiacDing(0x00B4,0x0020,0x012C,8,4)); // Zak 3 - CRCToSound(0x0BF59774, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00F8,0x00F7,8,1)); // Zak 72 - CRCToSound(0x656FFEDE, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00C4,0x00C3,8,1)); // Zak 73 - CRCToSound(0xFC4D41E5, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00A5,0x00A4,8,1)); // Zak 74 - CRCToSound(0xC0DD2089, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x009C,0x009B,8,1)); // Zak 75 - CRCToSound(0x627DFD92, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x008B,0x008A,8,1)); // Zak 76 - CRCToSound(0x703E05C1, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x007C,0x007B,8,1)); // Zak 77 - CRCToSound(0xB0F77006, V2A_Sound_Special_Zak52(0x00B0,0x01BC)); // Zak 52 - CRCToSound(0x5AE9D6A7, V2A_Sound_Special_ZakAirplane(0x00CA,0x22A4,0x0113,0x0227)); // Zak 109 - CRCToSound(0xABE0D3B0, V2A_Sound_Special_ZakAirplane(0x00CE,0x22A4,0x0227,0x0113)); // Zak 105 - CRCToSound(0x788CC749, V2A_Sound_Special_Zak71(0x00C8,0x0B37)); // Zak 71 - CRCToSound(0x2E2AB1FA, V2A_Sound_Special_Zak99(0x00D4,0x04F0,0x0FE3,0x0080,0x3F)); // Zak 99 - CRCToSound(0x1304CF20, V2A_Sound_Special_ManiacTypewriter(0x00DC,0x0624,0x023C,0x3C,2,(const uint8 *)"\x14\x11",false)); // Zak 79 - CRCToSound(0xAE68ED91, V2A_Sound_Special_Zak54(0x00D4,0x1A25,0x1E1E,0x0B80,0x01F4)); // Zak 54 - CRCToSound(0xA4F40F97, V2A_Sound_Special_Zak61(0x00E4,0x0020)); // Zak 61 - CRCToSound(0x348F85CE, V2A_Sound_Special_Zak62(0x00E4,0x0020)); // Zak 62 - CRCToSound(0xD473AB86, V2A_Sound_Special_ManiacTypewriter(0x0122,0x03E8,0x00BE,0x3F,7,(const uint8 *)"\x0F\x0B\x04\x0F\x1E\x0F\x66",false)); // Zak 46 - CRCToSound(0x84A0BA90, V2A_Sound_Special_Zak110(0x0126,0x0040,0x0136,0x0080,0x007C,0x0087)); // Zak 110 - CRCToSound(0x92680D9F, V2A_Sound_Special_Zak32(0x0140,0x0150,0x0010,0x0010)); // Zak 32 - CRCToSound(0xABFFDB02, V2A_Sound_Special_Zak86(0x01A2,0x2BAE)); // Zak 86 - CRCToSound(0x41045447, V2A_Sound_Special_Zak98(0x017A,0x0020)); // Zak 98 - CRCToSound(0xC8EEBD34, V2A_Sound_Special_Zak82(0x01A6,0x3900)); // Zak 82 - CRCToSound(0x42F9469F, V2A_Sound_Music(0x05F6,0x0636,0x0456,0x0516,0x05D6,0x05E6,0x0A36,true)); // Zak 96 - CRCToSound(0x038BBD78, V2A_Sound_Music(0x054E,0x05CE,0x044E,0x04BE,0x052E,0x053E,0x0BCE,true)); // Zak 85 - CRCToSound(0x06FFADC5, V2A_Sound_Music(0x0626,0x0686,0x0446,0x04F6,0x0606,0x0616,0x0C86,true)); // Zak 87 - CRCToSound(0xCE20ECF0, V2A_Sound_Music(0x0636,0x0696,0x0446,0x0576,0x0616,0x0626,0x0E96,true)); // Zak 114 - CRCToSound(0xBDA01BB6, V2A_Sound_Music(0x0678,0x06B8,0x0458,0x0648,0x0658,0x0668,0x0EB8,false)); // Zak 33 - CRCToSound(0x59976529, V2A_Sound_Music(0x088E,0x092E,0x048E,0x05EE,0x074E,0x07EE,0x112E,true)); // Zak 49 - CRCToSound(0xED1EED02, V2A_Sound_Music(0x08D0,0x0950,0x0440,0x07E0,0x08B0,0x08C0,0x1350,false)); // Zak 112 - CRCToSound(0x5A16C037, V2A_Sound_Music(0x634A,0x64CA,0x049A,0x18FA,0x398A,0x511A,0x6CCA,false)); // Zak 95 +static V2A_Sound *findSound(unsigned long crc) { + CRCToSound(0x8FAB08C4, V2A_Sound_SingleLooped(0x006C, 0x2B58, 0x016E, 0x3F)); // Maniac 17 + CRCToSound(0xB673160A, V2A_Sound_SingleLooped(0x006C, 0x1E78, 0x01C2, 0x1E)); // Maniac 38 + CRCToSound(0x4DB1D0B2, V2A_Sound_MultiLooped(0x0072, 0x1BC8, 0x023D, 0x3F, 0x0224, 0x3F)); // Maniac 20 + CRCToSound(0x754D75EF, V2A_Sound_Single(0x0076, 0x0738, 0x01FC, 0x3F)); // Maniac 10 + CRCToSound(0x6E3454AF, V2A_Sound_Single(0x0076, 0x050A, 0x017C, 0x3F)); // Maniac 12 + CRCToSound(0x92F0BBB6, V2A_Sound_Single(0x0076, 0x3288, 0x012E, 0x3F)); // Maniac 41 + CRCToSound(0xE1B13982, V2A_Sound_MultiLoopedDuration(0x0078, 0x0040, 0x007C, 0x3F, 0x007B, 0x3F, 0x001E)); // Maniac 21 + CRCToSound(0x288B16CF, V2A_Sound_MultiLoopedDuration(0x007A, 0x0040, 0x007C, 0x3F, 0x007B, 0x3F, 0x000A)); // Maniac 11 + CRCToSound(0xA7565268, V2A_Sound_MultiLoopedDuration(0x007A, 0x0040, 0x00F8, 0x3F, 0x00F7, 0x3F, 0x000A)); // Maniac 19 + CRCToSound(0x7D419BFC, V2A_Sound_MultiLoopedDuration(0x007E, 0x0040, 0x012C, 0x3F, 0x0149, 0x3F, 0x001E)); // Maniac 22 + CRCToSound(0x1B52280C, V2A_Sound_Single(0x0098, 0x0A58, 0x007F, 0x32)); // Maniac 6 + CRCToSound(0x38D4A810, V2A_Sound_Single(0x0098, 0x2F3C, 0x0258, 0x32)); // Maniac 7 + CRCToSound(0x09F98FC2, V2A_Sound_Single(0x0098, 0x0A56, 0x012C, 0x32)); // Maniac 16 + CRCToSound(0x90440A65, V2A_Sound_Single(0x0098, 0x0208, 0x0078, 0x28)); // Maniac 28 + CRCToSound(0x985C76EF, V2A_Sound_Single(0x0098, 0x0D6E, 0x00C8, 0x32)); // Maniac 30 + CRCToSound(0x76156137, V2A_Sound_Single(0x0098, 0x2610, 0x017C, 0x39)); // Maniac 39 + CRCToSound(0x5D95F88C, V2A_Sound_Single(0x0098, 0x0A58, 0x007F, 0x1E)); // Maniac 65 + CRCToSound(0x92D704EA, V2A_Sound_SingleLooped(0x009C, 0x29BC, 0x012C, 0x3F, 0x1BD4, 0x0DE8)); // Maniac 15 + CRCToSound(0x92F5513C, V2A_Sound_Single(0x009E, 0x0DD4, 0x01F4, 0x3F)); // Maniac 13 + CRCToSound(0xCC2F3B5A, V2A_Sound_Single(0x009E, 0x00DE, 0x01AC, 0x3F)); // Maniac 43 + CRCToSound(0x153207D3, V2A_Sound_Single(0x009E, 0x0E06, 0x02A8, 0x3F)); // Maniac 67 + CRCToSound(0xC4F370CE, V2A_Sound_Single(0x00AE, 0x0330, 0x01AC, 0x3F)); // Maniac 8 + CRCToSound(0x928C4BAC, V2A_Sound_Single(0x00AE, 0x08D6, 0x01AC, 0x3F)); // Maniac 9 + CRCToSound(0x62D5B11F, V2A_Sound_Single(0x00AE, 0x165C, 0x01CB, 0x3F)); // Maniac 27 + CRCToSound(0x3AB22CB5, V2A_Sound_Single(0x00AE, 0x294E, 0x012A, 0x3F)); // Maniac 62 + CRCToSound(0x2D70BBE9, V2A_Sound_SingleLoopedPitchbend(0x00B4, 0x1702, 0x03E8, 0x0190, 0x3F, 5)); // Maniac 64 + CRCToSound(0xFA4C1B1C, V2A_Sound_Special_Maniac69(0x00B2, 0x1702, 0x0190, 0x3F)); // Maniac 69 + CRCToSound(0x19D50D67, V2A_Sound_Special_ManiacDing(0x00B6, 0x0020, 0x00C8, 16, 2)); // Maniac 14 + CRCToSound(0x3E6FBE15, V2A_Sound_Special_ManiacTentacle(0x00B2, 0x0010, 0x007C, 0x016D, 1)); // Maniac 25 + CRCToSound(0x5305753C, V2A_Sound_Special_ManiacTentacle(0x00B2, 0x0010, 0x007C, 0x016D, 7)); // Maniac 36 + CRCToSound(0x28895106, V2A_Sound_Special_Maniac59(0x00C0, 0x00FE, 0x00E9, 0x0111, 4, 0x0A)); // Maniac 59 + CRCToSound(0xB641ACF6, V2A_Sound_Special_Maniac61(0x00C8, 0x0100, 0x00C8, 0x01C2)); // Maniac 61 + CRCToSound(0xE1A91583, V2A_Sound_Special_ManiacPhone(0x00D0, 0x0040, 0x007C, 0x3F, 0x007B, 0x3F, 0x3C, 5, 6)); // Maniac 23 + CRCToSound(0x64816ED5, V2A_Sound_Special_ManiacPhone(0x00D0, 0x0040, 0x00BE, 0x37, 0x00BD, 0x37, 0x3C, 5, 6)); // Maniac 24 + CRCToSound(0x639D72C2, V2A_Sound_Special_Maniac46(0x00D0, 0x10A4, 0x0080, 0x3F, 0x28, 3)); // Maniac 46 + CRCToSound(0xE8826D92, V2A_Sound_Special_ManiacTypewriter(0x00EC, 0x025A, 0x023C, 0x3F, 8, (const uint8 *)"\x20\x41\x04\x21\x08\x10\x13\x07", true)); // Maniac 45 + CRCToSound(0xEDFF3D41, V2A_Sound_Single(0x00F8, 0x2ADE, 0x01F8, 0x3F)); // Maniac 42 (this should echo, but it's barely noticeable and I don't feel like doing it) + CRCToSound(0x15606D06, V2A_Sound_Special_Maniac32(0x0148, 0x0020, 0x0168, 0x0020, 0x3F)); // Maniac 32 + CRCToSound(0x753EAFE3, V2A_Sound_Special_Maniac44(0x017C, 0x0010, 0x018C, 0x0020, 0x00C8, 0x0080, 0x3F)); // Maniac 44 + CRCToSound(0xB1AB065C, V2A_Sound_Music(0x0032, 0x00B2, 0x08B2, 0x1222, 0x1A52, 0x23C2, 0x3074, false)); // Maniac 50 + CRCToSound(0x091F5D9C, V2A_Sound_Music(0x0032, 0x0132, 0x0932, 0x1802, 0x23D2, 0x3EA2, 0x4F04, false)); // Maniac 58 + + CRCToSound(0x8E2C8AB3, V2A_Sound_SingleLooped(0x005C, 0x0F26, 0x0168, 0x3C)); // Zak 41 + CRCToSound(0x3792071F, V2A_Sound_SingleLooped(0x0060, 0x1A18, 0x06A4, 0x3F)); // Zak 88 + CRCToSound(0xF192EDE9, V2A_Sound_SingleLooped(0x0062, 0x0054, 0x01FC, 0x1E)); // Zak 68 + CRCToSound(0xC43B0245, V2A_Sound_Special_Zak70(0x006C, 0x166E, 0x00C8, 0x0190, 0x0320, 0x0640, 0x32)); // Zak 70 + CRCToSound(0xCEB51670, V2A_Sound_SingleLooped(0x00AC, 0x26DC, 0x012C, 0x3F)); // Zak 42 + CRCToSound(0x10347B51, V2A_Sound_SingleLooped(0x006C, 0x00E0, 0x0594, 0x3F)); // Zak 18 + CRCToSound(0x9D2FADC0, V2A_Sound_MultiLooped(0x0072, 0x1FC8, 0x016A, 0x3F, 0x01CE, 0x3F)); // Zak 80 + CRCToSound(0xFAD2C676, V2A_Sound_MultiLooped(0x0076, 0x0010, 0x0080, 0x3F, 0x0090, 0x3B)); // Zak 40 + CRCToSound(0x01508B48, V2A_Sound_Single(0x0076, 0x0D8C, 0x017C, 0x3F)); // Zak 90 + CRCToSound(0x9C18DC46, V2A_Sound_Single(0x0076, 0x0D8C, 0x015E, 0x3F)); // Zak 91 + CRCToSound(0xF98F7EAC, V2A_Sound_Single(0x0076, 0x0D8C, 0x0140, 0x3F)); // Zak 92 + CRCToSound(0xC925FBEF, V2A_Sound_MultiLoopedDuration(0x0080, 0x0010, 0x0080, 0x3F, 0x0090, 0x3B, 0x0168)); // Zak 53 + CRCToSound(0xCAB35257, V2A_Sound_Special_Zak101(0x00DA, 0x425C, 0x023C, 0x08F0, 0x0640, 0x0478, 0x3F, 0x012C)); // Zak 101 + CRCToSound(0xA31FE4FD, V2A_Sound_Single(0x0094, 0x036A, 0x00E1, 0x3F)); // Zak 97 + CRCToSound(0x0A1AE0F5, V2A_Sound_Single(0x009E, 0x0876, 0x0168, 0x3F)); // Zak 5 + CRCToSound(0xD01A66CB, V2A_Sound_Single(0x009E, 0x04A8, 0x0168, 0x3F)); // Zak 47 + CRCToSound(0x5497B912, V2A_Sound_Single(0x009E, 0x0198, 0x01F4, 0x3F)); // Zak 39 + CRCToSound(0x2B50362F, V2A_Sound_Single(0x009E, 0x09B6, 0x023D, 0x3F)); // Zak 67 + CRCToSound(0x7BFB6E72, V2A_Sound_Single(0x009E, 0x0D14, 0x0078, 0x3F)); // Zak 69 + CRCToSound(0xB803A792, V2A_Sound_Single(0x009E, 0x2302, 0x02BC, 0x3F)); // Zak 78 + CRCToSound(0x7AB82E39, V2A_Sound_SingleLooped(0x00A0, 0x2A3C, 0x016E, 0x3F, 0x1018, 0x1A24)); // Zak 100 + CRCToSound(0x28057CEC, V2A_Sound_Single(0x0098, 0x0FEC, 0x0140, 0x32)); // Zak 63 + CRCToSound(0x1180A2FC, V2A_Sound_Single(0x0098, 0x0F06, 0x0190, 0x32)); // Zak 64 + CRCToSound(0x12616755, V2A_Sound_Single(0x0098, 0x14C8, 0x023C, 0x14)); // Zak 9 + CRCToSound(0x642723AA, V2A_Sound_Special_Zak37(0x00A2, 0x1702, 0x01F4, 0x3F)); // Zak 37 + CRCToSound(0xDEE56848, V2A_Sound_Single(0x009A, 0x0F86, 0x0100, 0x3F)); // Zak 93 + CRCToSound(0xF9BE27B8, V2A_Sound_Special_Zak37(0x011C, 0x1704, 0x0228, 0x3F)); // Zak 113 + CRCToSound(0xC73487B2, V2A_Sound_Single(0x00B0, 0x18BA, 0x0478, 0x3F)); // Zak 81 + CRCToSound(0x32D8F925, V2A_Sound_Single(0x00B0, 0x2E46, 0x00F0, 0x3F)); // Zak 94 + CRCToSound(0x988C83A5, V2A_Sound_Single(0x00B0, 0x0DE0, 0x025B, 0x3F)); // Zak 106 + CRCToSound(0x8F1E3B3D, V2A_Sound_Single(0x00B0, 0x05FE, 0x04E2, 0x3F)); // Zak 107 + CRCToSound(0x0A2A7646, V2A_Sound_Single(0x00B0, 0x36FE, 0x016E, 0x3F)); // Zak 43 + CRCToSound(0x6F1FC435, V2A_Sound_Single(0x00B0, 0x2808, 0x044C, 0x3F)); // Zak 108 + CRCToSound(0x870EFC29, V2A_Sound_SingleLoopedPitchbend(0x00BA, 0x0100, 0x03E8, 0x00C8, 0x3F, 3)); // Zak 55 + CRCToSound(0xED773699, V2A_Sound_Special_ManiacDing(0x00B4, 0x0020, 0x012C, 8, 4)); // Zak 3 + CRCToSound(0x0BF59774, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x00F8, 0x00F7, 8, 1)); // Zak 72 + CRCToSound(0x656FFEDE, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x00C4, 0x00C3, 8, 1)); // Zak 73 + CRCToSound(0xFC4D41E5, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x00A5, 0x00A4, 8, 1)); // Zak 74 + CRCToSound(0xC0DD2089, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x009C, 0x009B, 8, 1)); // Zak 75 + CRCToSound(0x627DFD92, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x008B, 0x008A, 8, 1)); // Zak 76 + CRCToSound(0x703E05C1, V2A_Sound_Special_ZakStereoDing(0x00BE, 0x0020, 0x007C, 0x007B, 8, 1)); // Zak 77 + CRCToSound(0xB0F77006, V2A_Sound_Special_Zak52(0x00B0, 0x01BC)); // Zak 52 + CRCToSound(0x5AE9D6A7, V2A_Sound_Special_ZakAirplane(0x00CA, 0x22A4, 0x0113, 0x0227)); // Zak 109 + CRCToSound(0xABE0D3B0, V2A_Sound_Special_ZakAirplane(0x00CE, 0x22A4, 0x0227, 0x0113)); // Zak 105 + CRCToSound(0x788CC749, V2A_Sound_Special_Zak71(0x00C8, 0x0B37)); // Zak 71 + CRCToSound(0x2E2AB1FA, V2A_Sound_Special_Zak99(0x00D4, 0x04F0, 0x0FE3, 0x0080, 0x3F)); // Zak 99 + CRCToSound(0x1304CF20, V2A_Sound_Special_ManiacTypewriter(0x00DC, 0x0624, 0x023C, 0x3C, 2, (const uint8 *)"\x14\x11", false)); // Zak 79 + CRCToSound(0xAE68ED91, V2A_Sound_Special_Zak54(0x00D4, 0x1A25, 0x1E1E, 0x0B80, 0x01F4)); // Zak 54 + CRCToSound(0xA4F40F97, V2A_Sound_Special_Zak61(0x00E4, 0x0020)); // Zak 61 + CRCToSound(0x348F85CE, V2A_Sound_Special_Zak62(0x00E4, 0x0020)); // Zak 62 + CRCToSound(0xD473AB86, V2A_Sound_Special_ManiacTypewriter(0x0122, 0x03E8, 0x00BE, 0x3F, 7, (const uint8 *)"\x0F\x0B\x04\x0F\x1E\x0F\x66", false)); // Zak 46 + CRCToSound(0x84A0BA90, V2A_Sound_Special_Zak110(0x0126, 0x0040, 0x0136, 0x0080, 0x007C, 0x0087)); // Zak 110 + CRCToSound(0x92680D9F, V2A_Sound_Special_Zak32(0x0140, 0x0150, 0x0010, 0x0010)); // Zak 32 + CRCToSound(0xABFFDB02, V2A_Sound_Special_Zak86(0x01A2, 0x2BAE)); // Zak 86 + CRCToSound(0x41045447, V2A_Sound_Special_Zak98(0x017A, 0x0020)); // Zak 98 + CRCToSound(0xC8EEBD34, V2A_Sound_Special_Zak82(0x01A6, 0x3900)); // Zak 82 + CRCToSound(0x42F9469F, V2A_Sound_Music(0x05F6, 0x0636, 0x0456, 0x0516, 0x05D6, 0x05E6, 0x0A36, true)); // Zak 96 + CRCToSound(0x038BBD78, V2A_Sound_Music(0x054E, 0x05CE, 0x044E, 0x04BE, 0x052E, 0x053E, 0x0BCE, true)); // Zak 85 + CRCToSound(0x06FFADC5, V2A_Sound_Music(0x0626, 0x0686, 0x0446, 0x04F6, 0x0606, 0x0616, 0x0C86, true)); // Zak 87 + CRCToSound(0xCE20ECF0, V2A_Sound_Music(0x0636, 0x0696, 0x0446, 0x0576, 0x0616, 0x0626, 0x0E96, true)); // Zak 114 + CRCToSound(0xBDA01BB6, V2A_Sound_Music(0x0678, 0x06B8, 0x0458, 0x0648, 0x0658, 0x0668, 0x0EB8, false)); // Zak 33 + CRCToSound(0x59976529, V2A_Sound_Music(0x088E, 0x092E, 0x048E, 0x05EE, 0x074E, 0x07EE, 0x112E, true)); // Zak 49 + CRCToSound(0xED1EED02, V2A_Sound_Music(0x08D0, 0x0950, 0x0440, 0x07E0, 0x08B0, 0x08C0, 0x1350, false)); // Zak 112 + CRCToSound(0x5A16C037, V2A_Sound_Music(0x634A, 0x64CA, 0x049A, 0x18FA, 0x398A, 0x511A, 0x6CCA, false)); // Zak 95 return NULL; } @@ -1860,11 +1860,11 @@ Player_V2A::~Player_V2A() { delete _mod; } -void Player_V2A::setMusicVolume (int vol) { +void Player_V2A::setMusicVolume(int vol) { _mod->setMusicVolume(vol); } -int Player_V2A::getSoundSlot (int id) const { +int Player_V2A::getSoundSlot(int id) const { int i; for (i = 0; i < V2A_MAXSLOTS; i++) { if (_slot[i].id == id) @@ -1914,8 +1914,10 @@ void Player_V2A::startSound(int nr) { } stopSound(nr); int i = getSoundSlot(); - if (i == -1) + if (i == -1) { + delete snd; return; + } _slot[i].id = nr; _slot[i].sound = snd; _slot[i].sound->start(_mod, nr, data); @@ -1938,7 +1940,7 @@ void Player_V2A::updateSound() { } int Player_V2A::getMusicTimer() { - return 0; // FIXME - need to keep track of playing music resources + return 0; // FIXME - need to keep track of playing music resources } int Player_V2A::getSoundStatus(int nr) const { diff --git a/engines/scumm/player_v2a.h b/engines/scumm/player_v2a.h index 719d5491ea..fe20b43846 100644 --- a/engines/scumm/player_v2a.h +++ b/engines/scumm/player_v2a.h @@ -63,7 +63,7 @@ private: Player_MOD *_mod; soundSlot _slot[V2A_MAXSLOTS]; - int getSoundSlot (int id = 0) const; + int getSoundSlot(int id = 0) const; static void update_proc(void *param); void updateSound(); }; diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 3ab13df032..2f9f4c1195 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1293,7 +1293,10 @@ void ScummEngine::saveOrLoad(Serializer *s) { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE // FM-Towns specific (extra palette data, color cycle data, etc.) - if (s->getVersion() >= VER(82)) { + // In earlier save game versions (below 87) the FM-Towns specific data would get saved (and loaded) even in non FM-Towns games. + // This would cause an unnecessary save file incompatibility between DS (which uses the DISABLE_TOWNS_DUAL_LAYER_MODE setting) + // and other ports. + if ((_game.platform == Common::kPlatformFMTowns && s->getVersion() >= VER(87)) || (s->getVersion() >= VER(82) && s->getVersion() < VER(87))) { const SaveLoadEntry townsFields[] = { MKLINE(Common::Rect, left, sleInt16, VER(82)), MKLINE(Common::Rect, top, sleInt16, VER(82)), diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 16c225d20e..d55ec2d047 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 86 +#define CURRENT_VER 87 /** * An auxillary macro, used to specify savegame versions. We use this instead diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 81f6af453c..f94496b14b 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1171,11 +1171,8 @@ Common::Error ScummEngine::init() { Common::List<Graphics::PixelFormat> tryModes = _system->getSupportedFormats(); for (Common::List<Graphics::PixelFormat>::iterator g = tryModes.begin(); g != tryModes.end(); ++g) { if (g->bytesPerPixel != 2 || g->aBits()) { - g = tryModes.erase(g); - g--; - } - - if (*g == _outputPixelFormat) { + g = tryModes.reverse_erase(g); + } else if (*g == _outputPixelFormat) { tryModes.clear(); tryModes.push_back(_outputPixelFormat); break; diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index ba8c6e2277..f058ef1a2c 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -23,6 +23,8 @@ #include "common/config-manager.h" #include "common/timer.h" #include "common/util.h" +#include "common/ptr.h" +#include "common/substream.h" #include "scumm/actor.h" #include "scumm/file.h" @@ -62,7 +64,8 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer) _mixer(mixer), _soundQuePos(0), _soundQue2Pos(0), - _sfxFile(0), + _sfxFilename(), + _sfxFileEncByte(0), _offsetTable(0), _numSoundEffects(0), _soundMode(kVOCMode), @@ -91,7 +94,6 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer) Sound::~Sound() { stopCDTimer(); g_system->getAudioCDManager()->stop(); - delete _sfxFile; } void Sound::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags) { @@ -490,6 +492,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle int num = 0, i; int size = 0; int id = -1; + Common::ScopedPtr<ScummFile> file; if (_vm->_game.id == GID_CMI) { _sfxMode |= mode; @@ -523,25 +526,29 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle return; } - _sfxFile->close(); - sprintf(filename, "audio/%s.%d/%d.voc", roomname, offset, b); - _vm->openFile(*_sfxFile, filename); - if (!_sfxFile->isOpen()) { - sprintf(filename, "audio/%s_%d/%d.voc", roomname, offset, b); - _vm->openFile(*_sfxFile, filename); + file.reset(new ScummFile()); + if (!file) + error("startTalkSound: Out of memory"); + + sprintf(filename, "audio/%s.%u/%u.voc", roomname, offset, b); + if (!_vm->openFile(*file, filename)) { + sprintf(filename, "audio/%s_%u/%u.voc", roomname, offset, b); + _vm->openFile(*file, filename); } - if (!_sfxFile->isOpen()) { - sprintf(filename, "%d.%d.voc", offset, b); - _vm->openFile(*_sfxFile, filename); + + if (!file->isOpen()) { + sprintf(filename, "%u.%u.voc", offset, b); + _vm->openFile(*file, filename); } - if (!_sfxFile->isOpen()) { + + if (!file->isOpen()) { warning("startTalkSound: dig demo: voc file not found"); return; } } else { - if (!_sfxFile->isOpen()) { - warning("startTalkSound: SFX file is not open"); + if (_sfxFilename.empty()) { + warning("startTalkSound: SFX file not found"); return; } @@ -581,11 +588,30 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle size = -1; } - _sfxFile->seek(offset, SEEK_SET); + file.reset(new ScummFile()); + if (!file) + error("startTalkSound: Out of memory"); + + if (!_vm->openFile(*file, _sfxFilename)) { + warning("startTalkSound: could not open sfx file %s", _sfxFilename.c_str()); + return; + } + + file->setEnc(_sfxFileEncByte); + file->seek(offset, SEEK_SET); assert(num + 1 < (int)ARRAYSIZE(_mouthSyncTimes)); for (i = 0; i < num; i++) - _mouthSyncTimes[i] = _sfxFile->readUint16BE(); + _mouthSyncTimes[i] = file->readUint16BE(); + + // Adjust offset to account for the mouth sync times. It is noteworthy + // that we do not adjust the size here for compressed streams, since + // they only set size to the size of the compressed sound data. + offset += num * 2; + // TODO: In case we ever set up the size for VOC streams, we should + // really check whether the size contains the _mouthSyncTimes. + //if (_soundMode == kVOCMode) + // size -= num * 2; _mouthSyncTimes[i] = 0xFFFF; _sfxMode |= mode; @@ -601,9 +627,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle #ifdef USE_MAD { assert(size > 0); - Common::SeekableReadStream *tmp = _sfxFile->readStream(size); - assert(tmp); - input = Audio::makeMP3Stream(tmp, DisposeAfterUse::YES); + input = Audio::makeMP3Stream(new Common::SeekableSubReadStream(file.release(), offset, offset + size, DisposeAfterUse::YES), DisposeAfterUse::YES); } #endif break; @@ -611,9 +635,7 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle #ifdef USE_VORBIS { assert(size > 0); - Common::SeekableReadStream *tmp = _sfxFile->readStream(size); - assert(tmp); - input = Audio::makeVorbisStream(tmp, DisposeAfterUse::YES); + input = Audio::makeVorbisStream(new Common::SeekableSubReadStream(file.release(), offset, offset + size, DisposeAfterUse::YES), DisposeAfterUse::YES); } #endif break; @@ -621,14 +643,12 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle #ifdef USE_FLAC { assert(size > 0); - Common::SeekableReadStream *tmp = _sfxFile->readStream(size); - assert(tmp); - input = Audio::makeFLACStream(tmp, DisposeAfterUse::YES); + input = Audio::makeFLACStream(new Common::SeekableSubReadStream(file.release(), offset, offset + size, DisposeAfterUse::YES), DisposeAfterUse::YES); } #endif break; default: - input = Audio::makeVOCStream(_sfxFile, Audio::FLAG_UNSIGNED); + input = Audio::makeVOCStream(file.release(), Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); break; } @@ -847,20 +867,11 @@ void Sound::talkSound(uint32 a, uint32 b, int mode, int channel) { _talk_sound_mode |= mode; } -/* The sound code currently only supports General Midi. - * General Midi is used in Day Of The Tentacle. - * Roland music is also playable, but doesn't sound well. - * A mapping between roland instruments and GM instruments - * is needed. - */ - void Sound::setupSound() { - delete _sfxFile; - - _sfxFile = openSfxFile(); + setupSfxFile(); if (_vm->_game.id == GID_FT) { - _vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = _sfxFile->isOpen(); + _vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = _sfxFilename.empty() ? 0 : 1; } } @@ -892,7 +903,7 @@ void Sound::pauseSounds(bool pause) { } } -BaseScummFile *Sound::openSfxFile() { +void Sound::setupSfxFile() { struct SoundFileExtensions { const char *ext; SoundMode mode; @@ -912,8 +923,10 @@ BaseScummFile *Sound::openSfxFile() { { 0, kVOCMode } }; - ScummFile *file = new ScummFile(); + ScummFile file; _offsetTable = NULL; + _sfxFileEncByte = 0; + _sfxFilename.clear(); /* Try opening the file <baseName>.sou first, e.g. tentacle.sou. * That way, you can keep .sou files for multiple games in the @@ -938,15 +951,20 @@ BaseScummFile *Sound::openSfxFile() { tmp = basename[0] + "tlk"; } - if (file->open(tmp) && _vm->_game.heversion <= 74) - file->setEnc(0x69); + if (file.open(tmp)) + _sfxFilename = tmp; + + if (_vm->_game.heversion <= 74) + _sfxFileEncByte = 0x69; + _soundMode = kVOCMode; } else { - for (uint j = 0; j < 2 && !file->isOpen(); ++j) { + for (uint j = 0; j < 2 && !file.isOpen(); ++j) { for (int i = 0; extensions[i].ext; ++i) { tmp = basename[j] + extensions[i].ext; - if (_vm->openFile(*file, tmp)) { + if (_vm->openFile(file, tmp)) { _soundMode = extensions[i].mode; + _sfxFilename = tmp; break; } } @@ -970,23 +988,21 @@ BaseScummFile *Sound::openSfxFile() { */ int size, compressed_offset; MP3OffsetTable *cur; - compressed_offset = file->readUint32BE(); + compressed_offset = file.readUint32BE(); _offsetTable = (MP3OffsetTable *) malloc(compressed_offset); _numSoundEffects = compressed_offset / 16; size = compressed_offset; cur = _offsetTable; while (size > 0) { - cur->org_offset = file->readUint32BE(); - cur->new_offset = file->readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */ - cur->num_tags = file->readUint32BE(); - cur->compressed_size = file->readUint32BE(); + cur->org_offset = file.readUint32BE(); + cur->new_offset = file.readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */ + cur->num_tags = file.readUint32BE(); + cur->compressed_size = file.readUint32BE(); size -= 4 * 4; cur++; } } - - return file; } bool Sound::isSfxFinished() const { diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h index e9a37ac9fa..48f28d51ff 100644 --- a/engines/scumm/sound.h +++ b/engines/scumm/sound.h @@ -69,7 +69,8 @@ protected: int16 flags; } _soundQue2[10]; - BaseScummFile *_sfxFile; + Common::String _sfxFilename; + byte _sfxFileEncByte; SoundMode _soundMode; MP3OffsetTable *_offsetTable; // For compressed audio int _numSoundEffects; // For compressed audio @@ -126,7 +127,7 @@ public: void saveLoadWithSerializer(Serializer *ser); protected: - BaseScummFile *openSfxFile(); + void setupSfxFile(); bool isSfxFinished() const; void processSfxQueues(); diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp index 2699500527..484958ca52 100644 --- a/engines/sky/detection.cpp +++ b/engines/sky/detection.cpp @@ -55,9 +55,9 @@ static const SkyVersion skyVersions[] = { { 1413, -1, "floppy", 303, GUIO1(GUIO_NOSPEECH) }, { 1445, 8830435, "floppy", 348, GUIO1(GUIO_NOSPEECH) }, { 1445, -1, "floppy", 331, GUIO1(GUIO_NOSPEECH) }, - { 1711, -1, "cd demo", 365, GUIO1(GUIO_NONE) }, - { 5099, -1, "cd", 368, GUIO1(GUIO_NONE) }, - { 5097, -1, "cd", 372, GUIO1(GUIO_NONE) }, + { 1711, -1, "cd demo", 365, GUIO0() }, + { 5099, -1, "cd", 368, GUIO0() }, + { 5097, -1, "cd", 372, GUIO0() }, { 0, 0, 0, 0, 0 } }; diff --git a/engines/sky/music/adlibmusic.cpp b/engines/sky/music/adlibmusic.cpp index 1b5518fcb1..a41cd6a81d 100644 --- a/engines/sky/music/adlibmusic.cpp +++ b/engines/sky/music/adlibmusic.cpp @@ -30,9 +30,8 @@ namespace Sky { -AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pDisk) { +AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) { _driverFileBase = 60202; - _mixer = pMixer; _sampleRate = pMixer->getOutputRate(); _opl = makeAdLibOPL(_sampleRate); diff --git a/engines/sky/music/adlibmusic.h b/engines/sky/music/adlibmusic.h index 2782a07be6..2161795b4c 100644 --- a/engines/sky/music/adlibmusic.h +++ b/engines/sky/music/adlibmusic.h @@ -26,7 +26,6 @@ #include "sky/music/musicbase.h" #include "audio/audiostream.h" #include "audio/fmopl.h" -#include "audio/mixer.h" namespace Sky { @@ -44,7 +43,6 @@ public: private: FM_OPL *_opl; - Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; uint8 *_initSequence; uint32 _sampleRate, _nextMusicPoll; diff --git a/engines/sky/music/gmmusic.cpp b/engines/sky/music/gmmusic.cpp index d0ba1505cb..85240ea82e 100644 --- a/engines/sky/music/gmmusic.cpp +++ b/engines/sky/music/gmmusic.cpp @@ -34,7 +34,7 @@ void GmMusic::passTimerFunc(void *param) { ((GmMusic*)param)->timerCall(); } -GmMusic::GmMusic(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) { +GmMusic::GmMusic(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) { _driverFileBase = 60200; _midiDrv = pMidiDrv; int midiRes = _midiDrv->open(); diff --git a/engines/sky/music/gmmusic.h b/engines/sky/music/gmmusic.h index 0f54a930e4..068601ba1f 100644 --- a/engines/sky/music/gmmusic.h +++ b/engines/sky/music/gmmusic.h @@ -31,7 +31,7 @@ namespace Sky { class GmMusic : public MusicBase { public: - GmMusic(MidiDriver *pMidiDrv, Disk *pDisk); + GmMusic(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk); ~GmMusic(); virtual void setVolume(uint16 param); private: diff --git a/engines/sky/music/mt32music.cpp b/engines/sky/music/mt32music.cpp index d068a221b2..18ebf123ff 100644 --- a/engines/sky/music/mt32music.cpp +++ b/engines/sky/music/mt32music.cpp @@ -34,7 +34,7 @@ void MT32Music::passTimerFunc(void *param) { ((MT32Music*)param)->timerCall(); } -MT32Music::MT32Music(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) { +MT32Music::MT32Music(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) { _driverFileBase = 60200; _midiDrv = pMidiDrv; int midiRes = _midiDrv->open(); diff --git a/engines/sky/music/mt32music.h b/engines/sky/music/mt32music.h index 74962daac3..8f8e70f51b 100644 --- a/engines/sky/music/mt32music.h +++ b/engines/sky/music/mt32music.h @@ -31,7 +31,7 @@ namespace Sky { class MT32Music : public MusicBase { public: - MT32Music(MidiDriver *pMidiDrv, Disk *pDisk); + MT32Music(MidiDriver *pMidiDrv, Audio::Mixer *pMixer, Disk *pDisk); ~MT32Music(); private: static void passTimerFunc(void *param); diff --git a/engines/sky/music/musicbase.cpp b/engines/sky/music/musicbase.cpp index 60d0f352e7..018614da98 100644 --- a/engines/sky/music/musicbase.cpp +++ b/engines/sky/music/musicbase.cpp @@ -25,11 +25,13 @@ #include "common/util.h" #include "common/endian.h" #include "common/textconsole.h" +#include "audio/audiostream.h" namespace Sky { -MusicBase::MusicBase(Disk *pDisk) { +MusicBase::MusicBase(Audio::Mixer *pMixer, Disk *pDisk) { _musicData = NULL; + _mixer = pMixer; _skyDisk = pDisk; _currentMusic = 0; _musicVolume = 127; @@ -59,6 +61,8 @@ void MusicBase::loadSection(uint8 pSection) { } bool MusicBase::musicIsPlaying() { + if (_mixer->isSoundHandleActive(_musicHandle)) + return true; for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) if (_channels[cnt]->isActive()) return true; @@ -71,6 +75,8 @@ void MusicBase::stopMusic() { } void MusicBase::stopMusicInternal() { + _mixer->stopHandle(_musicHandle); + for (uint8 cnt = 0; cnt < _numberOfChannels; cnt++) delete _channels[cnt]; _numberOfChannels = 0; @@ -94,18 +100,51 @@ void MusicBase::loadNewMusic() { _currentMusic = _onNextPoll.musicToProcess; - if (_currentMusic != 0) { - musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1); - musicPos += _musicDataLoc + ((_currentMusic - 1) << 1); - musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc; + if (_currentMusic == 0) + return; + + // Try playing digital audio first (from the Music Enhancement Project). + // TODO: This always prefers digital music over the MIDI music types! + uint8 section = _currentSection; + uint8 song = _currentMusic; + // handle duplicates + if ((section == 2 && song == 1) || (section == 5 && song == 1)) { + section = 1; + song = 1; + } else if ((section == 2 && song == 4) || (section == 5 && song == 4)) { + section = 1; + song = 4; + } else if (section == 5 && song == 6) { + section = 4; + song = 4; + } + Common::String trackName = Common::String::format("music_%d%02d", section, song); + Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName); + if (stream) { + // not all tracks should loop + bool loops = true; + if ((section == 1 && song == 1) || (section == 1 && song == 4) + || (section == 2 && song == 1) || (section == 2 && song == 4) + || (section == 4 && song == 2) || (section == 4 && song == 3) + || (section == 4 && song == 5) || (section == 4 && song == 6) + || (section == 4 && song == 11) || (section == 5 && song == 1) + || (section == 5 && song == 3) || (section == 5 && song == 4)) + loops = false; + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, Audio::makeLoopingAudioStream(stream, loops ? 0 : 1)); + return; + } + + // no digital audio, resort to MIDI playback + musicPos = READ_LE_UINT16(_musicData + _musicDataLoc + 1); + musicPos += _musicDataLoc + ((_currentMusic - 1) << 1); + musicPos = READ_LE_UINT16(_musicData + musicPos) + _musicDataLoc; - _musicTempo0 = _musicData[musicPos]; - _musicTempo1 = _musicData[musicPos+1]; + _musicTempo0 = _musicData[musicPos]; + _musicTempo1 = _musicData[musicPos+1]; - setupChannels(_musicData + musicPos + 2); + setupChannels(_musicData + musicPos + 2); - updateTempo(); - } + updateTempo(); } void MusicBase::pollMusic() { diff --git a/engines/sky/music/musicbase.h b/engines/sky/music/musicbase.h index c175876380..066ebe593c 100644 --- a/engines/sky/music/musicbase.h +++ b/engines/sky/music/musicbase.h @@ -27,6 +27,8 @@ #include "common/scummsys.h" #include "common/mutex.h" +#include "audio/mixer.h" + namespace Sky { class Disk; @@ -48,7 +50,7 @@ private: class MusicBase { public: - MusicBase(Disk *pDisk); + MusicBase(Audio::Mixer *pMixer, Disk *pDisk); virtual ~MusicBase(); void loadSection(uint8 pSection); void startMusic(uint16 param); @@ -60,6 +62,7 @@ public: protected: + Audio::Mixer *_mixer; Disk *_skyDisk; uint8 *_musicData; @@ -75,6 +78,7 @@ protected: Actions _onNextPoll; ChannelBase *_channels[10]; Common::Mutex _mutex; + Audio::SoundHandle _musicHandle; virtual void setupPointers() = 0; virtual void setupChannels(uint8 *channelData) = 0; diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp index 72abc26f32..44ea3a305b 100644 --- a/engines/sky/sky.cpp +++ b/engines/sky/sky.cpp @@ -268,9 +268,9 @@ Common::Error SkyEngine::init() { } else { _systemVars.systemFlags |= SF_ROLAND; if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")) - _skyMusic = new MT32Music(MidiDriver::createMidi(dev), _skyDisk); + _skyMusic = new MT32Music(MidiDriver::createMidi(dev), _mixer, _skyDisk); else - _skyMusic = new GmMusic(MidiDriver::createMidi(dev), _skyDisk); + _skyMusic = new GmMusic(MidiDriver::createMidi(dev), _mixer, _skyDisk); } if (isCDVersion()) { diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index 324154f709..d55a08293e 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -28,6 +28,7 @@ #include "sword1/sword1.h" #include "sword1/animation.h" #include "sword1/text.h" +#include "sword1/resman.h" #include "common/str.h" #include "common/system.h" @@ -65,8 +66,8 @@ static const char *const sequenceList[20] = { // Basic movie player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType) - : _vm(vm), _textMan(textMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) { +MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType) + : _vm(vm), _textMan(textMan), _resMan(resMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) { _bgSoundStream = NULL; _decoderType = decoderType; _decoder = decoder; @@ -183,8 +184,8 @@ void MoviePlayer::performPostProcessing(byte *screen) { _textMan->makeTextSprite(2, (const uint8 *)_movieTexts.front()._text.c_str(), 600, LETTER_COL); FrameHeader *frame = _textMan->giveSpriteData(2); - _textWidth = frame->width; - _textHeight = frame->height; + _textWidth = _resMan->toUint16(frame->width); + _textHeight = _resMan->toUint16(frame->height); _textX = 320 - _textWidth / 2; _textY = 420 - _textHeight; } @@ -323,7 +324,7 @@ uint32 DXADecoderWithSound::getElapsedTime() const { // Factory function for creating the appropriate cutscene player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system) { +MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system) { Common::String filename; Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle; @@ -331,7 +332,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M if (Common::File::exists(filename)) { Video::SmackerDecoder *smkDecoder = new Video::SmackerDecoder(snd); - return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK); + return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK); } filename = Common::String::format("%s.dxa", sequenceList[id]); @@ -339,7 +340,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M if (Common::File::exists(filename)) { #ifdef USE_ZLIB DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle); - return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA); + return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA); #else GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK")); dialog.runModal(); diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h index fc3061bbf9..1c03c66342 100644 --- a/engines/sword1/animation.h +++ b/engines/sword1/animation.h @@ -67,7 +67,7 @@ private: class MoviePlayer { public: - MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType); + MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType); virtual ~MoviePlayer(); bool load(uint32 id); void play(); @@ -75,6 +75,7 @@ public: protected: SwordEngine *_vm; Text *_textMan; + ResMan *_resMan; Audio::Mixer *_snd; OSystem *_system; Common::List<MovieText> _movieTexts; @@ -93,7 +94,7 @@ protected: byte findWhitePalIndex(); }; -MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system); +MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system); } // End of namespace Sword1 diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp index d1c69c80ff..8e04861edf 100644 --- a/engines/sword1/logic.cpp +++ b/engines/sword1/logic.cpp @@ -520,7 +520,7 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc case IT_PUSHVARIABLE: debug(9, "IT_PUSHVARIABLE: ScriptVar[%d] => %d", scriptCode[pc], _scriptVars[scriptCode[pc]]); varNum = scriptCode[pc++]; - if (SwordEngine::_systemVars.isDemo && SwordEngine::isPc()) { + if (SwordEngine::_systemVars.isDemo && SwordEngine::isWindows()) { if (varNum >= 397) // BS1 Demo has different number of script variables varNum++; if (varNum >= 699) @@ -611,7 +611,7 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc case IT_POPVAR: // pop a variable debug(9, "IT_POPVAR: ScriptVars[%d] = %d", scriptCode[pc], stack[stackIdx - 1]); varNum = scriptCode[pc++]; - if (SwordEngine::_systemVars.isDemo && SwordEngine::isPc()) { + if (SwordEngine::_systemVars.isDemo && SwordEngine::isWindows()) { if (varNum >= 397) // BS1 Demo has different number of script variables varNum++; if (varNum >= 699) @@ -959,7 +959,7 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3 // meantime, we don't want any looping sound effects still playing. _sound->quitScreen(); - MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _mixer, _system); + MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _mixer, _system); if (player) { _screen->clearScreen(); if (player->load(sequenceId)) diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index b74cd8c393..3574074b00 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -62,11 +62,22 @@ Sound::~Sound() { _mixer->stopAll(); for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) if (_fxQueue[cnt].delay == 0) - _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId); + _resMan->resClose(getSampleId(_fxQueue[cnt].id)); _endOfQueue = 0; closeCowSystem(); } +uint32 Sound::getSampleId(int32 fxNo) { + byte cluster = _fxList[fxNo].sampleId.cluster; + byte id; + if (SwordEngine::_systemVars.isDemo && SwordEngine::_systemVars.platform == Common::kPlatformWindows) { + id = _fxList[fxNo].sampleId.idWinDemo; + } else { + id = _fxList[fxNo].sampleId.idStd; + } + return (cluster << 24) | id; +} + void Sound::checkSpeechFileEndianness() { // Some mac versions (not all of them) use big endian wav, although // the wav header doesn't indicate it. @@ -154,14 +165,18 @@ int Sound::addToQueue(int32 fxNo) { warning("Sound queue overflow"); return 0; } - _resMan->resOpen(_fxList[fxNo].sampleId); - _fxQueue[_endOfQueue].id = fxNo; - if (_fxList[fxNo].type == FX_SPOT) - _fxQueue[_endOfQueue].delay = _fxList[fxNo].delay + 1; - else - _fxQueue[_endOfQueue].delay = 1; - _endOfQueue++; - return 1; + uint32 sampleId = getSampleId(fxNo); + if ((sampleId & 0xFF) != 0xFF) { + _resMan->resOpen(sampleId); + _fxQueue[_endOfQueue].id = fxNo; + if (_fxList[fxNo].type == FX_SPOT) + _fxQueue[_endOfQueue].delay = _fxList[fxNo].delay + 1; + else + _fxQueue[_endOfQueue].delay = 1; + _endOfQueue++; + return 1; + } + return 0; } return 0; } @@ -186,7 +201,7 @@ void Sound::engine() { playSample(&_fxQueue[cnt2]); } else { if (!_mixer->isSoundHandleActive(_fxQueue[cnt2].handle)) { // sound finished - _resMan->resClose(_fxList[_fxQueue[cnt2].id].sampleId); + _resMan->resClose(getSampleId(_fxQueue[cnt2].id)); if (cnt2 != _endOfQueue - 1) _fxQueue[cnt2] = _fxQueue[_endOfQueue - 1]; _endOfQueue--; @@ -200,7 +215,7 @@ void Sound::fnStopFx(int32 fxNo) { for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) if (_fxQueue[cnt].id == (uint32)fxNo) { if (!_fxQueue[cnt].delay) // sound was started - _resMan->resClose(_fxList[_fxQueue[cnt].id].sampleId); + _resMan->resClose(getSampleId(_fxQueue[cnt].id)); if (cnt != _endOfQueue - 1) _fxQueue[cnt] = _fxQueue[_endOfQueue - 1]; _endOfQueue--; @@ -243,7 +258,7 @@ void Sound::quitScreen() { } void Sound::playSample(QueueElement *elem) { - uint8 *sampleData = (uint8 *)_resMan->fetchRes(_fxList[elem->id].sampleId); + uint8 *sampleData = (uint8 *)_resMan->fetchRes(getSampleId(elem->id)); for (uint16 cnt = 0; cnt < MAX_ROOMS_PER_FX; cnt++) { if (_fxList[elem->id].roomVolList[cnt].roomNo) { if ((_fxList[elem->id].roomVolList[cnt].roomNo == (int)Logic::_scriptVars[SCREEN]) || diff --git a/engines/sword1/sound.h b/engines/sword1/sound.h index 112ae5b6aa..4e1ac7ba34 100644 --- a/engines/sword1/sound.h +++ b/engines/sword1/sound.h @@ -53,8 +53,15 @@ struct RoomVol { int32 roomNo, leftVol, rightVol; }; +struct SampleId { + byte cluster; + byte idStd; + byte idWinDemo; +}; + struct FxDef { - uint32 sampleId, type, delay; + SampleId sampleId; + uint32 type, delay; RoomVol roomVolList[MAX_ROOMS_PER_FX]; }; @@ -100,6 +107,7 @@ private: void playSample(QueueElement *elem); void initCowSystem(); + uint32 getSampleId(int32 fxNo); int16 *uncompressSpeech(uint32 index, uint32 cSize, uint32 *size); void calcWaveVolume(int16 *data, uint32 length); bool _waveVolume[WAVE_VOL_TAB_LENGTH]; diff --git a/engines/sword1/staticres.cpp b/engines/sword1/staticres.cpp index 60c6877232..5dabce1301 100644 --- a/engines/sword1/staticres.cpp +++ b/engines/sword1/staticres.cpp @@ -2894,7 +2894,7 @@ const char Music::_tuneList[TOTAL_TUNES][8] = { const FxDef Sound::_fxList[312] = { // 0 { - 0, // sampleId + {0,0,0}, // sampleId 0, // type (FX_LOOP, FX_RANDOM or FX_SPOT) 0, // delay (random chance for FX_RANDOM sound fx) { // roomVolList diff --git a/engines/sword1/sword1.h b/engines/sword1/sword1.h index e973c12754..ccdc2d3a59 100644 --- a/engines/sword1/sword1.h +++ b/engines/sword1/sword1.h @@ -90,7 +90,7 @@ public: static bool isMac() { return _systemVars.platform == Common::kPlatformMacintosh; } static bool isPsx() { return _systemVars.platform == Common::kPlatformPSX; } - static bool isPc() { return _systemVars.platform == Common::kPlatformPC; } + static bool isWindows() { return _systemVars.platform == Common::kPlatformWindows ; } protected: // Engine APIs diff --git a/engines/sword1/swordres.h b/engines/sword1/swordres.h index 384c240283..b1fc206b80 100644 --- a/engines/sword1/swordres.h +++ b/engines/sword1/swordres.h @@ -1298,66 +1298,66 @@ namespace Sword1 { // 2 entities in TXTs, 2 in datafiles. // paris_1 // sound_fx -#define FX_CAMERA1 0x06000000 -#define FX_CAMERA2 0x06000001 -#define FX_CAMERA3 0x06000002 -#define FX_CANDO 0x06000003 -#define FX_CANUP 0x06000004 -#define FX_CAW1 0x06000005 -#define FX_DUST 0x06000006 -#define FX_HORN1 0x06000007 -#define FX_HORN2 0x06000008 -#define FX_HORN3 0x06000009 -#define FX_LVSFLY 0x0600000A -#define FX_PAP1 0x0600000B -#define FX_PAP2 0x0600000C -#define FX_PICK1 0x0600000D -#define FX_PICK2 0x0600000E -#define FX_PICK3 0x0600000F -#define FX_PICK4 0x06000010 -#define FX_PICK5 0x06000011 -#define FX_TRAFFIC2 0x06000012 -#define FX_TWEET1 0x06000013 -#define FX_TWEET2 0x06000014 -#define FX_TWEET3 0x06000015 -#define FX_TWEET4 0x06000016 -#define FX_TWEET5 0x06000017 -#define FX_BIN1 0x06000018 -#define FX_BIN2 0x06000019 -#define FX_BIN3 0x0600001A -#define FX_CAT 0x0600001B -#define FX_COVERON2 0x0600001C -#define FX_CRATE 0x0600001D -#define FX_DRAIN 0x0600001E -#define FX_HOLE 0x0600001F -#define FX_BODY 0x06000020 -#define FX_BOTDN 0x06000021 -#define FX_BOTUP 0x06000022 -#define FX_GULP 0x06000023 -#define FX_LIGHT 0x06000024 -#define FX_PIKUP 0x06000025 -#define FX_PAP3 0x06000026 -#define FX_PAP4 0x06000027 -#define FX_PAP5 0x06000028 -#define FX_PISTOL 0x06000029 -#define FX_TBOX 0x0600002A -#define FX_KNOKKNOK 0x0600002B -#define FX_ALBCLO 0x0600002C -#define FX_ALBOP 0x0600002D -#define FX_LADD1 0x0600002E -#define FX_LADD2 0x0600002F -#define FX_LADD3 0x06000030 -#define FX_RAT1 0x06000031 -#define FX_RAT2 0x06000032 -#define FX_SEWSTEP1 0x06000033 -#define FX_SEWSTEP2 0x06000034 -#define FX_SWATER3 0x06000035 -#define FX_DRIP1 0x06000036 -#define FX_DRIP2 0x06000037 -#define FX_DRIP3 0x06000038 -#define FX_SWATER1 0x06000039 -#define FX_SEWLADD7 0x0600003A -#define FX_SEWLADU7 0x0600003B +#define FX_CAMERA1 {0x06,0x00,0x00} +#define FX_CAMERA2 {0x06,0x01,0x01} +#define FX_CAMERA3 {0x06,0x02,0x02} +#define FX_CANDO {0x06,0x03,0x03} +#define FX_CANUP {0x06,0x04,0x04} +#define FX_CAW1 {0x06,0x05,0x05} +#define FX_DUST {0x06,0x06,0x06} +#define FX_HORN1 {0x06,0x07,0x07} +#define FX_HORN2 {0x06,0x08,0x08} +#define FX_HORN3 {0x06,0x09,0x09} +#define FX_LVSFLY {0x06,0x0A,0xFF} +#define FX_PAP1 {0x06,0x0B,0x0A} +#define FX_PAP2 {0x06,0x0C,0x0B} +#define FX_PICK1 {0x06,0x0D,0x0C} +#define FX_PICK2 {0x06,0x0E,0x0D} +#define FX_PICK3 {0x06,0x0F,0x0E} +#define FX_PICK4 {0x06,0x10,0x0F} +#define FX_PICK5 {0x06,0x11,0x10} +#define FX_TRAFFIC2 {0x06,0x12,0x11} +#define FX_TWEET1 {0x06,0x13,0x12} +#define FX_TWEET2 {0x06,0x14,0x13} +#define FX_TWEET3 {0x06,0x15,0x14} +#define FX_TWEET4 {0x06,0x16,0x15} +#define FX_TWEET5 {0x06,0x17,0x16} +#define FX_BIN1 {0x06,0x18,0x17} +#define FX_BIN2 {0x06,0x19,0x18} +#define FX_BIN3 {0x06,0x1A,0x19} +#define FX_CAT {0x06,0x1B,0x1A} +#define FX_COVERON2 {0x06,0x1C,0x1B} +#define FX_CRATE {0x06,0x1D,0x1C} +#define FX_DRAIN {0x06,0x1E,0x1D} +#define FX_HOLE {0x06,0x1F,0x1E} +#define FX_BODY {0x06,0x20,0x1F} +#define FX_BOTDN {0x06,0x21,0x20} +#define FX_BOTUP {0x06,0x22,0x21} +#define FX_GULP {0x06,0x23,0x22} +#define FX_LIGHT {0x06,0x24,0x23} +#define FX_PIKUP {0x06,0x25,0x24} +#define FX_PAP3 {0x06,0x26,0x25} +#define FX_PAP4 {0x06,0x27,0x26} +#define FX_PAP5 {0x06,0x28,0x27} +#define FX_PISTOL {0x06,0x29,0x28} +#define FX_TBOX {0x06,0x2A,0x29} +#define FX_KNOKKNOK {0x06,0x2B,0x2A} +#define FX_ALBCLO {0x06,0x2C,0x2B} +#define FX_ALBOP {0x06,0x2D,0x2C} +#define FX_LADD1 {0x06,0x2E,0x2D} +#define FX_LADD2 {0x06,0x2F,0x2E} +#define FX_LADD3 {0x06,0x30,0x2F} +#define FX_RAT1 {0x06,0x31,0x30} +#define FX_RAT2 {0x06,0x32,0x31} +#define FX_SEWSTEP1 {0x06,0x33,0x32} +#define FX_SEWSTEP2 {0x06,0x34,0x33} +#define FX_SWATER3 {0x06,0x35,0x34} +#define FX_DRIP1 {0x06,0x36,0x35} +#define FX_DRIP2 {0x06,0x37,0x36} +#define FX_DRIP3 {0x06,0x38,0x37} +#define FX_SWATER1 {0x06,0x39,0x38} +#define FX_SEWLADD7 {0x06,0x3A,0xFF} +#define FX_SEWLADU7 {0x06,0x3B,0x39} // 60 entities in TXTs, 60 in datafiles. // room1 #define PARIS1_PAL 0x06010000 @@ -1767,52 +1767,52 @@ namespace Sword1 { // 8 entities in TXTs, 8 in datafiles. // paris_2 // sound_fx -#define FX_BIRD 0x07000000 -#define FX_BIRD2 0x07000001 -#define FX_CARLTON 0x07000002 -#define FX_CARS 0x07000003 -#define FX_DOORTRY 0x07000004 -#define FX_FIESTA 0x07000005 -#define FX_FLATDOOR 0x07000006 -#define FX_HVYVEHR 0x07000007 -#define FX_HVYVEHL 0x07000008 -#define FX_LITEVEHR 0x07000009 -#define FX_LITEVEHL 0x0700000A -#define FX_FONEUP 0x0700000B -#define FX_FONEDN 0x0700000C -#define FX_GEOCCH 0x0700000D -#define FX_GEOCHAIR 0x0700000E -#define FX_GEOCHR9 0x0700000F -#define FX_NICOPEN 0x07000010 -#define FX_NICLOSE 0x07000011 -#define FX_PHONICO1 0x07000012 -#define FX_GRAMOFON 0x07000013 -#define FX_SHOCK1 0x07000014 -#define FX_WINDUP11 0x07000015 -#define FX_FRISK 0x07000016 -#define FX_TRAFFIC3 0x07000017 -#define FX_DESKBELL 0x07000018 -#define FX_KEY13 0x07000019 -#define FX_PAPER6 0x0700001A -#define FX_PHONEDN2 0x0700001B -#define FX_PHONEUP2 0x0700001C -#define FX_PIANO14 0x0700001D -#define FX_TRYDOR14 0x0700001E -#define FX_CABCLOSE 0x0700001F -#define FX_CABOPEN 0x07000020 -#define FX_DORCLOSE 0x07000021 -#define FX_WINDOPEN 0x07000022 -#define FX_COO 0x07000023 -#define FX_COO2 0x07000024 -#define FX_LEDGE1 0x07000025 -#define FX_LEDGE2 0x07000026 -#define FX_BRIEFOFF 0x07000027 -#define FX_BRIEFON 0x07000028 -#define FX_JUMPIN 0x07000029 -#define FX_WARDIN 0x0700002A -#define FX_WARDOUT 0x0700002B -#define FX_CLIMBIN 0x0700002C -#define FX_CLIMBOUT 0x0700002D +#define FX_BIRD {0x07,0x00,0x00} +#define FX_BIRD2 {0x07,0x01,0x01} +#define FX_CARLTON {0x07,0x02,0x02} +#define FX_CARS {0x07,0x03,0x03} +#define FX_DOORTRY {0x07,0x04,0x04} +#define FX_FIESTA {0x07,0x05,0x05} +#define FX_FLATDOOR {0x07,0x06,0x06} +#define FX_HVYVEHR {0x07,0x07,0xFF} +#define FX_HVYVEHL {0x07,0x08,0xFF} +#define FX_LITEVEHR {0x07,0x09,0xFF} +#define FX_LITEVEHL {0x07,0x0A,0xFF} +#define FX_FONEUP {0x07,0x0B,0x07} +#define FX_FONEDN {0x07,0x0C,0x08} +#define FX_GEOCCH {0x07,0x0D,0x09} +#define FX_GEOCHAIR {0x07,0x0E,0x0A} +#define FX_GEOCHR9 {0x07,0x0F,0x0B} +#define FX_NICOPEN {0x07,0x10,0x0D} +#define FX_NICLOSE {0x07,0x11,0x0E} +#define FX_PHONICO1 {0x07,0x12,0x0F} +#define FX_GRAMOFON {0x07,0x13,0x10} +#define FX_SHOCK1 {0x07,0x14,0x11} +#define FX_WINDUP11 {0x07,0x15,0x12} +#define FX_FRISK {0x07,0x16,0x13} +#define FX_TRAFFIC3 {0x07,0x17,0x14} +#define FX_DESKBELL {0x07,0x18,0x15} +#define FX_KEY13 {0x07,0x19,0xFF} +#define FX_PAPER6 {0x07,0x1A,0x16} +#define FX_PHONEDN2 {0x07,0x1B,0x17} +#define FX_PHONEUP2 {0x07,0x1C,0x18} +#define FX_PIANO14 {0x07,0x1D,0x19} +#define FX_TRYDOR14 {0x07,0x1E,0x1A} +#define FX_CABCLOSE {0x07,0x1F,0x1B} +#define FX_CABOPEN {0x07,0x20,0x1C} +#define FX_DORCLOSE {0x07,0x21,0x1D} +#define FX_WINDOPEN {0x07,0x22,0x1E} +#define FX_COO {0x07,0x23,0x1F} +#define FX_COO2 {0x07,0x24,0x20} +#define FX_LEDGE1 {0x07,0x25,0x21} +#define FX_LEDGE2 {0x07,0x26,0x22} +#define FX_BRIEFOFF {0x07,0x27,0x23} +#define FX_BRIEFON {0x07,0x28,0x24} +#define FX_JUMPIN {0x07,0x29,0x25} +#define FX_WARDIN {0x07,0x2A,0x26} +#define FX_WARDOUT {0x07,0x2B,0x27} +#define FX_CLIMBIN {0x07,0x2C,0x28} +#define FX_CLIMBOUT {0x07,0x2D,0x29} // 46 entities in TXTs, 46 in datafiles. // room9 #define PARIS2_PAL 0x07010000 @@ -2349,38 +2349,38 @@ namespace Sword1 { // 9 entities in TXTs, 9 in datafiles. // paris_3 // sound_fx -#define FX_MUESEXT 0x08000000 -#define FX_AIRCON28 0x08000001 -#define FX_SARCO28A 0x08000002 -#define FX_SARCO28B 0x08000003 -#define FX_SARCO28C 0x08000004 -#define FX_TOTEM28A 0x08000005 -#define FX_ALARM 0x08000006 -#define FX_CARABINE 0x08000007 -#define FX_DOOR29 0x08000008 -#define FX_FISHFALL 0x08000009 -#define FX_GDROP29 0x0800000A -#define FX_GUI_HIT 0x0800000B -#define FX_GUN1 0x0800000C -#define FX_ROPEDOWN 0x0800000D -#define FX_SARCO29 0x0800000E -#define FX_SMASHGLA 0x0800000F -#define FX_TOTEM29A 0x08000010 -#define FX_TOTEM29B 0x08000011 -#define FX_HOSPEXT 0x08000012 -#define FX_GRAVEL1 0x08000013 -#define FX_GRAVEL2 0x08000014 -#define FX_HOSPNOIS 0x08000015 -#define FX_CUPBOPEN 0x08000016 -#define FX_CUPBCLOS 0x08000017 -#define FX_KIKSHINY 0x08000018 -#define FX_SHINY 0x08000019 -#define FX_SHINYOFF 0x0800001A -#define FX_SHINYON 0x0800001B -#define FX_BLOODPRE 0x0800001C -#define FX_GUN34 0x0800001D -#define FX_PULSE2 0x0800001E -#define FX_PULSE3 0x0800001F +#define FX_MUESEXT {0x08,0x00,0x00} +#define FX_AIRCON28 {0x08,0x01,0x01} +#define FX_SARCO28A {0x08,0x02,0x02} +#define FX_SARCO28B {0x08,0x03,0x03} +#define FX_SARCO28C {0x08,0x04,0x04} +#define FX_TOTEM28A {0x08,0x05,0x05} +#define FX_ALARM {0x08,0x06,0x06} +#define FX_CARABINE {0x08,0x07,0x07} +#define FX_DOOR29 {0x08,0x08,0x08} +#define FX_FISHFALL {0x08,0x09,0x09} +#define FX_GDROP29 {0x08,0x0A,0x0A} +#define FX_GUI_HIT {0x08,0x0B,0x0B} +#define FX_GUN1 {0x08,0x0C,0x0C} +#define FX_ROPEDOWN {0x08,0x0D,0x0D} +#define FX_SARCO29 {0x08,0x0E,0x0E} +#define FX_SMASHGLA {0x08,0x0F,0x0F} +#define FX_TOTEM29A {0x08,0x10,0x10} +#define FX_TOTEM29B {0x08,0x11,0x11} +#define FX_HOSPEXT {0x08,0x12,0x12} +#define FX_GRAVEL1 {0x08,0x13,0x13} +#define FX_GRAVEL2 {0x08,0x14,0x14} +#define FX_HOSPNOIS {0x08,0x15,0x15} +#define FX_CUPBOPEN {0x08,0x16,0x16} +#define FX_CUPBCLOS {0x08,0x17,0x17} +#define FX_KIKSHINY {0x08,0x18,0xFF} +#define FX_SHINY {0x08,0x19,0x18} +#define FX_SHINYOFF {0x08,0x1A,0x19} +#define FX_SHINYON {0x08,0x1B,0x1A} +#define FX_BLOODPRE {0x08,0x1C,0x1B} +#define FX_GUN34 {0x08,0x1D,0x1C} +#define FX_PULSE2 {0x08,0x1E,0x1D} +#define FX_PULSE3 {0x08,0x1F,0x1E} // 32 entities in TXTs, 32 in datafiles. // benoir #define MEGABEN 0x08010000 @@ -2794,29 +2794,29 @@ namespace Sword1 { // 30 entities in TXTs, 30 in datafiles. // paris_4 // sound_fx -#define FX_COVDWN 0x09000000 -#define FX_KEYIN 0x09000001 -#define FX_MANOP36 0x09000002 -#define FX_MONTAMB 0x09000003 -#define FX_OOH 0x09000004 -#define FX_PULLUP36 0x09000005 -#define FX_REPLCE36 0x09000006 -#define FX_AMBIEN37 0x09000007 -#define FX_CHAIN37 0x09000008 -#define FX_CHAIN37B 0x09000009 -#define FX_DOOR37 0x0900000A -#define FX_HOLE37 0x0900000B -#define FX_KNOCK37 0x0900000C -#define FX_KNOCK37B 0x0900000D -#define FX_WINCH37 0x0900000E -#define FX_AIRCON41 0x0900000F -#define FX_FONEDN41 0x09000010 -#define FX_FONEUP41 0x09000011 -#define FX_PHONCALL 0x09000012 -#define FX_THERMO1 0x09000013 -#define FX_TAPDRIP 0x09000014 -#define FX_DRIER1 0x09000015 -#define FX_CHURCHFX 0x09000016 +#define FX_COVDWN {0x09,0x00,0xFF} +#define FX_KEYIN {0x09,0x01,0xFF} +#define FX_MANOP36 {0x09,0x02,0x00} +#define FX_MONTAMB {0x09,0x03,0x01} +#define FX_OOH {0x09,0x04,0x02} +#define FX_PULLUP36 {0x09,0x05,0x03} +#define FX_REPLCE36 {0x09,0x06,0x04} +#define FX_AMBIEN37 {0x09,0x07,0x05} +#define FX_CHAIN37 {0x09,0x08,0x06} +#define FX_CHAIN37B {0x09,0x09,0x06} +#define FX_DOOR37 {0x09,0x0A,0x07} +#define FX_HOLE37 {0x09,0x0B,0x08} +#define FX_KNOCK37 {0x09,0x0C,0x09} +#define FX_KNOCK37B {0x09,0x0D,0x0A} +#define FX_WINCH37 {0x09,0x0E,0x0B} +#define FX_AIRCON41 {0x09,0x0F,0x0C} +#define FX_FONEDN41 {0x09,0x10,0x0D} +#define FX_FONEUP41 {0x09,0x11,0x0E} +#define FX_PHONCALL {0x09,0x12,0x0F} +#define FX_THERMO1 {0x09,0x13,0x10} +#define FX_TAPDRIP {0x09,0x14,0xFF} +#define FX_DRIER1 {0x09,0x15,0x11} +#define FX_CHURCHFX {0x09,0x16,0x12} // 23 entities in TXTs, 23 in datafiles. // room36 #define R36SPRPAL 0x09010000 @@ -3302,56 +3302,56 @@ namespace Sword1 { // 39 entities in TXTs, 39 in datafiles. // ireland // sound_fx -#define FX_EIRBIRD3 0x0A000000 -#define FX_SHOCK2 0x0A000001 -#define FX_EIRBIRD1 0x0A000002 -#define FX_EIRBIRD2 0x0A000003 -#define FX_SWITCH19 0x0A000004 -#define FX_TRAPOPEN 0x0A000005 -#define FX_VIOLIN19 0x0A000006 -#define FX_WHISTLE 0x0A000007 -#define FX_BARFLAP 0x0A000008 -#define FX_DORCLOSE20 0x0A000009 -#define FX_DRINK 0x0A00000A -#define FX_FITZHIT 0x0A00000B -#define FX_FITZRUN 0x0A00000C -#define FX_FITZUP 0x0A00000D -#define FX_FUSE20 0x0A00000E -#define FX_PULLPINT 0x0A00000F -#define FX_SNEEZE1 0x0A000010 -#define FX_SNEEZE2 0x0A000011 -#define FX_WASHER 0x0A000012 -#define FX_CELTAP 0x0A000013 -#define FX_DRIPIRE 0x0A000014 -#define FX_DRIPIRE2 0x0A000015 -#define FX_TAP 0x0A000016 -#define FX_TAP2 0x0A000017 -#define FX_CLIMBHAY 0x0A000018 -#define FX_FARMERGO 0x0A000019 -#define FX_CASTLWAL 0x0A00001A -#define FX_CLIMBFAL 0x0A00001B -#define FX_KEYSTEP 0x0A00001C -#define FX_WIND 0x0A00001D -#define FX_GEOGOAT 0x0A00001E -#define FX_GOATBAA 0x0A00001F -#define FX_GOATCHEW 0x0A000020 -#define FX_GOATDOH 0x0A000021 -#define FX_PLOUGH 0x0A000022 -#define FX_EIRDRIP1 0x0A000023 -#define FX_EIRDRIP2 0x0A000024 -#define FX_LADDWN25 0x0A000025 -#define FX_LADDUP25 0x0A000026 -#define FX_SECDOR25 0x0A000027 -#define FX_SLABFALL 0x0A000028 -#define FX_SLABUP 0x0A000029 -#define FX_TRIGER25 0x0A00002A -#define FX_WRING 0x0A00002B -#define FX_LEVER 0x0A00002C -#define FX_LEVER2 0x0A00002D -#define FX_RAT3A 0x0A00002E -#define FX_RAT3B 0x0A00002F -#define FX_RAT3C 0x0A000030 -#define FX_RAT3D 0x0A000031 +#define FX_EIRBIRD3 {0x0A,0x00,0x00} +#define FX_SHOCK2 {0x0A,0x01,0x01} +#define FX_EIRBIRD1 {0x0A,0x02,0x02} +#define FX_EIRBIRD2 {0x0A,0x03,0x03} +#define FX_SWITCH19 {0x0A,0x04,0x04} +#define FX_TRAPOPEN {0x0A,0x05,0x05} +#define FX_VIOLIN19 {0x0A,0x06,0x06} +#define FX_WHISTLE {0x0A,0x07,0x07} +#define FX_BARFLAP {0x0A,0x08,0x08} +#define FX_DORCLOSE20 {0x0A,0x09,0x09} +#define FX_DRINK {0x0A,0x0A,0x0A} +#define FX_FITZHIT {0x0A,0x0B,0x0B} +#define FX_FITZRUN {0x0A,0x0C,0x0C} +#define FX_FITZUP {0x0A,0x0D,0x0D} +#define FX_FUSE20 {0x0A,0x0E,0x0E} +#define FX_PULLPINT {0x0A,0x0F,0x0F} +#define FX_SNEEZE1 {0x0A,0x10,0xFF} +#define FX_SNEEZE2 {0x0A,0x11,0xFF} +#define FX_WASHER {0x0A,0x12,0x10} +#define FX_CELTAP {0x0A,0x13,0x11} +#define FX_DRIPIRE {0x0A,0x14,0xFF} +#define FX_DRIPIRE2 {0x0A,0x15,0xFF} +#define FX_TAP {0x0A,0x16,0x12} +#define FX_TAP2 {0x0A,0x17,0x13} +#define FX_CLIMBHAY {0x0A,0x18,0x14} +#define FX_FARMERGO {0x0A,0x19,0x15} +#define FX_CASTLWAL {0x0A,0x1A,0x16} +#define FX_CLIMBFAL {0x0A,0x1B,0x17} +#define FX_KEYSTEP {0x0A,0x1C,0x18} +#define FX_WIND {0x0A,0x1D,0x19} +#define FX_GEOGOAT {0x0A,0x1E,0x1A} +#define FX_GOATBAA {0x0A,0x1F,0x1B} +#define FX_GOATCHEW {0x0A,0x20,0x1C} +#define FX_GOATDOH {0x0A,0x21,0x1D} +#define FX_PLOUGH {0x0A,0x22,0x1E} +#define FX_EIRDRIP1 {0x0A,0x23,0xFF} +#define FX_EIRDRIP2 {0x0A,0x24,0xFF} +#define FX_LADDWN25 {0x0A,0x25,0xFF} +#define FX_LADDUP25 {0x0A,0x26,0xFF} +#define FX_SECDOR25 {0x0A,0x27,0x21} +#define FX_SLABFALL {0x0A,0x28,0x22} +#define FX_SLABUP {0x0A,0x29,0x23} +#define FX_TRIGER25 {0x0A,0x2A,0x24} +#define FX_WRING {0x0A,0x2B,0x25} +#define FX_LEVER {0x0A,0x2C,0x26} +#define FX_LEVER2 {0x0A,0x2D,0x27} +#define FX_RAT3A {0x0A,0x2E,0x28} +#define FX_RAT3B {0x0A,0x2F,0x28} +#define FX_RAT3C {0x0A,0x30,0x28} +#define FX_RAT3D {0x0A,0x31,0x28} // 50 entities in TXTs, 50 in datafiles. // room19 #define R19SPRPAL 0x0A010000 @@ -3811,23 +3811,23 @@ namespace Sword1 { // 16 entities in TXTs, 16 in datafiles. // spain // sound_fx -#define FX_SPNBIRD1 0x0B000000 -#define FX_SPNBIRD2 0x0B000001 -#define FX_AMBIEN56 0x0B000002 -#define FX_DOGS56 0x0B000003 -#define FX_PENDULUM 0x0B000004 -#define FX_CANFALL 0x0B000005 -#define FX_HOSE57 0x0B000006 -#define FX_HOSE57B 0x0B000007 -#define FX_SPAIN 0x0B000008 -#define FX_CHESS 0x0B000009 -#define FX_SECDOR59 0x0B00000A -#define FX_WINDOW59 0x0B00000B -#define FX_LIONFALL 0x0B00000C -#define FX_LIONFAL2 0x0B00000D -#define FX_TOOTHPUL 0x0B00000E -#define FX_SECDOR61 0x0B00000F -#define FX_WELLDRIP 0x0B000010 +#define FX_SPNBIRD1 {0x0B,0x00,0x00} +#define FX_SPNBIRD2 {0x0B,0x01,0x01} +#define FX_AMBIEN56 {0x0B,0x02,0x02} +#define FX_DOGS56 {0x0B,0x03,0x03} +#define FX_PENDULUM {0x0B,0x04,0x04} +#define FX_CANFALL {0x0B,0x05,0x05} +#define FX_HOSE57 {0x0B,0x06,0x06} +#define FX_HOSE57B {0x0B,0x07,0x07} +#define FX_SPAIN {0x0B,0x08,0x08} +#define FX_CHESS {0x0B,0x09,0x09} +#define FX_SECDOR59 {0x0B,0x0A,0xFF} +#define FX_WINDOW59 {0x0B,0x0B,0xFF} +#define FX_LIONFALL {0x0B,0x0C,0x0B} +#define FX_LIONFAL2 {0x0B,0x0D,0x0C} +#define FX_TOOTHPUL {0x0B,0x0E,0x0D} +#define FX_SECDOR61 {0x0B,0x0F,0x0E} +#define FX_WELLDRIP {0x0B,0x10,0x0F} // 17 entities in TXTs, 17 in datafiles. // room56 #define SPAIN_PAL 0x0B010000 @@ -4186,34 +4186,34 @@ namespace Sword1 { // 8 entities in TXTs, 8 in datafiles. // syria // sound_fx -#define FX_CAMERA45 0x0C000000 -#define FX_SHOCK3 0x0C000001 -#define FX_STALLBEL 0x0C000002 -#define FX_AYUBDOOR 0x0C000003 -#define FX_BALLPLAY 0x0C000004 -#define FX_CATHIT 0x0C000005 -#define FX_MARIB 0x0C000006 -#define FX_NEWTON 0x0C000007 -#define FX_STALLCAT 0x0C000008 -#define FX_STATBREK 0x0C000009 -#define FX_KEYS49 0x0C00000A -#define FX_MANG1 0x0C00000B -#define FX_MANG2 0x0C00000C -#define FX_MANG3 0x0C00000D -#define FX_UNLOCK49 0x0C00000E -#define FX_WCCHAIN 0x0C00000F -#define FX_CUBDOR 0x0C000010 -#define FX_BREKSTIK 0x0C000011 -#define FX_CLIMBDWN 0x0C000012 -#define FX_CRICKET 0x0C000013 -#define FX_GEOFAL54 0x0C000014 -#define FX_KHANDOWN 0x0C000015 -#define FX_RINGPULL 0x0C000016 -#define FX_SECDOR54 0x0C000017 -#define FX_SHOTKHAN 0x0C000018 -#define FX_SYRIWIND 0x0C000019 -#define FX_THUMP1 0x0C00001A -#define FX_SECDOR55 0x0C00001B +#define FX_CAMERA45 {0x0C,0x00,0xFF} +#define FX_SHOCK3 {0x0C,0x01,0x00} +#define FX_STALLBEL {0x0C,0x02,0x01} +#define FX_AYUBDOOR {0x0C,0x03,0x02} +#define FX_BALLPLAY {0x0C,0x04,0x03} +#define FX_CATHIT {0x0C,0x05,0x04} +#define FX_MARIB {0x0C,0x06,0x05} +#define FX_NEWTON {0x0C,0x07,0x06} +#define FX_STALLCAT {0x0C,0x08,0x07} +#define FX_STATBREK {0x0C,0x09,0x08} +#define FX_KEYS49 {0x0C,0x0A,0x09} +#define FX_MANG1 {0x0C,0x0B,0x0A} +#define FX_MANG2 {0x0C,0x0C,0x0B} +#define FX_MANG3 {0x0C,0x0D,0x0C} +#define FX_UNLOCK49 {0x0C,0x0E,0x0D} +#define FX_WCCHAIN {0x0C,0x0F,0x0E} +#define FX_CUBDOR {0x0C,0x10,0x0F} +#define FX_BREKSTIK {0x0C,0x11,0x10} +#define FX_CLIMBDWN {0x0C,0x12,0x11} +#define FX_CRICKET {0x0C,0x13,0x12} +#define FX_GEOFAL54 {0x0C,0x14,0x13} +#define FX_KHANDOWN {0x0C,0x15,0x14} +#define FX_RINGPULL {0x0C,0x16,0x15} +#define FX_SECDOR54 {0x0C,0x17,0x16} +#define FX_SHOTKHAN {0x0C,0x18,0x17} +#define FX_SYRIWIND {0x0C,0x19,0x18} +#define FX_THUMP1 {0x0C,0x1A,0x19} +#define FX_SECDOR55 {0x0C,0x1B,0x1A} // 28 entities in TXTs, 28 in datafiles. // duane #define DUANE_MEGA 0x0C010000 @@ -4578,19 +4578,19 @@ namespace Sword1 { // 37 entities in TXTs, 37 in datafiles. // train // sound_fx -#define FX_SHOCK63 0x0D000000 -#define FX_TRAINEXT 0x0D000001 -#define FX_TRAININT 0x0D000002 -#define FX_DOOR65 0x0D000003 -#define FX_WIND66 0x0D000004 -#define FX_WINDOW66 0x0D000005 -#define FX_BRAKES 0x0D000006 -#define FX_DOOR69 0x0D000007 -#define FX_EKSHOOT 0x0D000008 -#define FX_FIGHT69 0x0D000009 -#define FX_PNEUMO69 0x0D00000A -#define FX_TICK69 0x0D00000B -#define FX_TRNPASS 0x0D00000C +#define FX_SHOCK63 {0x0D,0x00,0x00} +#define FX_TRAINEXT {0x0D,0x01,0x01} +#define FX_TRAININT {0x0D,0x02,0x02} +#define FX_DOOR65 {0x0D,0x03,0x03} +#define FX_WIND66 {0x0D,0x04,0x04} +#define FX_WINDOW66 {0x0D,0x05,0x05} +#define FX_BRAKES {0x0D,0x06,0x06} +#define FX_DOOR69 {0x0D,0x07,0x07} +#define FX_EKSHOOT {0x0D,0x08,0x08} +#define FX_FIGHT69 {0x0D,0x09,0xFF} +#define FX_PNEUMO69 {0x0D,0x0A,0x09} +#define FX_TICK69 {0x0D,0x0B,0x0A} +#define FX_TRNPASS {0x0D,0x0C,0x0B} // 13 entities in TXTs, 13 in datafiles. // room63 #define TRAIN_PAL 0x0D010000 @@ -4828,33 +4828,33 @@ namespace Sword1 { // 57 entities in TXTs, 57 in datafiles. // scotland // sound_fx -#define FX_WIND71 0x0E000000 -#define FX_GUST71 0x0E000001 -#define FX_OWL71A 0x0E000002 -#define FX_OWL71B 0x0E000003 -#define FX_COG72A 0x0E000004 -#define FX_PING 0x0E000005 -#define FX_RUMMAGE1 0x0E000006 -#define FX_RUMMAGE2 0x0E000007 -#define FX_SECDOR72 0x0E000008 -#define FX_CHANT 0x0E000009 -#define FX_DAGGER1 0x0E00000A -#define FX_GDROP73 0x0E00000B -#define FX_GUNPOWDR 0x0E00000C -#define FX_STAFF 0x0E00000D -#define FX_TORCH73 0x0E00000E -#define FX_BAPHAMB 0x0E00000F -#define FX_FIGHT1 0x0E000010 -#define FX_REFORGE2 0x0E000011 -#define FX_ROSSODIE 0x0E000012 -#define FX_GKSWORD 0x0E000013 -#define FX_REFORGE1 0x0E000014 -#define FX_REFORGE4 0x0E000015 -#define FX_CHOKE1 0x0E000016 -#define FX_CHOKE2 0x0E000017 -#define FX_EKDIES 0x0E000018 -#define FX_FIGHT2 0x0E000019 -#define FX_GUN79 0x0E00001A +#define FX_WIND71 {0x0E,0x00,0x00} +#define FX_GUST71 {0x0E,0x01,0x01} +#define FX_OWL71A {0x0E,0x02,0x02} +#define FX_OWL71B {0x0E,0x03,0x03} +#define FX_COG72A {0x0E,0x04,0x04} +#define FX_PING {0x0E,0x05,0x05} +#define FX_RUMMAGE1 {0x0E,0x06,0x06} +#define FX_RUMMAGE2 {0x0E,0x07,0x07} +#define FX_SECDOR72 {0x0E,0x08,0x08} +#define FX_CHANT {0x0E,0x09,0xFF} +#define FX_DAGGER1 {0x0E,0x0A,0x09} +#define FX_GDROP73 {0x0E,0x0B,0xFF} +#define FX_GUNPOWDR {0x0E,0x0C,0x0A} +#define FX_STAFF {0x0E,0x0D,0xFF} +#define FX_TORCH73 {0x0E,0x0E,0x0B} +#define FX_BAPHAMB {0x0E,0x0F,0xFF} +#define FX_FIGHT1 {0x0E,0x10,0xFF} +#define FX_REFORGE2 {0x0E,0x11,0xFF} +#define FX_ROSSODIE {0x0E,0x12,0x0C} +#define FX_GKSWORD {0x0E,0x13,0xFF} +#define FX_REFORGE1 {0x0E,0x14,0xFF} +#define FX_REFORGE4 {0x0E,0x15,0xFF} +#define FX_CHOKE1 {0x0E,0x16,0x0D} +#define FX_CHOKE2 {0x0E,0x17,0x0E} +#define FX_EKDIES {0x0E,0x18,0xFF} +#define FX_FIGHT2 {0x0E,0x19,0x0F} +#define FX_GUN79 {0x0E,0x1A,0x10} // 27 entities in TXTs, 27 in datafiles. // room71 #define R71L0 0x0E010000 diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp index 3b29b0333f..b0d4853e5e 100644 --- a/engines/sword25/gfx/image/renderedimage.cpp +++ b/engines/sword25/gfx/image/renderedimage.cpp @@ -152,7 +152,7 @@ RenderedImage::RenderedImage(uint width, uint height, bool &result) : _height(height) { _data = new byte[width * height * 4]; - Common::set_to(_data, &_data[width * height * 4], 0); + Common::fill(_data, &_data[width * height * 4], 0); _backSurface = Kernel::getInstance()->getGfx()->getSurface(); @@ -507,7 +507,7 @@ int *RenderedImage::scaleLine(int size, int srcSize) { int scale = 100 * size / srcSize; assert(scale > 0); int *v = new int[size]; - Common::set_to(v, &v[size], 0); + Common::fill(v, &v[size], 0); int distCtr = 0; int *destP = v; diff --git a/engines/teenagent/callbacks.cpp b/engines/teenagent/callbacks.cpp index f8bb142bd8..8882531d27 100644 --- a/engines/teenagent/callbacks.cpp +++ b/engines/teenagent/callbacks.cpp @@ -3110,7 +3110,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) { playSound(67, 4); playActorAnimation(680); SET_FLAG(0xDBB8, 0); - } else if (CHECK_FLAG(0xDBB8, 1)) { + } else if (CHECK_FLAG(0xDBB7, 1)) { processCallback(0x6b86); } else if (CHECK_FLAG(0xDBB9, 1)) { processCallback(0x6b86); @@ -3177,7 +3177,7 @@ bool TeenAgentEngine::processCallback(uint16 addr) { playSound(67, 5); playActorAnimation(688); SET_FLAG(0xdbbc, 0); - } else if (CHECK_FLAG(0xdbbc, 1)) { + } else if (CHECK_FLAG(0xdbbb, 1)) { processCallback(0x6b86); } else { playSound(66, 6); @@ -3221,7 +3221,8 @@ bool TeenAgentEngine::processCallback(uint16 addr) { return true; case 0x6c83: - Dialog::pop(scene, 0xdb2e, 0, 0, 0xd1, 0xef, 0, 1); + waitLanAnimationFrame(1, 1); + Dialog::pop(scene, 0xdb2e, 0, 727, 0xd1, 0xef, 0, 1); scene->getObject(1)->setName((const char *)res->dseg.ptr(0xaa94)); SET_FLAG(0xDBD1, 1); return true; @@ -3557,8 +3558,9 @@ bool TeenAgentEngine::processCallback(uint16 addr) { playSound(5, 39); displayAsyncMessage(0x5124, 40388, 9, 35, 0xd0); playActorAnimation(728); - //fixme: add 727 animation - Dialog::show(scene, 0x3d17, 0, 0, 0xd1, 0xef, 0, 1); + + waitLanAnimationFrame(1, 1); + Dialog::show(scene, 0x3d17, 0, 727, 0xd1, 0xef, 0, 1); SET_FLAG(0xDBD2, 1); processCallback(0x9175); return true; @@ -3572,13 +3574,14 @@ bool TeenAgentEngine::processCallback(uint16 addr) { return true; } displayMessage(0x5138); - waitLanAnimationFrame(1, 1); + waitLanAnimationFrame(1, 1); playSound(5, 3); playSound(5, 23); playActorAnimation(729); - //fixme: add 727 animation - Dialog::show(scene, 0x3d70, 0, 0, 0xd1, 0xef, 0, 1); + + waitLanAnimationFrame(1, 1); + Dialog::show(scene, 0x3d70, 0, 727, 0xd1, 0xef, 0, 1); SET_FLAG(0xDBD3, 1); processCallback(0x9175); return true; @@ -3597,8 +3600,9 @@ bool TeenAgentEngine::processCallback(uint16 addr) { playSound(5, 3); playSound(5, 25); playActorAnimation(730); - //fixme: add 727 animation - Dialog::show(scene, 0x3dd6, 0, 0, 0xd1, 0xef, 0, 1); + + waitLanAnimationFrame(1, 1); + Dialog::show(scene, 0x3dd6, 0, 727, 0xd1, 0xef, 0, 1); SET_FLAG(0xDBD4, 1); processCallback(0x9175); return true; diff --git a/engines/teenagent/console.cpp b/engines/teenagent/console.cpp index 5164b44729..9ab6001d54 100644 --- a/engines/teenagent/console.cpp +++ b/engines/teenagent/console.cpp @@ -25,10 +25,13 @@ namespace TeenAgent { Console::Console(TeenAgentEngine *engine) : _engine(engine) { - DCmd_Register("enable_object", WRAP_METHOD(Console, enableObject)); - DCmd_Register("disable_object", WRAP_METHOD(Console, enableObject)); - DCmd_Register("set_ons", WRAP_METHOD(Console, setOns)); - DCmd_Register("set_music", WRAP_METHOD(Console, setMusic)); + DCmd_Register("enable_object", WRAP_METHOD(Console, enableObject)); + DCmd_Register("disable_object", WRAP_METHOD(Console, enableObject)); + DCmd_Register("set_ons", WRAP_METHOD(Console, setOns)); + DCmd_Register("set_music", WRAP_METHOD(Console, setMusic)); + DCmd_Register("animation", WRAP_METHOD(Console, playAnimation)); + DCmd_Register("actor_animation", WRAP_METHOD(Console, playActorAnimation)); + DCmd_Register("call", WRAP_METHOD(Console, call)); } bool Console::enableObject(int argc, const char **argv) { @@ -97,13 +100,66 @@ bool Console::setMusic(int argc, const char **argv) { DebugPrintf("usage: %s index(1-11)\n", argv[0]); return true; } + int index = atoi(argv[1]); if (index <= 0 || index > 11) { DebugPrintf("invalid value\n"); return true; } + _engine->setMusic(index); return true; } +bool Console::playAnimation(int argc, const char **argv) { + if (argc < 3) { + DebugPrintf("usage: %s id slot(0-3)\n", argv[0]); + return true; + } + + int id = atoi(argv[1]); + int slot = atoi(argv[2]); + if (id < 0 || slot < 0 || slot > 3) { + DebugPrintf("invalid slot or animation id\n"); + return true; + } + + _engine->playAnimation(id, slot); + return true; +} + +bool Console::playActorAnimation(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("usage: %s id\n", argv[0]); + return true; + } + + int id = atoi(argv[1]); + if (id < 0) { + DebugPrintf("invalid animation id\n"); + return true; + } + + _engine->playActorAnimation(id); + return true; +} + +bool Console::call(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("usage: %s 0xHEXADDR\n", argv[0]); + return true; + } + + uint addr; + if (sscanf(argv[1], "0x%x", &addr) != 1) { + DebugPrintf("invalid address\n"); + return true; + } + + if (!_engine->processCallback(addr)) + DebugPrintf("calling callback %04x failed\n", addr); + + return true; +} + } diff --git a/engines/teenagent/console.h b/engines/teenagent/console.h index ab2f068520..4dbdd3fc07 100644 --- a/engines/teenagent/console.h +++ b/engines/teenagent/console.h @@ -36,6 +36,9 @@ private: bool enableObject(int argc, const char **argv); bool setOns(int argc, const char **argv); bool setMusic(int argc, const char **argv); + bool playAnimation(int argc, const char **argv); + bool playActorAnimation(int argc, const char **argv); + bool call(int argc, const char **argv); TeenAgentEngine *_engine; }; diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp index cf58df1344..dad876dd97 100644 --- a/engines/teenagent/detection.cpp +++ b/engines/teenagent/detection.cpp @@ -74,7 +74,7 @@ static const ADGameDescription teenAgentGameDescriptions[] = { Common::CZ_CZE, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, AD_TABLE_END_MARKER, }; diff --git a/engines/testbed/detection.cpp b/engines/testbed/detection.cpp index 356d75f7ea..02a9dfcb87 100644 --- a/engines/testbed/detection.cpp +++ b/engines/testbed/detection.cpp @@ -40,7 +40,7 @@ static const ADGameDescription testbedDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, AD_TABLE_END_MARKER }; diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h index 9175f9fa17..be44b1c462 100644 --- a/engines/tinsel/detection_tables.h +++ b/engines/tinsel/detection_tables.h @@ -62,7 +62,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -82,7 +82,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -210,7 +210,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -232,7 +232,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -257,7 +257,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -281,7 +281,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -304,7 +304,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -327,7 +327,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -347,7 +347,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -367,7 +367,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::HE_ISR, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -386,7 +386,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPSX, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -409,7 +409,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPSX, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -430,7 +430,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -452,7 +452,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, @@ -471,7 +471,7 @@ static const TinselGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - GUIO1(GUIO_NONE) + GUIO0() }, GID_DW1, 0, diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp index 6a5d626de8..545310185c 100644 --- a/engines/tinsel/graphics.cpp +++ b/engines/tinsel/graphics.cpp @@ -478,9 +478,9 @@ static void t2WrtNonZero(DRAWOBJECT *pObj, uint8 *srcP, uint8 *destP, bool apply // Non-transparent run length color += pObj->constant; if (horizFlipped) - Common::set_to(tempP - runLength + 1, tempP + 1, color); + Common::fill(tempP - runLength + 1, tempP + 1, color); else - Common::set_to(tempP, tempP + runLength, color); + Common::fill(tempP, tempP + runLength, color); } } @@ -533,7 +533,7 @@ static void WrtConst(DRAWOBJECT *pObj, uint8 *destP, bool applyClipping) { // Loop through any remaining lines while (pObj->height > 0) { - Common::set_to(destP, destP + pObj->width, pObj->constant); + Common::fill(destP, destP + pObj->width, pObj->constant); --pObj->height; destP += SCREEN_WIDTH; diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp index d6478f5cae..f552c49491 100644 --- a/engines/tinsel/music.cpp +++ b/engines/tinsel/music.cpp @@ -485,6 +485,7 @@ PCMMusicPlayer::PCMMusicPlayer() { PCMMusicPlayer::~PCMMusicPlayer() { _vm->_mixer->stopHandle(_handle); + delete _curChunk; } void PCMMusicPlayer::startPlay(int id) { diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp index 2afcb589b7..6a76ade90a 100644 --- a/engines/toon/detection.cpp +++ b/engines/toon/detection.cpp @@ -44,7 +44,7 @@ static const ADGameDescription gameDescriptions[] = { {"study.svl", 0, "281efa3f33f6712c0f641a605f4d40fd", 2511090}, AD_LISTEND }, - Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, { "toon", "", @@ -54,7 +54,7 @@ static const ADGameDescription gameDescriptions[] = { {"study.svl", 0, "df056b94ea83f1ed92a539cf636053ab", 2542668}, AD_LISTEND }, - Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, { "toon", "", @@ -64,7 +64,7 @@ static const ADGameDescription gameDescriptions[] = { {"study.svl", 0, "72fe96a9e10967d3138e918295babc42", 2910283}, AD_LISTEND }, - Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, { "toon", "", @@ -74,7 +74,7 @@ static const ADGameDescription gameDescriptions[] = { {"study.svl", 0, "b6b1ee2d9d94d53d305856039ab7bde7", 2634620}, AD_LISTEND }, - Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, GUIO0() }, { "toon", "", @@ -84,7 +84,7 @@ static const ADGameDescription gameDescriptions[] = { {"generic.svl", 0, "5eb99850ada22f0b8cf6392262d4dd07", 9404599}, AD_LISTEND }, - Common::DE_DEU, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE) + Common::DE_DEU, Common::kPlatformPC, ADGF_DEMO, GUIO0() }, { "toon", "", @@ -93,7 +93,7 @@ static const ADGameDescription gameDescriptions[] = { {"generic.svl", 0, "5c42724bb93b360dca7044d6b7ef26e5", 7739319}, AD_LISTEND }, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NONE) + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() }, AD_TABLE_END_MARKER diff --git a/engines/touche/detection.cpp b/engines/touche/detection.cpp index a42d765056..35dd54776f 100644 --- a/engines/touche/detection.cpp +++ b/engines/touche/detection.cpp @@ -45,7 +45,7 @@ static const ADGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // retail version - tracker item #1601818 "touche", @@ -54,7 +54,7 @@ static const ADGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // retail version "touche", @@ -63,7 +63,7 @@ static const ADGameDescription gameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // retail version - tracker item #1598643 "touche", @@ -72,7 +72,7 @@ static const ADGameDescription gameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // retail version - tracker item #1681643 "touche", @@ -81,7 +81,7 @@ static const ADGameDescription gameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // fan-made translation (http://www.iagtg.net/) - tracker item #1602360 "touche", @@ -90,7 +90,7 @@ static const ADGameDescription gameDescriptions[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // retail version - tracker item #1800500 "touche", @@ -99,7 +99,7 @@ static const ADGameDescription gameDescriptions[] = { Common::PL_POL, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO0() }, { // demo version "touche", @@ -108,7 +108,7 @@ static const ADGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - GUIO1(GUIO_NONE) + GUIO0() }, AD_TABLE_END_MARKER }; diff --git a/engines/tsage/blue_force/blueforce_dialogs.cpp b/engines/tsage/blue_force/blueforce_dialogs.cpp index 86feceb015..b9b3ad6c22 100644 --- a/engines/tsage/blue_force/blueforce_dialogs.cpp +++ b/engines/tsage/blue_force/blueforce_dialogs.cpp @@ -187,6 +187,7 @@ void RightClickDialog::execute() { break; case 4: // Options dialog + BlueForce::OptionsDialog::show(); break; } @@ -428,6 +429,72 @@ int RadioConvDialog::show() { return btnIndex; } +/*--------------------------------------------------------------------------*/ + +void OptionsDialog::show() { + OptionsDialog *dlg = new OptionsDialog(); + dlg->draw(); + + GfxButton *btn = dlg->execute(); + + if (btn == &dlg->_btnQuit) { + // Quit game + if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) { + g_vm->quitGame(); + } + } else if (btn == &dlg->_btnRestart) { + // Restart game + g_globals->_game->restartGame(); + } else if (btn == &dlg->_btnSound) { + // Sound dialog + SoundDialog::execute(); + } else if (btn == &dlg->_btnSave) { + // Save button + g_globals->_game->saveGame(); + } else if (btn == &dlg->_btnRestore) { + // Restore button + g_globals->_game->restoreGame(); + } + + dlg->remove(); + delete dlg; +} + +OptionsDialog::OptionsDialog() { + // Set the element text + _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT); + _btnRestore.setText(RESTORE_BTN_STRING); + _btnSave.setText(SAVE_BTN_STRING); + _btnRestart.setText(RESTART_BTN_STRING); + _btnQuit.setText(QUIT_BTN_STRING); + _btnSound.setText(SOUND_BTN_STRING); + _btnResume.setText(RESUME_BTN_STRING); + + // Set position of the elements + _gfxMessage._bounds.moveTo(0, 1); + _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1); + _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1); + _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1); + _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1); + _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1); + _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1); + + // Set all the buttons to the widest button + GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume}; + int16 btnWidth = 0; + for (int idx = 0; idx < 6; ++idx) + btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width()); + for (int idx = 0; idx < 6; ++idx) + btnList[idx]->_bounds.setWidth(btnWidth); + + // Add the items to the dialog + addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL); + + // Set the dialog size and position + frame(); + _bounds.collapse(-6, -6); + setCenter(160, 90); +} } // End of namespace BlueForce diff --git a/engines/tsage/blue_force/blueforce_dialogs.h b/engines/tsage/blue_force/blueforce_dialogs.h index ca51c97aa2..76de7d19d9 100644 --- a/engines/tsage/blue_force/blueforce_dialogs.h +++ b/engines/tsage/blue_force/blueforce_dialogs.h @@ -85,6 +85,20 @@ public: static int show(); }; +class OptionsDialog: public GfxDialog { +private: + GfxButton _btnSave, _btnRestore, _btnRestart; + GfxButton _btnQuit, _btnResume; + GfxButton _btnSound; + GfxMessage _gfxMessage; +public: + OptionsDialog(); + virtual ~OptionsDialog() {} + + static void show(); +}; + + } // End of namespace BlueForce } // End of namespace TsAGE diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp index 91fd5d3197..22299c1bf1 100644 --- a/engines/tsage/blue_force/blueforce_logic.cpp +++ b/engines/tsage/blue_force/blueforce_logic.cpp @@ -315,6 +315,24 @@ void BlueForceGame::processEvent(Event &event) { } } +void BlueForceGame::restart() { + g_globals->_scenePalette.clearListeners(); + g_globals->_soundHandler.stop(); + + // Reset the globals + g_globals->reset(); + + // Clear save/load slots + g_globals->_sceneHandler->_saveGameSlot = -1; + g_globals->_sceneHandler->_loadGameSlot = -1; + + g_globals->_stripNum = 0; + g_globals->_events.setCursor(CURSOR_WALK); + + // Change to the first game scene + g_globals->_sceneManager.changeScene(190); +} + /*--------------------------------------------------------------------------*/ AObjectArray::AObjectArray(): EventHandler() { @@ -755,6 +773,7 @@ void SceneExt::loadScene(int sceneNum) { _v51C34.top = 0; _v51C34.bottom = 300; + BF_GLOBALS._sceneHandler->_delayTicks = 1; } void SceneExt::checkGun() { @@ -955,7 +974,7 @@ void SceneHandlerExt::process(Event &event) { return; } - // If the user clicks the button whislt the introduction is active, prompt for playing the game + // If the user clicks the button whilst the introduction is active, prompt for playing the game if ((BF_GLOBALS._dayNumber == 0) && (event.eventType == EVENT_BUTTON_DOWN)) { // Prompt user for whether to start play or watch introduction BF_GLOBALS._player.enableControl(); diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h index 1b161bce06..d0d0e0ee40 100644 --- a/engines/tsage/blue_force/blueforce_logic.h +++ b/engines/tsage/blue_force/blueforce_logic.h @@ -45,6 +45,7 @@ public: virtual void processEvent(Event &event); virtual bool canSaveGameStateCurrently(); virtual bool canLoadGameStateCurrently(); + virtual void restart(); }; #define OBJ_ARRAY_SIZE 10 diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp index bb283d051e..682e273716 100644 --- a/engines/tsage/blue_force/blueforce_scenes0.cpp +++ b/engines/tsage/blue_force/blueforce_scenes0.cpp @@ -48,45 +48,45 @@ void Scene20::Action1::signal() { BF_GLOBALS._scenePalette.addRotation(64, 127, -1, 1, this); break; case 2: - scene->_object1.setVisage(22); - scene->_object1._strip = 1; - scene->_object1._frame = 1; - scene->_object1.changeZoom(100); - - scene->_object2.setVisage(22); - scene->_object2._strip = 2; - scene->_object2._frame = 1; - scene->_object2.changeZoom(100); - - scene->_object3.setVisage(22); - scene->_object3._strip = 3; - scene->_object3._frame = 1; - scene->_object3.changeZoom(100); - - scene->_object4.setVisage(22); - scene->_object4._strip = 4; - scene->_object4._frame = 1; - scene->_object4.changeZoom(100); - - scene->_object5.setVisage(22); - scene->_object5._strip = 5; - scene->_object5._frame = 1; - scene->_object5.changeZoom(100); - - scene->_object6.setVisage(22); - scene->_object6._strip = 6; - scene->_object6._frame = 1; - scene->_object6.changeZoom(100); - - scene->_object7.setVisage(22); - scene->_object7._strip = 7; - scene->_object7._frame = 1; - scene->_object7.changeZoom(100); - - scene->_object8.setVisage(22); - scene->_object8._strip = 8; - scene->_object8._frame = 1; - scene->_object8.changeZoom(100); + scene->_tsunamiWave.setVisage(22); + scene->_tsunamiWave._strip = 1; + scene->_tsunamiWave._frame = 1; + scene->_tsunamiWave.changeZoom(100); + + scene->_letterT.setVisage(22); + scene->_letterT._strip = 2; + scene->_letterT._frame = 1; + scene->_letterT.changeZoom(100); + + scene->_letterS.setVisage(22); + scene->_letterS._strip = 3; + scene->_letterS._frame = 1; + scene->_letterS.changeZoom(100); + + scene->_letterU.setVisage(22); + scene->_letterU._strip = 4; + scene->_letterU._frame = 1; + scene->_letterU.changeZoom(100); + + scene->_letterN.setVisage(22); + scene->_letterN._strip = 5; + scene->_letterN._frame = 1; + scene->_letterN.changeZoom(100); + + scene->_letterA.setVisage(22); + scene->_letterA._strip = 6; + scene->_letterA._frame = 1; + scene->_letterA.changeZoom(100); + + scene->_letterM.setVisage(22); + scene->_letterM._strip = 7; + scene->_letterM._frame = 1; + scene->_letterM.changeZoom(100); + + scene->_letterI.setVisage(22); + scene->_letterI._strip = 8; + scene->_letterI._frame = 1; + scene->_letterI.changeZoom(100); setDelay(1); break; @@ -97,12 +97,12 @@ void Scene20::Action1::signal() { setDelay(60); break; case 5: - scene->_object2.animate(ANIM_MODE_5, NULL); - scene->_object3.animate(ANIM_MODE_5, NULL); - scene->_object4.animate(ANIM_MODE_5, NULL); - scene->_object5.animate(ANIM_MODE_5, NULL); - scene->_object6.animate(ANIM_MODE_5, NULL); - scene->_object7.animate(ANIM_MODE_5, this); + scene->_letterT.animate(ANIM_MODE_5, NULL); + scene->_letterS.animate(ANIM_MODE_5, NULL); + scene->_letterU.animate(ANIM_MODE_5, NULL); + scene->_letterN.animate(ANIM_MODE_5, NULL); + scene->_letterA.animate(ANIM_MODE_5, NULL); + scene->_letterM.animate(ANIM_MODE_5, this); break; case 6: setDelay(120); @@ -121,76 +121,76 @@ void Scene20::Action1::signal() { void Scene20::postInit(SceneObjectList *OwnerList) { loadScene(20); - Scene::postInit(); + SceneExt::postInit(); setZoomPercents(60, 85, 200, 100); BF_GLOBALS._interfaceY = SCREEN_HEIGHT; _scenePalette.loadPalette(1); _scenePalette.loadPalette(22); - _object1.postInit(); - _object1.setVisage(21); - _object1._strip = 1; - _object1._frame = 1; - _object1.animate(ANIM_MODE_NONE, NULL); - _object1.setPosition(Common::Point(62, 85)); - _object1.changeZoom(100); - - _object2.postInit(); - _object2.setVisage(21); - _object2._strip = 2; - _object2._frame = 1; - _object2.animate(ANIM_MODE_NONE, NULL); - _object2.setPosition(Common::Point(27, 94)); - _object2.changeZoom(100); - - _object3.postInit(); - _object3.setVisage(21); - _object3._strip = 2; - _object3._frame = 2; - _object3.animate(ANIM_MODE_NONE, NULL); - _object3.setPosition(Common::Point(68, 94)); - _object3.changeZoom(100); - - _object4.postInit(); - _object4.setVisage(21); - _object4._strip = 2; - _object4._frame = 3; - _object4.animate(ANIM_MODE_NONE, NULL); - _object4.setPosition(Common::Point(110, 94)); - _object4.changeZoom(100); - - _object5.postInit(); - _object5.setVisage(21); - _object5._strip = 2; - _object5._frame = 4; - _object5.animate(ANIM_MODE_NONE, NULL); - _object5.setPosition(Common::Point(154, 94)); - _object5.changeZoom(100); - - _object6.postInit(); - _object6.setVisage(21); - _object6._strip = 2; - _object6._frame = 5; - _object6.animate(ANIM_MODE_NONE, NULL); - _object6.setPosition(Common::Point(199, 94)); - _object6.changeZoom(100); - - _object7.postInit(); - _object7.setVisage(21); - _object7._strip = 2; - _object7._frame = 6; - _object7.animate(ANIM_MODE_NONE, NULL); - _object7.setPosition(Common::Point(244, 94)); - _object7.changeZoom(100); - - _object8.postInit(); - _object8.setVisage(21); - _object8._strip = 2; - _object8._frame = 7; - _object8.animate(ANIM_MODE_NONE, NULL); - _object8.setPosition(Common::Point(286, 94)); - _object8.changeZoom(100); + _tsunamiWave.postInit(); + _tsunamiWave.setVisage(21); + _tsunamiWave._strip = 1; + _tsunamiWave._frame = 1; + _tsunamiWave.animate(ANIM_MODE_NONE, NULL); + _tsunamiWave.setPosition(Common::Point(62, 85)); + _tsunamiWave.changeZoom(100); + + _letterT.postInit(); + _letterT.setVisage(21); + _letterT._strip = 2; + _letterT._frame = 1; + _letterT.animate(ANIM_MODE_NONE, NULL); + _letterT.setPosition(Common::Point(27, 94)); + _letterT.changeZoom(100); + + _letterS.postInit(); + _letterS.setVisage(21); + _letterS._strip = 2; + _letterS._frame = 2; + _letterS.animate(ANIM_MODE_NONE, NULL); + _letterS.setPosition(Common::Point(68, 94)); + _letterS.changeZoom(100); + + _letterU.postInit(); + _letterU.setVisage(21); + _letterU._strip = 2; + _letterU._frame = 3; + _letterU.animate(ANIM_MODE_NONE, NULL); + _letterU.setPosition(Common::Point(110, 94)); + _letterU.changeZoom(100); + + _letterN.postInit(); + _letterN.setVisage(21); + _letterN._strip = 2; + _letterN._frame = 4; + _letterN.animate(ANIM_MODE_NONE, NULL); + _letterN.setPosition(Common::Point(154, 94)); + _letterN.changeZoom(100); + + _letterA.postInit(); + _letterA.setVisage(21); + _letterA._strip = 2; + _letterA._frame = 5; + _letterA.animate(ANIM_MODE_NONE, NULL); + _letterA.setPosition(Common::Point(199, 94)); + _letterA.changeZoom(100); + + _letterM.postInit(); + _letterM.setVisage(21); + _letterM._strip = 2; + _letterM._frame = 6; + _letterM.animate(ANIM_MODE_NONE, NULL); + _letterM.setPosition(Common::Point(244, 94)); + _letterM.changeZoom(100); + + _letterI.postInit(); + _letterI.setVisage(21); + _letterI._strip = 2; + _letterI._frame = 7; + _letterI.animate(ANIM_MODE_NONE, NULL); + _letterI.setPosition(Common::Point(286, 94)); + _letterI.changeZoom(100); setAction(&_action1); BF_GLOBALS._dialogCenter.y = 165; @@ -239,11 +239,11 @@ void Scene50::Tooltip2::dispatch() { } } -void Scene50::Tooltip::set(const Rect &bounds, int v60, const Common::String &msg, int v62) { +void Scene50::Tooltip::set(const Rect &bounds, int sceneNum, const Common::String &msg, int locationId) { _bounds = bounds; - _newSceneNumber = v60; + _newSceneNumber = sceneNum; _msg = msg; - _locationId = v62; + _locationId = locationId; } void Scene50::Tooltip::update() { @@ -261,8 +261,8 @@ void Scene50::Tooltip::update() { void Scene50::Tooltip::highlight(bool btnDown) { Scene50 *scene = (Scene50 *)BF_GLOBALS._sceneManager._scene; - scene->_field382 = _newSceneNumber; - if ((scene->_field380 != 0) || (scene->_field380 != _newSceneNumber)) + // In the original, a variable was used, always set to 0. The check is simplified + if (_newSceneNumber != 0) update(); if (btnDown) { @@ -323,11 +323,6 @@ void Scene50::Tooltip::highlight(bool btnDown) { /*--------------------------------------------------------------------------*/ -Scene50::Scene50(): SceneExt() { - _field382 = 0; - _field380 = 0; -} - void Scene50::postInit(SceneObjectList *OwnerList) { SceneExt::postInit(); @@ -439,11 +434,11 @@ void Scene50::signal() { } if ((BF_GLOBALS._driveFromScene == 410) && (_sceneNumber != BF_GLOBALS._driveFromScene)) { - BF_GLOBALS.setFlag(125); + BF_GLOBALS.setFlag(f1097Frankie); } if ((BF_GLOBALS._driveFromScene == 340) && (_sceneNumber != BF_GLOBALS._driveFromScene)) { - BF_GLOBALS.setFlag(123); + BF_GLOBALS.setFlag(f1097Marina); } if ((BF_GLOBALS._driveFromScene == 380) && (_sceneNumber != BF_GLOBALS._driveFromScene)) { @@ -469,7 +464,6 @@ void Scene50::signal() { BF_GLOBALS._player.enableControl(); BF_GLOBALS._events.setCursor(CURSOR_WALK); _sceneMode = 0; - _field380 = 0; } } @@ -477,7 +471,6 @@ void Scene50::process(Event &event) { SceneExt::process(event); Common::Point pt(event.mousePos.x + _sceneBounds.left, event.mousePos.y + _sceneBounds.top); bool mouseDown = false; - _field382 = 0; if ((event.mousePos.x > 270 && (_sceneBounds.right < (SCREEN_WIDTH * 2)))) loadBackground(4, 0); @@ -537,7 +530,7 @@ bool Scene60::Ignition::startAction(CursorType action, Event &event) { bool Scene60::Ignition::check1() { if (BF_GLOBALS._bookmark >= bStoppedFrankie) { - BF_GLOBALS._v5098C |= 1; + BF_GLOBALS._subFlagBitArr1 |= 1; return false; } else { if ((BF_GLOBALS._bookmark == bBookedGreen) && BF_GLOBALS.getFlag(fArrivedAtGangStop)) { @@ -564,13 +557,13 @@ bool Scene60::Ignition::check1() { } else if (BF_GLOBALS._bookmark < bStartOfGame) { // Should never reach here } else if (BF_GLOBALS._bookmark < bCalledToDomesticViolence) { - if ((BF_GLOBALS._v5098C >> 1) & 1) + if ((BF_GLOBALS._subFlagBitArr1 >> 1) & 1) BF_GLOBALS.setFlag(fLateToMarina); else - BF_GLOBALS._v5098C |= 2; + BF_GLOBALS._subFlagBitArr1 |= 2; } else { - int v = (((BF_GLOBALS._v5098C >> 2) & 15) + 1) & 15; - BF_GLOBALS._v5098C = (BF_GLOBALS._v5098C & 0xC3) | (v << 2); + int v = (((BF_GLOBALS._subFlagBitArr1 >> 2) & 15) + 1) & 15; + BF_GLOBALS._subFlagBitArr1 = (BF_GLOBALS._subFlagBitArr1 & 0xC3) | (v << 2); if ((v != 1) && (v != 2)) { BF_GLOBALS._deathReason = 19; @@ -580,17 +573,17 @@ bool Scene60::Ignition::check1() { } } - BF_GLOBALS._v5098C |= 1; + BF_GLOBALS._subFlagBitArr1 |= 1; return false; } bool Scene60::Ignition::check2() { switch (BF_GLOBALS._bookmark) { case bInspectionDone: - if (BF_GLOBALS._v5098D & 1) { + if (BF_GLOBALS._subFlagBitArr2 & 1) { BF_GLOBALS.setFlag(fLateToDrunkStop); } else { - BF_GLOBALS._v5098D |= 1; + BF_GLOBALS._subFlagBitArr2 |= 1; } break; case bCalledToDrunkStop: @@ -600,7 +593,7 @@ bool Scene60::Ignition::check2() { break; } - BF_GLOBALS._v5098C |= 0x80; + BF_GLOBALS._subFlagBitArr1 |= 0x80; return false; } @@ -1083,7 +1076,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) { switch (BF_GLOBALS._dayNumber) { case 1: - if (BF_GLOBALS.getFlag(onDuty) && (BF_GLOBALS._v5098C & 1) && + if (BF_GLOBALS.getFlag(onDuty) && (BF_GLOBALS._subFlagBitArr1 & 1) && (BF_GLOBALS._bookmark < bStartOfGame) && (BF_GLOBALS._sceneManager._previousScene != 342)) { setAction(&_action2); if (BF_GLOBALS._sceneManager._previousScene == 342) @@ -1091,7 +1084,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) { } break; case 2: - if (BF_GLOBALS.getFlag(onDuty) && ((BF_GLOBALS._v5098C >> 7) & 1) && + if (BF_GLOBALS.getFlag(onDuty) && ((BF_GLOBALS._subFlagBitArr1 >> 7) & 1) && (BF_GLOBALS._sceneManager._previousScene != 550) && (BF_GLOBALS._bookmark < bInspectionDone)) { setAction(&_action3); diff --git a/engines/tsage/blue_force/blueforce_scenes0.h b/engines/tsage/blue_force/blueforce_scenes0.h index 103e5f0a4c..29adec7e00 100644 --- a/engines/tsage/blue_force/blueforce_scenes0.h +++ b/engines/tsage/blue_force/blueforce_scenes0.h @@ -50,8 +50,8 @@ class Scene20 : public SceneExt { public: Action1 _action1; ScenePalette _scenePalette; - SceneObject _object1, _object2, _object3, _object4; - SceneObject _object5, _object6, _object7, _object8; + SceneObject _tsunamiWave, _letterT, _letterS, _letterU; + SceneObject _letterN, _letterA, _letterM, _letterI; virtual void postInit(SceneObjectList *OwnerList = NULL); }; @@ -65,7 +65,7 @@ class Scene50: public SceneExt { int _locationId; public: Tooltip(); - void set(const Rect &bounds, int v60, const Common::String &msg, int v62); + void set(const Rect &bounds, int sceneNum, const Common::String &msg, int locationId); void update(); void highlight(bool btnDown); @@ -81,7 +81,6 @@ class Scene50: public SceneExt { virtual void dispatch(); }; public: - int _field380, _field382; int _sceneNumber; SceneText _text; SceneItemType2 _item; @@ -89,7 +88,6 @@ public: Tooltip _location6, _location7, _location8, _location9; Timer _timer; public: - Scene50(); virtual Common::String getClassName() { return "Scene50"; } virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void remove(); diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp index 425446d6fb..402d776429 100644 --- a/engines/tsage/blue_force/blueforce_scenes1.cpp +++ b/engines/tsage/blue_force/blueforce_scenes1.cpp @@ -243,8 +243,8 @@ void Scene109::Action1::signal() { scene->_drunk.show(); scene->_drunk.setAction(&scene->_action3); scene->_object2.show(); - scene->_object9.show(); - scene->_object9.setAction(&scene->_action2); + scene->_beerSign.show(); + scene->_beerSign.setAction(&scene->_action2); BF_GLOBALS._v501FC = 170; setDelay(60); @@ -257,27 +257,27 @@ void Scene109::Action1::signal() { break; case 5: // Open briefcase and pass over disk - setAction(&scene->_sequenceManager6, this, 105, &scene->_object10, NULL); + setAction(&scene->_sequenceManager6, this, 105, &scene->_animationInset, NULL); break; case 6: // Protaginist 2 walk to the bar - scene->_object10.remove(); + scene->_animationInset.remove(); setAction(&scene->_sequenceManager6, this, 100, &scene->_protaginist2, NULL); break; case 7: // Two thugs enter and walk to table - scene->_object7.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_object7, NULL); - scene->_object5.setAction(&scene->_sequenceManager8, this, 102, &scene->_object5, NULL); + scene->_cop2.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_cop2, NULL); + scene->_cop1.setAction(&scene->_sequenceManager8, this, 102, &scene->_cop1, NULL); scene->_protaginist2.setAction(&scene->_sequenceManager6, NULL, 104, &scene->_protaginist2, &scene->_bartender, NULL); break; case 8: // Protaginist 1 leaves, protaginist 2 stands up - setAction(&scene->_sequenceManager8, this, 101, &scene->_object5, &scene->_protaginist1, NULL); + setAction(&scene->_sequenceManager8, this, 101, &scene->_cop1, &scene->_protaginist1, NULL); break; case 9: // Shots fired! scene->_protaginist1.setAction(&scene->_sequenceManager5, this, 98, &scene->_protaginist1, NULL); - scene->_object7.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_object7, NULL); + scene->_cop2.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_cop2, NULL); break; case 10: // End scene @@ -289,12 +289,12 @@ void Scene109::Action1::signal() { void Scene109::Action2::signal() { Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene; - scene->setAction(&scene->_sequenceManager2, this, 3117, &scene->_object9, NULL); + setAction(&scene->_sequenceManager2, this, 3117, &scene->_beerSign, NULL); } void Scene109::Action3::signal() { Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene; - scene->setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL); + setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL); } /*--------------------------------------------------------------------------*/ @@ -353,21 +353,21 @@ void Scene109::postInit(SceneObjectList *OwnerList) { _object2.setPosition(Common::Point(104, 64)); _object2.hide(); - _object9.postInit(); - _object9.setVisage(115); - _object9.setStrip(4); - _object9.setFrame(1); - _object9.setPosition(Common::Point(262, 29)); - _object9.hide(); + _beerSign.postInit(); + _beerSign.setVisage(115); + _beerSign.setStrip(4); + _beerSign.setFrame(1); + _beerSign.setPosition(Common::Point(262, 29)); + _beerSign.hide(); - _object5.postInit(); - _object5.hide(); + _cop1.postInit(); + _cop1.hide(); - _object7.postInit(); - _object7.hide(); + _cop2.postInit(); + _cop2.hide(); - _object10.postInit(); - _object10.hide(); + _animationInset.postInit(); + _animationInset.hide(); BF_GLOBALS._player.disableControl(); setAction(&_action1, this); @@ -985,7 +985,7 @@ void Scene114::signal() { * Scene 115 - Inside Tony's bar * *--------------------------------------------------------------------------*/ -bool Scene115::Object1::startAction(CursorType action, Event &event) { +bool Scene115::Kate::startAction(CursorType action, Event &event) { Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene; switch (action) { @@ -1001,7 +1001,7 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 0; scene->_stripManager.start(1174, scene); - } else if (scene->_field31E8 == 0) { + } else if (scene->_jukeboxPlaying == 0) { if (BF_GLOBALS.getFlag(fShowedIdToKate)) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 0; @@ -1014,10 +1014,10 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) { scene->setAction(&scene->_action7); return true; case INV_MUG_SHOT: - if (scene->_field31E8 == 0) { + if (scene->_jukeboxPlaying == 0) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 0; - if (BF_GLOBALS._v4CEAA == 0) + if (BF_GLOBALS._tonyDialogCtr == 0) scene->_stripManager.start(1167, scene); else if (BF_GLOBALS.getFlag(fShowedIdToKate)) scene->_stripManager.start(1159, scene); @@ -1035,8 +1035,8 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) { SET_EXT_FGCOLOR, 13, LIST_END); return true; case INV_ID: - if (scene->_field31E8 == 0) { - if (BF_GLOBALS._v4CEAA == 0) { + if (scene->_jukeboxPlaying == 0) { + if (BF_GLOBALS._tonyDialogCtr == 0) { scene->_sceneMode = 1167; scene->setAction(&scene->_action6); } else if (BF_GLOBALS.getFlag(fShowedIdToKate)) { @@ -1059,7 +1059,7 @@ bool Scene115::Object1::startAction(CursorType action, Event &event) { } } -bool Scene115::Object2::startAction(CursorType action, Event &event) { +bool Scene115::Tony::startAction(CursorType action, Event &event) { Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene; switch (action) { @@ -1077,7 +1077,7 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) { else if (BF_INVENTORY.getObjectScene(INV_COBB_RAP) == 1) { if (BF_GLOBALS.getFlag(fTalkedToTony)) scene->_sceneMode = 1151; - else if (BF_GLOBALS._v4CEAA == 0) { + else if (BF_GLOBALS._tonyDialogCtr == 0) { scene->_sceneMode = 1150; BF_GLOBALS.setFlag(fTalkedToTony); } else @@ -1088,14 +1088,14 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) { } else scene->_sceneMode = 1172; } else if (BF_GLOBALS.getFlag(onDuty)) { - if (scene->_field31EA == 0) { - scene->_field31EA = 1; + if (scene->_talkToTonyCtr == 0) { + scene->_talkToTonyCtr = 1; scene->_sceneMode = 1169; } else scene->_sceneMode = 1170; - } else if (scene->_field31EA == 0) { + } else if (scene->_talkToTonyCtr == 0) { scene->_sceneMode = 1171; - scene->_field31EA = 1; + scene->_talkToTonyCtr = 1; } else scene->_sceneMode = 1172; @@ -1111,7 +1111,7 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) { case INV_COBB_RAP: if (BF_GLOBALS.getFlag(onDuty)) scene->_sceneMode = 1177; - else if (BF_GLOBALS._v4CEAA == 0) + else if (BF_GLOBALS._tonyDialogCtr == 0) scene->_sceneMode = 1179; else scene->_sceneMode = 1154; @@ -1132,11 +1132,11 @@ bool Scene115::Object2::startAction(CursorType action, Event &event) { } else { T2_GLOBALS._uiElements.addScore(30); BF_GLOBALS.setFlag(fTalkedToTony); - if (BF_GLOBALS._v4CEAA == 0) { + if (BF_GLOBALS._tonyDialogCtr == 0) { scene->_sceneMode = 1150; scene->setAction(&scene->_action9); } else { - BF_GLOBALS._v4CEAA = 1; + BF_GLOBALS._tonyDialogCtr = 1; scene->setAction(&scene->_action2); } } @@ -1215,24 +1215,23 @@ bool Scene115::Object4::startAction(CursorType action, Event &event) { } } -void Scene115::Item1::signal() { +void Scene115::Jukebox::signal() { Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene; - if (_field1F8A == 2) - _field1F8A = 0; - - if (_field1F8A == 1) { - _field1F8A = 2; + if (_jokeboxPlayingCtr == 2) + _jokeboxPlayingCtr = 0; + else if (_jokeboxPlayingCtr == 1) { + _jokeboxPlayingCtr = 2; setAction(&_sequenceManager6, this, 118, &scene->_object12, &scene->_object11, NULL); } } -bool Scene115::Item1::startAction(CursorType action, Event &event) { +bool Scene115::Jukebox::startAction(CursorType action, Event &event) { Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene; if (action == CURSOR_USE) { - if (_field1F8A == 0) { - _field1F8A = 1; + if (_jokeboxPlayingCtr == 0) { + _jokeboxPlayingCtr = 1; BF_GLOBALS._player.disableControl(); scene->setAction(&scene->_action4); } else @@ -1246,20 +1245,20 @@ bool Scene115::Item1::startAction(CursorType action, Event &event) { return NamedHotspot::startAction(action, event); } -void Scene115::Item1::synchronize(Serializer &s) { +void Scene115::Jukebox::synchronize(Serializer &s) { NamedHotspot::synchronize(s); - s.syncAsSint16LE(_field1F8A); + s.syncAsSint16LE(_jokeboxPlayingCtr); } -Scene115::Item1::Item1() { - _field1F8A = 0; +Scene115::Jukebox::Jukebox() { + _jokeboxPlayingCtr = 0; } void Scene115::EventHandler1::dispatch() { Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene; if (BF_GLOBALS._player.getRegionIndex() == 27) { - scene->_object1.setAction(&scene->_action5); + scene->_kate.setAction(&scene->_action5); scene->removeTimer(this); } } @@ -1339,20 +1338,20 @@ void Scene115::Action2::signal() { switch (_actionIndex++) { case 0: BF_GLOBALS._player.disableControl(); - if (BF_GLOBALS._v4CEAA < 3) { - if (scene->_object2._position.x > 67) { - scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_object2, NULL); - } else if (scene->_object2._position.x != 67) { - scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_object2, NULL); + if (BF_GLOBALS._tonyDialogCtr < 3) { + if (scene->_tony._position.x > 67) { + scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_tony, NULL); + } else if (scene->_tony._position.x != 67) { + scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_tony, NULL); } } BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 1117, &BF_GLOBALS._player); break; case 1: - BF_GLOBALS._v4CEAA++; + ++BF_GLOBALS._tonyDialogCtr; if (BF_GLOBALS.getFlag(onDuty)) { if (BF_GLOBALS.getFlag(fTalkedToTony)) { - switch (BF_GLOBALS._v4CEAA) { + switch (BF_GLOBALS._tonyDialogCtr) { case 1: T2_GLOBALS._uiElements.addScore(30); scene->_stripManager.start(1181, this); @@ -1369,7 +1368,7 @@ void Scene115::Action2::signal() { } } else { if (BF_GLOBALS.getFlag(fTalkedToTony)) { - switch (BF_GLOBALS._v4CEAA) { + switch (BF_GLOBALS._tonyDialogCtr) { case 1: T2_GLOBALS._uiElements.addScore(30); scene->_stripManager.start(1153, this); @@ -1387,8 +1386,8 @@ void Scene115::Action2::signal() { } break; case 2: - if (BF_GLOBALS._v4CEAA == 3) - scene->_object2.setAction(&scene->_sequenceManager3, NULL, 3119, &scene->_object2, NULL); + if (BF_GLOBALS._tonyDialogCtr == 3) + scene->_tony.setAction(&scene->_sequenceManager3, NULL, 3119, &scene->_tony, NULL); BF_GLOBALS._player.enableControl(); remove(); default: @@ -1399,7 +1398,7 @@ void Scene115::Action2::signal() { void Scene115::Action3::signal() { Scene115 *scene = (Scene115 *)BF_GLOBALS._sceneManager._scene; - setAction(&scene->_sequenceManager4, this, 3117, &scene->_object7, NULL); + setAction(&scene->_sequenceManager4, this, 3117, &scene->_neonSign, NULL); } void Scene115::Action4::signal() { @@ -1426,7 +1425,7 @@ void Scene115::Action4::signal() { setAction(&scene->_sequenceManager1, this, 117, &scene->_object12, &scene->_object11, NULL); break; case 3: - scene->_sound1.play(81, &scene->_item1, 127); + scene->_sound1.play(81, &scene->_itemJukebox, 127); BF_GLOBALS._player.enableControl(); remove(); default: @@ -1439,10 +1438,11 @@ void Scene115::Action5::signal() { switch (_actionIndex++) { case 0: - if (scene->_item1._field1F8A == 0) { - setAction(&scene->_sequenceManager5, this, 1115, &scene->_object1, NULL); + if (scene->_itemJukebox._jokeboxPlayingCtr == 0) { + setAction(&scene->_sequenceManager5, this, 1115, &scene->_kate, NULL); + scene->_jukeboxPlaying = 1; } else { - _actionIndex--; + --_actionIndex; setDelay(120); } break; @@ -1450,15 +1450,15 @@ void Scene115::Action5::signal() { setAction(&scene->_sequenceManager5, this, 117, &scene->_object12, &scene->_object11, NULL); break; case 2: - scene->_sound1.play(81, &scene->_item1, 127); - scene->_item1._field1F8A = 1; + scene->_sound1.play(81, &scene->_itemJukebox, 127); + scene->_itemJukebox._jokeboxPlayingCtr = 1; setDelay(3); break; case 3: - setAction(&scene->_sequenceManager5, this, 1116, &scene->_object1, NULL); + setAction(&scene->_sequenceManager5, this, 1116, &scene->_kate, NULL); break; case 4: - scene->_field31E8 = 0; + scene->_jukeboxPlaying = 0; remove(); default: break; @@ -1471,22 +1471,22 @@ void Scene115::Action6::signal() { switch (_actionIndex++) { case 0: BF_GLOBALS._player.disableControl(); - BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 2115, &scene->_object1, &BF_GLOBALS._player, NULL); + BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 2115, &scene->_kate, &BF_GLOBALS._player, NULL); break; case 1: if (scene->_sceneMode == 9999) { - setAction(&scene->_sequenceManager1, this, 4115, &scene->_object1, &BF_GLOBALS._player, NULL); - _actionIndex--; + setAction(&scene->_sequenceManager1, this, 4115, &scene->_kate, &BF_GLOBALS._player, NULL); + --_actionIndex; scene->_sceneMode = 1166; } else { scene->_stripManager.start(scene->_sceneMode, this); } break; case 2: - scene->_object1.setVisage(131); - scene->_object1.setStrip(1); - scene->_object1.setFrame(1); - scene->_object1.setPosition(Common::Point(122, 97)); + scene->_kate.setVisage(131); + scene->_kate.setStrip(1); + scene->_kate.setFrame(1); + scene->_kate.setPosition(Common::Point(122, 97)); BF_GLOBALS._player.enableControl(); remove(); default: @@ -1507,11 +1507,11 @@ void Scene115::Action7::signal() { break; case 1: BF_GLOBALS._player.setStrip(4); - if (BF_GLOBALS._v4CEB0 == 0) + if (BF_GLOBALS._kateDialogCtr == 0) scene->_stripManager.start(1156, this); else scene->_stripManager.start(1157, this); - BF_GLOBALS._v4CEB0++; + ++BF_GLOBALS._kateDialogCtr; break; case 2: BF_GLOBALS._player.enableControl(); @@ -1528,11 +1528,11 @@ void Scene115::Action8::signal() { switch (_actionIndex++) { case 0: BF_GLOBALS._player.disableControl(); - setAction(&scene->_sequenceManager1, this, 2115, &scene->_object1, &BF_GLOBALS._player, NULL); + setAction(&scene->_sequenceManager1, this, 2115, &scene->_kate, &BF_GLOBALS._player, NULL); break; case 1: T2_GLOBALS._uiElements.addScore(30); - setAction(&scene->_sequenceManager1, this, 4115, &scene->_object1, &BF_GLOBALS._player, NULL); + setAction(&scene->_sequenceManager1, this, 4115, &scene->_kate, &BF_GLOBALS._player, NULL); break; case 2: scene->_stripManager.start(1160, this); @@ -1542,15 +1542,15 @@ void Scene115::Action8::signal() { break; case 4: BF_GLOBALS.setFlag(fGivenNapkin); - setAction(&scene->_sequenceManager1, this, 2117, &scene->_object1, &BF_GLOBALS._player, &scene->_object13, NULL); + setAction(&scene->_sequenceManager1, this, 2117, &scene->_kate, &BF_GLOBALS._player, &scene->_object13, NULL); break; case 5: BF_INVENTORY.setObjectScene(INV_NAPKIN, 1); T2_GLOBALS._uiElements.addScore(10); - scene->_object1.setVisage(131); - scene->_object1.setStrip(1); - scene->_object1.setFrame(1); - scene->_object1.setPosition(Common::Point(122, 97)); + scene->_kate.setVisage(131); + scene->_kate.setStrip(1); + scene->_kate.setFrame(1); + scene->_kate.setPosition(Common::Point(122, 97)); BF_GLOBALS._player.enableControl(); remove(); break; @@ -1565,17 +1565,17 @@ void Scene115::Action9::signal() { switch (_actionIndex++) { case 0: BF_GLOBALS._player.disableControl(); - if (scene->_object2._position.x > 67) - scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_object2, NULL); - else if (scene->_object2._position.x != 67) - scene->_object2.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_object2, NULL); + if (scene->_tony._position.x > 67) + scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1118, &scene->_tony, NULL); + else if (scene->_tony._position.x != 67) + scene->_tony.setAction(&scene->_sequenceManager3, NULL, 1119, &scene->_tony, NULL); BF_GLOBALS._player.setAction(&scene->_sequenceManager1, this, 1117, &BF_GLOBALS._player, NULL); break; case 1: scene->_stripManager.start(scene->_sceneMode, this); break; case 2: - scene->_object2.setAction(&scene->_sequenceManager3, this, 3119, &scene->_object2, NULL); + scene->_tony.setAction(&scene->_sequenceManager3, this, 3119, &scene->_tony, NULL); break; case 3: BF_GLOBALS._player.enableControl(); @@ -1586,7 +1586,7 @@ void Scene115::Action9::signal() { } Scene115::Scene115() : SceneExt () { - _field168A = _field31E8 = _field31EA = 0; + _lineNumModifier = _jukeboxPlaying = _talkToTonyCtr = 0; } void Scene115::postInit(SceneObjectList *OwnerList) { @@ -1595,7 +1595,7 @@ void Scene115::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._sound1.fadeSound(15); loadScene(115); setZoomPercents(98, 85, 115, 100); - _field31E8 = 0; + _jukeboxPlaying = 0; _stripManager.addSpeaker(&_gameTextSpeaker); _stripManager.addSpeaker(&_kateSpeaker); _stripManager.addSpeaker(&_tonySpeaker); @@ -1620,24 +1620,24 @@ void Scene115::postInit(SceneObjectList *OwnerList) { _object5.fixPriority(95); // Bartender - _object2.postInit(); - _object2.setVisage(132); - _object2.setPosition(Common::Point(74, 66)); - _object2.setStrip(3); - _object2.setFrame(1); - _object2.fixPriority(95); - _object2.animate(ANIM_MODE_2, NULL); - _object2._numFrames = 5; - _object2._field15F8 = 0; - _field31EA = 0; + _tony.postInit(); + _tony.setVisage(132); + _tony.setPosition(Common::Point(74, 66)); + _tony.setStrip(3); + _tony.setFrame(1); + _tony.fixPriority(95); + _tony.animate(ANIM_MODE_2, NULL); + _tony._numFrames = 5; + _tony._field15F8 = 0; + _talkToTonyCtr = 0; //Neon sign - _object7.postInit(); - _object7.setVisage(115); - _object7.setStrip(4); - _object7.setFrame(1); - _object7.setPosition(Common::Point(262, 29)); - _object7.setAction(&_action3); + _neonSign.postInit(); + _neonSign.setVisage(115); + _neonSign.setStrip(4); + _neonSign.setFrame(1); + _neonSign.setPosition(Common::Point(262, 29)); + _neonSign.setAction(&_action3); _object11.postInit(); _object11.hide(); @@ -1674,7 +1674,7 @@ void Scene115::postInit(SceneObjectList *OwnerList) { _object3.setVisage(123); _object3.setPosition(Common::Point(212, 108)); _object3.setAction(&_action1); - _field168A = 0; + _lineNumModifier = 0; BF_GLOBALS._sceneItems.push_front(&_object3); _object8.postInit(); @@ -1696,18 +1696,18 @@ void Scene115::postInit(SceneObjectList *OwnerList) { _object10.fixPriority(112); if (BF_INVENTORY.getObjectScene(INV_COBB_RAP) == 1) { - _object1.postInit(); - _object1.setVisage(131); - _object1.setPosition(Common::Point(122, 97)); - _object1.setStrip(1); - _object1.setFrame(1); - _object1.changeZoom(100); - _object1.fixPriority(95); - BF_GLOBALS._sceneItems.push_front(&_object1); + _kate.postInit(); + _kate.setVisage(131); + _kate.setPosition(Common::Point(122, 97)); + _kate.setStrip(1); + _kate.setFrame(1); + _kate.changeZoom(100); + _kate.fixPriority(95); + BF_GLOBALS._sceneItems.push_front(&_kate); } addTimer(&_eventHandler1); } - BF_GLOBALS._sceneItems.push_front(&_object2); + BF_GLOBALS._sceneItems.push_front(&_tony); _item11.setDetails(16, 115, 4, 15, 21, 1); _item12.setDetails(20, 115, 5, 15, 21, 1); @@ -1716,8 +1716,8 @@ void Scene115::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._sceneItems.push_front(&_item14); _item10.setDetails(Rect(0, 147, 30, 167), 115, -1, -1, -1, 1, NULL); // SUB_177B8 - addTimer(&_item1); - _item1.setDetails(Rect(147, 45, 179, 91), 115, 25, 26, 27, 1, NULL); + addTimer(&_itemJukebox); + _itemJukebox.setDetails(Rect(147, 45, 179, 91), 115, 25, 26, 27, 1, NULL); // _item6.setDetails(Rect(107, 43, 122, 61), 115, 28, 29, 30, 1, NULL); _item7.setDetails(Rect(180, 33, 230, 63), 115, 31, 32, 33, 1, NULL); @@ -1741,14 +1741,14 @@ void Scene115::signal() { break; case 1: BF_GLOBALS._player.updateAngle(_object3._position); - SceneItem::display(115, 38 + _field168A, SET_WIDTH, 312, + SceneItem::display(115, 38 + _lineNumModifier, SET_WIDTH, 312, SET_X, GLOBALS._sceneManager._scene->_sceneBounds.left + 4, SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2, SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 19, SET_EXT_BGCOLOR, 9, SET_EXT_FGCOLOR, 13, LIST_END); - _field168A++; - if (_field168A >= 4) - _field168A = 0; + ++_lineNumModifier; + if (_lineNumModifier >= 4) + _lineNumModifier = 0; // No break on purpose case 0: // No break on purpose @@ -1777,9 +1777,9 @@ void Scene115::process(Event &event) { void Scene115::synchronize(Serializer &s) { SceneExt::synchronize(s); - s.syncAsSint16LE(_field168A); - s.syncAsSint16LE(_field31E8); - s.syncAsSint16LE(_field31EA); + s.syncAsSint16LE(_lineNumModifier); + s.syncAsSint16LE(_jukeboxPlaying); + s.syncAsSint16LE(_talkToTonyCtr); } /*-------------------------------------------------------------------------- @@ -3123,7 +3123,7 @@ void Scene180::dispatch() { * *--------------------------------------------------------------------------*/ -bool Scene190::Object4::startAction(CursorType action, Event &event) { +bool Scene190::LyleCar::startAction(CursorType action, Event &event) { Scene190 *scene = (Scene190 *)BF_GLOBALS._sceneManager._scene; switch (action) { @@ -3191,14 +3191,14 @@ void Scene190::Action1::signal() { } case 2: scene->_sound.play(82); - scene->_object2.animate(ANIM_MODE_5, this); + scene->_door.animate(ANIM_MODE_5, this); break; case 3: ADD_MOVER(BF_GLOBALS._player, 180, 86); break; case 4: scene->_sound.play(82); - scene->_object2.animate(ANIM_MODE_6, this); + scene->_door.animate(ANIM_MODE_6, this); break; case 5: BF_GLOBALS._sound1.fadeOut2(NULL); @@ -3220,12 +3220,17 @@ void Scene190::postInit(SceneObjectList *OwnerList) { (BF_GLOBALS._sceneManager._previousScene == 20)) { // clearScreen(); } - if (BF_GLOBALS._dayNumber == 0) + if (BF_GLOBALS._dayNumber == 0) { // If at start of game, change to first day BF_GLOBALS._dayNumber = 1; + // To be checked: Not present in the original + g_globals->_sceneManager._previousScene = 100; + } + SceneExt::postInit(); // Load the scene data loadScene(190); + BF_GLOBALS._scenePalette.loadPalette(2); _stripManager.addSpeaker(&_speaker); @@ -3233,18 +3238,20 @@ void Scene190::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._player.disableControl(); // Initialise objects - _object2.postInit(); - _object2.setVisage(190); - _object2.setStrip(1); - _object2.setPosition(Common::Point(179, 88)); + _door.postInit(); + _door.setVisage(190); + _door.setStrip(1); + _door.setPosition(Common::Point(179, 88)); - _object3.postInit(); - _object3.setVisage(190); - _object3.setStrip(2); - _object3.fixPriority(200); - _object3.setPosition(Common::Point(170, 31)); - _object3.animate(ANIM_MODE_7, 0, NULL); - _object3.setDetails(190, 8, 26, 19, 1, NULL); + _flag.postInit(); + _flag.setVisage(190); + _flag.setStrip(2); + _flag.fixPriority(200); + _flag.setPosition(Common::Point(170, 31)); + _flag.animate(ANIM_MODE_7, 0, NULL); + _flag.setDetails(190, 8, 26, 19, 1, NULL); + + _fieldB52 = true; if (BF_GLOBALS.getFlag(fWithLyle)) { BF_GLOBALS._player.setVisage(303); @@ -3252,11 +3259,11 @@ void Scene190::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._player.animate(ANIM_MODE_1, NULL); BF_GLOBALS._player._moveDiff = Common::Point(3, 1); - _object4.postInit(); - _object4.setVisage(444); - _object4.setFrame(2); - _object4.setPosition(Common::Point(54, 114)); - _object4.setDetails(190, -1, -1, -1, 1, NULL); + _lyleCar.postInit(); + _lyleCar.setVisage(444); + _lyleCar.setFrame(2); + _lyleCar.setPosition(Common::Point(54, 114)); + _lyleCar.setDetails(190, -1, -1, -1, 1, NULL); switch (BF_GLOBALS._sceneManager._previousScene) { case 300: { @@ -3267,7 +3274,7 @@ void Scene190::postInit(SceneObjectList *OwnerList) { } case 315: _sceneMode = 1901; - setAction(&_sequenceManager, this, 1901, &BF_GLOBALS._player, &_object2, NULL); + setAction(&_sequenceManager, this, 1901, &BF_GLOBALS._player, &_door, NULL); break; case 50: case 60: @@ -3301,13 +3308,14 @@ void Scene190::postInit(SceneObjectList *OwnerList) { case 315: BF_GLOBALS._player._moveDiff = Common::Point(3, 1); _sceneMode = BF_GLOBALS.getFlag(onDuty) ? 1900 : 1901; - setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, &_object2, NULL); + setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, &_door, NULL); break; case 50: case 60: default: BF_GLOBALS.setFlag(onBike); BF_GLOBALS._player.disableControl(); + // To be checked: Not present in the original T2_GLOBALS._uiElements._active = true; _sceneMode = BF_GLOBALS.getFlag(onDuty) ? 192 : 190; setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, NULL); diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h index bdf414ec9b..3424521e5a 100644 --- a/engines/tsage/blue_force/blueforce_scenes1.h +++ b/engines/tsage/blue_force/blueforce_scenes1.h @@ -99,11 +99,12 @@ public: SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3; SequenceManager _sequenceManager4, _sequenceManager5, _sequenceManager6; SequenceManager _sequenceManager7, _sequenceManager8; - SceneObject _object1, _object2, _protaginist2, _protaginist1, _object5; - SceneObject _drunk, _object7, _bartender, _object9, _object10; + SceneObject _object1, _object2, _protaginist2, _protaginist1, _cop1; + SceneObject _drunk, _cop2, _bartender, _beerSign, _animationInset; IntroSceneText _text; Action1 _action1; - Action _action2, _action3; + Action2 _action2; + Action3 _action3; public: Scene109(); @@ -170,11 +171,11 @@ public: class Scene115: public SceneExt { /* Objects */ - class Object1: public NamedObject { + class Kate: public NamedObject { public: virtual bool startAction(CursorType action, Event &event); }; - class Object2: public NamedObject { + class Tony: public NamedObject { public: int _field15F8; virtual bool startAction(CursorType action, Event &event); @@ -196,12 +197,12 @@ class Scene115: public SceneExt { }; /* Items */ - class Item1: public NamedHotspot { + class Jukebox: public NamedHotspot { SequenceManager _sequenceManager6; public: - int _field1F8A; + int _jokeboxPlayingCtr; - Item1(); + Jukebox(); virtual bool startAction(CursorType action, Event &event); virtual void signal(); virtual void synchronize(Serializer &s); @@ -258,13 +259,13 @@ class Scene115: public SceneExt { SequenceManager _sequenceManager3; SequenceManager _sequenceManager4; SequenceManager _sequenceManager5; - Object1 _object1; - Object2 _object2; + Kate _kate; + Tony _tony; Object3 _object3; Object4 _object4; - SceneObject _object5, _object6, _object7, _object8, _object9; + SceneObject _object5, _object6, _neonSign, _object8, _object9; SceneObject _object10, _object11, _object12, _object13; - Item1 _item1; + Jukebox _itemJukebox; EventHandler1 _eventHandler1; NamedHotspot _item2, _item3, _item4, _item5, _item6, _item7, _item8, _item9; Item10 _item10; @@ -286,9 +287,9 @@ class Scene115: public SceneExt { SpeakerJakeUniform _jakeUniformSpeaker; SpeakerLyleHat _lyleHatSpeaker; ASound _sound1; - int _field168A; - int _field31E8; - int _field31EA; + int _lineNumModifier; + int _jukeboxPlaying; + int _talkToTonyCtr; public: Scene115(); virtual void synchronize(Serializer &s); @@ -431,7 +432,7 @@ public: class Scene190: public SceneExt { /* Objects */ - class Object4: public NamedObject { + class LyleCar: public NamedObject { public: virtual bool startAction(CursorType action, Event &event); }; @@ -458,8 +459,8 @@ class Scene190: public SceneExt { public: SequenceManager _sequenceManager; FollowerObject _object1; - NamedObject _object2, _object3; - Object4 _object4; + NamedObject _door, _flag; + LyleCar _lyleCar; Item1 _item1; Item2 _item2; NamedHotspot _item3, _item4, _item5, _item6; diff --git a/engines/tsage/blue_force/blueforce_scenes2.cpp b/engines/tsage/blue_force/blueforce_scenes2.cpp index 4b26d8d604..5a181af927 100644 --- a/engines/tsage/blue_force/blueforce_scenes2.cpp +++ b/engines/tsage/blue_force/blueforce_scenes2.cpp @@ -1152,7 +1152,7 @@ void Scene270::signal() { _grandma.setStrip(8); _grandma._frame = 5; _field384 = 1; - _field384 = 1; + _field386 = 1; BF_GLOBALS._player._moveDiff.x = 8; BF_GLOBALS._player.enableControl(); @@ -1290,7 +1290,7 @@ void Scene270::dispatch() { void Scene271::Action1::signal() { Scene271 *scene = (Scene271 *)BF_GLOBALS._sceneManager._scene; - scene->setAction(&scene->_sequenceManager2, this, 2703, &scene->_tv, NULL); + setAction(&scene->_sequenceManager2, this, 2703, &scene->_tv, NULL); } /*--------------------------------------------------------------------------*/ @@ -1454,7 +1454,7 @@ void Scene271::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._walkRegions.disableRegion(14); BF_GLOBALS._walkRegions.disableRegion(19); - BF_GLOBALS._player.setVisage(151); + BF_GLOBALS._player.setVisage(275); BF_GLOBALS._player.setPosition(Common::Point(348, 151)); _object12.postInit(); diff --git a/engines/tsage/blue_force/blueforce_scenes3.cpp b/engines/tsage/blue_force/blueforce_scenes3.cpp index d1ed2cd5e6..1dea7f7687 100644 --- a/engines/tsage/blue_force/blueforce_scenes3.cpp +++ b/engines/tsage/blue_force/blueforce_scenes3.cpp @@ -58,7 +58,7 @@ bool Scene300::Object19::startAction(CursorType action, Event &event) { return true; } - +// entrance door bool Scene300::Item1::startAction(CursorType action, Event &event) { if (action == CURSOR_USE) { Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene; @@ -75,6 +75,8 @@ bool Scene300::Item1::startAction(CursorType action, Event &event) { bool Scene300::Item2::startAction(CursorType action, Event &event) { if ((action == CURSOR_LOOK) || (action == CURSOR_USE)) { Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene; + BF_GLOBALS._player.disableControl(); + scene->_sceneMode = 0; scene->setAction(&scene->_sequenceManager1, scene, 304, &scene->_object11, NULL); return true; } else { @@ -108,7 +110,7 @@ void Scene300::Action1::signal() { setDelay(1); break; case 2: { - ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8, + ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8, BF_GLOBALS._player._position.y); break; } @@ -183,12 +185,13 @@ void Scene300::Action4::signal() { break; case 2: BF_GLOBALS._sceneManager.changeScene(60); + setDelay(15); break; case 3: setAction(&scene->_sequenceManager1, this, 319, &scene->_object19, NULL); break; case 4: - BF_GLOBALS.setFlag(2); + BF_GLOBALS.setFlag(onBike); BF_GLOBALS._sceneManager.changeScene(190); break; default: @@ -213,6 +216,7 @@ void Scene300::Action5::signal() { break; case 3: { ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 186, 140); + setDelay(3); break; } case 4: @@ -302,14 +306,14 @@ void Scene300::postInit(SceneObjectList *OwnerList) { break; case 190: _sceneMode = 0; - if (!BF_GLOBALS.getFlag(2)) { + if (!BF_GLOBALS.getFlag(onBike)) { _sceneMode = 7308; BF_GLOBALS._player.setPosition(Common::Point(175, 50)); ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, 123, 71); if ((BF_GLOBALS._dayNumber == 2) && (BF_GLOBALS._bookmark < bEndDayOne)) setupInspection(); - } else if (!BF_GLOBALS.getFlag(3)) { + } else if (!BF_GLOBALS.getFlag(onDuty)) { BF_GLOBALS._player.disableControl(); _sceneMode = 300; setAction(&_sequenceManager1, this, 300, &BF_GLOBALS._player, NULL); @@ -420,7 +424,7 @@ void Scene300::signal() { setAction(&_sequenceManager1, this, 312, &_object1, &_object16, NULL); break; case 317: - BF_GLOBALS.setFlag(2); + BF_GLOBALS.setFlag(onBike); BF_GLOBALS._sceneManager.changeScene(60); break; case 318: @@ -474,10 +478,10 @@ void Scene300::signal() { _object10.postInit(); _object10.hide(); - if (BF_GLOBALS.getFlag(1)) { + if (BF_GLOBALS.getFlag(gunClean)) { BF_GLOBALS._player.disableControl(); _sceneMode = 4308; - setAction(&_sequenceManager1, this, 6307, &_object2, &_object1, &_object9, &_object10, NULL); + setAction(&_sequenceManager1, this, 6307, &_object12, &_object1, &_object9, &_object10, NULL); } else { BF_GLOBALS._player.disableControl(); _sceneMode = 4308; @@ -552,7 +556,7 @@ void Scene300::dispatch() { if ((BF_GLOBALS._player._position.y < 59) && (BF_GLOBALS._player._position.x > 137) && (_sceneMode != 6308) && (_sceneMode != 7308)) { - BF_GLOBALS._v4CEA4 = 3; + // The original was setting a useless global variable (removed) _sceneMode = 6308; BF_GLOBALS._player.disableControl(); ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x + 20, @@ -638,7 +642,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_USE: - if (scene->_field1B60 || scene->_field1B64) + if (scene->_invGreenCount || scene->_invGangCount) SceneItem::display2(320, 51); else NamedHotspot::startAction(action, event); @@ -667,7 +671,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) { scene->_stripNumber = 3174; scene->setAction(&scene->_action1); } else { - ++scene->_field1B62; + ++scene->_bookGreenCount; scene->_stripNumber = (action == INV_GREENS_GUN) ? 3168 : 0; scene->_sceneMode = 3153; scene->setAction(&scene->_sequenceManager, scene, 3153, &BF_GLOBALS._player, NULL); @@ -675,7 +679,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) { break; case INV_FOREST_RAP: BF_GLOBALS._player.disableControl(); - scene->_stripNumber = BF_GLOBALS.getFlag(onDuty) ? 3178 : 3173; + scene->_stripNumber = BF_GLOBALS.getFlag(onDuty) ? 3173 : 3178; scene->setAction(&scene->_action1); break; case INV_GREEN_ID: @@ -693,7 +697,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) { scene->setAction(&scene->_action1); break; case INV_COBB_RAP: - if (BF_INVENTORY._mugshot._sceneNumber == 1) + if (BF_INVENTORY.getObjectScene(INV_MUG_SHOT) == 1) NamedHotspot::startAction(action, event); else { BF_GLOBALS._player.disableControl(); @@ -717,8 +721,8 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) { scene->_stripNumber = 3174; scene->setAction(&scene->_action1); } else { - ++scene->_field1B66; - if (!scene->_field1B6C && (scene->_field1B66 == 1)) { + ++scene->_bookGangCount; + if (!scene->_field1B6C && (scene->_bookGangCount == 1)) { scene->_field1B6C = 1; scene->_stripNumber = 3169; } else { @@ -759,9 +763,9 @@ bool Scene315::SutterSlot::startAction(CursorType action, Event &event) { case INV_BOOKING_FRANKIE: case INV_BOOKING_GANG: if (action == INV_BOOKING_GREEN) - ++scene->_field1B62; + ++scene->_bookGreenCount; else - ++scene->_field1B66; + ++scene->_bookGangCount; BF_GLOBALS._player.disableControl(); scene->_sceneMode = 12; @@ -874,6 +878,7 @@ bool Scene315::BulletinMemo::startAction(CursorType action, Event &event) { } } +// Own Mail Slot bool Scene315::Object2::startAction(CursorType action, Event &event) { Scene315 *scene = (Scene315 *)BF_GLOBALS._sceneManager._scene; @@ -939,6 +944,10 @@ void Scene315::Action1::signal() { if (scene->_sceneMode == 3169) { T2_GLOBALS._uiElements.addScore(30); BF_INVENTORY.setObjectScene(INV_MUG_SHOT, 1); + //HACK: This has to be checked wether or not it occurs in the original. + //When the _sceneMode is set to 3169, the value desn't change. + //If you show the forest rapsheet, it gives points (and again... and again...) + scene->_sceneMode = 3154; } remove(); @@ -957,9 +966,9 @@ Scene315::Scene315() { BF_GLOBALS.clearFlag(fCanDrawGun); _field1B68 = true; - _field1B6A = false; - _field1B60 = _field1B62 = 0; - _field1B64 = _field1B66 = 0; + _doorOpened = false; + _invGreenCount = _bookGreenCount = 0; + _invGangCount = _bookGangCount = 0; } void Scene315::synchronize(Serializer &s) { @@ -968,18 +977,19 @@ void Scene315::synchronize(Serializer &s) { s.syncAsSint16LE(_field1390); s.syncAsSint16LE(_stripNumber); s.syncAsSint16LE(_field1398); - s.syncAsSint16LE(_field1B60); - s.syncAsSint16LE(_field1B62); - s.syncAsSint16LE(_field1B64); - s.syncAsSint16LE(_field1B66); + s.syncAsSint16LE(_invGreenCount); + s.syncAsSint16LE(_bookGreenCount); + s.syncAsSint16LE(_invGangCount); + s.syncAsSint16LE(_bookGangCount); s.syncAsSint16LE(_field1B6C); s.syncAsSint16LE(_field139C); s.syncAsByte(_field1B68); - s.syncAsByte(_field1B6A); + s.syncAsByte(_doorOpened); s.syncAsSint16LE(_currentCursor); } void Scene315::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(OwnerList); loadScene(315); if (BF_GLOBALS._sceneManager._previousScene != 325) @@ -1061,29 +1071,29 @@ void Scene315::postInit(SceneObjectList *OwnerList) { // Set up evidence objects in inventory if (BF_INVENTORY._bookingGreen.inInventory()) - ++_field1B60; + ++_invGreenCount; if (BF_INVENTORY._greensGun.inInventory()) - ++_field1B60; + ++_invGreenCount; if (BF_INVENTORY._greensKnife.inInventory()) - ++_field1B60; + ++_invGreenCount; if (BF_INVENTORY._bullet22.inInventory()) - ++_field1B64; + ++_invGangCount; if (BF_INVENTORY._autoRifle.inInventory()) - ++_field1B64; + ++_invGangCount; if (BF_INVENTORY._wig.inInventory()) - ++_field1B64; + ++_invGangCount; if (BF_INVENTORY._bookingFrankie.inInventory()) - ++_field1B64; + ++_invGangCount; if (BF_INVENTORY._bookingGang.inInventory()) - ++_field1B64; + ++_invGangCount; if (BF_INVENTORY._snub22.inInventory()) - ++_field1B64; + ++_invGangCount; switch (BF_GLOBALS._sceneManager._previousScene) { case 190: if (_field1398) - _field1B6A = true; + _doorOpened = true; _sceneMode = BF_GLOBALS.getFlag(onDuty) ? 3150 : 3165; setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, NULL); break; @@ -1099,7 +1109,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) { case 300: default: if (_field1398) - _field1B6A = true; + _doorOpened = true; if (!BF_GLOBALS.getFlag(onDuty)) _sceneMode = 3166; else if (!_field1398) @@ -1111,7 +1121,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) { break; } - if (_field1B6A) { + if (_doorOpened) { _object8.setFrame(8); } else { BF_GLOBALS._walkRegions.disableRegion(4); @@ -1135,15 +1145,15 @@ void Scene315::signal() { BF_GLOBALS._player.enableControl(); break; case 10: - if (_field1B62) { - if (_field1B62 >= _field1B60) + if (_bookGreenCount) { + if (_bookGreenCount >= _invGreenCount) BF_GLOBALS.setFlag(fLeftTraceIn910); else ++ctr; } - if (_field1B66) { - if (_field1B66 < _field1B64) + if (_bookGangCount) { + if (_bookGangCount < _invGangCount) ++ctr; else if (BF_GLOBALS._bookmark < bBookedFrankieEvidence) BF_GLOBALS._bookmark = bBookedFrankieEvidence; @@ -1158,15 +1168,15 @@ void Scene315::signal() { BF_GLOBALS._sound1.fadeOut2(NULL); break; case 11: - if (_field1B62) { - if (_field1B62 >= _field1B60) + if (_bookGreenCount) { + if (_bookGreenCount >= _invGreenCount) BF_GLOBALS.setFlag(fLeftTraceIn910); else ++ctr; } - if (_field1B66) { - if (_field1B66 < _field1B64) + if (_bookGangCount) { + if (_bookGangCount < _invGangCount) ++ctr; else if (BF_GLOBALS._bookmark < bBookedFrankie) BF_GLOBALS._bookmark = bBookedFrankie; @@ -1195,7 +1205,7 @@ void Scene315::signal() { T2_GLOBALS._uiElements.addScore(30); BF_INVENTORY.setObjectScene((int)_currentCursor, 315); - if (!_field1B64 || (_field1B66 != _field1B64)) + if (!_invGangCount || (_bookGangCount != _invGangCount)) BF_GLOBALS._player.enableControl(); else { _field139C = 1; @@ -1217,7 +1227,8 @@ void Scene315::signal() { BF_GLOBALS._walkRegions.disableRegion(4); _object7.remove(); _object6.remove(); - + // No break on purpose + case 3155: BF_GLOBALS._player.enableControl(); _field1B68 = false; BF_GLOBALS._walkRegions.disableRegion(4); @@ -1230,7 +1241,7 @@ void Scene315::signal() { if (_stripNumber != 0) setAction(&_action1); - else if (!_field1B64 || (_field1B66 != _field1B64)) + else if (!_invGangCount || (_bookGangCount != _invGangCount)) BF_GLOBALS._player.enableControl(); else { _stripNumber = 3171; @@ -1238,13 +1249,6 @@ void Scene315::signal() { _field139C = 1; } break; - case 3155: - BF_GLOBALS._player.enableControl(); - _field1B68 = false; - BF_GLOBALS._walkRegions.disableRegion(4); - T2_GLOBALS._uiElements._active = true; - T2_GLOBALS._uiElements.show(); - break; case 3156: T2_GLOBALS._uiElements.addScore(10); BF_INVENTORY.setObjectScene(INV_DA_NOTE, 1); @@ -1287,6 +1291,11 @@ void Scene315::signal() { BF_GLOBALS._player.enableControl(); _object9.remove(); break; + case 3169: + T2_GLOBALS._uiElements.addScore(30); + BF_INVENTORY.setObjectScene(INV_MUG_SHOT, 1); + BF_GLOBALS._player.enableControl(); + break; case 3154: default: break; @@ -1318,7 +1327,7 @@ void Scene315::dispatch() { if (_field1B68) return; - if (_field1B6A) { + if (_doorOpened) { if (BF_GLOBALS._player._position.y < 69) { BF_GLOBALS._player.disableControl(); _field1B68 = true; @@ -2971,8 +2980,8 @@ bool Scene355::LockerInset::startAction(CursorType action, Event &event) { if (_frame == 1) { SceneItem::display2(355, 23); return true; - } - return true; + } else + return NamedObject::startAction(action, event); case INV_SCREWDRIVER: scene->_sound2.play(104); BF_INVENTORY.setObjectScene(INV_SCREWDRIVER, 999); @@ -4338,13 +4347,12 @@ void Scene360::Action1::signal() { /*--------------------------------------------------------------------------*/ -Scene360::Scene360() { - _uselessVariable = 0; -} - void Scene360::synchronize(Serializer &s) { SceneExt::synchronize(s); - s.syncAsSint16LE(_uselessVariable); + if (s.getVersion() < 9) { + int tmpVar; + s.syncAsSint16LE(tmpVar); + } } void Scene360::postInit(SceneObjectList *OwnerList) { @@ -4423,7 +4431,7 @@ void Scene360::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._player.enableControl(); if ((BF_GLOBALS._sceneManager._previousScene == 355) || (BF_GLOBALS._sceneManager._previousScene != 370)) { - _uselessVariable = 0; + // The original was using there a useless variable (now removed) BF_GLOBALS._player.setPosition(Common::Point(253, 135)); BF_GLOBALS._player.setStrip(2); @@ -5317,8 +5325,7 @@ bool Scene385::Door::startAction(CursorType action, Event &event) { bool Scene385::Jim::startAction(CursorType action, Event &event) { Scene385 *scene = (Scene385 *)BF_GLOBALS._sceneManager._scene; - switch (action) { - case CURSOR_TALK: + if (action == CURSOR_TALK) { if (scene->_jimFlag) { scene->_talkAction = 3867; scene->setAction(&scene->_action1); @@ -5342,24 +5349,24 @@ bool Scene385::Jim::startAction(CursorType action, Event &event) { break; } - scene->_jimFlag = 1; + scene->_jimFlag = true; scene->setAction(&scene->_action1); } return true; - case INV_PRINT_OUT: + } else if (action == INV_PRINT_OUT) { if (!BF_GLOBALS.getFlag(fGotPointsForMCard)) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.getFlag(fGotPointsForMCard); + BF_GLOBALS.setFlag(fGotPointsForMCard); scene->setAction(&scene->_action2); return true; - } - break; - default: - break; - } - - return NamedObject::startAction(action, event); + } else + return false; + } else if (action < CURSOR_WALK) + // Any other inventory item + return false; + else + return NamedObject::startAction(action, event); } bool Scene385::Dezi::startAction(CursorType action, Event &event) { @@ -5430,7 +5437,8 @@ bool Scene385::Exit::startAction(CursorType action, Event &event) { Scene385::Scene385(): SceneExt() { - _talkAction = _jimFlag = 0; + _talkAction = 0; + _jimFlag = false; } void Scene385::synchronize(Serializer &s) { diff --git a/engines/tsage/blue_force/blueforce_scenes3.h b/engines/tsage/blue_force/blueforce_scenes3.h index 73fcef2851..ea9d5f7311 100644 --- a/engines/tsage/blue_force/blueforce_scenes3.h +++ b/engines/tsage/blue_force/blueforce_scenes3.h @@ -213,9 +213,9 @@ public: int _field1390; int _stripNumber; int _field1398; - int _field1B60, _field1B62, _field1B64; - int _field1B66, _field1B6C, _field139C; - bool _field1B68, _field1B6A; + int _invGreenCount, _bookGreenCount, _invGangCount; + int _bookGangCount, _field1B6C, _field139C; + bool _field1B68, _doorOpened; CursorType _currentCursor; Scene315(); @@ -676,9 +676,7 @@ public: Barometer _barometer; Action1 _action1; ASound _sound1; - int _uselessVariable; - Scene360(); virtual void synchronize(Serializer &s); virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void signal(); @@ -815,7 +813,8 @@ public: SpeakerJake385 _jake385Speaker; NamedHotspot _item1, _item2, _item3, _item4, _item5; Exit _exit; - int _talkAction, _jimFlag; + int _talkAction; + bool _jimFlag; Scene385(); virtual void synchronize(Serializer &s); diff --git a/engines/tsage/blue_force/blueforce_scenes4.cpp b/engines/tsage/blue_force/blueforce_scenes4.cpp index 4cff38feab..deff4f2518 100644 --- a/engines/tsage/blue_force/blueforce_scenes4.cpp +++ b/engines/tsage/blue_force/blueforce_scenes4.cpp @@ -371,21 +371,27 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_USE: if (!BF_GLOBALS.getFlag(fCalledBackup)) { - if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup)) { + if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup)) scene->setAction(&scene->_action3); - } else { - SceneItem::display2(410, 5); - } + else + SceneItem::display(410, 5, SET_WIDTH, 300, + SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left, + SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2, + SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99, + SET_EXT_FGCOLOR, 13, LIST_END); } else if (!scene->_field1FBA) { - SceneItem::display2(410, 5); + SceneItem::display(410, 5, SET_WIDTH, 300, + SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left, + SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2, + SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99, + SET_EXT_FGCOLOR, 13, LIST_END); } else if (!scene->_field1FBE) { scene->_sceneMode = 4121; scene->_field1FBE = 1; T2_GLOBALS._uiElements.addScore(50); scene->signal(); - } else { + } else break; - } return true; case CURSOR_TALK: scene->setAction(&scene->_action5); @@ -711,6 +717,7 @@ void Scene410::signal() { break; case 7: BF_INVENTORY.setObjectScene(INV_TYRONE_ID, 1); + _sceneMode = 0; signal(); break; case 8: @@ -778,6 +785,7 @@ void Scene410::signal() { BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper()); BF_GLOBALS._player.updateAngle(Common::Point(100, 170)); BF_GLOBALS._walkRegions.enableRegion(22); + BF_GLOBALS._walkRegions.enableRegion(7); BF_GLOBALS._walkRegions.enableRegion(16); BF_GLOBALS._player.disableControl(); _sceneMode = 0; @@ -920,6 +928,17 @@ bool Scene415::GunInset::startAction(CursorType action, Event &event) { } } +void Scene415::GunInset::remove() { + Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene; + + BF_GLOBALS._player.disableControl(); + scene->_gunAndWig.remove(); + FocusObject::remove(); + + scene->_sceneMode = 0; + scene->_animatedSeat.animate(ANIM_MODE_6, scene); +} + bool Scene415::GunAndWig::startAction(CursorType action, Event &event) { Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene; @@ -954,7 +973,7 @@ bool Scene415::BulletsInset::startAction(CursorType action, Event &event) { Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene; if (action == CURSOR_USE) { - if (BF_GLOBALS.getFlag(fGotAutoWeapon)) { + if (BF_GLOBALS.getFlag(fGotBulletsFromDash)) { FocusObject::startAction(action, event); } else { remove(); @@ -966,6 +985,13 @@ bool Scene415::BulletsInset::startAction(CursorType action, Event &event) { } } +void Scene415::BulletsInset::remove() { + Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene; + + scene->_theBullets.remove(); + FocusObject::remove(); +} + bool Scene415::DashDrawer::startAction(CursorType action, Event &event) { Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene; @@ -993,7 +1019,6 @@ bool Scene415::TheBullets::startAction(CursorType action, Event &event) { case INV_FOREST_RAP: if (scene->_scoreBulletRapFlag) { SceneItem::display2(415, 35); - return true; } else { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 0; @@ -1001,7 +1026,7 @@ bool Scene415::TheBullets::startAction(CursorType action, Event &event) { T2_GLOBALS._uiElements.addScore(50); scene->_scoreBulletRapFlag = true; } - break; + return true; default: break; } @@ -1021,7 +1046,7 @@ bool Scene415::Lever::startAction(CursorType action, Event &event) { } else { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 2; - scene->setAction(&scene->_sequenceManager, scene, 4150, &scene->_object6, NULL); + scene->setAction(&scene->_sequenceManager, scene, 4150, &scene->_animatedSeat, NULL); } return true; default: @@ -1053,11 +1078,11 @@ void Scene415::postInit(SceneObjectList *OwnerList) { _dashDrawer.setPosition(Common::Point(151, 97)); _dashDrawer.setDetails(415, 22, -1, -1, 1, NULL); - _object6.postInit(); - _object6.setVisage(419); - _object6.setStrip(1); - _object6.setPosition(Common::Point(306, 116)); - _object6.fixPriority(80); + _animatedSeat.postInit(); + _animatedSeat.setVisage(419); + _animatedSeat.setStrip(1); + _animatedSeat.setPosition(Common::Point(306, 116)); + _animatedSeat.fixPriority(80); _windowLever.setDetails(16, 415, 25, -1, 26, 1); _item7.setDetails(17, 415, 32, -1, 33, 1); diff --git a/engines/tsage/blue_force/blueforce_scenes4.h b/engines/tsage/blue_force/blueforce_scenes4.h index 48b48ec7f8..937c015a4c 100644 --- a/engines/tsage/blue_force/blueforce_scenes4.h +++ b/engines/tsage/blue_force/blueforce_scenes4.h @@ -133,6 +133,7 @@ class Scene415: public SceneExt { class GunInset: public FocusObject { public: virtual bool startAction(CursorType action, Event &event); + virtual void remove(); }; class GunAndWig: public NamedObject { public: @@ -141,6 +142,7 @@ class Scene415: public SceneExt { class BulletsInset: public FocusObject { public: virtual bool startAction(CursorType action, Event &event); + virtual void remove(); }; class DashDrawer: public NamedObject { public: @@ -166,7 +168,7 @@ public: BulletsInset _bulletsInset; DashDrawer _dashDrawer; TheBullets _theBullets; - NamedObject _object6; + NamedObject _animatedSeat; NamedHotspot _item1, _steeringWheel, _horn, _dashboard; NamedHotspot _seat, _windowLever, _item7, _seatBelt; Lever _lever; diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp index d1f1e90234..7a250e2233 100644 --- a/engines/tsage/blue_force/blueforce_scenes5.cpp +++ b/engines/tsage/blue_force/blueforce_scenes5.cpp @@ -924,7 +924,7 @@ void Scene560::Action1::signal() { scene->_deskChair.setStrip(BF_GLOBALS._player._strip); scene->_deskChair.setPosition(BF_GLOBALS._player._position); - scene->_field380 = 1; + scene->_field380 = true; BF_GLOBALS._player.enableControl(); remove(); break; @@ -950,7 +950,7 @@ void Scene560::Action2::signal() { BF_GLOBALS._player.animate(ANIM_MODE_6, this); break; case 2: - scene->_field380 = 0; + scene->_field380 = false; scene->_deskChair.setPosition(Common::Point(81, 149)); scene->_deskChair.setVisage(561); scene->_deskChair.setStrip(3); @@ -1378,7 +1378,7 @@ bool Scene560::Computer::startAction(CursorType action, Event &event) { /*--------------------------------------------------------------------------*/ Scene560::Scene560(): SceneExt() { - _field380 = _field11EA = 0; + _field380 = _field11EA = false; } void Scene560::postInit(SceneObjectList *OwnerList) { @@ -1433,12 +1433,12 @@ void Scene560::postInit(SceneObjectList *OwnerList) { _deskChair.setStrip(BF_GLOBALS._player._strip); _deskChair.setPosition(BF_GLOBALS._player._position); - _field11EA = 0; - _field380 = 1; + _field11EA = false; + _field380 = true; } else { // Entering study through doorway - _field11EA = 0; - _field380 = 0; + _field11EA = false; + _field380 = false; BF_GLOBALS._player.postInit(); BF_GLOBALS._player.setVisage(563); @@ -1529,7 +1529,7 @@ void Scene560::signal() { } break; case 10: - _field11EA = 0; + _field11EA = false; BF_GLOBALS._player.enableControl(); break; case 11: @@ -1540,7 +1540,7 @@ void Scene560::signal() { void Scene560::process(Event &event) { if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) && - (_field380 == 1) && !_action) { + (_field380) && !_action) { _destPosition = event.mousePos; BF_GLOBALS._player.disableControl(); setAction(&_action2); @@ -1553,7 +1553,7 @@ void Scene560::process(Event &event) { void Scene560::dispatch() { if (!_field11EA && (BF_GLOBALS._player._position.y < 105)) { - _field11EA = 1; + _field11EA = true; BF_GLOBALS._player.disableControl(); BF_GLOBALS._sceneManager.changeScene(270); } @@ -2220,7 +2220,6 @@ void Scene580::postInit(SceneObjectList *OwnerList) { _vechile.setStrip(3); _vechile.setPosition(Common::Point(165, 76)); _vechile.setDetails(580, 2, 3, -1, 1, NULL); - _vechile.setVisage(303); BF_GLOBALS._player.setVisage(303); diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h index 34328ab9e8..76bf4cdbc3 100644 --- a/engines/tsage/blue_force/blueforce_scenes5.h +++ b/engines/tsage/blue_force/blueforce_scenes5.h @@ -228,7 +228,8 @@ public: NamedHotspot _chair, _lamp, _item4, _trophy, _watercolours, _fileCabinets; NamedHotspot _certificate, _bookcase, _desk, _carpet, _item12, _office; ASound _sound1; - int _field380, _field11EA; + bool _field380; + bool _field11EA; Common::Point _destPosition; Scene560(); diff --git a/engines/tsage/blue_force/blueforce_scenes6.cpp b/engines/tsage/blue_force/blueforce_scenes6.cpp index 5a651d8475..5fb1b562e0 100644 --- a/engines/tsage/blue_force/blueforce_scenes6.cpp +++ b/engines/tsage/blue_force/blueforce_scenes6.cpp @@ -37,7 +37,7 @@ namespace BlueForce { void Scene600::Action1::signal() { Scene600 *scene = (Scene600 *)BF_GLOBALS._sceneManager._scene; - static const uint32 black = 0; + static byte red[3] = {220, 0, 0}; switch (_actionIndex++) { case 0: @@ -49,8 +49,8 @@ void Scene600::Action1::signal() { break; case 2: scene->_sound1.play(59); - setAction(&scene->_sequenceManager, this, 600, &scene->_object2, &scene->_object1, - &BF_GLOBALS._player, &scene->_object3, NULL); + setAction(&scene->_sequenceManager, this, 600, &scene->_object2, &scene->_ryan, + &BF_GLOBALS._player, &scene->_skidMarks, NULL); break; case 3: BF_GLOBALS._sound1.play(61); @@ -61,13 +61,13 @@ void Scene600::Action1::signal() { break; case 5: { BF_GLOBALS._player.remove(); - scene->_object1.remove(); + scene->_ryan.remove(); scene->_object2.remove(); - scene->_object3.remove(); + scene->_skidMarks.remove(); - for (int percent = 100; percent >= 0; percent -= 5) { - BF_GLOBALS._scenePalette.fade((const byte *)&black, false, percent); - g_system->delayMillis(10); + for (int percent = 100; percent >= 0; percent -= 2) { + BF_GLOBALS._scenePalette.fade((const byte *)&red, false, percent); + g_system->delayMillis(5); } SynchronizedList<SceneObject *>::iterator i; @@ -91,6 +91,8 @@ void Scene600::Action1::signal() { BF_GLOBALS._v51C44 = 0; remove(); break; + default: + break; } } @@ -110,14 +112,14 @@ void Scene600::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._player.setPosition(Common::Point(639, 0)); BF_GLOBALS._player.disableControl(); - _object3.postInit(); - _object3.hide(); + _skidMarks.postInit(); + _skidMarks.hide(); _object2.postInit(); - - _object1.postInit(); - _object1.setVisage(600); - _object1.setStrip(7); - _object1.setPosition(Common::Point(417, 82)); + + _ryan.postInit(); + _ryan.setVisage(600); + _ryan.setStrip(7); + _ryan.setPosition(Common::Point(417, 82)); BF_GLOBALS.clearFlag(onDuty); BF_INVENTORY.setObjectScene(INV_TICKET_BOOK, 60); @@ -181,7 +183,7 @@ void Scene620::signal() { _object1.postInit(); _object1.setVisage(622); _object1.setPosition(Common::Point(101, 41)); - addFader((const byte *)&black, 2, this); + add2Faders((const byte *)&black, 2, 622, this); break; case 5: _object1.remove(); @@ -240,6 +242,8 @@ void Scene620::signal() { BF_GLOBALS._dayNumber = 3; BF_GLOBALS._sceneManager.changeScene(271); break; + default: + break; } } diff --git a/engines/tsage/blue_force/blueforce_scenes6.h b/engines/tsage/blue_force/blueforce_scenes6.h index e354e9e069..3f9c14aa11 100644 --- a/engines/tsage/blue_force/blueforce_scenes6.h +++ b/engines/tsage/blue_force/blueforce_scenes6.h @@ -49,7 +49,7 @@ public: SequenceManager _sequenceManager; Action1 _action1; ASoundExt _sound1; - NamedObject _object1, _object2, _object3; + NamedObject _ryan, _object2, _skidMarks; BackgroundSceneObject _object4, _object5; BackgroundSceneObject _object6, _object7, _object8; diff --git a/engines/tsage/blue_force/blueforce_scenes7.cpp b/engines/tsage/blue_force/blueforce_scenes7.cpp index 21a27640e9..7b84e3ccdd 100644 --- a/engines/tsage/blue_force/blueforce_scenes7.cpp +++ b/engines/tsage/blue_force/blueforce_scenes7.cpp @@ -37,7 +37,7 @@ namespace BlueForce { void Scene710::Timer1::signal() { PaletteRotation *rotation = BF_GLOBALS._scenePalette.addRotation(136, 138, -1); - rotation->setDelay(25); + rotation->setDelay(20); rotation = BF_GLOBALS._scenePalette.addRotation(146, 148, -1); rotation->setDelay(30); rotation = BF_GLOBALS._scenePalette.addRotation(187, 191, -1); @@ -113,19 +113,19 @@ bool Scene710::Object5::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_LOOK: - if (scene->_v1D64 <= 2) + if (scene->_stickThrowCount <= 2) return NamedObject::startAction(action, event); else { SceneItem::display2(710, 3); - scene->_v1D66 = 1; + scene->_watchCrate = true; return true; } case CURSOR_USE: - if ((scene->_kid._position.x < 0) && (scene->_v1D62 == 1)) { - scene->_v1D64++; - if (scene->_v1D66 == 0) { + if ((scene->_kid._position.x < 0) && (scene->_dogLying)) { + scene->_stickThrowCount++; + if (!scene->_watchCrate) { BF_GLOBALS._player.disableControl(); - scene->_v1D62 = 0; + scene->_dogLying = false; scene->_sceneMode = 7105; scene->setAction(&scene->_sequenceManager1, scene, 7105, &BF_GLOBALS._player, &scene->_stick, &scene->_dog, NULL); } else { @@ -187,7 +187,8 @@ void Scene710::postInit(SceneObjectList *OwnerList) { _item7.setDetails(Rect(0, 0, 640, 52), 710, 11, 17, -1, 1, NULL); _item9.setDetails(Rect(0, 0, 640, 128), 710, 5, 15, -1, 1, NULL); - _v1D62 = _v1D64 = _v1D66 = _v1D68 = 0; + _stickThrowCount = 0; + _dogLying = _watchCrate = _throwStick = false; _action1._state = 7100; _timer1.set(2, NULL); _sceneMode = 7100; @@ -205,6 +206,7 @@ void Scene710::signal() { setAction(&_sequenceManager1, this, 7102, &_dog, NULL); break; case 7101: + // Pick up crate part BF_GLOBALS._player.enableControl(); BF_INVENTORY.setObjectScene(INV_CRATE1, 1); _stick.remove(); @@ -214,19 +216,19 @@ void Scene710::signal() { _stick.setPosition(Common::Point(100, 122)); _stick.animate(ANIM_MODE_NONE, NULL); _stick._strip = 2; - if (_v1D64 <= 2) + if (_stickThrowCount <= 2) _stick._frame = 2; else { - if (_v1D64 == 3) { + if (_stickThrowCount == 3) { BF_GLOBALS._player.disableControl(); _sceneMode = 0; _stripManager.start(7108, this); } _stick._frame = 1; } - _v1D62 = 1; + _dogLying = true; BF_GLOBALS._walkRegions.disableRegion(2); - if ((_v1D68 != 0) && (_sceneMode != 0)) + if ((_throwStick) && (_sceneMode != 0)) BF_GLOBALS._player.enableControl(); break; case 7103: @@ -239,7 +241,7 @@ void Scene710::signal() { } break; case 7105: - _v1D68 = 1; + _throwStick = true; // No break on purpose case 7104: _sceneMode = 7102; @@ -256,8 +258,8 @@ void Scene710::signal() { } void Scene710::dispatch() { - if ((_kid._position.x > 0) && (_v1D62 == 1) && (_sceneMode != 7106)) { - _v1D62 = 0; + if ((_kid._position.x > 0) && (_dogLying) && (_sceneMode != 7106)) { + _dogLying = false; _sceneMode = 7103; setAction(&_sequenceManager1, this, 7103, &_kid, &_stick, &_dog, NULL); } @@ -266,10 +268,10 @@ void Scene710::dispatch() { void Scene710::synchronize(Serializer &s) { SceneExt::synchronize(s); - s.syncAsSint16LE(_v1D62); - s.syncAsSint16LE(_v1D64); - s.syncAsSint16LE(_v1D66); - s.syncAsSint16LE(_v1D68); + s.syncAsSint16LE(_dogLying); + s.syncAsSint16LE(_stickThrowCount); + s.syncAsSint16LE(_watchCrate); + s.syncAsSint16LE(_throwStick); } diff --git a/engines/tsage/blue_force/blueforce_scenes7.h b/engines/tsage/blue_force/blueforce_scenes7.h index 91bd1e537f..161d94cc2c 100644 --- a/engines/tsage/blue_force/blueforce_scenes7.h +++ b/engines/tsage/blue_force/blueforce_scenes7.h @@ -89,7 +89,10 @@ public: NamedHotspot _item7; NamedHotspot _item8; NamedHotspot _item9; - int _v1D62, _v1D64, _v1D66, _v1D68; + int _stickThrowCount; + bool _dogLying; + bool _watchCrate; + bool _throwStick; virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void signal(); diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp index 4a52f10704..32cd376891 100644 --- a/engines/tsage/blue_force/blueforce_scenes8.cpp +++ b/engines/tsage/blue_force/blueforce_scenes8.cpp @@ -562,24 +562,36 @@ bool Scene810::Lyle::startAction(CursorType action, Event &event) { case INV_PRINT_OUT: if (BF_GLOBALS.getFlag(shownLylePO)) { scene->_sceneMode = 8149; - } else if (!BF_GLOBALS.getFlag(shownLylePO)) { - if (!BF_GLOBALS.getFlag(shownFax)) { - // WORKAROUND: Original did not do a 'not', but I think this is correct - BF_GLOBALS.setFlag(shownFax); - scene->_sceneMode = 8125; - } else if (BF_GLOBALS.getFlag(shownLyleRapsheet)) { - scene->_sceneMode = 8104; + } else { + BF_GLOBALS.setFlag(shownLylePO); + if (BF_GLOBALS._dayNumber == 3) { + if (BF_GLOBALS.getFlag(shownFax)) { + BF_GLOBALS.setFlag(shownFax); + scene->_sceneMode = 8125; + } else if (BF_GLOBALS.getFlag(shownLyleRapsheet)) { + scene->_sceneMode = 8104; + } else { + scene->_sceneMode = 8121; + } + } else if (BF_GLOBALS.getFlag(onDuty)) { + if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))){ + scene->_sceneMode = 8141; + } else { + // Doublecheck on shownLyleCrate1 removed: useless + scene->_sceneMode = 8144; + } } else { - scene->_sceneMode = 8121; + if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))) { + scene->_sceneMode = 8129; + } else { // if (BF_GLOBALS.getFlag(shownLyleCrate1)) { + scene->_sceneMode = 8132; + // doublecheck Present in the original, may hide a bug in the original + //} else + // scene->_sceneMode = 8121; + } } - } else if (BF_GLOBALS.getFlag(onDuty)) { - scene->_sceneMode = 8141; - } else { - if (BF_GLOBALS.getFlag(shownLyleRapsheet) || BF_GLOBALS.getFlag(shownLyleCrate1)) - scene->_sceneMode = 8129; - else - scene->_sceneMode = 8121; } + BF_GLOBALS._player.disableControl(); scene->setAction(&scene->_action1); return true; @@ -654,12 +666,12 @@ bool Scene810::FaxMachineInset::startAction(CursorType action, Event &event) { if (BF_INVENTORY.getObjectScene(INV_PRINT_OUT) == 811) { T2_GLOBALS._uiElements.addScore(50); scene->_sound1.play(77); + scene->_fieldA70 = 1; BF_GLOBALS._player.disableControl(); scene->_sceneMode = 8109; scene->setAction(&scene->_sequenceManager1, scene, 8109, &BF_GLOBALS._player, &scene->_object6, &scene->_object5, NULL); - scene->_fieldA70 = 1; scene->_fieldA74 = 1; remove(); } else { diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp index af32e6ccc3..5e8bc12a18 100644 --- a/engines/tsage/blue_force/blueforce_scenes9.cpp +++ b/engines/tsage/blue_force/blueforce_scenes9.cpp @@ -62,16 +62,16 @@ bool Scene900::Gate::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_USE: - if (BF_GLOBALS._v4CEC0 == 0) { + if (BF_GLOBALS._gateStatus == 0) { return NamedObject::startAction(action, event); } else { BF_GLOBALS._player.disableControl(); - if (BF_GLOBALS._v4CEC0 == 2) { + if (BF_GLOBALS._gateStatus == 2) { scene->_sceneMode = 9006; - BF_GLOBALS._v4CEC0 = 1; + BF_GLOBALS._gateStatus = 1; scene->setAction(&scene->_sequenceManager1, scene, 9006, &BF_GLOBALS._player, this, NULL); } else { - BF_GLOBALS._v4CEC0 = 2; + BF_GLOBALS._gateStatus = 2; if (scene->_dog._flag == false) { BF_GLOBALS._player.setAction(&scene->_action4); } else { @@ -84,15 +84,15 @@ bool Scene900::Gate::startAction(CursorType action, Event &event) { } break; case INV_WAREHOUSE_KEYS: - if (BF_GLOBALS._v4CEC0 == 2) { + if (BF_GLOBALS._gateStatus == 2) { SceneItem::display2(900, 14); } else { - if (BF_GLOBALS._v4CEC0 == 0) { + if (BF_GLOBALS._gateStatus == 0) { if (!BF_GLOBALS.getFlag(fGotPointsForUnlockGate)) { BF_GLOBALS.setFlag(fGotPointsForUnlockGate); T2_GLOBALS._uiElements.addScore(30); } - BF_GLOBALS._v4CEC0 = 1; + BF_GLOBALS._gateStatus = 1; } else { if (!BF_GLOBALS.getFlag(fGotPointsForLockGate)) { if (BF_GLOBALS._bookmark == bEndDayThree) { @@ -100,7 +100,7 @@ bool Scene900::Gate::startAction(CursorType action, Event &event) { T2_GLOBALS._uiElements.addScore(30); } } - BF_GLOBALS._v4CEC0 = 0; + BF_GLOBALS._gateStatus = 0; } scene->_sceneMode = 9004; BF_GLOBALS._player.disableControl(); @@ -117,7 +117,7 @@ bool Scene900::Door::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_USE: - if (BF_GLOBALS._v4CEC0 == 2) { + if (BF_GLOBALS._gateStatus == 2) { if (_flag) { SceneItem::display2(900, 1); } else { @@ -131,7 +131,7 @@ bool Scene900::Door::startAction(CursorType action, Event &event) { return NamedObject::startAction(action, event); break; case INV_WAREHOUSE_KEYS: - if (BF_GLOBALS._v4CEC0 == 2) { + if (BF_GLOBALS._gateStatus == 2) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 9012; scene->setAction(&scene->_sequenceManager1, scene, 9012, &BF_GLOBALS._player, &scene->_door, NULL); @@ -180,11 +180,11 @@ bool Scene900::Lyle::startAction(CursorType action, Event &event) { if (action == CURSOR_TALK) { if (!_action) { if (scene->_dog._flag) { - if (BF_GLOBALS._v4CEC0 == 0) + if (BF_GLOBALS._gateStatus == 0) scene->_stripManager.start(9004, &BF_GLOBALS._stripProxy); else { if (scene->_door._flag == 1) { - if (BF_GLOBALS._v4CEC0 == 2) + if (BF_GLOBALS._gateStatus == 2) scene->_stripManager.start(9005, &BF_GLOBALS._stripProxy); else scene->_stripManager.start(9001, &BF_GLOBALS._stripProxy); @@ -445,7 +445,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) { if (BF_GLOBALS._sceneManager._previousScene == 910) { _sceneBounds.moveTo(639, 0); - BF_GLOBALS._v4CEC0 = 2; + BF_GLOBALS._gateStatus = 2; BF_INVENTORY.setObjectScene(INV_FISHING_NET, 900); _dog._flag = 1; } @@ -485,7 +485,7 @@ void Scene900::postInit(SceneObjectList *OwnerList) { _gate.setVisage(900); _gate.setStrip(2); - if (BF_GLOBALS._v4CEC0 == 2) + if (BF_GLOBALS._gateStatus == 2) _gate.setPosition(Common::Point(758, 127)); else { BF_GLOBALS._walkRegions.disableRegion(24); @@ -580,7 +580,7 @@ void Scene900::signal() { BF_GLOBALS._player.enableControl(); break; case 9001: - if ((BF_INVENTORY.getObjectScene(INV_FISHING_NET) == 900) || (BF_GLOBALS._v4CEC0 != 0) || + if ((BF_INVENTORY.getObjectScene(INV_FISHING_NET) == 900) || (BF_GLOBALS._gateStatus != 0) || (_door._flag == 0)) BF_GLOBALS.setFlag(fLeftTraceIn900); else @@ -593,7 +593,7 @@ void Scene900::signal() { BF_GLOBALS._player.enableControl(); break; case 9004: - if (BF_GLOBALS._v4CEC0 == 0) + if (BF_GLOBALS._gateStatus == 0) SceneItem::display2(900, 3); else SceneItem::display2(900, 4); @@ -625,7 +625,7 @@ void Scene900::signal() { break; case 9010: _sound1.play(92); - if (BF_GLOBALS._v4CEC0 == 2) { + if (BF_GLOBALS._gateStatus == 2) { _sceneMode = 9008; setAction(&_sequenceManager1, this, 9008, &BF_GLOBALS._player, &_dog, NULL); } else { @@ -666,9 +666,9 @@ void Scene900::signal() { BF_GLOBALS._player.enableControl(); break; case 9016: - if ((BF_GLOBALS._clip1Bullets == 0) && (BF_GLOBALS._clip2Bullets == 0)){ - BF_GLOBALS._clip1Bullets = 8; + if ((BF_GLOBALS._clip1Bullets == 0) && (BF_GLOBALS._clip2Bullets == 0)) { BF_GLOBALS._clip1Bullets = 8; + BF_GLOBALS._clip2Bullets = 8; SceneItem::display2(900, 25); } else if (BF_GLOBALS._clip1Bullets == 0) { BF_GLOBALS._clip1Bullets = 8; @@ -755,26 +755,26 @@ void Scene910::Action2::signal() { switch (_actionIndex++) { case 0: - scene->_object7.postInit(); - scene->_object7.setVisage(919); - scene->_object7.setPosition(Common::Point(267, 51)); - scene->_object7.fixPriority(40); + scene->_shadow.postInit(); + scene->_shadow.setVisage(919); + scene->_shadow.setPosition(Common::Point(267, 51)); + scene->_shadow.fixPriority(40); signal(); break; case 1: - scene->_object7.hide(); + scene->_shadow.hide(); setDelay(600); break; case 2: - scene->_object7.setStrip(BF_GLOBALS._randomSource.getRandomNumber(3) + 2); - scene->_object7.setFrame(1); - scene->_object7.show(); + scene->_shadow.setStrip(BF_GLOBALS._randomSource.getRandomNumber(2) + 2); + scene->_shadow.setFrame(1); + scene->_shadow.show(); setDelay(6); break; case 3: _actionIndex = 1; - scene->_object7.setStrip(BF_GLOBALS._randomSource.getRandomNumber(3) + 2); - scene->_object7.animate(ANIM_MODE_5, this); + scene->_shadow.setStrip(BF_GLOBALS._randomSource.getRandomNumber(2) + 2); + scene->_shadow.animate(ANIM_MODE_5, this); break; default: break; @@ -822,7 +822,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_USE: BF_GLOBALS._player.disableControl(); - scene->_field2DDA = 6; + scene->_sceneSubMode = 6; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -847,7 +847,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) { case 1: if (BF_GLOBALS._v4CEE2 > 1) { if (BF_GLOBALS._v4CEE2 != 4) { - if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(25)) && (BF_GLOBALS.getHasBullets())) { + if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())) { if (scene->_field2DE0 == 0) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 9126; @@ -868,7 +868,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) { return true; } } else { - if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(25)) && (BF_GLOBALS.getHasBullets())) { + if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 9125; scene->setAction(&scene->_sequenceManager1, scene, 9125, &scene->_nico, NULL); @@ -896,7 +896,7 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) { if (BF_GLOBALS._v4CEE2 < 4) { BF_GLOBALS._player.disableControl(); scene->_yellowCord.fixPriority(121); - scene->_field2DDA = 10; + scene->_sceneSubMode = 10; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -950,7 +950,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) { switch (action) { case CURSOR_USE: BF_GLOBALS._player.disableControl(); - scene->_field2DDA = 7; + scene->_sceneSubMode = 7; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -966,7 +966,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) { return true; break; case 1: - if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(25)) && (BF_GLOBALS.getHasBullets())){ + if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())){ BF_GLOBALS._player.disableControl(); if (BF_GLOBALS._v4CEE4 == 2) { scene->_sceneMode = 9132; @@ -994,7 +994,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) { } else { BF_GLOBALS._player.disableControl(); if (BF_GLOBALS._v4CEE2 == 4) { - scene->_field2DDA = 11; + scene->_sceneSubMode = 11; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1002,7 +1002,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) { scene->signal(); return true; } else { - scene->_field2DDA = 12; + scene->_sceneSubMode = 12; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1022,7 +1022,7 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) { return true; } else { BF_GLOBALS._player.disableControl(); - scene->_field2DDA = 11; + scene->_sceneSubMode = 11; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1082,7 +1082,7 @@ bool Scene910::PowerCord::startAction(CursorType action, Event &event) { if ((BF_GLOBALS._v4CEE0 == 0) || (_field92 != 1)) { BF_GLOBALS._player.disableControl(); if (_field92 == 1) { - scene->_field2DDA = 8; + scene->_sceneSubMode = 8; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1092,7 +1092,7 @@ bool Scene910::PowerCord::startAction(CursorType action, Event &event) { return true; } else { scene->_destPos = Common::Point(151, 186); - scene->_field2DDA = 4; + scene->_sceneSubMode = 4; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1143,7 +1143,7 @@ bool Scene910::BreakerBox::startAction(CursorType action, Event &event) { BF_GLOBALS._player.disableControl(); scene->_sceneMode = 9102; if (BF_GLOBALS.getFlag(gunDrawn)) { - scene->_field2DDA = 1; + scene->_sceneSubMode = 1; scene->_sceneMode = 9123; scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); return true; @@ -1173,7 +1173,7 @@ bool Scene910::FakeWall::startAction(CursorType action, Event &event) { if (action == INV_YELLOW_CORD) { BF_GLOBALS._player.disableControl(); scene->_destPos = Common::Point(285, 114); - scene->_field2DDA = 9; + scene->_sceneSubMode = 9; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1192,23 +1192,23 @@ void Scene910::BreakerBoxInset::postInit(SceneObjectList *OwnerList) { _lookLineNum = 7; _useLineNum = 8; BF_GLOBALS._sceneItems.push_back(this); - scene->_field2DD8 = 0; + scene->_breakerButtonCtr = 0; - _object13.setupBreaker(115, 44, 1, BF_GLOBALS._v4CECE[0]); - _object14.setupBreaker(116, 63, 2, BF_GLOBALS._v4CECE[1]); - _object15.setupBreaker(116, 69, 2, BF_GLOBALS._v4CECE[2]); - _object16.setupBreaker(115, 76, 1, BF_GLOBALS._v4CECE[3]); - _object17.setupBreaker(115, 95, 1, BF_GLOBALS._v4CECE[4]); - _object18.setupBreaker(116, 114, 2, BF_GLOBALS._v4CECE[5]); - _object19.setupBreaker(116, 120, 2, BF_GLOBALS._v4CECE[6]); - _object20.setupBreaker(188, 45, 2, BF_GLOBALS._v4CECE[7]); - _object21.setupBreaker(188, 51, 2, BF_GLOBALS._v4CECE[8]); - _object22.setupBreaker(179, 59, 1, BF_GLOBALS._v4CECE[9]); - _object23.setupBreaker(187, 78, 2, BF_GLOBALS._v4CECE[10]); - _object24.setupBreaker(187, 84, 2, BF_GLOBALS._v4CECE[11]); + _object13.setupBreaker(115, 44, 1, BF_GLOBALS._breakerBoxStatusArr[0]); + _object14.setupBreaker(116, 63, 2, BF_GLOBALS._breakerBoxStatusArr[1]); + _object15.setupBreaker(116, 69, 2, BF_GLOBALS._breakerBoxStatusArr[2]); + _object16.setupBreaker(115, 76, 1, BF_GLOBALS._breakerBoxStatusArr[3]); + _object17.setupBreaker(115, 95, 1, BF_GLOBALS._breakerBoxStatusArr[4]); + _object18.setupBreaker(116, 114, 2, BF_GLOBALS._breakerBoxStatusArr[5]); + _object19.setupBreaker(116, 120, 2, BF_GLOBALS._breakerBoxStatusArr[6]); + _object20.setupBreaker(188, 45, 2, BF_GLOBALS._breakerBoxStatusArr[7]); + _object21.setupBreaker(188, 51, 2, BF_GLOBALS._breakerBoxStatusArr[8]); + _object22.setupBreaker(179, 59, 1, BF_GLOBALS._breakerBoxStatusArr[9]); + _object23.setupBreaker(187, 78, 2, BF_GLOBALS._breakerBoxStatusArr[10]); + _object24.setupBreaker(187, 84, 2, BF_GLOBALS._breakerBoxStatusArr[11]); - _object25.subEBBDC(178, 90, 1, BF_GLOBALS._v4CECE[12]); - _object26.subEBBDC(178, 108, 2, BF_GLOBALS._v4CECE[13]); + _object25.setupHiddenSwitch(178, 90, 1, BF_GLOBALS._breakerBoxStatusArr[12]); + _object26.setupHiddenSwitch(178, 108, 2, BF_GLOBALS._breakerBoxStatusArr[13]); } void Scene910::BreakerBoxInset::remove() { @@ -1231,7 +1231,7 @@ void Scene910::BreakerBoxInset::remove() { _object27.remove(); _object28.remove(); - if ((BF_GLOBALS._v4CECE[13] < 4) && (scene->_breakerBox._frame > 1)) + if ((BF_GLOBALS._breakerBoxStatusArr[13] < 4) && (scene->_breakerBox._frame > 1)) scene->_breakerBox.animate(ANIM_MODE_6, NULL); FocusObject::remove(); @@ -1240,19 +1240,19 @@ void Scene910::BreakerBoxInset::remove() { void Scene910::Object13::synchronize(Serializer &s) { NamedObject::synchronize(s); s.syncAsSint16LE(_field90); - s.syncAsSint16LE(_field92); + s.syncAsSint16LE(_mode); } bool Scene910::Object13::startAction(CursorType action, Event &event) { static uint32 black = 0; Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene; - int8 var2; + int8 xDiff; - if (_field92 == 1) - var2 = 12; + if (_mode == 1) + xDiff = 12; else - var2 = 7; + xDiff = 7; switch (action) { case CURSOR_LOOK: @@ -1264,8 +1264,8 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { return true; case CURSOR_USE: scene->_sound2.play(101); - if (event.mousePos.x <= _position.x + var2) { - if (_field92 != 1) { + if (event.mousePos.x <= _position.x + xDiff) { + if (_mode != 1) { if (_frame > 6) setFrame(_frame - 1); } else { @@ -1273,7 +1273,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { setFrame(_frame - 1); } } else { - if (_field92 == 1) { + if (_mode == 1) { if (_frame < 3) setFrame(_frame + 1); } else { @@ -1282,18 +1282,18 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { } } - if (_field92 != 1) - BF_GLOBALS._v4CECE[_field90 - 1] = (_field90 + 251) % 256; + if (_mode != 1) + BF_GLOBALS._breakerBoxStatusArr[_field90 - 1] = (_field90 + 251) % 256; else - BF_GLOBALS._v4CECE[_field90 - 1] = _field90; + BF_GLOBALS._breakerBoxStatusArr[_field90 - 1] = _field90; switch (_field90) { case 1: if (BF_GLOBALS._v4CEE2 < 1) { if (_frame == 2) { - if (!BF_GLOBALS.getFlag(81)) { + if (!BF_GLOBALS.getFlag(fGotPointsForClosingDoor)) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.setFlag(81); + BF_GLOBALS.setFlag(fGotPointsForClosingDoor); } scene->_sceneMode = 0; if (BF_GLOBALS._dayNumber == 5) { @@ -1302,7 +1302,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { // _objectList.draw(); BF_GLOBALS._player.disableControl(); scene->_lyle.setVisage(912); - scene->_object7.remove(); + scene->_shadow.remove(); scene->_action2.remove(); scene->_nico.postInit(); scene->_sceneMode = 9129; @@ -1332,9 +1332,9 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { // _objectList.draw(); } else { if (BF_GLOBALS._v4CEC8 == 1) { - if (!BF_GLOBALS.getFlag(78)) { + if (!BF_GLOBALS.getFlag(fGotPointsForStartGenerator)) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.setFlag(78); + BF_GLOBALS.setFlag(fGotPointsForStartGenerator); } BF_GLOBALS._player.disableControl(); BF_GLOBALS._v4CEC8 = 0; @@ -1351,7 +1351,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { return true; case 4: if (_frame == 2) { - if (BF_GLOBALS._v4CECE[4] == 2) { + if (BF_GLOBALS._breakerBoxStatusArr[4] == 2) { scene->_action1.setActionIndex(2); scene->_action1.signal(); } @@ -1362,7 +1362,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { return true; case 5: if (_frame == 2) { - if (BF_GLOBALS._v4CECE[3] == 2) { + if (BF_GLOBALS._breakerBoxStatusArr[3] == 2) { scene->_action1.setActionIndex(2); scene->_action1.signal(); } @@ -1372,7 +1372,7 @@ bool Scene910::Object13::startAction(CursorType action, Event &event) { } return true; case 15: - if ((BF_GLOBALS._v4CECA == 2) && (BF_GLOBALS._v4CECE[17] == 1)) { + if ((BF_GLOBALS._v4CECA == 2) && (BF_GLOBALS._breakerBoxStatusArr[17] == 1)) { if (_frame == 7) scene->subE83E1(); else @@ -1397,9 +1397,9 @@ void Scene910::Object13::setupBreaker(int x, int y, int mode, int8 frameNumber) Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene; NamedObject::postInit(); - _field92 = mode; - scene->_field2DD8++; - _field90 = scene->_field2DD8; + _mode = mode; + scene->_breakerButtonCtr++; + _field90 = scene->_breakerButtonCtr; setVisage(910); if (mode == 1) { @@ -1432,18 +1432,18 @@ bool Scene910::Object25::startAction(CursorType action, Event &event) { SceneItem::display2(910, 11); return true; case CURSOR_USE: - _field92 = BF_GLOBALS._v4CECE[_field90 + 11]; + _field92 = BF_GLOBALS._breakerBoxStatusArr[_field90 + 11]; switch (_field92 - 1) { case 0: _field92 = 2; setStrip(7); setFrame(1); if (_field90 == 1) { - scene->_field2DD8 = 14; - scene->_breakerBoxInset._object27.setupBreaker(182, 92, 2, BF_GLOBALS._v4CECE[14]); + scene->_breakerButtonCtr = 14; + scene->_breakerBoxInset._object27.setupBreaker(182, 92, 2, BF_GLOBALS._breakerBoxStatusArr[14]); } else { - scene->_field2DD8 = 15; - scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._v4CECE[15]); + scene->_breakerButtonCtr = 15; + scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._breakerBoxStatusArr[15]); } SceneItem::display2(910, 12); break; @@ -1461,11 +1461,11 @@ bool Scene910::Object25::startAction(CursorType action, Event &event) { setStrip(7); setFrame(1); if (_field90 == 1) { - scene->_field2DD8 = 14; - scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._v4CECE[14]); + scene->_breakerButtonCtr = 14; + scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._breakerBoxStatusArr[14]); } else { - scene->_field2DD8 = 15; - scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._v4CECE[15]); + scene->_breakerButtonCtr = 15; + scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._breakerBoxStatusArr[15]); } break; case 3: @@ -1475,7 +1475,7 @@ bool Scene910::Object25::startAction(CursorType action, Event &event) { break; } - BF_GLOBALS._v4CECE[_field90 + 11] = _field92; + BF_GLOBALS._breakerBoxStatusArr[_field90 + 11] = _field92; return true; default: return NamedObject::startAction(action, event); @@ -1488,11 +1488,11 @@ void Scene910::Object25::remove() { SceneObject::remove(); } -void Scene910::Object25::subEBBDC(int x, int y, int arg8, int argA) { +void Scene910::Object25::setupHiddenSwitch(int x, int y, int arg8, int argA) { Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene; NamedObject::postInit(); - scene->_field2DD8++; + scene->_breakerButtonCtr++; _field90 = arg8; _field92 = argA; setVisage(910); @@ -1504,11 +1504,11 @@ void Scene910::Object25::subEBBDC(int x, int y, int arg8, int argA) { setStrip(7); setFrame(1); if (_field90 == 1) { - scene->_field2DD8 = 14; - scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._v4CECE[14]); + scene->_breakerButtonCtr = 14; + scene->_breakerBoxInset._object27.setupBreaker(182, 96, 2, BF_GLOBALS._breakerBoxStatusArr[14]); } else { - scene->_field2DD8 = 15; - scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._v4CECE[15]); + scene->_breakerButtonCtr = 15; + scene->_breakerBoxInset._object28.init(178, 108, 0, BF_GLOBALS._breakerBoxStatusArr[15]); } } @@ -1593,12 +1593,12 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) { default: break; } - BF_GLOBALS._v4CECE[_field90 + 15] = _frame; + BF_GLOBALS._breakerBoxStatusArr[_field90 + 15] = _frame; if (_field90 == 0) { if (_frame == 2) - BF_GLOBALS._v4CECE[13] = 2; + BF_GLOBALS._breakerBoxStatusArr[13] = 2; else - BF_GLOBALS._v4CECE[13] = 4; + BF_GLOBALS._breakerBoxStatusArr[13] = 4; } return true; case INV_HALF_YELLOW_CORD: @@ -1636,13 +1636,12 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) { setFrame(_field90 + 4); else if (_frame - _field90 == 3) setFrame(_field90 + 5); - BF_GLOBALS._v4CECE[15 + _field90] = _frame; - BF_GLOBALS._v4CECE[_field90 + 15] = _frame; + BF_GLOBALS._breakerBoxStatusArr[_field90 + 15] = _frame; if (_field90 == 0) { if (_frame == 2) - BF_GLOBALS._v4CECE[13] = 2; + BF_GLOBALS._breakerBoxStatusArr[13] = 2; else - BF_GLOBALS._v4CECE[13] = 4; + BF_GLOBALS._breakerBoxStatusArr[13] = 4; } return true; case INV_HALF_BLACK_CORD: @@ -1691,8 +1690,8 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) { scene->_blackCord.fixPriority(50); scene->_blackCord.show(); scene->_blackCord._field90 = 1; - if (BF_GLOBALS._v4CECE[17] == 1) { - if (BF_GLOBALS._v4CECE[14] == 2) + if (BF_GLOBALS._breakerBoxStatusArr[17] == 1) { + if (BF_GLOBALS._breakerBoxStatusArr[14] == 2) scene->subE83E1(); else scene->subE82BD(); @@ -1702,13 +1701,12 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) { setFrame(_field90 + 3); else if (_frame - _field90 == 4) setFrame(_field90 + 5); - BF_GLOBALS._v4CECE[15 + _field90] = _frame; - BF_GLOBALS._v4CECE[_field90 + 15] = _frame; + BF_GLOBALS._breakerBoxStatusArr[_field90 + 15] = _frame; if (_field90 == 0) { if (_frame == 2) - BF_GLOBALS._v4CECE[13] = 2; + BF_GLOBALS._breakerBoxStatusArr[13] = 2; else - BF_GLOBALS._v4CECE[13] = 4; + BF_GLOBALS._breakerBoxStatusArr[13] = 4; } return true; default: @@ -1719,7 +1717,7 @@ bool Scene910::BlackPlug::startAction(CursorType action, Event &event) { void Scene910::BlackPlug::init(int x, int y, int arg8, int8 argA) { NamedObject::postInit(); _field90 = arg8; - _field92 = argA; + _mode = argA; setVisage(910); if (_field90 == 0) setStrip(7); @@ -1745,11 +1743,11 @@ void Scene910::GeneratorInset::postInit(SceneObjectList *OwnerList) { _useLineNum = 87; BF_GLOBALS._sceneItems.push_front(this); - scene->_field2DD8 = 16; - _blackPlug.init(142, 86, 1, BF_GLOBALS._v4CECE[16]); + scene->_breakerButtonCtr = 16; + _blackPlug.init(142, 86, 1, BF_GLOBALS._breakerBoxStatusArr[16]); - scene->_field2DD8 = 17; - _powerButton.init(BF_GLOBALS._v4CECE[17]); + scene->_breakerButtonCtr = 17; + _powerButton.init(BF_GLOBALS._breakerBoxStatusArr[17]); } void Scene910::GeneratorInset::remove() { @@ -1770,30 +1768,30 @@ bool Scene910::PowerButton::startAction(CursorType action, Event &event) { if (_frame == 4) { scene->_sound1.play(100); scene->_sound1.holdAt(1); - if (!BF_GLOBALS.getFlag(77)) { + if (!BF_GLOBALS.getFlag(fGotPointsForFuseBoxPlug)) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.setFlag(77); + BF_GLOBALS.setFlag(fGotPointsForFuseBoxPlug); } setFrame(5); _object32.setFrame(7); if (BF_GLOBALS._v4CECA == 2) { - if (BF_GLOBALS._v4CECE[14] == 2) + if (BF_GLOBALS._breakerBoxStatusArr[14] == 2) scene->subE83E1(); else scene->subE82BD(); } } else { scene->_sound1.release(); - if (BF_GLOBALS._bookmark == 21) { - if (!BF_GLOBALS.getFlag(82)) { + if (BF_GLOBALS._bookmark == bEndDayThree) { + if (!BF_GLOBALS.getFlag(fGotPointsForLightsOff)) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.setFlag(82); + BF_GLOBALS.setFlag(fGotPointsForLightsOff); } } setFrame(4); _object32.setFrame(6); } - BF_GLOBALS._v4CECE[17] = (_frame + 252) % 256; + BF_GLOBALS._breakerBoxStatusArr[17] = (_frame + 252) % 256; return true; } else return NamedObject::startAction(action, event); @@ -1855,7 +1853,7 @@ bool Scene910::Item2::startAction(CursorType action, Event &event) { if (action == 59) { BF_GLOBALS._player.disableControl(); scene->_destPos = Common::Point(151, 186); - scene->_field2DDA = 5; + scene->_sceneSubMode = 5; scene->_sceneMode = 9123; if (BF_GLOBALS._player._visage == 1911) scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); @@ -1913,7 +1911,7 @@ bool Scene910::Item16::startAction(CursorType action, Event &event) { if (BF_GLOBALS._player._visage == 1911) { BF_GLOBALS._player.disableControl(); scene->_destPos = Common::Point(292, 100); - scene->_field2DDA = 0; + scene->_sceneSubMode = 0; scene->_sceneMode = 9123; scene->setAction(&scene->_sequenceManager1, scene, 9123, &BF_GLOBALS._player, NULL); } else { @@ -1940,8 +1938,8 @@ void Scene910::remove() { void Scene910::synchronize(Serializer &s) { PalettedScene::synchronize(s); - s.syncAsSint16LE(_field2DDA); - s.syncAsSint16LE(_field2DD8); + s.syncAsSint16LE(_sceneSubMode); + s.syncAsSint16LE(_breakerButtonCtr); s.syncAsSint16LE(_field2DE0); s.syncAsSint16LE(_field2DE2); s.syncAsSint16LE(_field2DE4); @@ -1979,7 +1977,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) { _vent.postInit(); _vent.setVisage(910); - if ((BF_GLOBALS._v4CECE[3] == 2) && (BF_GLOBALS._v4CECE[4] == 2)) { + if ((BF_GLOBALS._breakerBoxStatusArr[3] == 2) && (BF_GLOBALS._breakerBoxStatusArr[4] == 2)) { _action1.setActionIndex(4); } else { _vent.animate(ANIM_MODE_2, NULL); @@ -2041,7 +2039,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) { if (BF_GLOBALS._dayNumber == 0) { BF_GLOBALS._dayNumber = 5; BF_GLOBALS._sceneManager._previousScene = 900; - BF_GLOBALS.setFlag(7); + BF_GLOBALS.setFlag(fWithLyle); } if ( (BF_GLOBALS._sceneManager._previousScene == 910) @@ -2055,11 +2053,11 @@ void Scene910::postInit(SceneObjectList *OwnerList) { _field2DE0 = 0; _field2DE2 = 0; _field2DE4 = 0; - BF_GLOBALS.clearFlag(34); + BF_GLOBALS.clearFlag(fCanDrawGun); _lyle._position.x = 0; if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._sceneManager._previousScene == 900)){ - BF_GLOBALS.setFlag(34); + BF_GLOBALS.setFlag(fCanDrawGun); BF_GLOBALS._v4CEC8 = 0; BF_GLOBALS._player.setVisage(129); @@ -2071,13 +2069,13 @@ void Scene910::postInit(SceneObjectList *OwnerList) { _lyle._field90 = 0; _lyle.setDetails(910, 69, 70, 71, 5, &_item4); - BF_GLOBALS._v4CECE[0] = 3; - BF_GLOBALS._v4CECE[12] = 2; - BF_GLOBALS._v4CECE[13] = 4; - BF_GLOBALS._v4CECE[14] = 3; - BF_GLOBALS._v4CECE[15] = 3; - BF_GLOBALS._v4CECE[16] = 4; - BF_GLOBALS._v4CECE[17] = 1; + BF_GLOBALS._breakerBoxStatusArr[0] = 3; + BF_GLOBALS._breakerBoxStatusArr[12] = 2; + BF_GLOBALS._breakerBoxStatusArr[13] = 4; + BF_GLOBALS._breakerBoxStatusArr[14] = 3; + BF_GLOBALS._breakerBoxStatusArr[15] = 3; + BF_GLOBALS._breakerBoxStatusArr[16] = 4; + BF_GLOBALS._breakerBoxStatusArr[17] = 1; BF_GLOBALS._v4CECA = 2; BF_GLOBALS._v4CEE0 = 1; _yellowCord.setPosition(Common::Point(291, -30)); @@ -2085,7 +2083,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) { } if (BF_GLOBALS._sceneManager._previousScene == 920) { - BF_GLOBALS.setFlag(34); + BF_GLOBALS.setFlag(fCanDrawGun); BF_GLOBALS._player.setPosition(Common::Point(276, 119)); BF_GLOBALS._player.setStrip(6); if (BF_GLOBALS._v4CECC == 0) @@ -2116,7 +2114,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) { } BF_GLOBALS._player.enableControl(); } else if (BF_GLOBALS._sceneManager._previousScene == 935) { - BF_GLOBALS.setFlag(34); + BF_GLOBALS.setFlag(fCanDrawGun); BF_GLOBALS._v4CEC8 = 0; _lyle.postInit(); _lyle.setVisage(916); @@ -2153,13 +2151,13 @@ void Scene910::postInit(SceneObjectList *OwnerList) { else add2Faders((const byte *)&unk_50E90, 2, 911, this); } else { - BF_GLOBALS.clearFlag(8); + BF_GLOBALS.clearFlag(gunDrawn); BF_GLOBALS._player.disableControl(); } if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._v4CEE2 == 0)){ - _object7.postInit(); - _object7.setAction(&_action2); + _shadow.postInit(); + _shadow.setAction(&_action2); } if (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 1) @@ -2212,7 +2210,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) { BF_GLOBALS._walkRegions.disableRegion(10); } - if (BF_GLOBALS._v4CECE[17] != 0) { + if (BF_GLOBALS._breakerBoxStatusArr[17] != 0) { _sound1.play(100); _sound1.holdAt(1); } @@ -2379,7 +2377,7 @@ void Scene910::signal() { BF_GLOBALS._player.enableControl(); break; case 9101: - if ((BF_GLOBALS._v4CEE0 == 0) && (BF_GLOBALS._v4CEC8 != 0) && (BF_GLOBALS._v4CECE[17] == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910) && (BF_INVENTORY.getObjectScene(INV_BLACK_CORD) == 910)) + if ((BF_GLOBALS._v4CEE0 == 0) && (BF_GLOBALS._v4CEC8 != 0) && (BF_GLOBALS._breakerBoxStatusArr[17] == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910) && (BF_INVENTORY.getObjectScene(INV_BLACK_CORD) == 910)) BF_GLOBALS.clearFlag(fGotPointsForSearchingDA); else BF_GLOBALS.setFlag(fGotPointsForSearchingDA); @@ -2387,7 +2385,7 @@ void Scene910::signal() { BF_GLOBALS._sceneManager.changeScene(900); break; case 9102: - if ((BF_GLOBALS._v4CECE[13] < 4) && (_breakerBox._frame == 1)) + if ((BF_GLOBALS._breakerBoxStatusArr[13] < 4) && (_breakerBox._frame == 1)) _breakerBox.animate(ANIM_MODE_5, NULL); BF_GLOBALS._player.enableControl(); @@ -2457,7 +2455,7 @@ void Scene910::signal() { _nico.postInit(); _nico.setDetails(910, 63, 64, 65, 5, &_item4); BF_GLOBALS._v4CEE6 = 0; - _object7.postInit(); + _shadow.postInit(); _action2.remove(); _sceneMode = 9116; setAction(&_sequenceManager1, this, 9116, &_nico, NULL); @@ -2505,7 +2503,7 @@ void Scene910::signal() { break; case 9123: BF_GLOBALS.clearFlag(gunDrawn); - switch (_field2DDA - 1) { + switch (_sceneSubMode - 1) { case 0: _sceneMode = 9102; setAction(&_sequenceManager1, this, 9102, &BF_GLOBALS._player, NULL); @@ -2622,7 +2620,7 @@ void Scene910::signal() { break; case 9130: _lyle.setAction(&_sequenceManager2, NULL, 9133, &_lyle, NULL); - BF_GLOBALS._v4CECE[14] = 3; + BF_GLOBALS._breakerBoxStatusArr[14] = 3; subE82BD(); BF_GLOBALS._walkRegions.disableRegion(15); break; @@ -2781,7 +2779,7 @@ void Scene910::process(Event &event) { if (BF_GLOBALS._player._visage == 1911) { BF_GLOBALS._player.disableControl(); _destPos = event.mousePos; - _field2DDA = 0; + _sceneSubMode = 0; _sceneMode = 9123; setAction(&_sequenceManager1, this, 9123, &BF_GLOBALS._player, NULL); } else { @@ -2792,7 +2790,7 @@ void Scene910::process(Event &event) { } else if (BF_GLOBALS._player._visage == 1911) { BF_GLOBALS._player.disableControl(); _destPos = event.mousePos; - _field2DDA = 0; + _sceneSubMode = 0; _sceneMode = 9123; setAction(&_sequenceManager1, this, 9123, &BF_GLOBALS._player, NULL); } @@ -2823,7 +2821,7 @@ void Scene910::dispatch() { if ((BF_GLOBALS._player._position.x > 265) && (BF_GLOBALS._player._position.y < 102) && (BF_GLOBALS._v4CEE0 != 0) && (_sceneMode != 9143)) { BF_GLOBALS._player.disableControl(); if (BF_GLOBALS.getFlag(gunDrawn)) { - _field2DDA = 3; + _sceneSubMode = 3; _sceneMode = 9123; setAction(&_sequenceManager1, this, 9123, &BF_GLOBALS._player, NULL); } else if (BF_GLOBALS._v4CEE2 == 0) { @@ -2842,7 +2840,7 @@ void Scene910::dispatch() { if ((BF_GLOBALS._dayNumber == 5) && (BF_GLOBALS._player._position.x > 250) && (_sceneMode != 9135) && (_sceneMode != 11) && (BF_GLOBALS._v4CEE0 != 0) && (BF_GLOBALS._v4CEE2 == 0)) { BF_GLOBALS._player.disableControl(); - _object7.remove(); + _shadow.remove(); _nico.remove(); _nico.postInit(); _nico.setDetails(910, 63, 64, 65, 5, &_item4); @@ -2885,16 +2883,16 @@ void Scene910::subE82BD() { void Scene910::subE83E1() { if (BF_GLOBALS._v4CEE0 != 0) { _fakeWall.show(); - if ((BF_GLOBALS._bookmark == 21) && (!BF_GLOBALS.getFlag(80))) { + if ((BF_GLOBALS._bookmark == bEndDayThree) && (!BF_GLOBALS.getFlag(fGotPointsForOpeningDoor))) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.setFlag(80); + BF_GLOBALS.setFlag(fGotPointsForOpeningDoor); } BF_GLOBALS._v4CEE0 = 0; BF_GLOBALS._walkRegions.disableRegion(10); BF_GLOBALS._player.disableControl(); _sceneMode = 9115; _sound2.play(42); - if ((BF_GLOBALS._v4CECC == 0) && (BF_INVENTORY.getObjectScene(57) == 910)) + if ((BF_GLOBALS._v4CECC == 0) && (BF_INVENTORY.getObjectScene(INV_YELLOW_CORD) == 910)) setAction(&_sequenceManager1, this, 9128, &_fakeWall, &_yellowCord, &_object5, NULL); else setAction(&_sequenceManager1, this, 9115, &_fakeWall, &_object5, NULL); @@ -2941,7 +2939,7 @@ bool Scene920::Item1::startAction(CursorType action, Event &event) { BF_GLOBALS._player.disableControl(); if (BF_GLOBALS.getFlag(fCrateOpen)) { if (BF_GLOBALS._player._visage == 921) { - if ((BF_INVENTORY.getObjectScene(15) != 1) && (BF_GLOBALS.getFlag(fSawGuns))) { + if ((BF_INVENTORY.getObjectScene(INV_AUTO_RIFLE) != 1) && (BF_GLOBALS.getFlag(fSawGuns))) { scene->_sceneMode = 9207; scene->setAction(&scene->_sequenceManager1, scene, 9207, &BF_GLOBALS._player, NULL); } else { @@ -3055,7 +3053,7 @@ void Scene920::signal() { case 9207: BF_GLOBALS._player.enableControl(); T2_GLOBALS._uiElements.addScore(30); - BF_INVENTORY.setObjectScene(15, 1); + BF_INVENTORY.setObjectScene(INV_AUTO_RIFLE, 1); BF_GLOBALS._bookmark = bEndDayThree; break; default: @@ -3107,7 +3105,7 @@ bool Scene930::Object1::startAction(CursorType action, Event &event) { Scene930 *scene = (Scene930 *)BF_GLOBALS._sceneManager._scene; bool result; - if ((action == CURSOR_USE) && (!BF_GLOBALS.getFlag(93))) { + if ((action == CURSOR_USE) && (!BF_GLOBALS.getFlag(fGotPointsForFBI))) { scene->setAction(&scene->_action2); result = true; } else @@ -3124,8 +3122,8 @@ bool Scene930::Object2::startAction(CursorType action, Event &event) { NamedObject::startAction(action, event); T2_GLOBALS._uiElements.addScore(30); - BF_INVENTORY.setObjectScene(54, 1); - BF_GLOBALS.setFlag(93); + BF_INVENTORY.setObjectScene(INV_9MM_BULLETS, 1); + BF_GLOBALS.setFlag(fGotPointsForFBI); remove(); scene->_box.remove(); return true; @@ -3195,7 +3193,7 @@ bool Scene930::Object5::startAction(CursorType action, Event &event) { case CURSOR_WALK: return true; case CURSOR_USE: - if (BF_INVENTORY.getObjectScene(55) == 1) + if (BF_INVENTORY.getObjectScene(INV_SCHEDULE) == 1) return NamedObject::startAction(action, event); if (scene->_v141A == 0) { animate(ANIM_MODE_4, getFrameCount() - 1, 1, NULL); @@ -3204,7 +3202,7 @@ bool Scene930::Object5::startAction(CursorType action, Event &event) { _useLineNum = 78; } else { T2_GLOBALS._uiElements.addScore(50); - BF_INVENTORY.setObjectScene(55, 1); + BF_INVENTORY.setObjectScene(INV_SCHEDULE, 1); setFrame2(getFrameCount()); _lookLineNum = 92; _useLineNum = -1; @@ -3269,9 +3267,9 @@ void Scene930::Action1::signal() { break; case 5: scene->showBootWindow(); - if (!BF_GLOBALS.getFlag(72)) { + if (!BF_GLOBALS.getFlag(fGotPointsForCPU)) { T2_GLOBALS._uiElements.addScore(30); - BF_GLOBALS.setFlag(72); + BF_GLOBALS.setFlag(fGotPointsForCPU); } SceneItem::display(0, 312); BF_GLOBALS._player.enableControl(); @@ -3350,7 +3348,7 @@ void Scene930::postInit(SceneObjectList *OwnerList) { setZoomPercents(83, 75, 140, 100); _v141A = 0; _v141C = 0; - if (BF_INVENTORY.getObjectScene(54) != 1) { + if (BF_INVENTORY.getObjectScene(INV_9MM_BULLETS) != 1) { _box.postInit(); _box.setVisage(930); _box.setStrip(1); diff --git a/engines/tsage/blue_force/blueforce_scenes9.h b/engines/tsage/blue_force/blueforce_scenes9.h index b0761713b1..358f0b42e0 100644 --- a/engines/tsage/blue_force/blueforce_scenes9.h +++ b/engines/tsage/blue_force/blueforce_scenes9.h @@ -170,7 +170,7 @@ class Scene910: public PalettedScene { class Object13: public NamedObject { protected: - int _field90, _field92; + int _field90, _mode; public: void setupBreaker(int x, int y, int mode, int8 frameNumber); virtual void synchronize(Serializer &s); @@ -180,7 +180,7 @@ class Scene910: public PalettedScene { class BlackPlug: public Object13 { public: - void init(int x, int y, int arg8, int8 argA); + void init(int x, int y, int arg8, int8 mode); virtual bool startAction(CursorType action, Event &event); virtual void remove(); }; @@ -188,7 +188,7 @@ class Scene910: public PalettedScene { class Object25: public NamedObject { int _field90, _field92; public: - void subEBBDC(int x, int y, int arg8, int argA); + void setupHiddenSwitch(int x, int y, int arg8, int argA); virtual void synchronize(Serializer &s); virtual bool startAction(CursorType action, Event &event); virtual void remove(); @@ -253,7 +253,7 @@ class Scene910: public PalettedScene { virtual bool startAction(CursorType action, Event &event); }; - int _field2DDA, _field2DD8, _field2DE0, _field2DE2, _field2DE4; + int _sceneSubMode, _breakerButtonCtr, _field2DE0, _field2DE2, _field2DE4; Common::Point _destPos; public: SequenceManager _sequenceManager1, _sequenceManager2; @@ -270,7 +270,7 @@ public: Nico _nico; Stuart _stuart; Forbes _forbes; - NamedObject _object5, _vent, _object7; + NamedObject _object5, _vent, _shadow; PowerCord _blackCord, _yellowCord; BreakerBox _breakerBox; FakeWall _fakeWall; diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index d86548bd4b..b98f6f609d 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -32,7 +32,7 @@ namespace TsAGE { SequenceManager::SequenceManager() : Action() { - Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); + Common::fill(&_objectList[0], &_objectList[6], (SceneObject *)NULL); _sequenceData.clear(); _fontNum = 0; _sequenceOffset = 0; @@ -81,7 +81,7 @@ void SequenceManager::remove() { if (g_globals->_sceneObjects->contains(&_sceneText)) _sceneText.remove(); - Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); + Common::fill(&_objectList[0], &_objectList[6], (SceneObject *)NULL); Action::remove(); } @@ -342,7 +342,7 @@ void SequenceManager::attached(EventHandler *newOwner, EventHandler *endHandler, DEALLOCATE(seqData); - Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); + Common::fill(&_objectList[0], &_objectList[6], (SceneObject *)NULL); for (int idx = 0; idx < 6; ++idx) { _objectList[idx] = va_arg(va, SceneObject *); if (!_objectList[idx]) @@ -551,6 +551,9 @@ void Obj44::synchronize(Serializer &s) { for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx) _list[idx].synchronize(s); s.syncAsUint32LE(_speakerOffset); + + if (g_vm->getGameID() == GType_Ringworld2) + s.syncAsSint16LE(_mode); } /*--------------------------------------------------------------------------*/ @@ -581,6 +584,11 @@ void StripManager::start(int stripNum, EventHandler *owner, StripCallback *callb owner->setAction(this, owner); } +void StripManager::start3(int stripNum, EventHandler *owner, byte *lookupList) { + _lookupList = lookupList; + start(stripNum, owner, NULL); +} + void StripManager::reset() { _actionIndex = 0; _delayFrames = 0; @@ -703,7 +711,12 @@ void StripManager::signal() { return; } else if (_obj44Index == 10000) { // Reached end of strip + EventHandler *endHandler = _endHandler; remove(); + + if ((g_vm->getGameID() == GType_Ringworld2) && endHandler) + endHandler->signal(); + return; } @@ -714,7 +727,19 @@ void StripManager::signal() { load(); Obj44 &obj44 = _obj44List[_obj44Index]; - _field2E8 = obj44._id; + + if (g_vm->getGameID() != GType_Ringworld2) { + _field2E8 = obj44._id; + } else { + if (obj44._id) + _field2E8 = obj44._id; + + switch (obj44._mode) { + case 1: + break; + } + } + Common::StringArray choiceList; // Build up a list of script entries diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h index f82c07a7dd..db05913e08 100644 --- a/engines/tsage/converse.h +++ b/engines/tsage/converse.h @@ -185,6 +185,9 @@ public: int _field2[OBJ44_LIST_SIZE]; Obj0A _list[OBJ44_LIST_SIZE]; uint _speakerOffset; + + // Return to Ringworld specific field + int _mode; public: void load(const byte *dataP); virtual void synchronize(Serializer &s); @@ -215,6 +218,9 @@ public: Common::Array<byte> _script; StripProc _onBegin; StripProc _onEnd; + + // Ringworld 2 specific fields + byte *_lookupList; public: StripManager(); virtual ~StripManager(); @@ -225,6 +231,7 @@ public: virtual void process(Event &event); void start(int stripNum, EventHandler *owner, StripCallback *callback = NULL); + void start3(int stripNum, EventHandler *owner, byte *lookupList); void setCallback(StripCallback *callback) { _callbackObject = callback; } void setColors(int stdColor, int highlightColor) { _choiceDialog.setColors(stdColor, highlightColor); } void setFontNumber(int fontNum) { _choiceDialog.setFontNumber(fontNum); } diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 5a51a9c9ef..679fb59ef9 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -77,8 +77,8 @@ InvObject::InvObject(int strip, int frame) { } void InvObject::setCursor() { - if (g_vm->getGameID() == GType_BlueForce) { - // Blue Force cursor handling + if (g_vm->getGameID() != GType_Ringworld) { + // All other games _cursorId = (CursorType)BF_GLOBALS._inventory->indexOf(this); g_globals->_events.setCursor(_cursorId); } else { @@ -1061,6 +1061,8 @@ PaletteRotation::PaletteRotation() : PaletteModifierCached() { _percent = 0; _delayCtr = 0; _frameNumber = g_globals->_events.getFrameNumber(); + _idxChange = 1; + _countdown = 0; } void PaletteRotation::synchronize(Serializer &s) { @@ -1074,14 +1076,24 @@ void PaletteRotation::synchronize(Serializer &s) { s.syncAsSint32LE(_rotationMode); s.syncAsSint32LE(_duration); s.syncBytes(&_palette[0], 256 * 3); + + if (g_vm->getGameID() == GType_Ringworld2) { + s.syncAsSint16LE(_idxChange); + s.syncAsSint16LE(_countdown); + } } void PaletteRotation::signal() { + if (_countdown > 0) { + --_countdown; + return; + } + if (_delayCtr) { uint32 frameNumber = g_globals->_events.getFrameNumber(); if (frameNumber >= _frameNumber) { - _delayCtr = frameNumber - _frameNumber; + _delayCtr -= frameNumber - _frameNumber; _frameNumber = frameNumber; if (_delayCtr < 0) @@ -1098,21 +1110,24 @@ void PaletteRotation::signal() { bool flag = true; switch (_rotationMode) { case -1: - if (--_currIndex < _start) { + _currIndex -= _idxChange; + if (_currIndex < _start) { flag = decDuration(); if (flag) _currIndex = _end - 1; } break; case 1: - if (++_currIndex >= _end) { + _currIndex += _idxChange; + if (_currIndex >= _end) { flag = decDuration(); if (flag) _currIndex = _start; } break; case 2: - if (++_currIndex >= _end) { + _currIndex += _idxChange; + if (_currIndex >= _end) { flag = decDuration(); if (flag) { _currIndex = _end - 2; @@ -1121,7 +1136,8 @@ void PaletteRotation::signal() { } break; case 3: - if (--_currIndex < _start) { + _currIndex -= _idxChange; + if (_currIndex < _start) { flag = decDuration(); if (flag) { _currIndex = _start + 1; @@ -1144,7 +1160,9 @@ void PaletteRotation::signal() { void PaletteRotation::remove() { Action *action = _action; - g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start * 3], _start, _end - _start); + + if (_idxChange) + g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start * 3], _start, _end - _start); _scenePalette->_listeners.remove(this); @@ -1299,6 +1317,15 @@ void ScenePalette::setPalette(int index, int count) { } /** + * Get a palette entry + */ +void ScenePalette::getEntry(int index, uint *r, uint *g, uint *b) { + *r = _palette[index * 3]; + *g = _palette[index * 3 + 1]; + *b = _palette[index * 3 + 2]; +} + +/** * Set a palette entry */ void ScenePalette::setEntry(int index, uint r, uint g, uint b) { @@ -1439,7 +1466,7 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) { Rect tempRect = bounds; if (g_vm->getGameID() != GType_Ringworld) - tempRect.setHeight(BF_GLOBALS._interfaceY); + tempRect.setHeight(T2_GLOBALS._interfaceY); g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface, tempRect, Rect(0, 0, tempRect.width(), tempRect.height()), NULL); @@ -1551,6 +1578,7 @@ void SceneItem::display(int resNum, int lineNum, ...) { int maxWidth = 120; bool keepOnscreen = false; bool centerText = g_vm->getGameID() == GType_Ringworld; + Common::List<int> playList; if (resNum != 0) { va_list va; @@ -1559,6 +1587,17 @@ void SceneItem::display(int resNum, int lineNum, ...) { if (resNum == -1) msg = Common::String(va_arg(va, const char *)); + if (g_vm->getGameID() == GType_Ringworld2) { + // Pre-process the string for any sound information + while (msg.hasPrefix("!")) { + msg.deleteChar(0); + playList.push_back(atoi(msg.c_str())); + + while (!msg.empty() && (*msg.c_str() >= '0' && *msg.c_str() <= '9')) + msg.deleteChar(0); + } + } + int mode; do { // Get next instruction @@ -1666,6 +1705,12 @@ void SceneItem::display(int resNum, int lineNum, ...) { g_system->delayMillis(10); } + // For Return to Ringworld, play the voice overs in sequence + if ((g_vm->getGameID() == GType_Ringworld2) && !playList.empty() && !R2_GLOBALS._playStream.isPlaying()) { + R2_GLOBALS._playStream.play(*playList.begin(), NULL); + playList.pop_front(); + } + g_globals->_sceneText.remove(); } @@ -1688,7 +1733,8 @@ void SceneItem::display2(int resNum, int lineNum) { SET_EXT_FGCOLOR, 13, LIST_END); break; case GType_Ringworld2: - display(resNum, lineNum, SET_WIDTH, 280, SET_X, 20, SET_Y, 20, SET_EXT_BGCOLOR, 60, LIST_END); + display(resNum, lineNum, SET_WIDTH, 280, SET_X, 160, SET_Y, 20, SET_POS_MODE, ALIGN_CENTER, + SET_EXT_BGCOLOR, 60, LIST_END); break; default: display(resNum, lineNum, SET_WIDTH, 200, SET_EXT_BGCOLOR, 7, LIST_END); @@ -1827,7 +1873,6 @@ SceneObject::SceneObject() : SceneHotspot() { _moveDiff.x = 5; _moveDiff.y = 3; _numFrames = 10; - _numFrames = 10; _moveRate = 10; _regionBitList = 0; _sceneRegionId = 0; @@ -2754,6 +2799,7 @@ SceneText::SceneText() : SceneObject() { _fontNumber = 2; _width = 160; _textMode = ALIGN_LEFT; + _color1 = 0; _color2 = 0; _color3 = 0; } @@ -2929,6 +2975,17 @@ Player::Player(): SceneObject() { _enabled = false; _uiEnabled = false; _field8C = 0; + + // Return to Ringworld specific fields + _characterIndex = 0; + _oldSceneNumber = 0; + _fieldBC = 0; + + for (int i = 0; i < MAX_CHARACTERS; ++i) { + _characterScene[i] = 0; + _characterStrip[i] = 0; + _characterFrame[i] = 0; + } } void Player::postInit(SceneObjectList *OwnerList) { @@ -2988,6 +3045,11 @@ void Player::enableControl() { } } +void Player::enableControl(CursorType cursor) { + enableControl(); + R2_GLOBALS._events.setCursor(cursor); +} + void Player::process(Event &event) { if ((g_vm->getGameID() != GType_Ringworld) && _action) _action->process(event); @@ -3017,6 +3079,20 @@ void Player::synchronize(Serializer &s) { if (g_vm->getGameID() != GType_Ringworld) s.syncAsByte(_enabled); + + if (g_vm->getGameID() == GType_Ringworld2) { + s.syncAsSint16LE(_characterIndex); + s.syncAsSint16LE(_oldSceneNumber); + s.syncAsSint16LE(_fieldBC); + + for (int i = 0; i < MAX_CHARACTERS; ++i) { + s.syncAsSint16LE(_characterScene[i]); + s.syncAsSint16LE(_characterPos[i].x); + s.syncAsSint16LE(_characterPos[i].y); + s.syncAsSint16LE(_characterStrip[i]); + s.syncAsSint16LE(_characterFrame[i]); + } + } } /*--------------------------------------------------------------------------*/ @@ -3458,6 +3534,7 @@ void WalkRegions::clear() { _field18.clear(); _idxList.clear(); _idxList2.clear(); + _disabledRegions.clear(); } void WalkRegions::load(int sceneNum) { diff --git a/engines/tsage/core.h b/engines/tsage/core.h index 1a50d0beae..b2b491ce46 100644 --- a/engines/tsage/core.h +++ b/engines/tsage/core.h @@ -322,6 +322,8 @@ public: int _end; int _rotationMode; int _duration; + int _idxChange; + int _countdown; public: PaletteRotation(); @@ -372,6 +374,7 @@ public: bool loadPalette(int paletteNum); void refresh(); void setPalette(int index, int count); + void getEntry(int index, uint *r, uint *g, uint *b); void setEntry(int index, uint r, uint g, uint b); uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff); void getPalette(int start = 0, int count = 256); @@ -418,6 +421,7 @@ public: virtual void destroy() {} virtual bool startAction(CursorType action, Event &event); virtual void doAction(int action); + virtual bool performAction(CursorType action, Event &event) { return startAction(action, event); } bool contains(const Common::Point &pt); void setBounds(const Rect &newBounds) { _bounds = newBounds; } @@ -616,12 +620,23 @@ public: virtual void updateScreen(); }; +#define MAX_CHARACTERS 4 + class Player : public SceneObject { public: bool _canWalk; bool _uiEnabled; int _field8C; bool _enabled; + + // Return to Ringworld specific fields + int _characterIndex; + int _oldSceneNumber; + int _fieldBC; + int _characterScene[MAX_CHARACTERS]; + Common::Point _characterPos[MAX_CHARACTERS]; + int _characterStrip[MAX_CHARACTERS]; + int _characterFrame[MAX_CHARACTERS]; public: Player(); @@ -632,6 +647,7 @@ public: void disableControl(); void enableControl(); + void enableControl(CursorType cursor); }; /*--------------------------------------------------------------------------*/ @@ -810,6 +826,7 @@ public: Common::List<int> _disabledRegions; public: WalkRegions() { _resNum = -1; } + virtual ~WalkRegions() {} virtual void synchronize(Serializer &s); void clear(); diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp index 002835e76b..972d591c34 100644 --- a/engines/tsage/dialogs.cpp +++ b/engines/tsage/dialogs.cpp @@ -181,242 +181,6 @@ void ModalDialog::drawFrame() { /*--------------------------------------------------------------------------*/ -bool GfxInvImage::process(Event &event) { - if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) { - event.handled = _bounds.contains(event.mousePos); - return event.handled; - } - - return false; -} - -/*--------------------------------------------------------------------------*/ - -void InventoryDialog::show() { - // Determine how many items are in the player's inventory - int itemCount = 0; - SynchronizedList<InvObject *>::iterator i; - for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) { - if ((*i)->inInventory()) - ++itemCount; - } - - if (itemCount == 0) { - MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING); - return; - } - - InventoryDialog *dlg = new InventoryDialog(); - dlg->draw(); - dlg->execute(); - delete dlg; -} - -InventoryDialog::InventoryDialog() { - // Determine the maximum size of the image of any item in the player's inventory - int imgWidth = 0, imgHeight = 0; - - SynchronizedList<InvObject *>::iterator i; - for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) { - InvObject *invObject = *i; - if (invObject->inInventory()) { - // Get the image for the item - GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum); - - // Maintain the dimensions of the largest item image - imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width()); - imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height()); - - // Add the item to the display list - GfxInvImage *img = new GfxInvImage(); - _images.push_back(img); - img->setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum); - img->_invObject = invObject; - add(img); - } - } - assert(_images.size() > 0); - - // Figure out the number of columns/rows to show all the items - int cellsSize = 3; - while ((cellsSize * cellsSize) < (int)_images.size()) - ++cellsSize; - - // Set the position of each inventory item to be displayed - int cellX = 0; - Common::Point pt(0, 0); - - for (uint idx = 0; idx < _images.size(); ++idx) { - if (cellX == cellsSize) { - // Move to the start of the next line - pt.x = 0; - pt.y += imgHeight + 2; - cellX = 0; - } - - _images[idx]->_bounds.moveTo(pt.x, pt.y); - - pt.x += imgWidth + 2; - ++cellX; - } - - // Set up the buttons - pt.y += imgHeight + 2; - _btnOk.setText(OK_BTN_STRING); - _btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y); - _btnLook.setText(LOOK_BTN_STRING); - _btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top); - addElements(&_btnLook, &_btnOk, NULL); - - frame(); - setCenter(SCREEN_CENTER_X, SCREEN_CENTER_Y); -} - -InventoryDialog::~InventoryDialog() { - for (uint idx = 0; idx < _images.size(); ++idx) - delete _images[idx]; -} - -void InventoryDialog::execute() { - if ((RING_INVENTORY._selectedItem) && RING_INVENTORY._selectedItem->inInventory()) - RING_INVENTORY._selectedItem->setCursor(); - - GfxElement *hiliteObj; - bool lookFlag = false; - _gfxManager.activate(); - - while (!g_vm->shouldQuit()) { - // Get events - Event event; - while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) { - g_system->delayMillis(10); - g_system->updateScreen(); - } - if (g_vm->shouldQuit()) - break; - - hiliteObj = NULL; - if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos)) - break; - - // Pass event to elements - event.mousePos.x -= _gfxManager._bounds.left; - event.mousePos.y -= _gfxManager._bounds.top; - - for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) { - if ((*i)->process(event)) - hiliteObj = *i; - } - - if (!event.handled && event.eventType == EVENT_KEYPRESS) { - if ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)) { - // Exit the dialog - //hiliteObj = &_btnOk; - break; - } - } - - if (hiliteObj == &_btnOk) { - // Ok button clicked - if (lookFlag) - g_globals->_events.setCursor(CURSOR_WALK); - break; - } else if (hiliteObj == &_btnLook) { - // Look button clicked - if (_btnLook._message == LOOK_BTN_STRING) { - _btnLook._message = PICK_BTN_STRING; - lookFlag = 1; - g_globals->_events.setCursor(CURSOR_LOOK); - } else { - _btnLook._message = LOOK_BTN_STRING; - lookFlag = 0; - g_globals->_events.setCursor(CURSOR_WALK); - } - - hiliteObj->draw(); - } else if (hiliteObj) { - // Inventory item selected - InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject; - if (lookFlag) { - g_globals->_screenSurface.displayText(invObject->_description); - } else { - RING_INVENTORY._selectedItem = invObject; - invObject->setCursor(); - } - } - } - - _gfxManager.deactivate(); -} - -/*--------------------------------------------------------------------------*/ - -void OptionsDialog::show() { - OptionsDialog *dlg = new OptionsDialog(); - dlg->draw(); - - GfxButton *btn = dlg->execute(); - - if (btn == &dlg->_btnQuit) { - // Quit game - if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) { - g_vm->quitGame(); - } - } else if (btn == &dlg->_btnRestart) { - // Restart game - g_globals->_game->restartGame(); - } else if (btn == &dlg->_btnSound) { - // Sound dialog - SoundDialog::execute(); - } else if (btn == &dlg->_btnSave) { - // Save button - g_globals->_game->saveGame(); - } else if (btn == &dlg->_btnRestore) { - // Restore button - g_globals->_game->restoreGame(); - } - - dlg->remove(); - delete dlg; -} - -OptionsDialog::OptionsDialog() { - // Set the element text - _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT); - _btnRestore.setText(RESTORE_BTN_STRING); - _btnSave.setText(SAVE_BTN_STRING); - _btnRestart.setText(RESTART_BTN_STRING); - _btnQuit.setText(QUIT_BTN_STRING); - _btnSound.setText(SOUND_BTN_STRING); - _btnResume.setText(RESUME_BTN_STRING); - - // Set position of the elements - _gfxMessage._bounds.moveTo(0, 1); - _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1); - _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1); - _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1); - _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1); - _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1); - _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1); - - // Set all the buttons to the widest button - GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume}; - int16 btnWidth = 0; - for (int idx = 0; idx < 6; ++idx) - btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width()); - for (int idx = 0; idx < 6; ++idx) - btnList[idx]->_bounds.setWidth(btnWidth); - - // Add the items to the dialog - addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL); - - // Set the dialog size and position - frame(); - setCenter(160, 100); -} - -/*--------------------------------------------------------------------------*/ - void SoundDialog::execute() { ConfigDialog *dlg = new ConfigDialog(); dlg->runModal(); diff --git a/engines/tsage/dialogs.h b/engines/tsage/dialogs.h index 35ed60ba1a..33b55093d0 100644 --- a/engines/tsage/dialogs.h +++ b/engines/tsage/dialogs.h @@ -60,47 +60,6 @@ public: /*--------------------------------------------------------------------------*/ -class GfxInvImage : public GfxImage { -public: - InvObject *_invObject; -public: - GfxInvImage() : GfxImage(), _invObject(NULL) {} - - virtual bool process(Event &event); -}; - -#define MAX_INVOBJECT_DISPLAY 20 - -class InventoryDialog : public ModalDialog { -private: - Common::Array<GfxInvImage *> _images; - GfxButton _btnOk, _btnLook; -public: - InventoryDialog(); - virtual ~InventoryDialog(); - void execute(); - - static void show(); -}; - -/*--------------------------------------------------------------------------*/ - -class OptionsDialog : public ModalDialog { -private: - GfxButton _btnSave, _btnRestore, _btnRestart; - GfxButton _btnQuit, _btnResume; - GfxButton _btnSound; - GfxMessage _gfxMessage; -public: - OptionsDialog(); - virtual ~OptionsDialog() {} - GfxButton *execute() { return GfxDialog::execute(&_btnResume); } - - static void show(); -}; - -/*--------------------------------------------------------------------------*/ - class SoundDialog { public: static void execute(); diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp index d42b996e41..2c4efe5640 100644 --- a/engines/tsage/events.cpp +++ b/engines/tsage/events.cpp @@ -221,7 +221,8 @@ void EventsClass::setCursor(CursorType cursorType) { case CURSOR_WALK: default: - if (g_vm->getGameID() == GType_BlueForce) { + switch (g_vm->getGameID()) { + case GType_BlueForce: if (cursorType == CURSOR_WALK) { cursor = g_resourceManager->getSubResource(1, 5, 1, &size); } else { @@ -231,11 +232,25 @@ void EventsClass::setCursor(CursorType cursorType) { questionEnabled = true; } _currentCursor = cursorType; - } else { + break; + case GType_Ringworld2: + if (cursorType == CURSOR_WALK) { + cursor = CURSOR_WALK_DATA; + delFlag = false; + } else { + // Inventory icon + InvObject *invObject = g_globals->_inventory->getItem((int)cursorType); + cursor = g_resourceManager->getSubResource(6, invObject->_strip, invObject->_frame, &size); + questionEnabled = true; + } + _currentCursor = cursorType; + break; + default: // For Ringworld, always treat as the walk cursor cursor = CURSOR_WALK_DATA; _currentCursor = CURSOR_WALK; delFlag = false; + break; } break; } @@ -320,7 +335,6 @@ void EventsClass::setCursor(Graphics::Surface &cursor, int transColor, const Com } void EventsClass::setCursor(GfxSurface &cursor) { - // TODO: Find proper parameters for this form in Blue Force Graphics::Surface s = cursor.lockSurface(); const byte *cursorData = (const byte *)s.getBasePtr(0, 0); diff --git a/engines/tsage/events.h b/engines/tsage/events.h index 67d56ceb87..2ffa862ca6 100644 --- a/engines/tsage/events.h +++ b/engines/tsage/events.h @@ -83,8 +83,8 @@ enum CursorType { INV_CARAVAN_KEY = 67, BF_LAST_INVENT = 68, // Ringworld 2 objects - R2_1 = 1, R2_2 = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4, R2_5 = 5, R2_6 = 6, R2_7 = 7, - R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_14 = 14, + R2_OPTO_DISK = 1, R2_2 = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4, R2_5 = 5, R2_6 = 6, + R2_7 = 7, R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_14 = 14, R2_15 = 15, R2_16 = 16, R2_17 = 17, R2_18 = 18, R2_19 = 19, R2_20 = 20, R2_21 = 21, R2_22 = 22, R2_23 = 23, R2_24 = 24, R2_25 = 25, R2_26 = 26, R2_27 = 27, R2_28 = 28, R2_29 = 29, R2_30 = 30, R2_31 = 31, R2_32 = 32, R2_33 = 33, R2_34 = 34, R2_35 = 35, diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index 9bae180bc6..999261a32d 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -78,12 +78,15 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface _dialogCenter.y = 140; } else if (g_vm->getGameID() == GType_Ringworld2) { // Return to Ringworld - _gfxFontNumber = 2; - _gfxColors.background = 89; - _gfxColors.foreground = 83; - _fontColors.background = 88; - _fontColors.foreground = 92; - _dialogCenter.y = 140; + _gfxFontNumber = 50; + _gfxColors.background = 0; + _gfxColors.foreground = 59; + _fontColors.background = 4; + _fontColors.foreground = 15; + _color1 = 59; + _color2 = 15; + _color3 = 4; + _dialogCenter.y = 100; } else if ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_CD)) { _gfxFontNumber = 50; _gfxColors.background = 53; @@ -94,6 +97,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface _color2 = 18; _color3 = 18; } else { + // Ringworld _gfxFontNumber = 50; _gfxColors.background = 53; _gfxColors.foreground = 18; @@ -137,7 +141,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface case GType_Ringworld2: _inventory = new Ringworld2::Ringworld2InvObjectList(); _game = new Ringworld2::Ringworld2Game(); - _sceneHandler = new SceneHandler(); + _sceneHandler = new Ringworld2::SceneHandlerExt(); break; } } @@ -151,7 +155,7 @@ Globals::~Globals() { } void Globals::reset() { - Common::set_to(&_flags[0], &_flags[MAX_FLAGS], false); + Common::fill(&_flags[0], &_flags[MAX_FLAGS], false); g_saver->addFactory(classFactoryProc); } @@ -225,20 +229,23 @@ void BlueForceGlobals::synchronize(Serializer &s) { TsAGE2Globals::synchronize(s); s.syncAsSint16LE(_dayNumber); - s.syncAsSint16LE(_v4CEA4); - s.syncAsSint16LE(_v4CEAA); + if (s.getVersion() < 9) { + int tmpVar; + s.syncAsSint16LE(tmpVar); + } + s.syncAsSint16LE(_tonyDialogCtr); s.syncAsSint16LE(_marinaWomanCtr); - s.syncAsSint16LE(_v4CEB0); + s.syncAsSint16LE(_kateDialogCtr); s.syncAsSint16LE(_v4CEB6); s.syncAsSint16LE(_safeCombination); - s.syncAsSint16LE(_v4CEC0); + s.syncAsSint16LE(_gateStatus); s.syncAsSint16LE(_greenDay5TalkCtr); s.syncAsSint16LE(_v4CEC4); s.syncAsSint16LE(_v4CEC8); s.syncAsSint16LE(_v4CECA); s.syncAsSint16LE(_v4CECC); for (int i = 0; i < 18; i++) - s.syncAsByte(_v4CECE[i]); + s.syncAsByte(_breakerBoxStatusArr[i]); s.syncAsSint16LE(_v4CEE0); s.syncAsSint16LE(_v4CEE2); s.syncAsSint16LE(_v4CEE4); @@ -253,8 +260,8 @@ void BlueForceGlobals::synchronize(Serializer &s) { s.syncAsSint16LE(_v501FC); s.syncAsSint16LE(_v5020C); s.syncAsSint16LE(_v50696); - s.syncAsSint16LE(_v5098C); - s.syncAsSint16LE(_v5098D); + s.syncAsSint16LE(_subFlagBitArr1); + s.syncAsSint16LE(_subFlagBitArr2); s.syncAsSint16LE(_v50CC2); s.syncAsSint16LE(_v50CC4); s.syncAsSint16LE(_v50CC6); @@ -283,36 +290,35 @@ void BlueForceGlobals::reset() { _interfaceY = UI_INTERFACE_Y; _dayNumber = 0; - _v4CEA4 = 0; - _v4CEAA = 0; + _tonyDialogCtr = 0; _marinaWomanCtr = 0; - _v4CEB0 = 0; + _kateDialogCtr = 0; _v4CEB6 = 0; _safeCombination = 0; - _v4CEC0 = 0; + _gateStatus = 0; _greenDay5TalkCtr = 0; _v4CEC4 = 0; _v4CEC8 = 1; _v4CECA = 0; _v4CECC = 0; - _v4CECE[0] = 2; - _v4CECE[1] = 2; - _v4CECE[2] = 2; - _v4CECE[3] = 1; - _v4CECE[4] = 2; - _v4CECE[5] = 2; - _v4CECE[6] = 2; - _v4CECE[7] = 2; - _v4CECE[8] = 2; - _v4CECE[9] = 2; - _v4CECE[10] = 2; - _v4CECE[11] = 2; - _v4CECE[12] = 1; - _v4CECE[13] = 1; - _v4CECE[14] = 2; - _v4CECE[15] = 2; - _v4CECE[16] = 3; - _v4CECE[17] = 0; + _breakerBoxStatusArr[0] = 2; + _breakerBoxStatusArr[1] = 2; + _breakerBoxStatusArr[2] = 2; + _breakerBoxStatusArr[3] = 1; + _breakerBoxStatusArr[4] = 2; + _breakerBoxStatusArr[5] = 2; + _breakerBoxStatusArr[6] = 2; + _breakerBoxStatusArr[7] = 2; + _breakerBoxStatusArr[8] = 2; + _breakerBoxStatusArr[9] = 2; + _breakerBoxStatusArr[10] = 2; + _breakerBoxStatusArr[11] = 2; + _breakerBoxStatusArr[12] = 1; + _breakerBoxStatusArr[13] = 1; + _breakerBoxStatusArr[14] = 2; + _breakerBoxStatusArr[15] = 2; + _breakerBoxStatusArr[16] = 3; + _breakerBoxStatusArr[17] = 0; _v4CEE0 = 0; _v4CEE2 = 0; _v4CEE4 = 0; @@ -325,8 +331,8 @@ void BlueForceGlobals::reset() { _v501FC = 0; _v5020C = 0; _v50696 = 0; - _v5098C = 0; - _v5098D = 0; + _subFlagBitArr1 = 0; + _subFlagBitArr2 = 0; _v50CC2 = 0; _v50CC4 = 0; _v50CC6 = 0; @@ -367,10 +373,52 @@ void Ringworld2Globals::reset() { R2_INVENTORY.reset(); T2_GLOBALS._uiElements.updateInventory(); T2_GLOBALS._uiElements._active = false; + + // Reset fields + _v5657C = 0; + _v565F5 = 0; + _v57C2C = 0; + _v58CE2 = 0; + Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 0); + _speechSubtitles = 0; + _insetUp = 0; + + Common::fill(&_v565F1[0], &_v565F1[MAX_CHARACTERS], 0); + Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0); + _stripManager_lookupList[0] = 1; + _stripManager_lookupList[1] = 1; + _stripManager_lookupList[2] = 1; + _stripManager_lookupList[3] = 1; + _stripManager_lookupList[4] = 1; + _stripManager_lookupList[5] = 1; + _stripManager_lookupList[8] = 1; + _stripManager_lookupList[9] = 1; + _stripManager_lookupList[10] = 1; + _stripManager_lookupList[11] = 1; + + // Reset fields stored in the player class + _player._characterIndex = 1; + _player._characterScene[1] = 100; + _player._characterScene[2] = 300; + _player._characterScene[3] = 300; } void Ringworld2Globals::synchronize(Serializer &s) { TsAGE2Globals::synchronize(s); + int i; + + s.syncAsSint16LE(_v5657C); + s.syncAsSint16LE(_v565F5); + s.syncAsSint16LE(_v57C2C); + s.syncAsSint16LE(_v58CE2); + s.syncAsSint16LE(_speechSubtitles); + + for (i = 0; i < MAX_CHARACTERS; ++i) + s.syncAsSint16LE(_v565F1[i]); + for (i = 0; i < 12; ++i) + s.syncAsByte(_stripManager_lookupList[i]); + + s.syncAsSint16LE(_insetUp); } } // end of namespace Ringworld2 diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index 1e50c08f56..29d5125593 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -187,19 +187,18 @@ public: ASoundExt _sound1, _sound3; StripProxy _stripProxy; int _dayNumber; - int _v4CEA4; - int _v4CEAA; + int _tonyDialogCtr; int _marinaWomanCtr; - int _v4CEB0; + int _kateDialogCtr; int _v4CEB6; int _safeCombination; - int _v4CEC0; + int _gateStatus; int _greenDay5TalkCtr; int _v4CEC4; int _v4CEC8; int _v4CECA; int _v4CECC; - int8 _v4CECE[18]; + int8 _breakerBoxStatusArr[18]; int _v4CEE0; int _v4CEE2; int _v4CEE4; @@ -214,8 +213,8 @@ public: int _v501FC; int _v5020C; int _v50696; - uint8 _v5098C; - uint8 _v5098D; + uint8 _subFlagBitArr1; + uint8 _subFlagBitArr2; int _v50CC2; int _v50CC4; int _v50CC6; @@ -243,6 +242,16 @@ namespace Ringworld2 { class Ringworld2Globals: public TsAGE2Globals { public: ASoundExt _sound1, _sound2, _sound3, _sound4; + PlayStream _playStream; + StripProxy _stripProxy; + int _insetUp; + int _v565F5; + int _v5657C; + int _v57C2C; + int _v58CE2; + int _speechSubtitles; + int _v565F1[4]; + byte _stripManager_lookupList[12]; virtual void reset(); virtual void synchronize(Serializer &s); diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index 4b2da0b456..f0a5973e6b 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -81,7 +81,7 @@ GfxSurface surfaceFromRes(const byte *imgData) { if (!rleEncoded) { Common::copy(srcP, srcP + (r.width() * r.height()), destP); } else { - Common::set_to(destP, destP + (r.width() * r.height()), s._transColor); + Common::fill(destP, destP + (r.width() * r.height()), s._transColor); for (int yp = 0; yp < r.height(); ++yp) { int width = r.width(); @@ -105,7 +105,7 @@ GfxSurface surfaceFromRes(const byte *imgData) { controlVal &= 0x3f; int pixel = *srcP++; - Common::set_to(destP, destP + controlVal, pixel); + Common::fill(destP, destP + controlVal, pixel); destP += controlVal; width -= controlVal; } @@ -261,7 +261,7 @@ void GfxSurface::create(int width, int height) { } _customSurface = new Graphics::Surface(); _customSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - Common::set_to((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0); + Common::fill((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0); _bounds = Rect(0, 0, width, height); } @@ -455,7 +455,7 @@ static int *scaleLine(int size, int srcSize) { int scale = PRECISION_FACTOR * size / srcSize; assert(scale >= 0); int *v = new int[size]; - Common::set_to(v, &v[size], -1); + Common::fill(v, &v[size], -1); int distCtr = PRECISION_FACTOR / 2; int *destP = v; @@ -493,7 +493,7 @@ static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize, int trans byte *destP = (byte *)destImage.getBasePtr(0, yp); if (vertUsage[yp] == -1) { - Common::set_to(destP, destP + xSize, transIndex); + Common::fill(destP, destP + xSize, transIndex); } else { const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]); @@ -676,7 +676,39 @@ void GfxElement::drawFrame() { Rect tempRect = _bounds; tempRect.collapse(g_globals->_gfxEdgeAdjust, g_globals->_gfxEdgeAdjust); tempRect.collapse(-1, -1); - gfxManager.fillRect(tempRect, _colors.background); + + if (g_vm->getGameID() == GType_Ringworld2) { + // For Return to Ringworld, use palette shading + + // Get the current palette and determining a shading translation list + ScenePalette tempPalette; + tempPalette.getPalette(0, 256); + int transList[256]; + + for (int i = 0; i < 256; ++i) { + uint r, g, b, v; + tempPalette.getEntry(i, &r, &g, &b); + v = ((r >> 1) + (g >> 1) + (b >> 1)) / 4; + + transList[i] = tempPalette.indexOf(v, v, v); + } + + // Loop through the surface area to replace each pixel + // with its proper shaded replacement + Graphics::Surface surface = gfxManager.lockSurface(); + for (int y = tempRect.top; y < tempRect.bottom; ++y) { + byte *lineP = (byte *)surface.getBasePtr(tempRect.left, y); + for (int x = 0; x < tempRect.width(); ++x) { + *lineP = transList[*lineP]; + lineP++; + } + } + gfxManager.unlockSurface(); + + } else { + // Fill dialog content with specified background colour + gfxManager.fillRect(tempRect, _colors.background); + } --tempRect.bottom; --tempRect.right; gfxManager.fillArea(tempRect.left, tempRect.top, bgColor); diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h index 06b482d7b5..dba3401700 100644 --- a/engines/tsage/graphics.h +++ b/engines/tsage/graphics.h @@ -292,7 +292,7 @@ public: Common::copy(src, src + size, dest); } virtual void set(byte *dest, int size, byte val) { - Common::set_to(dest, dest + size, val); + Common::fill(dest, dest + size, val); } void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) { _surface.setBounds(_bounds); diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk index 0ea8916647..99aa12a249 100644 --- a/engines/tsage/module.mk +++ b/engines/tsage/module.mk @@ -38,6 +38,7 @@ MODULE_OBJS := \ ringworld2/ringworld2_dialogs.o \ ringworld2/ringworld2_logic.o \ ringworld2/ringworld2_scenes0.o \ + ringworld2/ringworld2_speakers.o \ saveload.o \ scenes.o \ sound.o \ diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp index 652ab32350..824f20e9b2 100644 --- a/engines/tsage/resources.cpp +++ b/engines/tsage/resources.cpp @@ -33,7 +33,7 @@ namespace TsAGE { MemoryManager::MemoryManager() { _memoryPool = new MemoryHeader*[MEMORY_POOL_SIZE]; - Common::set_to(&_memoryPool[0], &_memoryPool[MEMORY_POOL_SIZE], (MemoryHeader *)NULL); + Common::fill(&_memoryPool[0], &_memoryPool[MEMORY_POOL_SIZE], (MemoryHeader *)NULL); } MemoryManager::~MemoryManager() { @@ -67,7 +67,7 @@ uint16 MemoryManager::allocate(uint32 size) { byte *MemoryManager::allocate2(uint32 size) { uint32 idx = allocate(size); byte *result = lock(idx); - Common::set_to(result, result + size, 0); + Common::fill(result, result + size, 0); return result; } @@ -414,16 +414,27 @@ byte *TLib::getSubResource(int resNum, int rlbNum, int index, uint *size, bool s */ bool TLib::getMessage(int resNum, int lineNum, Common::String &result, bool suppressErrors) { byte *msgData = getResource(RES_MESSAGE, resNum, 0, true); - if (!msgData) { + if (!msgData || (lineNum < 0)) { if (suppressErrors) return false; error("Unknown message %d line %d", resNum, lineNum); } + int msgSize = _memoryManager.getSize(msgData); const char *srcP = (const char *)msgData; - while (lineNum-- > 0) + const char *endP = srcP + msgSize; + + while (lineNum-- > 0) { srcP += strlen(srcP) + 1; + + if (srcP >= endP) { + if (suppressErrors) + return false; + + error("Unknown message %d line %d", resNum, lineNum); + } + } result = Common::String(srcP); _memoryManager.deallocate(msgData); @@ -503,7 +514,7 @@ Common::String ResourceManager::getMessage(int resNum, int lineNum, bool suppres if (!suppressErrors) error("Unknown message %d line %d", resNum, lineNum); - return result; + return Common::String(); } } // end of namespace TsAGE diff --git a/engines/tsage/ringworld/ringworld_dialogs.cpp b/engines/tsage/ringworld/ringworld_dialogs.cpp index 9d1a7effc2..37101c9c58 100644 --- a/engines/tsage/ringworld/ringworld_dialogs.cpp +++ b/engines/tsage/ringworld/ringworld_dialogs.cpp @@ -210,13 +210,249 @@ void RightClickDialog::execute() { break; case 6: // Dialog options - OptionsDialog::show(); + Ringworld::OptionsDialog::show(); break; } _gfxManager.deactivate(); } +/*--------------------------------------------------------------------------*/ + +void OptionsDialog::show() { + OptionsDialog *dlg = new OptionsDialog(); + dlg->draw(); + + GfxButton *btn = dlg->execute(); + + if (btn == &dlg->_btnQuit) { + // Quit game + if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) { + g_vm->quitGame(); + } + } else if (btn == &dlg->_btnRestart) { + // Restart game + g_globals->_game->restartGame(); + } else if (btn == &dlg->_btnSound) { + // Sound dialog + SoundDialog::execute(); + } else if (btn == &dlg->_btnSave) { + // Save button + g_globals->_game->saveGame(); + } else if (btn == &dlg->_btnRestore) { + // Restore button + g_globals->_game->restoreGame(); + } + + dlg->remove(); + delete dlg; +} + +OptionsDialog::OptionsDialog() { + // Set the element text + _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT); + _btnRestore.setText(RESTORE_BTN_STRING); + _btnSave.setText(SAVE_BTN_STRING); + _btnRestart.setText(RESTART_BTN_STRING); + _btnQuit.setText(QUIT_BTN_STRING); + _btnSound.setText(SOUND_BTN_STRING); + _btnResume.setText(RESUME_BTN_STRING); + + // Set position of the elements + _gfxMessage._bounds.moveTo(0, 1); + _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1); + _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1); + _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1); + _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1); + _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1); + _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1); + + // Set all the buttons to the widest button + GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume}; + int16 btnWidth = 0; + for (int idx = 0; idx < 6; ++idx) + btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width()); + for (int idx = 0; idx < 6; ++idx) + btnList[idx]->_bounds.setWidth(btnWidth); + + // Add the items to the dialog + addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL); + + // Set the dialog size and position + frame(); + setCenter(160, 100); +} + +/*--------------------------------------------------------------------------*/ + +bool GfxInvImage::process(Event &event) { + if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) { + event.handled = _bounds.contains(event.mousePos); + return event.handled; + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +void InventoryDialog::show() { + // Determine how many items are in the player's inventory + int itemCount = 0; + SynchronizedList<InvObject *>::iterator i; + for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) { + if ((*i)->inInventory()) + ++itemCount; + } + + if (itemCount == 0) { + MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING); + return; + } + + InventoryDialog *dlg = new InventoryDialog(); + dlg->draw(); + dlg->execute(); + delete dlg; +} + +InventoryDialog::InventoryDialog() { + // Determine the maximum size of the image of any item in the player's inventory + int imgWidth = 0, imgHeight = 0; + + SynchronizedList<InvObject *>::iterator i; + for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) { + InvObject *invObject = *i; + if (invObject->inInventory()) { + // Get the image for the item + GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum); + + // Maintain the dimensions of the largest item image + imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width()); + imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height()); + + // Add the item to the display list + GfxInvImage *img = new GfxInvImage(); + _images.push_back(img); + img->setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum); + img->_invObject = invObject; + add(img); + } + } + assert(_images.size() > 0); + + // Figure out the number of columns/rows to show all the items + int cellsSize = 3; + while ((cellsSize * cellsSize) < (int)_images.size()) + ++cellsSize; + + // Set the position of each inventory item to be displayed + int cellX = 0; + Common::Point pt(0, 0); + + for (uint idx = 0; idx < _images.size(); ++idx) { + if (cellX == cellsSize) { + // Move to the start of the next line + pt.x = 0; + pt.y += imgHeight + 2; + cellX = 0; + } + + _images[idx]->_bounds.moveTo(pt.x, pt.y); + + pt.x += imgWidth + 2; + ++cellX; + } + + // Set up the buttons + pt.y += imgHeight + 2; + _btnOk.setText(OK_BTN_STRING); + _btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y); + _btnLook.setText(LOOK_BTN_STRING); + _btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top); + addElements(&_btnLook, &_btnOk, NULL); + + frame(); + setCenter(SCREEN_CENTER_X, SCREEN_CENTER_Y); +} + +InventoryDialog::~InventoryDialog() { + for (uint idx = 0; idx < _images.size(); ++idx) + delete _images[idx]; +} + +void InventoryDialog::execute() { + if ((RING_INVENTORY._selectedItem) && RING_INVENTORY._selectedItem->inInventory()) + RING_INVENTORY._selectedItem->setCursor(); + + GfxElement *hiliteObj; + bool lookFlag = false; + _gfxManager.activate(); + + while (!g_vm->shouldQuit()) { + // Get events + Event event; + while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) { + g_system->delayMillis(10); + g_system->updateScreen(); + } + if (g_vm->shouldQuit()) + break; + + hiliteObj = NULL; + if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos)) + break; + + // Pass event to elements + event.mousePos.x -= _gfxManager._bounds.left; + event.mousePos.y -= _gfxManager._bounds.top; + + for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) { + if ((*i)->process(event)) + hiliteObj = *i; + } + + if (!event.handled && event.eventType == EVENT_KEYPRESS) { + if ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)) { + // Exit the dialog + //hiliteObj = &_btnOk; + break; + } + } + + if (hiliteObj == &_btnOk) { + // Ok button clicked + if (lookFlag) + g_globals->_events.setCursor(CURSOR_WALK); + break; + } else if (hiliteObj == &_btnLook) { + // Look button clicked + if (_btnLook._message == LOOK_BTN_STRING) { + _btnLook._message = PICK_BTN_STRING; + lookFlag = 1; + g_globals->_events.setCursor(CURSOR_LOOK); + } else { + _btnLook._message = LOOK_BTN_STRING; + lookFlag = 0; + g_globals->_events.setCursor(CURSOR_WALK); + } + + hiliteObj->draw(); + } else if (hiliteObj) { + // Inventory item selected + InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject; + if (lookFlag) { + g_globals->_screenSurface.displayText(invObject->_description); + } else { + RING_INVENTORY._selectedItem = invObject; + invObject->setCursor(); + } + } + } + + _gfxManager.deactivate(); +} + } // End of namespace Ringworld } // End of namespace TsAGE diff --git a/engines/tsage/ringworld/ringworld_dialogs.h b/engines/tsage/ringworld/ringworld_dialogs.h index 11a8f10e70..b14b3f6d78 100644 --- a/engines/tsage/ringworld/ringworld_dialogs.h +++ b/engines/tsage/ringworld/ringworld_dialogs.h @@ -63,6 +63,45 @@ public: void execute(); }; +class OptionsDialog : public ModalDialog { +private: + GfxButton _btnSave, _btnRestore, _btnRestart; + GfxButton _btnQuit, _btnResume; + GfxButton _btnSound; + GfxMessage _gfxMessage; +public: + OptionsDialog(); + virtual ~OptionsDialog() {} + GfxButton *execute() { return GfxDialog::execute(&_btnResume); } + + static void show(); +}; + +/*--------------------------------------------------------------------------*/ + +class GfxInvImage : public GfxImage { +public: + InvObject *_invObject; +public: + GfxInvImage() : GfxImage(), _invObject(NULL) {} + + virtual bool process(Event &event); +}; + +#define MAX_INVOBJECT_DISPLAY 20 + +class InventoryDialog : public ModalDialog { +private: + Common::Array<GfxInvImage *> _images; + GfxButton _btnOk, _btnLook; +public: + InventoryDialog(); + virtual ~InventoryDialog(); + void execute(); + + static void show(); +}; + } // End of namespace Ringworld } // End of namespace TsAGE diff --git a/engines/tsage/ringworld/ringworld_scenes10.cpp b/engines/tsage/ringworld/ringworld_scenes10.cpp index 5aeb127915..668e86dafb 100644 --- a/engines/tsage/ringworld/ringworld_scenes10.cpp +++ b/engines/tsage/ringworld/ringworld_scenes10.cpp @@ -709,7 +709,7 @@ void Scene9360::postInit(SceneObjectList *OwnerList) { * *--------------------------------------------------------------------------*/ Scene9400::Scene9400() { - _field1032 = 0; + _hittingAnvil = false; } void Scene9400::SceneHotspot7::doAction(int action) { @@ -767,12 +767,12 @@ void Scene9400::signal() { void Scene9400::dispatch() { if ((_object1._animateMode == 2) && (_object1._strip == 1) && (_object1._frame == 4)){ - if (_field1032 == 0) { + if (_hittingAnvil == false) { _soundHandler.play(296); - _field1032 = 1; + _hittingAnvil = true; } } else { - _field1032 = 0; + _hittingAnvil = false; } if (_action == 0) { if (g_globals->_player._position.y < 120) { @@ -826,7 +826,7 @@ void Scene9400::postInit(SceneObjectList *OwnerList) { void Scene9400::synchronize(Serializer &s) { Scene::synchronize(s); if (s.getVersion() >= 3) - s.syncAsSint16LE(_field1032); + s.syncAsSint16LE(_hittingAnvil); } /*-------------------------------------------------------------------------- diff --git a/engines/tsage/ringworld/ringworld_scenes10.h b/engines/tsage/ringworld/ringworld_scenes10.h index 0193d5af63..48859ab454 100644 --- a/engines/tsage/ringworld/ringworld_scenes10.h +++ b/engines/tsage/ringworld/ringworld_scenes10.h @@ -236,7 +236,7 @@ public: NamedHotspot _hotspot5; NamedHotspot _hotspot6; ASound _soundHandler; - int _field1032; + bool _hittingAnvil; SceneHotspot7 _hotspot7; SceneHotspot8 _hotspot8; diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp index 3cf1207e9e..49726eba2e 100644 --- a/engines/tsage/ringworld/ringworld_scenes5.cpp +++ b/engines/tsage/ringworld/ringworld_scenes5.cpp @@ -1478,7 +1478,7 @@ void Scene4025::Hole::doAction(int action) { void Scene4025::Peg::synchronize(Serializer &s) { SceneObject::synchronize(s); - s.syncAsSint16LE(_field88); + s.syncAsSint16LE(_pegId); s.syncAsSint16LE(_armStrip); } @@ -1513,35 +1513,35 @@ void Scene4025::postInit(SceneObjectList *OwnerList) { _pegPtr = _pegPtr2 = NULL; _peg1.postInit(); - _peg1._field88 = 1; + _peg1._pegId = 1; _peg1.setVisage(4025); _peg1.setStrip(2); _peg1.setFrame(1); _peg1.setPosition(Common::Point(203, 61)); _peg2.postInit(); - _peg2._field88 = 4; + _peg2._pegId = 4; _peg2.setVisage(4025); _peg2.setStrip(2); _peg2.setFrame(2); _peg2.setPosition(Common::Point(195, 57)); _peg3.postInit(); - _peg3._field88 = 0; + _peg3._pegId = 0; _peg3.setVisage(4025); _peg3.setStrip(2); _peg3.setFrame(3); _peg3.setPosition(Common::Point(202, 66)); _peg4.postInit(); - _peg4._field88 = 3; + _peg4._pegId = 3; _peg4.setVisage(4025); _peg4.setStrip(2); _peg4.setFrame(4); _peg4.setPosition(Common::Point(194, 68)); _peg5.postInit(); - _peg5._field88 = 2; + _peg5._pegId = 2; _peg5.setVisage(4025); _peg5.setStrip(1); _peg5.setFrame(5); @@ -2173,7 +2173,7 @@ void Scene4050::Action4::signal() { case 5: scene->_hotspot16.setStrip2(4); scene->_hotspot16.setFrame(1); - scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);; + scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this); break; case 6: scene->_hotspot16.animate(ANIM_MODE_5, NULL); @@ -4311,7 +4311,7 @@ void Scene4301::Action1::signal() { setDelay(20); break; case 21: - scene->_field68E = true; + scene->_puzzleDone = true; remove(); break; } @@ -4412,7 +4412,7 @@ void Scene4301::postInit(SceneObjectList *OwnerList) { Scene::postInit(); setZoomPercents(0, 100, 200, 100); - _field68E = false; + _puzzleDone = false; RING_INVENTORY._stasisBox2._sceneNumber = 1; _hotspot4.setDetails(97, 76, 127, 102, 4300, 5, 6); @@ -4432,8 +4432,8 @@ void Scene4301::postInit(SceneObjectList *OwnerList) { void Scene4301::dispatch() { if (_action) { _action->dispatch(); - } else if (_field68E) { - _field68E = 0; + } else if (_puzzleDone) { + _puzzleDone = false; g_globals->clearFlag(50); g_globals->_sceneManager._fadeMode = FADEMODE_NONE; g_globals->_sceneManager.setNewScene(4300); diff --git a/engines/tsage/ringworld/ringworld_scenes5.h b/engines/tsage/ringworld/ringworld_scenes5.h index 80e67755bd..c93df2a1d8 100644 --- a/engines/tsage/ringworld/ringworld_scenes5.h +++ b/engines/tsage/ringworld/ringworld_scenes5.h @@ -215,10 +215,10 @@ class Scene4025 : public Scene { }; class Peg : public SceneObject { public: - int _field88; + int _pegId; int _armStrip; - Peg() : SceneObject() { _field88 = 0; _armStrip = 3; } + Peg() : SceneObject() { _pegId = 0; _armStrip = 3; } virtual void synchronize(Serializer &s); virtual void doAction(int action); }; @@ -682,13 +682,13 @@ public: SceneObject _hotspot1, _hotspot2, _hotspot3; Hotspot4 _hotspot4; Hotspot5 _hotspot5; - bool _field68E; + bool _puzzleDone; virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void dispatch(); virtual void synchronize(Serializer &s) { Scene::synchronize(s); - s.syncAsSint16LE(_field68E); + s.syncAsSint16LE(_puzzleDone); } }; diff --git a/engines/tsage/ringworld/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp index 57a073caee..30a91b57aa 100644 --- a/engines/tsage/ringworld/ringworld_scenes6.cpp +++ b/engines/tsage/ringworld/ringworld_scenes6.cpp @@ -1124,7 +1124,7 @@ void Scene5100::postInit(SceneObjectList *OwnerList) { _hotspot4.setVisage(5363); _hotspot4.setPosition(Common::Point(1025, 65)); _hotspot4.setStrip(4); - _hotspot4.animate(ANIM_MODE_7, 0, NULL);; + _hotspot4.animate(ANIM_MODE_7, 0, NULL); g_globals->_sceneItems.push_back(&_hotspot4); _hotspot9.postInit(); diff --git a/engines/tsage/ringworld/ringworld_scenes8.cpp b/engines/tsage/ringworld/ringworld_scenes8.cpp index f8fb8b01e7..9cb85a6930 100644 --- a/engines/tsage/ringworld/ringworld_scenes8.cpp +++ b/engines/tsage/ringworld/ringworld_scenes8.cpp @@ -1879,12 +1879,12 @@ void Scene7700::SceneHotspot8::doAction(int action) { scene->_soundHandler.play(259); scene->_object15.setFrame(scene->_object15.getFrameCount()); scene->_object15.animate(ANIM_MODE_6, scene); - if ((scene->_field977 == 2) && (scene->_field97B == 0)) { - scene->_field979++; + if ((scene->_seatCountLeft1 == 2) && (scene->_seatCountLeft2 == 0)) { + scene->_seatCountRight++; } else { - scene->_field97B = 0; - scene->_field979 = 0; - scene->_field977 = 0; + scene->_seatCountLeft2 = 0; + scene->_seatCountRight = 0; + scene->_seatCountLeft1 = 0; } break; default: @@ -1905,26 +1905,26 @@ void Scene7700::SceneHotspot9::doAction(int action) { scene->_soundHandler.play(259); scene->_object15.setFrame(1); scene->_object15.animate(ANIM_MODE_5, scene); - if (scene->_field977 > 2) { - scene->_field97B = 0; - scene->_field979 = 0; - scene->_field977 = 0; + if (scene->_seatCountLeft1 > 2) { + scene->_seatCountLeft2 = 0; + scene->_seatCountRight = 0; + scene->_seatCountLeft1 = 0; } - if (scene->_field979 != 0) { - if (scene->_field979 != 4) { - scene->_field97B = 0; - scene->_field979 = 0; - scene->_field977 = 0; + if (scene->_seatCountRight != 0) { + if (scene->_seatCountRight != 4) { + scene->_seatCountLeft2 = 0; + scene->_seatCountRight = 0; + scene->_seatCountLeft1 = 0; } else { - scene->_field97B++; - if (scene->_field97B == 3) { + scene->_seatCountLeft2++; + if (scene->_seatCountLeft2 == 3) { g_globals->_player.disableControl(); scene->setAction(&scene->_action3); } } } else { - scene->_field977++; + scene->_seatCountLeft1++; } break; default: @@ -2315,9 +2315,9 @@ void Scene7700::postInit(SceneObjectList *OwnerList) { Scene::postInit(); setZoomPercents(100, 80, 200, 100); g_globals->setFlag(53); - _field97B = 0; - _field979 = 0; - _field977 = 0; + _seatCountLeft2 = 0; + _seatCountRight = 0; + _seatCountLeft1 = 0; _stripManager.addSpeaker(&_speakerEText); _stripManager.addSpeaker(&_speakerQText); @@ -2538,9 +2538,9 @@ Scene7700::Scene7700() { void Scene7700::synchronize(Serializer &s) { Scene::synchronize(s); if (s.getVersion() >= 3) { - s.syncAsSint16LE(_field977); - s.syncAsSint16LE(_field979); - s.syncAsSint16LE(_field97B); + s.syncAsSint16LE(_seatCountLeft1); + s.syncAsSint16LE(_seatCountRight); + s.syncAsSint16LE(_seatCountLeft2); } } diff --git a/engines/tsage/ringworld/ringworld_scenes8.h b/engines/tsage/ringworld/ringworld_scenes8.h index 84178c36f9..b24f220f8c 100644 --- a/engines/tsage/ringworld/ringworld_scenes8.h +++ b/engines/tsage/ringworld/ringworld_scenes8.h @@ -480,7 +480,7 @@ public: SceneHotspot11 _sceneHotspot34; SceneHotspot11 _sceneHotspot35; SceneHotspot11 _sceneHotspot36; - int _field977, _field979, _field97B; + int _seatCountLeft1, _seatCountRight, _seatCountLeft2; Scene7700(); virtual void postInit(SceneObjectList *OwnerList = NULL); diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp index 8d4863f332..ade76d501a 100644 --- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp +++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp @@ -31,6 +31,7 @@ #include "tsage/staticres.h" #include "tsage/globals.h" #include "tsage/ringworld2/ringworld2_dialogs.h" +#include "tsage/ringworld2/ringworld2_logic.h" namespace TsAGE { @@ -176,6 +177,7 @@ void RightClickDialog::execute() { break; case 4: // Change player + CharacterDialog::show(); break; case 5: // Options dialog @@ -188,6 +190,258 @@ void RightClickDialog::execute() { _gfxManager.deactivate(); } +/*--------------------------------------------------------------------------*/ + +void CharacterDialog::show() { + CharacterDialog *dlg = new CharacterDialog(); + dlg->draw(); + + // Make the default button the currently active character + GfxButton *btn = NULL; + int oldCharacter = R2_GLOBALS._player._characterIndex; + switch (oldCharacter) { + case 1: + btn = &dlg->_btnQuinn; + break; + case 2: + btn = &dlg->_btnSeeker; + break; + case 3: + btn = &dlg->_btnMiranda; + break; + default: + break; + } + + // Show the character selection dialog + btn = dlg->execute(btn); + + // Figure out the new selected character + if (btn == &dlg->_btnQuinn) + R2_GLOBALS._player._characterIndex = 1; + else if (btn == &dlg->_btnSeeker) + R2_GLOBALS._player._characterIndex = 2; + else if (btn == &dlg->_btnMiranda) + R2_GLOBALS._player._characterIndex = 3; + + // Remove the dialog + dlg->remove(); + delete dlg; + + // Only do transfer if a different character was selected + if (R2_GLOBALS._player._characterIndex != oldCharacter) { + // Save the details of the previously active character + SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene; + scene->saveCharacter(oldCharacter); + + // Play a transition sound as the character is changed + if (R2_GLOBALS._player._characterScene[0] != 300) { + switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) { + case 0: + R2_GLOBALS._sound4.stop(); + break; + case 1: + R2_GLOBALS._sound4.play(45); + break; + case 2: + R2_GLOBALS._sound4.play(4); + break; + case 3: + R2_GLOBALS._sound4.play(5); + break; + case 4: + R2_GLOBALS._sound4.play(6); + break; + default: + break; + } + } else if (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex] > 1) { + switch (R2_GLOBALS._v565F1[R2_GLOBALS._player._characterIndex]) { + case 2: + R2_GLOBALS._sound4.play(45); + break; + case 3: + R2_GLOBALS._sound4.play(4); + break; + case 4: + R2_GLOBALS._sound4.play(5); + break; + case 5: + R2_GLOBALS._sound4.play(6); + break; + default: + break; + } + } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._v565F1[1] != 1)) { + switch (R2_GLOBALS._v565F1[1]) { + case 2: + R2_GLOBALS._sound4.play(45); + break; + case 3: + R2_GLOBALS._sound4.play(4); + break; + case 4: + R2_GLOBALS._sound4.play(5); + break; + case 5: + R2_GLOBALS._sound4.play(6); + break; + default: + break; + } + } else if (R2_GLOBALS._player._characterScene[2] != 300) { + R2_GLOBALS._sound4.stop(); + } else if (R2_GLOBALS._v565F1[2] == 1) { + R2_GLOBALS._sound4.stop(); + } else { + switch (R2_GLOBALS._v565F1[1]) { + case 2: + R2_GLOBALS._sound4.play(45); + break; + case 3: + R2_GLOBALS._sound4.play(4); + break; + case 4: + R2_GLOBALS._sound4.play(5); + break; + case 5: + R2_GLOBALS._sound4.play(6); + break; + default: + break; + } + } + + // Change to whichever scene the newly selected character is in + R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex]); + } +} + +CharacterDialog::CharacterDialog() { + // Set the element text + _msgTitle.set(CHAR_TITLE, 140, ALIGN_LEFT); + _btnQuinn.setText(CHAR_QUINN_MSG); + _btnSeeker.setText(CHAR_SEEKER_MSG); + _btnMiranda.setText(CHAR_MIRANDA_MSG); + _btnCancel.setText(CHAR_CANCEL_MSG); + + // Set position of the elements + _msgTitle._bounds.moveTo(5, 5); + _btnQuinn._bounds.moveTo(25, _msgTitle._bounds.bottom + 1); + _btnSeeker._bounds.moveTo(25, _btnQuinn._bounds.bottom + 1); + _btnMiranda._bounds.moveTo(25, _btnSeeker._bounds.bottom + 1); + _btnCancel._bounds.moveTo(25, _btnMiranda._bounds.bottom + 1); + + // Add the items to the dialog + addElements(&_msgTitle, &_btnQuinn, &_btnSeeker, &_btnMiranda, &_btnCancel, NULL); + + // Set the dialog size and position + frame(); + _bounds.collapse(-6, -6); + setCenter(160, 100); +} + +/*--------------------------------------------------------------------------*/ + +void HelpDialog::show() { + // Set the palette and change the cursor + BF_GLOBALS._events.setCursor(CURSOR_ARROW); + + // Create the dialog and draw it + HelpDialog *dlg = new HelpDialog(); + dlg->draw(); + + // Show the character selection dialog + GfxButton *btn = dlg->execute(&dlg->_btnResume); + + // If a function button was selected, take care of it + Event evt; + evt.eventType = EVENT_KEYPRESS; + evt.kbd.keycode = Common::KEYCODE_INVALID; + if (btn == &dlg->_btnList[0]) { + evt.kbd.keycode = Common::KEYCODE_F2; + } else if (btn == &dlg->_btnList[1]) { + evt.kbd.keycode = Common::KEYCODE_F3; + } else if (btn == &dlg->_btnList[2]) { + evt.kbd.keycode = Common::KEYCODE_F4; + } else if (btn == &dlg->_btnList[3]) { + evt.kbd.keycode = Common::KEYCODE_F5; + } else if (btn == &dlg->_btnList[4]) { + evt.kbd.keycode = Common::KEYCODE_F7; + } else if (btn == &dlg->_btnList[5]) { + evt.kbd.keycode = Common::KEYCODE_F8; + } else if (btn == &dlg->_btnList[6]) { + evt.kbd.keycode = Common::KEYCODE_F10; + } + + // Remove the dialog + dlg->remove(); + delete dlg; + + // If a action button was selected, dispatch to handle it + if (evt.kbd.keycode != Common::KEYCODE_INVALID) + R2_GLOBALS._game->processEvent(evt); +} + +HelpDialog::HelpDialog() { + // Set the title and game version + _msgTitle.set(HELP_MSG, 172, ALIGN_CENTER); + _msgTitle._bounds.moveTo(5, 0); + _msgVersion.set(GAME_VERSION, 172, ALIGN_CENTER); + _msgVersion._bounds.moveTo(5, _msgTitle._bounds.bottom + 3); + addElements(&_msgTitle, &_msgVersion, NULL); + + // Set buttons + _btnList[0].setText(F2); + _btnList[0]._bounds.moveTo(5, _msgVersion._bounds.bottom + 2); + _btnDescription[0].set(SOUND_OPTIONS, 140, ALIGN_LEFT); + _btnDescription[0]._bounds.moveTo(_btnList[0]._bounds.right + 2, _btnList[0]._bounds.top + 4); + + _btnList[1].setText(F3); + _btnList[1]._bounds.moveTo(5, _btnList[0]._bounds.bottom); + _btnDescription[1].set(QUIT_GAME, 140, ALIGN_LEFT); + _btnDescription[1]._bounds.moveTo(_btnList[1]._bounds.right + 2, _btnList[1]._bounds.top + 4); + + _btnList[2].setText(F4); + _btnList[2]._bounds.moveTo(5, _btnList[1]._bounds.bottom); + _btnDescription[2].set(RESTART_GAME, 140, ALIGN_LEFT); + _btnDescription[2]._bounds.moveTo(_btnList[2]._bounds.right + 2, _btnList[2]._bounds.top + 4); + + _btnList[3].setText(F5); + _btnList[3]._bounds.moveTo(5, _btnList[2]._bounds.bottom); + _btnDescription[3].set(SAVE_GAME, 140, ALIGN_LEFT); + _btnDescription[3]._bounds.moveTo(_btnList[3]._bounds.right + 2, _btnList[3]._bounds.top + 4); + + _btnList[4].setText(F7); + _btnList[4]._bounds.moveTo(5, _btnList[3]._bounds.bottom); + _btnDescription[4].set(RESTORE_GAME, 140, ALIGN_LEFT); + _btnDescription[4]._bounds.moveTo(_btnList[4]._bounds.right + 2, _btnList[4]._bounds.top + 4); + + _btnList[5].setText(F8); + _btnList[5]._bounds.moveTo(5, _btnList[4]._bounds.bottom); + _btnDescription[5].set(SHOW_CREDITS, 140, ALIGN_LEFT); + _btnDescription[5]._bounds.moveTo(_btnList[5]._bounds.right + 2, _btnList[5]._bounds.top + 4); + + _btnList[6].setText(F10); + _btnList[6]._bounds.moveTo(5, _btnList[5]._bounds.bottom); + _btnDescription[6].set(PAUSE_GAME, 140, ALIGN_LEFT); + _btnDescription[6]._bounds.moveTo(_btnList[6]._bounds.right + 2, _btnList[6]._bounds.top + 4); + + for (int i = 0; i < 7; ++i) { + addElements(&_btnList[i], &_btnDescription[i], NULL); + } + + // Add 'Resume' button + _btnResume.setText(RESUME_PLAY); + _btnResume._bounds.moveTo(5, _btnList[6]._bounds.bottom + 2); + addElements(&_btnResume, NULL); + + // Set the dialog size and position + frame(); + _bounds.collapse(-6, -6); + setCenter(160, 100); +} + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.h b/engines/tsage/ringworld2/ringworld2_dialogs.h index bbc35da3ea..02a1aed81c 100644 --- a/engines/tsage/ringworld2/ringworld2_dialogs.h +++ b/engines/tsage/ringworld2/ringworld2_dialogs.h @@ -59,6 +59,31 @@ public: void execute(); }; +class CharacterDialog: public GfxDialog { +private: + GfxMessage _msgTitle; + GfxButton _btnQuinn, _btnMiranda, _btnSeeker; + GfxButton _btnCancel; +public: + CharacterDialog(); + virtual ~CharacterDialog() {} + + static void show(); +}; + +class HelpDialog: public GfxDialog { +private: + GfxMessage _msgTitle, _msgVersion; + GfxButton _btnList[7]; + GfxMessage _btnDescription[7]; + GfxButton _btnResume; +public: + HelpDialog(); + virtual ~HelpDialog() {} + + static void show(); +}; + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index d033627ae9..d0921a1eb3 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -35,9 +35,108 @@ namespace Ringworld2 { Scene *Ringworld2Game::createScene(int sceneNumber) { switch (sceneNumber) { /* Scene group #0 */ + // + case 50: return new Scene50(); // Quinn's room case 100: return new Scene100(); - + // Computer console + case 125: return new Scene125(); + // + case 150: + case 160: + case 175: + case 180: + case 200: + case 205: + case 250: + error("Missing scene %d from group 0", sceneNumber); + case 300: + return new Scene300(); + case 325: + case 400: + case 500: + case 525: + case 600: + case 700: + case 800: + case 825: + case 850: + case 900: + error("Missing scene %d from group 0", sceneNumber); + /* Scene group #1 */ + // + case 1000: + case 1010: + case 1020: + case 1100: + case 1200: + case 1330: + case 1500: + case 1525: + case 1530: + case 1550: + case 1575: + case 1580: + case 1625: + case 1700: + case 1750: + case 1800: + case 1850: + case 1875: + case 1900: + case 1925: + case 1945: + case 1950: + error("Missing scene %d from group 1", sceneNumber); + /* Scene group #2 */ + // + case 2000: + case 2350: + case 2400: + case 2425: + case 2430: + case 2435: + case 2440: + case 2445: + case 2450: + case 2455: + case 2500: + case 2525: + case 2530: + case 2535: + case 2600: + case 2700: + case 2750: + case 2800: + case 2900: + error("Missing scene %d from group 2", sceneNumber); + /* Scene group #3 */ + // + case 3100: + case 3125: + case 3150: + case 3175: + case 3200: + case 3210: + case 3220: + case 3230: + case 3240: + case 3245: + case 3250: + case 3255: + case 3260: + case 3275: + case 3350: + case 3375: + case 3385: + case 3395: + case 3400: + case 3500: + case 3600: + case 3700: + case 3800: + case 3900: + error("Missing scene %d from group 3", sceneNumber); default: error("Unknown scene number - %d", sceneNumber); break; @@ -79,18 +178,8 @@ void SceneExt::postInit(SceneObjectList *OwnerList) { } void SceneExt::remove() { -/* - R2_GLOBALS._uiElements.hide(); - R2_GLOBALS._uiElements.resetClear(); - - if (_action) { - if (_action->_endHandler) - _action->_endHandler = NULL; - _action->remove(); - } - - _focusObject = NULL; -*/ + _sceneAreas.clear(); + Scene::remove(); } void SceneExt::process(Event &event) { @@ -219,6 +308,41 @@ void SceneExt::refreshBackground(int xAmount, int yAmount) { DEALLOCATE(dataP); } +/** + * Saves the current player position and view in the details for the specified character index + */ +void SceneExt::saveCharacter(int characterIndex) { + R2_GLOBALS._player._characterPos[characterIndex] = R2_GLOBALS._player._position; + R2_GLOBALS._player._characterStrip[characterIndex] = R2_GLOBALS._player._strip; + R2_GLOBALS._player._characterFrame[characterIndex] = R2_GLOBALS._player._frame; +} + +/*--------------------------------------------------------------------------*/ + +void SceneHandlerExt::postInit(SceneObjectList *OwnerList) { + SceneHandler::postInit(OwnerList); +} + +void SceneHandlerExt::process(Event &event) { + if (T2_GLOBALS._uiElements._active) { + T2_GLOBALS._uiElements.process(event); + if (event.handled) + return; + } + + SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene); + if (scene) { + // Handle any scene areas that have been registered + SynchronizedList<SceneArea *>::iterator saIter; + for (saIter = scene->_sceneAreas.begin(); saIter != scene->_sceneAreas.end() && !event.handled; ++saIter) { + (*saIter)->process(event); + } + } + + if (!event.handled) + SceneHandler::process(event); +} + /*--------------------------------------------------------------------------*/ DisplayHotspot::DisplayHotspot(int regionId, ...) { @@ -398,7 +522,7 @@ void Ringworld2InvObjectList::reset() { } // Set up default inventory - setObjectScene(R2_1, 800); + setObjectScene(R2_OPTO_DISK, 800); setObjectScene(R2_2, 400); setObjectScene(R2_NEGATOR_GUN, 100); setObjectScene(R2_STEPPING_DISKS, 100); @@ -537,7 +661,7 @@ void Ringworld2Game::processEvent(Event &event) { switch (event.kbd.keycode) { case Common::KEYCODE_F1: // F1 - Help -// MessageDialog::show(HELP_MSG, OK_BTN_STRING); + HelpDialog::show(); break; case Common::KEYCODE_F2: @@ -563,6 +687,11 @@ void Ringworld2Game::processEvent(Event &event) { g_globals->_events.setCursorFromFlag(); break; + case Common::KEYCODE_F8: + // F8 - Credits + warning("TODO: Show Credits"); + break; + case Common::KEYCODE_F10: // F10 - Pause GfxDialog::setPalette(); @@ -753,6 +882,103 @@ void SceneActor::setDetails(int resNum, int lookLineNum, int talkLineNum, int us _useLineNum = useLineNum; } +/*--------------------------------------------------------------------------*/ + +SceneArea::SceneArea(): EventHandler() { + _enabled = true; + _insideArea = false; + _savedCursorNum = CURSOR_NONE; + _cursorState = 0; +} + +void SceneArea::synchronize(Serializer &s) { + EventHandler::synchronize(s); + + _bounds.synchronize(s); + s.syncAsSint16LE(_enabled); + s.syncAsSint16LE(_insideArea); + s.syncAsSint16LE(_cursorNum); + s.syncAsSint16LE(_savedCursorNum); + s.syncAsSint16LE(_cursorState); +} + +void SceneArea::remove() { + static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.remove(this); +} + +void SceneArea::process(Event &event) { + if (!R2_GLOBALS._insetUp && _enabled && R2_GLOBALS._events.isCursorVisible()) { + CursorType cursor = R2_GLOBALS._events.getCursor(); + + if (_bounds.contains(event.mousePos)) { + // Cursor moving in bounded area + if (cursor != _cursorNum) { + _savedCursorNum = cursor; + _cursorState = 0; + R2_GLOBALS._events.setCursor(_cursorNum); + } + _insideArea = true; + } else if ((event.mousePos.y < 171) && _insideArea && (_cursorNum != cursor) && + (_savedCursorNum != CURSOR_NONE)) { + // Cursor moved outside bounded area + R2_GLOBALS._events.setCursor(_savedCursorNum); + } + } +} + +void SceneArea::setDetails(const Rect &bounds, CursorType cursor) { + _bounds = bounds; + _cursorNum = cursor; + + static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this); +} + +/*--------------------------------------------------------------------------*/ + +SceneExit::SceneExit(): SceneArea() { + _moving = false; + _destPos = Common::Point(-1, -1); +} + +void SceneExit::synchronize(Serializer &s) { + SceneArea::synchronize(s); + + s.syncAsSint16LE(_moving); + s.syncAsSint16LE(_destPos.x); + s.syncAsSint16LE(_destPos.y); +} + +void SceneExit::setDetails(const Rect &bounds, CursorType cursor, int sceneNumber) { + _sceneNumber = sceneNumber; + SceneArea::setDetails(bounds, cursor); +} + +void SceneExit::changeScene() { + R2_GLOBALS._sceneManager.setNewScene(_sceneNumber); +} + +void SceneExit::process(Event &event) { + if (!R2_GLOBALS._insetUp) { + SceneArea::process(event); + + if (_enabled && (event.eventType == EVENT_BUTTON_DOWN)) { + if (!_bounds.contains(event.mousePos)) + _moving = 0; + else if (!R2_GLOBALS._player._canWalk) { + _moving = 0; + changeScene(); + event.handled = true; + } else { + Common::Point dest((_destPos.x == -1) ? event.mousePos.x : _destPos.x, + (_destPos.y == -1) ? event.mousePos.y : _destPos.y); + ADD_PLAYER_MOVER(dest.x, dest.y); + + _moving = true; + event.handled = true; + } + } + } +} } // End of namespace Ringworld2 diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h index b12978344c..152e6f8518 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.h +++ b/engines/tsage/ringworld2/ringworld2_logic.h @@ -42,6 +42,38 @@ public: static Scene *createScene(int sceneNumber); }; +class SceneArea: public EventHandler { +public: + Rect _bounds; + bool _enabled; + bool _insideArea; + CursorType _cursorNum; + CursorType _savedCursorNum; + int _cursorState; +public: + SceneArea(); + void setDetails(const Rect &bounds, CursorType cursor); + + virtual void synchronize(Serializer &s); + virtual void remove(); + virtual void process(Event &event); +}; + +class SceneExit: public SceneArea { +public: + bool _moving; + int _sceneNumber; + Common::Point _destPos; +public: + SceneExit(); + void setDetails(const Rect &bounds, CursorType cursor, int sceneNumber); + void setDest(const Common::Point &p) { _destPos = p; } + void changeScene(); + + virtual void synchronize(Serializer &s); + virtual void process(Event &event); +}; + class SceneExt: public Scene { private: static void startStrip(); @@ -55,6 +87,7 @@ public: SceneObject *_focusObject; Visage _cursorVisage; + SynchronizedList<SceneArea *> _sceneAreas; Rect _v51C34; public: @@ -67,12 +100,20 @@ public: virtual void dispatch(); virtual void loadScene(int sceneNum); virtual void refreshBackground(int xAmount, int yAmount); + virtual void saveCharacter(int characterIndex); bool display(CursorType action); void fadeOut(); void clearScreen(); }; +class SceneHandlerExt: public SceneHandler { +public: + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); +}; + + class DisplayHotspot : public SceneObject { private: Common::Array<int> _actions; @@ -241,7 +282,6 @@ public: } }; - } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp index a2fb011d23..4df081d0cb 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp @@ -24,11 +24,54 @@ #include "tsage/tsage.h" #include "tsage/staticres.h" #include "tsage/ringworld2/ringworld2_scenes0.h" +#include "tsage/ringworld2/ringworld2_speakers.h" namespace TsAGE { namespace Ringworld2 { +void Scene50::Action1::signal() { + switch (_actionIndex++) { + case 0: + setDelay(2); + break; + case 1: + setDelay(180); + break; + case 2: + R2_GLOBALS._sceneManager.changeScene(100); + break; + default: + break; + } +} + +void Scene50::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(OwnerList); + loadScene(110); + + R2_GLOBALS._v58CE2 = 0; + R2_GLOBALS._scenePalette.loadPalette(0); + + R2_GLOBALS._sound2.play(10); + R2_GLOBALS._player.disableControl(); + + setAction(&_action1); +} + +void Scene50::process(Event &event) { + if ((event.eventType != EVENT_BUTTON_DOWN) && (event.eventType != EVENT_KEYPRESS) && (event.eventType == 27)) { + event.handled = true; + warning("TODO: incomplete Scene50::process()"); + // CursorType _oldCursorId = _cursorId; + g_globals->_events.setCursor(R2_2); + // _cursorManager.sub_1D474(2, 0); + // sub_5566A(1); + // _cursorManager._fieldE = _oldCursorId; + R2_GLOBALS._sceneManager.changeScene(100); + } +} + /*-------------------------------------------------------------------------- * Scene 100 - Quinn's Room * @@ -346,6 +389,1579 @@ void Scene100::dispatch() { } } +/*-------------------------------------------------------------------------- + * Scene 125 - Computer Terminal + * + *--------------------------------------------------------------------------*/ + +bool Scene125::Object5::startAction(CursorType action, Event &event) { + if (action == CURSOR_USE) + return true; + else + return SceneActor::startAction(action, event); +} + +/*--------------------------------------------------------------------------*/ + +Scene125::Icon::Icon(): SceneActor() { + _lookLineNum = 0; + _field98 = 0; + _pressed = false; +} + +void Scene125::Icon::postInit(SceneObjectList *OwnerList) { + SceneObject::postInit(); + + _object1.postInit(); + _object1.fixPriority(255); + _object1.hide(); + + _sceneText1._color1 = 92; + _sceneText1._color2 = 0; + _sceneText1._width = 200; + _sceneText2._color1 = 0; + _sceneText2._color2 = 0; + _sceneText2._width = 200; + setDetails(125, -1, -1, -1, 2, NULL); +} + +void Scene125::Icon::synchronize(Serializer &s) { + SceneActor::synchronize(s); + s.syncAsSint16LE(_lookLineNum); + s.syncAsSint16LE(_field98); + s.syncAsSint16LE(_pressed); +} + +void Scene125::Icon::process(Event &event) { + Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene; + + if (!event.handled && !(_flags & OBJFLAG_HIDING) && R2_GLOBALS._player._uiEnabled) { + + if (event.eventType == EVENT_BUTTON_DOWN) { + int regionIndex = R2_GLOBALS._sceneRegions.indexOf(event.mousePos); + + switch (R2_GLOBALS._events.getCursor()) { + case CURSOR_LOOK: + if (regionIndex == _sceneRegionId) { + event.handled = true; + if (_lookLineNum == 26) { + SceneItem::display2(130, 7); + } else { + SceneItem::display2(130, _lookLineNum); + } + } + break; + + case CURSOR_USE: + if ((regionIndex == _sceneRegionId) && !_pressed) { + scene->_sound1.play(14); + setFrame(2); + + switch (_object1._strip) { + case 1: + _object1.setStrip(2); + break; + case 3: + _object1.setStrip(4); + break; + case 5: + _object1.setStrip(6); + break; + default: + break; + } + + _pressed = true; + event.handled = true; + } + break; + + default: + break; + } + } + + if ((event.eventType == EVENT_BUTTON_UP) && _pressed) { + setFrame(1); + + switch (_object1._strip) { + case 2: + _object1.setStrip(1); + break; + case 4: + _object1.setStrip(3); + break; + case 6: + _object1.setStrip(5); + break; + default: + break; + } + + _pressed = false; + event.handled = true; + scene->consoleAction(_lookLineNum); + } + } +} + +void Scene125::Icon::setIcon(int id) { + Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene; + + _lookLineNum = _field98 = id; + SceneActor::_lookLineNum = id; + + _sceneText1.remove(); + _sceneText2.remove(); + + if (_lookLineNum) { + showIcon(); + _object1.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1); + _object1.setPosition(_position); + + _sceneText1._fontNumber = scene->_iconFontNumber; + _sceneText1.setup(CONSOLE_MESSAGES[id]); + _sceneText1.fixPriority(20); + + _sceneText2._fontNumber = scene->_iconFontNumber; + _sceneText2.setup(CONSOLE_MESSAGES[id]); + _sceneText2.fixPriority(20); + + _sceneText2._fontNumber = scene->_iconFontNumber; + _sceneText2.setup(CONSOLE_MESSAGES[id]); + _sceneText2.fixPriority(10); + + switch (_lookLineNum) { + case 5: + _sceneText1.setPosition(Common::Point(62, _position.y + 8)); + _sceneText2.setPosition(Common::Point(64, _position.y + 10)); + break; + case 6: + case 7: + case 24: + case 25: + _sceneText1.setPosition(Common::Point(65, _position.y + 8)); + _sceneText2.setPosition(Common::Point(67, _position.y + 10)); + break; + case 26: + _sceneText1.setPosition(Common::Point(83, _position.y + 8)); + _sceneText2.setPosition(Common::Point(85, _position.y + 10)); + break; + default: + _sceneText1.setPosition(Common::Point(121, _position.y + 8)); + _sceneText2.setPosition(Common::Point(123, _position.y + 10)); + break; + } + } else { + hideIcon(); + } +} + +void Scene125::Icon::showIcon() { + _sceneText1.show(); + _sceneText2.show(); + _object1.show(); + _object2.show(); + show(); +} + +void Scene125::Icon::hideIcon() { + _sceneText1.hide(); + _sceneText2.hide(); + _object1.hide(); + _object2.hide(); + hide(); +} + +/*--------------------------------------------------------------------------*/ + +bool Scene125::Item4::startAction(CursorType action, Event &event) { + Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene; + switch (action) { + case CURSOR_USE: + if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldSceneNumber) { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 126; + scene->setAction(&scene->_sequenceManager, scene, 126, &scene->_object7, NULL); + return true; + } + break; + case R2_OPTO_DISK: + if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1) { + R2_GLOBALS._player.disableControl(); + scene->_object7.postInit(); + scene->_sceneMode = 125; + scene->setAction(&scene->_sequenceManager, scene, 125, &scene->_object7, NULL); + return true; + } + break; + default: + break; + } + + return SceneHotspot::startAction(action, event); +} + +/*--------------------------------------------------------------------------*/ + +Scene125::Scene125(): SceneExt() { + _iconFontNumber = 50; + _consoleMode = 5; + _logIndex = _databaseIndex = _infodiskIndex = 0; + + _soundCount = _soundIndex = 0; + for (int i = 0; i < 10; ++i) + _soundIndexes[i] = 0; +} + +void Scene125::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + loadScene(160); + _palette.loadPalette(0); + + if (R2_GLOBALS._sceneManager._previousScene != 125) + // Save the prior scene to return to when the console is turned off + R2_GLOBALS._player._oldSceneNumber = R2_GLOBALS._sceneManager._previousScene; + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.hide(); + R2_GLOBALS._player.disableControl(); + + if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldSceneNumber) { + _object7.postInit(); + _object7.setup(160, 3, 5); + _object7.setPosition(Common::Point(47, 167)); + } + + _object6.postInit(); + _object6.setup(162, 1, 1); + _object6.setPosition(Common::Point(214, 168)); + + _item4.setDetails(Rect(27, 145, 81, 159), 126, 9, -1, -1, 1, NULL); + _item3.setDetails(Rect(144, 119, 286, 167), 126, 6, 7, 8, 1, NULL); + _item2.setDetails(1, 126, 3, 4, 5); + _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 126, 0, 1, -1, 1, NULL); + + _sceneMode = 1; + signal(); +} + +void Scene125::signal() { + switch (_sceneMode) { + case 1: + _icon1.postInit(); + _icon1._sceneRegionId = 2; + _icon2.postInit(); + _icon2._sceneRegionId = 3; + _icon3.postInit(); + _icon3._sceneRegionId = 4; + _icon4.postInit(); + _icon4._sceneRegionId = 5; + + _sceneMode = 2; + setAction(&_sequenceManager, this, 127, &_icon1, &_icon2, &_icon3, &_icon4, &R2_GLOBALS._player, NULL); + break; + case 2: + _icon1.setup(160, 1, 1); + _icon1.setPosition(Common::Point(65, 17)); + _icon1._object2.postInit(); + _icon1._object2.setup(160, 7, 1); + _icon1._object2.setPosition(Common::Point(106, 41)); + + _icon2.setup(160, 1, 1); + _icon2.setPosition(Common::Point(80, 32)); + _icon2._object2.postInit(); + _icon2._object2.setup(160, 7, 2); + _icon2._object2.setPosition(Common::Point(106, 56)); + + _icon3.setup(160, 1, 1); + _icon3.setPosition(Common::Point(65, 47)); + _icon3._object2.postInit(); + _icon3._object2.setup(160, 7, 1); + _icon3._object2.setPosition(Common::Point(106, 71)); + + _icon4.setup(160, 1, 1); + _icon4.setPosition(Common::Point(80, 62)); + _icon4._sceneRegionId = 5; + _icon4._object2.postInit(); + _icon4._object2.setup(160, 7, 2); + _icon4._object2.setPosition(Common::Point(106, 86)); + + _icon5.postInit(); + _icon5.setup(160, 1, 1); + _icon5.setPosition(Common::Point(37, 92)); + _icon5.setIcon(6); + _icon5._sceneRegionId = 7; + + _icon6.postInit(); + _icon6.setup(160, 1, 1); + _icon6.setPosition(Common::Point(106, 110)); + _icon6.setIcon(5); + _icon6._sceneRegionId = 8; + + consoleAction(5); + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + break; + case 10: + switch (_consoleMode) { + case 12: + _sceneMode = 129; + + _object1.postInit(); + _object2.postInit(); + _object3.postInit(); + + if (R2_GLOBALS.getFlag(13)) { + _object4.postInit(); + setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_object1, &_object2, + &_object3, &_object4, NULL); + } else { + setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_object1, &_object2, &_object3, NULL); + } + break; + case 13: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + _infodiskIndex = 0; + setDetails(129, 0); + break; + case 23: + R2_GLOBALS._sceneManager.changeScene(1330); + break; + case 27: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + _databaseIndex = 0; + setDetails(128, 0); + break; + case 28: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + _databaseIndex = 37; + setDetails(128, 37); + break; + case 29: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + _databaseIndex = 68; + setDetails(128, 68); + break; + case 30: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + _databaseIndex = 105; + setDetails(128, 105); + break; + default: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + _logIndex = 0; + setDetails(127, 0); + break; + } + break; + case 11: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + + if ((_consoleMode >= 27) && (_consoleMode <= 30)) { + consoleAction(11); + } + consoleAction(2); + _icon6.setIcon(5); + break; + case 12: + if (_soundCount > 0) + --_soundCount; + if (!_soundCount || (R2_GLOBALS._speechSubtitles & 2)) { + _soundIndex = 0; + R2_GLOBALS._playStream.stop(); + } else { + _sceneMode = 12; + R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex++], this); + } + break; + case 125: + R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldSceneNumber); + break; + case 126: + R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 1); + _object7.remove(); + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + break; + case 128: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + SceneItem::display2(126, 12); + break; + default: + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + break; + } +} + +void Scene125::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_consoleMode); + s.syncAsSint16LE(_iconFontNumber); + s.syncAsSint16LE(_logIndex); + s.syncAsSint16LE(_databaseIndex); + s.syncAsSint16LE(_infodiskIndex); + s.syncAsSint16LE(_soundCount); + s.syncAsSint16LE(_soundIndex); + + for (int i = 0; i < 10; ++i) + s.syncAsSint16LE(_soundIndexes[i]); +} + +void Scene125::process(Event &event) { + SceneExt::process(event); + + if (R2_GLOBALS._player._uiEnabled) { + _icon1.process(event); + _icon2.process(event); + _icon3.process(event); + _icon4.process(event); + _icon5.process(event); + _icon6.process(event); + } +} + +void Scene125::dispatch() { + if (_soundCount) + R2_GLOBALS._playStream.proc1(); + + Scene::dispatch(); +} + +/** + * Handles actions on the console screen. + */ +void Scene125::consoleAction(int id) { + _icon3.setIcon(0); + _icon4.setIcon(0); + + if (id == 5) + _icon5.setIcon(6); + else { + switch (_consoleMode) { + case 10: + case 12: + case 13: + case 27: + case 28: + case 29: + case 30: + break; + default: + _icon5.setIcon(7); + break; + } + } + + switch (id) { + case 1: + _icon1.setIcon(8); + _icon2.setIcon(9); + break; + case 2: + _icon1.setIcon(10); + _icon2.setIcon(11); + _icon3.setIcon(12); + _icon4.setIcon(13); + break; + case 3: + _icon1.setIcon(15); + _icon2.setIcon(16); + _icon3.setIcon(17); + break; + case 4: + _icon1.setIcon(22); + _icon2.setIcon(23); + break; + case 6: + R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldSceneNumber); + break; + case 7: + if (_consoleMode == 11) + consoleAction(2); + else if (_consoleMode == 22) + consoleAction(4); + else + consoleAction(5); + break; + case 8: + _iconFontNumber = 50; + stop(); + _icon6.setIcon(5); + consoleAction(1); + break; + case 9: + _iconFontNumber = 52; + stop(); + _icon6.setIcon(5); + consoleAction(1); + break; + case 10: + R2_GLOBALS._player.disableControl(); + consoleAction(2); + _icon1.hideIcon(); + _icon2.hideIcon(); + _icon3.hideIcon(); + _icon5.setIcon(24); + + _icon4.setPosition(Common::Point(52, 107)); + _icon4._sceneRegionId = 9; + _icon4.setIcon(25); + _icon4._object2.hide(); + + _icon6.setIcon(26); + _sceneMode = 10; + + _palette.loadPalette(161); + R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this); + break; + case 11: + _icon1.setIcon(27); + _icon2.setIcon(28); + _icon3.setIcon(29); + _icon4.setIcon(30); + break; + case 12: + R2_GLOBALS._player.disableControl(); + consoleAction(2); + _icon1.hideIcon(); + _icon2.hideIcon(); + _icon3.hideIcon(); + _icon4.hideIcon(); + _icon5.hideIcon(); + + _icon6.setIcon(26); + _sceneMode = 10; + _palette.loadPalette(161); + R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this); + break; + case 13: + consoleAction(2); + if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldSceneNumber) { + SceneItem::display2(126, 17); + } else { + R2_GLOBALS._player.disableControl(); + + _icon1.hideIcon(); + _icon2.hideIcon(); + _icon3.hideIcon(); + _icon5.setIcon(24); + + _icon4.setPosition(Common::Point(52, 107)); + _icon4._sceneRegionId = 9; + _icon4.setIcon(25); + _icon4._object2.hide(); + + _icon6.setIcon(26); + _sceneMode = 10; + + _palette.loadPalette(161); + R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this); + } + break; + case 15: + consoleAction(3); + + if (R2_GLOBALS._v565F5 < 3) { + R2_GLOBALS._player.disableControl(); + _object5.postInit(); + _object5.setup(162, 2, 2); + _object5.setPosition(Common::Point(216, UI_INTERFACE_Y)); + + R2_GLOBALS._v565F5 += 2; + } else if (R2_GLOBALS._v565F5 == 3) { + SceneItem::display2(126, 13); + } else { + SceneItem::display2(126, 14); + } + break; + case 16: + consoleAction(3); + + if (R2_GLOBALS._v565F5 < 4) { + R2_GLOBALS._player.disableControl(); + _object5.postInit(); + _object5.setup(162, 2, 3); + _object5.setPosition(Common::Point(218, UI_INTERFACE_Y)); + + ++R2_GLOBALS._v565F5; + } else { + SceneItem::display2(126, 15); + } + break; + case 17: + consoleAction(3); + + if (R2_GLOBALS._v565F5 < 4) { + R2_GLOBALS._player.disableControl(); + _object5.postInit(); + _object5.setup(162, 2, 1); + _object5.setPosition(Common::Point(215, UI_INTERFACE_Y)); + + ++R2_GLOBALS._v565F5; + } else { + SceneItem::display2(126, 16); + } + break; + case 22: + _icon1.setIcon(31); + _icon2.setIcon(32); + _icon3.setIcon(33); + _icon4.setIcon(34); + break; + case 23: + R2_GLOBALS._player.disableControl(); + consoleAction(4); + _icon1.hideIcon(); + _icon2.hideIcon(); + _icon3.hideIcon(); + _icon4.hideIcon(); + _icon5.hideIcon(); + _icon6.hideIcon(); + + _sceneMode = 10; + _palette.loadPalette(161); + break; + case 24: + _icon4.setIcon(25); + _icon4._object2.hide(); + + if (_consoleMode == 10) { + setDetails(127, --_logIndex); + } else if (_consoleMode == 13) { + setDetails(129, --_infodiskIndex); + } else { + setDetails(128, --_databaseIndex); + } + break; + case 25: + _icon4.setIcon(25); + _icon4._object2.hide(); + + if (_consoleMode == 10) { + setDetails(127, ++_logIndex); + } else if (_consoleMode == 13) { + setDetails(129, ++_infodiskIndex); + } else { + setDetails(128, ++_databaseIndex); + } + break; + case 26: + R2_GLOBALS._player.disableControl(); + stop(); + _icon4.setPosition(Common::Point(80, 62)); + _icon4._sceneRegionId = 5; + _icon4.hideIcon(); + + R2_GLOBALS._player.hide(); + _object1.hide(); + _object2.hide(); + _object3.hide(); + _object4.hide(); + + _sceneMode = 11; + _palette.loadPalette(160); + R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this); + break; + case 27: + case 28: + case 29: + case 30: + R2_GLOBALS._player.disableControl(); + consoleAction(11); + _consoleMode = id; + + _icon1.hideIcon(); + _icon2.hideIcon(); + _icon3.hideIcon(); + _icon4.hideIcon(); + _icon5.setIcon(24); + + _icon4.setPosition(Common::Point(52, 107)); + _icon4._sceneRegionId = 9; + _icon4.setIcon(25); + _icon4._object2.hide(); + + _icon6.setIcon(26); + _sceneMode = 10; + + _palette.loadPalette(161); + R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this); + break; + case 31: + consoleAction(22); + R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 63 : 10); + break; + case 32: + consoleAction(22); + R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 64 : 10); + break; + case 33: + consoleAction(22); + R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 65 : 10); + break; + case 34: + consoleAction(22); + R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 66 : 10); + break; + default: + _icon1.setIcon(1); + _icon2.setIcon(2); + _icon3.setIcon(3); + _icon4.setIcon(4); + break; + } + + if ((id != 6) && (id != 7) && (id != 24) && (id != 25)) + _consoleMode = id; +} + +/** + * Sets the message to be displayed on the console screen. + */ +void Scene125::setDetails(int resNum, int lineNum) { + stop(); + + Common::String msg = g_resourceManager->getMessage(resNum, lineNum, true); + + if (!msg.empty()) { + // Check for any specified sound numbers embedded in the message + msg = parseMessage(msg); + + _sceneText._fontNumber = _iconFontNumber; + _sceneText._color1 = 92; + _sceneText._color2 = 0; + _sceneText._width = 221; + _sceneText.fixPriority(20); + _sceneText.setup(msg); + _sceneText.setPosition(Common::Point(49, 19)); + + R2_GLOBALS._sceneObjects->draw(); + + if ((_soundCount > 0) && (R2_GLOBALS._speechSubtitles & 2)) { + _sceneMode = 12; + R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex], this); + } + } else { + // Passed the start or end of the message set, so return to the menu + R2_GLOBALS._player.disableControl(); + R2_GLOBALS._player.hide(); + + _icon4.setPosition(Common::Point(80, 62)); + _icon4._sceneRegionId = 5; + _icon4.hideIcon(); + + _consoleMode = 0; + _palette.loadPalette(160); + _sceneMode = 11; + R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this); + } +} + +/** + * Stops any playing console sounds and hides any current console message. + */ +void Scene125::stop() { + _sceneText.remove(); + _soundIndex = 0; + _soundCount = 0; + + R2_GLOBALS._playStream.stop(); +} + +/** + * Parses a message to be displayed on the console to see whether there are any sounds to be played. + */ +Common::String Scene125::parseMessage(const Common::String &msg) { + _soundIndex = 0; + _soundCount = 0; + + const char *msgP = msg.c_str(); + while (*msgP == '!') { + // Get the sound number + _soundIndexes[_soundCount++] = atoi(++msgP); + + while (!((*msgP == '\0') || (*msgP < '0') || (*msgP > '9'))) + ++msgP; + } + + return Common::String(msgP); +} + +/*-------------------------------------------------------------------------- + * Scene 300 - Bridge + * + *--------------------------------------------------------------------------*/ + +void Scene300::Action1::signal() { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (_actionIndex) { + case 0: + setAction(&scene->_sequenceManager2, this, 311, (R2_GLOBALS._player._characterIndex == 1) ? + (SceneObject *)&R2_GLOBALS._player : (SceneObject *)&scene->_quinn); + _actionIndex = 2; + break; + case 1: + setAction(&scene->_sequenceManager2, this, 312, (R2_GLOBALS._player._characterIndex == 1) ? + (SceneObject *)&R2_GLOBALS._player : (SceneObject *)&scene->_quinn); + _actionIndex = 0; + break; + case 2: + if (!R2_GLOBALS._playStream.isPlaying()) + _actionIndex = R2_GLOBALS._randomSource.getRandomNumber(1); + break; + default: + break; + } +} + +void Scene300::Action2::signal() { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (_actionIndex) { + case 0: + setAction(&scene->_sequenceManager3, this, 302, &scene->_seeker, NULL); + _actionIndex = 2; + break; + case 1: + setAction(&scene->_sequenceManager3, this, 303, &scene->_seeker, NULL); + _actionIndex = 2; + break; + case 2: + if (!R2_GLOBALS._playStream.isPlaying()) + _actionIndex = R2_GLOBALS._randomSource.getRandomNumber(1); + + setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(119)); + break; + default: + break; + } +} + +void Scene300::Action3::signal() { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (_actionIndex) { + case 0: + setAction(&scene->_sequenceManager3, this, 304, &scene->_miranda, NULL); + _actionIndex = 2; + break; + case 1: + setAction(&scene->_sequenceManager3, this, 305, &scene->_miranda, NULL); + _actionIndex = 2; + break; + case 2: + if (!R2_GLOBALS._playStream.isPlaying()) + _actionIndex = R2_GLOBALS._randomSource.getRandomNumber(1); + + setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(119)); + break; + default: + break; + } +} + + +void Scene300::Action4::signal() { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + if (!R2_GLOBALS._playStream.isPlaying()) { + scene->_object7.setStrip2(R2_GLOBALS._randomSource.getRandomNumber(2)); + scene->_object7.setFrame(1); + + scene->_object9.setStrip2(3); + scene->_object9.setFrame(1); + } + + setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(479)); +} + +/*--------------------------------------------------------------------------*/ + +bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case CURSOR_USE: + if (R2_GLOBALS._player._characterIndex != 1) + SceneItem::display2(300, 46); + else if (R2_GLOBALS.getFlag(44)) { + R2_GLOBALS._player.setAction(NULL); + R2_GLOBALS._sceneManager.changeScene(325); + } else { + R2_GLOBALS._player.disableControl(); + scene->_sceneMode = 306; + scene->setAction(&scene->_sequenceManager1, scene, 306, &R2_GLOBALS._player, NULL); + } + return true; + + case CURSOR_LOOK: + if (R2_GLOBALS._player._characterIndex == 1) { + SceneItem::display2(300, 47); + return true; + } + break; + + default: + break; + } + + return NamedHotspot::startAction(action, event); +} + +bool Scene300::MirandaWorkstation::startAction(CursorType action, Event &event) { + switch (action) { + case CURSOR_USE: + if (R2_GLOBALS._player._characterIndex != 3) + SceneItem::display2(300, 49); + else + R2_GLOBALS._sceneManager.changeScene(325); + return true; + + case CURSOR_LOOK: + if (R2_GLOBALS._player._characterIndex == 3) { + SceneItem::display2(300, 47); + return true; + } + break; + + default: + break; + } + + return NamedHotspot::startAction(action, event); +} + +bool Scene300::SeekerWorkstation::startAction(CursorType action, Event &event) { + switch (action) { + case CURSOR_LOOK: + if (R2_GLOBALS._player._characterIndex == 2) { + SceneItem::display2(300, 47); + return true; + } + break; + + case CURSOR_USE: + if (R2_GLOBALS._player._characterIndex != 2) + SceneItem::display2(300, 48); + else + R2_GLOBALS._sceneManager.changeScene(325); + return true; + + default: + break; + } + + return NamedHotspot::startAction(action, event); +} + +/*--------------------------------------------------------------------------*/ + +bool Scene300::Miranda::startAction(CursorType action, Event &event) { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + + switch (action) { + case CURSOR_TALK: + if (R2_GLOBALS._player._characterIndex == 1) { + + } else { + scene->_sceneMode = 10; + R2_GLOBALS._events.setCursor(CURSOR_WALK); // TODO: Determine correct cursor + + if (!R2_GLOBALS.getFlag(44)) + scene->_field412 = 174 + R2_GLOBALS._randomSource.getRandomNumber(2); + else if (!R2_GLOBALS.getFlag(55)) + scene->_field412 = 211; + else + scene->_field412 = 438; + } + return true; + + case R2_OPTO_DISK: + SceneItem::display2(300, 54); + return true; + + case R2_2: + if (!R2_GLOBALS.getFlag(2) || !R2_GLOBALS.getFlag(3) || (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1)) + SceneItem::display2(300, 55); + else { + R2_GLOBALS._player.disableControl(); + scene->_field412 = R2_GLOBALS.getFlag(4) ? 121 : 120; + scene->_sceneMode = 309; + scene->setAction(&scene->_sequenceManager1, scene, 309, &R2_GLOBALS._player, NULL); + } + return true; + + default: + break; + } + + return SceneActor::startAction(action, event); +} + +bool Scene300::Seeker::startAction(CursorType action, Event &event) { + return false; +} + +bool Scene300::Quinn::startAction(CursorType action, Event &event) { + return false; +} + +/*--------------------------------------------------------------------------*/ + +Scene300::Scene300(): SceneExt() { + _field412 = 0; + _rotation = NULL; +} + +void Scene300::synchronize(Serializer &s) { + SceneExt::synchronize(s); + + s.syncAsSint16LE(_field412); + SYNC_POINTER(_rotation); +} + +void Scene300::postInit(SceneObjectList *OwnerList) { + SceneExt::postInit(); + loadScene(300); + _sound1.play(23); + setZoomPercents(75, 93, 120, 100); + + if (R2_GLOBALS._sceneManager._previousScene == -1) { + R2_GLOBALS._sceneManager._previousScene = 1000; + R2_GLOBALS._player._characterIndex = 1; + } + + _stripManager.setColors(60, 255); + _stripManager.setFontNumber(3); + _stripManager.addSpeaker(&_mirandaSpeaker); + _stripManager.addSpeaker(&_seekerSpeaker); + _stripManager.addSpeaker(&_quinnSpeaker); + _stripManager.addSpeaker(&_quinnLSpeaker); + _stripManager.addSpeaker(&_seekerLSpeaker); + _stripManager.addSpeaker(&_tealSpeaker); + _stripManager.addSpeaker(&_soldierSpeaker); + + _rotation = R2_GLOBALS._scenePalette.addRotation(237, 254, -1); + _rotation->setDelay(3); + _rotation->_countdown = 1; + + if (R2_GLOBALS.getFlag(51) && !R2_GLOBALS.getFlag(25)) { + _object1.postInit(); + _object1.setup(301, 7, 2); + _object1.setPosition(Common::Point(65, 24)); + + _object2.postInit(); + _object2.setup(301, 8, 2); + _object2.setPosition(Common::Point(254, 24)); + } + + _doorway.postInit(); + _doorway.setVisage(300); + _doorway.setPosition(Common::Point(159, 79)); + + _object3.postInit(); + _object3.setup(300, 4, 1); + _object3.setPosition(Common::Point(84, 48)); + _object3.animate(ANIM_MODE_2, NULL); + _object3._numFrames = 5; + + _object4.postInit(); + _object4.setup(300, 5, 1); + _object4.setPosition(Common::Point(236, 48)); + + _object4.animate(ANIM_MODE_2, NULL); + + _protocolDisplay.postInit(); + _protocolDisplay.setup(300, 6, 1); + _protocolDisplay.setPosition(Common::Point(287, 71)); + _protocolDisplay.animate(ANIM_MODE_7, NULL); + _protocolDisplay._numFrames = 5; + + _object6.postInit(); + _object6.setup(300, 7, 1); + _object6.setPosition(Common::Point(214, 37)); + _object6.animate(ANIM_MODE_2, NULL); + _object6._numFrames = 3; + + _object7.postInit(); + _object7.setup(301, 1, 1); + _object7.setPosition(Common::Point(39, 97)); + _object7.fixPriority(124); + _object7.animate(ANIM_MODE_2, NULL); + _object7._numFrames = 5; + _object7.setAction(&_action4); + + _object8.postInit(); + _object8.setup(300, 8, 1); + _object8.setPosition(Common::Point(105, 37)); + _object8.animate(ANIM_MODE_2, NULL); + _object8._numFrames = 5; + + _object9.postInit(); + _object9.setup(301, 6, 1); + _object9.setPosition(Common::Point(274, 116)); + _object9.fixPriority(143); + _object9.animate(ANIM_MODE_2, NULL); + _object9._numFrames = 5; + + _quinnWorkstation1.setDetails(Rect(243, 148, 315, 167), 300, 30, 31, 32, 1, NULL); + _mirandaWorkstation1.setDetails(Rect(4, 128, 69, 167), 300, 33, 31, 35, 1, NULL); + + switch (R2_GLOBALS._player._characterIndex) { + case 1: + _miranda.postInit(); + _miranda.setup(302, 2, 1); + _miranda.setPosition(Common::Point(47, 128)); + _miranda.setAction(&_action3); + _miranda.setDetails(300, 39, 40, 41, 1, NULL); + + if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) { + _seeker.postInit(); + _seeker.setVisage(302); + _seeker.setPosition(Common::Point(158, 108)); + _seeker.fixPriority(130); + _seeker.setAction(&_action2); + _seeker.setDetails(300, 42, 43, 44, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.animate(ANIM_MODE_1, NULL); + R2_GLOBALS._player.disableControl(); + break; + + case 2: + _miranda.postInit(); + _miranda.setup(302, 2, 1); + _miranda.setPosition(Common::Point(47, 128)); + _miranda.setAction(&_action3); + _miranda.setDetails(300, 39, 40, 41, 1, NULL); + + if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) { + _quinn.postInit(); + _quinn.setup(302, 3, 1); + _quinn.setPosition(Common::Point(271, 150)); + _quinn.setAction(&_action1); + _quinn.setDetails(300, 50, 51, 52, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setup(302, 1, 3); + R2_GLOBALS._player.setPosition(Common::Point(158, 108)); + R2_GLOBALS._player.fixPriority(130); + R2_GLOBALS._player.enableControl(CURSOR_USE); + break; + + case 3: + if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) { + _seeker.postInit(); + _seeker.setVisage(302); + _seeker.setPosition(Common::Point(158, 108)); + _seeker.fixPriority(130); + _seeker.setAction(&_action2); + _seeker.setDetails(300, 42, 43, 44, 1, NULL); + } + + if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) { + _quinn.postInit(); + _quinn.setup(302, 3, 1); + _quinn.setPosition(Common::Point(271, 150)); + _quinn.setAction(&_action1); + _quinn.setDetails(300, 50, 51, 52, 1, NULL); + } + + R2_GLOBALS._player.postInit(); + R2_GLOBALS._player.setup(302, 2, 1); + R2_GLOBALS._player.setPosition(Common::Point(47, 128)); + R2_GLOBALS._player.enableControl(CURSOR_USE); + break; + + default: + break; + } + + _seekerWorkstation.setDetails(Rect(101, 95, 217, 143), 300, 36, 31, 35, 1, NULL); + _quinnWorkstation2.setDetails(Rect(224, 102, 315, 143), 300, 30, 31, 32, 1, NULL); + _mirandaWorkstation2.setDetails(Rect(4, 83, 84, 124), 300, 33, 31, 35, 1, NULL); + _hull.setDetails(11, 300, 6, -1, -1); + _statusDisplays.setDetails(12, 300, 9, 10, -1); + _damageControl.setDetails(13, 300, 12, -1, -1); + _manualOverrides.setDetails(14, 300, 15, -1, 17); + _scanners1.setDetails(Rect(126, 15, 183, 25), 300, 18, -1, 20, 1, NULL); + _scanners2.setDetails(Rect(126, 80, 183, 90), 300, 18, -1, 20, 1, NULL); + _protocolDisplay.setDetails(300, 27, -1, 29, 1, NULL); + _indirectLighting1.setDetails(Rect(74, 71, 122, 89), 300, 21, -1, -1, 1, NULL); + _indirectLighting2.setDetails(Rect(197, 71, 245, 89), 300, 21, -1, -1, 1, NULL); + _lighting.setDetails(Rect(129, 3, 190, 14), 300, 24, -1, -1, 1, NULL); + _doorway.setDetails(300, 3, -1, 5, 1, NULL); + _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 300, 0, -1, -1, 1, NULL); + + switch (R2_GLOBALS._player._characterIndex) { + case 1: + _sceneMode = 300; + + switch (R2_GLOBALS._sceneManager._previousScene) { + case 250: + setAction(&_sequenceManager1, this, 300, &R2_GLOBALS._player, &_doorway, NULL); + break; + case 325: + if (!R2_GLOBALS.getFlag(44) || R2_GLOBALS.getFlag(25)) + setAction(&_sequenceManager1, this, 309, &R2_GLOBALS._player, NULL); + else { + R2_GLOBALS.setFlag(60); + R2_GLOBALS._player.setup(302, 3, 1); + R2_GLOBALS._player.setPosition(Common::Point(271, 150)); + R2_GLOBALS._player.setAction(&_action1); + + if (R2_GLOBALS.getFlag(55)) { + if (R2_GLOBALS.getFlag(57)) { + R2_GLOBALS.clearFlag(60); + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Find correct cursor + _sceneMode = 16; + _stripManager.start(404, this); + } else { + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + } + } else { + if (R2_GLOBALS.getFlag(45)) { + R2_GLOBALS.clearFlag(60); + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Find correct cursor + _sceneMode = 12; + _stripManager.start3(204, this, R2_GLOBALS._stripManager_lookupList); + } else { + R2_GLOBALS._player.enableControl(); + R2_GLOBALS._player._canWalk = false; + } + } + } + break; + case 1000: + R2_GLOBALS.setFlag(60); + R2_GLOBALS._player.setup(302, 3, 1); + R2_GLOBALS._player.setPosition(Common::Point(271, 150)); + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor #2 + + if (R2_GLOBALS.getFlag(51)) { + _sceneMode = 13; + _stripManager.start3(300, this, R2_GLOBALS._stripManager_lookupList); + } else { + _sceneMode = 11; + _stripManager.start3(200, this, R2_GLOBALS._stripManager_lookupList); + } + break; + + case 1100: + R2_GLOBALS._player.setVisage(10); + R2_GLOBALS._player.setPosition(Common::Point(160, 95)); + _field412 = 400; + _sceneMode = 309; + setAction(&_sequenceManager1, this, 309, &R2_GLOBALS._player, NULL); + break; + + case 1500: + R2_GLOBALS.clearFlag(60); + R2_GLOBALS._player.setup(302, 3, 1); + R2_GLOBALS._player.setPosition(Common::Point(271, 150)); + _sceneMode = 17; + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor #2 + _stripManager.start(413, this); + break; + + default: + if (R2_GLOBALS.getFlag(60)) { + R2_GLOBALS._player.setup(302, 3, 1); + R2_GLOBALS._player.setPosition(Common::Point(271, 150)); + R2_GLOBALS._player.setAction(&_action1); + R2_GLOBALS._player.enableControl(CURSOR_USE); + R2_GLOBALS._player._canWalk = false; + } else { + R2_GLOBALS._player.setStrip(3); + R2_GLOBALS._player.setPosition(Common::Point(200, 150)); + R2_GLOBALS._player.enableControl(); + } + break; + } + break; + + case 3: + if (R2_GLOBALS._sceneManager._previousScene == 1500) { + R2_GLOBALS._player._fieldBC = 3150; + R2_GLOBALS._player._characterScene[3] = 3150; + R2_GLOBALS._player._effect = 0; + R2_GLOBALS._player.setAction(NULL); + R2_GLOBALS._player.disableControl(); + + _quinn.postInit(); + _quinn.setVisage(10); + _quinn.setPosition(Common::Point(10, 10)); + _quinn.hide(); + + _seeker.postInit(); + _seeker.setVisage(20); + _seeker.setPosition(Common::Point(20, 20)); + _seeker.hide(); + + _teal.postInit(); + _soldier.postInit(); + _object12.postInit(); + + R2_GLOBALS._sound1.play(107); + _sceneMode = 308; + + setAction(&_sequenceManager1, this, 308, &R2_GLOBALS._player, &_teal, &_soldier, &_object12, &_doorway, NULL); + } + break; + default: + break; + } +} + +void Scene300::remove() { + R2_GLOBALS._player.setAction(NULL); + SceneExt::remove(); +} + +void Scene300::signal() { + switch (_sceneMode) { + case 10: + switch (_stripManager._field2E8) { + case 0: + R2_GLOBALS._sound1.changeSound(10); + R2_GLOBALS.setFlag(38); + break; + case 1: + R2_GLOBALS.setFlag(3); + break; + case 2: + R2_GLOBALS.setFlag(4); + break; + case 3: + R2_GLOBALS.setFlag(13); + if (R2_GLOBALS._stripManager_lookupList[1] == 6) + R2_GLOBALS.setFlag(40); + break; + case 4: + if (R2_GLOBALS._stripManager_lookupList[1] == 6) + R2_GLOBALS.setFlag(40); + break; + case 5: + R2_GLOBALS._sceneManager.changeScene(1000); + break; + default: + break; + } + + _stripManager._field2E8 = 0; + switch (_field412) { + case 400: + R2_GLOBALS._player.disableControl(); + _sceneMode = 15; + setAction(&_sequenceManager1, this, 306, &R2_GLOBALS._player, NULL); + break; + case 181: + R2_GLOBALS._player.setStrip(6); + // Deliberate fall-through + default: + R2_GLOBALS._player.enableControl(CURSOR_TALK); + + if ((R2_GLOBALS._player._characterIndex != 1) || R2_GLOBALS.getFlag(44)) + R2_GLOBALS._player._canWalk = false; + break; + } + break; + + case 11: + R2_GLOBALS.setFlag(44); + R2_GLOBALS._player.enableControl(CURSOR_USE); + break; + + case 12: + R2_GLOBALS._player.setAction(NULL); + R2_GLOBALS._sceneManager.changeScene(1010); + break; + + case 13: + R2_GLOBALS._player.disableControl(); + _seeker.changeZoom(-1); + _sceneMode = 313; + _seeker.setAction(NULL); + setAction(&_sequenceManager1, this, 313, &R2_GLOBALS._player, &_seeker, NULL); + break; + + case 14: + if (_seeker._action) + R2_GLOBALS._player.disableControl(); + _sceneMode = 314; + break; + + case 15: + R2_GLOBALS.setFlag(55); + R2_GLOBALS.setFlag(38); + R2_GLOBALS.setFlag(44); + R2_GLOBALS.setFlag(51); + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor 2 + _sceneMode = 16; + _stripManager.start3(401, this, R2_GLOBALS._stripManager_lookupList); + break; + + case 16: + if (_stripManager._field2E8 == 1) { + R2_GLOBALS._player.setAction(NULL); + R2_GLOBALS._sceneManager.changeScene(1000); + } else { + R2_GLOBALS._player.setAction(&_action1); + R2_GLOBALS._player.enableControl(CURSOR_TALK); + } + break; + + case 17: + R2_GLOBALS._player.disableControl(); + _sceneMode = 316; + _seeker.changeZoom(-1); + _seeker.setAction(&_sequenceManager3, this, 316, &_seeker, &_doorway, NULL); + R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 307, &R2_GLOBALS._player, NULL); + break; + + case 18: + R2_GLOBALS._player.disableControl(); + _sceneMode = 317; + setAction(&_sequenceManager1, this, 317, &_teal, &_doorway, NULL); + break; + + case 19: + R2_GLOBALS._player.disableControl(); + _sceneMode = 318; + setAction(&_sequenceManager1, this, 318, &R2_GLOBALS._player, &_teal, &_soldier, &_object12, NULL); + break; + + case 20: + R2_GLOBALS._player._characterIndex = 1; + R2_GLOBALS._sceneManager.changeScene(1500); + break; + + case 300: + case 307: + R2_GLOBALS._player.enableControl(); + break; + + case 301: + R2_GLOBALS._sceneManager.changeScene(250); + break; + + case 306: + R2_GLOBALS._sceneManager.changeScene(325); + break; + + case 308: + _sceneMode = 18; + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor 2 + _stripManager.start(418, this); + break; + + case 310: + R2_GLOBALS._player.setStrip(5); + // Deliberate fall-through + case 309: + signal309(); + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor 2 + _sceneMode = 10; + _stripManager.start3(_field412, this, R2_GLOBALS._stripManager_lookupList); + break; + + case 313: + _sceneMode = 14; + R2_GLOBALS._player._effect = 0; + _seeker.setAction(&_sequenceManager3, this, 314, &_seeker, &_doorway, NULL); + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor 2 + _stripManager.start(301, this); + break; + + case 314: + R2_GLOBALS._player.disableControl(); + _sceneMode = 315; + R2_GLOBALS._player._effect = 1; + setAction(&_sequenceManager1, this, 315, &R2_GLOBALS._player, &_doorway, NULL); + break; + + case 315: + R2_GLOBALS._sceneManager.changeScene(1100); + break; + + case 316: + R2_GLOBALS._player._characterScene[2] = 500; + _seeker.remove(); + R2_GLOBALS._player.enableControl(/* TODO: Cursor #3 */); + break; + + case 317: + _sceneMode = 19; + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor 2 + _stripManager.start(419, this); + break; + + case 318: + _sceneMode = 20; + R2_GLOBALS._events.setCursor(CURSOR_USE); // TODO: Cursor 2 + _stripManager.start(420, this); + break; + + default: + break; + } +} + +void Scene300::signal309() { + if (R2_GLOBALS.getFlag(2)) + R2_GLOBALS._stripManager_lookupList[0] = (R2_INVENTORY.getObjectScene(R2_2) == 1) ? 3 : 2; + + if (R2_GLOBALS.getFlag(4)) + R2_GLOBALS._stripManager_lookupList[0] = 4; + + if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1) + R2_GLOBALS._stripManager_lookupList[0] = 5; + + if (R2_GLOBALS.getFlag(13)) { + R2_GLOBALS._stripManager_lookupList[0] = 6; + R2_GLOBALS._stripManager_lookupList[2] = 2; + } + + if (R2_GLOBALS.getFlag(39)) + R2_GLOBALS._stripManager_lookupList[1] = 2; + + if (R2_GLOBALS.getFlag(5)) + R2_GLOBALS._stripManager_lookupList[1] = 3; + + if (R2_GLOBALS.getFlag(6)) + R2_GLOBALS._stripManager_lookupList[1] = 4; + + if (R2_GLOBALS.getFlag(8)) + R2_GLOBALS._stripManager_lookupList[1] = 5; + + if (R2_GLOBALS.getFlag(9)) { + R2_GLOBALS._stripManager_lookupList[1] = 6; + R2_GLOBALS._stripManager_lookupList[3] = 2; + } + + if (R2_GLOBALS.getFlag(48)) + R2_GLOBALS._stripManager_lookupList[4] = 2; + + if (R2_GLOBALS.getFlag(49)) + R2_GLOBALS._stripManager_lookupList[4] = 3; +} + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h index a80bda0726..c207118372 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.h +++ b/engines/tsage/ringworld2/ringworld2_scenes0.h @@ -31,6 +31,7 @@ #include "tsage/globals.h" #include "tsage/sound.h" #include "tsage/ringworld2/ringworld2_logic.h" +#include "tsage/ringworld2/ringworld2_speakers.h" namespace TsAGE { @@ -38,6 +39,20 @@ namespace Ringworld2 { using namespace TsAGE; +class Scene50: public SceneExt { + + class Action1: public Action { + public: + void signal(); + }; + +public: + Action1 _action1; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); +}; + class Scene100: public SceneExt { /* Objects */ class Door: public SceneActorExt { @@ -85,6 +100,147 @@ public: virtual void dispatch(); }; +class Scene125: public SceneExt { + /* Objects */ + class Object5: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + + class Icon: public SceneActor { + public: + int _lookLineNum, _field98; + bool _pressed; + SceneObject _object1, _object2; + SceneText _sceneText1, _sceneText2; + + Icon(); + virtual Common::String getClassName() { return "Scene125_Icon"; } + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronize(Serializer &s); + virtual void process(Event &event); + + void setIcon(int id); + void showIcon(); + void hideIcon(); + }; + + /* Items */ + class Item4: public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + +public: + ScenePalette _palette; + ASoundExt _sound1; + NamedHotspot _background, _item2, _item3; + Item4 _item4; + SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _object7; + Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6; + SequenceManager _sequenceManager; + SceneText _sceneText; + int _consoleMode, _iconFontNumber, _logIndex, _databaseIndex, _infodiskIndex; + int _soundCount, _soundIndex; + int _soundIndexes[10]; + + Scene125(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronize(Serializer &s); + virtual void signal(); + virtual void process(Event &event); + virtual void dispatch(); + + void consoleAction(int id); + void setDetails(int resNum, int lineNum); + void stop(); + Common::String parseMessage(const Common::String &msg); +}; + +class Scene300: public SceneExt { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + + /* Items */ + class QuinnWorkstation: public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class MirandaWorkstation: public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class SeekerWorkstation: public NamedHotspot { + public: + virtual bool startAction(CursorType action, Event &event); + }; + + /* Objects */ + class Miranda: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class Seeker: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; + class Quinn: public SceneActor { + public: + virtual bool startAction(CursorType action, Event &event); + }; +public: + SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3, _sequenceManager4; + ASoundExt _sound1; + SpeakerMiranda300 _mirandaSpeaker; + SpeakerSeeker300 _seekerSpeaker; + SpeakerSeekerL _seekerLSpeaker; + SpeakerQuinn300 _quinnSpeaker; + SpeakerQuinnL _quinnLSpeaker; + SpeakerTeal300 _tealSpeaker; + SpeakerSoldier300 _soldierSpeaker; + + NamedHotspot _background, _hull, _statusDisplays, _damageControl, _manualOverrides; + NamedHotspot _scanners1, _scanners2, _indirectLighting1, _indirectLighting2, _lighting; + QuinnWorkstation _quinnWorkstation1, _quinnWorkstation2; + SeekerWorkstation _seekerWorkstation; + MirandaWorkstation _mirandaWorkstation1, _mirandaWorkstation2; + SceneActor _object1, _object2, _object3, _object4, _protocolDisplay; + SceneActor _object6, _object7, _object8, _object9; + SceneActor _teal, _soldier, _object12, _doorway; + Miranda _miranda; + Seeker _seeker; + Quinn _quinn; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + PaletteRotation *_rotation; + int _field412; + + Scene300(); + void signal309(); + + virtual void synchronize(Serializer &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void signal(); +}; + } // End of namespace Ringworld2 } // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp new file mode 100644 index 0000000000..3c9a84c123 --- /dev/null +++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp @@ -0,0 +1,460 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "tsage/ringworld2/ringworld2_speakers.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/graphics.h" +#include "tsage/staticres.h" +#include "tsage/ringworld2/ringworld2_scenes0.h" + +namespace TsAGE { + +namespace Ringworld2 { + +VisualSpeaker::VisualSpeaker(): Speaker() { + _delayAmount = 0; + _frameNumber = R2_GLOBALS._events.getFrameNumber(); + _color1 = 8; + _color2 = 0; + _displayMode = 0; + _fieldF6 = 0; +} + +void VisualSpeaker::remove() { + if (_object2) { + if (_fieldF8) { + _fieldF8 = 0; + _object1.setStrip(_object1._strip - 1); + _object1.setFrame(_object1.getFrameCount()); + _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL); + } else { + _object1.animate(ANIM_MODE_6, (_fieldF6 == 0xff) ? this : NULL); + } + } + + Speaker::remove(); +} + +void VisualSpeaker::synchronize(Serializer &s) { + Speaker::synchronize(s); + + SYNC_POINTER(_object2); + s.syncAsSint16LE(_fieldF6); + s.syncAsSint16LE(_fieldF8); + s.syncAsSint16LE(_displayMode); + s.syncAsSint16LE(_soundId); + s.syncAsSint16LE(_delayAmount); + s.syncAsByte(_removeObject); + s.syncAsSint32LE(_frameNumber); + s.syncAsSint16LE(_numFrames); +} + +void VisualSpeaker::setText(const Common::String &msg) { + _sceneText.remove(); + + // Position the text depending on the specified display mode + switch (_displayMode) { + case 2: + _textPos = Common::Point(60, 20); + break; + case 3: + _textPos = Common::Point(110, 20); + break; + case 4: + _textPos = Common::Point(10, 100); + break; + case 5: + _textPos = Common::Point(60, 100); + break; + case 6: + _textPos = Common::Point(110, 100); + break; + case 7: + _textPos = Common::Point(170, 20); + break; + case 8: + _textPos = Common::Point(170, 100); + break; + case 9: + _textPos = Common::Point(330, 20); + break; + default: + _textPos = Common::Point(10, 20); + break; + } + + // Check if the message starts with a '!'. If so, it indicates a speech resource Id to be played, + // in which case extract the resource number from the message. + _soundId = 0; + Common::String s = msg; + if (s.hasPrefix("!")) { + s.deleteChar(0); + _soundId = atoi(msg.c_str()); + + while (!s.empty() && (*s.c_str() >= '0' && *s.c_str() <= '9')) + s.deleteChar(0); + } + + // Set up the text details + _sceneText._color1 = _color1; + _sceneText._color2 = _color2; + _sceneText._color3 = _color3; + _sceneText._width = _textWidth; + _sceneText._fontNumber = _fontNumber; + _sceneText._textMode = _textMode; + _sceneText.setup(msg); + + //_sceneText.clone(); + + _sceneText.setPosition(_textPos); + _sceneText.setPriority(0x100); + + // If subtitles are turned off, don't show the text + if (!(R2_GLOBALS._speechSubtitles & 1)) { + _sceneText.hide(); + } + + // Figure out the text delay if subtitles are turned on, or there's no speech resource specified + if ((R2_GLOBALS._speechSubtitles & 1) || !_soundId) { + const char *msgP = s.c_str(); + int numWords = 0; + while (*msgP != '\0') { + if (*msgP++ == ' ') + ++numWords; + } + + if (!numWords && !s.empty()) + ++numWords; + + _numFrames = numWords * 30 + 120; + setFrame(_numFrames); + } else { + _numFrames = 1; + } + + // If the text is empty, no delay is needed + if (s.empty()) + _numFrames = 0; + + + if (_fieldF6) { + if ((R2_GLOBALS._speechSubtitles & 1) || !_soundId) + _sceneText.hide(); + } else { + if ((R2_GLOBALS._speechSubtitles & 2) && _soundId) { + if (!R2_GLOBALS._playStream.play(_soundId, NULL)) + _sceneText.show(); + } + } +} + +void VisualSpeaker::proc16() { + R2_GLOBALS._playStream.stop(); + _fieldF6 = 0; + _object1.remove(); + + assert(_object2); + _object2->show(); + _object2 = NULL; + _fieldF8 = 0; +} + +void VisualSpeaker::setFrame(int numFrames) { + _delayAmount = numFrames; + _frameNumber = R2_GLOBALS._events.getFrameNumber(); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerMiranda300::SpeakerMiranda300(): VisualSpeaker() { + _speakerName = "MIRANDA"; + _color1 = 154; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerMiranda300::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 3) { + _object2 = &R2_GLOBALS._player; + } else { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_miranda; + } + + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else if (v == 100) { + _numFrames = 0; + ((SceneItem *)_action)->_sceneRegionId = 0; + + _object1.setStrip(_object1._strip - 1); + _object1.setFrame(_object1.getFrameCount()); + _object1.animate(ANIM_MODE_6, this); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + + if (v == 4) { + _object1.setup(304, 5, 1); + } else { + _object1.setup(305, v * 2 - 1, 1); + } + _object1.animate(ANIM_MODE_5, this); + } +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSeeker300::SpeakerSeeker300(): VisualSpeaker() { + _speakerName = "SEEKER"; + _color1 = 35; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerSeeker300::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 3) { + _object2 = &R2_GLOBALS._player; + } else { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_seeker; + } + + _object2->hide(); + _object1.postInit(); + _object1.fixPriority(140); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else if (v == 100) { + _numFrames = 0; + ((SceneItem *)_action)->_sceneRegionId = 0; + + _object1.setStrip(_object1._strip - 1); + _object1.setFrame(_object1.getFrameCount()); + _object1.animate(ANIM_MODE_6, this); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setup(306, v * 2 - 1, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSeekerL::SpeakerSeekerL(): VisualSpeaker() { + _speakerName = "SEEKERL"; + _color1 = 35; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; + _fontNumber = 10; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQuinnL::SpeakerQuinnL(): VisualSpeaker() { + _speakerName = "QUINNL"; + _color1 = 35; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; + _fontNumber = 10; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQuinn300::SpeakerQuinn300(): VisualSpeaker() { + _speakerName = "QUINN"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerQuinn300::proc15() { + int v = _fieldF6; + + if (!_object2) { + if (R2_GLOBALS._player._characterIndex == 3) { + _object2 = &R2_GLOBALS._player; + } else { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_quinn; + } + + _object2->hide(); + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else if (v == 100) { + _numFrames = 0; + ((SceneItem *)_action)->_sceneRegionId = 0; + + _object1.setStrip(_object1._strip - 1); + _object1.setFrame(_object1.getFrameCount()); + _object1.animate(ANIM_MODE_6, this); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + + switch (_object2->_visage) { + case 10: + _object1.setup((v - 1) / 4 + 4010, ((v - ((v - 1) / 4 * 4) - 1) % 8) * 2 + 1, 1); + break; + case 302: + _object1.setup(308, (v - 1) % 8 + 1, 1); + break; + case 308: + _object1.setup(308, 5, 1); + break; + } + + _object1.animate(ANIM_MODE_5, this); + } +} + +/*--------------------------------------------------------------------------*/ + +SpeakerTeal300::SpeakerTeal300(): VisualSpeaker() { + _speakerName = "TEAL"; + _color1 = 22; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerTeal300::proc15() { + int v = _fieldF6; + + if (!_object2) { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_teal; + _object2->hide(); + + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setup(303, 1, 1); + _object1.animate(ANIM_MODE_5, this); + } +} + + +/*--------------------------------------------------------------------------*/ + +SpeakerSoldier300::SpeakerSoldier300(): VisualSpeaker() { + _speakerName = "SOLDIER"; + _color1 = 60; + _color2 = 0; + _fieldF6 = 0; + _textWidth = 300; + _hideObjects = false; + _object2 = NULL; + _displayMode = 1; + _numFrames = 0; +} + +void SpeakerSoldier300::proc15() { + int v = _fieldF6; + + if (!_object2) { + Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene; + _object2 = &scene->_teal; + _object2->hide(); + + _object1.postInit(); + _object1.setPosition(_object2->_position); + + if (_object2->_mover) + _object2->addMover(NULL); + } + + if (v == 0) { + _object1.animate(ANIM_MODE_2, NULL); + } else { + ((SceneItem *)_action)->_sceneRegionId = 0; + _object1.setup(303, 3, 1); + _object1.animate(ANIM_MODE_5, this); + } +} +} // End of namespace Ringworld2 + +} // End of namespace TsAGE diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h new file mode 100644 index 0000000000..97972549fa --- /dev/null +++ b/engines/tsage/ringworld2/ringworld2_speakers.h @@ -0,0 +1,122 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TSAGE_RINGWORLD2_SPEAKERS_H +#define TSAGE_RINGWORLD2_SPEAKERS_H + +#include "common/scummsys.h" +#include "tsage/converse.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" +#include "tsage/ringworld2/ringworld2_logic.h" + +namespace TsAGE { + +namespace Ringworld2 { + +using namespace TsAGE; + +class VisualSpeaker: public Speaker { +public: + SceneActor _object1; + SceneObject *_object2; + int _fieldF6, _fieldF8; + int _displayMode; + int _soundId; + int _delayAmount; + bool _removeObject; + int _frameNumber; + int _numFrames; +private: + void setFrame(int numFrames); +public: + VisualSpeaker(); + + virtual Common::String getClassName() { return "VisualSpeaker"; } + virtual void synchronize(Serializer &s); + virtual void remove(); + virtual void setText(const Common::String &msg); + virtual void proc15() {} + virtual void proc16(); +}; + +class SpeakerMiranda300: public VisualSpeaker { +public: + SpeakerMiranda300(); + + virtual Common::String getClassName() { return "SpeakerMiranda300"; } + virtual void proc15(); +}; + +class SpeakerSeeker300: public VisualSpeaker { +public: + SpeakerSeeker300(); + + virtual Common::String getClassName() { return "SpeakerSeeker300"; } + virtual void proc15(); +}; + +class SpeakerSeekerL: public VisualSpeaker { +public: + SpeakerSeekerL(); + + virtual Common::String getClassName() { return "SpeakerSeekerL"; } +}; + +class SpeakerQuinnL: public VisualSpeaker { +public: + SpeakerQuinnL(); + + virtual Common::String getClassName() { return "SpeakerQuinnL"; } +}; + +class SpeakerQuinn300: public VisualSpeaker { +public: + SpeakerQuinn300(); + + virtual Common::String getClassName() { return "SpeakerQuinn300"; } + virtual void proc15(); +}; + +class SpeakerTeal300: public VisualSpeaker { +public: + SpeakerTeal300(); + + virtual Common::String getClassName() { return "SpeakerTeal300"; } + virtual void proc15(); +}; + +class SpeakerSoldier300: public VisualSpeaker { +public: + SpeakerSoldier300(); + + virtual Common::String getClassName() { return "SpeakerSoldier300"; } + virtual void proc15(); +}; + +} // End of namespace Ringworld2 + +} // End of namespace TsAGE + +#endif diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h index 207051a182..ff78abf52d 100644 --- a/engines/tsage/saveload.h +++ b/engines/tsage/saveload.h @@ -33,7 +33,7 @@ namespace TsAGE { typedef void (*SaveNotifierFn)(bool postFlag); -#define TSAGE_SAVEGAME_VERSION 8 +#define TSAGE_SAVEGAME_VERSION 9 class SavedObject; diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 5ed7c06800..6362c63bc3 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -259,7 +259,7 @@ Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), _sceneMode = 0; _activeScreenNumber = 0; _oldSceneBounds = Rect(4000, 4000, 4100, 4100); - Common::set_to(&_zoomPercents[0], &_zoomPercents[256], 0); + Common::fill(&_zoomPercents[0], &_zoomPercents[256], 0); } Scene::~Scene() { @@ -363,7 +363,7 @@ void Scene::loadSceneData(int sceneNum) { _priorities.load(sceneNum); // Initialize the section enabled list - Common::set_to(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff); + Common::fill(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff); g_globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160; g_globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100; diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index b61e63236b..9df5a6666b 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -36,7 +36,7 @@ static SoundManager *_soundManager = NULL; SoundManager::SoundManager() { _soundManager = this; - __sndmgrReady = false; + _sndmgrReady = false; _ourSndResVersion = 0x102; _ourDrvResVersion = 0x10A; @@ -52,7 +52,7 @@ SoundManager::SoundManager() { } SoundManager::~SoundManager() { - if (__sndmgrReady) { + if (_sndmgrReady) { Common::StackLock slock(_serverDisabledMutex); g_vm->_mixer->stopAll(); @@ -83,7 +83,7 @@ SoundManager::~SoundManager() { } void SoundManager::postInit() { - if (!__sndmgrReady) { + if (!_sndmgrReady) { g_saver->addSaveNotifier(&SoundManager::saveNotifier); g_saver->addLoadNotifier(&SoundManager::loadNotifier); g_saver->addListener(this); @@ -94,7 +94,7 @@ void SoundManager::postInit() { // thread, and doesn't get too far ahead, I've left it to the AdlibSoundDriver class to // call the update method, rather than having it be called separately // g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / SOUND_FREQUENCY, NULL, "tsageSoundUpdate"); - __sndmgrReady = true; + _sndmgrReady = true; } } @@ -136,7 +136,7 @@ void SoundManager::update() { } Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) { - assert(__sndmgrReady); + assert(_sndmgrReady); _availableDrivers.clear(); // Build up a list of available drivers. Currently we only implement an Adlib music @@ -549,7 +549,7 @@ void SoundManager::loadNotifier(bool postFlag) { void SoundManager::loadNotifierProc(bool postFlag) { if (!postFlag) { // Stop any currently playing sounds - if (__sndmgrReady) { + if (_sndmgrReady) { Common::StackLock slock(_serverDisabledMutex); for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) { @@ -569,7 +569,7 @@ void SoundManager::loadNotifierProc(bool postFlag) { void SoundManager::listenerSynchronize(Serializer &s) { s.validate("SoundManager"); - assert(__sndmgrReady && _driversDetected); + assert(_sndmgrReady && _driversDetected); if (s.getVersion() < 6) return; @@ -798,7 +798,7 @@ void SoundManager::_sfRethinkVoiceTypes() { continue; _sfUpdateVoiceStructs(); - Common::set_to(sound->_chWork, sound->_chWork + SOUND_ARR_SIZE, false); + Common::fill(sound->_chWork, sound->_chWork + SOUND_ARR_SIZE, false); for (;;) { // Scan for sub priority @@ -1485,7 +1485,7 @@ Sound::Sound() { memset(_chNumVoices, 0, SOUND_ARR_SIZE * sizeof(int)); memset(_chSubPriority, 0, SOUND_ARR_SIZE * sizeof(int)); memset(_chFlags, 0, SOUND_ARR_SIZE * sizeof(int)); - Common::set_to(_chWork, _chWork + SOUND_ARR_SIZE, false); + Common::fill(_chWork, _chWork + SOUND_ARR_SIZE, false); memset(_channelData, 0, SOUND_ARR_SIZE * sizeof(byte *)); memset(_trkChannel, 0, SOUND_ARR_SIZE * sizeof(int)); memset(_trkState, 0, SOUND_ARR_SIZE * sizeof(int)); @@ -2557,7 +2557,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); - Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false); + Common::fill(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false); memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); memset(_v4405E, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); memset(_v44067, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); @@ -2565,7 +2565,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { memset(_v44079, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); memset(_v44082, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); _v44082[ADLIB_CHANNEL_COUNT] = 0x90; - Common::set_to(_pitchBlend, _pitchBlend + ADLIB_CHANNEL_COUNT, 0x2000); + Common::fill(_pitchBlend, _pitchBlend + ADLIB_CHANNEL_COUNT, 0x2000); memset(_v4409E, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); _patchData = NULL; } diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 2c5d2ac951..c7b07e2cc3 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -169,7 +169,7 @@ class SoundManager : public SaveListener { private: SoundDriver *instantiateDriver(int driverNum); public: - bool __sndmgrReady; + bool _sndmgrReady; int _ourSndResVersion, _ourDrvResVersion; SynchronizedList<Sound *> _playList; Common::List<SoundDriver *> _installedDrivers; @@ -414,6 +414,16 @@ public: virtual void signal(); }; +class PlayStream { +public: + Sound _sound; + + void setFile(const Common::String &filename) {} + bool play(int soundNum, EventHandler *endAction) { return false; } + void stop() {} + void proc1() {} + bool isPlaying() const { return false; } +}; #define ADLIB_CHANNEL_COUNT 9 diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp index c98d9d2e53..238e7b3049 100644 --- a/engines/tsage/staticres.cpp +++ b/engines/tsage/staticres.cpp @@ -77,7 +77,6 @@ const char *INV_EMPTY_MSG = "You have nothing in your possesion."; const char *QUIT_CONFIRM_MSG = "Do you want to quit playing this game?"; const char *RESTART_MSG = "Do you want to restart this game?"; const char *GAME_PAUSED_MSG = "Game is paused."; -const char *OPTIONS_MSG = "\x01Options..."; const char *OK_BTN_STRING = " Ok "; const char *CANCEL_BTN_STRING = "Cancel"; const char *QUIT_BTN_STRING = " Quit "; @@ -99,6 +98,7 @@ F4 - Restart\rF5 - Save game\rF7 - Restore Game\rF10 - Pause game"; const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?"; const char *START_PLAY_BTN_STRING = " Start Play "; const char *INTRODUCTION_BTN_STRING = "Introduction"; +const char *OPTIONS_MSG = "\x01Options..."; // Scene specific resources const char *EXIT_MSG = " EXIT "; @@ -134,6 +134,7 @@ F4 - Restart\rF5 - Save game\rF7 - Restore Game\rF10 - Pause game"; const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?"; const char *START_PLAY_BTN_STRING = " Play "; const char *INTRODUCTION_BTN_STRING = " Watch "; +const char *OPTIONS_MSG = "Options..."; // Blue Force general messages const char *BF_NAME = "Blue Force"; @@ -180,4 +181,41 @@ const char *THE_NEXT_DAY = "The Next Day"; } // End of namespace BlueForce +namespace Ringworld2 { + +const char *CONSOLE_MESSAGES[] = { + NULL, "Select Language", "Computer Services", "Food Services", "Entertainment Services", + "Main Menu", "Exit Menu", "Previous Menu", "Interworld", "Hero's Tongue", "Personal Log", + "Database", "Starchart", "Iso-Opto Disk Reader", "Eject Disk", "Meals", "Snacks", + "Beverages", "Human Basic Snacks", "Kzin Basic Snacks", "Hot Beverages", "Cold Beverages", + "Music", "Outpost Alpha", " ", " ", "Done", "A-G", "H-O", "P-S", "T-Z", "Tchaikovsky", + "Mozart", "Bach", "Rossini" +}; + +const char *HELP_MSG = "\x1\rRETURN TO\r RINGWORLD\x14"; +const char *CHAR_TITLE = "\x01Select Character:"; +const char *CHAR_QUINN_MSG = " Quinn "; +const char *CHAR_SEEKER_MSG = " Seeker "; +const char *CHAR_MIRANDA_MSG = "Miranda"; +const char *CHAR_CANCEL_MSG = " Cancel "; + +const char *GAME_VERSION = "ScummVM Version"; +const char *SOUND_OPTIONS = "Sound options"; +const char *QUIT_GAME = "Quit"; +const char *RESTART_GAME = "Restart"; +const char *SAVE_GAME = "Save game"; +const char *RESTORE_GAME = "Restore game"; +const char *SHOW_CREDITS = "Show credits"; +const char *PAUSE_GAME = "Pause game"; +const char *RESUME_PLAY = " Resume play "; +const char *F2 = "F2"; +const char *F3 = "F3"; +const char *F4 = "F4"; +const char *F5 = "F5"; +const char *F7 = "F7"; +const char *F8 = "F8"; +const char *F10 = "F10"; + +} // End of namespace Ringworld2 + } // End of namespace TsAGE diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h index 203fa1481d..faff3f4103 100644 --- a/engines/tsage/staticres.h +++ b/engines/tsage/staticres.h @@ -44,7 +44,6 @@ extern const char *RESTORING_NOT_ALLOWED_MSG; extern const char *QUIT_CONFIRM_MSG; extern const char *RESTART_MSG; extern const char *GAME_PAUSED_MSG; -extern const char *OPTIONS_MSG; extern const char *OK_BTN_STRING; extern const char *CANCEL_BTN_STRING; extern const char *QUIT_BTN_STRING; @@ -64,6 +63,7 @@ extern const char *HELP_MSG; extern const char *WATCH_INTRO_MSG; extern const char *START_PLAY_BTN_STRING; extern const char *INTRODUCTION_BTN_STRING; +extern const char *OPTIONS_MSG; // Scene specific resources extern const char *EXIT_MSG; @@ -98,6 +98,7 @@ extern const char *HELP_MSG; extern const char *WATCH_INTRO_MSG; extern const char *START_PLAY_BTN_STRING; extern const char *INTRODUCTION_BTN_STRING; +extern const char *OPTIONS_MSG; // Blue Force messages extern const char *BF_NAME; @@ -143,6 +144,38 @@ extern const char *THE_NEXT_DAY; } // End of namespace BlueForce +namespace Ringworld2 { + +// Scene 125 - Console messages +extern const char *CONSOLE_MESSAGES[]; + +// Dialog messages +extern const char *HELP_MSG; +extern const char *CHAR_TITLE; +extern const char *CHAR_QUINN_MSG; +extern const char *CHAR_SEEKER_MSG; +extern const char *CHAR_MIRANDA_MSG; +extern const char *CHAR_CANCEL_MSG; + +extern const char *GAME_VERSION; +extern const char *SOUND_OPTIONS; +extern const char *QUIT_GAME; +extern const char *RESTART_GAME; +extern const char *SAVE_GAME; +extern const char *RESTORE_GAME; +extern const char *SHOW_CREDITS; +extern const char *PAUSE_GAME; +extern const char *RESUME_PLAY; +extern const char *F2; +extern const char *F3; +extern const char *F4; +extern const char *F5; +extern const char *F7; +extern const char *F8; +extern const char *F10; + +} // End of namespace Ringworld2 + } // End of namespace TsAGE #endif diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp index 7e7198fc2b..f2775e083d 100644 --- a/engines/tsage/tsage.cpp +++ b/engines/tsage/tsage.cpp @@ -61,6 +61,9 @@ bool TSageEngine::hasFeature(EngineFeature f) const { } void TSageEngine::initialize() { + // Set up the correct graphics mode + init(); + g_saver = new Saver(); // Set up the resource manager @@ -97,7 +100,7 @@ void TSageEngine::initialize() { // Reset all global variables R2_GLOBALS.reset(); - } + } g_globals->gfxManager().setDefaults(); diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp index f6eae80d9c..ef4eb29028 100644 --- a/engines/tsage/user_interface.cpp +++ b/engines/tsage/user_interface.cpp @@ -71,12 +71,27 @@ void UIQuestion::process(Event &event) { } void UIQuestion::showDescription(CursorType cursor) { - if (cursor == INV_FOREST_RAP) { - // Forest rap item has a graphical display - showItem(5, 1, 1); - } else { - // Display object description - SceneItem::display2(9001, (int)cursor); + switch (g_vm->getGameID()) { + case GType_BlueForce: + if (cursor == INV_FOREST_RAP) { + // Forest rap item has a graphical display + showItem(5, 1, 1); + } else { + // Display object description + SceneItem::display2(9001, (int)cursor); + } + break; + case GType_Ringworld2: + if ((cursor == R2_9) || (cursor == R2_39)) { + // Show communicator + warning("TODO: Communicator"); + } else { + // Show object description + SceneItem::display2(3, (int)cursor); + } + break; + default: + break; } } @@ -266,9 +281,11 @@ void UICollection::draw() { /*--------------------------------------------------------------------------*/ UIElements::UIElements(): UICollection() { - _cursorVisage.setVisage(1, 5); + if (g_vm->getGameID() == GType_Ringworld2) + _cursorVisage.setVisage(5, 1); + else + _cursorVisage.setVisage(1, 5); g_saver->addLoadNotifier(&UIElements::loadNotifierProc); - _characterIndex = 0; } void UIElements::synchronize(Serializer &s) { @@ -296,13 +313,11 @@ void UIElements::synchronize(Serializer &s) { s.syncAsSint16LE(itemId); } } - - if (g_vm->getGameID() == GType_Ringworld2) - s.syncAsSint16LE(_characterIndex); } void UIElements::process(Event &event) { - if (_clearScreen && GLOBALS._player._enabled && (GLOBALS._sceneManager._sceneNumber != 50)) { + if (_clearScreen && GLOBALS._player._enabled && + ((g_vm->getGameID() != GType_BlueForce) || (GLOBALS._sceneManager._sceneNumber != 50))) { if (_bounds.contains(event.mousePos)) { // Cursor inside UI area if (!_cursorChanged) { @@ -310,7 +325,8 @@ void UIElements::process(Event &event) { // Inventory icon being displayed, so leave alone } else { // Change to the inventory use cursor - GfxSurface surface = _cursorVisage.getFrame(6); + int cursorId = (g_vm->getGameID() == GType_Ringworld2) ? 11 : 6; + GfxSurface surface = _cursorVisage.getFrame(cursorId); GLOBALS._events.setCursor(surface); } _cursorChanged = true; @@ -407,7 +423,7 @@ void UIElements::setup(const Common::Point &pt) { break; case GType_Ringworld2: // Set up the character display - _character.setup(1, 5, _characterIndex, 285, 11, 255); + _character.setup(1, 5, R2_GLOBALS._player._characterIndex, 285, 11, 255); add(&_character); break; default: diff --git a/engines/tsage/user_interface.h b/engines/tsage/user_interface.h index 94a2444e39..0fbfc5a00f 100644 --- a/engines/tsage/user_interface.h +++ b/engines/tsage/user_interface.h @@ -129,7 +129,6 @@ public: Common::Array<int> _itemList; Visage _cursorVisage; UIElement _character; - int _characterIndex; UIElements(); virtual Common::String getClassName() { return "UIElements"; } diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp index 77c84b281c..aeeebe6877 100644 --- a/engines/tucker/detection.cpp +++ b/engines/tucker/detection.cpp @@ -43,7 +43,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::FR_FRA, Common::kPlatformPC, Tucker::kGameFlagNoSubtitles, - GUIO1(GUIO_NONE) + GUIO0() }, { "tucker", @@ -52,7 +52,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, Tucker::kGameFlagEncodedData, - GUIO1(GUIO_NONE) + GUIO0() }, { "tucker", @@ -61,7 +61,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::ES_ESP, Common::kPlatformPC, Tucker::kGameFlagEncodedData, - GUIO1(GUIO_NONE) + GUIO0() }, { "tucker", @@ -70,7 +70,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::DE_DEU, Common::kPlatformPC, Tucker::kGameFlagEncodedData, - GUIO1(GUIO_NONE) + GUIO0() }, { "tucker", @@ -79,7 +79,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::PL_POL, Common::kPlatformPC, 0, - GUIO1(GUIO_NONE) + GUIO0() }, { "tucker", @@ -88,7 +88,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::CZ_CZE, Common::kPlatformPC, Tucker::kGameFlagEncodedData, - GUIO1(GUIO_NONE) + GUIO0() }, { "tucker", @@ -97,7 +97,7 @@ static const ADGameDescription tuckerGameDescriptions[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | Tucker::kGameFlagDemo, - GUIO1(GUIO_NONE) + GUIO0() }, AD_TABLE_END_MARKER }; @@ -109,7 +109,7 @@ static const ADGameDescription tuckerDemoGameDescription = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | Tucker::kGameFlagDemo | Tucker::kGameFlagIntroOnly, - GUIO1(GUIO_NONE) + GUIO0() }; class TuckerMetaEngine : public AdvancedMetaEngine { diff --git a/engines/tucker/locations.cpp b/engines/tucker/locations.cpp index 70b17e4191..49340e96ac 100644 --- a/engines/tucker/locations.cpp +++ b/engines/tucker/locations.cpp @@ -2185,6 +2185,7 @@ void TuckerEngine::updateSprite_locationNum48(int i) { _spritesTable[i].needUpdate = 1; state = 2; } else if (getRandomNumber() < 30000) { + // FIXME: This case is similar to the case below. _spritesTable[i].needUpdate = 0; state = 2; _spritesTable[i].updateDelay = 5; @@ -2858,6 +2859,7 @@ void TuckerEngine::updateSprite_locationNum66_1(int i) { _spritesTable[i].needUpdate = 1; state = 8; } else if (getRandomNumber() > 30000) { + // FIXME: This case is the same as the one below state = 10; _spritesTable[i].needUpdate = 0; } else { |