annotate src/gb/gbSound.cpp @ 525:fa7676dbf6f2

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