1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef SCUMM_PLAYERS_PLAYER_AD_H 24 #define SCUMM_PLAYERS_PLAYER_AD_H 25 26 #include "scumm/music.h" 27 28 #include "common/mutex.h" 29 #include "common/serializer.h" 30 31 namespace OPL { 32 class OPL; 33 } 34 35 namespace Scumm { 36 37 class ScummEngine; 38 39 /** 40 * Sound output for v3/v4 AdLib data. 41 */ 42 class Player_AD : public MusicEngine { 43 public: 44 Player_AD(ScummEngine *scumm, Common::Mutex &mutex); 45 ~Player_AD() override; 46 47 // MusicEngine API 48 void setMusicVolume(int vol) override; 49 void startSound(int sound) override; 50 void stopSound(int sound) override; 51 void stopAllSounds() override; 52 int getMusicTimer() override; 53 int getSoundStatus(int sound) const override; 54 55 void saveLoadWithSerializer(Common::Serializer &ser) override; 56 57 // Timer callback 58 void onTimer(); 59 60 private: 61 ScummEngine *const _vm; 62 Common::Mutex &_mutex; 63 64 void setupVolume(); 65 int _musicVolume; 66 int _sfxVolume; 67 68 OPL::OPL *_opl2; 69 70 int _musicResource; 71 int32 _engineMusicTimer; 72 73 struct SfxSlot; 74 75 struct HardwareChannel { 76 bool allocated; 77 int priority; 78 SfxSlot *sfxOwner; 79 } _hwChannels[9]; 80 int _numHWChannels; 81 static const int _operatorOffsetToChannel[22]; 82 83 int allocateHWChannel(int priority, SfxSlot *owner = nullptr); 84 void freeHWChannel(int channel); 85 void limitHWChannels(int newCount); 86 87 // AdLib register utilities 88 uint8 _registerBackUpTable[256]; 89 void writeReg(int r, int v); 90 uint8 readReg(int r) const; 91 92 // Instrument setup 93 void setupChannel(const uint channel, const byte *instrOffset); 94 void setupOperator(const uint opr, const byte *&instrOffset); 95 static const int _operatorOffsetTable[18]; 96 97 // Music handling 98 void startMusic(); 99 void stopMusic(); 100 void updateMusic(); 101 bool parseCommand(); 102 uint parseVLQ(); 103 void noteOff(uint channel); 104 void setupFrequency(uint channel, int8 frequency); 105 void setupRhythm(uint rhythmInstr, uint instrOffset); 106 107 const byte *_musicData; 108 uint _timerLimit; 109 uint _musicTicks; 110 uint32 _musicTimer; 111 uint32 _internalMusicTimer; 112 bool _loopFlag; 113 uint _musicLoopStart; 114 uint _instrumentOffset[16]; 115 116 struct VoiceChannel { 117 uint lastEvent; 118 uint frequency; 119 uint b0Reg; 120 } _voiceChannels[9]; 121 void freeVoiceChannel(uint channel); 122 123 void musicSeekTo(const uint position); 124 bool _isSeeking; 125 126 uint _mdvdrState; 127 128 uint32 _curOffset; 129 uint32 _nextEventTimer; 130 131 static const uint _noteFrequencies[12]; 132 static const uint _mdvdrTable[6]; 133 static const uint _rhythmOperatorTable[6]; 134 static const uint _rhythmChannelTable[6]; 135 136 // SFX handling 137 enum { 138 kNoteStatePreInit = -1, 139 kNoteStateAttack = 0, 140 kNoteStateDecay = 1, 141 kNoteStateSustain = 2, 142 kNoteStateRelease = 3, 143 kNoteStateOff = 4 144 }; 145 146 struct Note { 147 int state; 148 int playTime; 149 int sustainTimer; 150 int instrumentValue; 151 int bias; 152 int preIncrease; 153 int adjust; 154 155 struct Envelope { 156 int stepIncrease; 157 int step; 158 int stepCounter; 159 int timer; 160 } envelope; 161 }; 162 163 enum { 164 kChannelStateOff = 0, 165 kChannelStateParse = 1, 166 kChannelStatePlay = 2 167 }; 168 169 struct Channel { 170 int state; 171 const byte *currentOffset; 172 const byte *startOffset; 173 uint8 instrumentData[7]; 174 175 Note notes[2]; 176 177 int hardwareChannel; 178 }; 179 180 struct SfxSlot { 181 int resource; 182 int priority; 183 184 Channel channels[3]; 185 } _sfx[3]; 186 187 SfxSlot *allocateSfxSlot(int priority); 188 bool startSfx(SfxSlot *sfx, const byte *resource); 189 void stopSfx(SfxSlot *sfx); 190 191 void updateSfx(); 192 void clearChannel(const Channel &channel); 193 void updateChannel(Channel *channel); 194 void parseSlot(Channel *channel); 195 void updateSlot(Channel *channel); 196 void parseNote(Note *note, const Channel &channel, const byte *offset); 197 bool processNote(Note *note, const Channel &channel, const byte *offset); 198 void noteOffOn(int channel); 199 void writeRegisterSpecial(int channel, uint8 value, int offset); 200 uint8 readRegisterSpecial(int channel, uint8 defaultValue, int offset); 201 void setupNoteEnvelopeState(Note *note, int steps, int adjust); 202 bool processNoteEnvelope(Note *note); 203 204 int _sfxTimer; 205 206 uint8 _rndSeed; 207 uint8 getRnd(); 208 209 static const uint _noteBiasTable[7]; 210 static const uint _numStepsTable[16]; 211 static const uint _noteAdjustScaleTable[7]; 212 static const uint _noteAdjustTable[16]; 213 static const bool _useOperatorTable[7]; 214 static const uint _channelOffsetTable[11]; 215 static const uint _channelOperatorOffsetTable[7]; 216 static const uint _baseRegisterTable[7]; 217 static const uint _registerMaskTable[7]; 218 static const uint _registerShiftTable[7]; 219 }; 220 221 } // End of namespace Scumm 222 223 #endif 224