Mercurial > vba-linux
comparison src/gba/GBASound.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 #if (defined(WIN32) && !defined(SDL)) | |
2 # include "../win32/stdafx.h" | |
3 # include "../win32/VBA.h" | |
4 #endif | |
5 | |
6 #include <cstring> | |
7 #include <cassert> | |
8 | |
9 #include "GBASound.h" | |
10 #include "../common/System.h" // SDL build needs this | |
11 #include "../common/Util.h" | |
12 #include "GBA.h" | |
13 #include "GBAGlobals.h" | |
14 | |
15 #ifndef countof | |
16 #define countof(a) (sizeof(a) / sizeof(a[0])) | |
17 #endif | |
18 | |
19 soundtick_t USE_TICKS_AS = 380; // (16777216.0/44100.0); // FIXME: (16777216.0/280896.0)(fps) vs 60.0fps? | |
20 | |
21 #define SOUND_MAGIC 0x60000000 | |
22 #define SOUND_MAGIC_2 0x30000000 | |
23 #define NOISE_MAGIC (2097152.0 / 44100.0) | |
24 | |
25 extern bool8 stopState; | |
26 | |
27 u8 soundWavePattern[4][32] = { | |
28 { 0x01, 0x01, 0x01, 0x01, | |
29 0xff, 0xff, 0xff, 0xff, | |
30 0xff, 0xff, 0xff, 0xff, | |
31 0xff, 0xff, 0xff, 0xff, | |
32 0xff, 0xff, 0xff, 0xff, | |
33 0xff, 0xff, 0xff, 0xff, | |
34 0xff, 0xff, 0xff, 0xff, | |
35 0xff, 0xff, 0xff, 0xff }, | |
36 { 0x01, 0x01, 0x01, 0x01, | |
37 0x01, 0x01, 0x01, 0x01, | |
38 0xff, 0xff, 0xff, 0xff, | |
39 0xff, 0xff, 0xff, 0xff, | |
40 0xff, 0xff, 0xff, 0xff, | |
41 0xff, 0xff, 0xff, 0xff, | |
42 0xff, 0xff, 0xff, 0xff, | |
43 0xff, 0xff, 0xff, 0xff }, | |
44 { 0x01, 0x01, 0x01, 0x01, | |
45 0x01, 0x01, 0x01, 0x01, | |
46 0x01, 0x01, 0x01, 0x01, | |
47 0x01, 0x01, 0x01, 0x01, | |
48 0xff, 0xff, 0xff, 0xff, | |
49 0xff, 0xff, 0xff, 0xff, | |
50 0xff, 0xff, 0xff, 0xff, | |
51 0xff, 0xff, 0xff, 0xff }, | |
52 { 0x01, 0x01, 0x01, 0x01, | |
53 0x01, 0x01, 0x01, 0x01, | |
54 0x01, 0x01, 0x01, 0x01, | |
55 0x01, 0x01, 0x01, 0x01, | |
56 0x01, 0x01, 0x01, 0x01, | |
57 0x01, 0x01, 0x01, 0x01, | |
58 0xff, 0xff, 0xff, 0xff, | |
59 0xff, 0xff, 0xff, 0xff } | |
60 }; | |
61 | |
62 int32 soundFreqRatio[8] = { | |
63 1048576, // 0 | |
64 524288, // 1 | |
65 262144, // 2 | |
66 174763, // 3 | |
67 131072, // 4 | |
68 104858, // 5 | |
69 87381, // 6 | |
70 74898 // 7 | |
71 }; | |
72 | |
73 int32 soundShiftClock[16] = { | |
74 2, // 0 | |
75 4, // 1 | |
76 8, // 2 | |
77 16, // 3 | |
78 32, // 4 | |
79 64, // 5 | |
80 128, // 6 | |
81 256, // 7 | |
82 512, // 8 | |
83 1024, // 9 | |
84 2048, // 10 | |
85 4096, // 11 | |
86 8192, // 12 | |
87 16384, // 13 | |
88 1, // 14 | |
89 1 // 15 | |
90 }; | |
91 | |
92 int32 soundVolume = 0; | |
93 | |
94 u8 soundBuffer[6][735]; | |
95 u16 soundFinalWave[1470]; | |
96 u16 soundFrameSound[735 * 30 * 2]; // for avi logging | |
97 | |
98 u32 soundBufferLen = 1470; | |
99 u32 soundBufferTotalLen = 14700; | |
100 int32 soundQuality = 2; | |
101 int32 soundPaused = 1; | |
102 int32 soundPlay = 0; | |
103 soundtick_t soundTicks = soundQuality * USE_TICKS_AS; | |
104 soundtick_t SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS; | |
105 u32 soundNextPosition = 0; | |
106 | |
107 int32 soundLevel1 = 0; | |
108 int32 soundLevel2 = 0; | |
109 int32 soundBalance = 0; | |
110 int32 soundMasterOn = 0; | |
111 u32 soundIndex = 0; | |
112 u32 soundBufferIndex = 0; | |
113 int32 soundFrameSoundWritten = 0; | |
114 int32 soundDebug = 0; | |
115 bool8 soundOffFlag = false; | |
116 | |
117 int32 sound1On = 0; | |
118 int32 sound1ATL = 0; | |
119 int32 sound1Skip = 0; | |
120 int32 sound1Index = 0; | |
121 int32 sound1Continue = 0; | |
122 int32 sound1EnvelopeVolume = 0; | |
123 int32 sound1EnvelopeATL = 0; | |
124 int32 sound1EnvelopeUpDown = 0; | |
125 int32 sound1EnvelopeATLReload = 0; | |
126 int32 sound1SweepATL = 0; | |
127 int32 sound1SweepATLReload = 0; | |
128 int32 sound1SweepSteps = 0; | |
129 int32 sound1SweepUpDown = 0; | |
130 int32 sound1SweepStep = 0; | |
131 u8 * sound1Wave = soundWavePattern[2]; | |
132 | |
133 int32 sound2On = 0; | |
134 int32 sound2ATL = 0; | |
135 int32 sound2Skip = 0; | |
136 int32 sound2Index = 0; | |
137 int32 sound2Continue = 0; | |
138 int32 sound2EnvelopeVolume = 0; | |
139 int32 sound2EnvelopeATL = 0; | |
140 int32 sound2EnvelopeUpDown = 0; | |
141 int32 sound2EnvelopeATLReload = 0; | |
142 u8 * sound2Wave = soundWavePattern[2]; | |
143 | |
144 int32 sound3On = 0; | |
145 int32 sound3ATL = 0; | |
146 int32 sound3Skip = 0; | |
147 int32 sound3Index = 0; | |
148 int32 sound3Continue = 0; | |
149 int32 sound3OutputLevel = 0; | |
150 int32 sound3Last = 0; | |
151 u8 sound3WaveRam[0x20]; | |
152 int32 sound3Bank = 0; | |
153 int32 sound3DataSize = 0; | |
154 int32 sound3ForcedOutput = 0; | |
155 | |
156 int32 sound4On = 0; | |
157 int32 sound4Clock = 0; | |
158 int32 sound4ATL = 0; | |
159 int32 sound4Skip = 0; | |
160 int32 sound4Index = 0; | |
161 int32 sound4ShiftRight = 0x7f; | |
162 int32 sound4ShiftSkip = 0; | |
163 int32 sound4ShiftIndex = 0; | |
164 int32 sound4NSteps = 0; | |
165 int32 sound4CountDown = 0; | |
166 int32 sound4Continue = 0; | |
167 int32 sound4EnvelopeVolume = 0; | |
168 int32 sound4EnvelopeATL = 0; | |
169 int32 sound4EnvelopeUpDown = 0; | |
170 int32 sound4EnvelopeATLReload = 0; | |
171 | |
172 int32 soundControl = 0; | |
173 | |
174 int32 soundDSFifoAIndex = 0; | |
175 int32 soundDSFifoACount = 0; | |
176 int32 soundDSFifoAWriteIndex = 0; | |
177 bool8 soundDSAEnabled = false; | |
178 int32 soundDSATimer = 0; | |
179 u8 soundDSFifoA[32]; | |
180 u8 soundDSAValue = 0; | |
181 | |
182 int32 soundDSFifoBIndex = 0; | |
183 int32 soundDSFifoBCount = 0; | |
184 int32 soundDSFifoBWriteIndex = 0; | |
185 bool8 soundDSBEnabled = false; | |
186 int32 soundDSBTimer = 0; | |
187 u8 soundDSFifoB[32]; | |
188 u8 soundDSBValue = 0; | |
189 | |
190 int32 soundEnableFlag = 0x3ff; | |
191 int32 soundMutedFlag = 0; | |
192 | |
193 s16 soundFilter[4000]; | |
194 s16 soundRight[5] = { 0, 0, 0, 0, 0 }; | |
195 s16 soundLeft[5] = { 0, 0, 0, 0, 0 }; | |
196 int32 soundEchoIndex = 0; | |
197 bool8 soundEcho = false; | |
198 bool8 soundLowPass = false; | |
199 bool8 soundReverse = false; | |
200 | |
201 static int32 soundTicks_int32; | |
202 static int32 SOUND_CLOCK_TICKS_int32; | |
203 static int32 soundDSBValue_int32; | |
204 variable_desc soundSaveStruct[] = { | |
205 { &soundPaused, sizeof(int32) }, | |
206 { &soundPlay, sizeof(int32) }, | |
207 { &soundTicks_int32, sizeof(int32) }, | |
208 { &SOUND_CLOCK_TICKS_int32, sizeof(int32) }, | |
209 { &soundLevel1, sizeof(int32) }, | |
210 { &soundLevel2, sizeof(int32) }, | |
211 { &soundBalance, sizeof(int32) }, | |
212 { &soundMasterOn, sizeof(int32) }, | |
213 { &soundIndex, sizeof(int32) }, | |
214 { &sound1On, sizeof(int32) }, | |
215 { &sound1ATL, sizeof(int32) }, | |
216 { &sound1Skip, sizeof(int32) }, | |
217 { &sound1Index, sizeof(int32) }, | |
218 { &sound1Continue, sizeof(int32) }, | |
219 { &sound1EnvelopeVolume, sizeof(int32) }, | |
220 { &sound1EnvelopeATL, sizeof(int32) }, | |
221 { &sound1EnvelopeATLReload, sizeof(int32) }, | |
222 { &sound1EnvelopeUpDown, sizeof(int32) }, | |
223 { &sound1SweepATL, sizeof(int32) }, | |
224 { &sound1SweepATLReload, sizeof(int32) }, | |
225 { &sound1SweepSteps, sizeof(int32) }, | |
226 { &sound1SweepUpDown, sizeof(int32) }, | |
227 { &sound1SweepStep, sizeof(int32) }, | |
228 { &sound2On, sizeof(int32) }, | |
229 { &sound2ATL, sizeof(int32) }, | |
230 { &sound2Skip, sizeof(int32) }, | |
231 { &sound2Index, sizeof(int32) }, | |
232 { &sound2Continue, sizeof(int32) }, | |
233 { &sound2EnvelopeVolume, sizeof(int32) }, | |
234 { &sound2EnvelopeATL, sizeof(int32) }, | |
235 { &sound2EnvelopeATLReload, sizeof(int32) }, | |
236 { &sound2EnvelopeUpDown, sizeof(int32) }, | |
237 { &sound3On, sizeof(int32) }, | |
238 { &sound3ATL, sizeof(int32) }, | |
239 { &sound3Skip, sizeof(int32) }, | |
240 { &sound3Index, sizeof(int32) }, | |
241 { &sound3Continue, sizeof(int32) }, | |
242 { &sound3OutputLevel, sizeof(int32) }, | |
243 { &sound4On, sizeof(int32) }, | |
244 { &sound4ATL, sizeof(int32) }, | |
245 { &sound4Skip, sizeof(int32) }, | |
246 { &sound4Index, sizeof(int32) }, | |
247 { &sound4Clock, sizeof(int32) }, | |
248 { &sound4ShiftRight, sizeof(int32) }, | |
249 { &sound4ShiftSkip, sizeof(int32) }, | |
250 { &sound4ShiftIndex, sizeof(int32) }, | |
251 { &sound4NSteps, sizeof(int32) }, | |
252 { &sound4CountDown, sizeof(int32) }, | |
253 { &sound4Continue, sizeof(int32) }, | |
254 { &sound4EnvelopeVolume, sizeof(int32) }, | |
255 { &sound4EnvelopeATL, sizeof(int32) }, | |
256 { &sound4EnvelopeATLReload, sizeof(int32) }, | |
257 { &sound4EnvelopeUpDown, sizeof(int32) }, | |
258 { &soundEnableFlag, sizeof(int32) }, | |
259 { &soundControl, sizeof(int32) }, | |
260 { &soundDSFifoAIndex, sizeof(int32) }, | |
261 { &soundDSFifoACount, sizeof(int32) }, | |
262 { &soundDSFifoAWriteIndex, sizeof(int32) }, | |
263 { &soundDSAEnabled, sizeof(bool8) }, | |
264 { &soundDSATimer, sizeof(int32) }, | |
265 { &soundDSFifoA[0], 32 }, | |
266 { &soundDSAValue, sizeof(u8) }, | |
267 { &soundDSFifoBIndex, sizeof(int32) }, | |
268 { &soundDSFifoBCount, sizeof(int32) }, | |
269 { &soundDSFifoBWriteIndex, sizeof(int32) }, | |
270 { &soundDSBEnabled, sizeof(int32) }, | |
271 { &soundDSBTimer, sizeof(int32) }, | |
272 { &soundDSFifoB[0], 32 }, | |
273 { &soundDSBValue_int32, sizeof(int32) }, // save as int32 because of a mistake of the past. | |
274 { &soundBuffer[0][0], 6 * 735 }, | |
275 { &soundFinalWave[0], 2 * 735 }, | |
276 { NULL, 0 } | |
277 }; | |
278 | |
279 variable_desc soundSaveStructV2[] = { | |
280 { &sound3WaveRam[0], 0x20 }, | |
281 { &sound3Bank, sizeof(int32) }, | |
282 { &sound3DataSize, sizeof(int32) }, | |
283 { &sound3ForcedOutput, sizeof(int32) }, | |
284 { NULL, 0 } | |
285 }; | |
286 | |
287 //variable_desc soundSaveStructV3[] = { | |
288 // { &soundTicks, sizeof(soundtick_t) }, | |
289 // { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) }, | |
290 // { &USE_TICKS_AS, sizeof(soundtick_t) }, | |
291 // { NULL, 0 } | |
292 //}; | |
293 | |
294 void soundEvent(u32 address, u8 data) | |
295 { | |
296 int freq = 0; | |
297 | |
298 switch (address) | |
299 { | |
300 case NR10: | |
301 data &= 0x7f; | |
302 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7); | |
303 sound1SweepSteps = data & 7; | |
304 sound1SweepUpDown = data & 0x08; | |
305 sound1SweepStep = 0; | |
306 ioMem[address] = data; | |
307 break; | |
308 case NR11: | |
309 sound1Wave = soundWavePattern[data >> 6]; | |
310 sound1ATL = 172 * (64 - (data & 0x3f)); | |
311 ioMem[address] = data; | |
312 break; | |
313 case NR12: | |
314 sound1EnvelopeUpDown = data & 0x08; | |
315 sound1EnvelopeATLReload = 689 * (data & 7); | |
316 if ((data & 0xF8) == 0) | |
317 sound1EnvelopeVolume = 0; | |
318 ioMem[address] = data; | |
319 break; | |
320 case NR13: | |
321 freq = (((int)(ioMem[NR14] & 7)) << 8) | data; | |
322 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f)); | |
323 freq = 2048 - freq; | |
324 if (freq) | |
325 { | |
326 sound1Skip = SOUND_MAGIC / freq; | |
327 } | |
328 else | |
329 sound1Skip = 0; | |
330 ioMem[address] = data; | |
331 break; | |
332 case NR14: | |
333 data &= 0xC7; | |
334 freq = (((int)(data & 7) << 8) | ioMem[NR13]); | |
335 freq = 2048 - freq; | |
336 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f)); | |
337 sound1Continue = data & 0x40; | |
338 if (freq) | |
339 { | |
340 sound1Skip = SOUND_MAGIC / freq; | |
341 } | |
342 else | |
343 sound1Skip = 0; | |
344 if (data & 0x80) | |
345 { | |
346 ioMem[NR52] |= 1; | |
347 sound1EnvelopeVolume = ioMem[NR12] >> 4; | |
348 sound1EnvelopeUpDown = ioMem[NR12] & 0x08; | |
349 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f)); | |
350 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (ioMem[NR12] & 7); | |
351 sound1SweepATL = sound1SweepATLReload = 344 * ((ioMem[NR10] >> 4) & 7); | |
352 sound1SweepSteps = ioMem[NR10] & 7; | |
353 sound1SweepUpDown = ioMem[NR10] & 0x08; | |
354 sound1SweepStep = 0; | |
355 | |
356 sound1Index = 0; | |
357 sound1On = 1; | |
358 } | |
359 ioMem[address] = data; | |
360 break; | |
361 case NR21: | |
362 sound2Wave = soundWavePattern[data >> 6]; | |
363 sound2ATL = 172 * (64 - (data & 0x3f)); | |
364 ioMem[address] = data; | |
365 break; | |
366 case NR22: | |
367 sound2EnvelopeUpDown = data & 0x08; | |
368 sound2EnvelopeATLReload = 689 * (data & 7); | |
369 if ((data & 0xF8) == 0) | |
370 sound2EnvelopeVolume = 0; | |
371 ioMem[address] = data; | |
372 break; | |
373 case NR23: | |
374 freq = (((int)(ioMem[NR24] & 7)) << 8) | data; | |
375 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f)); | |
376 freq = 2048 - freq; | |
377 if (freq) | |
378 { | |
379 sound2Skip = SOUND_MAGIC / freq; | |
380 } | |
381 else | |
382 sound2Skip = 0; | |
383 ioMem[address] = data; | |
384 break; | |
385 case NR24: | |
386 data &= 0xC7; | |
387 freq = (((int)(data & 7) << 8) | ioMem[NR23]); | |
388 freq = 2048 - freq; | |
389 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f)); | |
390 sound2Continue = data & 0x40; | |
391 if (freq) | |
392 { | |
393 sound2Skip = SOUND_MAGIC / freq; | |
394 } | |
395 else | |
396 sound2Skip = 0; | |
397 if (data & 0x80) | |
398 { | |
399 ioMem[NR52] |= 2; | |
400 sound2EnvelopeVolume = ioMem[NR22] >> 4; | |
401 sound2EnvelopeUpDown = ioMem[NR22] & 0x08; | |
402 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f)); | |
403 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (ioMem[NR22] & 7); | |
404 | |
405 sound2Index = 0; | |
406 sound2On = 1; | |
407 } | |
408 ioMem[address] = data; | |
409 break; | |
410 case NR30: | |
411 data &= 0xe0; | |
412 if (!(data & 0x80)) | |
413 { | |
414 ioMem[NR52] &= 0xfb; | |
415 sound3On = 0; | |
416 } | |
417 if (((data >> 6) & 1) != sound3Bank) | |
418 memcpy(&ioMem[0x90], &sound3WaveRam[(((data >> 6) & 1) * 0x10) ^ 0x10], | |
419 0x10); | |
420 sound3Bank = (data >> 6) & 1; | |
421 sound3DataSize = (data >> 5) & 1; | |
422 ioMem[address] = data; | |
423 break; | |
424 case NR31: | |
425 sound3ATL = 172 * (256 - data); | |
426 ioMem[address] = data; | |
427 break; | |
428 case NR32: | |
429 data &= 0xe0; | |
430 sound3OutputLevel = (data >> 5) & 3; | |
431 sound3ForcedOutput = (data >> 7) & 1; | |
432 ioMem[address] = data; | |
433 break; | |
434 case NR33: | |
435 freq = 2048 - (((int)(ioMem[NR34] & 7) << 8) | data); | |
436 if (freq) | |
437 { | |
438 sound3Skip = SOUND_MAGIC_2 / freq; | |
439 } | |
440 else | |
441 sound3Skip = 0; | |
442 ioMem[address] = data; | |
443 break; | |
444 case NR34: | |
445 data &= 0xc7; | |
446 freq = 2048 - (((data & 7) << 8) | (int)ioMem[NR33]); | |
447 if (freq) | |
448 { | |
449 sound3Skip = SOUND_MAGIC_2 / freq; | |
450 } | |
451 else | |
452 { | |
453 sound3Skip = 0; | |
454 } | |
455 sound3Continue = data & 0x40; | |
456 if ((data & 0x80) && (ioMem[NR30] & 0x80)) | |
457 { | |
458 ioMem[NR52] |= 4; | |
459 sound3ATL = 172 * (256 - ioMem[NR31]); | |
460 sound3Index = 0; | |
461 sound3On = 1; | |
462 } | |
463 ioMem[address] = data; | |
464 break; | |
465 case NR41: | |
466 data &= 0x3f; | |
467 sound4ATL = 172 * (64 - (data & 0x3f)); | |
468 ioMem[address] = data; | |
469 break; | |
470 case NR42: | |
471 sound4EnvelopeUpDown = data & 0x08; | |
472 sound4EnvelopeATLReload = 689 * (data & 7); | |
473 if ((data & 0xF8) == 0) | |
474 sound4EnvelopeVolume = 0; | |
475 ioMem[address] = data; | |
476 break; | |
477 case NR43: | |
478 freq = soundFreqRatio[data & 7]; | |
479 sound4NSteps = data & 0x08; | |
480 | |
481 sound4Skip = freq * NOISE_MAGIC; | |
482 | |
483 sound4Clock = data >> 4; | |
484 | |
485 freq = freq / soundShiftClock[sound4Clock]; | |
486 | |
487 sound4ShiftSkip = freq * NOISE_MAGIC; | |
488 ioMem[address] = data; | |
489 break; | |
490 case NR44: | |
491 data &= 0xc0; | |
492 sound4Continue = data & 0x40; | |
493 if (data & 0x80) | |
494 { | |
495 ioMem[NR52] |= 8; | |
496 sound4EnvelopeVolume = ioMem[NR42] >> 4; | |
497 sound4EnvelopeUpDown = ioMem[NR42] & 0x08; | |
498 sound4ATL = 172 * (64 - (ioMem[NR41] & 0x3f)); | |
499 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (ioMem[NR42] & 7); | |
500 | |
501 sound4On = 1; | |
502 | |
503 sound4Index = 0; | |
504 sound4ShiftIndex = 0; | |
505 | |
506 freq = soundFreqRatio[ioMem[NR43] & 7]; | |
507 | |
508 sound4Skip = freq * NOISE_MAGIC; | |
509 | |
510 sound4NSteps = ioMem[NR43] & 0x08; | |
511 | |
512 freq = freq / soundShiftClock[ioMem[NR43] >> 4]; | |
513 | |
514 sound4ShiftSkip = freq * NOISE_MAGIC; | |
515 if (sound4NSteps) | |
516 sound4ShiftRight = 0x7f; | |
517 else | |
518 sound4ShiftRight = 0x7fff; | |
519 } | |
520 ioMem[address] = data; | |
521 break; | |
522 case NR50: | |
523 data &= 0x77; | |
524 soundLevel1 = data & 7; | |
525 soundLevel2 = (data >> 4) & 7; | |
526 ioMem[address] = data; | |
527 break; | |
528 case NR51: | |
529 soundBalance = (data & soundEnableFlag); | |
530 ioMem[address] = data; | |
531 break; | |
532 case NR52: | |
533 data &= 0x80; | |
534 data |= ioMem[NR52] & 15; | |
535 soundMasterOn = data & 0x80; | |
536 if (!(data & 0x80)) | |
537 { | |
538 sound1On = 0; | |
539 sound2On = 0; | |
540 sound3On = 0; | |
541 sound4On = 0; | |
542 } | |
543 ioMem[address] = data; | |
544 break; | |
545 case 0x90: | |
546 case 0x91: | |
547 case 0x92: | |
548 case 0x93: | |
549 case 0x94: | |
550 case 0x95: | |
551 case 0x96: | |
552 case 0x97: | |
553 case 0x98: | |
554 case 0x99: | |
555 case 0x9a: | |
556 case 0x9b: | |
557 case 0x9c: | |
558 case 0x9d: | |
559 case 0x9e: | |
560 case 0x9f: | |
561 sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 15)] = data; | |
562 break; | |
563 } | |
564 } | |
565 | |
566 void soundEvent(u32 address, u16 data) | |
567 { | |
568 switch (address) | |
569 { | |
570 case SGCNT0_H: | |
571 data &= 0xFF0F; | |
572 soundControl = data & 0x770F;; | |
573 if (data & 0x0800) | |
574 { | |
575 soundDSFifoAWriteIndex = 0; | |
576 soundDSFifoAIndex = 0; | |
577 soundDSFifoACount = 0; | |
578 soundDSAValue = 0; | |
579 memset(soundDSFifoA, 0, 32); | |
580 } | |
581 soundDSAEnabled = (data & 0x0300) ? true : false; | |
582 soundDSATimer = (data & 0x0400) ? 1 : 0; | |
583 if (data & 0x8000) | |
584 { | |
585 soundDSFifoBWriteIndex = 0; | |
586 soundDSFifoBIndex = 0; | |
587 soundDSFifoBCount = 0; | |
588 soundDSBValue = 0; | |
589 memset(soundDSFifoB, 0, 32); | |
590 } | |
591 soundDSBEnabled = (data & 0x3000) ? true : false; | |
592 soundDSBTimer = (data & 0x4000) ? 1 : 0; | |
593 *((u16 *)&ioMem[address]) = data; | |
594 break; | |
595 case FIFOA_L: | |
596 case FIFOA_H: | |
597 soundDSFifoA[soundDSFifoAWriteIndex++] = data & 0xFF; | |
598 soundDSFifoA[soundDSFifoAWriteIndex++] = data >> 8; | |
599 soundDSFifoACount += 2; | |
600 soundDSFifoAWriteIndex &= 31; | |
601 *((u16 *)&ioMem[address]) = data; | |
602 break; | |
603 case FIFOB_L: | |
604 case FIFOB_H: | |
605 soundDSFifoB[soundDSFifoBWriteIndex++] = data & 0xFF; | |
606 soundDSFifoB[soundDSFifoBWriteIndex++] = data >> 8; | |
607 soundDSFifoBCount += 2; | |
608 soundDSFifoBWriteIndex &= 31; | |
609 *((u16 *)&ioMem[address]) = data; | |
610 break; | |
611 case 0x88: | |
612 data &= 0xC3FF; | |
613 *((u16 *)&ioMem[address]) = data; | |
614 break; | |
615 case 0x90: | |
616 case 0x92: | |
617 case 0x94: | |
618 case 0x96: | |
619 case 0x98: | |
620 case 0x9a: | |
621 case 0x9c: | |
622 case 0x9e: | |
623 *((u16 *)&sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 14)]) = data; | |
624 *((u16 *)&ioMem[address]) = data; | |
625 break; | |
626 } | |
627 } | |
628 | |
629 void soundChannel1() | |
630 { | |
631 int vol = sound1EnvelopeVolume; | |
632 | |
633 int freq = 0; | |
634 int value = 0; | |
635 | |
636 if (sound1On && (sound1ATL || !sound1Continue)) | |
637 { | |
638 sound1Index += soundQuality * sound1Skip; | |
639 sound1Index &= 0x1fffffff; | |
640 | |
641 value = ((s8)sound1Wave[sound1Index >> 24]) * vol; | |
642 } | |
643 | |
644 soundBuffer[0][soundIndex] = value; | |
645 | |
646 if (sound1On) | |
647 { | |
648 if (sound1ATL) | |
649 { | |
650 sound1ATL -= soundQuality; | |
651 | |
652 if (sound1ATL <= 0 && sound1Continue) | |
653 { | |
654 ioMem[NR52] &= 0xfe; | |
655 sound1On = 0; | |
656 } | |
657 } | |
658 | |
659 if (sound1EnvelopeATL) | |
660 { | |
661 sound1EnvelopeATL -= soundQuality; | |
662 | |
663 if (sound1EnvelopeATL <= 0) | |
664 { | |
665 if (sound1EnvelopeUpDown) | |
666 { | |
667 if (sound1EnvelopeVolume < 15) | |
668 sound1EnvelopeVolume++; | |
669 } | |
670 else | |
671 { | |
672 if (sound1EnvelopeVolume) | |
673 sound1EnvelopeVolume--; | |
674 } | |
675 | |
676 sound1EnvelopeATL += sound1EnvelopeATLReload; | |
677 } | |
678 } | |
679 | |
680 if (sound1SweepATL) | |
681 { | |
682 sound1SweepATL -= soundQuality; | |
683 | |
684 if (sound1SweepATL <= 0) | |
685 { | |
686 freq = (((int)(ioMem[NR14] & 7) << 8) | ioMem[NR13]); | |
687 | |
688 int updown = 1; | |
689 | |
690 if (sound1SweepUpDown) | |
691 updown = -1; | |
692 | |
693 int newfreq = 0; | |
694 if (sound1SweepSteps) | |
695 { | |
696 newfreq = freq + updown * freq / (1 << sound1SweepSteps); | |
697 if (newfreq == freq) | |
698 newfreq = 0; | |
699 } | |
700 else | |
701 newfreq = freq; | |
702 | |
703 if (newfreq < 0) | |
704 { | |
705 sound1SweepATL += sound1SweepATLReload; | |
706 } | |
707 else if (newfreq > 2047) | |
708 { | |
709 sound1SweepATL = 0; | |
710 sound1On = 0; | |
711 ioMem[NR52] &= 0xfe; | |
712 } | |
713 else | |
714 { | |
715 sound1SweepATL += sound1SweepATLReload; | |
716 sound1Skip = SOUND_MAGIC / (2048 - newfreq); | |
717 | |
718 ioMem[NR13] = newfreq & 0xff; | |
719 ioMem[NR14] = (ioMem[NR14] & 0xf8) | ((newfreq >> 8) & 7); | |
720 } | |
721 } | |
722 } | |
723 } | |
724 } | |
725 | |
726 void soundChannel2() | |
727 { | |
728 // int freq = 0; | |
729 int vol = sound2EnvelopeVolume; | |
730 | |
731 int value = 0; | |
732 | |
733 if (sound2On && (sound2ATL || !sound2Continue)) | |
734 { | |
735 sound2Index += soundQuality * sound2Skip; | |
736 sound2Index &= 0x1fffffff; | |
737 | |
738 value = ((s8)sound2Wave[sound2Index >> 24]) * vol; | |
739 } | |
740 | |
741 soundBuffer[1][soundIndex] = value; | |
742 | |
743 if (sound2On) | |
744 { | |
745 if (sound2ATL) | |
746 { | |
747 sound2ATL -= soundQuality; | |
748 | |
749 if (sound2ATL <= 0 && sound2Continue) | |
750 { | |
751 ioMem[NR52] &= 0xfd; | |
752 sound2On = 0; | |
753 } | |
754 } | |
755 | |
756 if (sound2EnvelopeATL) | |
757 { | |
758 sound2EnvelopeATL -= soundQuality; | |
759 | |
760 if (sound2EnvelopeATL <= 0) | |
761 { | |
762 if (sound2EnvelopeUpDown) | |
763 { | |
764 if (sound2EnvelopeVolume < 15) | |
765 sound2EnvelopeVolume++; | |
766 } | |
767 else | |
768 { | |
769 if (sound2EnvelopeVolume) | |
770 sound2EnvelopeVolume--; | |
771 } | |
772 sound2EnvelopeATL += sound2EnvelopeATLReload; | |
773 } | |
774 } | |
775 } | |
776 } | |
777 | |
778 void soundChannel3() | |
779 { | |
780 int value = sound3Last; | |
781 | |
782 if (sound3On && (sound3ATL || !sound3Continue)) | |
783 { | |
784 sound3Index += soundQuality * sound3Skip; | |
785 if (sound3DataSize) | |
786 { | |
787 sound3Index &= 0x3fffffff; | |
788 value = sound3WaveRam[sound3Index >> 25]; | |
789 } | |
790 else | |
791 { | |
792 sound3Index &= 0x1fffffff; | |
793 value = sound3WaveRam[sound3Bank * 0x10 + (sound3Index >> 25)]; | |
794 } | |
795 | |
796 if ((sound3Index & 0x01000000)) | |
797 { | |
798 value &= 0x0f; | |
799 } | |
800 else | |
801 { | |
802 value >>= 4; | |
803 } | |
804 | |
805 value -= 8; | |
806 value *= 2; | |
807 | |
808 if (sound3ForcedOutput) | |
809 { | |
810 value = ((value >> 1) + value) >> 1; | |
811 } | |
812 else | |
813 { | |
814 switch (sound3OutputLevel) | |
815 { | |
816 case 0: | |
817 value = 0; | |
818 break; | |
819 case 1: | |
820 break; | |
821 case 2: | |
822 value = (value >> 1); | |
823 break; | |
824 case 3: | |
825 value = (value >> 2); | |
826 break; | |
827 } | |
828 } | |
829 //value += 1; | |
830 sound3Last = value; | |
831 } | |
832 | |
833 soundBuffer[2][soundIndex] = value; | |
834 | |
835 if (sound3On) | |
836 { | |
837 if (sound3ATL) | |
838 { | |
839 sound3ATL -= soundQuality; | |
840 | |
841 if (sound3ATL <= 0 && sound3Continue) | |
842 { | |
843 ioMem[NR52] &= 0xfb; | |
844 sound3On = 0; | |
845 } | |
846 } | |
847 } | |
848 } | |
849 | |
850 void soundChannel4() | |
851 { | |
852 int vol = sound4EnvelopeVolume; | |
853 | |
854 int value = 0; | |
855 | |
856 if (sound4Clock <= 0x0c) | |
857 { | |
858 if (sound4On && (sound4ATL || !sound4Continue)) | |
859 { | |
860 #define NOISE_ONE_SAMP_SCALE 0x200000 | |
861 | |
862 sound4Index += soundQuality * sound4Skip; | |
863 sound4ShiftIndex += soundQuality * sound4ShiftSkip; | |
864 | |
865 if (sound4NSteps) | |
866 { | |
867 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE) | |
868 { | |
869 sound4ShiftRight = (((sound4ShiftRight << 6) ^ | |
870 (sound4ShiftRight << 5)) & 0x40) | | |
871 (sound4ShiftRight >> 1); | |
872 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE; | |
873 } | |
874 } | |
875 else | |
876 { | |
877 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE) | |
878 { | |
879 sound4ShiftRight = (((sound4ShiftRight << 14) ^ | |
880 (sound4ShiftRight << 13)) & 0x4000) | | |
881 (sound4ShiftRight >> 1); | |
882 | |
883 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE; | |
884 } | |
885 } | |
886 | |
887 sound4Index %= NOISE_ONE_SAMP_SCALE; | |
888 sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE; | |
889 | |
890 value = ((sound4ShiftRight & 1) * 2 - 1) * vol; | |
891 } | |
892 else | |
893 { | |
894 value = 0; | |
895 } | |
896 } | |
897 | |
898 soundBuffer[3][soundIndex] = value; | |
899 | |
900 if (sound4On) | |
901 { | |
902 if (sound4ATL) | |
903 { | |
904 sound4ATL -= soundQuality; | |
905 | |
906 if (sound4ATL <= 0 && sound4Continue) | |
907 { | |
908 ioMem[NR52] &= 0xfd; | |
909 sound4On = 0; | |
910 } | |
911 } | |
912 | |
913 if (sound4EnvelopeATL) | |
914 { | |
915 sound4EnvelopeATL -= soundQuality; | |
916 | |
917 if (sound4EnvelopeATL <= 0) | |
918 { | |
919 if (sound4EnvelopeUpDown) | |
920 { | |
921 if (sound4EnvelopeVolume < 15) | |
922 sound4EnvelopeVolume++; | |
923 } | |
924 else | |
925 { | |
926 if (sound4EnvelopeVolume) | |
927 sound4EnvelopeVolume--; | |
928 } | |
929 sound4EnvelopeATL += sound4EnvelopeATLReload; | |
930 } | |
931 } | |
932 } | |
933 } | |
934 | |
935 void soundDirectSoundA() | |
936 { | |
937 soundBuffer[4][soundIndex] = soundDSAValue; | |
938 } | |
939 | |
940 void soundDirectSoundATimer() | |
941 { | |
942 if (soundDSAEnabled) | |
943 { | |
944 if (soundDSFifoACount <= 16) | |
945 { | |
946 CPUCheckDMA(3, 2); | |
947 if (soundDSFifoACount <= 16) | |
948 { | |
949 soundEvent(FIFOA_L, (u16)0); | |
950 soundEvent(FIFOA_H, (u16)0); | |
951 soundEvent(FIFOA_L, (u16)0); | |
952 soundEvent(FIFOA_H, (u16)0); | |
953 soundEvent(FIFOA_L, (u16)0); | |
954 soundEvent(FIFOA_H, (u16)0); | |
955 soundEvent(FIFOA_L, (u16)0); | |
956 soundEvent(FIFOA_H, (u16)0); | |
957 } | |
958 } | |
959 | |
960 soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]); | |
961 soundDSFifoAIndex = (++soundDSFifoAIndex) & 31; | |
962 soundDSFifoACount--; | |
963 } | |
964 else | |
965 soundDSAValue = 0; | |
966 } | |
967 | |
968 void soundDirectSoundB() | |
969 { | |
970 soundBuffer[5][soundIndex] = soundDSBValue; | |
971 } | |
972 | |
973 void soundDirectSoundBTimer() | |
974 { | |
975 if (soundDSBEnabled) | |
976 { | |
977 if (soundDSFifoBCount <= 16) | |
978 { | |
979 CPUCheckDMA(3, 4); | |
980 if (soundDSFifoBCount <= 16) | |
981 { | |
982 soundEvent(FIFOB_L, (u16)0); | |
983 soundEvent(FIFOB_H, (u16)0); | |
984 soundEvent(FIFOB_L, (u16)0); | |
985 soundEvent(FIFOB_H, (u16)0); | |
986 soundEvent(FIFOB_L, (u16)0); | |
987 soundEvent(FIFOB_H, (u16)0); | |
988 soundEvent(FIFOB_L, (u16)0); | |
989 soundEvent(FIFOB_H, (u16)0); | |
990 } | |
991 } | |
992 | |
993 soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]); | |
994 soundDSFifoBIndex = (++soundDSFifoBIndex) & 31; | |
995 soundDSFifoBCount--; | |
996 } | |
997 else | |
998 { | |
999 soundDSBValue = 0; | |
1000 } | |
1001 } | |
1002 | |
1003 void soundTimerOverflow(int timer) | |
1004 { | |
1005 if (soundDSAEnabled && (soundDSATimer == timer)) | |
1006 { | |
1007 soundDirectSoundATimer(); | |
1008 } | |
1009 if (soundDSBEnabled && (soundDSBTimer == timer)) | |
1010 { | |
1011 soundDirectSoundBTimer(); | |
1012 } | |
1013 } | |
1014 | |
1015 void soundMix() | |
1016 { | |
1017 int res = 0; | |
1018 int cgbRes = 0; | |
1019 int ratio = ioMem[0x82] & 3; | |
1020 int dsaRatio = ioMem[0x82] & 4; | |
1021 int dsbRatio = ioMem[0x82] & 8; | |
1022 | |
1023 if (ioMem) | |
1024 soundBalance = (ioMem[NR51] & soundEnableFlag & ~soundMutedFlag); | |
1025 | |
1026 if (soundBalance & 16) | |
1027 { | |
1028 cgbRes = ((s8)soundBuffer[0][soundIndex]); | |
1029 } | |
1030 if (soundBalance & 32) | |
1031 { | |
1032 cgbRes += ((s8)soundBuffer[1][soundIndex]); | |
1033 } | |
1034 if (soundBalance & 64) | |
1035 { | |
1036 cgbRes += ((s8)soundBuffer[2][soundIndex]); | |
1037 } | |
1038 if (soundBalance & 128) | |
1039 { | |
1040 cgbRes += ((s8)soundBuffer[3][soundIndex]); | |
1041 } | |
1042 | |
1043 if ((soundControl & 0x0200) && (soundEnableFlag & 0x100)) | |
1044 { | |
1045 if (!dsaRatio) | |
1046 res = ((s8)soundBuffer[4][soundIndex]) >> 1; | |
1047 else | |
1048 res = ((s8)soundBuffer[4][soundIndex]); | |
1049 } | |
1050 | |
1051 if ((soundControl & 0x2000) && (soundEnableFlag & 0x200)) | |
1052 { | |
1053 if (!dsbRatio) | |
1054 res += ((s8)soundBuffer[5][soundIndex]) >> 1; | |
1055 else | |
1056 res += ((s8)soundBuffer[5][soundIndex]); | |
1057 } | |
1058 | |
1059 res = (res * 170); | |
1060 cgbRes = (cgbRes * 52 * soundLevel1); | |
1061 | |
1062 switch (ratio) | |
1063 { | |
1064 case 0: | |
1065 case 3: // prohibited, but 25% | |
1066 cgbRes >>= 2; | |
1067 break; | |
1068 case 1: | |
1069 cgbRes >>= 1; | |
1070 break; | |
1071 case 2: | |
1072 break; | |
1073 } | |
1074 | |
1075 res += cgbRes; | |
1076 | |
1077 if (soundEcho) | |
1078 { | |
1079 res *= 2; | |
1080 res += soundFilter[soundEchoIndex]; | |
1081 res /= 2; | |
1082 soundFilter[soundEchoIndex++] = res; | |
1083 } | |
1084 | |
1085 if (soundLowPass) | |
1086 { | |
1087 soundLeft[4] = soundLeft[3]; | |
1088 soundLeft[3] = soundLeft[2]; | |
1089 soundLeft[2] = soundLeft[1]; | |
1090 soundLeft[1] = soundLeft[0]; | |
1091 soundLeft[0] = res; | |
1092 res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] + | |
1093 soundLeft[0]) / 14; | |
1094 } | |
1095 | |
1096 bool noSpecialEffects = false; | |
1097 #if (defined(WIN32) && !defined(SDL)) | |
1098 if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog) | |
1099 noSpecialEffects = true; | |
1100 #endif | |
1101 | |
1102 if (!noSpecialEffects) | |
1103 { | |
1104 switch (soundVolume) | |
1105 { | |
1106 case 0: | |
1107 case 1: | |
1108 case 2: | |
1109 case 3: | |
1110 res *= (soundVolume + 1); | |
1111 break; | |
1112 case 4: | |
1113 res >>= 2; | |
1114 break; | |
1115 case 5: | |
1116 res >>= 1; | |
1117 break; | |
1118 } | |
1119 } | |
1120 | |
1121 if (res > 32767) | |
1122 res = 32767; | |
1123 if (res < -32768) | |
1124 res = -32768; | |
1125 | |
1126 if (soundReverse && !noSpecialEffects) | |
1127 { | |
1128 soundFinalWave[++soundBufferIndex] = res; | |
1129 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) | |
1130 /*assert(false)*/; | |
1131 else | |
1132 soundFrameSound[++soundFrameSoundWritten] = res; | |
1133 } | |
1134 else | |
1135 { | |
1136 soundFinalWave[soundBufferIndex++] = res; | |
1137 if (soundFrameSoundWritten >= countof(soundFrameSound)) | |
1138 /*assert(false)*/; | |
1139 else | |
1140 soundFrameSound[soundFrameSoundWritten++] = res; | |
1141 } | |
1142 | |
1143 res = 0; | |
1144 cgbRes = 0; | |
1145 | |
1146 if (soundBalance & 1) | |
1147 { | |
1148 cgbRes = ((s8)soundBuffer[0][soundIndex]); | |
1149 } | |
1150 if (soundBalance & 2) | |
1151 { | |
1152 cgbRes += ((s8)soundBuffer[1][soundIndex]); | |
1153 } | |
1154 if (soundBalance & 4) | |
1155 { | |
1156 cgbRes += ((s8)soundBuffer[2][soundIndex]); | |
1157 } | |
1158 if (soundBalance & 8) | |
1159 { | |
1160 cgbRes += ((s8)soundBuffer[3][soundIndex]); | |
1161 } | |
1162 | |
1163 if ((soundControl & 0x0100) && (soundEnableFlag & 0x100)) | |
1164 { | |
1165 if (!dsaRatio) | |
1166 res = ((s8)soundBuffer[4][soundIndex]) >> 1; | |
1167 else | |
1168 res = ((s8)soundBuffer[4][soundIndex]); | |
1169 } | |
1170 | |
1171 if ((soundControl & 0x1000) && (soundEnableFlag & 0x200)) | |
1172 { | |
1173 if (!dsbRatio) | |
1174 res += ((s8)soundBuffer[5][soundIndex]) >> 1; | |
1175 else | |
1176 res += ((s8)soundBuffer[5][soundIndex]); | |
1177 } | |
1178 | |
1179 res = (res * 170); | |
1180 cgbRes = (cgbRes * 52 * soundLevel1); | |
1181 | |
1182 switch (ratio) | |
1183 { | |
1184 case 0: | |
1185 case 3: // prohibited, but 25% | |
1186 cgbRes >>= 2; | |
1187 break; | |
1188 case 1: | |
1189 cgbRes >>= 1; | |
1190 break; | |
1191 case 2: | |
1192 break; | |
1193 } | |
1194 | |
1195 res += cgbRes; | |
1196 | |
1197 if (soundEcho) | |
1198 { | |
1199 res *= 2; | |
1200 res += soundFilter[soundEchoIndex]; | |
1201 res /= 2; | |
1202 soundFilter[soundEchoIndex++] = res; | |
1203 | |
1204 if (soundEchoIndex >= 4000) | |
1205 soundEchoIndex = 0; | |
1206 } | |
1207 | |
1208 if (soundLowPass) | |
1209 { | |
1210 soundRight[4] = soundRight[3]; | |
1211 soundRight[3] = soundRight[2]; | |
1212 soundRight[2] = soundRight[1]; | |
1213 soundRight[1] = soundRight[0]; | |
1214 soundRight[0] = res; | |
1215 res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] + | |
1216 soundRight[0]) / 14; | |
1217 } | |
1218 | |
1219 if (!noSpecialEffects) | |
1220 { | |
1221 switch (soundVolume) | |
1222 { | |
1223 case 0: | |
1224 case 1: | |
1225 case 2: | |
1226 case 3: | |
1227 res *= (soundVolume + 1); | |
1228 break; | |
1229 case 4: | |
1230 res >>= 2; | |
1231 break; | |
1232 case 5: | |
1233 res >>= 1; | |
1234 break; | |
1235 } | |
1236 } | |
1237 | |
1238 if (res > 32767) | |
1239 res = 32767; | |
1240 if (res < -32768) | |
1241 res = -32768; | |
1242 | |
1243 if (soundReverse && !noSpecialEffects) | |
1244 { | |
1245 soundFinalWave[-1 + soundBufferIndex++] = res; | |
1246 if ((soundFrameSoundWritten) >= countof(soundFrameSound)) | |
1247 /*assert(false)*/; | |
1248 else | |
1249 soundFrameSound[-1 + soundFrameSoundWritten++] = res; | |
1250 } | |
1251 else | |
1252 { | |
1253 soundFinalWave[soundBufferIndex++] = res; | |
1254 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) | |
1255 /*assert(false)*/; | |
1256 else | |
1257 soundFrameSound[soundFrameSoundWritten++] = res; | |
1258 } | |
1259 } | |
1260 | |
1261 void soundTick() | |
1262 { | |
1263 if (systemSoundOn) | |
1264 { | |
1265 if (soundMasterOn && !stopState) | |
1266 { | |
1267 soundChannel1(); | |
1268 soundChannel2(); | |
1269 soundChannel3(); | |
1270 soundChannel4(); | |
1271 soundDirectSoundA(); | |
1272 soundDirectSoundB(); | |
1273 soundMix(); | |
1274 } | |
1275 else | |
1276 { | |
1277 soundFinalWave[soundBufferIndex++] = 0; | |
1278 soundFinalWave[soundBufferIndex++] = 0; | |
1279 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound)) | |
1280 /*assert(false)*/; | |
1281 else | |
1282 { | |
1283 soundFrameSound[soundFrameSoundWritten++] = 0; | |
1284 soundFrameSound[soundFrameSoundWritten++] = 0; | |
1285 } | |
1286 } | |
1287 | |
1288 soundIndex++; | |
1289 | |
1290 if (2 * soundBufferIndex >= soundBufferLen) | |
1291 { | |
1292 if (systemSoundOn) | |
1293 { | |
1294 if (soundPaused) | |
1295 { | |
1296 soundResume(); | |
1297 } | |
1298 | |
1299 systemSoundWriteToBuffer(); | |
1300 } | |
1301 soundIndex = 0; | |
1302 soundBufferIndex = 0; | |
1303 } | |
1304 } | |
1305 } | |
1306 | |
1307 void soundShutdown() | |
1308 { | |
1309 systemSoundShutdown(); | |
1310 } | |
1311 | |
1312 void soundPause() | |
1313 { | |
1314 systemSoundPause(); | |
1315 } | |
1316 | |
1317 void soundResume() | |
1318 { | |
1319 systemSoundResume(); | |
1320 } | |
1321 | |
1322 void soundEnableChannels(int channels) | |
1323 { | |
1324 int c = (channels & 0x0f) << 4; | |
1325 soundEnableFlag |= ((channels & 0x30f) | c); | |
1326 } | |
1327 | |
1328 void soundDisableChannels(int channels) | |
1329 { | |
1330 int c = (channels & 0x0f) << 4; | |
1331 soundEnableFlag &= ~((channels & 0x30f) | c); | |
1332 } | |
1333 | |
1334 int soundGetEnabledChannels() | |
1335 { | |
1336 return (soundEnableFlag & 0x30f); | |
1337 } | |
1338 | |
1339 #if 0 | |
1340 // unused | |
1341 void soundMuteChannels(int channels) | |
1342 { | |
1343 soundMutedFlag |= channels & 0x30f; | |
1344 } | |
1345 | |
1346 void soundUnmuteChannels(int channels) | |
1347 { | |
1348 soundMutedFlag &= ~(channels & 0x30f); | |
1349 } | |
1350 | |
1351 int soundGetMutedChannels() | |
1352 { | |
1353 return (soundMutedFlag & 0x30f); | |
1354 } | |
1355 #endif | |
1356 | |
1357 void soundReset() | |
1358 { | |
1359 systemSoundReset(); | |
1360 | |
1361 soundPaused = 1; | |
1362 soundPlay = 0; | |
1363 SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS; | |
1364 soundTicks = SOUND_CLOCK_TICKS; | |
1365 soundNextPosition = 0; | |
1366 soundMasterOn = 1; | |
1367 soundIndex = 0; | |
1368 soundBufferIndex = 0; | |
1369 soundLevel1 = 7; | |
1370 soundLevel2 = 7; | |
1371 | |
1372 sound1On = 0; | |
1373 sound1ATL = 0; | |
1374 sound1Skip = 0; | |
1375 sound1Index = 0; | |
1376 sound1Continue = 0; | |
1377 sound1EnvelopeVolume = 0; | |
1378 sound1EnvelopeATL = 0; | |
1379 sound1EnvelopeUpDown = 0; | |
1380 sound1EnvelopeATLReload = 0; | |
1381 sound1SweepATL = 0; | |
1382 sound1SweepATLReload = 0; | |
1383 sound1SweepSteps = 0; | |
1384 sound1SweepUpDown = 0; | |
1385 sound1SweepStep = 0; | |
1386 sound1Wave = soundWavePattern[2]; | |
1387 | |
1388 sound2On = 0; | |
1389 sound2ATL = 0; | |
1390 sound2Skip = 0; | |
1391 sound2Index = 0; | |
1392 sound2Continue = 0; | |
1393 sound2EnvelopeVolume = 0; | |
1394 sound2EnvelopeATL = 0; | |
1395 sound2EnvelopeUpDown = 0; | |
1396 sound2EnvelopeATLReload = 0; | |
1397 sound2Wave = soundWavePattern[2]; | |
1398 | |
1399 sound3On = 0; | |
1400 sound3ATL = 0; | |
1401 sound3Skip = 0; | |
1402 sound3Index = 0; | |
1403 sound3Continue = 0; | |
1404 sound3OutputLevel = 0; | |
1405 sound3Last = 0; | |
1406 sound3Bank = 0; | |
1407 sound3DataSize = 0; | |
1408 sound3ForcedOutput = 0; | |
1409 | |
1410 sound4On = 0; | |
1411 sound4Clock = 0; | |
1412 sound4ATL = 0; | |
1413 sound4Skip = 0; | |
1414 sound4Index = 0; | |
1415 sound4ShiftRight = 0x7f; | |
1416 sound4NSteps = 0; | |
1417 sound4CountDown = 0; | |
1418 sound4Continue = 0; | |
1419 sound4EnvelopeVolume = 0; | |
1420 sound4EnvelopeATL = 0; | |
1421 sound4EnvelopeUpDown = 0; | |
1422 sound4EnvelopeATLReload = 0; | |
1423 | |
1424 sound1On = 0; | |
1425 sound2On = 0; | |
1426 sound3On = 0; | |
1427 sound4On = 0; | |
1428 | |
1429 int addr = 0x90; | |
1430 | |
1431 while (addr < 0xA0) | |
1432 { | |
1433 ioMem[addr++] = 0x00; | |
1434 ioMem[addr++] = 0xff; | |
1435 } | |
1436 | |
1437 addr = 0; | |
1438 while (addr < 0x20) | |
1439 { | |
1440 sound3WaveRam[addr++] = 0x00; | |
1441 sound3WaveRam[addr++] = 0xff; | |
1442 } | |
1443 | |
1444 memset(soundFinalWave, 0, soundBufferLen); | |
1445 | |
1446 memset(soundFilter, 0, sizeof(soundFilter)); | |
1447 soundEchoIndex = 0; | |
1448 } | |
1449 | |
1450 bool soundInit() | |
1451 { | |
1452 if (systemSoundInit()) | |
1453 { | |
1454 memset(soundBuffer[0], 0, 735 * 2); | |
1455 memset(soundBuffer[1], 0, 735 * 2); | |
1456 memset(soundBuffer[2], 0, 735 * 2); | |
1457 memset(soundBuffer[3], 0, 735 * 2); | |
1458 | |
1459 memset(soundFinalWave, 0, soundBufferLen); | |
1460 | |
1461 soundPaused = 1; | |
1462 return true; | |
1463 } | |
1464 return false; | |
1465 } | |
1466 | |
1467 void soundSetQuality(int quality) | |
1468 { | |
1469 if (soundQuality != quality && systemSoundCanChangeQuality()) | |
1470 { | |
1471 if (!soundOffFlag) | |
1472 soundShutdown(); | |
1473 soundQuality = quality; | |
1474 soundNextPosition = 0; | |
1475 if (!soundOffFlag) | |
1476 soundInit(); | |
1477 SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality; | |
1478 soundIndex = 0; | |
1479 soundBufferIndex = 0; | |
1480 } | |
1481 else if (soundQuality != quality) | |
1482 { | |
1483 soundNextPosition = 0; | |
1484 SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality; | |
1485 soundIndex = 0; | |
1486 soundBufferIndex = 0; | |
1487 } | |
1488 } | |
1489 | |
1490 void soundSaveGame(gzFile gzFile) | |
1491 { | |
1492 soundTicks_int32 = (int32) soundTicks; | |
1493 SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS; | |
1494 soundDSBValue_int32 = (int32) soundDSBValue; | |
1495 | |
1496 utilWriteData(gzFile, soundSaveStruct); | |
1497 utilWriteData(gzFile, soundSaveStructV2); | |
1498 | |
1499 utilGzWrite(gzFile, &soundQuality, sizeof(int32)); | |
1500 //utilWriteData(gzFile, soundSaveStructV3); | |
1501 } | |
1502 | |
1503 void soundReadGame(gzFile gzFile, int version) | |
1504 { | |
1505 int32 oldSoundPaused = soundPaused; | |
1506 int32 oldSoundEnableFlag = soundEnableFlag; | |
1507 utilReadData(gzFile, soundSaveStruct); | |
1508 soundPaused = oldSoundPaused; | |
1509 soundEnableFlag = oldSoundEnableFlag; | |
1510 | |
1511 if (version >= SAVE_GAME_VERSION_3) | |
1512 { | |
1513 utilReadData(gzFile, soundSaveStructV2); | |
1514 } | |
1515 else | |
1516 { | |
1517 sound3Bank = (ioMem[NR30] >> 6) & 1; | |
1518 sound3DataSize = (ioMem[NR30] >> 5) & 1; | |
1519 sound3ForcedOutput = (ioMem[NR32] >> 7) & 1; | |
1520 // nothing better to do here... | |
1521 memcpy(&sound3WaveRam[0x00], &ioMem[0x90], 0x10); | |
1522 memcpy(&sound3WaveRam[0x10], &ioMem[0x90], 0x10); | |
1523 } | |
1524 soundBufferIndex = soundIndex * 2; | |
1525 | |
1526 int quality = 1; | |
1527 utilGzRead(gzFile, &quality, sizeof(int32)); | |
1528 soundSetQuality(quality); | |
1529 | |
1530 sound1Wave = soundWavePattern[ioMem[NR11] >> 6]; | |
1531 sound2Wave = soundWavePattern[ioMem[NR21] >> 6]; | |
1532 | |
1533 //if(version >= SAVE_GAME_VERSION_14) { | |
1534 // utilReadData(gzFile, soundSaveStructV3); | |
1535 //} | |
1536 //else { | |
1537 soundTicks = (soundtick_t) soundTicks_int32; | |
1538 SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32; | |
1539 //} | |
1540 soundDSBValue = (u8) (soundDSBValue_int32 & 0xff); | |
1541 } | |
1542 |