[Scummvm-cvs-logs] scummvm master -> 4069f63eb0caf668e03636df1c697e3fd0724414
lordhoto
lordhoto at gmail.com
Wed Jun 4 18:53:50 CEST 2014
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
727cb7661c SCUMM: Fix typo in AD code.
051034f811 SCUMM: Simplify voice channel allocation in AD code.
46b30f94c3 SCUMM: Only forward declare Serializer in music.h.
f63d00d4c6 SCUMM: Slightly refactor music playback in AD player.
eeed91c420 SCUMM: Implement simple seeking in AD player.
4069f63eb0 SCUMM: Save/load music/sfx data in AD player.
Commit: 727cb7661cb67098541eed074ab8c74d6c3f5b4f
https://github.com/scummvm/scummvm/commit/727cb7661cb67098541eed074ab8c74d6c3f5b4f
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2014-06-04T18:51:15+02:00
Commit Message:
SCUMM: Fix typo in AD code.
Changed paths:
engines/scumm/players/player_ad.cpp
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index 3b86c56..3bbb429 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -324,7 +324,7 @@ void Player_AD::writeReg(int r, int v) {
int vol = 0x3F - (v & 0x3F);
vol = vol * scale / Audio::Mixer::kMaxChannelVolume;
- v &= 0xA0;
+ v &= 0xC0;
v |= (0x3F - vol);
}
}
Commit: 051034f811c2e08a9473d9fe42f9183eb62293f3
https://github.com/scummvm/scummvm/commit/051034f811c2e08a9473d9fe42f9183eb62293f3
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2014-06-04T18:51:15+02:00
Commit Message:
SCUMM: Simplify voice channel allocation in AD code.
Changed paths:
engines/scumm/players/player_ad.cpp
engines/scumm/players/player_ad.h
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index 3bbb429..882e5f5 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -74,9 +74,6 @@ Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
_numHWChannels = ARRAYSIZE(_hwChannels);
memset(_voiceChannels, 0, sizeof(_voiceChannels));
- for (int i = 0; i < ARRAYSIZE(_voiceChannels); ++i) {
- _voiceChannels[i].hardwareChannel = -1;
- }
_musicVolume = _sfxVolume = 255;
}
@@ -510,9 +507,11 @@ void Player_AD::updateMusic() {
if (_musicData[instrOffset + 13] != 0) {
setupRhythm(_musicData[instrOffset + 13], instrOffset);
} else {
- int channel = allocateVoiceChannel();
+ // Priority 256 makes sure we always prefer music
+ // channels over SFX channels.
+ int channel = allocateHWChannel(256);
if (channel != -1) {
- setupChannel(_voiceChannels[channel].hardwareChannel, _musicData + instrOffset);
+ setupChannel(channel, _musicData + instrOffset);
_voiceChannels[channel].lastEvent = command + 0x90;
_voiceChannels[channel].frequency = _musicData[_curOffset];
setupFrequency(channel, _musicData[_curOffset]);
@@ -576,8 +575,7 @@ void Player_AD::updateMusic() {
}
void Player_AD::noteOff(uint channel) {
- VoiceChannel &vChannel = _voiceChannels[channel];
- writeReg(0xB0 + vChannel.hardwareChannel, vChannel.b0Reg & 0xDF);
+ writeReg(0xB0 + channel, _voiceChannels[channel].b0Reg & 0xDF);
freeVoiceChannel(channel);
}
@@ -593,14 +591,13 @@ void Player_AD::setupFrequency(uint channel, int8 frequency) {
++octave;
}
- VoiceChannel &vChannel = _voiceChannels[channel];
const uint noteFrequency = _noteFrequencies[frequency];
octave <<= 2;
octave |= noteFrequency >> 8;
octave |= 0x20;
- writeReg(0xA0 + vChannel.hardwareChannel, noteFrequency & 0xFF);
- vChannel.b0Reg = octave;
- writeReg(0xB0 + vChannel.hardwareChannel, octave);
+ writeReg(0xA0 + channel, noteFrequency & 0xFF);
+ _voiceChannels[channel].b0Reg = octave;
+ writeReg(0xB0 + channel, octave);
}
void Player_AD::setupRhythm(uint rhythmInstr, uint instrOffset) {
@@ -621,29 +618,11 @@ void Player_AD::setupRhythm(uint rhythmInstr, uint instrOffset) {
}
}
-int Player_AD::allocateVoiceChannel() {
- for (int i = 0; i < ARRAYSIZE(_voiceChannels); ++i) {
- if (!_voiceChannels[i].lastEvent) {
- // 256 makes sure it's a higher prority than any SFX
- _voiceChannels[i].hardwareChannel = allocateHWChannel(256);
- if (_voiceChannels[i].hardwareChannel != -1) {
- return i;
- } else {
- // No free HW channels => cancel
- return -1;
- }
- }
- }
-
- return -1;
-}
-
void Player_AD::freeVoiceChannel(uint channel) {
VoiceChannel &vChannel = _voiceChannels[channel];
- assert(vChannel.hardwareChannel != -1);
+ assert(vChannel.lastEvent);
- freeHWChannel(vChannel.hardwareChannel);
- vChannel.hardwareChannel = -1;
+ freeHWChannel(channel);
vChannel.lastEvent = 0;
vChannel.b0Reg = 0;
vChannel.frequency = 0;
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
index 0a0ba8a..d061c1a 100644
--- a/engines/scumm/players/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -128,10 +128,7 @@ private:
uint lastEvent;
uint frequency;
uint b0Reg;
-
- int hardwareChannel;
} _voiceChannels[9];
- int allocateVoiceChannel();
void freeVoiceChannel(uint channel);
uint _mdvdrState;
Commit: 46b30f94c3cdbf583f5f98e8f4b5341819c9d372
https://github.com/scummvm/scummvm/commit/46b30f94c3cdbf583f5f98e8f4b5341819c9d372
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2014-06-04T18:51:15+02:00
Commit Message:
SCUMM: Only forward declare Serializer in music.h.
Changed paths:
engines/scumm/music.h
engines/scumm/players/player_ad.cpp
diff --git a/engines/scumm/music.h b/engines/scumm/music.h
index c5762ed..e170647 100644
--- a/engines/scumm/music.h
+++ b/engines/scumm/music.h
@@ -24,10 +24,11 @@
#define SCUMM_MUSIC_H
#include "common/scummsys.h"
-#include "engines/scumm/saveload.h"
namespace Scumm {
+class Serializer;
+
/**
* Pure virtual base class for the various music/sound engines used in Scumm
* games. In particular, the iMuse code provides a subclass of this. There are
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index 882e5f5..5abeaf2 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -24,6 +24,7 @@
#include "scumm/imuse/imuse.h"
#include "scumm/scumm.h"
#include "scumm/resource.h"
+#include "scumm/saveload.h"
#include "audio/fmopl.h"
Commit: f63d00d4c6ab7a037aa1d7103c6de7e40d6e803e
https://github.com/scummvm/scummvm/commit/f63d00d4c6ab7a037aa1d7103c6de7e40d6e803e
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2014-06-04T18:51:15+02:00
Commit Message:
SCUMM: Slightly refactor music playback in AD player.
Changed paths:
engines/scumm/players/player_ad.cpp
engines/scumm/players/player_ad.h
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index 5abeaf2..f7f5bb3 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -463,116 +463,137 @@ void Player_AD::updateMusic() {
}
while (true) {
- uint command = _musicData[_curOffset++];
- if (command == 0xFF) {
- // META EVENT
- // Get the command number.
- command = _musicData[_curOffset++];
- if (command == 47) {
- // End of track
- if (_loopFlag) {
- // In case the track is looping jump to the start.
- _curOffset = _musicLoopStart;
- _nextEventTimer = 0;
- continue;
- } else {
- // Otherwise completely stop playback.
- stopMusic();
- }
+ if (parseCommand()) {
+ // We received an EOT command. In case there's no music playing
+ // we know there was no looping enabled. Thus, we stop further
+ // handling. Otherwise we will just continue parsing. It is
+ // important to note that we need to parse a command directly
+ // at the new position, i.e. there is no time value we need to
+ // parse.
+ if (_soundPlaying == -1) {
return;
- } else if (command == 88) {
- // This is proposedly a debug information insertion. The CMS
- // player code handles this differently, but is still using
- // the same resources...
- _curOffset += 5;
- } else if (command == 81) {
- // Change tempo. This is used exclusively in Loom.
- const uint timing = _musicData[_curOffset + 2] | (_musicData[_curOffset + 1] << 8);
- _musicTicks = 0x73000 / timing;
- command = _musicData[_curOffset++];
- _curOffset += command;
} else {
- // In case an unknown meta event occurs just skip over the
- // data by using the length supplied.
- command = _musicData[_curOffset++];
- _curOffset += command;
+ continue;
}
- } else {
- if (command >= 0x90) {
- // NOTE ON
- // Extract the channel number and save it in command.
- command -= 0x90;
+ }
- const uint instrOffset = _instrumentOffset[command];
- if (instrOffset) {
- if (_musicData[instrOffset + 13] != 0) {
- setupRhythm(_musicData[instrOffset + 13], instrOffset);
- } else {
- // Priority 256 makes sure we always prefer music
- // channels over SFX channels.
- int channel = allocateHWChannel(256);
- if (channel != -1) {
- setupChannel(channel, _musicData + instrOffset);
- _voiceChannels[channel].lastEvent = command + 0x90;
- _voiceChannels[channel].frequency = _musicData[_curOffset];
- setupFrequency(channel, _musicData[_curOffset]);
- }
- }
- }
+ // In case there is a delay till the next event stop handling.
+ if (_musicData[_curOffset] != 0) {
+ break;
+ }
+ ++_curOffset;
+ }
+
+ _nextEventTimer = parseVLQ();
+ _nextEventTimer >>= (_vm->_game.id == GID_LOOM) ? 2 : 1;
+ if (!_nextEventTimer) {
+ _nextEventTimer = 1;
+ }
+}
+
+bool Player_AD::parseCommand() {
+ uint command = _musicData[_curOffset++];
+ if (command == 0xFF) {
+ // META EVENT
+ // Get the command number.
+ command = _musicData[_curOffset++];
+ if (command == 47) {
+ // End of track
+ if (_loopFlag) {
+ // In case the track is looping jump to the start.
+ _curOffset = _musicLoopStart;
+ _nextEventTimer = 0;
} else {
- // NOTE OFF
- const uint note = _musicData[_curOffset];
- command += 0x10;
-
- // Find the output channel which plays the note.
- uint channel = 0xFF;
- for (int i = 0; i < ARRAYSIZE(_voiceChannels); ++i) {
- if (_voiceChannels[i].frequency == note && _voiceChannels[i].lastEvent == command) {
- channel = i;
- break;
+ // Otherwise completely stop playback.
+ stopMusic();
+ }
+ return true;
+ } else if (command == 88) {
+ // This is proposedly a debug information insertion. The CMS
+ // player code handles this differently, but is still using
+ // the same resources...
+ _curOffset += 5;
+ } else if (command == 81) {
+ // Change tempo. This is used exclusively in Loom.
+ const uint timing = _musicData[_curOffset + 2] | (_musicData[_curOffset + 1] << 8);
+ _musicTicks = 0x73000 / timing;
+ command = _musicData[_curOffset++];
+ _curOffset += command;
+ } else {
+ // In case an unknown meta event occurs just skip over the
+ // data by using the length supplied.
+ command = _musicData[_curOffset++];
+ _curOffset += command;
+ }
+ } else {
+ if (command >= 0x90) {
+ // NOTE ON
+ // Extract the channel number and save it in command.
+ command -= 0x90;
+
+ const uint instrOffset = _instrumentOffset[command];
+ if (instrOffset) {
+ if (_musicData[instrOffset + 13] != 0) {
+ setupRhythm(_musicData[instrOffset + 13], instrOffset);
+ } else {
+ // Priority 256 makes sure we always prefer music
+ // channels over SFX channels.
+ int channel = allocateHWChannel(256);
+ if (channel != -1) {
+ setupChannel(channel, _musicData + instrOffset);
+ _voiceChannels[channel].lastEvent = command + 0x90;
+ _voiceChannels[channel].frequency = _musicData[_curOffset];
+ setupFrequency(channel, _musicData[_curOffset]);
}
}
+ }
+ } else {
+ // NOTE OFF
+ const uint note = _musicData[_curOffset];
+ command += 0x10;
+
+ // Find the output channel which plays the note.
+ uint channel = 0xFF;
+ for (int i = 0; i < ARRAYSIZE(_voiceChannels); ++i) {
+ if (_voiceChannels[i].frequency == note && _voiceChannels[i].lastEvent == command) {
+ channel = i;
+ break;
+ }
+ }
- if (channel != 0xFF) {
- // In case a output channel playing the note was found,
- // stop it.
- noteOff(channel);
- } else {
- // In case there is no such note this will disable the
- // rhythm instrument played on the channel.
- command -= 0x90;
- const uint instrOffset = _instrumentOffset[command];
- if (instrOffset && _musicData[instrOffset + 13] != 0) {
- const uint rhythmInstr = _musicData[instrOffset + 13];
- if (rhythmInstr < 6) {
- _mdvdrState &= _mdvdrTable[rhythmInstr] ^ 0xFF;
- writeReg(0xBD, _mdvdrState);
- }
+ if (channel != 0xFF) {
+ // In case a output channel playing the note was found,
+ // stop it.
+ noteOff(channel);
+ } else {
+ // In case there is no such note this will disable the
+ // rhythm instrument played on the channel.
+ command -= 0x90;
+ const uint instrOffset = _instrumentOffset[command];
+ if (instrOffset && _musicData[instrOffset + 13] != 0) {
+ const uint rhythmInstr = _musicData[instrOffset + 13];
+ if (rhythmInstr < 6) {
+ _mdvdrState &= _mdvdrTable[rhythmInstr] ^ 0xFF;
+ writeReg(0xBD, _mdvdrState);
}
}
}
-
- _curOffset += 2;
}
- // In case there is a delay till the next event stop handling.
- if (_musicData[_curOffset] != 0) {
- break;
- }
- ++_curOffset;
+ _curOffset += 2;
}
- _nextEventTimer = _musicData[_curOffset++];
- if (_nextEventTimer & 0x80) {
- _nextEventTimer -= 0x80;
- _nextEventTimer <<= 7;
- _nextEventTimer |= _musicData[_curOffset++];
- }
+ return false;
+}
- _nextEventTimer >>= (_vm->_game.id == GID_LOOM) ? 2 : 1;
- if (!_nextEventTimer) {
- _nextEventTimer = 1;
+uint Player_AD::parseVLQ() {
+ uint vlq = _musicData[_curOffset++];
+ if (vlq & 0x80) {
+ vlq -= 0x80;
+ vlq <<= 7;
+ vlq |= _musicData[_curOffset++];
}
+ return vlq;
}
void Player_AD::noteOff(uint channel) {
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
index d061c1a..3807ebc 100644
--- a/engines/scumm/players/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -111,6 +111,8 @@ private:
void startMusic();
void stopMusic();
void updateMusic();
+ bool parseCommand();
+ uint parseVLQ();
void noteOff(uint channel);
void setupFrequency(uint channel, int8 frequency);
void setupRhythm(uint rhythmInstr, uint instrOffset);
Commit: eeed91c42025329bb06cc99eb08e0ce23ab828e4
https://github.com/scummvm/scummvm/commit/eeed91c42025329bb06cc99eb08e0ce23ab828e4
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2014-06-04T18:51:15+02:00
Commit Message:
SCUMM: Implement simple seeking in AD player.
Changed paths:
engines/scumm/players/player_ad.cpp
engines/scumm/players/player_ad.h
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index f7f5bb3..08519b4 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 3807ebc..f5e7ecc 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;
Commit: 4069f63eb0caf668e03636df1c697e3fd0724414
https://github.com/scummvm/scummvm/commit/4069f63eb0caf668e03636df1c697e3fd0724414
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2014-06-04T18:51:15+02:00
Commit Message:
SCUMM: Save/load music/sfx data in AD player.
This makes sure that the currently playing music and sfx are resumed when
loading a save game.
Changed paths:
engines/scumm/players/player_ad.cpp
engines/scumm/players/player_ad.h
engines/scumm/saveload.h
diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index 08519b4..5ed50ab 100644
--- a/engines/scumm/players/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -185,8 +185,51 @@ void Player_AD::saveLoadWithSerializer(Serializer *ser) {
return;
}
- // TODO: Be nicer than the original and save the data to continue the
- // currently played sound resources on load?
+ if (ser->getVersion() >= VER(96)) {
+ int32 res[4] = {
+ _soundPlaying, _sfx[0].resource, _sfx[1].resource, _sfx[2].resource
+ };
+
+ // The first thing we save is a list of sound resources being played
+ // at the moment.
+ ser->saveLoadArrayOf(res, 4, sizeof(res[0]), sleInt32);
+
+ // If we are loading start the music again at this point.
+ if (ser->isLoading()) {
+ if (res[0] != -1) {
+ startSound(res[0]);
+ }
+ }
+
+ uint32 musicOffset = _curOffset;
+
+ static const SaveLoadEntry musicData[] = {
+ MKLINE(Player_AD, _engineMusicTimer, sleInt32, VER(96)),
+ MKLINE(Player_AD, _musicTimer, sleUint32, VER(96)),
+ MKLINE(Player_AD, _internalMusicTimer, sleUint32, VER(96)),
+ MKLINE(Player_AD, _curOffset, sleUint32, VER(96)),
+ MKLINE(Player_AD, _nextEventTimer, sleUint32, VER(96)),
+ MKEND()
+ };
+
+ ser->saveLoadEntries(this, musicData);
+
+ // We seek back to the old music position.
+ if (ser->isLoading()) {
+ SWAP(musicOffset, _curOffset);
+ musicSeekTo(musicOffset);
+ }
+
+ // Finally start up the SFX. This makes sure that they are not
+ // accidently stopped while seeking to the old music position.
+ if (ser->isLoading()) {
+ for (int i = 1; i < ARRAYSIZE(res); ++i) {
+ if (res[i] != -1) {
+ startSound(res[i]);
+ }
+ }
+ }
+ }
}
int Player_AD::readBuffer(int16 *buffer, const int numSamples) {
diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h
index f5e7ecc..63a8503 100644
--- a/engines/scumm/players/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -81,7 +81,7 @@ private:
int _samplesTillCallbackRemainder;
int _soundPlaying;
- int _engineMusicTimer;
+ int32 _engineMusicTimer;
struct SfxSlot;
@@ -120,8 +120,8 @@ private:
const byte *_musicData;
uint _timerLimit;
uint _musicTicks;
- uint _musicTimer;
- uint _internalMusicTimer;
+ uint32 _musicTimer;
+ uint32 _internalMusicTimer;
bool _loopFlag;
uint _musicLoopStart;
uint _instrumentOffset[16];
@@ -138,8 +138,8 @@ private:
uint _mdvdrState;
- uint _curOffset;
- uint _nextEventTimer;
+ uint32 _curOffset;
+ uint32 _nextEventTimer;
static const uint _noteFrequencies[12];
static const uint _mdvdrTable[6];
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index bd8ae3f..01ed21e 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 95
+#define CURRENT_VER 96
/**
* An auxillary macro, used to specify savegame versions. We use this instead
More information about the Scummvm-git-logs
mailing list