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