diff options
Diffstat (limited to 'engines/scumm/player_ad.h')
-rw-r--r-- | engines/scumm/player_ad.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/engines/scumm/player_ad.h b/engines/scumm/player_ad.h new file mode 100644 index 0000000000..da6c7177ef --- /dev/null +++ b/engines/scumm/player_ad.h @@ -0,0 +1,190 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_PLAYER_AD_H +#define SCUMM_PLAYER_AD_H + +#include "scumm/music.h" + +#include "audio/audiostream.h" +#include "audio/mixer.h" + +#include "common/mutex.h" + +namespace OPL { +class OPL; +} + +namespace Scumm { + +class ScummEngine; + +/** + * Sound output for v3/v4 AdLib data. + */ +class Player_AD : public MusicEngine, public Audio::AudioStream { +public: + Player_AD(ScummEngine *scumm, Audio::Mixer *mixer); + virtual ~Player_AD(); + + // MusicEngine API + virtual void setMusicVolume(int vol); + virtual void startSound(int sound); + virtual void stopSound(int sound); + virtual void stopAllSounds(); + virtual int getMusicTimer(); + virtual int getSoundStatus(int sound) const; + + virtual void saveLoadWithSerializer(Serializer *ser); + + // AudioStream API + virtual int readBuffer(int16 *buffer, const int numSamples); + virtual bool isStereo() const { return false; } + virtual bool endOfData() const { return false; } + virtual int getRate() const { return _rate; } + +private: + ScummEngine *const _vm; + Common::Mutex _mutex; + Audio::Mixer *const _mixer; + const int _rate; + Audio::SoundHandle _soundHandle; + void setupVolume(); + + OPL::OPL *_opl2; + + int _samplesPerCallback; + int _samplesPerCallbackRemainder; + int _samplesTillCallback; + int _samplesTillCallbackRemainder; + + int _soundPlaying; + int _engineMusicTimer; + + // AdLib register utilities + uint8 _registerBackUpTable[256]; + void writeReg(int r, int v); + uint8 readReg(int r) const; + + // Instrument setup + void setupChannel(const uint channel, uint instrOffset) { + setupChannel(channel, _resource + instrOffset); + } + void setupChannel(const uint channel, const byte *instrOffset); + void setupOperator(const uint opr, const byte *&instrOffset); + static const int _operatorOffsetTable[18]; + + // Sound data + const byte *_resource; + + // Music handling + void startMusic(); + void updateMusic(); + void noteOff(uint channel); + int findFreeChannel(); + void setupFrequency(uint channel, int8 frequency); + void setupRhythm(uint rhythmInstr, uint instrOffset); + + uint _timerLimit; + uint _musicTicks; + uint _musicTimer; + uint _internalMusicTimer; + bool _loopFlag; + uint _musicLoopStart; + uint _instrumentOffset[16]; + uint _channelLastEvent[9]; + uint _channelFrequency[9]; + uint _channelB0Reg[9]; + + uint _mdvdrState; + uint _voiceChannels; + + uint _curOffset; + uint _nextEventTimer; + + static const uint _noteFrequencies[12]; + static const uint _mdvdrTable[6]; + static const uint _rhythmOperatorTable[6]; + static const uint _rhythmChannelTable[6]; + + // SFX handling + void startSfx(); + void updateSfx(); + void clearChannel(int channel); + void updateChannel(int channel); + void parseSlot(int channel); + void updateSlot(int channel); + void parseNote(int channel, int num, const byte *offset); + bool processNote(int note, const byte *offset); + void noteOffOn(int channel); + void writeRegisterSpecial(int note, uint8 value, int offset); + uint8 readRegisterSpecial(int note, uint8 defaultValue, int offset); + void setupNoteEnvelopeState(int note, int steps, int adjust); + bool processNoteEnvelope(int note, int &instrumentValue); + + int _sfxTimer; + + int _sfxResource[3]; + int _sfxPriority[3]; + + struct Channel { + int state; + const byte *currentOffset; + const byte *startOffset; + uint8 instrumentData[7]; + } _channels[11]; + + uint8 _rndSeed; + uint8 getRnd(); + + struct Note { + int state; + int playTime; + int sustainTimer; + int instrumentValue; + int bias; + int preIncrease; + int adjust; + + struct Envelope { + int stepIncrease; + int step; + int stepCounter; + int timer; + } envelope; + } _notes[22]; + + static const uint _noteBiasTable[7]; + static const uint _numStepsTable[16]; + static const uint _noteAdjustScaleTable[7]; + static const uint _noteAdjustTable[16]; + static const bool _useOperatorTable[7]; + static const uint _channelOffsetTable[11]; + static const uint _channelOperatorOffsetTable[7]; + static const uint _baseRegisterTable[7]; + static const uint _registerMaskTable[7]; + static const uint _registerShiftTable[7]; +}; + +} // End of namespace Scumm + +#endif |