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