Esempio n. 1
0
        public Player_AD(ScummEngine scumm, IMixer mixer)
        {
            _vm = scumm;
            _mixer = mixer;
            _rate = mixer.OutputRate;
            // TODO: vs OPL
            //        _opl2 = OPL::Config::create();
            _opl2 = new DosBoxOPL(OplType.Opl2);
            _opl2.Init(_rate);

            _samplesPerCallback = _rate / AD_CALLBACK_FREQUENCY;
            _samplesPerCallbackRemainder = _rate % AD_CALLBACK_FREQUENCY;
            _samplesTillCallback = 0;
            _samplesTillCallbackRemainder = 0;

            WriteReg(0x01, 0x00);
            WriteReg(0xBD, 0x00);
            WriteReg(0x08, 0x00);
            WriteReg(0x01, 0x20);

            _soundHandle = _mixer.PlayStream(SoundType.Plain, this, -1, Mixer.MaxChannelVolume, 0, false, true);

            _engineMusicTimer = 0;
            _soundPlaying = -1;

            _curOffset = 0;

            _sfxTimer = 4;
            _rndSeed = 1;

            for (int i = 0; i < _sfx.Length; ++i)
            {
                _sfx[i] = new SfxSlot();
                _sfx[i].Resource = -1;
                for (int j = 0; j < _sfx[i].Channels.Length; ++j)
                {
                    _sfx[i].Channels[j].HardwareChannel = -1;
                }
            }

            _numHWChannels = _hwChannels.Length;

            _musicVolume = _sfxVolume = 255;
            _isSeeking = false;
        }
Esempio n. 2
0
        bool StartSfx(SfxSlot sfx, byte[] resource)
        {
            WriteReg(0xBD, 0x00);

            // Clear the channels.
            sfx.Channels[0].State = ChannelState.Off;
            sfx.Channels[1].State = ChannelState.Off;
            sfx.Channels[2].State = ChannelState.Off;

            // Set up the first channel to pick up playback.
            // Try to allocate a hardware channel.
            sfx.Channels[0].HardwareChannel = AllocateHWChannel(sfx.Priority, sfx);
            if (sfx.Channels[0].HardwareChannel == -1)
            {
                Debug.WriteLine("AD No hardware channel available");
                return false;
            }
            sfx.Channels[0].MusicData = resource;
            sfx.Channels[0].CurrentOffset = sfx.Channels[0].StartOffset = 2;
            sfx.Channels[0].State = ChannelState.Parse;

            // Scan for the start of the other channels and set them up if required.
            int curChannel = 1;
            var bufferPosition = 2;
            byte command = 0;
            while ((command = resource[bufferPosition]) != 0xFF)
            {
                switch (command)
                {
                    case 1:
					// INSTRUMENT DEFINITION
                        bufferPosition += 15;
                        break;

                    case 2:
					// NOTE DEFINITION
                        bufferPosition += 11;
                        break;

                    case 0x80:
					// LOOP
                        bufferPosition += 1;
                        break;

                    default:
					// START OF CHANNEL
                        bufferPosition += 1;
                        if (curChannel >= 3)
                        {
                            throw new InvalidOperationException(string.Format("AD SFX resource {0} uses more than 3 channels", sfx.Resource));
                        }
                        sfx.Channels[curChannel].HardwareChannel = AllocateHWChannel(sfx.Priority, sfx);
                        if (sfx.Channels[curChannel].HardwareChannel == -1)
                        {
                            Debug.WriteLine("AD No hardware channel available");
                            return false;
                        }
                        sfx.Channels[curChannel].CurrentOffset = bufferPosition;
                        sfx.Channels[curChannel].StartOffset = bufferPosition;
                        sfx.Channels[curChannel].State = ChannelState.Parse;
                        ++curChannel;
                        break;
                }
            }

            return true;
        }
Esempio n. 3
0
        void StopSfx(SfxSlot sfx)
        {
            if (sfx.Resource == -1)
            {
                return;
            }

            // 1. step: Clear all the channels.
            for (int i = 0; i < sfx.Channels.Length; ++i)
            {
                if (sfx.Channels[i].State != ChannelState.Off)
                {
                    ClearChannel(sfx.Channels[i]);
                    sfx.Channels[i].State = ChannelState.Off;
                }

                if (sfx.Channels[i].HardwareChannel != -1)
                {
                    FreeHWChannel(sfx.Channels[i].HardwareChannel);
                    sfx.Channels[i].HardwareChannel = -1;
                }
            }

            // TODO: 2. step: Unlock the resource.
//			_vm._res.unlock(rtSound, sfx.resource);
            sfx.Resource = -1;
        }
Esempio n. 4
0
        int AllocateHWChannel(int priority, SfxSlot owner = null)
        {
            // We always reaLlocate the channel with the lowest priority in case none
            // is free.
            int channel = -1;
            int minPrio = priority;

            for (int i = 0; i < _numHWChannels; ++i)
            {
                if (!_hwChannels[i].Allocated)
                {
                    channel = i;
                    break;
                }

                // We don't allow SFX to reallocate their own channels. Otherwise we
                // would call stopSfx in the midst of startSfx and that can lead to
                // horrible states...
                // We also prevent the music from reallocating its own channels like
                // in the original.
                if (_hwChannels[i].Priority <= minPrio && _hwChannels[i].SfxOwner != owner)
                {
                    minPrio = _hwChannels[i].Priority;
                    channel = i;
                }
            }

            if (channel != -1)
            {
                // In case the HW channel belongs to a SFX we will completely
                // stop playback of that SFX.
                // TODO: Maybe be more fine grained in the future and allow
                // detachment of individual channels of a SFX?
                if (_hwChannels[channel].Allocated && _hwChannels[channel].SfxOwner != null)
                {
                    StopSfx(_hwChannels[channel].SfxOwner);
                }

                _hwChannels[channel].Allocated = true;
                _hwChannels[channel].Priority = priority;
                _hwChannels[channel].SfxOwner = owner;
            }

            return channel;
        }