1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 #include <memory.h>
20
21 #include "../System.h"
22 #include "../Util.h"
23 #include "gbGlobals.h"
24 #include "gbSound.h"
25
26 extern u8 soundBuffer[6][735];
27 extern u16 soundFinalWave[1470];
28 extern int soundVolume;
29
30 #define SOUND_MAGIC 0x60000000
31 #define SOUND_MAGIC_2 0x30000000
32 #define NOISE_MAGIC 5
33
34 extern int speed;
35
36 extern void soundResume();
37
38 extern u8 soundWavePattern[4][32];
39
40 extern int soundBufferLen;
41 extern int soundBufferTotalLen;
42 extern int soundQuality;
43 extern int soundPaused;
44 extern int soundPlay;
45 extern int soundTicks;
46 extern int SOUND_CLOCK_TICKS;
47 extern u32 soundNextPosition;
48
49 extern int soundLevel1;
50 extern int soundLevel2;
51 extern int soundBalance;
52 extern int soundMasterOn;
53 extern int soundIndex;
54 extern int soundBufferIndex;
55 int soundVIN = 0;
56 extern int soundDebug;
57
58 extern int sound1On;
59 extern int sound1ATL;
60 extern int sound1Skip;
61 extern int sound1Index;
62 extern int sound1Continue;
63 extern int sound1EnvelopeVolume;
64 extern int sound1EnvelopeATL;
65 extern int sound1EnvelopeUpDown;
66 extern int sound1EnvelopeATLReload;
67 extern int sound1SweepATL;
68 extern int sound1SweepATLReload;
69 extern int sound1SweepSteps;
70 extern int sound1SweepUpDown;
71 extern int sound1SweepStep;
72 extern u8 *sound1Wave;
73
74 extern int sound2On;
75 extern int sound2ATL;
76 extern int sound2Skip;
77 extern int sound2Index;
78 extern int sound2Continue;
79 extern int sound2EnvelopeVolume;
80 extern int sound2EnvelopeATL;
81 extern int sound2EnvelopeUpDown;
82 extern int sound2EnvelopeATLReload;
83 extern u8 *sound2Wave;
84
85 extern int sound3On;
86 extern int sound3ATL;
87 extern int sound3Skip;
88 extern int sound3Index;
89 extern int sound3Continue;
90 extern int sound3OutputLevel;
91 extern int sound3Last;
92
93 extern int sound4On;
94 extern int sound4Clock;
95 extern int sound4ATL;
96 extern int sound4Skip;
97 extern int sound4Index;
98 extern int sound4ShiftRight;
99 extern int sound4ShiftSkip;
100 extern int sound4ShiftIndex;
101 extern int sound4NSteps;
102 extern int sound4CountDown;
103 extern int sound4Continue;
104 extern int sound4EnvelopeVolume;
105 extern int sound4EnvelopeATL;
106 extern int sound4EnvelopeUpDown;
107 extern int sound4EnvelopeATLReload;
108
109 extern int soundEnableFlag;
110
111 extern int soundFreqRatio[8];
112 extern int soundShiftClock[16];
113
114 extern s16 soundFilter[4000];
115 extern s16 soundLeft[5];
116 extern s16 soundRight[5];
117 extern int soundEchoIndex;
118 extern bool soundEcho;
119 extern bool soundLowPass;
120 extern bool soundReverse;
121 extern bool soundOffFlag;
122
123 bool gbDigitalSound = false;
124
gbSoundEvent(register u16 address,register int data)125 void gbSoundEvent(register u16 address, register int data)
126 {
127 int freq = 0;
128
129 gbMemory[address] = data;
130
131 #ifndef FINAL_VERSION
132 if(soundDebug) {
133 // don't translate. debug only
134 log("Sound event: %08lx %02x\n", address, data);
135 }
136 #endif
137 switch(address) {
138 case NR10:
139 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
140 sound1SweepSteps = data & 7;
141 sound1SweepUpDown = data & 0x08;
142 sound1SweepStep = 0;
143 break;
144 case NR11:
145 sound1Wave = soundWavePattern[data >> 6];
146 sound1ATL = 172 * (64 - (data & 0x3f));
147 break;
148 case NR12:
149 sound1EnvelopeVolume = data >> 4;
150 sound1EnvelopeUpDown = data & 0x08;
151 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);
152 break;
153 case NR13:
154 freq = (((int)(gbMemory[NR14] & 7)) << 8) | data;
155 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
156 freq = 2048 - freq;
157 if(freq) {
158 sound1Skip = SOUND_MAGIC / freq;
159 } else
160 sound1Skip = 0;
161 break;
162 case NR14:
163 freq = (((int)(data&7) << 8) | gbMemory[NR13]);
164 freq = 2048 - freq;
165 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
166 sound1Continue = data & 0x40;
167 if(freq) {
168 sound1Skip = SOUND_MAGIC / freq;
169 } else
170 sound1Skip = 0;
171 if(data & 0x80) {
172 gbMemory[NR52] |= 1;
173 sound1EnvelopeVolume = gbMemory[NR12] >> 4;
174 sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;
175 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));
176 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);
177 sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);
178 sound1SweepSteps = gbMemory[NR10] & 7;
179 sound1SweepUpDown = gbMemory[NR10] & 0x08;
180 sound1SweepStep = 0;
181
182 sound1Index = 0;
183 sound1On = 1;
184 }
185 break;
186 case NR21:
187 sound2Wave = soundWavePattern[data >> 6];
188 sound2ATL = 172 * (64 - (data & 0x3f));
189 break;
190 case NR22:
191 sound2EnvelopeVolume = data >> 4;
192 sound2EnvelopeUpDown = data & 0x08;
193 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);
194 break;
195 case NR23:
196 freq = (((int)(gbMemory[NR24] & 7)) << 8) | data;
197 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
198 freq = 2048 - freq;
199 if(freq) {
200 sound2Skip = SOUND_MAGIC / freq;
201 } else
202 sound2Skip = 0;
203 break;
204 case NR24:
205 freq = (((int)(data&7) << 8) | gbMemory[NR23]);
206 freq = 2048 - freq;
207 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
208 sound2Continue = data & 0x40;
209 if(freq) {
210 sound2Skip = SOUND_MAGIC / freq;
211 } else
212 sound2Skip = 0;
213 if(data & 0x80) {
214 gbMemory[NR52] |= 2;
215 sound2EnvelopeVolume = gbMemory[NR22] >> 4;
216 sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;
217 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));
218 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);
219
220 sound2Index = 0;
221 sound2On = 1;
222 }
223 break;
224 case NR30:
225 if(!(data & 0x80)) {
226 gbMemory[NR52] &= 0xfb;
227 sound3On = 0;
228 }
229 break;
230 case NR31:
231 sound3ATL = 172 * (256-data);
232 break;
233 case NR32:
234 sound3OutputLevel = (data >> 5) & 3;
235 break;
236 case NR33:
237 freq = 2048 - (((int)(gbMemory[NR34]&7) << 8) | data);
238 if(freq) {
239 sound3Skip = SOUND_MAGIC_2 / freq;
240 } else
241 sound3Skip = 0;
242 break;
243 case NR34:
244 freq = 2048 - (((data &7) << 8) | (int)gbMemory[NR33]);
245 if(freq) {
246 sound3Skip = SOUND_MAGIC_2 / freq;
247 } else {
248 sound3Skip = 0;
249 }
250 sound3Continue = data & 0x40;
251 if((data & 0x80) && (gbMemory[NR30] & 0x80)) {
252 gbMemory[NR52] |= 4;
253 sound3ATL = 172 * (256 - gbMemory[NR31]);
254 sound3Index = 0;
255 sound3On = 1;
256 }
257 break;
258 case NR41:
259 sound4ATL = 172 * (64 - (data & 0x3f));
260 break;
261 case NR42:
262 sound4EnvelopeVolume = data >> 4;
263 sound4EnvelopeUpDown = data & 0x08;
264 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);
265 break;
266 case NR43:
267 freq = soundFreqRatio[data & 7];
268 sound4NSteps = data & 0x08;
269
270 sound4Skip = (freq << 8) / NOISE_MAGIC;
271
272 sound4Clock = data >> 4;
273
274 freq = freq / soundShiftClock[sound4Clock];
275
276 sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
277
278 break;
279 case NR44:
280 sound4Continue = data & 0x40;
281 if(data & 0x80) {
282 gbMemory[NR52] |= 8;
283 sound4EnvelopeVolume = gbMemory[NR42] >> 4;
284 sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;
285 sound4ATL = 172 * (64 - (gbMemory[NR41] & 0x3f));
286 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);
287
288 sound4On = 1;
289
290 sound4Index = 0;
291 sound4ShiftIndex = 0;
292
293 freq = soundFreqRatio[gbMemory[NR43] & 7];
294
295 sound4Skip = (freq << 8) / NOISE_MAGIC;
296
297 sound4NSteps = gbMemory[NR43] & 0x08;
298
299 freq = freq / soundShiftClock[gbMemory[NR43] >> 4];
300
301 sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
302 if(sound4NSteps)
303 sound4ShiftRight = 0x7fff;
304 else
305 sound4ShiftRight = 0x7f;
306 }
307 break;
308 case NR50:
309 soundVIN = data & 0x88;
310 soundLevel1 = data & 7;
311 soundLevel2 = (data >> 4) & 7;
312 break;
313 case NR51:
314 soundBalance = (data & soundEnableFlag);
315 break;
316 case NR52:
317 soundMasterOn = data & 0x80;
318 if(!(data & 0x80)) {
319 sound1On = 0;
320 sound2On = 0;
321 sound3On = 0;
322 sound4On = 0;
323 }
324 break;
325 }
326
327 gbDigitalSound = true;
328
329 if(sound1On && sound1EnvelopeVolume != 0)
330 gbDigitalSound = false;
331 if(sound2On && sound2EnvelopeVolume != 0)
332 gbDigitalSound = false;
333 if(sound3On && sound3OutputLevel != 0)
334 gbDigitalSound = false;
335 if(sound4On && sound4EnvelopeVolume != 0)
336 gbDigitalSound = false;
337 }
338
gbSoundChannel1()339 void gbSoundChannel1()
340 {
341 int vol = sound1EnvelopeVolume;
342
343 int freq = 0;
344
345 int value = 0;
346
347 if(sound1On && (sound1ATL || !sound1Continue)) {
348 sound1Index += soundQuality*sound1Skip;
349 sound1Index &= 0x1fffffff;
350
351 value = ((s8)sound1Wave[sound1Index>>24]) * vol;
352 }
353
354 soundBuffer[0][soundIndex] = value;
355
356
357 if(sound1On) {
358 if(sound1ATL) {
359 sound1ATL-=soundQuality;
360
361 if(sound1ATL <=0 && sound1Continue) {
362 gbMemory[NR52] &= 0xfe;
363 sound1On = 0;
364 }
365 }
366
367 if(sound1EnvelopeATL) {
368 sound1EnvelopeATL-=soundQuality;
369
370 if(sound1EnvelopeATL<=0) {
371 if(sound1EnvelopeUpDown) {
372 if(sound1EnvelopeVolume < 15)
373 sound1EnvelopeVolume++;
374 } else {
375 if(sound1EnvelopeVolume)
376 sound1EnvelopeVolume--;
377 }
378
379 sound1EnvelopeATL += sound1EnvelopeATLReload;
380 }
381 }
382
383 if(sound1SweepATL) {
384 sound1SweepATL-=soundQuality;
385
386 if(sound1SweepATL<=0) {
387 freq = (((int)(gbMemory[NR14]&7) << 8) | gbMemory[NR13]);
388
389 int updown = 1;
390
391 if(sound1SweepUpDown)
392 updown = -1;
393
394 int newfreq = 0;
395 if(sound1SweepSteps) {
396 newfreq = freq + updown * freq / (1 << sound1SweepSteps);
397 if(newfreq == freq)
398 newfreq = 0;
399 } else
400 newfreq = freq;
401
402 if(newfreq < 0) {
403 sound1SweepATL += sound1SweepATLReload;
404 } else if(newfreq > 2047) {
405 sound1SweepATL = 0;
406 sound1On = 0;
407 gbMemory[NR52] &= 0xfe;
408 } else {
409 sound1SweepATL += sound1SweepATLReload;
410 sound1Skip = SOUND_MAGIC/(2048 - newfreq);
411
412 gbMemory[NR13] = newfreq & 0xff;
413 gbMemory[NR14] = (gbMemory[NR14] & 0xf8) |((newfreq >> 8) & 7);
414 }
415 }
416 }
417 }
418 }
419
gbSoundChannel2()420 void gbSoundChannel2()
421 {
422 // int freq = 0;
423 int vol = sound2EnvelopeVolume;
424
425 int value = 0;
426
427 if(sound2On && (sound2ATL || !sound2Continue)) {
428 sound2Index += soundQuality*sound2Skip;
429 sound2Index &= 0x1fffffff;
430
431 value = ((s8)sound2Wave[sound2Index>>24]) * vol;
432 }
433
434 soundBuffer[1][soundIndex] = value;
435
436 if(sound2On) {
437 if(sound2ATL) {
438 sound2ATL-=soundQuality;
439
440 if(sound2ATL <= 0 && sound2Continue) {
441 gbMemory[NR52] &= 0xfd;
442 sound2On = 0;
443 }
444 }
445
446 if(sound2EnvelopeATL) {
447 sound2EnvelopeATL-=soundQuality;
448
449 if(sound2EnvelopeATL <= 0) {
450 if(sound2EnvelopeUpDown) {
451 if(sound2EnvelopeVolume < 15)
452 sound2EnvelopeVolume++;
453 } else {
454 if(sound2EnvelopeVolume)
455 sound2EnvelopeVolume--;
456 }
457 sound2EnvelopeATL += sound2EnvelopeATLReload;
458 }
459 }
460 }
461 }
462
gbSoundChannel3()463 void gbSoundChannel3()
464 {
465 int value = sound3Last;
466
467 if(sound3On && (sound3ATL || !sound3Continue)) {
468 sound3Index += soundQuality*sound3Skip;
469 sound3Index &= 0x1fffffff;
470
471 value = gbMemory[0xff30 + (sound3Index>>25)];
472
473 if( (sound3Index & 0x01000000)) {
474 value &= 0x0f;
475 } else {
476 value >>= 4;
477 }
478
479 value -= 8;
480
481 switch(sound3OutputLevel) {
482 case 0:
483 value = 0;
484 break;
485 case 1:
486 break;
487 case 2:
488 value = (value >> 1);
489 break;
490 case 3:
491 value = (value >> 2);
492 break;
493 }
494 sound3Last = value;
495 }
496
497 soundBuffer[2][soundIndex] = value;
498
499 if(sound3On) {
500 if(sound3ATL) {
501 sound3ATL-=soundQuality;
502
503 if(sound3ATL <= 0 && sound3Continue) {
504 gbMemory[NR52] &= 0xfb;
505 sound3On = 0;
506 }
507 }
508 }
509 }
510
gbSoundChannel4()511 void gbSoundChannel4()
512 {
513 int vol = sound4EnvelopeVolume;
514
515 int value = 0;
516
517 if(sound4Clock <= 0x0c) {
518 if(sound4On && (sound4ATL || !sound4Continue)) {
519 sound4Index += soundQuality*sound4Skip;
520 sound4ShiftIndex += soundQuality*sound4ShiftSkip;
521
522 if(sound4NSteps) {
523 while(sound4ShiftIndex > 0x1fffff) {
524 sound4ShiftRight = (((sound4ShiftRight << 6) ^
525 (sound4ShiftRight << 5)) & 0x40) |
526 (sound4ShiftRight >> 1);
527 sound4ShiftIndex -= 0x200000;
528 }
529 } else {
530 while(sound4ShiftIndex > 0x1fffff) {
531 sound4ShiftRight = (((sound4ShiftRight << 14) ^
532 (sound4ShiftRight << 13)) & 0x4000) |
533 (sound4ShiftRight >> 1);
534
535 sound4ShiftIndex -= 0x200000;
536 }
537 }
538
539 sound4Index &= 0x1fffff;
540 sound4ShiftIndex &= 0x1fffff;
541
542 value = ((sound4ShiftRight & 1)*2-1) * vol;
543 } else {
544 value = 0;
545 }
546 }
547
548 soundBuffer[3][soundIndex] = value;
549
550 if(sound4On) {
551 if(sound4ATL) {
552 sound4ATL-=soundQuality;
553
554 if(sound4ATL <= 0 && sound4Continue) {
555 gbMemory[NR52] &= 0xfd;
556 sound4On = 0;
557 }
558 }
559
560 if(sound4EnvelopeATL) {
561 sound4EnvelopeATL-=soundQuality;
562
563 if(sound4EnvelopeATL <= 0) {
564 if(sound4EnvelopeUpDown) {
565 if(sound4EnvelopeVolume < 15)
566 sound4EnvelopeVolume++;
567 } else {
568 if(sound4EnvelopeVolume)
569 sound4EnvelopeVolume--;
570 }
571 sound4EnvelopeATL += sound4EnvelopeATLReload;
572 }
573 }
574 }
575 }
576
gbSoundMix()577 void gbSoundMix()
578 {
579 int res = 0;
580
581 if(soundBalance & 16) {
582 res += ((s8)soundBuffer[0][soundIndex]);
583 }
584 if(soundBalance & 32) {
585 res += ((s8)soundBuffer[1][soundIndex]);
586 }
587 if(soundBalance & 64) {
588 res += ((s8)soundBuffer[2][soundIndex]);
589 }
590 if(soundBalance & 128) {
591 res += ((s8)soundBuffer[3][soundIndex]);
592 }
593
594 if(gbDigitalSound)
595 res = soundLevel1*256;
596 else
597 res *= soundLevel1*60;
598
599 if(soundEcho) {
600 res *= 2;
601 res += soundFilter[soundEchoIndex];
602 res /= 2;
603 soundFilter[soundEchoIndex++] = res;
604 }
605
606 if(soundLowPass) {
607 soundLeft[4] = soundLeft[3];
608 soundLeft[3] = soundLeft[2];
609 soundLeft[2] = soundLeft[1];
610 soundLeft[1] = soundLeft[0];
611 soundLeft[0] = res;
612 res = (soundLeft[4] + 2*soundLeft[3] + 8*soundLeft[2] + 2*soundLeft[1] +
613 soundLeft[0])/14;
614 }
615
616 switch(soundVolume) {
617 case 0:
618 case 1:
619 case 2:
620 case 3:
621 res *= (soundVolume+1);
622 break;
623 case 4:
624 res >>= 2;
625 break;
626 case 5:
627 res >>= 1;
628 break;
629 }
630
631 if(res > 32767)
632 res = 32767;
633 if(res < -32768)
634 res = -32768;
635
636 if(soundReverse)
637 soundFinalWave[++soundBufferIndex] = res;
638 else
639 soundFinalWave[soundBufferIndex++] = res;
640
641 res = 0;
642
643 if(soundBalance & 1) {
644 res += ((s8)soundBuffer[0][soundIndex]);
645 }
646 if(soundBalance & 2) {
647 res += ((s8)soundBuffer[1][soundIndex]);
648 }
649 if(soundBalance & 4) {
650 res += ((s8)soundBuffer[2][soundIndex]);
651 }
652 if(soundBalance & 8) {
653 res += ((s8)soundBuffer[3][soundIndex]);
654 }
655
656 if(gbDigitalSound)
657 res = soundLevel2*256;
658 else
659 res *= soundLevel2*60;
660
661 if(soundEcho) {
662 res *= 2;
663 res += soundFilter[soundEchoIndex];
664 res /= 2;
665 soundFilter[soundEchoIndex++] = res;
666
667 if(soundEchoIndex >= 4000)
668 soundEchoIndex = 0;
669 }
670
671 if(soundLowPass) {
672 soundRight[4] = soundRight[3];
673 soundRight[3] = soundRight[2];
674 soundRight[2] = soundRight[1];
675 soundRight[1] = soundRight[0];
676 soundRight[0] = res;
677 res = (soundRight[4] + 2*soundRight[3] + 8*soundRight[2] + 2*soundRight[1] +
678 soundRight[0])/14;
679 }
680
681 switch(soundVolume) {
682 case 0:
683 case 1:
684 case 2:
685 case 3:
686 res *= (soundVolume+1);
687 break;
688 case 4:
689 res >>= 2;
690 break;
691 case 5:
692 res >>= 1;
693 break;
694 }
695
696 if(res > 32767)
697 res = 32767;
698 if(res < -32768)
699 res = -32768;
700
701 if(soundReverse)
702 soundFinalWave[-1+soundBufferIndex++] = res;
703 else
704 soundFinalWave[soundBufferIndex++] = res;
705 }
706
gbSoundTick()707 void gbSoundTick()
708 {
709 if(systemSoundOn) {
710 if(soundMasterOn) {
711 gbSoundChannel1();
712 gbSoundChannel2();
713 gbSoundChannel3();
714 gbSoundChannel4();
715
716 gbSoundMix();
717 } else {
718 soundFinalWave[soundBufferIndex++] = 0;
719 soundFinalWave[soundBufferIndex++] = 0;
720 }
721
722 soundIndex++;
723
724 if(2*soundBufferIndex >= soundBufferLen) {
725 if(systemSoundOn) {
726 if(soundPaused) {
727 soundResume();
728 }
729
730 systemWriteDataToSoundBuffer();
731 }
732 soundIndex = 0;
733 soundBufferIndex = 0;
734 }
735 }
736 }
737
gbSoundReset()738 void gbSoundReset()
739 {
740 soundPaused = 1;
741 soundPlay = 0;
742 SOUND_CLOCK_TICKS = soundQuality * 24;
743 soundTicks = SOUND_CLOCK_TICKS;
744 soundNextPosition = 0;
745 soundMasterOn = 1;
746 soundIndex = 0;
747 soundBufferIndex = 0;
748 soundLevel1 = 7;
749 soundLevel2 = 7;
750 soundVIN = 0;
751
752 sound1On = 0;
753 sound1ATL = 0;
754 sound1Skip = 0;
755 sound1Index = 0;
756 sound1Continue = 0;
757 sound1EnvelopeVolume = 0;
758 sound1EnvelopeATL = 0;
759 sound1EnvelopeUpDown = 0;
760 sound1EnvelopeATLReload = 0;
761 sound1SweepATL = 0;
762 sound1SweepATLReload = 0;
763 sound1SweepSteps = 0;
764 sound1SweepUpDown = 0;
765 sound1SweepStep = 0;
766 sound1Wave = soundWavePattern[2];
767
768 sound2On = 0;
769 sound2ATL = 0;
770 sound2Skip = 0;
771 sound2Index = 0;
772 sound2Continue = 0;
773 sound2EnvelopeVolume = 0;
774 sound2EnvelopeATL = 0;
775 sound2EnvelopeUpDown = 0;
776 sound2EnvelopeATLReload = 0;
777 sound2Wave = soundWavePattern[2];
778
779 sound3On = 0;
780 sound3ATL = 0;
781 sound3Skip = 0;
782 sound3Index = 0;
783 sound3Continue = 0;
784 sound3OutputLevel = 0;
785
786 sound4On = 0;
787 sound4Clock = 0;
788 sound4ATL = 0;
789 sound4Skip = 0;
790 sound4Index = 0;
791 sound4ShiftRight = 0x7f;
792 sound4NSteps = 0;
793 sound4CountDown = 0;
794 sound4Continue = 0;
795 sound4EnvelopeVolume = 0;
796 sound4EnvelopeATL = 0;
797 sound4EnvelopeUpDown = 0;
798 sound4EnvelopeATLReload = 0;
799
800 // don't translate
801 if(soundDebug) {
802 log("*** Sound Init ***\n");
803 }
804
805 gbSoundEvent(0xff10, 0x80);
806 gbSoundEvent(0xff11, 0xbf);
807 gbSoundEvent(0xff12, 0xf3);
808 gbSoundEvent(0xff14, 0xbf);
809 gbSoundEvent(0xff16, 0x3f);
810 gbSoundEvent(0xff17, 0x00);
811 gbSoundEvent(0xff19, 0xbf);
812
813 gbSoundEvent(0xff1a, 0x7f);
814 gbSoundEvent(0xff1b, 0xff);
815 gbSoundEvent(0xff1c, 0xbf);
816 gbSoundEvent(0xff1e, 0xbf);
817
818 gbSoundEvent(0xff20, 0xff);
819 gbSoundEvent(0xff21, 0x00);
820 gbSoundEvent(0xff22, 0x00);
821 gbSoundEvent(0xff23, 0xbf);
822 gbSoundEvent(0xff24, 0x77);
823 gbSoundEvent(0xff25, 0xf3);
824
825 gbSoundEvent(0xff26, 0xf0);
826
827 // don't translate
828 if(soundDebug) {
829 log("*** Sound Init Complete ***\n");
830 }
831
832 sound1On = 0;
833 sound2On = 0;
834 sound3On = 0;
835 sound4On = 0;
836
837 int addr = 0xff30;
838
839 while(addr < 0xff40) {
840 gbMemory[addr++] = 0x00;
841 gbMemory[addr++] = 0xff;
842 }
843
844 memset(soundFinalWave, 0x00, soundBufferLen);
845
846
847 memset(soundFilter, 0, sizeof(soundFilter));
848 soundEchoIndex = 0;
849 }
850
851 extern bool soundInit();
852 extern void soundShutdown();
853
gbSoundSetQuality(int quality)854 void gbSoundSetQuality(int quality)
855 {
856 if(soundQuality != quality && systemCanChangeSoundQuality()) {
857 if(!soundOffFlag)
858 soundShutdown();
859 soundQuality = quality;
860 soundNextPosition = 0;
861 if(!soundOffFlag)
862 soundInit();
863 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * 24 * soundQuality;
864 soundIndex = 0;
865 soundBufferIndex = 0;
866 } else {
867 soundNextPosition = 0;
868 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * 24 * soundQuality;
869 soundIndex = 0;
870 soundBufferIndex = 0;
871 }
872 }
873
874 variable_desc gbSoundSaveStruct[] = {
875 { &soundPaused, sizeof(int) },
876 { &soundPlay, sizeof(int) },
877 { &soundTicks, sizeof(int) },
878 { &SOUND_CLOCK_TICKS, sizeof(int) },
879 { &soundLevel1, sizeof(int) },
880 { &soundLevel2, sizeof(int) },
881 { &soundBalance, sizeof(int) },
882 { &soundMasterOn, sizeof(int) },
883 { &soundIndex, sizeof(int) },
884 { &soundVIN, sizeof(int) },
885 { &sound1On, sizeof(int) },
886 { &sound1ATL, sizeof(int) },
887 { &sound1Skip, sizeof(int) },
888 { &sound1Index, sizeof(int) },
889 { &sound1Continue, sizeof(int) },
890 { &sound1EnvelopeVolume, sizeof(int) },
891 { &sound1EnvelopeATL, sizeof(int) },
892 { &sound1EnvelopeATLReload, sizeof(int) },
893 { &sound1EnvelopeUpDown, sizeof(int) },
894 { &sound1SweepATL, sizeof(int) },
895 { &sound1SweepATLReload, sizeof(int) },
896 { &sound1SweepSteps, sizeof(int) },
897 { &sound1SweepUpDown, sizeof(int) },
898 { &sound1SweepStep, sizeof(int) },
899 { &sound2On, sizeof(int) },
900 { &sound2ATL, sizeof(int) },
901 { &sound2Skip, sizeof(int) },
902 { &sound2Index, sizeof(int) },
903 { &sound2Continue, sizeof(int) },
904 { &sound2EnvelopeVolume, sizeof(int) },
905 { &sound2EnvelopeATL, sizeof(int) },
906 { &sound2EnvelopeATLReload, sizeof(int) },
907 { &sound2EnvelopeUpDown, sizeof(int) },
908 { &sound3On, sizeof(int) },
909 { &sound3ATL, sizeof(int) },
910 { &sound3Skip, sizeof(int) },
911 { &sound3Index, sizeof(int) },
912 { &sound3Continue, sizeof(int) },
913 { &sound3OutputLevel, sizeof(int) },
914 { &sound4On, sizeof(int) },
915 { &sound4ATL, sizeof(int) },
916 { &sound4Skip, sizeof(int) },
917 { &sound4Index, sizeof(int) },
918 { &sound4Clock, sizeof(int) },
919 { &sound4ShiftRight, sizeof(int) },
920 { &sound4ShiftSkip, sizeof(int) },
921 { &sound4ShiftIndex, sizeof(int) },
922 { &sound4NSteps, sizeof(int) },
923 { &sound4CountDown, sizeof(int) },
924 { &sound4Continue, sizeof(int) },
925 { &sound4EnvelopeVolume, sizeof(int) },
926 { &sound4EnvelopeATL, sizeof(int) },
927 { &sound4EnvelopeATLReload, sizeof(int) },
928 { &sound4EnvelopeUpDown, sizeof(int) },
929 { &soundEnableFlag, sizeof(int) },
930 { NULL, 0 }
931 };
932
gbSoundSaveGame(gzFile gzFile)933 void gbSoundSaveGame(gzFile gzFile)
934 {
935 utilWriteData(gzFile, gbSoundSaveStruct);
936
937 utilGzWrite(gzFile, soundBuffer, 4*735);
938 utilGzWrite(gzFile, soundFinalWave, 2*735);
939 utilGzWrite(gzFile, &soundQuality, sizeof(int));
940 }
941
gbSoundReadGame(int version,gzFile gzFile)942 void gbSoundReadGame(int version,gzFile gzFile)
943 {
944 utilReadData(gzFile, gbSoundSaveStruct);
945
946 soundBufferIndex = soundIndex * 2;
947
948 utilGzRead(gzFile, soundBuffer, 4*735);
949 utilGzRead(gzFile, soundFinalWave, 2*735);
950
951 if(version >=7) {
952 int quality = 1;
953 utilGzRead(gzFile, &quality, sizeof(int));
954 gbSoundSetQuality(quality);
955 } else {
956 soundQuality = -1;
957 gbSoundSetQuality(1);
958 }
959
960 sound1Wave = soundWavePattern[gbMemory[NR11] >> 6];
961 sound2Wave = soundWavePattern[gbMemory[NR21] >> 6];
962 }
963