ScummVM API documentation
psound.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef MADS_NEBULAR_SOUND_PSOUND_H
23 #define MADS_NEBULAR_SOUND_PSOUND_H
24 
25 #include "mads/core/native_sound_timer.h"
26 #include "mads/core/sound_manager.h"
27 
28 namespace OPL {
29 class OPL;
30 }
31 
32 namespace MADS {
33 namespace RexNebular {
34 namespace Sound {
35 
38  uint16 panning;
39  uint16 frequency;
40  uint16 bank;
41  uint16 channel;
42  uint16 operators;
43 };
44 
47  const char *filename;
48  int dataOffset;
49  int initializedDataSize;
50  int totalDataSize;
51  uint16 nullSequenceOffset;
52  uint16 patchTableOffset;
53  byte patchCount;
54  byte musicChannelCount;
55  PSoundTableLayout tables;
56 };
57 
59 class PSound : public SoundDriver {
60 public:
61  enum {
62  kChannelCount = 9,
63  kMusicChannelCount = 6,
64  kPatchSize = 64,
65  kOpcodeBudgetPerTick = 256
66  };
67 
68  enum RegisterBank {
69  kFirstBank = 1,
70  kSecondBank = 2,
71  kBothBanks = kFirstBank | kSecondBank
72  };
73 
74 protected:
76  struct Channel {
77  byte activeCount; // +00
78  int8 pitchBend; // +01
79  int8 volumeFadeStep; // +02
80  int8 panningFadeStep; // +03
81  byte note; // +04
82  byte patch; // +05
83  byte volume; // +06
84  byte noteOffset; // +07
85  byte keyOnDelay; // +08
86  byte volumeFadeCounter; // +09
87  byte volumeFadeReload; // +0a
88  byte panningFadeCounter; // +0b
89  byte panningFadeReload; // +0c
90  byte panning; // +0d
91  int8 volumeOffset; // +0e
92  byte mode; // +0f
93  byte operatorTotalLevel[4]; // +10..+13
94  uint16 sequenceStart; // +14
95  uint16 position; // +16
96  uint16 innerLoopStart; // +18
97  uint16 outerLoopStart; // +1a
98  uint16 innerLoopCount; // +1c
99  uint16 outerLoopCount; // +1e
100  uint16 originalSequence; // +20
101  int8 transpose; // +22
102  int8 noteTranspose; // +23
103  byte pendingStop; // +24
104  int8 patchAttenuation; // +25
105 
106  void reset();
107  void load(uint16 sequenceOffset);
108  };
109 
110  struct ChannelData {
111  byte noiseMode;
112  uint16 frequencyMask;
113  uint16 frequencyBase;
114  int16 frequencyStep;
115 
116  void reset();
117  };
118 
119  OPL::OPL *_opl;
120  byte _registerCache[2][256];
121  NativeSoundTimer _hostTimer;
122  Channel _channels[kChannelCount];
123  ChannelData _channelData[kChannelCount];
124 
125  int _masterVolume;
126  uint16 _randomSeed;
127  uint16 _frameCounter;
128  int16 _pollResult;
129  int8 _resultFlag;
130  uint16 _nullSequenceOffset;
131  uint16 _patchTableOffset;
132  PSoundTableLayout _tableLayout;
133  byte _patchCount;
134  byte _musicChannelCount;
135  int _commandParam;
136  bool _updatesEnabled;
137  // Host-owned gate for native export 4; changed only by export-3 results.
138  bool _noiseServiceEnabled;
139 
140  byte _noiseTicks[2];
141  byte _savedNoiseTicks[2];
142  byte _noiseChannel[2];
143  uint16 _noiseMask[2];
144  int32 _noiseBase[2];
145  int16 _noiseStep[2];
146  bool _noiseState;
147 
148  PSound(Audio::Mixer *mixer, const PSoundDriverData &driverData);
149  ~PSound() override;
150 
151  bool isDataRangeValid(uint32 offset, uint32 length) const;
152  void requireDataRange(uint32 offset, uint32 length, const char *operation) const;
153  const byte *getDataPointer(uint32 offset, uint32 length,
154  const char *operation) const;
155  byte *getDataPointer(uint32 offset, uint32 length, const char *operation);
156  void validateDataLayout(const PSoundDriverData &driverData) const;
157 
158  byte readDataByte(uint32 offset) const;
159  uint16 readDataUint16(uint32 offset) const;
160  void writeDataByte(uint32 offset, byte value);
161  void writeDataUint16(uint32 offset, uint16 value);
162 
163  byte getBankMask(uint channel) const;
164  byte getOplChannel(uint channel) const;
165  byte getOperatorOffset(uint channel, uint operatorIndex) const;
166  const byte *getPatch(uint patchIndex) const;
167  byte getPanningAttenuation(byte panning) const;
168  uint16 getFrequencyNumber(byte semitone) const;
169 
170  void writeRegister(byte banks, byte reg, byte value);
171  byte getCachedRegister(byte banks, byte reg) const;
172  void resetDriver();
173  virtual int command0();
174  int command1();
175  int command2();
176  int command3();
177  int command4();
178  int command5();
179  int command6();
180  int command7();
181  int command8();
182  int nullCommand() {
183  return 0;
184  }
185 
186  void loadChannel(uint channel, uint16 sequenceOffset);
187  void playSound(uint16 sequenceOffset);
188  void playSoundAny(uint16 sequenceOffset);
189  bool isSoundActive(uint16 sequenceOffset) const;
190  void requestStop(uint firstChannel, uint endChannel);
191  void setCurrentSequence(uint firstChannel, uint endChannel,
192  uint16 sequenceOffset);
193 
194  void onTimer();
195  int serviceUpdate();
196  void serviceNoise();
197  void update();
198  virtual void tickCallback() {
199  }
200  virtual byte getStopFadeReload() const {
201  return 4;
202  }
203  void updateChannel(uint channelIndex);
204  bool executeOpcode(uint channelIndex, byte opcode, bool &levelsDirty);
205  void checkPendingStops();
206  void finishChannel(uint channelIndex);
207 
208  void loadPatch(uint channelIndex, byte patchIndex);
209  void programOperator(byte banks, uint channelIndex, uint operatorIndex,
210  const byte *operatorData);
211  void updatePanning(uint channelIndex);
212  void updateChannelLevels(uint channelIndex);
213  void updateChannelFrequency(uint channelIndex, bool keyOn);
214  void updatePitchBend(uint channelIndex);
215  void keyOff(uint channelIndex);
216  void startNoise(uint channelIndex);
217  void updateNoise();
218  void setNoiseFrequency(uint channelIndex, int frequency);
219  void resultCheck();
220 
221  uint16 nextRandom();
222  byte scaledCommandParameter(int param) const;
223 
224 public:
225  static void validate(bool isDemo);
226  bool isReady() const { return _opl != nullptr; }
227 
228  int stop() override;
229  int poll() override;
230  void noise() override;
231  void setVolume(int volume) override;
232 };
233 
234 } // namespace Sound
235 } // namespace RexNebular
236 } // namespace MADS
237 
238 #endif // MADS_NEBULAR_SOUND_PSOUND_H
Definition: mixer.h:70
Definition: native_sound_timer.h:33
Definition: sound_manager.h:40
Definition: fmopl.h:35
Definition: anim_timer.h:27
Definition: psound.h:59
Definition: fmopl.h:116