protected override bool LoadMusic(byte[] ptr) { var offset = 0; var resource = new MacResManager(ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path)); bool found = false; uint i; for (i = 0; i < monkeyIslandFileNames.Length; i++) { if (resource.Open(monkeyIslandFileNames[i])) { found = true; break; } } if (!found) { return(false); } offset += 8; // TODO: Decipher the unknown bytes in the header. For now, skip 'em offset += 28; var idArray = resource.GetResIDArray(RES_SND); // Load the three channels and their instruments for (i = 0; i < 3; i++) { Debug.Assert(ptr.ToUInt32BigEndian(offset) == System.Text.Encoding.UTF8.GetBytes("Chan").ToUInt32BigEndian()); var len = ptr.ToUInt32BigEndian(offset + 4); var instrument = ptr.ToUInt32BigEndian(offset + 8); _channel[i]._length = len - 20; _channel[i]._data = ptr; _channel[i]._dataOffset = offset + 12; _channel[i]._looped = (ptr.ToUInt32BigEndian((int)(offset + len - 8)) == System.Text.Encoding.UTF8.GetBytes("Loop").ToUInt32BigEndian()); _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.Length; j++) { var name = resource.GetResName(RES_SND, idArray[j]); if (instrument == System.Text.Encoding.UTF8.GetBytes(name).ToUInt32BigEndian()) { Debug.WriteLine("Player_V5M::loadMusic: Channel {0}: Loading instrument '{1}'", i, name); var stream = resource.GetResource(RES_SND, idArray[j]); if (!_channel[i].LoadInstrument(stream)) { resource.Close(); return(false); } break; } } offset += (int)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. uint[] samples = new uint[3]; uint maxSamples = 0; for (i = 0; i < 3; i++) { samples[i] = 0; for (uint j = 0; j < _channel[i]._length; j += 4) { samples[i] += DurationToSamples(_channel[i]._data.ToUInt16BigEndian((int)(_channel[i]._dataOffset + j))); } if (samples[i] > maxSamples) { maxSamples = samples[i]; } } for (i = 0; i < 3; i++) { _lastNoteSamples[i] = maxSamples - samples[i]; } return(true); }
protected override bool LoadMusic(byte[] ptr) { var resource = new MacResManager(ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path)); bool found = false; for (int i = 0; i < loomFileNames.Length; 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.WriteLine("Player_V3M::loadMusic: Skipping unknown music type {0:X2}{1:X2}", ptr[4], ptr[5]); resource.Close(); return(false); } for (var i = 0; i < 5; i++) { var instrument = ptr.ToUInt16BigEndian(20 + 2 * i); int offset = ptr.ToUInt16BigEndian(30 + 2 * i); _channel[i]._looped = false; _channel[i]._length = (uint)(ptr.ToUInt16BigEndian(offset + 4) * 3); _channel[i]._data = ptr; _channel[i]._dataOffset = offset + 6; _channel[i]._pos = 0; _channel[i]._pitchModifier = 0; _channel[i]._velocity = 0; _channel[i]._remaining = 0; _channel[i]._notesLeft = true; var stream = resource.GetResource(RES_SND, instrument); if (_channel[i].LoadInstrument(stream)) { Debug.WriteLine("Player_V3M::loadMusic: Channel {0} - Loaded Instrument {1} ({2})", i, instrument, resource.GetResName(RES_SND, instrument)); } else { resource.Close(); return(false); } } resource.Close(); return(true); }