bool Player_V3M::loadMusic(const byte *ptr) { Common::MacResManager resource; bool found = false; for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) { if (resource.open(loomFileNames[i])) { found = true; break; } } if (!found) { return false; } if (ptr[4] != 's' || ptr[5] != 'o') { // Like the original we ignore all sound resources which do not have // a 'so' tag in them. // See bug #3602239 ("Mac Loom crashes using opening spell on // gravestone") for a case where this is required. Loom Mac tries to // play resource 11 here. This resource is no Mac sound resource // though, it is a PC Speaker resource. A test with the original // interpreter also has shown that no sound is played while the // screen is shaking. debug(5, "Player_V3M::loadMusic: Skipping unknown music type %02X%02X", ptr[4], ptr[5]); resource.close(); return false; } uint i; for (i = 0; i < 5; i++) { int instrument = READ_BE_UINT16(ptr + 20 + 2 * i); int offset = READ_BE_UINT16(ptr + 30 + 2 * i); _channel[i]._looped = false; _channel[i]._length = READ_BE_UINT16(ptr + offset + 4) * 3; _channel[i]._data = ptr + offset + 6; _channel[i]._pos = 0; _channel[i]._pitchModifier = 0; _channel[i]._velocity = 0; _channel[i]._remaining = 0; _channel[i]._notesLeft = true; Common::SeekableReadStream *stream = resource.getResource(RES_SND, instrument); if (_channel[i].loadInstrument(stream)) { debug(6, "Player_V3M::loadMusic: Channel %d - Loaded Instrument %d (%s)", i, instrument, resource.getResName(RES_SND, instrument).c_str()); } else { resource.close(); return false; } } resource.close(); return true; }
bool Player_V5M::loadMusic(const byte *ptr) { Common::MacResManager resource; bool found = false; uint i; for (i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) { if (resource.open(monkeyIslandFileNames[i])) { found = true; break; } } if (!found) { return false; } ptr += 8; // TODO: Decipher the unknown bytes in the header. For now, skip 'em ptr += 28; Common::MacResIDArray idArray = resource.getResIDArray(RES_SND); // Load the three channels and their instruments for (i = 0; i < 3; i++) { assert(READ_BE_UINT32(ptr) == MKTAG('C', 'h', 'a', 'n')); uint32 len = READ_BE_UINT32(ptr + 4); uint32 instrument = READ_BE_UINT32(ptr + 8); _channel[i]._length = len - 20; _channel[i]._data = ptr + 12; _channel[i]._looped = (READ_BE_UINT32(ptr + len - 8) == MKTAG('L', 'o', 'o', 'p')); _channel[i]._pos = 0; _channel[i]._pitchModifier = 0; _channel[i]._velocity = 0; _channel[i]._remaining = 0; _channel[i]._notesLeft = true; for (uint j = 0; j < idArray.size(); j++) { Common::String name = resource.getResName(RES_SND, idArray[j]); if (instrument == READ_BE_UINT32(name.c_str())) { debug(6, "Player_V5M::loadMusic: Channel %d: Loading instrument '%s'", i, name.c_str()); Common::SeekableReadStream *stream = resource.getResource(RES_SND, idArray[j]); if (!_channel[i].loadInstrument(stream)) { resource.close(); return false; } break; } } ptr += len; } resource.close(); // The last note of each channel is just zeroes. We will adjust this // note so that all the channels end at the same time. uint32 samples[3]; uint32 maxSamples = 0; for (i = 0; i < 3; i++) { samples[i] = 0; for (uint j = 0; j < _channel[i]._length; j += 4) { samples[i] += durationToSamples(READ_BE_UINT16(&_channel[i]._data[j])); } if (samples[i] > maxSamples) { maxSamples = samples[i]; } } for (i = 0; i < 3; i++) { _lastNoteSamples[i] = maxSamples - samples[i]; } return true; }