aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/imuse.cpp75
-rw-r--r--scumm/imuse.h4
-rw-r--r--scumm/imuse_internal.h8
-rw-r--r--scumm/imuse_player.cpp20
-rw-r--r--scumm/scummvm.cpp6
-rw-r--r--scumm/sound.cpp63
6 files changed, 86 insertions, 90 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index c67949b134..75098556f3 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -49,6 +49,8 @@ _base_sounds (0),
_paused (false),
_initialized (false),
_tempoFactor (0),
+_player_limit (ARRAYSIZE(_players)),
+_recycle_players (false),
_queue_end (0),
_queue_pos (0),
_queue_sound (0),
@@ -89,7 +91,7 @@ MidiDriver *IMuseInternal::getMidiDriver() {
return driver;
}
-byte *IMuseInternal::findTag(int sound, char *tag, int index) {
+byte *IMuseInternal::findStartOfSound (int sound) {
byte *ptr = NULL;
int32 size, pos;
@@ -97,7 +99,7 @@ byte *IMuseInternal::findTag(int sound, char *tag, int index) {
ptr = _base_sounds[sound];
if (ptr == NULL) {
- debug(1, "IMuseInternal::findTag completely failed finding sound %d", sound);
+ debug (1, "IMuseInternal::findStartOfSound(): Sound %d doesn't exist!", sound);
return NULL;
}
@@ -106,16 +108,18 @@ byte *IMuseInternal::findTag(int sound, char *tag, int index) {
size = READ_BE_UINT32_UNALIGNED(ptr);
ptr += 4;
+ // Okay, we're looking for one of those things: either
+ // an 'MThd' tag (for SMF), or a 'FORM' tag (for XMIDI).
+ size = 48; // Arbitrary; we should find our tag within the first 48 bytes of the resource
pos = 0;
-
while (pos < size) {
- if (!memcmp(ptr + pos, tag, 4) && !index--)
- return ptr + pos + 8;
- pos += READ_BE_UINT32_UNALIGNED(ptr + pos + 4) + 8;
+ if (!memcmp (ptr + pos, "MThd", 4) || !memcmp (ptr + pos, "FORM", 4))
+ return ptr + pos;
+ ++pos; // We could probably iterate more intelligently
}
- debug(3, "IMuseInternal::findTag failed finding sound %d", sound);
- return NULL;
+ debug(3, "IMuseInternal::findStartOfSound(): Failed to align on sound %d!", sound);
+ return 0;
}
bool IMuseInternal::isMT32(int sound) {
@@ -219,6 +223,14 @@ bool IMuseInternal::startSound(int sound) {
return false;
}
+ // Not sure exactly what the old code was doing,
+ // but we'll go ahead and do a similar check.
+ mdhd = findStartOfSound (sound);
+ if (!mdhd) {
+ debug (2, "IMuseInternal::startSound(): Couldn't find sound %d!", sound);
+ return false;
+ }
+/*
mdhd = findTag(sound, MDHD_TAG, 0);
if (!mdhd) {
mdhd = findTag(sound, MDPG_TAG, 0);
@@ -227,6 +239,7 @@ bool IMuseInternal::startSound(int sound) {
return false;
}
}
+*/
// Check which MIDI driver this track should use.
// If it's NULL, it ain't something we can play.
@@ -257,7 +270,7 @@ Player *IMuseInternal::allocate_player(byte priority) {
int i;
byte bestpri = 255;
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
+ for (i = _player_limit; i != 0; i--, player++) {
if (!player->isActive())
return player;
if (player->getPriority() < bestpri) {
@@ -266,7 +279,7 @@ Player *IMuseInternal::allocate_player(byte priority) {
}
}
- if (bestpri < priority)
+ if (bestpri < priority || _recycle_players)
return best;
debug(1, "Denying player request");
@@ -410,22 +423,21 @@ Part *IMuseInternal::allocate_part (byte pri, MidiDriver *midi) {
return best;
}
-int IMuseInternal::getSoundStatus(int sound) {
- Player *player = findActivePlayer (sound);
- if (player && !player->isFadingOut())
- return 1;
- return get_queue_sound_status(sound);
-}
+int IMuseInternal::getSoundStatus (int sound, bool ignoreFadeouts) {
+ Player *player;
+ if (sound == -1) {
+ player = _players;
+ for (int i = ARRAYSIZE(_players); i; --i, ++player) {
+ if (player->isActive() && (!ignoreFadeouts || !player->isFadingOut()))
+ return player->getID();
+ }
+ return 0;
+ }
-// This is exactly the same as getSoundStatus except that
-// it treats sounds that are fading out just the same as
-// other sounds. This is the method to use when determining
-// what resources to expire from memory.
-bool IMuseInternal::get_sound_active(int sound) {
- Player *player = findActivePlayer (sound);
- if (player)
+ player = findActivePlayer (sound);
+ if (player && (!ignoreFadeouts || !player->isFadingOut()))
return 1;
- return (get_queue_sound_status(sound) != 0);
+ return get_queue_sound_status(sound);
}
int IMuseInternal::get_queue_sound_status(int sound) {
@@ -1041,6 +1053,17 @@ uint32 IMuseInternal::property(int prop, uint32 value) {
case IMuse::PROP_OLD_ADLIB_INSTRUMENTS:
_old_adlib_instruments = (value > 0);
+ break;
+
+ case IMuse::PROP_LIMIT_PLAYERS:
+ if (value > 0 && value <= ARRAYSIZE(_players))
+ _player_limit = (int) value;
+ break;
+
+ case IMuse::PROP_RECYCLE_PLAYERS:
+ if (value > 0 && value <= ARRAYSIZE(_players))
+ _recycle_players = (value != 0);
+ break;
}
return 0;
}
@@ -1674,8 +1697,8 @@ int IMuse::get_master_volume() { in(); int ret = _target->get_master_volume(); o
bool IMuse::startSound(int sound) { in(); bool ret = _target->startSound (sound); out(); return ret; }
int IMuse::stopSound(int sound) { in(); int ret = _target->stopSound (sound); out(); return ret; }
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); out(); return ret; }
-bool IMuse::get_sound_active(int sound) { in(); bool ret = _target->get_sound_active (sound); 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; }
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; }
int IMuse::clear_queue() { in(); int ret = _target->clear_queue(); out(); return ret; }
void IMuse::setBase(byte **base) { in(); _target->setBase (base); out(); }
diff --git a/scumm/imuse.h b/scumm/imuse.h
index bb5c85a3ea..541f34e067 100644
--- a/scumm/imuse.h
+++ b/scumm/imuse.h
@@ -47,7 +47,9 @@ public:
PROP_TEMPO_BASE = 1,
PROP_NATIVE_MT32 = 2,
PROP_MULTI_MIDI = 3,
- PROP_OLD_ADLIB_INSTRUMENTS = 4
+ PROP_OLD_ADLIB_INSTRUMENTS = 4,
+ PROP_LIMIT_PLAYERS = 5,
+ PROP_RECYCLE_PLAYERS = 6
};
void on_timer (MidiDriver *midi);
diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h
index d035e72267..fc6ce08d6e 100644
--- a/scumm/imuse_internal.h
+++ b/scumm/imuse_internal.h
@@ -366,6 +366,9 @@ private:
int _tempoFactor;
+ int _player_limit; // Limits how many simultaneous music tracks are played
+ bool _recycle_players; // Can we stop a player in order to start another one?
+
uint _queue_end, _queue_pos, _queue_sound;
byte _queue_adding;
@@ -390,7 +393,7 @@ private:
CommandQueue _cmd_queue[64];
DeferredCommand _deferredCommands[4];
- byte *findTag(int sound, char *tag, int index);
+ byte *findStartOfSound (int sound);
bool isMT32(int sound);
bool isGM(int sound);
int get_queue_sound_status(int sound);
@@ -457,8 +460,7 @@ public:
bool startSound(int sound);
int stopSound(int sound);
int stop_all_sounds();
- int getSoundStatus(int sound);
- bool get_sound_active(int sound);
+ int getSoundStatus (int sound, bool ignoreFadeouts = true);
int32 doCommand(int a, int b, int c, int d, int e, int f, int g, int h);
int clear_queue();
void setBase(byte **base);
diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp
index 82255a5763..42cb05bc6f 100644
--- a/scumm/imuse_player.cpp
+++ b/scumm/imuse_player.cpp
@@ -88,6 +88,14 @@ bool Player::startSound (int sound, MidiDriver *midi) {
void *mdhd;
int i;
+ // Not sure what the old code was doing,
+ // but we'll go ahead and do a similar check.
+ mdhd = _se->findStartOfSound (sound);
+ if (!mdhd) {
+ warning ("Player::startSound(): Couldn't find start of sound %d!", sound);
+ return false;
+ }
+/*
mdhd = _se->findTag(sound, MDHD_TAG, 0);
if (mdhd == NULL) {
mdhd = _se->findTag(sound, MDPG_TAG, 0);
@@ -96,7 +104,7 @@ bool Player::startSound (int sound, MidiDriver *midi) {
return false;
}
}
-
+*/
_isMT32 = _se->isMT32(sound);
_isGM = _se->isGM(sound);
@@ -114,8 +122,8 @@ bool Player::startSound (int sound, MidiDriver *midi) {
for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i)
_parameterFaders[i].init();
-
hook_clear();
+
if (start_seq_sound(sound) != 0) {
_active = false;
_midi = NULL;
@@ -163,14 +171,16 @@ int Player::start_seq_sound(int sound) {
setTempo(500000);
setSpeed(128);
- ptr = _se->findTag (sound, "MThd", 0);
+ ptr = _se->findStartOfSound (sound);
if (ptr == NULL)
return -1;
if (_parser)
delete _parser;
- ptr -= 8; // findTag puts us past the tag and length
- _parser = MidiParser::createParser_SMF();
+ if (!memcmp (ptr, "FORM", 4))
+ _parser = MidiParser::createParser_XMIDI();
+ else
+ _parser = MidiParser::createParser_SMF();
_parser->setTimerRate ((_midi->getBaseTempo() * _speed) >> 7);
_parser->setMidiDriver (this);
_parser->property (MidiParser::mpSmartJump, 1);
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index 391d8dece1..fd5fa8a79f 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -614,6 +614,10 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst)
_imuse->property (IMuse::PROP_OLD_ADLIB_INSTRUMENTS, (_features & GF_SMALL_HEADER) ? 1 : 0);
_imuse->property (IMuse::PROP_MULTI_MIDI, detector->_multi_midi);
_imuse->property (IMuse::PROP_NATIVE_MT32, detector->_native_mt32);
+ if (_features & GF_HUMONGOUS) {
+ _imuse->property (IMuse::PROP_LIMIT_PLAYERS, 1);
+ _imuse->property (IMuse::PROP_RECYCLE_PLAYERS, 1);
+ }
_imuse->set_music_volume(_sound->_sound_volume_music);
}
}
@@ -815,7 +819,7 @@ void Scumm::initScummVars() {
VAR(VAR_VIDEOMODE) = 0x13;
VAR(VAR_HEAPSPACE) = 1400;
VAR(VAR_MOUSEPRESENT) = true; // FIXME - used to be 0, but that seems odd?!?
- if ((_features & GF_HUMONGOUS) && (_gameId != GID_PUTTDEMO))
+ if (_features & GF_HUMONGOUS)
VAR(VAR_SOUNDPARAM) = 1; // soundblaster for music
else
VAR(VAR_SOUNDPARAM) = 0;
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
index bc0bbcb9bb..b52255d673 100644
--- a/scumm/sound.cpp
+++ b/scumm/sound.cpp
@@ -236,55 +236,8 @@ void Sound::playSound(int soundID) {
}
// XMIDI
else if ((READ_UINT32_UNALIGNED(ptr) == MKID('MIDI')) && (_scumm->_features & GF_HUMONGOUS)) {
- // skip HSHD
- ptr += 8 + READ_BE_UINT32_UNALIGNED(ptr+12);
- if (READ_UINT32_UNALIGNED(ptr) != MKID('SDAT'))
- return; // abort
-
- size = READ_BE_UINT32_UNALIGNED(ptr+4) - 8;
- ptr += 8; // don't need SDAT block anymore
-
- // XMIDI playing stuff goes here
- // ptr should be pointing to XMIDI file in memory
- // HACK (Jamieson630): Just to see if it works.
- static MidiParser *parser = 0;
-
- MidiDriver *driver = 0;
- if (_scumm && _scumm->_imuse)
- driver = _scumm->_imuse->getMidiDriver();
- if (driver) {
- driver->setTimerCallback (0, 0);
- if (parser) {
- delete parser;
- parser = 0;
- }
- parser = MidiParser::createParser_XMIDI();
- parser->setMidiDriver (driver);
- parser->setTimerRate (driver->getBaseTempo());
- if (_scumm->_gameId != GID_PUTTDEMO)
- parser->property (MidiParser::mpAutoLoop, 1);
- parser->loadMusic (ptr, size);
- driver->open();
- driver->setTimerCallback (parser, &MidiParser::timerCallback);
- }
-
- // FIXME: dumping xmi files for testing, remove when working
- if (1) {
- File out;
- char buf[64];
- sprintf(buf, "dumps/sound-%d.xmi", soundID);
-
- out.open(buf, "", 1);
- if (out.isOpen() == false) {
- out.open(buf, "", 2);
- if (out.isOpen() == false)
- return;
- out.write(ptr, size);
- }
- out.close();
- }
-
- return;
+ // Pass XMIDI on to IMuse unprocessed.
+ // IMuse can handle XMIDI resources now.
}
else if (READ_UINT32_UNALIGNED(ptr) == MKID('ADL ')) {
// played as MIDI, just to make perhaps the later use
@@ -636,11 +589,13 @@ int Sound::isSoundRunning(int sound) {
return pollCD();
if (_scumm->_features & GF_HUMONGOUS) {
- if (sound == -2) {
- return isSfxFinished();
- // FIXME are we playing music?
- } else if (sound == -1)
- return 1;
+ if (sound == -2) {
+ return isSfxFinished();
+ } else if (sound == -1) {
+ // getSoundStatus(), with a -1, will return the
+ // ID number of the first active music it finds.
+ return _scumm->_imuse->getSoundStatus (sound);
+ }
}
_scumm->_mixer->stopID(sound);