mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
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:
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user