MADS: Implemented sound player logic and outer game loop

This commit is contained in:
Paul Gilbert 2014-02-23 21:34:20 -05:00
parent 8c9420a834
commit 8ee283d921
8 changed files with 261 additions and 22 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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<SpriteSlot> _spriteSlots;
Common::Array<int> _spriteList;
int _spriteListIndex;
/**
* Constructor
*/
Scene();
/**
* Initialise the sprite data
* @param flag Also reset sprite list
*/
void clearSprites(bool flag);
};
} // End of namespace MADS

View File

@ -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::poll() {
if (_asound)
_asound->poll();
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::noise() {
if (_driver)
_driver->noise();
}
} // End of namespace MADS

View File

@ -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<int> _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