Class for handling Mac data and resource forks. It can read from raw, MacBinary, and AppleDouble formats.
Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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;
        }