Mercurial > vba-clojure
view src/gb/gbSound.cpp @ 574:be6f46094ad0
implemented video-memory pointer logic.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 01 Sep 2012 04:05:51 -0500 |
parents | fa7676dbf6f2 |
children |
line wrap: on
line source
1 #ifdef WIN322 # include "../win32/stdafx.h"3 # include "../win32/VBA.h"4 #endif6 #include <cstring>7 #include <cassert>8 #include <stdio.h>10 #include "../common/System.h"11 #include "../common/Util.h"12 //#include "../Blip_Buffer.h"13 #include "gbGlobals.h"14 #include "gbSound.h"16 #ifndef countof17 #define countof(a) (sizeof(a) / sizeof(a[0]))18 #endif20 extern u8 soundBuffer[6][735];21 extern u16 soundFinalWave[1470];22 extern u16 soundFrameSound[735 * 30 * 2];23 extern int32 soundVolume;25 soundtick_t GB_USE_TICKS_AS = 24; // (1048576.0/44100.0); // FIXME: (4194304.0/70224.0)(fps) vs 60.0fps?27 #define SOUND_MAGIC 0x6000000028 #define SOUND_MAGIC_2 0x3000000029 #define NOISE_MAGIC (2097152.0 / 44100.0)31 extern int32 speed;33 extern u8 soundWavePattern[4][32];35 extern u32 soundBufferLen;36 extern u32 soundBufferTotalLen;37 extern int32 soundQuality;38 extern int32 soundPaused;39 extern int32 soundPlay;40 extern soundtick_t soundTicks;41 extern soundtick_t SOUND_CLOCK_TICKS;42 extern u32 soundNextPosition;44 extern int32 soundLevel1;45 extern int32 soundLevel2;46 extern int32 soundBalance;47 extern int32 soundMasterOn;48 extern u32 soundIndex;49 extern u32 soundBufferIndex;50 extern int32 soundFrameSoundWritten;51 int32 soundVIN = 0;52 extern int32 soundDebug;54 extern int32 sound1On;55 extern int32 sound1ATL;56 extern int32 sound1Skip;57 extern int32 sound1Index;58 extern int32 sound1Continue;59 extern int32 sound1EnvelopeVolume;60 extern int32 sound1EnvelopeATL;61 extern int32 sound1EnvelopeUpDown;62 extern int32 sound1EnvelopeATLReload;63 extern int32 sound1SweepATL;64 extern int32 sound1SweepATLReload;65 extern int32 sound1SweepSteps;66 extern int32 sound1SweepUpDown;67 extern int32 sound1SweepStep;68 extern u8 * sound1Wave;70 extern int32 sound2On;71 extern int32 sound2ATL;72 extern int32 sound2Skip;73 extern int32 sound2Index;74 extern int32 sound2Continue;75 extern int32 sound2EnvelopeVolume;76 extern int32 sound2EnvelopeATL;77 extern int32 sound2EnvelopeUpDown;78 extern int32 sound2EnvelopeATLReload;79 extern u8 * sound2Wave;81 extern int32 sound3On;82 extern int32 sound3ATL;83 extern int32 sound3Skip;84 extern int32 sound3Index;85 extern int32 sound3Continue;86 extern int32 sound3OutputLevel;87 extern int32 sound3Last;89 extern int32 sound4On;90 extern int32 sound4Clock;91 extern int32 sound4ATL;92 extern int32 sound4Skip;93 extern int32 sound4Index;94 extern int32 sound4ShiftRight;95 extern int32 sound4ShiftSkip;96 extern int32 sound4ShiftIndex;97 extern int32 sound4NSteps;98 extern int32 sound4CountDown;99 extern int32 sound4Continue;100 extern int32 sound4EnvelopeVolume;101 extern int32 sound4EnvelopeATL;102 extern int32 sound4EnvelopeUpDown;103 extern int32 sound4EnvelopeATLReload;105 extern int32 soundEnableFlag;106 extern int32 soundMutedFlag;108 extern int32 soundFreqRatio[8];109 extern int32 soundShiftClock[16];111 extern s16 soundFilter[4000];112 extern s16 soundLeft[5];113 extern s16 soundRight[5];114 extern int32 soundEchoIndex;115 extern bool8 soundEcho;116 extern bool8 soundLowPass;117 extern bool8 soundReverse;118 extern bool8 soundOffFlag;120 bool8 gbDigitalSound = false;122 void gbSoundEvent(register u16 address, register int data)123 {124 int freq = 0;126 gbMemory[address] = data;128 #ifndef FINAL_VERSION129 if (soundDebug)130 {131 // don't translate. debug only132 log("Sound event: %08lx %02x\n", address, data);133 }134 #endif135 switch (address)136 {137 case NR10:138 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);139 sound1SweepSteps = data & 7;140 sound1SweepUpDown = data & 0x08;141 sound1SweepStep = 0;142 break;143 case NR11:144 sound1Wave = soundWavePattern[data >> 6];145 sound1ATL = 172 * (64 - (data & 0x3f));146 break;147 case NR12:148 sound1EnvelopeVolume = data >> 4;149 sound1EnvelopeUpDown = data & 0x08;150 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);151 break;152 case NR13:153 freq = (((int)(gbMemory[NR14] & 7)) << 8) | data;154 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));155 freq = 2048 - freq;156 if (freq)157 {158 sound1Skip = SOUND_MAGIC / freq;159 }160 else161 sound1Skip = 0;162 break;163 case NR14:164 freq = (((int)(data & 7) << 8) | gbMemory[NR13]);165 freq = 2048 - freq;166 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));167 sound1Continue = data & 0x40;168 if (freq)169 {170 sound1Skip = SOUND_MAGIC / freq;171 }172 else173 sound1Skip = 0;174 if (data & 0x80)175 {176 gbMemory[NR52] |= 1;177 sound1EnvelopeVolume = gbMemory[NR12] >> 4;178 sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;179 sound1ATL = 172 * (64 - (gbMemory[NR11] & 0x3f));180 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);181 sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);182 sound1SweepSteps = gbMemory[NR10] & 7;183 sound1SweepUpDown = gbMemory[NR10] & 0x08;184 sound1SweepStep = 0;186 sound1Index = 0;187 sound1On = 1;188 }189 break;190 case NR21:191 sound2Wave = soundWavePattern[data >> 6];192 sound2ATL = 172 * (64 - (data & 0x3f));193 break;194 case NR22:195 sound2EnvelopeVolume = data >> 4;196 sound2EnvelopeUpDown = data & 0x08;197 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);198 break;199 case NR23:200 freq = (((int)(gbMemory[NR24] & 7)) << 8) | data;201 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));202 freq = 2048 - freq;203 if (freq)204 {205 sound2Skip = SOUND_MAGIC / freq;206 }207 else208 sound2Skip = 0;209 break;210 case NR24:211 freq = (((int)(data & 7) << 8) | gbMemory[NR23]);212 freq = 2048 - freq;213 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));214 sound2Continue = data & 0x40;215 if (freq)216 {217 sound2Skip = SOUND_MAGIC / freq;218 }219 else220 sound2Skip = 0;221 if (data & 0x80)222 {223 gbMemory[NR52] |= 2;224 sound2EnvelopeVolume = gbMemory[NR22] >> 4;225 sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;226 sound2ATL = 172 * (64 - (gbMemory[NR21] & 0x3f));227 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);229 sound2Index = 0;230 sound2On = 1;231 }232 break;233 case NR30:234 if (!(data & 0x80))235 {236 gbMemory[NR52] &= 0xfb;237 sound3On = 0;238 }239 break;240 case NR31:241 sound3ATL = 172 * (256 - data);242 break;243 case NR32:244 sound3OutputLevel = (data >> 5) & 3;245 break;246 case NR33:247 freq = 2048 - (((int)(gbMemory[NR34] & 7) << 8) | data);248 if (freq)249 {250 sound3Skip = SOUND_MAGIC_2 / freq;251 }252 else253 sound3Skip = 0;254 break;255 case NR34:256 freq = 2048 - (((data & 7) << 8) | (int)gbMemory[NR33]);257 if (freq)258 {259 sound3Skip = SOUND_MAGIC_2 / freq;260 }261 else262 {263 sound3Skip = 0;264 }265 sound3Continue = data & 0x40;266 if ((data & 0x80) && (gbMemory[NR30] & 0x80))267 {268 gbMemory[NR52] |= 4;269 sound3ATL = 172 * (256 - gbMemory[NR31]);270 sound3Index = 0;271 sound3On = 1;272 }273 break;274 case NR41:275 sound4ATL = 172 * (64 - (data & 0x3f));276 break;277 case NR42:278 sound4EnvelopeVolume = data >> 4;279 sound4EnvelopeUpDown = data & 0x08;280 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);281 break;282 case NR43:283 freq = soundFreqRatio[data & 7];284 sound4NSteps = data & 0x08;286 sound4Skip = freq * NOISE_MAGIC;288 sound4Clock = data >> 4;290 freq = freq / soundShiftClock[sound4Clock];292 sound4ShiftSkip = freq * NOISE_MAGIC;294 break;295 case NR44:296 sound4Continue = data & 0x40;297 if (data & 0x80)298 {299 gbMemory[NR52] |= 8;300 sound4EnvelopeVolume = gbMemory[NR42] >> 4;301 sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;302 sound4ATL = 172 * (64 - (gbMemory[NR41] & 0x3f));303 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);305 sound4On = 1;307 sound4Index = 0;308 sound4ShiftIndex = 0;310 freq = soundFreqRatio[gbMemory[NR43] & 7];312 sound4Skip = freq * NOISE_MAGIC;314 sound4NSteps = gbMemory[NR43] & 0x08;316 freq = freq / soundShiftClock[gbMemory[NR43] >> 4];318 sound4ShiftSkip = freq * NOISE_MAGIC;319 if (sound4NSteps)320 sound4ShiftRight = 0x7f;321 else322 sound4ShiftRight = 0x7fff;323 }324 break;325 case NR50:326 soundVIN = data & 0x88;327 soundLevel1 = data & 7;328 soundLevel2 = (data >> 4) & 7;329 break;330 case NR51:331 soundBalance = (data & soundEnableFlag);332 gbMemory[address] = data;333 break;334 case NR52:335 soundMasterOn = data & 0x80;336 if (!(data & 0x80))337 {338 sound1On = 0;339 sound2On = 0;340 sound3On = 0;341 sound4On = 0;342 }343 break;344 }346 gbDigitalSound = true;348 if (sound1On && sound1EnvelopeVolume != 0)349 gbDigitalSound = false;350 if (sound2On && sound2EnvelopeVolume != 0)351 gbDigitalSound = false;352 if (sound3On && sound3OutputLevel != 0)353 gbDigitalSound = false;354 if (sound4On && sound4EnvelopeVolume != 0)355 gbDigitalSound = false;356 }358 void gbSoundChannel1()359 {360 int vol = sound1EnvelopeVolume;362 int freq = 0;364 int value = 0;366 if (sound1On && (sound1ATL || !sound1Continue))367 {368 sound1Index += soundQuality * sound1Skip;369 sound1Index &= 0x1fffffff;371 value = ((s8)sound1Wave[sound1Index >> 24]) * vol;372 }374 soundBuffer[0][soundIndex] = value;376 if (sound1On)377 {378 if (sound1ATL)379 {380 sound1ATL -= soundQuality;382 if (sound1ATL <= 0 && sound1Continue)383 {384 gbMemory[NR52] &= 0xfe;385 sound1On = 0;386 }387 }389 if (sound1EnvelopeATL)390 {391 sound1EnvelopeATL -= soundQuality;393 if (sound1EnvelopeATL <= 0)394 {395 if (sound1EnvelopeUpDown)396 {397 if (sound1EnvelopeVolume < 15)398 sound1EnvelopeVolume++;399 }400 else401 {402 if (sound1EnvelopeVolume)403 sound1EnvelopeVolume--;404 }406 sound1EnvelopeATL += sound1EnvelopeATLReload;407 }408 }410 if (sound1SweepATL)411 {412 sound1SweepATL -= soundQuality;414 if (sound1SweepATL <= 0)415 {416 freq = (((int)(gbMemory[NR14] & 7) << 8) | gbMemory[NR13]);418 int updown = 1;420 if (sound1SweepUpDown)421 updown = -1;423 int newfreq = 0;424 if (sound1SweepSteps)425 {426 newfreq = freq + updown * freq / (1 << sound1SweepSteps);427 if (newfreq == freq)428 newfreq = 0;429 }430 else431 newfreq = freq;433 if (newfreq < 0)434 {435 sound1SweepATL += sound1SweepATLReload;436 }437 else if (newfreq > 2047)438 {439 sound1SweepATL = 0;440 sound1On = 0;441 gbMemory[NR52] &= 0xfe;442 }443 else444 {445 sound1SweepATL += sound1SweepATLReload;446 sound1Skip = SOUND_MAGIC / (2048 - newfreq);448 gbMemory[NR13] = newfreq & 0xff;449 gbMemory[NR14] = (gbMemory[NR14] & 0xf8) | ((newfreq >> 8) & 7);450 }451 }452 }453 }454 }456 void gbSoundChannel2()457 {458 // int freq = 0;459 int vol = sound2EnvelopeVolume;461 int value = 0;463 if (sound2On && (sound2ATL || !sound2Continue))464 {465 sound2Index += soundQuality * sound2Skip;466 sound2Index &= 0x1fffffff;468 value = ((s8)sound2Wave[sound2Index >> 24]) * vol;469 }471 soundBuffer[1][soundIndex] = value;473 if (sound2On)474 {475 if (sound2ATL)476 {477 sound2ATL -= soundQuality;479 if (sound2ATL <= 0 && sound2Continue)480 {481 gbMemory[NR52] &= 0xfd;482 sound2On = 0;483 }484 }486 if (sound2EnvelopeATL)487 {488 sound2EnvelopeATL -= soundQuality;490 if (sound2EnvelopeATL <= 0)491 {492 if (sound2EnvelopeUpDown)493 {494 if (sound2EnvelopeVolume < 15)495 sound2EnvelopeVolume++;496 }497 else498 {499 if (sound2EnvelopeVolume)500 sound2EnvelopeVolume--;501 }502 sound2EnvelopeATL += sound2EnvelopeATLReload;503 }504 }505 }506 }508 void gbSoundChannel3()509 {510 int value = sound3Last;512 if (sound3On && (sound3ATL || !sound3Continue))513 {514 sound3Index += soundQuality * sound3Skip;515 sound3Index &= 0x1fffffff;517 value = gbMemory[0xff30 + (sound3Index >> 25)];519 if ((sound3Index & 0x01000000))520 {521 value &= 0x0f;522 }523 else524 {525 value >>= 4;526 }528 value -= 8;529 value *= 2;531 switch (sound3OutputLevel)532 {533 case 0:534 value = 0;535 break;536 case 1:537 break;538 case 2:539 value = (value >> 1);540 break;541 case 3:542 value = (value >> 2);543 break;544 }545 //value += 1;546 sound3Last = value;547 }549 soundBuffer[2][soundIndex] = value;551 if (sound3On)552 {553 if (sound3ATL)554 {555 sound3ATL -= soundQuality;557 if (sound3ATL <= 0 && sound3Continue)558 {559 gbMemory[NR52] &= 0xfb;560 sound3On = 0;561 }562 }563 }564 }566 void gbSoundChannel4()567 {568 int vol = sound4EnvelopeVolume;570 int value = 0;572 if (sound4Clock <= 0x0c)573 {574 if (sound4On && (sound4ATL || !sound4Continue))575 {576 #define NOISE_ONE_SAMP_SCALE 0x200000578 sound4Index += soundQuality * sound4Skip;579 sound4ShiftIndex += soundQuality * sound4ShiftSkip;581 if (sound4NSteps)582 {583 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)584 {585 sound4ShiftRight = (((sound4ShiftRight << 6) ^586 (sound4ShiftRight << 5)) & 0x40) |587 (sound4ShiftRight >> 1);588 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;589 }590 }591 else592 {593 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)594 {595 sound4ShiftRight = (((sound4ShiftRight << 14) ^596 (sound4ShiftRight << 13)) & 0x4000) |597 (sound4ShiftRight >> 1);599 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;600 }601 }603 sound4Index %= NOISE_ONE_SAMP_SCALE;604 sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE;606 value = ((sound4ShiftRight & 1) * 2 - 1) * vol;607 }608 else609 {610 value = 0;611 }612 }614 soundBuffer[3][soundIndex] = value;616 if (sound4On)617 {618 if (sound4ATL)619 {620 sound4ATL -= soundQuality;622 if (sound4ATL <= 0 && sound4Continue)623 {624 gbMemory[NR52] &= 0xfd;625 sound4On = 0;626 }627 }629 if (sound4EnvelopeATL)630 {631 sound4EnvelopeATL -= soundQuality;633 if (sound4EnvelopeATL <= 0)634 {635 if (sound4EnvelopeUpDown)636 {637 if (sound4EnvelopeVolume < 15)638 sound4EnvelopeVolume++;639 }640 else641 {642 if (sound4EnvelopeVolume)643 sound4EnvelopeVolume--;644 }645 sound4EnvelopeATL += sound4EnvelopeATLReload;646 }647 }648 }649 }651 void gbSoundMix()652 {653 int res = 0;655 if (gbMemory)656 soundBalance = (gbMemory[NR51] & soundEnableFlag & ~soundMutedFlag);658 if (soundBalance & 16)659 {660 res += ((s8)soundBuffer[0][soundIndex]);661 }662 if (soundBalance & 32)663 {664 res += ((s8)soundBuffer[1][soundIndex]);665 }666 if (soundBalance & 64)667 {668 res += ((s8)soundBuffer[2][soundIndex]);669 }670 if (soundBalance & 128)671 {672 res += ((s8)soundBuffer[3][soundIndex]);673 }675 if (gbDigitalSound)676 res = soundLevel1 * 256;677 else678 res *= soundLevel1 * 60;680 if (soundEcho)681 {682 res *= 2;683 res += soundFilter[soundEchoIndex];684 res /= 2;685 soundFilter[soundEchoIndex++] = res;686 }688 if (soundLowPass)689 {690 soundLeft[4] = soundLeft[3];691 soundLeft[3] = soundLeft[2];692 soundLeft[2] = soundLeft[1];693 soundLeft[1] = soundLeft[0];694 soundLeft[0] = res;695 res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] +696 soundLeft[0]) / 14;697 }699 bool noSpecialEffects = false;700 #if (defined(WIN32) && !defined(SDL))701 if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog)702 noSpecialEffects = true;703 #endif705 if (!noSpecialEffects)706 {707 switch (soundVolume)708 {709 case 0:710 case 1:711 case 2:712 case 3:713 res *= (soundVolume + 1);714 break;715 case 4:716 res >>= 2;717 break;718 case 5:719 res >>= 1;720 break;721 }722 }724 if (res > 32767)725 res = 32767;726 if (res < -32768)727 res = -32768;729 if (soundReverse && !noSpecialEffects)730 {731 soundFinalWave[++soundBufferIndex] = res;732 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))734 ; //printf("oh noes!\n");735 else736 soundFrameSound[++soundFrameSoundWritten] = res;737 }738 else739 {740 soundFinalWave[soundBufferIndex++] = res;741 if (soundFrameSoundWritten >= countof(soundFrameSound))742 ; //printf("oh noes!\n");743 else744 soundFrameSound[soundFrameSoundWritten++] = res;745 }747 res = 0;749 if (soundBalance & 1)750 {751 res += ((s8)soundBuffer[0][soundIndex]);752 }753 if (soundBalance & 2)754 {755 res += ((s8)soundBuffer[1][soundIndex]);756 }757 if (soundBalance & 4)758 {759 res += ((s8)soundBuffer[2][soundIndex]);760 }761 if (soundBalance & 8)762 {763 res += ((s8)soundBuffer[3][soundIndex]);764 }766 if (gbDigitalSound)767 res = soundLevel2 * 256;768 else769 res *= soundLevel2 * 60;771 if (soundEcho)772 {773 res *= 2;774 res += soundFilter[soundEchoIndex];775 res /= 2;776 soundFilter[soundEchoIndex++] = res;778 if (soundEchoIndex >= 4000)779 soundEchoIndex = 0;780 }782 if (soundLowPass)783 {784 soundRight[4] = soundRight[3];785 soundRight[3] = soundRight[2];786 soundRight[2] = soundRight[1];787 soundRight[1] = soundRight[0];788 soundRight[0] = res;789 res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] +790 soundRight[0]) / 14;791 }793 if (!noSpecialEffects)794 {795 switch (soundVolume)796 {797 case 0:798 case 1:799 case 2:800 case 3:801 res *= (soundVolume + 1);802 break;803 case 4:804 res >>= 2;805 break;806 case 5:807 res >>= 1;808 break;809 }810 }812 if (res > 32767)813 res = 32767;814 if (res < -32768)815 res = -32768;817 if (soundReverse && !noSpecialEffects)818 {819 soundFinalWave[-1 + soundBufferIndex++] = res;820 if ((soundFrameSoundWritten) >= countof(soundFrameSound))821 ;//printf("oh noes!\n");822 else823 soundFrameSound[-1 + soundFrameSoundWritten++] = res;824 }825 else826 {827 soundFinalWave[soundBufferIndex++] = res;828 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))829 ;//printf("oh noes!\n");830 else831 soundFrameSound[soundFrameSoundWritten++] = res;832 }833 }835 void gbSoundTick()836 {837 if (systemSoundOn)838 {839 if (soundMasterOn)840 {841 gbSoundChannel1();842 gbSoundChannel2();843 gbSoundChannel3();844 gbSoundChannel4();846 gbSoundMix();847 }848 else849 {850 soundFinalWave[soundBufferIndex++] = 0;851 soundFinalWave[soundBufferIndex++] = 0;852 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))854 ;//printf("oh noes!\n");855 else856 {857 soundFrameSound[soundFrameSoundWritten++] = 0;858 soundFrameSound[soundFrameSoundWritten++] = 0;859 }860 }862 soundIndex++;864 if (2 * soundBufferIndex >= soundBufferLen)865 {866 if (systemSoundOn)867 {868 if (soundPaused)869 {870 extern void soundResume();871 soundResume();872 }874 systemSoundWriteToBuffer();875 }876 soundIndex = 0;877 soundBufferIndex = 0;878 }879 }880 }882 void gbSoundReset()883 {884 soundPaused = 1;885 soundPlay = 0;886 SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;887 // soundTicks = SOUND_CLOCK_TICKS;888 soundTicks = 0;889 soundNextPosition = 0;890 soundMasterOn = 1;891 soundIndex = 0;892 soundBufferIndex = 0;893 soundLevel1 = 7;894 soundLevel2 = 7;895 soundVIN = 0;897 sound1On = 0;898 sound1ATL = 0;899 sound1Skip = 0;900 sound1Index = 0;901 sound1Continue = 0;902 sound1EnvelopeVolume = 0;903 sound1EnvelopeATL = 0;904 sound1EnvelopeUpDown = 0;905 sound1EnvelopeATLReload = 0;906 sound1SweepATL = 0;907 sound1SweepATLReload = 0;908 sound1SweepSteps = 0;909 sound1SweepUpDown = 0;910 sound1SweepStep = 0;911 sound1Wave = soundWavePattern[2];913 sound2On = 0;914 sound2ATL = 0;915 sound2Skip = 0;916 sound2Index = 0;917 sound2Continue = 0;918 sound2EnvelopeVolume = 0;919 sound2EnvelopeATL = 0;920 sound2EnvelopeUpDown = 0;921 sound2EnvelopeATLReload = 0;922 sound2Wave = soundWavePattern[2];924 sound3On = 0;925 sound3ATL = 0;926 sound3Skip = 0;927 sound3Index = 0;928 sound3Continue = 0;929 sound3OutputLevel = 0;931 sound4On = 0;932 sound4Clock = 0;933 sound4ATL = 0;934 sound4Skip = 0;935 sound4Index = 0;936 sound4ShiftRight = 0x7f;937 sound4NSteps = 0;938 sound4CountDown = 0;939 sound4Continue = 0;940 sound4EnvelopeVolume = 0;941 sound4EnvelopeATL = 0;942 sound4EnvelopeUpDown = 0;943 sound4EnvelopeATLReload = 0;945 // don't translate946 if (soundDebug)947 {948 log("*** Sound Init ***\n");949 }951 gbSoundEvent(0xff10, 0x80);952 gbSoundEvent(0xff11, 0xbf);953 gbSoundEvent(0xff12, 0xf3);954 gbSoundEvent(0xff14, 0xbf);955 gbSoundEvent(0xff16, 0x3f);956 gbSoundEvent(0xff17, 0x00);957 gbSoundEvent(0xff19, 0xbf);959 gbSoundEvent(0xff1a, 0x7f);960 gbSoundEvent(0xff1b, 0xff);961 gbSoundEvent(0xff1c, 0xbf);962 gbSoundEvent(0xff1e, 0xbf);964 gbSoundEvent(0xff20, 0xff);965 gbSoundEvent(0xff21, 0x00);966 gbSoundEvent(0xff22, 0x00);967 gbSoundEvent(0xff23, 0xbf);968 gbSoundEvent(0xff24, 0x77);969 gbSoundEvent(0xff25, 0xf3);971 gbSoundEvent(0xff26, 0xf0);973 // don't translate974 if (soundDebug)975 {976 log("*** Sound Init Complete ***\n");977 }979 sound1On = 0;980 sound2On = 0;981 sound3On = 0;982 sound4On = 0;984 int addr = 0xff30;986 while (addr < 0xff40)987 {988 gbMemory[addr++] = 0x00;989 gbMemory[addr++] = 0xff;990 }992 memset(soundFinalWave, 0x00, soundBufferLen);994 memset(soundFilter, 0, sizeof(soundFilter));995 soundEchoIndex = 0;996 }998 extern bool soundInit();999 extern void soundShutdown();1001 void gbSoundSetQuality(int quality)1002 {1003 if (soundQuality != quality && systemSoundCanChangeQuality())1004 {1005 if (!soundOffFlag)1006 soundShutdown();1007 soundQuality = quality;1008 soundNextPosition = 0;1009 if (!soundOffFlag)1010 soundInit();1011 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality;1012 soundIndex = 0;1013 soundBufferIndex = 0;1014 }1015 else1016 {1017 soundNextPosition = 0;1018 SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * GB_USE_TICKS_AS * soundQuality;1019 soundIndex = 0;1020 soundBufferIndex = 0;1021 }1022 }1024 static int32 soundTicks_int32;1025 static int32 SOUND_CLOCK_TICKS_int32;1026 variable_desc gbSoundSaveStruct[] = {1027 { &soundPaused, sizeof(int32) },1028 { &soundPlay, sizeof(int32) },1029 { &soundTicks_int32, sizeof(int32) },1030 { &SOUND_CLOCK_TICKS_int32, sizeof(int32) },1031 { &soundLevel1, sizeof(int32) },1032 { &soundLevel2, sizeof(int32) },1033 { &soundBalance, sizeof(int32) },1034 { &soundMasterOn, sizeof(int32) },1035 { &soundIndex, sizeof(int32) },1036 { &soundVIN, sizeof(int32) },1037 { &sound1On, sizeof(int32) },1038 { &sound1ATL, sizeof(int32) },1039 { &sound1Skip, sizeof(int32) },1040 { &sound1Index, sizeof(int32) },1041 { &sound1Continue, sizeof(int32) },1042 { &sound1EnvelopeVolume, sizeof(int32) },1043 { &sound1EnvelopeATL, sizeof(int32) },1044 { &sound1EnvelopeATLReload, sizeof(int32) },1045 { &sound1EnvelopeUpDown, sizeof(int32) },1046 { &sound1SweepATL, sizeof(int32) },1047 { &sound1SweepATLReload, sizeof(int32) },1048 { &sound1SweepSteps, sizeof(int32) },1049 { &sound1SweepUpDown, sizeof(int32) },1050 { &sound1SweepStep, sizeof(int32) },1051 { &sound2On, sizeof(int32) },1052 { &sound2ATL, sizeof(int32) },1053 { &sound2Skip, sizeof(int32) },1054 { &sound2Index, sizeof(int32) },1055 { &sound2Continue, sizeof(int32) },1056 { &sound2EnvelopeVolume, sizeof(int32) },1057 { &sound2EnvelopeATL, sizeof(int32) },1058 { &sound2EnvelopeATLReload, sizeof(int32) },1059 { &sound2EnvelopeUpDown, sizeof(int32) },1060 { &sound3On, sizeof(int32) },1061 { &sound3ATL, sizeof(int32) },1062 { &sound3Skip, sizeof(int32) },1063 { &sound3Index, sizeof(int32) },1064 { &sound3Continue, sizeof(int32) },1065 { &sound3OutputLevel, sizeof(int32) },1066 { &sound4On, sizeof(int32) },1067 { &sound4ATL, sizeof(int32) },1068 { &sound4Skip, sizeof(int32) },1069 { &sound4Index, sizeof(int32) },1070 { &sound4Clock, sizeof(int32) },1071 { &sound4ShiftRight, sizeof(int32) },1072 { &sound4ShiftSkip, sizeof(int32) },1073 { &sound4ShiftIndex, sizeof(int32) },1074 { &sound4NSteps, sizeof(int32) },1075 { &sound4CountDown, sizeof(int32) },1076 { &sound4Continue, sizeof(int32) },1077 { &sound4EnvelopeVolume, sizeof(int32) },1078 { &sound4EnvelopeATL, sizeof(int32) },1079 { &sound4EnvelopeATLReload, sizeof(int32) },1080 { &sound4EnvelopeUpDown, sizeof(int32) },1081 { &soundEnableFlag, sizeof(int32) },1082 { NULL, 0 }1083 };1085 //variable_desc gbSoundSaveStructV2[] = {1086 // { &soundTicks, sizeof(soundtick_t) },1087 // { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) },1088 // { &GB_USE_TICKS_AS, sizeof(soundtick_t) },1089 // { NULL, 0 }1090 //};1092 void gbSoundSaveGame(gzFile gzFile)1093 {1094 soundTicks_int32 = (int32) soundTicks;1095 SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS;1097 utilWriteData(gzFile, gbSoundSaveStruct);1099 utilGzWrite(gzFile, soundBuffer, 4 * 735);1100 utilGzWrite(gzFile, soundFinalWave, 2 * 735);1101 utilGzWrite(gzFile, &soundQuality, sizeof(int32));1103 //utilWriteData(gzFile, gbSoundSaveStructV2);1104 }1106 void gbSoundReadGame(int version, gzFile gzFile)1107 {1108 int32 oldSoundPaused = soundPaused;1109 int32 oldSoundEnableFlag = soundEnableFlag;1110 utilReadData(gzFile, gbSoundSaveStruct);1111 soundPaused = oldSoundPaused;1112 soundEnableFlag = oldSoundEnableFlag;1114 soundBufferIndex = soundIndex * 2;1116 utilGzRead(gzFile, soundBuffer, 4 * 735);1117 utilGzRead(gzFile, soundFinalWave, 2 * 735);1119 if (version >= 7)1120 {1121 int quality = 1;1122 utilGzRead(gzFile, &quality, sizeof(int32));1123 gbSoundSetQuality(quality);1124 }1125 else1126 {1127 soundQuality = -1;1128 gbSoundSetQuality(1);1129 }1131 sound1Wave = soundWavePattern[gbMemory[NR11] >> 6];1132 sound2Wave = soundWavePattern[gbMemory[NR21] >> 6];1134 //if(version >= 14) {1135 // utilReadData(gzFile, gbSoundSaveStructV2);1136 //}1137 //else {1138 soundTicks = (soundtick_t) soundTicks_int32;1139 SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32;1140 //}1141 }