1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
4 // Copyright (C) 2004-2006 VBA development team
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or(at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #define USE_TICKS_AS 380
29 #define SOUND_MAGIC 0x60000000
30 #define SOUND_MAGIC_2 0x30000000
33 extern bool stopState
;
35 u8 soundWavePattern
[4][32] = {
70 int soundFreqRatio
[8] = {
81 int soundShiftClock
[16]= {
102 u8 soundBuffer
[6][735];
103 u16 soundFinalWave
[1470];
105 int soundBufferLen
= 1470;
106 int soundBufferTotalLen
= 14700;
107 int soundQuality
= 2;
110 int soundTicks
= soundQuality
* USE_TICKS_AS
;
111 int SOUND_CLOCK_TICKS
= soundQuality
* USE_TICKS_AS
;
112 u32 soundNextPosition
= 0;
116 int soundBalance
= 0;
117 int soundMasterOn
= 0;
119 int soundBufferIndex
= 0;
121 bool soundOffFlag
= false;
127 int sound1Continue
= 0;
128 int sound1EnvelopeVolume
= 0;
129 int sound1EnvelopeATL
= 0;
130 int sound1EnvelopeUpDown
= 0;
131 int sound1EnvelopeATLReload
= 0;
132 int sound1SweepATL
= 0;
133 int sound1SweepATLReload
= 0;
134 int sound1SweepSteps
= 0;
135 int sound1SweepUpDown
= 0;
136 int sound1SweepStep
= 0;
137 u8
*sound1Wave
= soundWavePattern
[2];
143 int sound2Continue
= 0;
144 int sound2EnvelopeVolume
= 0;
145 int sound2EnvelopeATL
= 0;
146 int sound2EnvelopeUpDown
= 0;
147 int sound2EnvelopeATLReload
= 0;
148 u8
*sound2Wave
= soundWavePattern
[2];
154 int sound3Continue
= 0;
155 int sound3OutputLevel
= 0;
157 u8 sound3WaveRam
[0x20];
159 int sound3DataSize
= 0;
160 int sound3ForcedOutput
= 0;
167 int sound4ShiftRight
= 0x7f;
168 int sound4ShiftSkip
= 0;
169 int sound4ShiftIndex
= 0;
170 int sound4NSteps
= 0;
171 int sound4CountDown
= 0;
172 int sound4Continue
= 0;
173 int sound4EnvelopeVolume
= 0;
174 int sound4EnvelopeATL
= 0;
175 int sound4EnvelopeUpDown
= 0;
176 int sound4EnvelopeATLReload
= 0;
178 int soundControl
= 0;
180 int soundDSFifoAIndex
= 0;
181 int soundDSFifoACount
= 0;
182 int soundDSFifoAWriteIndex
= 0;
183 bool soundDSAEnabled
= false;
184 int soundDSATimer
= 0;
186 u8 soundDSAValue
= 0;
188 int soundDSFifoBIndex
= 0;
189 int soundDSFifoBCount
= 0;
190 int soundDSFifoBWriteIndex
= 0;
191 bool soundDSBEnabled
= false;
192 int soundDSBTimer
= 0;
194 u8 soundDSBValue
= 0;
196 int soundEnableFlag
= 0x3ff;
198 s16 soundFilter
[4000];
199 s16 soundRight
[5] = { 0, 0, 0, 0, 0 };
200 s16 soundLeft
[5] = { 0, 0, 0, 0, 0 };
201 int soundEchoIndex
= 0;
202 bool soundEcho
= false;
203 bool soundLowPass
= false;
204 bool soundReverse
= false;
206 variable_desc soundSaveStruct
[] = {
207 { &soundPaused
, sizeof(int) },
208 { &soundPlay
, sizeof(int) },
209 { &soundTicks
, sizeof(int) },
210 { &SOUND_CLOCK_TICKS
, sizeof(int) },
211 { &soundLevel1
, sizeof(int) },
212 { &soundLevel2
, sizeof(int) },
213 { &soundBalance
, sizeof(int) },
214 { &soundMasterOn
, sizeof(int) },
215 { &soundIndex
, sizeof(int) },
216 { &sound1On
, sizeof(int) },
217 { &sound1ATL
, sizeof(int) },
218 { &sound1Skip
, sizeof(int) },
219 { &sound1Index
, sizeof(int) },
220 { &sound1Continue
, sizeof(int) },
221 { &sound1EnvelopeVolume
, sizeof(int) },
222 { &sound1EnvelopeATL
, sizeof(int) },
223 { &sound1EnvelopeATLReload
, sizeof(int) },
224 { &sound1EnvelopeUpDown
, sizeof(int) },
225 { &sound1SweepATL
, sizeof(int) },
226 { &sound1SweepATLReload
, sizeof(int) },
227 { &sound1SweepSteps
, sizeof(int) },
228 { &sound1SweepUpDown
, sizeof(int) },
229 { &sound1SweepStep
, sizeof(int) },
230 { &sound2On
, sizeof(int) },
231 { &sound2ATL
, sizeof(int) },
232 { &sound2Skip
, sizeof(int) },
233 { &sound2Index
, sizeof(int) },
234 { &sound2Continue
, sizeof(int) },
235 { &sound2EnvelopeVolume
, sizeof(int) },
236 { &sound2EnvelopeATL
, sizeof(int) },
237 { &sound2EnvelopeATLReload
, sizeof(int) },
238 { &sound2EnvelopeUpDown
, sizeof(int) },
239 { &sound3On
, sizeof(int) },
240 { &sound3ATL
, sizeof(int) },
241 { &sound3Skip
, sizeof(int) },
242 { &sound3Index
, sizeof(int) },
243 { &sound3Continue
, sizeof(int) },
244 { &sound3OutputLevel
, sizeof(int) },
245 { &sound4On
, sizeof(int) },
246 { &sound4ATL
, sizeof(int) },
247 { &sound4Skip
, sizeof(int) },
248 { &sound4Index
, sizeof(int) },
249 { &sound4Clock
, sizeof(int) },
250 { &sound4ShiftRight
, sizeof(int) },
251 { &sound4ShiftSkip
, sizeof(int) },
252 { &sound4ShiftIndex
, sizeof(int) },
253 { &sound4NSteps
, sizeof(int) },
254 { &sound4CountDown
, sizeof(int) },
255 { &sound4Continue
, sizeof(int) },
256 { &sound4EnvelopeVolume
, sizeof(int) },
257 { &sound4EnvelopeATL
, sizeof(int) },
258 { &sound4EnvelopeATLReload
, sizeof(int) },
259 { &sound4EnvelopeUpDown
, sizeof(int) },
260 { &soundEnableFlag
, sizeof(int) },
261 { &soundControl
, sizeof(int) },
262 { &soundDSFifoAIndex
, sizeof(int) },
263 { &soundDSFifoACount
, sizeof(int) },
264 { &soundDSFifoAWriteIndex
, sizeof(int) },
265 { &soundDSAEnabled
, sizeof(bool) },
266 { &soundDSATimer
, sizeof(int) },
267 { &soundDSFifoA
[0], 32 },
268 { &soundDSAValue
, sizeof(u8
) },
269 { &soundDSFifoBIndex
, sizeof(int) },
270 { &soundDSFifoBCount
, sizeof(int) },
271 { &soundDSFifoBWriteIndex
, sizeof(int) },
272 { &soundDSBEnabled
, sizeof(int) },
273 { &soundDSBTimer
, sizeof(int) },
274 { &soundDSFifoB
[0], 32 },
275 { &soundDSBValue
, sizeof(int) },
276 { &soundBuffer
[0][0], 6*735 },
277 { &soundFinalWave
[0], 2*735 },
281 variable_desc soundSaveStructV2
[] = {
282 { &sound3WaveRam
[0], 0x20 },
283 { &sound3Bank
, sizeof(int) },
284 { &sound3DataSize
, sizeof(int) },
285 { &sound3ForcedOutput
, sizeof(int) },
289 void soundEvent(u32 address
, u8 data
)
296 sound1SweepATL
= sound1SweepATLReload
= 344 * ((data
>> 4) & 7);
297 sound1SweepSteps
= data
& 7;
298 sound1SweepUpDown
= data
& 0x08;
300 ioMem
[address
] = data
;
303 sound1Wave
= soundWavePattern
[data
>> 6];
304 sound1ATL
= 172 * (64 - (data
& 0x3f));
305 ioMem
[address
] = data
;
308 sound1EnvelopeUpDown
= data
& 0x08;
309 sound1EnvelopeATLReload
= 689 * (data
& 7);
310 if((data
& 0xF8) == 0)
311 sound1EnvelopeVolume
= 0;
312 ioMem
[address
] = data
;
315 freq
= (((int)(ioMem
[NR14
] & 7)) << 8) | data
;
316 sound1ATL
= 172 * (64 - (ioMem
[NR11
] & 0x3f));
319 sound1Skip
= SOUND_MAGIC
/ freq
;
322 ioMem
[address
] = data
;
326 freq
= (((int)(data
&7) << 8) | ioMem
[NR13
]);
328 sound1ATL
= 172 * (64 - (ioMem
[NR11
] & 0x3f));
329 sound1Continue
= data
& 0x40;
331 sound1Skip
= SOUND_MAGIC
/ freq
;
336 sound1EnvelopeVolume
= ioMem
[NR12
] >> 4;
337 sound1EnvelopeUpDown
= ioMem
[NR12
] & 0x08;
338 sound1ATL
= 172 * (64 - (ioMem
[NR11
] & 0x3f));
339 sound1EnvelopeATLReload
= sound1EnvelopeATL
= 689 * (ioMem
[NR12
] & 7);
340 sound1SweepATL
= sound1SweepATLReload
= 344 * ((ioMem
[NR10
] >> 4) & 7);
341 sound1SweepSteps
= ioMem
[NR10
] & 7;
342 sound1SweepUpDown
= ioMem
[NR10
] & 0x08;
348 ioMem
[address
] = data
;
351 sound2Wave
= soundWavePattern
[data
>> 6];
352 sound2ATL
= 172 * (64 - (data
& 0x3f));
353 ioMem
[address
] = data
;
356 sound2EnvelopeUpDown
= data
& 0x08;
357 sound2EnvelopeATLReload
= 689 * (data
& 7);
358 if((data
& 0xF8) == 0)
359 sound2EnvelopeVolume
= 0;
360 ioMem
[address
] = data
;
363 freq
= (((int)(ioMem
[NR24
] & 7)) << 8) | data
;
364 sound2ATL
= 172 * (64 - (ioMem
[NR21
] & 0x3f));
367 sound2Skip
= SOUND_MAGIC
/ freq
;
370 ioMem
[address
] = data
;
374 freq
= (((int)(data
&7) << 8) | ioMem
[NR23
]);
376 sound2ATL
= 172 * (64 - (ioMem
[NR21
] & 0x3f));
377 sound2Continue
= data
& 0x40;
379 sound2Skip
= SOUND_MAGIC
/ freq
;
384 sound2EnvelopeVolume
= ioMem
[NR22
] >> 4;
385 sound2EnvelopeUpDown
= ioMem
[NR22
] & 0x08;
386 sound2ATL
= 172 * (64 - (ioMem
[NR21
] & 0x3f));
387 sound2EnvelopeATLReload
= sound2EnvelopeATL
= 689 * (ioMem
[NR22
] & 7);
392 ioMem
[address
] = data
;
400 if(((data
>> 6) & 1) != sound3Bank
)
401 memcpy(&ioMem
[0x90], &sound3WaveRam
[(((data
>> 6) & 1) * 0x10)^0x10],
403 sound3Bank
= (data
>> 6) & 1;
404 sound3DataSize
= (data
>> 5) & 1;
405 ioMem
[address
] = data
;
408 sound3ATL
= 172 * (256-data
);
409 ioMem
[address
] = data
;
413 sound3OutputLevel
= (data
>> 5) & 3;
414 sound3ForcedOutput
= (data
>> 7) & 1;
415 ioMem
[address
] = data
;
418 freq
= 2048 - (((int)(ioMem
[NR34
]&7) << 8) | data
);
420 sound3Skip
= SOUND_MAGIC_2
/ freq
;
423 ioMem
[address
] = data
;
427 freq
= 2048 - (((data
&7) << 8) | (int)ioMem
[NR33
]);
429 sound3Skip
= SOUND_MAGIC_2
/ freq
;
433 sound3Continue
= data
& 0x40;
434 if((data
& 0x80) && (ioMem
[NR30
] & 0x80)) {
436 sound3ATL
= 172 * (256 - ioMem
[NR31
]);
440 ioMem
[address
] = data
;
444 sound4ATL
= 172 * (64 - (data
& 0x3f));
445 ioMem
[address
] = data
;
448 sound4EnvelopeUpDown
= data
& 0x08;
449 sound4EnvelopeATLReload
= 689 * (data
& 7);
450 if((data
& 0xF8) == 0)
451 sound4EnvelopeVolume
= 0;
452 ioMem
[address
] = data
;
455 freq
= soundFreqRatio
[data
& 7];
456 sound4NSteps
= data
& 0x08;
458 sound4Skip
= (freq
<< 8) / NOISE_MAGIC
;
460 sound4Clock
= data
>> 4;
462 freq
= freq
/ soundShiftClock
[sound4Clock
];
464 sound4ShiftSkip
= (freq
<< 8) / NOISE_MAGIC
;
465 ioMem
[address
] = data
;
469 sound4Continue
= data
& 0x40;
472 sound4EnvelopeVolume
= ioMem
[NR42
] >> 4;
473 sound4EnvelopeUpDown
= ioMem
[NR42
] & 0x08;
474 sound4ATL
= 172 * (64 - (ioMem
[NR41
] & 0x3f));
475 sound4EnvelopeATLReload
= sound4EnvelopeATL
= 689 * (ioMem
[NR42
] & 7);
480 sound4ShiftIndex
= 0;
482 freq
= soundFreqRatio
[ioMem
[NR43
] & 7];
484 sound4Skip
= (freq
<< 8) / NOISE_MAGIC
;
486 sound4NSteps
= ioMem
[NR43
] & 0x08;
488 freq
= freq
/ soundShiftClock
[ioMem
[NR43
] >> 4];
490 sound4ShiftSkip
= (freq
<< 8) / NOISE_MAGIC
;
492 sound4ShiftRight
= 0x7fff;
494 sound4ShiftRight
= 0x7f;
496 ioMem
[address
] = data
;
500 soundLevel1
= data
& 7;
501 soundLevel2
= (data
>> 4) & 7;
502 ioMem
[address
] = data
;
505 soundBalance
= (data
& soundEnableFlag
);
506 ioMem
[address
] = data
;
510 data
|= ioMem
[NR52
] & 15;
511 soundMasterOn
= data
& 0x80;
518 ioMem
[address
] = data
;
536 sound3WaveRam
[(sound3Bank
*0x10)^0x10+(address
&15)] = data
;
541 void soundEvent(u32 address
, u16 data
)
546 soundControl
= data
& 0x770F;
548 soundDSFifoAWriteIndex
= 0;
549 soundDSFifoAIndex
= 0;
550 soundDSFifoACount
= 0;
552 memset(soundDSFifoA
, 0, 32);
554 soundDSAEnabled
= (data
& 0x0300) ? true : false;
555 soundDSATimer
= (data
& 0x0400) ? 1 : 0;
557 soundDSFifoBWriteIndex
= 0;
558 soundDSFifoBIndex
= 0;
559 soundDSFifoBCount
= 0;
561 memset(soundDSFifoB
, 0, 32);
563 soundDSBEnabled
= (data
& 0x3000) ? true : false;
564 soundDSBTimer
= (data
& 0x4000) ? 1 : 0;
565 *((u16
*)&ioMem
[address
]) = soundControl
;
569 soundDSFifoA
[soundDSFifoAWriteIndex
++] = data
& 0xFF;
570 soundDSFifoA
[soundDSFifoAWriteIndex
++] = data
>> 8;
571 soundDSFifoACount
+= 2;
572 soundDSFifoAWriteIndex
&= 31;
573 *((u16
*)&ioMem
[address
]) = data
;
577 soundDSFifoB
[soundDSFifoBWriteIndex
++] = data
& 0xFF;
578 soundDSFifoB
[soundDSFifoBWriteIndex
++] = data
>> 8;
579 soundDSFifoBCount
+= 2;
580 soundDSFifoBWriteIndex
&= 31;
581 *((u16
*)&ioMem
[address
]) = data
;
585 *((u16
*)&ioMem
[address
]) = data
;
595 *((u16
*)&sound3WaveRam
[(sound3Bank
*0x10)^0x10+(address
&14)]) = data
;
596 *((u16
*)&ioMem
[address
]) = data
;
603 int vol
= sound1EnvelopeVolume
;
608 if(sound1On
&& (sound1ATL
|| !sound1Continue
)) {
609 sound1Index
+= soundQuality
*sound1Skip
;
610 sound1Index
&= 0x1fffffff;
612 value
= ((s8
)sound1Wave
[sound1Index
>>24]) * vol
;
615 soundBuffer
[0][soundIndex
] = value
;
620 sound1ATL
-=soundQuality
;
622 if(sound1ATL
<=0 && sound1Continue
) {
628 if(sound1EnvelopeATL
) {
629 sound1EnvelopeATL
-=soundQuality
;
631 if(sound1EnvelopeATL
<=0) {
632 if(sound1EnvelopeUpDown
) {
633 if(sound1EnvelopeVolume
< 15)
634 sound1EnvelopeVolume
++;
636 if(sound1EnvelopeVolume
)
637 sound1EnvelopeVolume
--;
640 sound1EnvelopeATL
+= sound1EnvelopeATLReload
;
645 sound1SweepATL
-=soundQuality
;
647 if(sound1SweepATL
<=0) {
648 freq
= (((int)(ioMem
[NR14
]&7) << 8) | ioMem
[NR13
]);
652 if(sound1SweepUpDown
)
656 if(sound1SweepSteps
) {
657 newfreq
= freq
+ updown
* freq
/ (1 << sound1SweepSteps
);
664 sound1SweepATL
+= sound1SweepATLReload
;
665 } else if(newfreq
> 2047) {
670 sound1SweepATL
+= sound1SweepATLReload
;
671 sound1Skip
= SOUND_MAGIC
/(2048 - newfreq
);
673 ioMem
[NR13
] = newfreq
& 0xff;
674 ioMem
[NR14
] = (ioMem
[NR14
] & 0xf8) |((newfreq
>> 8) & 7);
684 int vol
= sound2EnvelopeVolume
;
688 if(sound2On
&& (sound2ATL
|| !sound2Continue
)) {
689 sound2Index
+= soundQuality
*sound2Skip
;
690 sound2Index
&= 0x1fffffff;
692 value
= ((s8
)sound2Wave
[sound2Index
>>24]) * vol
;
695 soundBuffer
[1][soundIndex
] = value
;
699 sound2ATL
-=soundQuality
;
701 if(sound2ATL
<= 0 && sound2Continue
) {
707 if(sound2EnvelopeATL
) {
708 sound2EnvelopeATL
-=soundQuality
;
710 if(sound2EnvelopeATL
<= 0) {
711 if(sound2EnvelopeUpDown
) {
712 if(sound2EnvelopeVolume
< 15)
713 sound2EnvelopeVolume
++;
715 if(sound2EnvelopeVolume
)
716 sound2EnvelopeVolume
--;
718 sound2EnvelopeATL
+= sound2EnvelopeATLReload
;
726 int value
= sound3Last
;
728 if(sound3On
&& (sound3ATL
|| !sound3Continue
)) {
729 sound3Index
+= soundQuality
*sound3Skip
;
731 sound3Index
&= 0x3fffffff;
732 value
= sound3WaveRam
[sound3Index
>>25];
734 sound3Index
&= 0x1fffffff;
735 value
= sound3WaveRam
[sound3Bank
*0x10 + (sound3Index
>>25)];
738 if( (sound3Index
& 0x01000000)) {
747 if(sound3ForcedOutput
) {
748 value
= ((value
>> 1) + value
) >> 1;
750 switch(sound3OutputLevel
) {
757 value
= (value
>> 1);
760 value
= (value
>> 2);
767 soundBuffer
[2][soundIndex
] = value
;
771 sound3ATL
-=soundQuality
;
773 if(sound3ATL
<= 0 && sound3Continue
) {
783 int vol
= sound4EnvelopeVolume
;
787 if(sound4Clock
<= 0x0c) {
788 if(sound4On
&& (sound4ATL
|| !sound4Continue
)) {
789 sound4Index
+= soundQuality
*sound4Skip
;
790 sound4ShiftIndex
+= soundQuality
*sound4ShiftSkip
;
793 while(sound4ShiftIndex
> 0x1fffff) {
794 sound4ShiftRight
= (((sound4ShiftRight
<< 6) ^
795 (sound4ShiftRight
<< 5)) & 0x40) |
796 (sound4ShiftRight
>> 1);
797 sound4ShiftIndex
-= 0x200000;
800 while(sound4ShiftIndex
> 0x1fffff) {
801 sound4ShiftRight
= (((sound4ShiftRight
<< 14) ^
802 (sound4ShiftRight
<< 13)) & 0x4000) |
803 (sound4ShiftRight
>> 1);
805 sound4ShiftIndex
-= 0x200000;
809 sound4Index
&= 0x1fffff;
810 sound4ShiftIndex
&= 0x1fffff;
812 value
= ((sound4ShiftRight
& 1)*2-1) * vol
;
818 soundBuffer
[3][soundIndex
] = value
;
822 sound4ATL
-=soundQuality
;
824 if(sound4ATL
<= 0 && sound4Continue
) {
830 if(sound4EnvelopeATL
) {
831 sound4EnvelopeATL
-=soundQuality
;
833 if(sound4EnvelopeATL
<= 0) {
834 if(sound4EnvelopeUpDown
) {
835 if(sound4EnvelopeVolume
< 15)
836 sound4EnvelopeVolume
++;
838 if(sound4EnvelopeVolume
)
839 sound4EnvelopeVolume
--;
841 sound4EnvelopeATL
+= sound4EnvelopeATLReload
;
847 void soundDirectSoundA()
849 soundBuffer
[4][soundIndex
] = soundDSAValue
;
852 void soundDirectSoundATimer()
854 if(soundDSAEnabled
) {
855 if(soundDSFifoACount
<= 16) {
857 if(soundDSFifoACount
<= 16) {
858 soundEvent(FIFOA_L
, (u16
)0);
859 soundEvent(FIFOA_H
, (u16
)0);
860 soundEvent(FIFOA_L
, (u16
)0);
861 soundEvent(FIFOA_H
, (u16
)0);
862 soundEvent(FIFOA_L
, (u16
)0);
863 soundEvent(FIFOA_H
, (u16
)0);
864 soundEvent(FIFOA_L
, (u16
)0);
865 soundEvent(FIFOA_H
, (u16
)0);
869 soundDSAValue
= (soundDSFifoA
[soundDSFifoAIndex
]);
870 soundDSFifoAIndex
= (soundDSFifoAIndex
+ 1) & 31;
876 void soundDirectSoundB()
878 soundBuffer
[5][soundIndex
] = soundDSBValue
;
881 void soundDirectSoundBTimer()
883 if(soundDSBEnabled
) {
884 if(soundDSFifoBCount
<= 16) {
886 if(soundDSFifoBCount
<= 16) {
887 soundEvent(FIFOB_L
, (u16
)0);
888 soundEvent(FIFOB_H
, (u16
)0);
889 soundEvent(FIFOB_L
, (u16
)0);
890 soundEvent(FIFOB_H
, (u16
)0);
891 soundEvent(FIFOB_L
, (u16
)0);
892 soundEvent(FIFOB_H
, (u16
)0);
893 soundEvent(FIFOB_L
, (u16
)0);
894 soundEvent(FIFOB_H
, (u16
)0);
898 soundDSBValue
= (soundDSFifoB
[soundDSFifoBIndex
]);
899 soundDSFifoBIndex
= (soundDSFifoBIndex
+ 1) & 31;
906 void soundTimerOverflow(int timer
)
908 if(soundDSAEnabled
&& (soundDSATimer
== timer
)) {
909 soundDirectSoundATimer();
911 if(soundDSBEnabled
&& (soundDSBTimer
== timer
)) {
912 soundDirectSoundBTimer();
917 #define max(a,b) (a)<(b)?(b):(a)
924 int ratio
= ioMem
[0x82] & 3;
925 int dsaRatio
= ioMem
[0x82] & 4;
926 int dsbRatio
= ioMem
[0x82] & 8;
928 if(soundBalance
& 16) {
929 cgbRes
= ((s8
)soundBuffer
[0][soundIndex
]);
931 if(soundBalance
& 32) {
932 cgbRes
+= ((s8
)soundBuffer
[1][soundIndex
]);
934 if(soundBalance
& 64) {
935 cgbRes
+= ((s8
)soundBuffer
[2][soundIndex
]);
937 if(soundBalance
& 128) {
938 cgbRes
+= ((s8
)soundBuffer
[3][soundIndex
]);
941 if((soundControl
& 0x0200) && (soundEnableFlag
& 0x100)){
943 res
= ((s8
)soundBuffer
[4][soundIndex
])>>1;
945 res
= ((s8
)soundBuffer
[4][soundIndex
]);
948 if((soundControl
& 0x2000) && (soundEnableFlag
& 0x200)){
950 res
+= ((s8
)soundBuffer
[5][soundIndex
])>>1;
952 res
+= ((s8
)soundBuffer
[5][soundIndex
]);
956 cgbRes
= (cgbRes
* 52 * soundLevel1
);
960 case 3: // prohibited, but 25%
974 res
+= soundFilter
[soundEchoIndex
];
976 soundFilter
[soundEchoIndex
++] = res
;
980 soundLeft
[4] = soundLeft
[3];
981 soundLeft
[3] = soundLeft
[2];
982 soundLeft
[2] = soundLeft
[1];
983 soundLeft
[1] = soundLeft
[0];
985 res
= (soundLeft
[4] + 2*soundLeft
[3] + 8*soundLeft
[2] + 2*soundLeft
[1] +
989 switch(soundVolume
) {
994 res
*= (soundVolume
+1);
1010 soundFinalWave
[++soundBufferIndex
] = res
;
1012 soundFinalWave
[soundBufferIndex
++] = res
;
1017 if(soundBalance
& 1) {
1018 cgbRes
= ((s8
)soundBuffer
[0][soundIndex
]);
1020 if(soundBalance
& 2) {
1021 cgbRes
+= ((s8
)soundBuffer
[1][soundIndex
]);
1023 if(soundBalance
& 4) {
1024 cgbRes
+= ((s8
)soundBuffer
[2][soundIndex
]);
1026 if(soundBalance
& 8) {
1027 cgbRes
+= ((s8
)soundBuffer
[3][soundIndex
]);
1030 if((soundControl
& 0x0100) && (soundEnableFlag
& 0x100)){
1032 res
= ((s8
)soundBuffer
[4][soundIndex
])>>1;
1034 res
= ((s8
)soundBuffer
[4][soundIndex
]);
1037 if((soundControl
& 0x1000) && (soundEnableFlag
& 0x200)){
1039 res
+= ((s8
)soundBuffer
[5][soundIndex
])>>1;
1041 res
+= ((s8
)soundBuffer
[5][soundIndex
]);
1045 cgbRes
= (cgbRes
* 52 * soundLevel1
);
1049 case 3: // prohibited, but 25%
1063 res
+= soundFilter
[soundEchoIndex
];
1065 soundFilter
[soundEchoIndex
++] = res
;
1067 if(soundEchoIndex
>= 4000)
1072 soundRight
[4] = soundRight
[3];
1073 soundRight
[3] = soundRight
[2];
1074 soundRight
[2] = soundRight
[1];
1075 soundRight
[1] = soundRight
[0];
1076 soundRight
[0] = res
;
1077 res
= (soundRight
[4] + 2*soundRight
[3] + 8*soundRight
[2] + 2*soundRight
[1] +
1081 switch(soundVolume
) {
1086 res
*= (soundVolume
+1);
1102 soundFinalWave
[-1+soundBufferIndex
++] = res
;
1104 soundFinalWave
[soundBufferIndex
++] = res
;
1110 if(soundMasterOn
&& !stopState
) {
1115 soundDirectSoundA();
1116 soundDirectSoundB();
1119 soundFinalWave
[soundBufferIndex
++] = 0;
1120 soundFinalWave
[soundBufferIndex
++] = 0;
1125 if(2*soundBufferIndex
>= soundBufferLen
) {
1131 systemWriteDataToSoundBuffer();
1134 soundBufferIndex
= 0;
1139 void soundShutdown()
1141 systemSoundShutdown();
1152 systemSoundResume();
1156 void soundEnable(int channels
)
1158 int c
= channels
& 0x0f;
1160 soundEnableFlag
|= ((channels
& 0x30f) |c
| (c
<< 4));
1162 soundBalance
= (ioMem
[NR51
] & soundEnableFlag
);
1165 void soundDisable(int channels
)
1167 int c
= channels
& 0x0f;
1169 soundEnableFlag
&= (~((channels
& 0x30f)|c
|(c
<<4)));
1171 soundBalance
= (ioMem
[NR51
] & soundEnableFlag
);
1174 int soundGetEnable()
1176 return (soundEnableFlag
& 0x30f);
1185 SOUND_CLOCK_TICKS
= soundQuality
* USE_TICKS_AS
;
1186 soundTicks
= SOUND_CLOCK_TICKS
;
1187 soundNextPosition
= 0;
1190 soundBufferIndex
= 0;
1199 sound1EnvelopeVolume
= 0;
1200 sound1EnvelopeATL
= 0;
1201 sound1EnvelopeUpDown
= 0;
1202 sound1EnvelopeATLReload
= 0;
1204 sound1SweepATLReload
= 0;
1205 sound1SweepSteps
= 0;
1206 sound1SweepUpDown
= 0;
1207 sound1SweepStep
= 0;
1208 sound1Wave
= soundWavePattern
[2];
1215 sound2EnvelopeVolume
= 0;
1216 sound2EnvelopeATL
= 0;
1217 sound2EnvelopeUpDown
= 0;
1218 sound2EnvelopeATLReload
= 0;
1219 sound2Wave
= soundWavePattern
[2];
1226 sound3OutputLevel
= 0;
1230 sound3ForcedOutput
= 0;
1237 sound4ShiftRight
= 0x7f;
1239 sound4CountDown
= 0;
1241 sound4EnvelopeVolume
= 0;
1242 sound4EnvelopeATL
= 0;
1243 sound4EnvelopeUpDown
= 0;
1244 sound4EnvelopeATLReload
= 0;
1253 while(addr
< 0xA0) {
1254 ioMem
[addr
++] = 0x00;
1255 ioMem
[addr
++] = 0xff;
1259 while(addr
< 0x20) {
1260 sound3WaveRam
[addr
++] = 0x00;
1261 sound3WaveRam
[addr
++] = 0xff;
1264 memset(soundFinalWave
, 0, soundBufferLen
);
1266 memset(soundFilter
, 0, sizeof(soundFilter
));
1272 if(systemSoundInit()) {
1273 memset(soundBuffer
[0], 0, 735*2);
1274 memset(soundBuffer
[1], 0, 735*2);
1275 memset(soundBuffer
[2], 0, 735*2);
1276 memset(soundBuffer
[3], 0, 735*2);
1278 memset(soundFinalWave
, 0, soundBufferLen
);
1286 void soundSetQuality(int quality
)
1288 if(soundQuality
!= quality
&& systemCanChangeSoundQuality()) {
1291 soundQuality
= quality
;
1292 soundNextPosition
= 0;
1295 SOUND_CLOCK_TICKS
= USE_TICKS_AS
* soundQuality
;
1297 soundBufferIndex
= 0;
1298 } else if(soundQuality
!= quality
) {
1299 soundNextPosition
= 0;
1300 SOUND_CLOCK_TICKS
= USE_TICKS_AS
* soundQuality
;
1302 soundBufferIndex
= 0;
1306 void soundSaveGame(gzFile gzFile
)
1308 utilWriteData(gzFile
, soundSaveStruct
);
1309 utilWriteData(gzFile
, soundSaveStructV2
);
1311 utilGzWrite(gzFile
, &soundQuality
, sizeof(int));
1314 void soundReadGame(gzFile gzFile
, int version
)
1316 utilReadData(gzFile
, soundSaveStruct
);
1317 if(version
>= SAVE_GAME_VERSION_3
) {
1318 utilReadData(gzFile
, soundSaveStructV2
);
1320 sound3Bank
= (ioMem
[NR30
] >> 6) & 1;
1321 sound3DataSize
= (ioMem
[NR30
] >> 5) & 1;
1322 sound3ForcedOutput
= (ioMem
[NR32
] >> 7) & 1;
1323 // nothing better to do here...
1324 memcpy(&sound3WaveRam
[0x00], &ioMem
[0x90], 0x10);
1325 memcpy(&sound3WaveRam
[0x10], &ioMem
[0x90], 0x10);
1327 soundBufferIndex
= soundIndex
* 2;
1330 utilGzRead(gzFile
, &quality
, sizeof(int));
1331 soundSetQuality(quality
);
1333 sound1Wave
= soundWavePattern
[ioMem
[NR11
] >> 6];
1334 sound2Wave
= soundWavePattern
[ioMem
[NR21
] >> 6];