Corrected timing mechanism for RO music streams.

RO streams have built-in timer markers (the
unknown 0xA0 mentioned in FR [742249]) that
override automated methods of updating
VAR_MUSIC_TIMER. Since these timer markers
do not seem to be present in AD resources, the
old mechanism is used if MD_ADLIB is the current
MidiDriver.

svn-id: r9720
This commit is contained in:
Jamieson Christian
2003-08-16 09:34:19 +00:00
parent 8281c2eecc
commit 121b00a6f7
7 changed files with 38 additions and 3 deletions
+16
View File
@@ -317,6 +317,21 @@ void IMuseInternal::on_timer(MidiDriver *midi) {
sequencer_timers(midi);
}
int IMuseInternal::getMusicTimer() {
int best_time = 0;
Player *player = _players;
int i;
for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
if (player->isActive()) {
int timer = player->getMusicTimer();
if (timer > best_time)
best_time = timer;
}
}
return best_time / 1000000;
}
void IMuseInternal::sequencer_timers(MidiDriver *midi) {
Player *player = _players;
int i;
@@ -1744,6 +1759,7 @@ int IMuse::stopSound(int sound) { in(); int ret = _target->stopSound(sound); out
int IMuse::stop_all_sounds() { in(); int ret = _target->stop_all_sounds(); out(); return ret; }
int IMuse::getSoundStatus(int sound) { in(); int ret = _target->getSoundStatus(sound, true); out(); return ret; }
bool IMuse::get_sound_active(int sound) { in(); bool ret = _target->getSoundStatus(sound, false) ? 1 : 0; out(); return ret; }
int IMuse::getMusicTimer() { in(); int ret = _target->getMusicTimer(); out(); return ret; }
int32 IMuse::doCommand (int a, int b, int c, int d, int e, int f, int g, int h) { in(); int32 ret = _target->doCommand(a,b,c,d,e,f,g,h); out(); return ret; }
int32 IMuse::doCommand (int numargs, int args[]) { in(); int32 ret = _target->doCommand (numargs, args); out(); return ret; }
int IMuse::clear_queue() { in(); int ret = _target->clear_queue(); out(); return ret; }
+1
View File
@@ -67,6 +67,7 @@ public:
int stop_all_sounds();
int getSoundStatus(int sound);
bool get_sound_active(int sound);
int getMusicTimer();
int32 doCommand (int a, int b, int c, int d, int e, int f, int g, int h);
int32 doCommand (int numargs, int args[]);
int clear_queue();
+5 -2
View File
@@ -261,6 +261,7 @@ public:
int setTranspose(byte relative, int b);
int setVolume(byte vol);
bool startSound(int sound, MidiDriver *midi);
uint32 getMusicTimer();
public:
// MidiDriver interface
@@ -349,7 +350,7 @@ struct Part {
class IMuseInternal {
friend class Player;
private:
protected:
bool _old_adlib_instruments;
bool _enable_multi_midi;
MidiDriver *_midi_adlib;
@@ -359,7 +360,7 @@ private:
SoundMixer *_mixer;
private:
protected:
bool _paused;
bool _initialized;
@@ -392,6 +393,7 @@ private:
CommandQueue _cmd_queue[64];
DeferredCommand _deferredCommands[4];
protected:
byte *findStartOfSound(int sound);
bool isMT32(int sound);
bool isGM(int sound);
@@ -461,6 +463,7 @@ public:
int stopSound(int sound);
int stop_all_sounds();
int getSoundStatus(int sound, bool ignoreFadeouts = true);
int getMusicTimer();
int32 doCommand (int a, int b, int c, int d, int e, int f, int g, int h);
int32 doCommand (int numargs, int args[]);
int clear_queue();
+4
View File
@@ -128,6 +128,10 @@ bool Player::startSound(int sound, MidiDriver *midi) {
return true;
}
uint32 Player::getMusicTimer() {
return _parser ? _parser->getTime() : 0;
}
bool Player::isFadingOut() {
int i;
for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) {
+9 -1
View File
@@ -32,12 +32,16 @@
//////////////////////////////////////////////////
class MidiParser_RO : public MidiParser {
protected:
int _markerCount; // Number of markers encountered in stream so far
protected:
void compressToType0();
void parseNextEvent (EventInfo &info);
public:
bool loadMusic (byte *data, uint32 size);
uint32 getTime() { return (uint32) _markerCount * 1000000; }
};
@@ -53,7 +57,10 @@ void MidiParser_RO::parseNextEvent (EventInfo &info) {
do {
info.start = _position._play_pos;
info.event = *(_position._play_pos++);
if (info.command() == 0xA) continue;
if (info.command() == 0xA) {
++_markerCount;
continue;
} // end if
if (info.event == 0xF0) {
byte delay = *(_position._play_pos++);
@@ -107,6 +114,7 @@ bool MidiParser_RO::loadMusic (byte *data, uint32 size) {
_num_tracks = 1;
_ppqn = 120;
_tracks[0] = pos + 2;
_markerCount = 0;
// Note that we assume the original data passed in
// will persist beyond this call, i.e. we do NOT
+2
View File
@@ -1207,6 +1207,8 @@ int Scumm::scummLoop(int delta) {
// Covered automatically by the Sound class
} else if (_playerV2) {
VAR(VAR_MUSIC_TIMER) = _playerV2->getMusicTimer();
} else if (_imuse && _midiDriver != MD_ADLIB) {
VAR(VAR_MUSIC_TIMER) = _imuse->getMusicTimer();
} else if (_features & GF_SMALL_HEADER) {
// TODO: The music delay (given in milliseconds) might have to be tuned a little
// to get it correct for all games. Without the ability to watch/listen to the
+1
View File
@@ -248,6 +248,7 @@ public:
bool setTrack (int track);
bool jumpToTick (uint32 tick, bool fireEvents = false);
uint32 getTick() { return _position._play_tick; }
virtual uint32 getTime() { return _position._play_time; }
static MidiParser *createParser_SMF();
static MidiParser *createParser_XMIDI();