diff options
author | athrxx | 2011-05-22 18:25:29 +0200 |
---|---|---|
committer | unknown | 2011-05-29 01:03:55 +0200 |
commit | 3d42141e9dda203a5dae7bb91384405be5abc243 (patch) | |
tree | b1948b4599c02b0ac46eaf628362a0d31ee19a6c /engines/scumm/imuse | |
parent | 187ecdd54f94026dd47b959050295f10faa65bb0 (diff) | |
download | scummvm-rg350-3d42141e9dda203a5dae7bb91384405be5abc243.tar.gz scummvm-rg350-3d42141e9dda203a5dae7bb91384405be5abc243.tar.bz2 scummvm-rg350-3d42141e9dda203a5dae7bb91384405be5abc243.zip |
SCUMM: implement some missing (very low relevance) imuse code
1) Don't skip transpose setting in sysex command 0. There are only a few sounds where this setting is used (mainly sfx).
2) Make MI2 and INDY4 read certain player start parameters from the sound resource. The start parameters usually match our default parameters (exception: e.g. LeChuck's Fortress). The use of these parameters has been dropped in DOTT (they use default parameters like we do).
Diffstat (limited to 'engines/scumm/imuse')
-rw-r--r-- | engines/scumm/imuse/imuse.cpp | 27 | ||||
-rw-r--r-- | engines/scumm/imuse/imuse_internal.h | 10 | ||||
-rw-r--r-- | engines/scumm/imuse/imuse_part.cpp | 3 | ||||
-rw-r--r-- | engines/scumm/imuse/imuse_player.cpp | 47 | ||||
-rw-r--r-- | engines/scumm/imuse/sysex_scumm.cpp | 8 |
5 files changed, 73 insertions, 22 deletions
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index fe23b88e52..7d971f5ca4 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -99,8 +99,9 @@ IMuseInternal::~IMuseInternal() { } } -byte *IMuseInternal::findStartOfSound(int sound) { +byte *IMuseInternal::findStartOfSound(int sound, int ct) { int32 size, pos; + static uint32 id[] = { 'MThd', 'FORM', 'MDhd', 'MDpg' }; byte *ptr = g_scumm->_res->_types[rtSound][sound]._address; @@ -110,10 +111,11 @@ byte *IMuseInternal::findStartOfSound(int sound) { } // Check for old-style headers first, like 'RO' + int trFlag = (kMThd | kFORM); if (ptr[0] == 'R' && ptr[1] == 'O'&& ptr[2] != 'L') - return ptr; + return ct == trFlag ? ptr : 0; if (ptr[4] == 'S' && ptr[5] == 'O') - return ptr + 4; + return ct == trFlag ? ptr + 4 : 0; ptr += 4; size = READ_BE_UINT32(ptr); @@ -124,12 +126,16 @@ byte *IMuseInternal::findStartOfSound(int sound) { 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, "MThd", 4) || !memcmp(ptr + pos, "FORM", 4)) - return ptr + pos; + for (int i = 0; i < ARRAYSIZE(id); ++i) { + if ((ct & (1 << i)) && (READ_BE_UINT32(ptr + pos) == id[i])) + return ptr + pos; + } ++pos; // We could probably iterate more intelligently } - debug(3, "IMuseInternal::findStartOfSound(): Failed to align on sound %d", sound); + if (ct == (kMThd | kFORM)) + debug(3, "IMuseInternal::findStartOfSound(): Failed to align on sound %d", sound); + return 0; } @@ -556,7 +562,7 @@ bool IMuseInternal::startSound_internal(int sound, int offset) { return false; } - void *ptr = findStartOfSound(sound); + byte *ptr = findStartOfSound(sound); if (!ptr) { debug(2, "IMuseInternal::startSound(): Couldn't find sound %d", sound); return false; @@ -576,8 +582,11 @@ bool IMuseInternal::startSound_internal(int sound, int offset) { // Bug #590511 and Patch #607175 (which was reversed to fix // an FOA regression: Bug #622606). Player *player = findActivePlayer(sound); - if (!player) - player = allocate_player(128); + if (!player) { + ptr = findStartOfSound(sound, IMuseInternal::kMDhd); + player = allocate_player(ptr ? (READ_BE_UINT32(&ptr[4]) && ptr[10] ? ptr[10] : 128) : 128); + } + if (!player) return false; diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h index ec60b22509..8808a3655a 100644 --- a/engines/scumm/imuse/imuse_internal.h +++ b/engines/scumm/imuse/imuse_internal.h @@ -229,6 +229,7 @@ protected: // Sequencer part int start_seq_sound(int sound, bool reset_vars = true); + void loadStartParameters(int sound); int query_param(int param); public: @@ -445,7 +446,14 @@ protected: static void midiTimerCallback(void *data); void on_timer(MidiDriver *midi); - byte *findStartOfSound(int sound); + enum ChunkType { + kMThd = 1, + kFORM = 2, + kMDhd = 4, // Used in MI2 and INDY4. Contain certain start parameters (priority, volume, etc. ) for the player. + kMDpg = 8 // These chunks exist in DOTT and SAMNMAX. They don't get processed, however. + }; + + byte *findStartOfSound(int sound, int ct = (kMThd | kFORM)); bool isMT32(int sound); bool isMIDI(int sound); int get_queue_sound_status(int sound) const; diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp index 808af23dde..5df8407a96 100644 --- a/engines/scumm/imuse/imuse_part.cpp +++ b/engines/scumm/imuse/imuse_part.cpp @@ -137,7 +137,8 @@ void Part::set_pan(int8 pan) { } void Part::set_transpose(int8 transpose) { - _transpose_eff = transpose_clamp((_transpose = transpose) + _player->getTranspose(), -24, 24); + _transpose = transpose; + _transpose_eff = (_transpose == -128) ? 0 : transpose_clamp(_transpose + _player->getTranspose(), -24, 24); sendPitchBend(); } diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp index e7ee935130..0b084f3116 100644 --- a/engines/scumm/imuse/imuse_player.cpp +++ b/engines/scumm/imuse/imuse_player.cpp @@ -90,7 +90,7 @@ Player::~Player() { } bool Player::startSound(int sound, MidiDriver *midi) { - void *ptr; + byte *ptr; int i; // Not sure what the old code was doing, @@ -108,13 +108,8 @@ bool Player::startSound(int sound, MidiDriver *midi) { _active = true; _midi = midi; _id = sound; - _priority = 0x80; - _volume = 0x7F; - _vol_chan = 0xFFFF; - _vol_eff = (_se->get_channel_volume(0xFFFF) << 7) >> 7; - _pan = 0; - _transpose = 0; - _detune = 0; + + loadStartParameters(sound); for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) _parameterFaders[i].init(); @@ -125,7 +120,7 @@ bool Player::startSound(int sound, MidiDriver *midi) { _midi = NULL; return false; } - + debugC(DEBUG_IMUSE, "Starting music %d", sound); return true; } @@ -199,11 +194,43 @@ int Player::start_seq_sound(int sound, bool reset_vars) { _parser->property(MidiParser::mpSmartJump, 1); _parser->loadMusic(ptr, 0); _parser->setTrack(_track_index); - setSpeed(reset_vars ? 128 : _speed); + + ptr = _se->findStartOfSound(sound, IMuseInternal::kMDhd); + setSpeed(reset_vars ? (ptr ? (READ_BE_UINT32(&ptr[4]) && ptr[15] ? ptr[15] : 128) : 128) : _speed); return 0; } +void Player::loadStartParameters(int sound) { + _priority = 0x80; + _volume = 0x7F; + _vol_chan = 0xFFFF; + _vol_eff = (_se->get_channel_volume(0xFFFF) << 7) >> 7; + _pan = 0; + _transpose = 0; + _detune = 0; + + byte *ptr = _se->findStartOfSound(sound, IMuseInternal::kMDhd); + uint32 size = 0; + + if (ptr) { + ptr += 4; + size = READ_BE_UINT32(ptr); + ptr += 4; + + // MDhd chunks don't get used in MI1 and contain only zeroes. + // We check for volume, priority and speed settings of zero here. + if (size && (ptr[2] | ptr[3] | ptr[7])) { + _priority = ptr[2]; + _volume = ptr[3]; + _pan = ptr[4]; + _transpose = ptr[5]; + _detune = ptr[6]; + setSpeed(ptr[7]); + } + } +} + void Player::uninit_parts() { assert(!_parts || _parts->_player == this); diff --git a/engines/scumm/imuse/sysex_scumm.cpp b/engines/scumm/imuse/sysex_scumm.cpp index 6ab71c2fa5..4eb3bee93c 100644 --- a/engines/scumm/imuse/sysex_scumm.cpp +++ b/engines/scumm/imuse/sysex_scumm.cpp @@ -64,6 +64,11 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) { // BYTE 14: Pitchbend range(lower 4 bits) [bug #1088045] // BYTE 15: Program(upper 4 bits) // BYTE 16: Program(lower 4 bits) + + // athrxx (05-21-2011): + // BYTE 9, 10: Transpose (if set to 0x80, this means that part->_transpose_eff will be 0 (also ignoring player->_transpose) + // BYTE 11, 12: Detune + part = player->getPart(p[0] & 0x0F); if (part) { part->set_onoff(p[2] & 0x01); @@ -71,7 +76,8 @@ void sysexHandler_Scumm(Player *player, const byte *msg, uint16 len) { part->set_pri(p[4]); part->volume((p[5] & 0x0F) << 4 |(p[6] & 0x0F)); part->set_pan((p[7] & 0x0F) << 4 | (p[8] & 0x0F)); - part->_percussion = player->_isMIDI ? ((p[9] & 0x08) > 0) : false; + part->_percussion = player->_isMIDI ? ((p[9] & 0x08) > 0) : false; + part->set_transpose((p[9] & 0x0F) << 4 | (p[10] & 0x0F)); part->set_detune((p[11] & 0x0F) << 4 | (p[12] & 0x0F)); part->pitchBendFactor((p[13] & 0x0F) << 4 | (p[14] & 0x0F)); if (part->_percussion) { |