mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-30 07:23:05 +00:00
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).
This commit is contained in:
parent
187ecdd54f
commit
3d42141e9d
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user