aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorJohannes Schickel2014-06-04 18:51:15 +0200
committerJohannes Schickel2014-06-04 18:51:15 +0200
commiteeed91c42025329bb06cc99eb08e0ce23ab828e4 (patch)
treee28a995ced70d112a515a4ed3da9502113d42c5c /engines/scumm
parentf63d00d4c6ab7a037aa1d7103c6de7e40d6e803e (diff)
downloadscummvm-rg350-eeed91c42025329bb06cc99eb08e0ce23ab828e4.tar.gz
scummvm-rg350-eeed91c42025329bb06cc99eb08e0ce23ab828e4.tar.bz2
scummvm-rg350-eeed91c42025329bb06cc99eb08e0ce23ab828e4.zip
SCUMM: Implement simple seeking in AD player.
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/players/player_ad.cpp33
-rw-r--r--engines/scumm/players/player_ad.h3
2 files changed, 36 insertions, 0 deletions
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index f7f5bb3e1c..08519b42cf 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -77,6 +77,7 @@ Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
memset(_voiceChannels, 0, sizeof(_voiceChannels));
_musicVolume = _sfxVolume = 255;
+ _isSeeking = false;
}
Player_AD::~Player_AD() {
@@ -329,6 +330,7 @@ void Player_AD::writeReg(int r, int v) {
// Since AdLib's lowest volume level does not imply that the sound is
// completely silent we ignore key on in such a case.
+ // We also ignore key on for music whenever we do seeking.
if (r >= 0xB0 && r <= 0xB8) {
const int channel = r - 0xB0;
bool mute = false;
@@ -339,6 +341,8 @@ void Player_AD::writeReg(int r, int v) {
} else {
if (!_musicVolume) {
mute = true;
+ } else {
+ mute = _isSeeking;
}
}
@@ -650,6 +654,35 @@ void Player_AD::freeVoiceChannel(uint channel) {
vChannel.frequency = 0;
}
+void Player_AD::musicSeekTo(const uint position) {
+ // This method is actually dangerous to use and should only be used for
+ // loading save games because it does not set up anything like the engine
+ // music timer or similar.
+ _isSeeking = true;
+
+ // Seek until the given position.
+ while (_curOffset != position) {
+ if (parseCommand()) {
+ // We encountered an EOT command. This should not happen unless
+ // we try to seek to an illegal position. In this case just abort
+ // seeking.
+ ::debugC(3, DEBUG_SOUND, "AD illegal seek to %u", position);
+ break;
+ }
+ parseVLQ();
+ }
+
+ _isSeeking = false;
+
+ // Turn on all notes.
+ for (int i = 0; i < ARRAYSIZE(_voiceChannels); ++i) {
+ if (_voiceChannels[i].lastEvent != 0) {
+ const int reg = 0xB0 + i;
+ writeReg(reg, readReg(reg));
+ }
+ }
+}
+
const uint Player_AD::_noteFrequencies[12] = {
0x200, 0x21E, 0x23F, 0x261,
0x285, 0x2AB, 0x2D4, 0x300,
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
index 3807ebc7e0..f5e7ecccbc 100644
--- a/engines/scumm/players/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -133,6 +133,9 @@ private:
} _voiceChannels[9];
void freeVoiceChannel(uint channel);
+ void musicSeekTo(const uint position);
+ bool _isSeeking;
+
uint _mdvdrState;
uint _curOffset;