From 8ee283d921ec88bad61469e136a31aef0ff5b9ca Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 23 Feb 2014 21:34:20 -0500 Subject: MADS: Implemented sound player logic and outer game loop --- engines/mads/game.cpp | 26 +++++++++++- engines/mads/game.h | 12 ++++-- engines/mads/nebular/game_nebular.h | 4 +- engines/mads/palette.h | 7 ++++ engines/mads/scene.cpp | 40 +++++++++++++++++++ engines/mads/scene.h | 53 +++++++++++++++++++++++- engines/mads/sound.cpp | 80 ++++++++++++++++++++++++++++++++----- engines/mads/sound.h | 61 ++++++++++++++++++++++++++-- 8 files changed, 261 insertions(+), 22 deletions(-) diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index aa0d1dcac6..3acbd41ba6 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -43,6 +43,7 @@ Game::Game(MADSEngine *vm): _vm(vm), _surface(nullptr) { _saveSlot = -1; _statusFlag = 0; _sectionHandler = nullptr; + _v1 = _v2 = 0; } Game::~Game() { @@ -96,9 +97,30 @@ void Game::run() { } void Game::gameLoop() { - setSectionHandler(); + while (!_vm->shouldQuit() && _statusFlag) { + setSectionHandler(); + _sectionHandler->preLoadSection(); + initSection(_scene._sectionNum); + _sectionHandler->postLoadSection(); + + _scene.clearSprites(true); + + if (_scene._sectionNum == _scene._sectionNum2) { + sectionLoop(); + } + + // TODO: Extra reset methods + _vm->_events->resetCursor(); + _vm->_events->freeCursors(); + _vm->_sound->closeDriver(); + + } + + _vm->_palette->close(); +} + +void Game::sectionLoop() { - // TODO: More stuff } void Game::initSection(int sectionNumber) { diff --git a/engines/mads/game.h b/engines/mads/game.h index 9dd7ca0ace..4a8daed6ca 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -77,9 +77,9 @@ protected: public: SectionHandler(MADSEngine *vm): _vm(vm) {} - virtual void loadSection() = 0; + virtual void preLoadSection() = 0; virtual void sectionPtr2() = 0; - virtual void sectionPtr3() = 0; + virtual void postLoadSection() = 0; }; class Game { @@ -88,6 +88,11 @@ private: * Main game loop */ void gameLoop(); + + /** + * Inner game loop for executing gameplay within a game section + */ + void sectionLoop(); protected: MADSEngine *_vm; MSurface *_surface; @@ -100,8 +105,9 @@ protected: int _saveSlot; int _statusFlag; DialogId _pendingDialog; - SectionHandler *_sectionHandler; + int _v1; + int _v2; /** * Constructor diff --git a/engines/mads/nebular/game_nebular.h b/engines/mads/nebular/game_nebular.h index b7f47aa9cd..31bd4ae2b2 100644 --- a/engines/mads/nebular/game_nebular.h +++ b/engines/mads/nebular/game_nebular.h @@ -50,9 +50,9 @@ public: Section1Handler(MADSEngine *vm): SectionHandler(vm) {} // TODO: Properly implement handler methods - virtual void loadSection() {} + virtual void preLoadSection() {} virtual void sectionPtr2() {} - virtual void sectionPtr3() {} + virtual void postLoadSection() {} }; // TODO: Properly implement handler classes diff --git a/engines/mads/palette.h b/engines/mads/palette.h index 9a4e4518f7..b5588fecd6 100644 --- a/engines/mads/palette.h +++ b/engines/mads/palette.h @@ -178,6 +178,13 @@ public: */ void setLowRange(); + /** + * Set up the palette as the game ends + */ + void close() { + warning("TODO: Palette::close"); + } + // Color indexes uint8 BLACK; uint8 BLUE; diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index f6bbf32e40..cf7ba6c674 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -34,4 +34,44 @@ Scene::Scene() { _currentSceneId = 0; } +void Scene::clearSprites(bool flag) { + for (int i = 0; i < TEXT_DISPLAY_COUNT; ++i) + _textDisplay[i]._active = false; + + if (flag) + _spriteList.clear(); + + _spriteSlots.clear(); + _spriteSlots.push_back(SpriteSlot(ST_FULL_SCREEN_REFRESH, -1)); +} + +/*------------------------------------------------------------------------*/ + +SpriteSlot::SpriteSlot() { + _spriteType = ST_NONE; + _seqIndex = 0; + _spriteListIndex = 0; + _frameNumber = 0; + _depth = 0; + _scale = 0; +} + +SpriteSlot::SpriteSlot(SpriteType type, int seqIndex) { + _spriteType = type; + _seqIndex = seqIndex; + _spriteListIndex = 0; + _frameNumber = 0; + _depth = 0; + _scale = 0; +} + +/*------------------------------------------------------------------------*/ + +TextDisplay::TextDisplay() { + _active = false; + _spacing = 0; + _expire = 0; + _col1 = _col2 = 0; +} + } // End of namespace MADS diff --git a/engines/mads/scene.h b/engines/mads/scene.h index a5359a9895..e2afd081b3 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -24,9 +24,47 @@ #define MADS_SCENE_H #include "common/scummsys.h" +#include "common/array.h" +#include "common/rect.h" namespace MADS { +enum SpriteType { + ST_NONE = 0, ST_FOREGROUND = 1, ST_BACKGROUND = -4, + ST_FULL_SCREEN_REFRESH = -2, ST_EXPIRED = -1 +}; + +class SpriteSlot { +public: + SpriteType _spriteType; + int _seqIndex; + int _spriteListIndex; + int _frameNumber; + Common::Point _position; + int _depth; + int _scale; +public: + SpriteSlot(); + SpriteSlot(SpriteType type, int seqIndex); +}; + +class TextDisplay { +public: + bool _active; + int _spacing; + Common::Rect _bounds; + int _expire; + int _col1; + int _col2; + Common::String _fontName; + Common::String _msg; + + TextDisplay(); +}; + +#define SPRITE_COUNT 50 +#define TEXT_DISPLAY_COUNT 40 + class Scene { public: int _priorSectionNum; @@ -35,8 +73,21 @@ public: int _priorSceneId; int _nextSceneId; int _currentSceneId; - + TextDisplay _textDisplay[TEXT_DISPLAY_COUNT]; + Common::Array _spriteSlots; + Common::Array _spriteList; + int _spriteListIndex; + + /** + * Constructor + */ Scene(); + + /** + * Initialise the sprite data + * @param flag Also reset sprite list + */ + void clearSprites(bool flag); }; } // End of namespace MADS diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp index 46ba997198..8608abf4e7 100644 --- a/engines/mads/sound.cpp +++ b/engines/mads/sound.cpp @@ -24,29 +24,89 @@ #include "audio/decoders/raw.h" #include "common/memstream.h" #include "mads/sound.h" +#include "mads/mads.h" +#include "mads/nebular/sound_nebular.h" namespace MADS { SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) { _vm = vm; _mixer = mixer; - _asound = nullptr; + _driver = nullptr; + _pollSoundEnabled = false; + _soundPollFlag = false; + _newSoundsPaused = false; } SoundManager::~SoundManager() { - delete _asound; + delete _driver; } -void SoundManager::test() { - _asound = new Nebular::ASound1(_mixer); - _asound->command(5); - _asound->command(28); - _asound->command(19); +void SoundManager::init(int sectionNumber) { + assert(sectionNumber > 0 && sectionNumber < 10); + + switch (_vm->getGameID()) { + case GType_RexNebular: + // TODO: Other Rex Adlib section drivers + assert(sectionNumber == 1); + _driver = new Nebular::ASound1(_mixer); + break; + + default: + error("Unknown game"); + } +} + +void SoundManager::closeDriver() { + if (_driver) { + command(0); + setEnabled(false); + stop(); + + removeDriver(); + } +} + +void SoundManager::removeDriver() { + delete _driver; + _driver = nullptr; +} + +void SoundManager::setEnabled(bool flag) { + _pollSoundEnabled = flag; + _soundPollFlag = false; +} + +void SoundManager::queueNewCommands() { + _newSoundsPaused = true; +} + +void SoundManager::startQueuedCommands() { + _newSoundsPaused = false; + + while (!_queuedCommands.empty()) { + int commandId = _queuedCommands.front(); + command(commandId); + } +} + +void SoundManager::command(int commandId, int param) { + if (_newSoundsPaused) { + if (_queuedCommands.size() < 8) + _queuedCommands.push(commandId); + } else if (_driver) { + _driver->command(commandId, param); + } +} + +void SoundManager::stop() { + if (_driver) + _driver->stop(); } -void SoundManager::poll() { - if (_asound) - _asound->poll(); +void SoundManager::noise() { + if (_driver) + _driver->noise(); } } // End of namespace MADS diff --git a/engines/mads/sound.h b/engines/mads/sound.h index 7a9a4ef29b..51213f0e4e 100644 --- a/engines/mads/sound.h +++ b/engines/mads/sound.h @@ -24,6 +24,7 @@ #define MADS_SOUND_H #include "common/scummsys.h" +#include "common/queue.h" #include "audio/audiostream.h" #include "audio/mixer.h" #include "mads/nebular/sound_nebular.h" @@ -36,13 +37,65 @@ class SoundManager { private: MADSEngine *_vm; Audio::Mixer *_mixer; - Nebular::ASound *_asound; + Nebular::ASound *_driver; + bool _pollSoundEnabled; + bool _soundPollFlag; + bool _newSoundsPaused; + Common::Queue _queuedCommands; public: SoundManager(MADSEngine *vm, Audio::Mixer *mixer); ~SoundManager(); - - void test(); - void poll(); + + /** + * Initialises the sound driver for a given game section + */ + void init(int sectionNumber); + + /** + * Stop any currently active sound and remove the driver + */ + void closeDriver(); + + /** + * Remove the driver + */ + void removeDriver(); + + /** + * Sets the enabled status of the sound + * @flag True if sound should be enabled + */ + void setEnabled(bool flag); + + /** + * Temporarily pause the playback of any new sound commands + */ + void queueNewCommands(); + + /** + * Stop queueing sound commands, and execute any previously queued ones + */ + void startQueuedCommands(); + + //@{ + /** + * Executes a command on the sound driver + * @param commandid Command Id to execute + * @param param Optional paramater specific to a few commands + */ + void command(int commandId, int param = 0); + + /** + * Stops any currently playing sound + */ + void stop(); + + /** + * Noise + * Some sort of random noise generation? + */ + void noise(); + //@} }; } // End of namespace MADS -- cgit v1.2.3