From 1ede08405595cafe5792aa514a4bc3309602e40f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 May 2015 10:56:22 -0400 Subject: SHERLOCK: Implement more scene loading and setNPCPath --- engines/sherlock/objects.h | 2 +- engines/sherlock/people.cpp | 12 ++++++++++ engines/sherlock/people.h | 18 +++++++++++++-- engines/sherlock/scene.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++ engines/sherlock/scene.h | 18 +++++++++++++++ engines/sherlock/sound.cpp | 17 +++++++++++++-- engines/sherlock/sound.h | 7 +++++- 7 files changed, 121 insertions(+), 6 deletions(-) (limited to 'engines') diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 761c03d501..f1047628e4 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -107,7 +107,7 @@ struct WalkSequence { bool _horizFlip; Common::Array _sequences; - WalkSequence() : _vgsName(nullptr), _horizFlip(false) {} + WalkSequence() : _horizFlip(false) {} const byte &operator[](int idx) { return _sequences[idx]; } /** diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 638cbf662b..7879f29105 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -80,6 +80,18 @@ void WalkSequence::load(Common::SeekableReadStream &s) { /*----------------------------------------------------------------*/ +Person::Person() : Sprite(), _walkLoaded(false), _npcIndex(0), _npcStack(0), _npcPause(false) { + Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); +} + +void Person::clearNPC() { + Common::fill(&_npcPath[0], &_npcPath[MAX_NPC_PATH], 0); + _npcIndex = _npcStack = 0; + _npcName = ""; +} + +/*----------------------------------------------------------------*/ + People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) { _holmesOn = true; _oldWalkSequence = -1; diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index f3e7950400..a1968785db 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -34,7 +34,9 @@ enum PeopleId { PLAYER = 0, AL = 0, PEG = 1, - MAX_PLAYERS = 6 + MAX_PLAYERS = 6, + MAX_NPC = 5, + MAX_NPC_PATH = 200 }; // Animation sequence identifiers for characters @@ -66,11 +68,23 @@ public: bool _walkLoaded; Common::String _portrait; + // NPC related fields + int _npcIndex; + int _npcStack; + bool _npcPause; + byte _npcPath[MAX_NPC_PATH]; + Common::String _npcName; + // Rose Tattoo fields Common::String _walkVGSName; // Name of walk library person is using Common::Array _walkSequences; public: - Person() : Sprite(), _walkLoaded(false) {} + Person(); + + /** + * Clear the NPC related data + */ + void clearNPC(); }; class SherlockEngine; diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index e625dae7aa..0f679d732f 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -249,6 +249,7 @@ bool Scene::loadScene(const Common::String &filename) { SaveManager &saves = *_vm->_saves; Screen &screen = *_vm->_screen; Sound &sound = *_vm->_sound; + Talk &talk = *_vm->_talk; UserInterface &ui = *_vm->_ui; bool flag; @@ -264,6 +265,36 @@ bool Scene::loadScene(const Common::String &filename) { _cAnim.clear(); _sequenceBuffer.clear(); + // Check if it's a scene we need to keep trakc track of how many times we've visited + for (int idx = (int)_sceneTripCounters.size() - 1; idx >= 0; --idx) { + if (_sceneTripCounters[idx]._sceneNumber == _currentScene) { + if (--_sceneTripCounters[idx]._numTimes == 0) { + _vm->setFlags(_sceneTripCounters[idx]._flag); + _sceneTripCounters.remove_at(idx); + } + } + } + + if (IS_ROSE_TATTOO) { + // Set the NPC paths for the scene + setNPCPath(0); + + // Handle loading music for the scene + if (sound._midiDrvLoaded) { + if (talk._scriptMoreFlag != 1 && talk._scriptMoreFlag != 3) + sound._nextSongName = Common::String::format("res%02d", _currentScene); + + // If it's a new song, then start it up + if (sound._currentSongName.compareToIgnoreCase(sound._nextSongName)) { + if (sound.loadSong(sound._nextSongName)) { + sound.setMIDIVolume(sound._musicVolume); + if (sound._musicOn) + sound.startSong(); + } + } + } + } + // // Load the room resource file for the scene // @@ -1585,4 +1616,26 @@ void Scene::synchronize(Common::Serializer &s) { } } +void Scene::setNPCPath(int npc) { + People &people = *_vm->_people; + Talk &talk = *_vm->_talk; + + people[npc].clearNPC(); + people[npc]._name = Common::String::format("WATS%.2dA", _currentScene); + + // If we're in the middle of a script that will continue once the scene is loaded, + // return without calling the path script + if (talk._scriptMoreFlag == 1 || talk._scriptMoreFlag == 3) + return; + + // Turn off all the NPCs, since the talk script will turn them back on as needed + for (uint idx = 0; idx < MAX_NPC; ++idx) + people[idx + 1]._type = INVALID; + + // Call the path script for the scene + Common::String pathFile = Common::String::format("PATH%.2dA", _currentScene); + talk.talkTo(pathFile); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 0cbd775c56..b0b5624840 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -128,6 +128,16 @@ public: void load(Common::SeekableReadStream &s); }; +struct SceneTripEntry { + bool _flag; + int _sceneNumber; + int _numTimes; + + SceneTripEntry() : _flag(false), _sceneNumber(0), _numTimes(0) {} + SceneTripEntry(bool flag, int sceneNumber, int numTimes) : _flag(flag), + _sceneNumber(sceneNumber), _numTimes(numTimes) {} +}; + class Scene { private: SherlockEngine *_vm; @@ -212,6 +222,7 @@ public: bool _doBgAnimDone; int _tempFadeStyle; int _cAnimFramePause; + Common::Array _sceneTripCounters; public: Scene(SherlockEngine *vm); ~Scene(); @@ -291,6 +302,13 @@ public: * Synchronize the data for a savegame */ void synchronize(Common::Serializer &s); + + /** + * Resets the NPC path information when entering a new scene. + * @remarks The default talk file for the given NPC is set to WATS##A, where ## is + * the scene number being entered + */ + void setNPCPath(int npc); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index b8fe61dd29..279dd44157 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -58,6 +58,8 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _soundPlaying = false; _soundIsOn = &_soundPlaying; _curPriority = 0; + _midiDrvLoaded = false; + _musicVolume = 0; _soundOn = true; _musicOn = true; @@ -231,12 +233,19 @@ void Sound::stopMusic() { warning("TODO: Sound::stopMusic"); } -int Sound::loadSong(int songNumber) { +bool Sound::loadSong(int songNumber) { // TODO warning("TODO: Sound::loadSong"); - return 0; + return false; } +bool Sound::loadSong(const Common::String &name) { + // TODO + warning("TODO: Sound::loadSong"); + return false; +} + + void Sound::startSong() { // TODO warning("TODO: Sound::startSong"); @@ -264,5 +273,9 @@ void Sound::freeDigiSound() { _soundPlaying = false; } +void Sound::setMIDIVolume(int volume) { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h index 689e615a36..06450ff50d 100644 --- a/engines/sherlock/sound.h +++ b/engines/sherlock/sound.h @@ -58,6 +58,9 @@ public: bool _soundPlaying; bool *_soundIsOn; byte *_digiBuf; + bool _midiDrvLoaded; + Common::String _currentSongName, _nextSongName; + int _musicVolume; public: Sound(SherlockEngine *vm, Audio::Mixer *mixer); @@ -94,7 +97,8 @@ public: /** * Load a specified song */ - int loadSong(int songNumber); + bool loadSong(int songNumber); + bool loadSong(const Common::String &name); /** * Start playing a song @@ -119,6 +123,7 @@ public: void stopSndFuncPtr(int v1, int v2); void waitTimerRoland(uint time); void freeDigiSound(); + void setMIDIVolume(int volume); }; } // End of namespace Sherlock -- cgit v1.2.3