aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/imuse.cpp16
-rw-r--r--scumm/imuse.h1
-rw-r--r--scumm/imuse_internal.h7
-rw-r--r--scumm/imuse_player.cpp4
-rw-r--r--scumm/midiparser_ro.cpp10
-rw-r--r--scumm/scummvm.cpp2
-rw-r--r--sound/midiparser.h1
7 files changed, 38 insertions, 3 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index 542fcbeb78..ceed012148 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -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; }
diff --git a/scumm/imuse.h b/scumm/imuse.h
index 7788ddf0ea..98cd328eb4 100644
--- a/scumm/imuse.h
+++ b/scumm/imuse.h
@@ -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();
diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h
index 847b56dde3..8ab454d87f 100644
--- a/scumm/imuse_internal.h
+++ b/scumm/imuse_internal.h
@@ -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();
diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp
index a85e7428a2..a754700b37 100644
--- a/scumm/imuse_player.cpp
+++ b/scumm/imuse_player.cpp
@@ -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) {
diff --git a/scumm/midiparser_ro.cpp b/scumm/midiparser_ro.cpp
index 67d61a82f3..4f01a3e5fe 100644
--- a/scumm/midiparser_ro.cpp
+++ b/scumm/midiparser_ro.cpp
@@ -33,11 +33,15 @@
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
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index 0a6ad8f942..e332cfad6b 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -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
diff --git a/sound/midiparser.h b/sound/midiparser.h
index c5fad965d5..e419535df0 100644
--- a/sound/midiparser.h
+++ b/sound/midiparser.h
@@ -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();