protected override bool CheckMusicAvailable() { var resource = new MacResManager(ServiceLocator.FileStorage.GetDirectoryName(_vm.Game.Path)); for (int i = 0; i < monkeyIslandFileNames.Length; i++) { if (resource.Exists(monkeyIslandFileNames[i])) { return true; } } // GUI::MessageDialog dialog(_( // "Could not find the 'Monkey Island' Macintosh executable to read the\n" // "instruments from. Music will be disabled."), _("OK")); // dialog.runModal(); return false; }
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; }