ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
tfmx.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 // Only compiled if SCUMM is built-in or we're building for dynamic modules
23 #if !defined(AUDIO_MODS_TFMX_H) && (defined(ENABLE_SCUMM) || defined(DYNAMIC_MODULES))
24 #define AUDIO_MODS_TFMX_H
25 
26 #include "audio/mods/paula.h"
27 
28 namespace Audio {
29 
30 class Tfmx : public Paula {
31 public:
32  Tfmx(int rate, bool stereo);
33  virtual ~Tfmx();
34 
42  void stopSong(bool stopAudio = true) { Common::StackLock lock(_mutex); stopSongImpl(stopAudio); }
52  void doSong(int songPos, bool stopAudio = false);
61  int doSfx(uint16 sfxIndex, bool unlockChannel = false);
67  void stopMacroEffect(int channel);
68 
69  void doMacro(int note, int macro, int relVol = 0, int finetune = 0, int channelNo = 0);
70  int getTicks() const { return _playerCtx.tickCount; }
71  int getSongIndex() const { return _playerCtx.song; }
72  void setSignalPtr(uint16 *ptr, uint16 numSignals) { _playerCtx.signal = ptr; _playerCtx.numSignals = numSignals; }
73  void freeResources() { _deleteResource = true; freeResourceDataImpl(); }
74  bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData, bool autoDelete = true);
75  void setModuleData(Tfmx &otherPlayer);
76 
77 protected:
78  void interrupt();
79 
80 private:
81  enum { kPalDefaultCiaVal = 11822, kNtscDefaultCiaVal = 14320, kCiaBaseInterval = 0x1B51F8 };
82  enum { kNumVoices = 4, kNumChannels = 8, kNumSubsongs = 32, kMaxPatternOffsets = 128, kMaxMacroOffsets = 128 };
83 
84  struct MdatResource {
85  const byte *mdatAlloc;
86  const byte *mdatData;
87  uint32 mdatLen;
88 
89  uint16 headerFlags;
90 // uint32 headerUnknown;
91 // char textField[6 * 40];
92 
93  struct Subsong {
94  uint16 songstart;
95  uint16 songend;
96  uint16 tempo;
97  } subsong[kNumSubsongs];
98 
99  uint32 trackstepOffset;
100  uint32 sfxTableOffset;
101 
102  uint32 patternOffset[kMaxPatternOffsets];
103  uint32 macroOffset[kMaxMacroOffsets];
104 
105  void boundaryCheck(const void *address, size_t accessLen = 1) const {
106  assert(mdatAlloc <= address && (const byte *)address + accessLen <= (const byte *)mdatData + mdatLen);
107  }
108  } const *_resource;
109 
110  struct SampleResource {
111  const int8 *sampleData;
112  uint32 sampleLen;
113 
114  void boundaryCheck(const void *address, size_t accessLen = 2) const {
115  assert(sampleData <= address && (const byte *)address + accessLen <= (const byte *)sampleData + sampleLen);
116  }
117  } _resourceSample;
118 
119  bool _deleteResource;
120 
121  bool hasResources() {
122  return _resource && _resource->mdatLen && _resourceSample.sampleLen;
123  }
124 
125  struct ChannelContext {
126  byte paulaChannel;
127 
128 // byte macroIndex;
129  uint16 macroWait;
130  uint32 macroOffset;
131  uint32 macroReturnOffset;
132  uint16 macroStep;
133  uint16 macroReturnStep;
134  uint8 macroLoopCount;
135  bool macroRun;
136  int8 macroSfxRun;
137 
138  uint32 customMacro;
139  uint8 customMacroIndex;
140  uint8 customMacroPrio;
141 
142  bool sfxLocked;
143  int16 sfxLockTime;
144  bool keyUp;
145 
146  bool deferWait;
147  uint16 dmaIntCount;
148 
149  uint32 sampleStart;
150  uint16 sampleLen;
151  uint16 refPeriod;
152  uint16 period;
153 
154  int8 volume;
155  uint8 relVol;
156  uint8 note;
157  uint8 prevNote;
158  int16 fineTune; // always a signextended byte
159 
160  uint8 portaSkip;
161  uint8 portaCount;
162  uint16 portaDelta;
163  uint16 portaValue;
164 
165  uint8 envSkip;
166  uint8 envCount;
167  uint8 envDelta;
168  int8 envEndVolume;
169 
170  uint8 vibLength;
171  uint8 vibCount;
172  int16 vibValue;
173  int8 vibDelta;
174 
175  uint8 addBeginLength;
176  uint8 addBeginCount;
177  int32 addBeginDelta;
178  } _channelCtx[kNumVoices];
179 
180  struct PatternContext {
181  uint32 offset; // patternStart, Offset from mdat
182  uint32 savedOffset; // for subroutine calls
183  uint16 step; // distance from patternStart
184  uint16 savedStep;
185 
186  uint8 command;
187  int8 expose;
188  uint8 loopCount;
189  uint8 wait;
190  } _patternCtx[kNumChannels];
191 
192  struct TrackStepContext {
193  uint16 startInd;
194  uint16 stopInd;
195  uint16 posInd;
196  int16 loopCount;
197  } _trackCtx;
198 
199  struct PlayerContext {
200  int8 song;
201 
202  uint16 patternCount;
203  uint16 patternSkip;
204 
205  int8 volume;
206 
207  uint8 fadeSkip;
208  uint8 fadeCount;
209  int8 fadeEndVolume;
210  int8 fadeDelta;
211 
212  int tickCount;
213 
214  uint16 *signal;
215  uint16 numSignals;
216 
217  bool stopWithLastPattern;
218  } _playerCtx;
219 
220  const byte *getSfxPtr(uint16 index = 0) const {
221  const byte *sfxPtr = (const byte *)(_resource->mdatData + _resource->sfxTableOffset + index * 8);
222 
223  _resource->boundaryCheck(sfxPtr, 8);
224  return sfxPtr;
225  }
226 
227  const uint16 *getTrackPtr(uint16 trackstep = 0) const {
228  const uint16 *trackData = (const uint16 *)(_resource->mdatData + _resource->trackstepOffset + 16 * trackstep);
229 
230  _resource->boundaryCheck(trackData, 16);
231  return trackData;
232  }
233 
234  const uint32 *getPatternPtr(uint32 offset) const {
235  const uint32 *pattData = (const uint32 *)(_resource->mdatData + offset);
236 
237  _resource->boundaryCheck(pattData, 4);
238  return pattData;
239  }
240 
241  const uint32 *getMacroPtr(uint32 offset) const {
242  const uint32 *macroData = (const uint32 *)(_resource->mdatData + offset);
243 
244  _resource->boundaryCheck(macroData, 4);
245  return macroData;
246  }
247 
248  const int8 *getSamplePtr(const uint32 offset) const {
249  const int8 *sample = _resourceSample.sampleData + offset;
250 
251  _resourceSample.boundaryCheck(sample, 2);
252  return sample;
253  }
254 
255  static inline void initMacroProgramm(ChannelContext &channel);
256  static inline void clearEffects(ChannelContext &channel);
257  static inline void haltMacroProgramm(ChannelContext &channel);
258  static inline void unlockMacroChannel(ChannelContext &channel);
259  static inline void initPattern(PatternContext &pattern, uint8 cmd, int8 expose, uint32 offset);
260  void stopSongImpl(bool stopAudio = true);
261  static inline void setNoteMacro(ChannelContext &channel, uint note, int fineTune);
262  void initFadeCommand(const uint8 fadeTempo, const int8 endVol);
263  void setModuleData(const MdatResource *resource, const int8 *sampleData, uint32 sampleLen, bool autoDelete = true);
264  static const MdatResource *loadMdatFile(Common::SeekableReadStream &musicData);
265  static const int8 *loadSampleFile(uint32 &sampleLen, Common::SeekableReadStream &sampleStream);
266  void freeResourceDataImpl();
267  void effects(ChannelContext &channel);
268  void macroRun(ChannelContext &channel);
269  void advancePatterns();
270  bool patternRun(PatternContext &pattern);
271  bool trackRun(bool incStep = false);
272  void noteCommand(uint8 note, uint8 param1, uint8 param2, uint8 param3);
273 };
274 
275 } // End of namespace Audio
276 
277 #endif // !defined(AUDIO_MODS_TFMX_H)
Definition: mutex.h:51
Definition: stream.h:745
Definition: system.h:38