ScummVM API documentation
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
28namespace Audio {
29
30class Tfmx : public Paula {
31public:
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
77protected:
78 void interrupt() override;
79
80private:
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: stream.h:745
Definition: mutex.h:51
Definition: system.h:39