rlm@1
|
1 #ifdef WIN32
|
rlm@1
|
2 # include "../win32/stdafx.h"
|
rlm@1
|
3 # include "../win32/VBA.h"
|
rlm@1
|
4 #endif
|
rlm@1
|
5
|
rlm@1
|
6 #include <cstring>
|
rlm@1
|
7 #include <cassert>
|
rlm@1
|
8
|
rlm@1
|
9 #include "../common/System.h"
|
rlm@1
|
10 #include "../common/Util.h"
|
rlm@1
|
11 //#include "../Blip_Buffer.h"
|
rlm@1
|
12 #include "gbGlobals.h"
|
rlm@1
|
13 #include "gbSound.h"
|
rlm@1
|
14
|
rlm@1
|
15 #ifndef countof
|
rlm@1
|
16 #define countof(a) (sizeof(a) / sizeof(a[0]))
|
rlm@1
|
17 #endif
|
rlm@1
|
18
|
rlm@1
|
19 extern u8 soundBuffer[6][735];
|
rlm@1
|
20 extern u16 soundFinalWave[1470];
|
rlm@1
|
21 extern u16 soundFrameSound[735 * 30 * 2];
|
rlm@1
|
22 extern int32 soundVolume;
|
rlm@1
|
23
|
rlm@1
|
24 soundtick_t GB_USE_TICKS_AS = 24; // (1048576.0/44100.0); // FIXME: (4194304.0/70224.0)(fps) vs 60.0fps?
|
rlm@1
|
25
|
rlm@1
|
26 #define SOUND_MAGIC 0x60000000
|
rlm@1
|
27 #define SOUND_MAGIC_2 0x30000000
|
rlm@1
|
28 #define NOISE_MAGIC (2097152.0 / 44100.0)
|
rlm@1
|
29
|
rlm@1
|
30 extern int32 speed;
|
rlm@1
|
31
|
rlm@1
|
32 extern u8 soundWavePattern[4][32];
|
rlm@1
|
33
|
rlm@1
|
34 extern u32 soundBufferLen;
|
rlm@1
|
35 extern u32 soundBufferTotalLen;
|
rlm@1
|
36 extern int32 soundQuality;
|
rlm@1
|
37 extern int32 soundPaused;
|
rlm@1
|
38 extern int32 soundPlay;
|
rlm@1
|
39 extern soundtick_t soundTicks;
|
rlm@1
|
40 extern soundtick_t SOUND_CLOCK_TICKS;
|
rlm@1
|
41 extern u32 soundNextPosition;
|
rlm@1
|
42
|
rlm@1
|
43 extern int32 soundLevel1;
|
rlm@1
|
44 extern int32 soundLevel2;
|
rlm@1
|
45 extern int32 soundBalance;
|
rlm@1
|
46 extern int32 soundMasterOn;
|
rlm@1
|
47 extern u32 soundIndex;
|
rlm@1
|
48 extern u32 soundBufferIndex;
|
rlm@1
|
49 extern int32 soundFrameSoundWritten;
|
rlm@1
|
50 int32 soundVIN = 0;
|
rlm@1
|
51 extern int32 soundDebug;
|
rlm@1
|
52
|
rlm@1
|
53 extern int32 sound1On;
|
rlm@1
|
54 extern int32 sound1ATL;
|
rlm@1
|
55 extern int32 sound1Skip;
|
rlm@1
|
56 extern int32 sound1Index;
|
rlm@1
|
57 extern int32 sound1Continue;
|
rlm@1
|
58 extern int32 sound1EnvelopeVolume;
|
rlm@1
|
59 extern int32 sound1EnvelopeATL;
|
rlm@1
|
60 extern int32 sound1EnvelopeUpDown;
|
rlm@1
|
61 extern int32 sound1EnvelopeATLReload;
|
rlm@1
|
62 extern int32 sound1SweepATL;
|
rlm@1
|
63 extern int32 sound1SweepATLReload;
|
rlm@1
|
64 extern int32 sound1SweepSteps;
|
rlm@1
|
65 extern int32 sound1SweepUpDown;
|
rlm@1
|
66 extern int32 sound1SweepStep;
|
rlm@1
|
67 extern u8 * sound1Wave;
|
rlm@1
|
68
|
rlm@1
|
69 extern int32 sound2On;
|
rlm@1
|
70 extern int32 sound2ATL;
|
rlm@1
|
71 extern int32 sound2Skip;
|
rlm@1
|
72 extern int32 sound2Index;
|
rlm@1
|
73 extern int32 sound2Continue;
|
rlm@1
|
74 extern int32 sound2EnvelopeVolume;
|
rlm@1
|
75 extern int32 sound2EnvelopeATL;
|
rlm@1
|
76 extern int32 sound2EnvelopeUpDown;
|
rlm@1
|
77 extern int32 sound2EnvelopeATLReload;
|
rlm@1
|
78 extern u8 * sound2Wave;
|
rlm@1
|
79
|
rlm@1
|
80 extern int32 sound3On;
|
rlm@1
|
81 extern int32 sound3ATL;
|
rlm@1
|
82 extern int32 sound3Skip;
|
rlm@1
|
83 extern int32 sound3Index;
|
rlm@1
|
84 extern int32 sound3Continue;
|
rlm@1
|
85 extern int32 sound3OutputLevel;
|
rlm@1
|
86 extern int32 sound3Last;
|
rlm@1
|
87
|
rlm@1
|
88 extern int32 sound4On;
|
rlm@1
|
89 extern int32 sound4Clock;
|
rlm@1
|
90 extern int32 sound4ATL;
|
rlm@1
|
91 extern int32 sound4Skip;
|
rlm@1
|
92 extern int32 sound4Index;
|
rlm@1
|
93 extern int32 sound4ShiftRight;
|
rlm@1
|
94 extern int32 sound4ShiftSkip;
|
rlm@1
|
95 extern int32 sound4ShiftIndex;
|
rlm@1
|
96 extern int32 sound4NSteps;
|
rlm@1
|
97 extern int32 sound4CountDown;
|
rlm@1
|
98 extern int32 sound4Continue;
|
rlm@1
|
99 extern int32 sound4EnvelopeVolume;
|
rlm@1
|
100 extern int32 sound4EnvelopeATL;
|
rlm@1
|
101 extern int32 sound4EnvelopeUpDown;
|
rlm@1
|
102 extern int32 sound4EnvelopeATLReload;
|
rlm@1
|
103
|
rlm@1
|
104 extern int32 soundEnableFlag;
|
rlm@1
|
105 extern int32 soundMutedFlag;
|
rlm@1
|
106
|
rlm@1
|
107 extern int32 soundFreqRatio[8];
|
rlm@1
|
108 extern int32 soundShiftClock[16];
|
rlm@1
|
109
|
rlm@1
|
110 extern s16 soundFilter[4000];
|
rlm@1
|
111 extern s16 soundLeft[5];
|
rlm@1
|
112 extern s16 soundRight[5];
|
rlm@1
|
113 extern int32 soundEchoIndex;
|
rlm@1
|
114 extern bool8 soundEcho;
|
rlm@1
|
115 extern bool8 soundLowPass;
|
rlm@1
|
116 extern bool8 soundReverse;
|
rlm@1
|
117 extern bool8 soundOffFlag;
|
rlm@1
|
118
|
rlm@1
|
119 bool8 gbDigitalSound = false;
|
rlm@1
|
120
|
rlm@1
|
121 void gbSoundEvent(register u16 address, register int data)
|
rlm@1
|
122 {
|
rlm@1
|
123 int freq = 0;
|
rlm@1
|
124
|
rlm@1
|
125 gbMemory[address] = data;
|
rlm@1
|
126
|
rlm@1
|
127 #ifndef FINAL_VERSION
|
rlm@1
|
128 if (soundDebug)
|
rlm@1
|
129 {
|
rlm@1
|
130 // don't translate. debug only
|
rlm@1
|
131 log("Sound event: %08lx %02x\n", address, data);
|
rlm@1
|
132 }
|
rlm@1
|
133 #endif
|
rlm@1
|
134 switch (address)
|
rlm@1
|
135 {
|
rlm@1
|
136 case NR10:
|
rlm@1
|
137 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
|
rlm@1
|
138 sound1SweepSteps = data & 7;
|
rlm@1
|
139 sound1SweepUpDown = data & 0x08;
|
rlm@1
|
140 sound1SweepStep = 0;
|
rlm@1
|
141 break;
|
rlm@1
|
142 case NR11:
|
rlm@1
|
143 sound1Wave = soundWavePattern[data >> 6];
|
rlm@1
|
144 sound1ATL = 172 * (64 - (data & 0x3f));
|
rlm@1
|
145 break;
|
rlm@1
|
146 case NR12:
|
rlm@1
|
147 sound1EnvelopeVolume = data >> 4;
|
rlm@1
|
148 sound1EnvelopeUpDown = data & 0x08;
|
rlm@1
|
149 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);
|
rlm@1
|
150 break;
|
rlm@1
|
151 case NR13:
|
rlm@1
|
152 freq = (((int)(gbMemory[NR14] & 7)) << 8) | data;
|
rlm@1
|
153 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
|
rlm@1
|
154 freq = 2048 - freq;
|
rlm@1
|
155 if (freq)
|
rlm@1
|
156 {
|
rlm@1
|
157 sound1Skip = SOUND_MAGIC / freq;
|
rlm@1
|
158 }
|
rlm@1
|
159 else
|
rlm@1
|
160 sound1Skip = 0;
|
rlm@1
|
161 break;
|
rlm@1
|
162 case NR14:
|
rlm@1
|
163 freq = (((int)(data & 7) << 8) | gbMemory[NR13]);
|
rlm@1
|
164 freq = 2048 - freq;
|
rlm@1
|
165 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
|
rlm@1
|
166 sound1Continue = data & 0x40;
|
rlm@1
|
167 if (freq)
|
rlm@1
|
168 {
|
rlm@1
|
169 sound1Skip = SOUND_MAGIC / freq;
|
rlm@1
|
170 }
|
rlm@1
|
171 else
|
rlm@1
|
172 sound1Skip = 0;
|
rlm@1
|
173 if (data & 0x80)
|
rlm@1
|
174 {
|
rlm@1
|
175 gbMemory[NR52] |= 1;
|
rlm@1
|
176 sound1EnvelopeVolume = gbMemory[NR12] >> 4;
|
rlm@1
|
177 sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;
|
rlm@1
|
178 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
|
rlm@1
|
179 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);
|
rlm@1
|
180 sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);
|
rlm@1
|
181 sound1SweepSteps = gbMemory[NR10] & 7;
|
rlm@1
|
182 sound1SweepUpDown = gbMemory[NR10] & 0x08;
|
rlm@1
|
183 sound1SweepStep = 0;
|
rlm@1
|
184
|
rlm@1
|
185 sound1Index = 0;
|
rlm@1
|
186 sound1On = 1;
|
rlm@1
|
187 }
|
rlm@1
|
188 break;
|
rlm@1
|
189 case NR21:
|
rlm@1
|
190 sound2Wave = soundWavePattern[data >> 6];
|
rlm@1
|
191 sound2ATL = 172 * (64 - (data & 0x3f));
|
rlm@1
|
192 break;
|
rlm@1
|
193 case NR22:
|
rlm@1
|
194 sound2EnvelopeVolume = data >> 4;
|
rlm@1
|
195 sound2EnvelopeUpDown = data & 0x08;
|
rlm@1
|
196 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);
|
rlm@1
|
197 break;
|
rlm@1
|
198 case NR23:
|
rlm@1
|
199 freq = (((int)(gbMemory[NR24] & 7)) << 8) | data;
|
rlm@1
|
200 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
|
rlm@1
|
201 freq = 2048 - freq;
|
rlm@1
|
202 if (freq)
|
rlm@1
|
203 {
|
rlm@1
|
204 sound2Skip = SOUND_MAGIC / freq;
|
rlm@1
|
205 }
|
rlm@1
|
206 else
|
rlm@1
|
207 sound2Skip = 0;
|
rlm@1
|
208 break;
|
rlm@1
|
209 case NR24:
|
rlm@1
|
210 freq = (((int)(data & 7) << 8) | gbMemory[NR23]);
|
rlm@1
|
211 freq = 2048 - freq;
|
rlm@1
|
212 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
|
rlm@1
|
213 sound2Continue = data & 0x40;
|
rlm@1
|
214 if (freq)
|
rlm@1
|
215 {
|
rlm@1
|
216 sound2Skip = SOUND_MAGIC / freq;
|
rlm@1
|
217 }
|
rlm@1
|
218 else
|
rlm@1
|
219 sound2Skip = 0;
|
rlm@1
|
220 if (data & 0x80)
|
rlm@1
|
221 {
|
rlm@1
|
222 gbMemory[NR52] |= 2;
|
rlm@1
|
223 sound2EnvelopeVolume = gbMemory[NR22] >> 4;
|
rlm@1
|
224 sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;
|
rlm@1
|
225 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
|
rlm@1
|
226 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);
|
rlm@1
|
227
|
rlm@1
|
228 sound2Index = 0;
|
rlm@1
|
229 sound2On = 1;
|
rlm@1
|
230 }
|
rlm@1
|
231 break;
|
rlm@1
|
232 case NR30:
|
rlm@1
|
233 if (!(data & 0x80))
|
rlm@1
|
234 {
|
rlm@1
|
235 gbMemory[NR52] &= 0xfb;
|
rlm@1
|
236 sound3On = 0;
|
rlm@1
|
237 }
|
rlm@1
|
238 break;
|
rlm@1
|
239 case NR31:
|
rlm@1
|
240 sound3ATL = 172 * (256 - data);
|
rlm@1
|
241 break;
|
rlm@1
|
242 case NR32:
|
rlm@1
|
243 sound3OutputLevel = (data >> 5) & 3;
|
rlm@1
|
244 break;
|
rlm@1
|
245 case NR33:
|
rlm@1
|
246 freq = 2048 - (((int)(gbMemory[NR34] & 7) << 8) | data);
|
rlm@1
|
247 if (freq)
|
rlm@1
|
248 {
|
rlm@1
|
249 sound3Skip = SOUND_MAGIC_2 / freq;
|
rlm@1
|
250 }
|
rlm@1
|
251 else
|
rlm@1
|
252 sound3Skip = 0;
|
rlm@1
|
253 break;
|
rlm@1
|
254 case NR34:
|
rlm@1
|
255 freq = 2048 - (((data & 7) << 8) | (int)gbMemory[NR33]);
|
rlm@1
|
256 if (freq)
|
rlm@1
|
257 {
|
rlm@1
|
258 sound3Skip = SOUND_MAGIC_2 / freq;
|
rlm@1
|
259 }
|
rlm@1
|
260 else
|
rlm@1
|
261 {
|
rlm@1
|
262 sound3Skip = 0;
|
rlm@1
|
263 }
|
rlm@1
|
264 sound3Continue = data & 0x40;
|
rlm@1
|
265 if ((data & 0x80) && (gbMemory[NR30] & 0x80))
|
rlm@1
|
266 {
|
rlm@1
|
267 gbMemory[NR52] |= 4;
|
rlm@1
|
268 sound3ATL = 172 * (256 - gbMemory[NR31]);
|
rlm@1
|
269 sound3Index = 0;
|
rlm@1
|
270 sound3On = 1;
|
rlm@1
|
271 }
|
rlm@1
|
272 break;
|
rlm@1
|
273 case NR41:
|
rlm@1
|
274 sound4ATL = 172 * (64 - (data & 0x3f));
|
rlm@1
|
275 break;
|
rlm@1
|
276 case NR42:
|
rlm@1
|
277 sound4EnvelopeVolume = data >> 4;
|
rlm@1
|
278 sound4EnvelopeUpDown = data & 0x08;
|
rlm@1
|
279 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);
|
rlm@1
|
280 break;
|
rlm@1
|
281 case NR43:
|
rlm@1
|
282 freq = soundFreqRatio[data & 7];
|
rlm@1
|
283 sound4NSteps = data & 0x08;
|
rlm@1
|
284
|
rlm@1
|
285 sound4Skip = freq * NOISE_MAGIC;
|
rlm@1
|
286
|
rlm@1
|
287 sound4Clock = data >> 4;
|
rlm@1
|
288
|
rlm@1
|
289 freq = freq / soundShiftClock[sound4Clock];
|
rlm@1
|
290
|
rlm@1
|
291 sound4ShiftSkip = freq * NOISE_MAGIC;
|
rlm@1
|
292
|
rlm@1
|
293 break;
|
rlm@1
|
294 case NR44:
|
rlm@1
|
295 sound4Continue = data & 0x40;
|
rlm@1
|
296 if (data & 0x80)
|
rlm@1
|
297 {
|
rlm@1
|
298 gbMemory[NR52] |= 8;
|
rlm@1
|
299 sound4EnvelopeVolume = gbMemory[NR42] >> 4;
|
rlm@1
|
300 sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;
|
rlm@1
|
301 sound4ATL = 172 * (64 - (gbMemory[NR41] & 0x3f));
|
rlm@1
|
302 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);
|
rlm@1
|
303
|
rlm@1
|
304 sound4On = 1;
|
rlm@1
|
305
|
rlm@1
|
306 sound4Index = 0;
|
rlm@1
|
307 sound4ShiftIndex = 0;
|
rlm@1
|
308
|
rlm@1
|
309 freq = soundFreqRatio[gbMemory[NR43] & 7];
|
rlm@1
|
310
|
rlm@1
|
311 sound4Skip = freq * NOISE_MAGIC;
|
rlm@1
|
312
|
rlm@1
|
313 sound4NSteps = gbMemory[NR43] & 0x08;
|
rlm@1
|
314
|
rlm@1
|
315 freq = freq / soundShiftClock[gbMemory[NR43] >> 4];
|
rlm@1
|
316
|
rlm@1
|
317 sound4ShiftSkip = freq * NOISE_MAGIC;
|
rlm@1
|
318 if (sound4NSteps)
|
rlm@1
|
319 sound4ShiftRight = 0x7f;
|
rlm@1
|
320 else
|
rlm@1
|
321 sound4ShiftRight = 0x7fff;
|
rlm@1
|
322 }
|
rlm@1
|
323 break;
|
rlm@1
|
324 case NR50:
|
rlm@1
|
325 soundVIN = data & 0x88;
|
rlm@1
|
326 soundLevel1 = data & 7;
|
rlm@1
|
327 soundLevel2 = (data >> 4) & 7;
|
rlm@1
|
328 break;
|
rlm@1
|
329 case NR51:
|
rlm@1
|
330 soundBalance = (data & soundEnableFlag);
|
rlm@1
|
331 gbMemory[address] = data;
|
rlm@1
|
332 break;
|
rlm@1
|
333 case NR52:
|
rlm@1
|
334 soundMasterOn = data & 0x80;
|
rlm@1
|
335 if (!(data & 0x80))
|
rlm@1
|
336 {
|
rlm@1
|
337 sound1On = 0;
|
rlm@1
|
338 sound2On = 0;
|
rlm@1
|
339 sound3On = 0;
|
rlm@1
|
340 sound4On = 0;
|
rlm@1
|
341 }
|
rlm@1
|
342 break;
|
rlm@1
|
343 }
|
rlm@1
|
344
|
rlm@1
|
345 gbDigitalSound = true;
|
rlm@1
|
346
|
rlm@1
|
347 if (sound1On && sound1EnvelopeVolume != 0)
|
rlm@1
|
348 gbDigitalSound = false;
|
rlm@1
|
349 if (sound2On && sound2EnvelopeVolume != 0)
|
rlm@1
|
350 gbDigitalSound = false;
|
rlm@1
|
351 if (sound3On && sound3OutputLevel != 0)
|
rlm@1
|
352 gbDigitalSound = false;
|
rlm@1
|
353 if (sound4On && sound4EnvelopeVolume != 0)
|
rlm@1
|
354 gbDigitalSound = false;
|
rlm@1
|
355 }
|
rlm@1
|
356
|
rlm@1
|
357 void gbSoundChannel1()
|
rlm@1
|
358 {
|
rlm@1
|
359 int vol = sound1EnvelopeVolume;
|
rlm@1
|
360
|
rlm@1
|
361 int freq = 0;
|
rlm@1
|
362
|
rlm@1
|
363 int value = 0;
|
rlm@1
|
364
|
rlm@1
|
365 if (sound1On && (sound1ATL || !sound1Continue))
|
rlm@1
|
366 {
|
rlm@1
|
367 sound1Index += soundQuality * sound1Skip;
|
rlm@1
|
368 sound1Index &= 0x1fffffff;
|
rlm@1
|
369
|
rlm@1
|
370 value = ((s8)sound1Wave[sound1Index >> 24]) * vol;
|
rlm@1
|
371 }
|
rlm@1
|
372
|
rlm@1
|
373 soundBuffer[0][soundIndex] = value;
|
rlm@1
|
374
|
rlm@1
|
375 if (sound1On)
|
rlm@1
|
376 {
|
rlm@1
|
377 if (sound1ATL)
|
rlm@1
|
378 {
|
rlm@1
|
379 sound1ATL -= soundQuality;
|
rlm@1
|
380
|
rlm@1
|
381 if (sound1ATL <= 0 && sound1Continue)
|
rlm@1
|
382 {
|
rlm@1
|
383 gbMemory[NR52] &= 0xfe;
|
rlm@1
|
384 sound1On = 0;
|
rlm@1
|
385 }
|
rlm@1
|
386 }
|
rlm@1
|
387
|
rlm@1
|
388 if (sound1EnvelopeATL)
|
rlm@1
|
389 {
|
rlm@1
|
390 sound1EnvelopeATL -= soundQuality;
|
rlm@1
|
391
|
rlm@1
|
392 if (sound1EnvelopeATL <= 0)
|
rlm@1
|
393 {
|
rlm@1
|
394 if (sound1EnvelopeUpDown)
|
rlm@1
|
395 {
|
rlm@1
|
396 if (sound1EnvelopeVolume < 15)
|
rlm@1
|
397 sound1EnvelopeVolume++;
|
rlm@1
|
398 }
|
rlm@1
|
399 else
|
rlm@1
|
400 {
|
rlm@1
|
401 if (sound1EnvelopeVolume)
|
rlm@1
|
402 sound1EnvelopeVolume--;
|
rlm@1
|
403 }
|
rlm@1
|
404
|
rlm@1
|
405 sound1EnvelopeATL += sound1EnvelopeATLReload;
|
rlm@1
|
406 }
|
rlm@1
|
407 }
|
rlm@1
|
408
|
rlm@1
|
409 if (sound1SweepATL)
|
rlm@1
|
410 {
|
rlm@1
|
411 sound1SweepATL -= soundQuality;
|
rlm@1
|
412
|
rlm@1
|
413 if (sound1SweepATL <= 0)
|
rlm@1
|
414 {
|
rlm@1
|
415 freq = (((int)(gbMemory[NR14] & 7) << 8) | gbMemory[NR13]);
|
rlm@1
|
416
|
rlm@1
|
417 int updown = 1;
|
rlm@1
|
418
|
rlm@1
|
419 if (sound1SweepUpDown)
|
rlm@1
|
420 updown = -1;
|
rlm@1
|
421
|
rlm@1
|
422 int newfreq = 0;
|
rlm@1
|
423 if (sound1SweepSteps)
|
rlm@1
|
424 {
|
rlm@1
|
425 newfreq = freq + updown * freq / (1 << sound1SweepSteps);
|
rlm@1
|
426 if (newfreq == freq)
|
rlm@1
|
427 newfreq = 0;
|
rlm@1
|
428 }
|
rlm@1
|
429 else
|
rlm@1
|
430 newfreq = freq;
|
rlm@1
|
431
|
rlm@1
|
432 if (newfreq < 0)
|
rlm@1
|
433 {
|
rlm@1
|
434 sound1SweepATL += sound1SweepATLReload;
|
rlm@1
|
435 }
|
rlm@1
|
436 else if (newfreq > 2047)
|
rlm@1
|
437 {
|
rlm@1
|
438 sound1SweepATL = 0;
|
rlm@1
|
439 sound1On = 0;
|
rlm@1
|
440 gbMemory[NR52] &= 0xfe;
|
rlm@1
|
441 }
|
rlm@1
|
442 else
|
rlm@1
|
443 {
|
rlm@1
|
444 sound1SweepATL += sound1SweepATLReload;
|
rlm@1
|
445 sound1Skip = SOUND_MAGIC / (2048 - newfreq);
|
rlm@1
|
446
|
rlm@1
|
447 gbMemory[NR13] = newfreq & 0xff;
|
rlm@1
|
448 gbMemory[NR14] = (gbMemory[NR14] & 0xf8) | ((newfreq >> 8) & 7);
|
rlm@1
|
449 }
|
rlm@1
|
450 }
|
rlm@1
|
451 }
|
rlm@1
|
452 }
|
rlm@1
|
453 }
|
rlm@1
|
454
|
rlm@1
|
455 void gbSoundChannel2()
|
rlm@1
|
456 {
|
rlm@1
|
457 // int freq = 0;
|
rlm@1
|
458 int vol = sound2EnvelopeVolume;
|
rlm@1
|
459
|
rlm@1
|
460 int value = 0;
|
rlm@1
|
461
|
rlm@1
|
462 if (sound2On && (sound2ATL || !sound2Continue))
|
rlm@1
|
463 {
|
rlm@1
|
464 sound2Index += soundQuality * sound2Skip;
|
rlm@1
|
465 sound2Index &= 0x1fffffff;
|
rlm@1
|
466
|
rlm@1
|
467 value = ((s8)sound2Wave[sound2Index >> 24]) * vol;
|
rlm@1
|
468 }
|
rlm@1
|
469
|
rlm@1
|
470 soundBuffer[1][soundIndex] = value;
|
rlm@1
|
471
|
rlm@1
|
472 if (sound2On)
|
rlm@1
|
473 {
|
rlm@1
|
474 if (sound2ATL)
|
rlm@1
|
475 {
|
rlm@1
|
476 sound2ATL -= soundQuality;
|
rlm@1
|
477
|
rlm@1
|
478 if (sound2ATL <= 0 && sound2Continue)
|
rlm@1
|
479 {
|
rlm@1
|
480 gbMemory[NR52] &= 0xfd;
|
rlm@1
|
481 sound2On = 0;
|
rlm@1
|
482 }
|
rlm@1
|
483 }
|
rlm@1
|
484
|
rlm@1
|
485 if (sound2EnvelopeATL)
|
rlm@1
|
486 {
|
rlm@1
|
487 sound2EnvelopeATL -= soundQuality;
|
rlm@1
|
488
|
rlm@1
|
489 if (sound2EnvelopeATL <= 0)
|
rlm@1
|
490 {
|
rlm@1
|
491 if (sound2EnvelopeUpDown)
|
rlm@1
|
492 {
|
rlm@1
|
493 if (sound2EnvelopeVolume < 15)
|
rlm@1
|
494 sound2EnvelopeVolume++;
|
rlm@1
|
495 }
|
rlm@1
|
496 else
|
rlm@1
|
497 {
|
rlm@1
|
498 if (sound2EnvelopeVolume)
|
rlm@1
|
499 sound2EnvelopeVolume--;
|
rlm@1
|
500 }
|
rlm@1
|
501 sound2EnvelopeATL += sound2EnvelopeATLReload;
|
rlm@1
|
502 }
|
rlm@1
|
503 }
|
rlm@1
|
504 }
|
rlm@1
|
505 }
|
rlm@1
|
506
|
rlm@1
|
507 void gbSoundChannel3()
|
rlm@1
|
508 {
|
rlm@1
|
509 int value = sound3Last;
|
rlm@1
|
510
|
rlm@1
|
511 if (sound3On && (sound3ATL || !sound3Continue))
|
rlm@1
|
512 {
|
rlm@1
|
513 sound3Index += soundQuality * sound3Skip;
|
rlm@1
|
514 sound3Index &= 0x1fffffff;
|
rlm@1
|
515
|
rlm@1
|
516 value = gbMemory[0xff30 + (sound3Index >> 25)];
|
rlm@1
|
517
|
rlm@1
|
518 if ((sound3Index & 0x01000000))
|
rlm@1
|
519 {
|
rlm@1
|
520 value &= 0x0f;
|
rlm@1
|
521 }
|
rlm@1
|
522 else
|
rlm@1
|
523 {
|
rlm@1
|
524 value >>= 4;
|
rlm@1
|
525 }
|
rlm@1
|
526
|
rlm@1
|
527 value -= 8;
|
rlm@1
|
528 value *= 2;
|
rlm@1
|
529
|
rlm@1
|
530 switch (sound3OutputLevel)
|
rlm@1
|
531 {
|
rlm@1
|
532 case 0:
|
rlm@1
|
533 value = 0;
|
rlm@1
|
534 break;
|
rlm@1
|
535 case 1:
|
rlm@1
|
536 break;
|
rlm@1
|
537 case 2:
|
rlm@1
|
538 value = (value >> 1);
|
rlm@1
|
539 break;
|
rlm@1
|
540 case 3:
|
rlm@1
|
541 value = (value >> 2);
|
rlm@1
|
542 break;
|
rlm@1
|
543 }
|
rlm@1
|
544 //value += 1;
|
rlm@1
|
545 sound3Last = value;
|
rlm@1
|
546 }
|
rlm@1
|
547
|
rlm@1
|
548 soundBuffer[2][soundIndex] = value;
|
rlm@1
|
549
|
rlm@1
|
550 if (sound3On)
|
rlm@1
|
551 {
|
rlm@1
|
552 if (sound3ATL)
|
rlm@1
|
553 {
|
rlm@1
|
554 sound3ATL -= soundQuality;
|
rlm@1
|
555
|
rlm@1
|
556 if (sound3ATL <= 0 && sound3Continue)
|
rlm@1
|
557 {
|
rlm@1
|
558 gbMemory[NR52] &= 0xfb;
|
rlm@1
|
559 sound3On = 0;
|
rlm@1
|
560 }
|
rlm@1
|
561 }
|
rlm@1
|
562 }
|
rlm@1
|
563 }
|
rlm@1
|
564
|
rlm@1
|
565 void gbSoundChannel4()
|
rlm@1
|
566 {
|
rlm@1
|
567 int vol = sound4EnvelopeVolume;
|
rlm@1
|
568
|
rlm@1
|
569 int value = 0;
|
rlm@1
|
570
|
rlm@1
|
571 if (sound4Clock <= 0x0c)
|
rlm@1
|
572 {
|
rlm@1
|
573 if (sound4On && (sound4ATL || !sound4Continue))
|
rlm@1
|
574 {
|
rlm@1
|
575 #define NOISE_ONE_SAMP_SCALE 0x200000
|
rlm@1
|
576
|
rlm@1
|
577 sound4Index += soundQuality * sound4Skip;
|
rlm@1
|
578 sound4ShiftIndex += soundQuality * sound4ShiftSkip;
|
rlm@1
|
579
|
rlm@1
|
580 if (sound4NSteps)
|
rlm@1
|
581 {
|
rlm@1
|
582 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
|
rlm@1
|
583 {
|
rlm@1
|
584 sound4ShiftRight = (((sound4ShiftRight << 6) ^
|
rlm@1
|
585 (sound4ShiftRight << 5)) & 0x40) |
|
rlm@1
|
586 (sound4ShiftRight >> 1);
|
rlm@1
|
587 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
|
rlm@1
|
588 }
|
rlm@1
|
589 }
|
rlm@1
|
590 else
|
rlm@1
|
591 {
|
rlm@1
|
592 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
|
rlm@1
|
593 {
|
rlm@1
|
594 sound4ShiftRight = (((sound4ShiftRight << 14) ^
|
rlm@1
|
595 (sound4ShiftRight << 13)) & 0x4000) |
|
rlm@1
|
596 (sound4ShiftRight >> 1);
|
rlm@1
|
597
|
rlm@1
|
598 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
|
rlm@1
|
599 }
|
rlm@1
|
600 }
|
rlm@1
|
601
|
rlm@1
|
602 sound4Index %= NOISE_ONE_SAMP_SCALE;
|
rlm@1
|
603 sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE;
|
rlm@1
|
604
|
rlm@1
|
605 value = ((sound4ShiftRight & 1) * 2 - 1) * vol;
|
rlm@1
|
606 }
|
rlm@1
|
607 else
|
rlm@1
|
608 {
|
rlm@1
|
609 value = 0;
|
rlm@1
|
610 }
|
rlm@1
|
611 }
|
rlm@1
|
612
|
rlm@1
|
613 soundBuffer[3][soundIndex] = value;
|
rlm@1
|
614
|
rlm@1
|
615 if (sound4On)
|
rlm@1
|
616 {
|
rlm@1
|
617 if (sound4ATL)
|
rlm@1
|
618 {
|
rlm@1
|
619 sound4ATL -= soundQuality;
|
rlm@1
|
620
|
rlm@1
|
621 if (sound4ATL <= 0 && sound4Continue)
|
rlm@1
|
622 {
|
rlm@1
|
623 gbMemory[NR52] &= 0xfd;
|
rlm@1
|
624 sound4On = 0;
|
rlm@1
|
625 }
|
rlm@1
|
626 }
|
rlm@1
|
627
|
rlm@1
|
628 if (sound4EnvelopeATL)
|
rlm@1
|
629 {
|
rlm@1
|
630 sound4EnvelopeATL -= soundQuality;
|
rlm@1
|
631
|
rlm@1
|
632 if (sound4EnvelopeATL <= 0)
|
rlm@1
|
633 {
|
rlm@1
|
634 if (sound4EnvelopeUpDown)
|
rlm@1
|
635 {
|
rlm@1
|
636 if (sound4EnvelopeVolume < 15)
|
rlm@1
|
637 sound4EnvelopeVolume++;
|
rlm@1
|
638 }
|
rlm@1
|
639 else
|
rlm@1
|
640 {
|
rlm@1
|
641 if (sound4EnvelopeVolume)
|
rlm@1
|
642 sound4EnvelopeVolume--;
|
rlm@1
|
643 }
|
rlm@1
|
644 sound4EnvelopeATL += sound4EnvelopeATLReload;
|
rlm@1
|
645 }
|
rlm@1
|
646 }
|
rlm@1
|
647 }
|
rlm@1
|
648 }
|
rlm@1
|
649
|
rlm@1
|
650 void gbSoundMix()
|
rlm@1
|
651 {
|
rlm@1
|
652 int res = 0;
|
rlm@1
|
653
|
rlm@1
|
654 if (gbMemory)
|
rlm@1
|
655 soundBalance = (gbMemory[NR51] & soundEnableFlag & ~soundMutedFlag);
|
rlm@1
|
656
|
rlm@1
|
657 if (soundBalance & 16)
|
rlm@1
|
658 {
|
rlm@1
|
659 res += ((s8)soundBuffer[0][soundIndex]);
|
rlm@1
|
660 }
|
rlm@1
|
661 if (soundBalance & 32)
|
rlm@1
|
662 {
|
rlm@1
|
663 res += ((s8)soundBuffer[1][soundIndex]);
|
rlm@1
|
664 }
|
rlm@1
|
665 if (soundBalance & 64)
|
rlm@1
|
666 {
|
rlm@1
|
667 res += ((s8)soundBuffer[2][soundIndex]);
|
rlm@1
|
668 }
|
rlm@1
|
669 if (soundBalance & 128)
|
rlm@1
|
670 {
|
rlm@1
|
671 res += ((s8)soundBuffer[3][soundIndex]);
|
rlm@1
|
672 }
|
rlm@1
|
673
|
rlm@1
|
674 if (gbDigitalSound)
|
rlm@1
|
675 res = soundLevel1 * 256;
|
rlm@1
|
676 else
|
rlm@1
|
677 res *= soundLevel1 * 60;
|
rlm@1
|
678
|
rlm@1
|
679 if (soundEcho)
|
rlm@1
|
680 {
|
rlm@1
|
681 res *= 2;
|
rlm@1
|
682 res += soundFilter[soundEchoIndex];
|
rlm@1
|
683 res /= 2;
|
rlm@1
|
684 soundFilter[soundEchoIndex++] = res;
|
rlm@1
|
685 }
|
rlm@1
|
686
|
rlm@1
|
687 if (soundLowPass)
|
rlm@1
|
688 {
|
rlm@1
|
689 soundLeft[4] = soundLeft[3];
|
rlm@1
|
690 soundLeft[3] = soundLeft[2];
|
rlm@1
|
691 soundLeft[2] = soundLeft[1];
|
rlm@1
|
692 soundLeft[1] = soundLeft[0];
|
rlm@1
|
693 soundLeft[0] = res;
|
rlm@1
|
694 res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] +
|
rlm@1
|
695 soundLeft[0]) / 14;
|
rlm@1
|
696 }
|
rlm@1
|
697
|
rlm@1
|
698 bool noSpecialEffects = false;
|
rlm@1
|
699 #if (defined(WIN32) && !defined(SDL))
|
rlm@1
|
700 if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog)
|
rlm@1
|
701 noSpecialEffects = true;
|
rlm@1
|
702 #endif
|
rlm@1
|
703
|
rlm@1
|
704 if (!noSpecialEffects)
|
rlm@1
|
705 {
|
rlm@1
|
706 switch (soundVolume)
|
rlm@1
|
707 {
|
rlm@1
|
708 case 0:
|
rlm@1
|
709 case 1:
|
rlm@1
|
710 case 2:
|
rlm@1
|
711 case 3:
|
rlm@1
|
712 res *= (soundVolume + 1);
|
rlm@1
|
713 break;
|
rlm@1
|
714 case 4:
|
rlm@1
|
715 res >>= 2;
|
rlm@1
|
716 break;
|
rlm@1
|
717 case 5:
|
rlm@1
|
718 res >>= 1;
|
rlm@1
|
719 break;
|
rlm@1
|
720 }
|
rlm@1
|
721 }
|
rlm@1
|
722
|
rlm@1
|
723 if (res > 32767)
|
rlm@1
|
724 res = 32767;
|
rlm@1
|
725 if (res < -32768)
|
rlm@1
|
726 res = -32768;
|
rlm@1
|
727
|
rlm@1
|
728 if (soundReverse && !noSpecialEffects)
|
rlm@1
|
729 {
|
rlm@1
|
730 soundFinalWave[++soundBufferIndex] = res;
|
rlm@1
|
731 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
|
rlm@1
|
732 /*assert(false)*/;
|
rlm@1
|
733 else
|
rlm@1
|
734 soundFrameSound[++soundFrameSoundWritten] = res;
|
rlm@1
|
735 }
|
rlm@1
|
736 else
|
rlm@1
|
737 {
|
rlm@1
|
738 soundFinalWave[soundBufferIndex++] = res;
|
rlm@1
|
739 if (soundFrameSoundWritten >= countof(soundFrameSound))
|
rlm@1
|
740 /*assert(false)*/;
|
rlm@1
|
741 else
|
rlm@1
|
742 soundFrameSound[soundFrameSoundWritten++] = res;
|
rlm@1
|
743 }
|
rlm@1
|
744
|
rlm@1
|
745 res = 0;
|
rlm@1
|
746
|
rlm@1
|
747 if (soundBalance & 1)
|
rlm@1
|
748 {
|
rlm@1
|
749 res += ((s8)soundBuffer[0][soundIndex]);
|
rlm@1
|
750 }
|
rlm@1
|
751 if (soundBalance & 2)
|
rlm@1
|
752 {
|
rlm@1
|
753 res += ((s8)soundBuffer[1][soundIndex]);
|
rlm@1
|
754 }
|
rlm@1
|
755 if (soundBalance & 4)
|
rlm@1
|
756 {
|
rlm@1
|
757 res += ((s8)soundBuffer[2][soundIndex]);
|
rlm@1
|
758 }
|
rlm@1
|
759 if (soundBalance & 8)
|
rlm@1
|
760 {
|
rlm@1
|
761 res += ((s8)soundBuffer[3][soundIndex]);
|
rlm@1
|
762 }
|
rlm@1
|
763
|
rlm@1
|
764 if (gbDigitalSound)
|
rlm@1
|
765 res = soundLevel2 * 256;
|
rlm@1
|
766 else
|
rlm@1
|
767 res *= soundLevel2 * 60;
|
rlm@1
|
768
|
rlm@1
|
769 if (soundEcho)
|
rlm@1
|
770 {
|
rlm@1
|
771 res *= 2;
|
rlm@1
|
772 res += soundFilter[soundEchoIndex];
|
rlm@1
|
773 res /= 2;
|
rlm@1
|
774 soundFilter[soundEchoIndex++] = res;
|
rlm@1
|
775
|
rlm@1
|
776 if (soundEchoIndex >= 4000)
|
rlm@1
|
777 soundEchoIndex = 0;
|
rlm@1
|
778 }
|
rlm@1
|
779
|
rlm@1
|
780 if (soundLowPass)
|
rlm@1
|
781 {
|
rlm@1
|
782 soundRight[4] = soundRight[3];
|
rlm@1
|
783 soundRight[3] = soundRight[2];
|
rlm@1
|
784 soundRight[2] = soundRight[1];
|
rlm@1
|
785 soundRight[1] = soundRight[0];
|
rlm@1
|
786 soundRight[0] = res;
|
rlm@1
|
787 res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] +
|
rlm@1
|
788 soundRight[0]) / 14;
|
rlm@1
|
789 }
|
rlm@1
|
790
|
rlm@1
|
791 if (!noSpecialEffects)
|
rlm@1
|
792 {
|
rlm@1
|
793 switch (soundVolume)
|
rlm@1
|
794 {
|
rlm@1
|
795 case 0:
|
rlm@1
|
796 case 1:
|
rlm@1
|
797 case 2:
|
rlm@1
|
798 case 3:
|
rlm@1
|
799 res *= (soundVolume + 1);
|
rlm@1
|
800 break;
|
rlm@1
|
801 case 4:
|
rlm@1
|
802 res >>= 2;
|
rlm@1
|
803 break;
|
rlm@1
|
804 case 5:
|
rlm@1
|
805 res >>= 1;
|
rlm@1
|
806 break;
|
rlm@1
|
807 }
|
rlm@1
|
808 }
|
rlm@1
|
809
|
rlm@1
|
810 if (res > 32767)
|
rlm@1
|
811 res = 32767;
|
rlm@1
|
812 if (res < -32768)
|
rlm@1
|
813 res = -32768;
|
rlm@1
|
814
|
rlm@1
|
815 if (soundReverse && !noSpecialEffects)
|
rlm@1
|
816 {
|
rlm@1
|
817 soundFinalWave[-1 + soundBufferIndex++] = res;
|
rlm@1
|
818 if ((soundFrameSoundWritten) >= countof(soundFrameSound))
|
rlm@1
|
819 /*assert(false)*/;
|
rlm@1
|
820 else
|
rlm@1
|
821 soundFrameSound[-1 + soundFrameSoundWritten++] = res;
|
rlm@1
|
822 }
|
rlm@1
|
823 else
|
rlm@1
|
824 {
|
rlm@1
|
825 soundFinalWave[soundBufferIndex++] = res;
|
rlm@1
|
826 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
|
rlm@1
|
827 /*assert(false)*/;
|
rlm@1
|
828 else
|
rlm@1
|
829 soundFrameSound[soundFrameSoundWritten++] = res;
|
rlm@1
|
830 }
|
rlm@1
|
831 }
|
rlm@1
|
832
|
rlm@1
|
833 void gbSoundTick()
|
rlm@1
|
834 {
|
rlm@1
|
835 if (systemSoundOn)
|
rlm@1
|
836 {
|
rlm@1
|
837 if (soundMasterOn)
|
rlm@1
|
838 {
|
rlm@1
|
839 gbSoundChannel1();
|
rlm@1
|
840 gbSoundChannel2();
|
rlm@1
|
841 gbSoundChannel3();
|
rlm@1
|
842 gbSoundChannel4();
|
rlm@1
|
843
|
rlm@1
|
844 gbSoundMix();
|
rlm@1
|
845 }
|
rlm@1
|
846 else
|
rlm@1
|
847 {
|
rlm@1
|
848 soundFinalWave[soundBufferIndex++] = 0;
|
rlm@1
|
849 soundFinalWave[soundBufferIndex++] = 0;
|
rlm@1
|
850 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
|
rlm@1
|
851 /*assert(false)*/;
|
rlm@1
|
852 else
|
rlm@1
|
853 {
|
rlm@1
|
854 soundFrameSound[soundFrameSoundWritten++] = 0;
|
rlm@1
|
855 soundFrameSound[soundFrameSoundWritten++] = 0;
|
rlm@1
|
856 }
|
rlm@1
|
857 }
|
rlm@1
|
858
|
rlm@1
|
859 soundIndex++;
|
rlm@1
|
860
|
rlm@1
|
861 if (2 * soundBufferIndex >= soundBufferLen)
|
rlm@1
|
862 {
|
rlm@1
|
863 if (systemSoundOn)
|
rlm@1
|
864 {
|
rlm@1
|
865 if (soundPaused)
|
rlm@1
|
866 {
|
rlm@1
|
867 extern void soundResume();
|
rlm@1
|
868 soundResume();
|
rlm@1
|
869 }
|
rlm@1
|
870
|
rlm@1
|
871 systemSoundWriteToBuffer();
|
rlm@1
|
872 }
|
rlm@1
|
873 soundIndex = 0;
|
rlm@1
|
874 soundBufferIndex = 0;
|
rlm@1
|
875 }
|
rlm@1
|
876 }
|
rlm@1
|
877 }
|
rlm@1
|
878
|
rlm@1
|
879 void gbSoundReset()
|
rlm@1
|
880 {
|
rlm@1
|
881 soundPaused = 1;
|
rlm@1
|
882 soundPlay = 0;
|
rlm@1
|
883 SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;
|
rlm@1
|
884 // soundTicks = SOUND_CLOCK_TICKS;
|
rlm@1
|
885 soundTicks = 0;
|
rlm@1
|
886 soundNextPosition = 0;
|
rlm@1
|
887 soundMasterOn = 1;
|
rlm@1
|
888 soundIndex = 0;
|
rlm@1
|
889 soundBufferIndex = 0;
|
rlm@1
|
890 soundLevel1 = 7;
|
rlm@1
|
891 soundLevel2 = 7;
|
rlm@1
|
892 soundVIN = 0;
|
rlm@1
|
893
|
rlm@1
|
894 sound1On = 0;
|
rlm@1
|
895 sound1ATL = 0;
|
rlm@1
|
896 sound1Skip = 0;
|
rlm@1
|
897 sound1Index = 0;
|
rlm@1
|
898 sound1Continue = 0;
|
rlm@1
|
899 sound1EnvelopeVolume = 0;
|
rlm@1
|
900 sound1EnvelopeATL = 0;
|
rlm@1
|
901 sound1EnvelopeUpDown = 0;
|
rlm@1
|
902 sound1EnvelopeATLReload = 0;
|
rlm@1
|
903 sound1SweepATL = 0;
|
rlm@1
|
904 sound1SweepATLReload = 0;
|
rlm@1
|
905 sound1SweepSteps = 0;
|
rlm@1
|
906 sound1SweepUpDown = 0;
|
rlm@1
|
907 sound1SweepStep = 0;
|
rlm@1
|
908 sound1Wave = soundWavePattern[2];
|
rlm@1
|
909
|
rlm@1
|
910 sound2On = 0;
|
rlm@1
|
911 sound2ATL = 0;
|
rlm@1
|
912 sound2Skip = 0;
|
rlm@1
|
913 sound2Index = 0;
|
rlm@1
|
914 sound2Continue = 0;
|
rlm@1
|
915 sound2EnvelopeVolume = 0;
|
rlm@1
|
916 sound2EnvelopeATL = 0;
|
rlm@1
|
917 sound2EnvelopeUpDown = 0;
|
rlm@1
|
918 sound2EnvelopeATLReload = 0;
|
rlm@1
|
919 sound2Wave = soundWavePattern[2];
|
rlm@1
|
920
|
rlm@1
|
921 sound3On = 0;
|
rlm@1
|
922 sound3ATL = 0;
|
rlm@1
|
923 sound3Skip = 0;
|
rlm@1
|
924 sound3Index = 0;
|
rlm@1
|
925 sound3Continue = 0;
|
rlm@1
|
926 sound3OutputLevel = 0;
|
rlm@1
|
927
|
rlm@1
|
928 sound4On = 0;
|
rlm@1
|
929 sound4Clock = 0;
|
rlm@1
|
930 sound4ATL = 0;
|
rlm@1
|
931 sound4Skip = 0;
|
rlm@1
|
932 sound4Index = 0;
|
rlm@1
|
933 sound4ShiftRight = 0x7f;
|
rlm@1
|
934 sound4NSteps = 0;
|
rlm@1
|
935 sound4CountDown = 0;
|
rlm@1
|
936 sound4Continue = 0;
|
rlm@1
|
937 sound4EnvelopeVolume = 0;
|
rlm@1
|
938 sound4EnvelopeATL = 0;
|
rlm@1
|
939 sound4EnvelopeUpDown = 0;
|
rlm@1
|
940 sound4EnvelopeATLReload = 0;
|
rlm@1
|
941
|
rlm@1
|
942 // don't translate
|
rlm@1
|
943 if (soundDebug)
|
rlm@1
|
944 {
|
rlm@1
|
945 log("*** Sound Init ***\n");
|
rlm@1
|
946 }
|
rlm@1
|
947
|
rlm@1
|
948 gbSoundEvent(0xff10, 0x80);
|
rlm@1
|
949 gbSoundEvent(0xff11, 0xbf);
|
rlm@1
|
950 gbSoundEvent(0xff12, 0xf3);
|
rlm@1
|
951 gbSoundEvent(0xff14, 0xbf);
|
rlm@1
|
952 gbSoundEvent(0xff16, 0x3f);
|
rlm@1
|
953 gbSoundEvent(0xff17, 0x00);
|
rlm@1
|
954 gbSoundEvent(0xff19, 0xbf);
|
rlm@1
|
955
|
rlm@1
|
956 gbSoundEvent(0xff1a, 0x7f);
|
rlm@1
|
957 gbSoundEvent(0xff1b, 0xff);
|
rlm@1
|
958 gbSoundEvent(0xff1c, 0xbf);
|
rlm@1
|
959 gbSoundEvent(0xff1e, 0xbf);
|
rlm@1
|
960
|
rlm@1
|
961 gbSoundEvent(0xff20, 0xff);
|
rlm@1
|
962 gbSoundEvent(0xff21, 0x00);
|
rlm@1
|
963 gbSoundEvent(0xff22, 0x00);
|
rlm@1
|
964 gbSoundEvent(0xff23, 0xbf);
|
rlm@1
|
965 gbSoundEvent(0xff24, 0x77);
|
rlm@1
|
966 gbSoundEvent(0xff25, 0xf3);
|
rlm@1
|
967
|
rlm@1
|
968 gbSoundEvent(0xff26, 0xf0);
|
rlm@1
|
969
|
rlm@1
|
970 // don't translate
|
rlm@1
|
971 if (soundDebug)
|
rlm@1
|
972 {
|
rlm@1
|
973 log("*** Sound Init Complete ***\n");
|
rlm@1
|
974 }
|
rlm@1
|
975
|
rlm@1
|
976 sound1On = 0;
|
rlm@1
|
977 sound2On = 0;
|
rlm@1
|
978 sound3On = 0;
|
rlm@1
|
979 sound4On = 0;
|
rlm@1
|
980
|
rlm@1
|
981 int addr = 0xff30;
|
rlm@1
|
982
|
rlm@1
|
983 while (addr < 0xff40)
|
rlm@1
|
984 {
|
rlm@1
|
985 gbMemory[addr++] = 0x00;
|
rlm@1
|
986 gbMemory[addr++] = 0xff;
|
rlm@1
|
987 }
|
rlm@1
|
988
|
rlm@1
|
989 memset(soundFinalWave, 0x00, soundBufferLen);
|
rlm@1
|
990
|
rlm@1
|
991 memset(soundFilter, 0, sizeof(soundFilter));
|
rlm@1
|
992 soundEchoIndex = 0;
|
rlm@1
|
993 }
|
rlm@1
|
994
|
rlm@1
|
995 extern bool soundInit();
|
rlm@1
|
996 extern void soundShutdown();
|
rlm@1
|
997
|
rlm@1
|
998 void gbSoundSetQuality(int quality)
|
rlm@1
|
999 {
|
rlm@1
|
1000 if (soundQuality != quality && systemSoundCanChangeQuality())
|
rlm@1
|
1001 {
|
rlm@1
|
1002 if (!soundOffFlag)
|
rlm@1
|
1003 soundShutdown();
|
rlm@1
|
1004 soundQuality = quality;
|
rlm@1
|
1005 soundNextPosition = 0;
|
rlm@1
|
1006 if (!soundOffFlag)
|
rlm@1
|
1007 soundInit();
|
rlm@1
|
1008 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality;
|
rlm@1
|
1009 soundIndex = 0;
|
rlm@1
|
1010 soundBufferIndex = 0;
|
rlm@1
|
1011 }
|
rlm@1
|
1012 else
|
rlm@1
|
1013 {
|
rlm@1
|
1014 soundNextPosition = 0;
|
rlm@1
|
1015 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality;
|
rlm@1
|
1016 soundIndex = 0;
|
rlm@1
|
1017 soundBufferIndex = 0;
|
rlm@1
|
1018 }
|
rlm@1
|
1019 }
|
rlm@1
|
1020
|
rlm@1
|
1021 static int32 soundTicks_int32;
|
rlm@1
|
1022 static int32 SOUND_CLOCK_TICKS_int32;
|
rlm@1
|
1023 variable_desc gbSoundSaveStruct[] = {
|
rlm@1
|
1024 { &soundPaused, sizeof(int32) },
|
rlm@1
|
1025 { &soundPlay, sizeof(int32) },
|
rlm@1
|
1026 { &soundTicks_int32, sizeof(int32) },
|
rlm@1
|
1027 { &SOUND_CLOCK_TICKS_int32, sizeof(int32) },
|
rlm@1
|
1028 { &soundLevel1, sizeof(int32) },
|
rlm@1
|
1029 { &soundLevel2, sizeof(int32) },
|
rlm@1
|
1030 { &soundBalance, sizeof(int32) },
|
rlm@1
|
1031 { &soundMasterOn, sizeof(int32) },
|
rlm@1
|
1032 { &soundIndex, sizeof(int32) },
|
rlm@1
|
1033 { &soundVIN, sizeof(int32) },
|
rlm@1
|
1034 { &sound1On, sizeof(int32) },
|
rlm@1
|
1035 { &sound1ATL, sizeof(int32) },
|
rlm@1
|
1036 { &sound1Skip, sizeof(int32) },
|
rlm@1
|
1037 { &sound1Index, sizeof(int32) },
|
rlm@1
|
1038 { &sound1Continue, sizeof(int32) },
|
rlm@1
|
1039 { &sound1EnvelopeVolume, sizeof(int32) },
|
rlm@1
|
1040 { &sound1EnvelopeATL, sizeof(int32) },
|
rlm@1
|
1041 { &sound1EnvelopeATLReload, sizeof(int32) },
|
rlm@1
|
1042 { &sound1EnvelopeUpDown, sizeof(int32) },
|
rlm@1
|
1043 { &sound1SweepATL, sizeof(int32) },
|
rlm@1
|
1044 { &sound1SweepATLReload, sizeof(int32) },
|
rlm@1
|
1045 { &sound1SweepSteps, sizeof(int32) },
|
rlm@1
|
1046 { &sound1SweepUpDown, sizeof(int32) },
|
rlm@1
|
1047 { &sound1SweepStep, sizeof(int32) },
|
rlm@1
|
1048 { &sound2On, sizeof(int32) },
|
rlm@1
|
1049 { &sound2ATL, sizeof(int32) },
|
rlm@1
|
1050 { &sound2Skip, sizeof(int32) },
|
rlm@1
|
1051 { &sound2Index, sizeof(int32) },
|
rlm@1
|
1052 { &sound2Continue, sizeof(int32) },
|
rlm@1
|
1053 { &sound2EnvelopeVolume, sizeof(int32) },
|
rlm@1
|
1054 { &sound2EnvelopeATL, sizeof(int32) },
|
rlm@1
|
1055 { &sound2EnvelopeATLReload, sizeof(int32) },
|
rlm@1
|
1056 { &sound2EnvelopeUpDown, sizeof(int32) },
|
rlm@1
|
1057 { &sound3On, sizeof(int32) },
|
rlm@1
|
1058 { &sound3ATL, sizeof(int32) },
|
rlm@1
|
1059 { &sound3Skip, sizeof(int32) },
|
rlm@1
|
1060 { &sound3Index, sizeof(int32) },
|
rlm@1
|
1061 { &sound3Continue, sizeof(int32) },
|
rlm@1
|
1062 { &sound3OutputLevel, sizeof(int32) },
|
rlm@1
|
1063 { &sound4On, sizeof(int32) },
|
rlm@1
|
1064 { &sound4ATL, sizeof(int32) },
|
rlm@1
|
1065 { &sound4Skip, sizeof(int32) },
|
rlm@1
|
1066 { &sound4Index, sizeof(int32) },
|
rlm@1
|
1067 { &sound4Clock, sizeof(int32) },
|
rlm@1
|
1068 { &sound4ShiftRight, sizeof(int32) },
|
rlm@1
|
1069 { &sound4ShiftSkip, sizeof(int32) },
|
rlm@1
|
1070 { &sound4ShiftIndex, sizeof(int32) },
|
rlm@1
|
1071 { &sound4NSteps, sizeof(int32) },
|
rlm@1
|
1072 { &sound4CountDown, sizeof(int32) },
|
rlm@1
|
1073 { &sound4Continue, sizeof(int32) },
|
rlm@1
|
1074 { &sound4EnvelopeVolume, sizeof(int32) },
|
rlm@1
|
1075 { &sound4EnvelopeATL, sizeof(int32) },
|
rlm@1
|
1076 { &sound4EnvelopeATLReload, sizeof(int32) },
|
rlm@1
|
1077 { &sound4EnvelopeUpDown, sizeof(int32) },
|
rlm@1
|
1078 { &soundEnableFlag, sizeof(int32) },
|
rlm@1
|
1079 { NULL, 0 }
|
rlm@1
|
1080 };
|
rlm@1
|
1081
|
rlm@1
|
1082 //variable_desc gbSoundSaveStructV2[] = {
|
rlm@1
|
1083 // { &soundTicks, sizeof(soundtick_t) },
|
rlm@1
|
1084 // { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) },
|
rlm@1
|
1085 // { &GB_USE_TICKS_AS, sizeof(soundtick_t) },
|
rlm@1
|
1086 // { NULL, 0 }
|
rlm@1
|
1087 //};
|
rlm@1
|
1088
|
rlm@1
|
1089 void gbSoundSaveGame(gzFile gzFile)
|
rlm@1
|
1090 {
|
rlm@1
|
1091 soundTicks_int32 = (int32) soundTicks;
|
rlm@1
|
1092 SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS;
|
rlm@1
|
1093
|
rlm@1
|
1094 utilWriteData(gzFile, gbSoundSaveStruct);
|
rlm@1
|
1095
|
rlm@1
|
1096 utilGzWrite(gzFile, soundBuffer, 4 * 735);
|
rlm@1
|
1097 utilGzWrite(gzFile, soundFinalWave, 2 * 735);
|
rlm@1
|
1098 utilGzWrite(gzFile, &soundQuality, sizeof(int32));
|
rlm@1
|
1099
|
rlm@1
|
1100 //utilWriteData(gzFile, gbSoundSaveStructV2);
|
rlm@1
|
1101 }
|
rlm@1
|
1102
|
rlm@1
|
1103 void gbSoundReadGame(int version, gzFile gzFile)
|
rlm@1
|
1104 {
|
rlm@1
|
1105 int32 oldSoundPaused = soundPaused;
|
rlm@1
|
1106 int32 oldSoundEnableFlag = soundEnableFlag;
|
rlm@1
|
1107 utilReadData(gzFile, gbSoundSaveStruct);
|
rlm@1
|
1108 soundPaused = oldSoundPaused;
|
rlm@1
|
1109 soundEnableFlag = oldSoundEnableFlag;
|
rlm@1
|
1110
|
rlm@1
|
1111 soundBufferIndex = soundIndex * 2;
|
rlm@1
|
1112
|
rlm@1
|
1113 utilGzRead(gzFile, soundBuffer, 4 * 735);
|
rlm@1
|
1114 utilGzRead(gzFile, soundFinalWave, 2 * 735);
|
rlm@1
|
1115
|
rlm@1
|
1116 if (version >= 7)
|
rlm@1
|
1117 {
|
rlm@1
|
1118 int quality = 1;
|
rlm@1
|
1119 utilGzRead(gzFile, &quality, sizeof(int32));
|
rlm@1
|
1120 gbSoundSetQuality(quality);
|
rlm@1
|
1121 }
|
rlm@1
|
1122 else
|
rlm@1
|
1123 {
|
rlm@1
|
1124 soundQuality = -1;
|
rlm@1
|
1125 gbSoundSetQuality(1);
|
rlm@1
|
1126 }
|
rlm@1
|
1127
|
rlm@1
|
1128 sound1Wave = soundWavePattern[gbMemory[NR11] >> 6];
|
rlm@1
|
1129 sound2Wave = soundWavePattern[gbMemory[NR21] >> 6];
|
rlm@1
|
1130
|
rlm@1
|
1131 //if(version >= 14) {
|
rlm@1
|
1132 // utilReadData(gzFile, gbSoundSaveStructV2);
|
rlm@1
|
1133 //}
|
rlm@1
|
1134 //else {
|
rlm@1
|
1135 soundTicks = (soundtick_t) soundTicks_int32;
|
rlm@1
|
1136 SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32;
|
rlm@1
|
1137 //}
|
rlm@1
|
1138 }
|
rlm@1
|
1139
|