aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2016-09-14 23:04:28 -0400
committerPaul Gilbert2016-09-14 23:04:28 -0400
commit2042133b448a06c67281dabc5f74023a0e6ffa18 (patch)
tree1b51a9e072a48e9c296205c8cd30fa6347d32832
parenta06d1b7efe0066d17fdc7d30e9c8983fcd3f8094 (diff)
downloadscummvm-rg350-2042133b448a06c67281dabc5f74023a0e6ffa18.tar.gz
scummvm-rg350-2042133b448a06c67281dabc5f74023a0e6ffa18.tar.bz2
scummvm-rg350-2042133b448a06c67281dabc5f74023a0e6ffa18.zip
XEEN: Added music playback interface methods
-rw-r--r--engines/xeen/music.cpp98
-rw-r--r--engines/xeen/music.h54
2 files changed, 138 insertions, 14 deletions
diff --git a/engines/xeen/music.cpp b/engines/xeen/music.cpp
index 415b413ff8..ae3d5aba83 100644
--- a/engines/xeen/music.cpp
+++ b/engines/xeen/music.cpp
@@ -178,27 +178,42 @@ void MusicDriver::playFX(uint effectId, const byte *data) {
}
}
+void MusicDriver::playSong(const byte *data) {
+ _musDataPtr = data;
+ _musSubroutines.clear();
+ _musCountdownTimer = 0;
+ _field1E = true;
+}
+
+int MusicDriver::songCommand(uint commandId, byte volume) {
+ if (RESTART_MUSIC == 1) {
+ _musDataPtr = nullptr;
+ _musSubroutines.clear();
+ }
+
+ return 0;
+}
const CommandFn MusicDriver::MUSIC_COMMANDS[16] = {
- &MusicDriver::musCallSubroutine, &MusicDriver::musSetCountdown,
+ &MusicDriver::musCallSubroutine, &MusicDriver::musSetCountdown,
&MusicDriver::musSetInstrument, &MusicDriver::cmdNoOperation,
&MusicDriver::musSetPitchWheel, &MusicDriver::musSkipWord,
&MusicDriver::musSetPanning, &MusicDriver::cmdNoOperation,
&MusicDriver::musFade, &MusicDriver::musStartNote,
&MusicDriver::musSetVolume, &MusicDriver::musInjectMidi,
&MusicDriver::musPlayInstrument, &MusicDriver::cmdFreezeFrequency,
- &MusicDriver::cmdChangeFrequency, &MusicDriver::musEndSubroutine
+ &MusicDriver::cmdChangeFrequency, &MusicDriver::musEndSubroutine
};
const CommandFn MusicDriver::FX_COMMANDS[16] = {
- &MusicDriver::fxCallSubroutine, &MusicDriver::fxSetCountdown,
- &MusicDriver::fxSetInstrument, &MusicDriver::fxSetVolume,
- &MusicDriver::fxMidiReset, &MusicDriver::fxMidiDword,
- &MusicDriver::fxSetPanning, &MusicDriver::fxChannelOff,
- &MusicDriver::fxFade, &MusicDriver::fxStartNote,
- &MusicDriver::cmdNoOperation, &MusicDriver::fxInjectMidi,
- &MusicDriver::fxPlayInstrument, &MusicDriver::cmdFreezeFrequency,
- &MusicDriver::cmdChangeFrequency, &MusicDriver::fxEndSubroutine
+ &MusicDriver::fxCallSubroutine, &MusicDriver::fxSetCountdown,
+ &MusicDriver::fxSetInstrument, &MusicDriver::fxSetVolume,
+ &MusicDriver::fxMidiReset, &MusicDriver::fxMidiDword,
+ &MusicDriver::fxSetPanning, &MusicDriver::fxChannelOff,
+ &MusicDriver::fxFade, &MusicDriver::fxStartNote,
+ &MusicDriver::cmdNoOperation, &MusicDriver::fxInjectMidi,
+ &MusicDriver::fxPlayInstrument, &MusicDriver::cmdFreezeFrequency,
+ &MusicDriver::cmdChangeFrequency, &MusicDriver::fxEndSubroutine
};
/*------------------------------------------------------------------------*/
@@ -239,6 +254,36 @@ void AdlibMusicDriver::playFX(uint effectId, const byte *data) {
MusicDriver::playFX(effectId, data);
}
+void AdlibMusicDriver::playSong(const byte *data) {
+ Common::StackLock slock(_driverMutex);
+ MusicDriver::playSong(data);
+ _field180 = 0;
+}
+
+int AdlibMusicDriver::songCommand(uint commandId, byte volume) {
+ Common::StackLock slock(_driverMutex);
+
+ if (commandId == STOP_MUSIC) {
+ _field1E = 0;
+ _field180 = 0;
+ resetFrequencies();
+ } else if (commandId == RESTART_MUSIC) {
+ _field180 = 0;
+ _field1E = true;
+ } else if (commandId < 0x100) {
+ if (_field1E) {
+ _field180 = commandId;
+ _field182 = 63;
+ }
+ } else if (commandId == SET_VOLUME) {
+ _volume = volume;
+ } else if (commandId == GET_STATUS) {
+ return _field180;
+ }
+
+ return 0;
+}
+
void AdlibMusicDriver::write(int reg, int val) {
_queue.push(RegisterValue(reg, val));
}
@@ -531,7 +576,8 @@ const uint AdlibMusicDriver::WAVEFORMS[24] = {
/*------------------------------------------------------------------------*/
-Music::Music(Audio::Mixer *mixer) : _mixer(mixer), _musicDriver(nullptr) {
+Music::Music(Audio::Mixer *mixer) : _mixer(mixer), _musicDriver(nullptr),
+ _songData(nullptr) {
_mixer = mixer;
_musicDriver = new AdlibMusicDriver();
loadEffectsData();
@@ -540,6 +586,7 @@ Music::Music(Audio::Mixer *mixer) : _mixer(mixer), _musicDriver(nullptr) {
Music::~Music() {
delete _musicDriver;
delete[] _effectsData;
+ delete[] _songData;
}
void Music::loadEffectsData() {
@@ -563,11 +610,38 @@ void Music::loadEffectsData() {
_effectsOffsets[idx] = READ_LE_UINT16(&effectsData[EFFECTS_OFFSET + idx * 2]);
}
-void Music::playEffect(uint effectId) {
+void Music::playFX(uint effectId) {
if (effectId < _effectsOffsets.size()) {
const byte *dataP = &_effectsData[_effectsOffsets[effectId]];
_musicDriver->playFX(effectId, dataP);
}
}
+int Music::songCommand(uint commandId, byte volume) {
+ int result = _musicDriver->songCommand(commandId, volume);
+ if (commandId == STOP_MUSIC) {
+ delete[] _songData;
+ _songData = nullptr;
+ }
+
+ return result;
+}
+
+void Music::playSong(Common::SeekableReadStream &stream) {
+ if (_songData)
+ stopMusic();
+
+ byte *songData = new byte[stream.size()];
+ stream.seek(0);
+ stream.read(songData, stream.size());
+ _songData = songData;
+
+ _musicDriver->playSong(_songData);
+}
+
+void Music::playSong(const Common::String &name) {
+ File f(name);
+ playSong(f);
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/music.h b/engines/xeen/music.h
index e6cfbbade5..a715471088 100644
--- a/engines/xeen/music.h
+++ b/engines/xeen/music.h
@@ -38,6 +38,11 @@ namespace OPL {
namespace Xeen {
+enum MusicCommand {
+ STOP_MUSIC = 0, RESTART_MUSIC = 1, SET_VOLUME = 0x100,
+ GET_STATUS = 0xFFE0
+};
+
class MusicDriver;
typedef bool (MusicDriver::*CommandFn)(const byte *&srcP, byte param);
@@ -149,6 +154,16 @@ public:
* Starts an special effect playing
*/
virtual void playFX(uint effectId, const byte *data);
+
+ /**
+ * Plays a song
+ */
+ virtual void playSong(const byte *data);
+
+ /**
+ * Executes special music command
+ */
+ virtual int songCommand(uint commandId, byte volume = 0);
};
class AdlibMusicDriver : public MusicDriver {
@@ -265,14 +280,24 @@ public:
* Starts an special effect playing
*/
virtual void playFX(uint effectId, const byte *data);
-};
+ /**
+ * Plays a song
+ */
+ virtual void playSong(const byte *data);
+
+ /**
+ * Executes special music command
+ */
+ virtual int songCommand(uint commandId, byte volume = 0);
+};
class Music {
private:
MusicDriver *_musicDriver;
const byte *_effectsData;
Common::Array<uint16> _effectsOffsets;
+ const byte *_songData;
private:
/**
* Loads effects data that was embedded in the music driver
@@ -293,7 +318,32 @@ public:
/**
* Starts an effect playing
*/
- void playEffect(uint effectId);
+ void playFX(uint effectId);
+
+ /**
+ * Executes special music command
+ */
+ int songCommand(uint commandId, byte volume = 0);
+
+ /**
+ * Stops any currently playing music
+ */
+ void stopMusic() { songCommand(STOP_MUSIC); }
+
+ /**
+ * Restart the music
+ */
+ void restartMusic() { songCommand(RESTART_MUSIC); }
+
+ /**
+ * Plays a song
+ */
+ void playSong(Common::SeekableReadStream &stream);
+
+ /**
+ * Plays a song
+ */
+ void playSong(const Common::String &name);
};
} // End of namespace Xeen