annotate src/gb/gbSound.cpp @ 477:ee000791ab4e

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