annotate src/gba/GBASound.cpp @ 270:49096b8b99d5

script: delivered oak's parcel; got pokedex.
author Robert McIntyre <rlm@mit.edu>
date Mon, 26 Mar 2012 23:54:52 -0500
parents f9f4f1b99eed
children
rev   line source
rlm@1 1 #if (defined(WIN32) && !defined(SDL))
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 "GBASound.h"
rlm@1 10 #include "../common/System.h" // SDL build needs this
rlm@1 11 #include "../common/Util.h"
rlm@1 12 #include "GBA.h"
rlm@1 13 #include "GBAGlobals.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 soundtick_t USE_TICKS_AS = 380; // (16777216.0/44100.0); // FIXME: (16777216.0/280896.0)(fps) vs 60.0fps?
rlm@1 20
rlm@1 21 #define SOUND_MAGIC 0x60000000
rlm@1 22 #define SOUND_MAGIC_2 0x30000000
rlm@1 23 #define NOISE_MAGIC (2097152.0 / 44100.0)
rlm@1 24
rlm@1 25 extern bool8 stopState;
rlm@1 26
rlm@1 27 u8 soundWavePattern[4][32] = {
rlm@1 28 { 0x01, 0x01, 0x01, 0x01,
rlm@1 29 0xff, 0xff, 0xff, 0xff,
rlm@1 30 0xff, 0xff, 0xff, 0xff,
rlm@1 31 0xff, 0xff, 0xff, 0xff,
rlm@1 32 0xff, 0xff, 0xff, 0xff,
rlm@1 33 0xff, 0xff, 0xff, 0xff,
rlm@1 34 0xff, 0xff, 0xff, 0xff,
rlm@1 35 0xff, 0xff, 0xff, 0xff },
rlm@1 36 { 0x01, 0x01, 0x01, 0x01,
rlm@1 37 0x01, 0x01, 0x01, 0x01,
rlm@1 38 0xff, 0xff, 0xff, 0xff,
rlm@1 39 0xff, 0xff, 0xff, 0xff,
rlm@1 40 0xff, 0xff, 0xff, 0xff,
rlm@1 41 0xff, 0xff, 0xff, 0xff,
rlm@1 42 0xff, 0xff, 0xff, 0xff,
rlm@1 43 0xff, 0xff, 0xff, 0xff },
rlm@1 44 { 0x01, 0x01, 0x01, 0x01,
rlm@1 45 0x01, 0x01, 0x01, 0x01,
rlm@1 46 0x01, 0x01, 0x01, 0x01,
rlm@1 47 0x01, 0x01, 0x01, 0x01,
rlm@1 48 0xff, 0xff, 0xff, 0xff,
rlm@1 49 0xff, 0xff, 0xff, 0xff,
rlm@1 50 0xff, 0xff, 0xff, 0xff,
rlm@1 51 0xff, 0xff, 0xff, 0xff },
rlm@1 52 { 0x01, 0x01, 0x01, 0x01,
rlm@1 53 0x01, 0x01, 0x01, 0x01,
rlm@1 54 0x01, 0x01, 0x01, 0x01,
rlm@1 55 0x01, 0x01, 0x01, 0x01,
rlm@1 56 0x01, 0x01, 0x01, 0x01,
rlm@1 57 0x01, 0x01, 0x01, 0x01,
rlm@1 58 0xff, 0xff, 0xff, 0xff,
rlm@1 59 0xff, 0xff, 0xff, 0xff }
rlm@1 60 };
rlm@1 61
rlm@1 62 int32 soundFreqRatio[8] = {
rlm@1 63 1048576, // 0
rlm@1 64 524288, // 1
rlm@1 65 262144, // 2
rlm@1 66 174763, // 3
rlm@1 67 131072, // 4
rlm@1 68 104858, // 5
rlm@1 69 87381, // 6
rlm@1 70 74898 // 7
rlm@1 71 };
rlm@1 72
rlm@1 73 int32 soundShiftClock[16] = {
rlm@1 74 2, // 0
rlm@1 75 4, // 1
rlm@1 76 8, // 2
rlm@1 77 16, // 3
rlm@1 78 32, // 4
rlm@1 79 64, // 5
rlm@1 80 128, // 6
rlm@1 81 256, // 7
rlm@1 82 512, // 8
rlm@1 83 1024, // 9
rlm@1 84 2048, // 10
rlm@1 85 4096, // 11
rlm@1 86 8192, // 12
rlm@1 87 16384, // 13
rlm@1 88 1, // 14
rlm@1 89 1 // 15
rlm@1 90 };
rlm@1 91
rlm@1 92 int32 soundVolume = 0;
rlm@1 93
rlm@1 94 u8 soundBuffer[6][735];
rlm@1 95 u16 soundFinalWave[1470];
rlm@1 96 u16 soundFrameSound[735 * 30 * 2]; // for avi logging
rlm@1 97
rlm@1 98 u32 soundBufferLen = 1470;
rlm@1 99 u32 soundBufferTotalLen = 14700;
rlm@1 100 int32 soundQuality = 2;
rlm@1 101 int32 soundPaused = 1;
rlm@1 102 int32 soundPlay = 0;
rlm@1 103 soundtick_t soundTicks = soundQuality * USE_TICKS_AS;
rlm@1 104 soundtick_t SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS;
rlm@1 105 u32 soundNextPosition = 0;
rlm@1 106
rlm@1 107 int32 soundLevel1 = 0;
rlm@1 108 int32 soundLevel2 = 0;
rlm@1 109 int32 soundBalance = 0;
rlm@1 110 int32 soundMasterOn = 0;
rlm@1 111 u32 soundIndex = 0;
rlm@1 112 u32 soundBufferIndex = 0;
rlm@1 113 int32 soundFrameSoundWritten = 0;
rlm@1 114 int32 soundDebug = 0;
rlm@1 115 bool8 soundOffFlag = false;
rlm@1 116
rlm@1 117 int32 sound1On = 0;
rlm@1 118 int32 sound1ATL = 0;
rlm@1 119 int32 sound1Skip = 0;
rlm@1 120 int32 sound1Index = 0;
rlm@1 121 int32 sound1Continue = 0;
rlm@1 122 int32 sound1EnvelopeVolume = 0;
rlm@1 123 int32 sound1EnvelopeATL = 0;
rlm@1 124 int32 sound1EnvelopeUpDown = 0;
rlm@1 125 int32 sound1EnvelopeATLReload = 0;
rlm@1 126 int32 sound1SweepATL = 0;
rlm@1 127 int32 sound1SweepATLReload = 0;
rlm@1 128 int32 sound1SweepSteps = 0;
rlm@1 129 int32 sound1SweepUpDown = 0;
rlm@1 130 int32 sound1SweepStep = 0;
rlm@1 131 u8 * sound1Wave = soundWavePattern[2];
rlm@1 132
rlm@1 133 int32 sound2On = 0;
rlm@1 134 int32 sound2ATL = 0;
rlm@1 135 int32 sound2Skip = 0;
rlm@1 136 int32 sound2Index = 0;
rlm@1 137 int32 sound2Continue = 0;
rlm@1 138 int32 sound2EnvelopeVolume = 0;
rlm@1 139 int32 sound2EnvelopeATL = 0;
rlm@1 140 int32 sound2EnvelopeUpDown = 0;
rlm@1 141 int32 sound2EnvelopeATLReload = 0;
rlm@1 142 u8 * sound2Wave = soundWavePattern[2];
rlm@1 143
rlm@1 144 int32 sound3On = 0;
rlm@1 145 int32 sound3ATL = 0;
rlm@1 146 int32 sound3Skip = 0;
rlm@1 147 int32 sound3Index = 0;
rlm@1 148 int32 sound3Continue = 0;
rlm@1 149 int32 sound3OutputLevel = 0;
rlm@1 150 int32 sound3Last = 0;
rlm@1 151 u8 sound3WaveRam[0x20];
rlm@1 152 int32 sound3Bank = 0;
rlm@1 153 int32 sound3DataSize = 0;
rlm@1 154 int32 sound3ForcedOutput = 0;
rlm@1 155
rlm@1 156 int32 sound4On = 0;
rlm@1 157 int32 sound4Clock = 0;
rlm@1 158 int32 sound4ATL = 0;
rlm@1 159 int32 sound4Skip = 0;
rlm@1 160 int32 sound4Index = 0;
rlm@1 161 int32 sound4ShiftRight = 0x7f;
rlm@1 162 int32 sound4ShiftSkip = 0;
rlm@1 163 int32 sound4ShiftIndex = 0;
rlm@1 164 int32 sound4NSteps = 0;
rlm@1 165 int32 sound4CountDown = 0;
rlm@1 166 int32 sound4Continue = 0;
rlm@1 167 int32 sound4EnvelopeVolume = 0;
rlm@1 168 int32 sound4EnvelopeATL = 0;
rlm@1 169 int32 sound4EnvelopeUpDown = 0;
rlm@1 170 int32 sound4EnvelopeATLReload = 0;
rlm@1 171
rlm@1 172 int32 soundControl = 0;
rlm@1 173
rlm@1 174 int32 soundDSFifoAIndex = 0;
rlm@1 175 int32 soundDSFifoACount = 0;
rlm@1 176 int32 soundDSFifoAWriteIndex = 0;
rlm@1 177 bool8 soundDSAEnabled = false;
rlm@1 178 int32 soundDSATimer = 0;
rlm@1 179 u8 soundDSFifoA[32];
rlm@1 180 u8 soundDSAValue = 0;
rlm@1 181
rlm@1 182 int32 soundDSFifoBIndex = 0;
rlm@1 183 int32 soundDSFifoBCount = 0;
rlm@1 184 int32 soundDSFifoBWriteIndex = 0;
rlm@1 185 bool8 soundDSBEnabled = false;
rlm@1 186 int32 soundDSBTimer = 0;
rlm@1 187 u8 soundDSFifoB[32];
rlm@1 188 u8 soundDSBValue = 0;
rlm@1 189
rlm@1 190 int32 soundEnableFlag = 0x3ff;
rlm@1 191 int32 soundMutedFlag = 0;
rlm@1 192
rlm@1 193 s16 soundFilter[4000];
rlm@1 194 s16 soundRight[5] = { 0, 0, 0, 0, 0 };
rlm@1 195 s16 soundLeft[5] = { 0, 0, 0, 0, 0 };
rlm@1 196 int32 soundEchoIndex = 0;
rlm@1 197 bool8 soundEcho = false;
rlm@1 198 bool8 soundLowPass = false;
rlm@1 199 bool8 soundReverse = false;
rlm@1 200
rlm@1 201 static int32 soundTicks_int32;
rlm@1 202 static int32 SOUND_CLOCK_TICKS_int32;
rlm@1 203 static int32 soundDSBValue_int32;
rlm@1 204 variable_desc soundSaveStruct[] = {
rlm@1 205 { &soundPaused, sizeof(int32) },
rlm@1 206 { &soundPlay, sizeof(int32) },
rlm@1 207 { &soundTicks_int32, sizeof(int32) },
rlm@1 208 { &SOUND_CLOCK_TICKS_int32, sizeof(int32) },
rlm@1 209 { &soundLevel1, sizeof(int32) },
rlm@1 210 { &soundLevel2, sizeof(int32) },
rlm@1 211 { &soundBalance, sizeof(int32) },
rlm@1 212 { &soundMasterOn, sizeof(int32) },
rlm@1 213 { &soundIndex, sizeof(int32) },
rlm@1 214 { &sound1On, sizeof(int32) },
rlm@1 215 { &sound1ATL, sizeof(int32) },
rlm@1 216 { &sound1Skip, sizeof(int32) },
rlm@1 217 { &sound1Index, sizeof(int32) },
rlm@1 218 { &sound1Continue, sizeof(int32) },
rlm@1 219 { &sound1EnvelopeVolume, sizeof(int32) },
rlm@1 220 { &sound1EnvelopeATL, sizeof(int32) },
rlm@1 221 { &sound1EnvelopeATLReload, sizeof(int32) },
rlm@1 222 { &sound1EnvelopeUpDown, sizeof(int32) },
rlm@1 223 { &sound1SweepATL, sizeof(int32) },
rlm@1 224 { &sound1SweepATLReload, sizeof(int32) },
rlm@1 225 { &sound1SweepSteps, sizeof(int32) },
rlm@1 226 { &sound1SweepUpDown, sizeof(int32) },
rlm@1 227 { &sound1SweepStep, sizeof(int32) },
rlm@1 228 { &sound2On, sizeof(int32) },
rlm@1 229 { &sound2ATL, sizeof(int32) },
rlm@1 230 { &sound2Skip, sizeof(int32) },
rlm@1 231 { &sound2Index, sizeof(int32) },
rlm@1 232 { &sound2Continue, sizeof(int32) },
rlm@1 233 { &sound2EnvelopeVolume, sizeof(int32) },
rlm@1 234 { &sound2EnvelopeATL, sizeof(int32) },
rlm@1 235 { &sound2EnvelopeATLReload, sizeof(int32) },
rlm@1 236 { &sound2EnvelopeUpDown, sizeof(int32) },
rlm@1 237 { &sound3On, sizeof(int32) },
rlm@1 238 { &sound3ATL, sizeof(int32) },
rlm@1 239 { &sound3Skip, sizeof(int32) },
rlm@1 240 { &sound3Index, sizeof(int32) },
rlm@1 241 { &sound3Continue, sizeof(int32) },
rlm@1 242 { &sound3OutputLevel, sizeof(int32) },
rlm@1 243 { &sound4On, sizeof(int32) },
rlm@1 244 { &sound4ATL, sizeof(int32) },
rlm@1 245 { &sound4Skip, sizeof(int32) },
rlm@1 246 { &sound4Index, sizeof(int32) },
rlm@1 247 { &sound4Clock, sizeof(int32) },
rlm@1 248 { &sound4ShiftRight, sizeof(int32) },
rlm@1 249 { &sound4ShiftSkip, sizeof(int32) },
rlm@1 250 { &sound4ShiftIndex, sizeof(int32) },
rlm@1 251 { &sound4NSteps, sizeof(int32) },
rlm@1 252 { &sound4CountDown, sizeof(int32) },
rlm@1 253 { &sound4Continue, sizeof(int32) },
rlm@1 254 { &sound4EnvelopeVolume, sizeof(int32) },
rlm@1 255 { &sound4EnvelopeATL, sizeof(int32) },
rlm@1 256 { &sound4EnvelopeATLReload, sizeof(int32) },
rlm@1 257 { &sound4EnvelopeUpDown, sizeof(int32) },
rlm@1 258 { &soundEnableFlag, sizeof(int32) },
rlm@1 259 { &soundControl, sizeof(int32) },
rlm@1 260 { &soundDSFifoAIndex, sizeof(int32) },
rlm@1 261 { &soundDSFifoACount, sizeof(int32) },
rlm@1 262 { &soundDSFifoAWriteIndex, sizeof(int32) },
rlm@1 263 { &soundDSAEnabled, sizeof(bool8) },
rlm@1 264 { &soundDSATimer, sizeof(int32) },
rlm@1 265 { &soundDSFifoA[0], 32 },
rlm@1 266 { &soundDSAValue, sizeof(u8) },
rlm@1 267 { &soundDSFifoBIndex, sizeof(int32) },
rlm@1 268 { &soundDSFifoBCount, sizeof(int32) },
rlm@1 269 { &soundDSFifoBWriteIndex, sizeof(int32) },
rlm@1 270 { &soundDSBEnabled, sizeof(int32) },
rlm@1 271 { &soundDSBTimer, sizeof(int32) },
rlm@1 272 { &soundDSFifoB[0], 32 },
rlm@1 273 { &soundDSBValue_int32, sizeof(int32) }, // save as int32 because of a mistake of the past.
rlm@1 274 { &soundBuffer[0][0], 6 * 735 },
rlm@1 275 { &soundFinalWave[0], 2 * 735 },
rlm@1 276 { NULL, 0 }
rlm@1 277 };
rlm@1 278
rlm@1 279 variable_desc soundSaveStructV2[] = {
rlm@1 280 { &sound3WaveRam[0], 0x20 },
rlm@1 281 { &sound3Bank, sizeof(int32) },
rlm@1 282 { &sound3DataSize, sizeof(int32) },
rlm@1 283 { &sound3ForcedOutput, sizeof(int32) },
rlm@1 284 { NULL, 0 }
rlm@1 285 };
rlm@1 286
rlm@1 287 //variable_desc soundSaveStructV3[] = {
rlm@1 288 // { &soundTicks, sizeof(soundtick_t) },
rlm@1 289 // { &SOUND_CLOCK_TICKS, sizeof(soundtick_t) },
rlm@1 290 // { &USE_TICKS_AS, sizeof(soundtick_t) },
rlm@1 291 // { NULL, 0 }
rlm@1 292 //};
rlm@1 293
rlm@1 294 void soundEvent(u32 address, u8 data)
rlm@1 295 {
rlm@1 296 int freq = 0;
rlm@1 297
rlm@1 298 switch (address)
rlm@1 299 {
rlm@1 300 case NR10:
rlm@1 301 data &= 0x7f;
rlm@1 302 sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
rlm@1 303 sound1SweepSteps = data & 7;
rlm@1 304 sound1SweepUpDown = data & 0x08;
rlm@1 305 sound1SweepStep = 0;
rlm@1 306 ioMem[address] = data;
rlm@1 307 break;
rlm@1 308 case NR11:
rlm@1 309 sound1Wave = soundWavePattern[data >> 6];
rlm@1 310 sound1ATL = 172 * (64 - (data & 0x3f));
rlm@1 311 ioMem[address] = data;
rlm@1 312 break;
rlm@1 313 case NR12:
rlm@1 314 sound1EnvelopeUpDown = data & 0x08;
rlm@1 315 sound1EnvelopeATLReload = 689 * (data & 7);
rlm@1 316 if ((data & 0xF8) == 0)
rlm@1 317 sound1EnvelopeVolume = 0;
rlm@1 318 ioMem[address] = data;
rlm@1 319 break;
rlm@1 320 case NR13:
rlm@1 321 freq = (((int)(ioMem[NR14] & 7)) << 8) | data;
rlm@1 322 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
rlm@1 323 freq = 2048 - freq;
rlm@1 324 if (freq)
rlm@1 325 {
rlm@1 326 sound1Skip = SOUND_MAGIC / freq;
rlm@1 327 }
rlm@1 328 else
rlm@1 329 sound1Skip = 0;
rlm@1 330 ioMem[address] = data;
rlm@1 331 break;
rlm@1 332 case NR14:
rlm@1 333 data &= 0xC7;
rlm@1 334 freq = (((int)(data & 7) << 8) | ioMem[NR13]);
rlm@1 335 freq = 2048 - freq;
rlm@1 336 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
rlm@1 337 sound1Continue = data & 0x40;
rlm@1 338 if (freq)
rlm@1 339 {
rlm@1 340 sound1Skip = SOUND_MAGIC / freq;
rlm@1 341 }
rlm@1 342 else
rlm@1 343 sound1Skip = 0;
rlm@1 344 if (data & 0x80)
rlm@1 345 {
rlm@1 346 ioMem[NR52] |= 1;
rlm@1 347 sound1EnvelopeVolume = ioMem[NR12] >> 4;
rlm@1 348 sound1EnvelopeUpDown = ioMem[NR12] & 0x08;
rlm@1 349 sound1ATL = 172 * (64 - (ioMem[NR11] & 0x3f));
rlm@1 350 sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (ioMem[NR12] & 7);
rlm@1 351 sound1SweepATL = sound1SweepATLReload = 344 * ((ioMem[NR10] >> 4) & 7);
rlm@1 352 sound1SweepSteps = ioMem[NR10] & 7;
rlm@1 353 sound1SweepUpDown = ioMem[NR10] & 0x08;
rlm@1 354 sound1SweepStep = 0;
rlm@1 355
rlm@1 356 sound1Index = 0;
rlm@1 357 sound1On = 1;
rlm@1 358 }
rlm@1 359 ioMem[address] = data;
rlm@1 360 break;
rlm@1 361 case NR21:
rlm@1 362 sound2Wave = soundWavePattern[data >> 6];
rlm@1 363 sound2ATL = 172 * (64 - (data & 0x3f));
rlm@1 364 ioMem[address] = data;
rlm@1 365 break;
rlm@1 366 case NR22:
rlm@1 367 sound2EnvelopeUpDown = data & 0x08;
rlm@1 368 sound2EnvelopeATLReload = 689 * (data & 7);
rlm@1 369 if ((data & 0xF8) == 0)
rlm@1 370 sound2EnvelopeVolume = 0;
rlm@1 371 ioMem[address] = data;
rlm@1 372 break;
rlm@1 373 case NR23:
rlm@1 374 freq = (((int)(ioMem[NR24] & 7)) << 8) | data;
rlm@1 375 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
rlm@1 376 freq = 2048 - freq;
rlm@1 377 if (freq)
rlm@1 378 {
rlm@1 379 sound2Skip = SOUND_MAGIC / freq;
rlm@1 380 }
rlm@1 381 else
rlm@1 382 sound2Skip = 0;
rlm@1 383 ioMem[address] = data;
rlm@1 384 break;
rlm@1 385 case NR24:
rlm@1 386 data &= 0xC7;
rlm@1 387 freq = (((int)(data & 7) << 8) | ioMem[NR23]);
rlm@1 388 freq = 2048 - freq;
rlm@1 389 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
rlm@1 390 sound2Continue = data & 0x40;
rlm@1 391 if (freq)
rlm@1 392 {
rlm@1 393 sound2Skip = SOUND_MAGIC / freq;
rlm@1 394 }
rlm@1 395 else
rlm@1 396 sound2Skip = 0;
rlm@1 397 if (data & 0x80)
rlm@1 398 {
rlm@1 399 ioMem[NR52] |= 2;
rlm@1 400 sound2EnvelopeVolume = ioMem[NR22] >> 4;
rlm@1 401 sound2EnvelopeUpDown = ioMem[NR22] & 0x08;
rlm@1 402 sound2ATL = 172 * (64 - (ioMem[NR21] & 0x3f));
rlm@1 403 sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (ioMem[NR22] & 7);
rlm@1 404
rlm@1 405 sound2Index = 0;
rlm@1 406 sound2On = 1;
rlm@1 407 }
rlm@1 408 ioMem[address] = data;
rlm@1 409 break;
rlm@1 410 case NR30:
rlm@1 411 data &= 0xe0;
rlm@1 412 if (!(data & 0x80))
rlm@1 413 {
rlm@1 414 ioMem[NR52] &= 0xfb;
rlm@1 415 sound3On = 0;
rlm@1 416 }
rlm@1 417 if (((data >> 6) & 1) != sound3Bank)
rlm@1 418 memcpy(&ioMem[0x90], &sound3WaveRam[(((data >> 6) & 1) * 0x10) ^ 0x10],
rlm@1 419 0x10);
rlm@1 420 sound3Bank = (data >> 6) & 1;
rlm@1 421 sound3DataSize = (data >> 5) & 1;
rlm@1 422 ioMem[address] = data;
rlm@1 423 break;
rlm@1 424 case NR31:
rlm@1 425 sound3ATL = 172 * (256 - data);
rlm@1 426 ioMem[address] = data;
rlm@1 427 break;
rlm@1 428 case NR32:
rlm@1 429 data &= 0xe0;
rlm@1 430 sound3OutputLevel = (data >> 5) & 3;
rlm@1 431 sound3ForcedOutput = (data >> 7) & 1;
rlm@1 432 ioMem[address] = data;
rlm@1 433 break;
rlm@1 434 case NR33:
rlm@1 435 freq = 2048 - (((int)(ioMem[NR34] & 7) << 8) | data);
rlm@1 436 if (freq)
rlm@1 437 {
rlm@1 438 sound3Skip = SOUND_MAGIC_2 / freq;
rlm@1 439 }
rlm@1 440 else
rlm@1 441 sound3Skip = 0;
rlm@1 442 ioMem[address] = data;
rlm@1 443 break;
rlm@1 444 case NR34:
rlm@1 445 data &= 0xc7;
rlm@1 446 freq = 2048 - (((data & 7) << 8) | (int)ioMem[NR33]);
rlm@1 447 if (freq)
rlm@1 448 {
rlm@1 449 sound3Skip = SOUND_MAGIC_2 / freq;
rlm@1 450 }
rlm@1 451 else
rlm@1 452 {
rlm@1 453 sound3Skip = 0;
rlm@1 454 }
rlm@1 455 sound3Continue = data & 0x40;
rlm@1 456 if ((data & 0x80) && (ioMem[NR30] & 0x80))
rlm@1 457 {
rlm@1 458 ioMem[NR52] |= 4;
rlm@1 459 sound3ATL = 172 * (256 - ioMem[NR31]);
rlm@1 460 sound3Index = 0;
rlm@1 461 sound3On = 1;
rlm@1 462 }
rlm@1 463 ioMem[address] = data;
rlm@1 464 break;
rlm@1 465 case NR41:
rlm@1 466 data &= 0x3f;
rlm@1 467 sound4ATL = 172 * (64 - (data & 0x3f));
rlm@1 468 ioMem[address] = data;
rlm@1 469 break;
rlm@1 470 case NR42:
rlm@1 471 sound4EnvelopeUpDown = data & 0x08;
rlm@1 472 sound4EnvelopeATLReload = 689 * (data & 7);
rlm@1 473 if ((data & 0xF8) == 0)
rlm@1 474 sound4EnvelopeVolume = 0;
rlm@1 475 ioMem[address] = data;
rlm@1 476 break;
rlm@1 477 case NR43:
rlm@1 478 freq = soundFreqRatio[data & 7];
rlm@1 479 sound4NSteps = data & 0x08;
rlm@1 480
rlm@1 481 sound4Skip = freq * NOISE_MAGIC;
rlm@1 482
rlm@1 483 sound4Clock = data >> 4;
rlm@1 484
rlm@1 485 freq = freq / soundShiftClock[sound4Clock];
rlm@1 486
rlm@1 487 sound4ShiftSkip = freq * NOISE_MAGIC;
rlm@1 488 ioMem[address] = data;
rlm@1 489 break;
rlm@1 490 case NR44:
rlm@1 491 data &= 0xc0;
rlm@1 492 sound4Continue = data & 0x40;
rlm@1 493 if (data & 0x80)
rlm@1 494 {
rlm@1 495 ioMem[NR52] |= 8;
rlm@1 496 sound4EnvelopeVolume = ioMem[NR42] >> 4;
rlm@1 497 sound4EnvelopeUpDown = ioMem[NR42] & 0x08;
rlm@1 498 sound4ATL = 172 * (64 - (ioMem[NR41] & 0x3f));
rlm@1 499 sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (ioMem[NR42] & 7);
rlm@1 500
rlm@1 501 sound4On = 1;
rlm@1 502
rlm@1 503 sound4Index = 0;
rlm@1 504 sound4ShiftIndex = 0;
rlm@1 505
rlm@1 506 freq = soundFreqRatio[ioMem[NR43] & 7];
rlm@1 507
rlm@1 508 sound4Skip = freq * NOISE_MAGIC;
rlm@1 509
rlm@1 510 sound4NSteps = ioMem[NR43] & 0x08;
rlm@1 511
rlm@1 512 freq = freq / soundShiftClock[ioMem[NR43] >> 4];
rlm@1 513
rlm@1 514 sound4ShiftSkip = freq * NOISE_MAGIC;
rlm@1 515 if (sound4NSteps)
rlm@1 516 sound4ShiftRight = 0x7f;
rlm@1 517 else
rlm@1 518 sound4ShiftRight = 0x7fff;
rlm@1 519 }
rlm@1 520 ioMem[address] = data;
rlm@1 521 break;
rlm@1 522 case NR50:
rlm@1 523 data &= 0x77;
rlm@1 524 soundLevel1 = data & 7;
rlm@1 525 soundLevel2 = (data >> 4) & 7;
rlm@1 526 ioMem[address] = data;
rlm@1 527 break;
rlm@1 528 case NR51:
rlm@1 529 soundBalance = (data & soundEnableFlag);
rlm@1 530 ioMem[address] = data;
rlm@1 531 break;
rlm@1 532 case NR52:
rlm@1 533 data &= 0x80;
rlm@1 534 data |= ioMem[NR52] & 15;
rlm@1 535 soundMasterOn = data & 0x80;
rlm@1 536 if (!(data & 0x80))
rlm@1 537 {
rlm@1 538 sound1On = 0;
rlm@1 539 sound2On = 0;
rlm@1 540 sound3On = 0;
rlm@1 541 sound4On = 0;
rlm@1 542 }
rlm@1 543 ioMem[address] = data;
rlm@1 544 break;
rlm@1 545 case 0x90:
rlm@1 546 case 0x91:
rlm@1 547 case 0x92:
rlm@1 548 case 0x93:
rlm@1 549 case 0x94:
rlm@1 550 case 0x95:
rlm@1 551 case 0x96:
rlm@1 552 case 0x97:
rlm@1 553 case 0x98:
rlm@1 554 case 0x99:
rlm@1 555 case 0x9a:
rlm@1 556 case 0x9b:
rlm@1 557 case 0x9c:
rlm@1 558 case 0x9d:
rlm@1 559 case 0x9e:
rlm@1 560 case 0x9f:
rlm@1 561 sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 15)] = data;
rlm@1 562 break;
rlm@1 563 }
rlm@1 564 }
rlm@1 565
rlm@1 566 void soundEvent(u32 address, u16 data)
rlm@1 567 {
rlm@1 568 switch (address)
rlm@1 569 {
rlm@1 570 case SGCNT0_H:
rlm@1 571 data &= 0xFF0F;
rlm@1 572 soundControl = data & 0x770F;;
rlm@1 573 if (data & 0x0800)
rlm@1 574 {
rlm@1 575 soundDSFifoAWriteIndex = 0;
rlm@1 576 soundDSFifoAIndex = 0;
rlm@1 577 soundDSFifoACount = 0;
rlm@1 578 soundDSAValue = 0;
rlm@1 579 memset(soundDSFifoA, 0, 32);
rlm@1 580 }
rlm@1 581 soundDSAEnabled = (data & 0x0300) ? true : false;
rlm@1 582 soundDSATimer = (data & 0x0400) ? 1 : 0;
rlm@1 583 if (data & 0x8000)
rlm@1 584 {
rlm@1 585 soundDSFifoBWriteIndex = 0;
rlm@1 586 soundDSFifoBIndex = 0;
rlm@1 587 soundDSFifoBCount = 0;
rlm@1 588 soundDSBValue = 0;
rlm@1 589 memset(soundDSFifoB, 0, 32);
rlm@1 590 }
rlm@1 591 soundDSBEnabled = (data & 0x3000) ? true : false;
rlm@1 592 soundDSBTimer = (data & 0x4000) ? 1 : 0;
rlm@1 593 *((u16 *)&ioMem[address]) = data;
rlm@1 594 break;
rlm@1 595 case FIFOA_L:
rlm@1 596 case FIFOA_H:
rlm@1 597 soundDSFifoA[soundDSFifoAWriteIndex++] = data & 0xFF;
rlm@1 598 soundDSFifoA[soundDSFifoAWriteIndex++] = data >> 8;
rlm@1 599 soundDSFifoACount += 2;
rlm@1 600 soundDSFifoAWriteIndex &= 31;
rlm@1 601 *((u16 *)&ioMem[address]) = data;
rlm@1 602 break;
rlm@1 603 case FIFOB_L:
rlm@1 604 case FIFOB_H:
rlm@1 605 soundDSFifoB[soundDSFifoBWriteIndex++] = data & 0xFF;
rlm@1 606 soundDSFifoB[soundDSFifoBWriteIndex++] = data >> 8;
rlm@1 607 soundDSFifoBCount += 2;
rlm@1 608 soundDSFifoBWriteIndex &= 31;
rlm@1 609 *((u16 *)&ioMem[address]) = data;
rlm@1 610 break;
rlm@1 611 case 0x88:
rlm@1 612 data &= 0xC3FF;
rlm@1 613 *((u16 *)&ioMem[address]) = data;
rlm@1 614 break;
rlm@1 615 case 0x90:
rlm@1 616 case 0x92:
rlm@1 617 case 0x94:
rlm@1 618 case 0x96:
rlm@1 619 case 0x98:
rlm@1 620 case 0x9a:
rlm@1 621 case 0x9c:
rlm@1 622 case 0x9e:
rlm@1 623 *((u16 *)&sound3WaveRam[(sound3Bank * 0x10) ^ 0x10 + (address & 14)]) = data;
rlm@1 624 *((u16 *)&ioMem[address]) = data;
rlm@1 625 break;
rlm@1 626 }
rlm@1 627 }
rlm@1 628
rlm@1 629 void soundChannel1()
rlm@1 630 {
rlm@1 631 int vol = sound1EnvelopeVolume;
rlm@1 632
rlm@1 633 int freq = 0;
rlm@1 634 int value = 0;
rlm@1 635
rlm@1 636 if (sound1On && (sound1ATL || !sound1Continue))
rlm@1 637 {
rlm@1 638 sound1Index += soundQuality * sound1Skip;
rlm@1 639 sound1Index &= 0x1fffffff;
rlm@1 640
rlm@1 641 value = ((s8)sound1Wave[sound1Index >> 24]) * vol;
rlm@1 642 }
rlm@1 643
rlm@1 644 soundBuffer[0][soundIndex] = value;
rlm@1 645
rlm@1 646 if (sound1On)
rlm@1 647 {
rlm@1 648 if (sound1ATL)
rlm@1 649 {
rlm@1 650 sound1ATL -= soundQuality;
rlm@1 651
rlm@1 652 if (sound1ATL <= 0 && sound1Continue)
rlm@1 653 {
rlm@1 654 ioMem[NR52] &= 0xfe;
rlm@1 655 sound1On = 0;
rlm@1 656 }
rlm@1 657 }
rlm@1 658
rlm@1 659 if (sound1EnvelopeATL)
rlm@1 660 {
rlm@1 661 sound1EnvelopeATL -= soundQuality;
rlm@1 662
rlm@1 663 if (sound1EnvelopeATL <= 0)
rlm@1 664 {
rlm@1 665 if (sound1EnvelopeUpDown)
rlm@1 666 {
rlm@1 667 if (sound1EnvelopeVolume < 15)
rlm@1 668 sound1EnvelopeVolume++;
rlm@1 669 }
rlm@1 670 else
rlm@1 671 {
rlm@1 672 if (sound1EnvelopeVolume)
rlm@1 673 sound1EnvelopeVolume--;
rlm@1 674 }
rlm@1 675
rlm@1 676 sound1EnvelopeATL += sound1EnvelopeATLReload;
rlm@1 677 }
rlm@1 678 }
rlm@1 679
rlm@1 680 if (sound1SweepATL)
rlm@1 681 {
rlm@1 682 sound1SweepATL -= soundQuality;
rlm@1 683
rlm@1 684 if (sound1SweepATL <= 0)
rlm@1 685 {
rlm@1 686 freq = (((int)(ioMem[NR14] & 7) << 8) | ioMem[NR13]);
rlm@1 687
rlm@1 688 int updown = 1;
rlm@1 689
rlm@1 690 if (sound1SweepUpDown)
rlm@1 691 updown = -1;
rlm@1 692
rlm@1 693 int newfreq = 0;
rlm@1 694 if (sound1SweepSteps)
rlm@1 695 {
rlm@1 696 newfreq = freq + updown * freq / (1 << sound1SweepSteps);
rlm@1 697 if (newfreq == freq)
rlm@1 698 newfreq = 0;
rlm@1 699 }
rlm@1 700 else
rlm@1 701 newfreq = freq;
rlm@1 702
rlm@1 703 if (newfreq < 0)
rlm@1 704 {
rlm@1 705 sound1SweepATL += sound1SweepATLReload;
rlm@1 706 }
rlm@1 707 else if (newfreq > 2047)
rlm@1 708 {
rlm@1 709 sound1SweepATL = 0;
rlm@1 710 sound1On = 0;
rlm@1 711 ioMem[NR52] &= 0xfe;
rlm@1 712 }
rlm@1 713 else
rlm@1 714 {
rlm@1 715 sound1SweepATL += sound1SweepATLReload;
rlm@1 716 sound1Skip = SOUND_MAGIC / (2048 - newfreq);
rlm@1 717
rlm@1 718 ioMem[NR13] = newfreq & 0xff;
rlm@1 719 ioMem[NR14] = (ioMem[NR14] & 0xf8) | ((newfreq >> 8) & 7);
rlm@1 720 }
rlm@1 721 }
rlm@1 722 }
rlm@1 723 }
rlm@1 724 }
rlm@1 725
rlm@1 726 void soundChannel2()
rlm@1 727 {
rlm@1 728 // int freq = 0;
rlm@1 729 int vol = sound2EnvelopeVolume;
rlm@1 730
rlm@1 731 int value = 0;
rlm@1 732
rlm@1 733 if (sound2On && (sound2ATL || !sound2Continue))
rlm@1 734 {
rlm@1 735 sound2Index += soundQuality * sound2Skip;
rlm@1 736 sound2Index &= 0x1fffffff;
rlm@1 737
rlm@1 738 value = ((s8)sound2Wave[sound2Index >> 24]) * vol;
rlm@1 739 }
rlm@1 740
rlm@1 741 soundBuffer[1][soundIndex] = value;
rlm@1 742
rlm@1 743 if (sound2On)
rlm@1 744 {
rlm@1 745 if (sound2ATL)
rlm@1 746 {
rlm@1 747 sound2ATL -= soundQuality;
rlm@1 748
rlm@1 749 if (sound2ATL <= 0 && sound2Continue)
rlm@1 750 {
rlm@1 751 ioMem[NR52] &= 0xfd;
rlm@1 752 sound2On = 0;
rlm@1 753 }
rlm@1 754 }
rlm@1 755
rlm@1 756 if (sound2EnvelopeATL)
rlm@1 757 {
rlm@1 758 sound2EnvelopeATL -= soundQuality;
rlm@1 759
rlm@1 760 if (sound2EnvelopeATL <= 0)
rlm@1 761 {
rlm@1 762 if (sound2EnvelopeUpDown)
rlm@1 763 {
rlm@1 764 if (sound2EnvelopeVolume < 15)
rlm@1 765 sound2EnvelopeVolume++;
rlm@1 766 }
rlm@1 767 else
rlm@1 768 {
rlm@1 769 if (sound2EnvelopeVolume)
rlm@1 770 sound2EnvelopeVolume--;
rlm@1 771 }
rlm@1 772 sound2EnvelopeATL += sound2EnvelopeATLReload;
rlm@1 773 }
rlm@1 774 }
rlm@1 775 }
rlm@1 776 }
rlm@1 777
rlm@1 778 void soundChannel3()
rlm@1 779 {
rlm@1 780 int value = sound3Last;
rlm@1 781
rlm@1 782 if (sound3On && (sound3ATL || !sound3Continue))
rlm@1 783 {
rlm@1 784 sound3Index += soundQuality * sound3Skip;
rlm@1 785 if (sound3DataSize)
rlm@1 786 {
rlm@1 787 sound3Index &= 0x3fffffff;
rlm@1 788 value = sound3WaveRam[sound3Index >> 25];
rlm@1 789 }
rlm@1 790 else
rlm@1 791 {
rlm@1 792 sound3Index &= 0x1fffffff;
rlm@1 793 value = sound3WaveRam[sound3Bank * 0x10 + (sound3Index >> 25)];
rlm@1 794 }
rlm@1 795
rlm@1 796 if ((sound3Index & 0x01000000))
rlm@1 797 {
rlm@1 798 value &= 0x0f;
rlm@1 799 }
rlm@1 800 else
rlm@1 801 {
rlm@1 802 value >>= 4;
rlm@1 803 }
rlm@1 804
rlm@1 805 value -= 8;
rlm@1 806 value *= 2;
rlm@1 807
rlm@1 808 if (sound3ForcedOutput)
rlm@1 809 {
rlm@1 810 value = ((value >> 1) + value) >> 1;
rlm@1 811 }
rlm@1 812 else
rlm@1 813 {
rlm@1 814 switch (sound3OutputLevel)
rlm@1 815 {
rlm@1 816 case 0:
rlm@1 817 value = 0;
rlm@1 818 break;
rlm@1 819 case 1:
rlm@1 820 break;
rlm@1 821 case 2:
rlm@1 822 value = (value >> 1);
rlm@1 823 break;
rlm@1 824 case 3:
rlm@1 825 value = (value >> 2);
rlm@1 826 break;
rlm@1 827 }
rlm@1 828 }
rlm@1 829 //value += 1;
rlm@1 830 sound3Last = value;
rlm@1 831 }
rlm@1 832
rlm@1 833 soundBuffer[2][soundIndex] = value;
rlm@1 834
rlm@1 835 if (sound3On)
rlm@1 836 {
rlm@1 837 if (sound3ATL)
rlm@1 838 {
rlm@1 839 sound3ATL -= soundQuality;
rlm@1 840
rlm@1 841 if (sound3ATL <= 0 && sound3Continue)
rlm@1 842 {
rlm@1 843 ioMem[NR52] &= 0xfb;
rlm@1 844 sound3On = 0;
rlm@1 845 }
rlm@1 846 }
rlm@1 847 }
rlm@1 848 }
rlm@1 849
rlm@1 850 void soundChannel4()
rlm@1 851 {
rlm@1 852 int vol = sound4EnvelopeVolume;
rlm@1 853
rlm@1 854 int value = 0;
rlm@1 855
rlm@1 856 if (sound4Clock <= 0x0c)
rlm@1 857 {
rlm@1 858 if (sound4On && (sound4ATL || !sound4Continue))
rlm@1 859 {
rlm@1 860 #define NOISE_ONE_SAMP_SCALE 0x200000
rlm@1 861
rlm@1 862 sound4Index += soundQuality * sound4Skip;
rlm@1 863 sound4ShiftIndex += soundQuality * sound4ShiftSkip;
rlm@1 864
rlm@1 865 if (sound4NSteps)
rlm@1 866 {
rlm@1 867 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
rlm@1 868 {
rlm@1 869 sound4ShiftRight = (((sound4ShiftRight << 6) ^
rlm@1 870 (sound4ShiftRight << 5)) & 0x40) |
rlm@1 871 (sound4ShiftRight >> 1);
rlm@1 872 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
rlm@1 873 }
rlm@1 874 }
rlm@1 875 else
rlm@1 876 {
rlm@1 877 while (sound4ShiftIndex >= NOISE_ONE_SAMP_SCALE)
rlm@1 878 {
rlm@1 879 sound4ShiftRight = (((sound4ShiftRight << 14) ^
rlm@1 880 (sound4ShiftRight << 13)) & 0x4000) |
rlm@1 881 (sound4ShiftRight >> 1);
rlm@1 882
rlm@1 883 sound4ShiftIndex -= NOISE_ONE_SAMP_SCALE;
rlm@1 884 }
rlm@1 885 }
rlm@1 886
rlm@1 887 sound4Index %= NOISE_ONE_SAMP_SCALE;
rlm@1 888 sound4ShiftIndex %= NOISE_ONE_SAMP_SCALE;
rlm@1 889
rlm@1 890 value = ((sound4ShiftRight & 1) * 2 - 1) * vol;
rlm@1 891 }
rlm@1 892 else
rlm@1 893 {
rlm@1 894 value = 0;
rlm@1 895 }
rlm@1 896 }
rlm@1 897
rlm@1 898 soundBuffer[3][soundIndex] = value;
rlm@1 899
rlm@1 900 if (sound4On)
rlm@1 901 {
rlm@1 902 if (sound4ATL)
rlm@1 903 {
rlm@1 904 sound4ATL -= soundQuality;
rlm@1 905
rlm@1 906 if (sound4ATL <= 0 && sound4Continue)
rlm@1 907 {
rlm@1 908 ioMem[NR52] &= 0xfd;
rlm@1 909 sound4On = 0;
rlm@1 910 }
rlm@1 911 }
rlm@1 912
rlm@1 913 if (sound4EnvelopeATL)
rlm@1 914 {
rlm@1 915 sound4EnvelopeATL -= soundQuality;
rlm@1 916
rlm@1 917 if (sound4EnvelopeATL <= 0)
rlm@1 918 {
rlm@1 919 if (sound4EnvelopeUpDown)
rlm@1 920 {
rlm@1 921 if (sound4EnvelopeVolume < 15)
rlm@1 922 sound4EnvelopeVolume++;
rlm@1 923 }
rlm@1 924 else
rlm@1 925 {
rlm@1 926 if (sound4EnvelopeVolume)
rlm@1 927 sound4EnvelopeVolume--;
rlm@1 928 }
rlm@1 929 sound4EnvelopeATL += sound4EnvelopeATLReload;
rlm@1 930 }
rlm@1 931 }
rlm@1 932 }
rlm@1 933 }
rlm@1 934
rlm@1 935 void soundDirectSoundA()
rlm@1 936 {
rlm@1 937 soundBuffer[4][soundIndex] = soundDSAValue;
rlm@1 938 }
rlm@1 939
rlm@1 940 void soundDirectSoundATimer()
rlm@1 941 {
rlm@1 942 if (soundDSAEnabled)
rlm@1 943 {
rlm@1 944 if (soundDSFifoACount <= 16)
rlm@1 945 {
rlm@1 946 CPUCheckDMA(3, 2);
rlm@1 947 if (soundDSFifoACount <= 16)
rlm@1 948 {
rlm@1 949 soundEvent(FIFOA_L, (u16)0);
rlm@1 950 soundEvent(FIFOA_H, (u16)0);
rlm@1 951 soundEvent(FIFOA_L, (u16)0);
rlm@1 952 soundEvent(FIFOA_H, (u16)0);
rlm@1 953 soundEvent(FIFOA_L, (u16)0);
rlm@1 954 soundEvent(FIFOA_H, (u16)0);
rlm@1 955 soundEvent(FIFOA_L, (u16)0);
rlm@1 956 soundEvent(FIFOA_H, (u16)0);
rlm@1 957 }
rlm@1 958 }
rlm@1 959
rlm@1 960 soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]);
rlm@1 961 soundDSFifoAIndex = (++soundDSFifoAIndex) & 31;
rlm@1 962 soundDSFifoACount--;
rlm@1 963 }
rlm@1 964 else
rlm@1 965 soundDSAValue = 0;
rlm@1 966 }
rlm@1 967
rlm@1 968 void soundDirectSoundB()
rlm@1 969 {
rlm@1 970 soundBuffer[5][soundIndex] = soundDSBValue;
rlm@1 971 }
rlm@1 972
rlm@1 973 void soundDirectSoundBTimer()
rlm@1 974 {
rlm@1 975 if (soundDSBEnabled)
rlm@1 976 {
rlm@1 977 if (soundDSFifoBCount <= 16)
rlm@1 978 {
rlm@1 979 CPUCheckDMA(3, 4);
rlm@1 980 if (soundDSFifoBCount <= 16)
rlm@1 981 {
rlm@1 982 soundEvent(FIFOB_L, (u16)0);
rlm@1 983 soundEvent(FIFOB_H, (u16)0);
rlm@1 984 soundEvent(FIFOB_L, (u16)0);
rlm@1 985 soundEvent(FIFOB_H, (u16)0);
rlm@1 986 soundEvent(FIFOB_L, (u16)0);
rlm@1 987 soundEvent(FIFOB_H, (u16)0);
rlm@1 988 soundEvent(FIFOB_L, (u16)0);
rlm@1 989 soundEvent(FIFOB_H, (u16)0);
rlm@1 990 }
rlm@1 991 }
rlm@1 992
rlm@1 993 soundDSBValue = (soundDSFifoB[soundDSFifoBIndex]);
rlm@1 994 soundDSFifoBIndex = (++soundDSFifoBIndex) & 31;
rlm@1 995 soundDSFifoBCount--;
rlm@1 996 }
rlm@1 997 else
rlm@1 998 {
rlm@1 999 soundDSBValue = 0;
rlm@1 1000 }
rlm@1 1001 }
rlm@1 1002
rlm@1 1003 void soundTimerOverflow(int timer)
rlm@1 1004 {
rlm@1 1005 if (soundDSAEnabled && (soundDSATimer == timer))
rlm@1 1006 {
rlm@1 1007 soundDirectSoundATimer();
rlm@1 1008 }
rlm@1 1009 if (soundDSBEnabled && (soundDSBTimer == timer))
rlm@1 1010 {
rlm@1 1011 soundDirectSoundBTimer();
rlm@1 1012 }
rlm@1 1013 }
rlm@1 1014
rlm@1 1015 void soundMix()
rlm@1 1016 {
rlm@1 1017 int res = 0;
rlm@1 1018 int cgbRes = 0;
rlm@1 1019 int ratio = ioMem[0x82] & 3;
rlm@1 1020 int dsaRatio = ioMem[0x82] & 4;
rlm@1 1021 int dsbRatio = ioMem[0x82] & 8;
rlm@1 1022
rlm@1 1023 if (ioMem)
rlm@1 1024 soundBalance = (ioMem[NR51] & soundEnableFlag & ~soundMutedFlag);
rlm@1 1025
rlm@1 1026 if (soundBalance & 16)
rlm@1 1027 {
rlm@1 1028 cgbRes = ((s8)soundBuffer[0][soundIndex]);
rlm@1 1029 }
rlm@1 1030 if (soundBalance & 32)
rlm@1 1031 {
rlm@1 1032 cgbRes += ((s8)soundBuffer[1][soundIndex]);
rlm@1 1033 }
rlm@1 1034 if (soundBalance & 64)
rlm@1 1035 {
rlm@1 1036 cgbRes += ((s8)soundBuffer[2][soundIndex]);
rlm@1 1037 }
rlm@1 1038 if (soundBalance & 128)
rlm@1 1039 {
rlm@1 1040 cgbRes += ((s8)soundBuffer[3][soundIndex]);
rlm@1 1041 }
rlm@1 1042
rlm@1 1043 if ((soundControl & 0x0200) && (soundEnableFlag & 0x100))
rlm@1 1044 {
rlm@1 1045 if (!dsaRatio)
rlm@1 1046 res = ((s8)soundBuffer[4][soundIndex]) >> 1;
rlm@1 1047 else
rlm@1 1048 res = ((s8)soundBuffer[4][soundIndex]);
rlm@1 1049 }
rlm@1 1050
rlm@1 1051 if ((soundControl & 0x2000) && (soundEnableFlag & 0x200))
rlm@1 1052 {
rlm@1 1053 if (!dsbRatio)
rlm@1 1054 res += ((s8)soundBuffer[5][soundIndex]) >> 1;
rlm@1 1055 else
rlm@1 1056 res += ((s8)soundBuffer[5][soundIndex]);
rlm@1 1057 }
rlm@1 1058
rlm@1 1059 res = (res * 170);
rlm@1 1060 cgbRes = (cgbRes * 52 * soundLevel1);
rlm@1 1061
rlm@1 1062 switch (ratio)
rlm@1 1063 {
rlm@1 1064 case 0:
rlm@1 1065 case 3: // prohibited, but 25%
rlm@1 1066 cgbRes >>= 2;
rlm@1 1067 break;
rlm@1 1068 case 1:
rlm@1 1069 cgbRes >>= 1;
rlm@1 1070 break;
rlm@1 1071 case 2:
rlm@1 1072 break;
rlm@1 1073 }
rlm@1 1074
rlm@1 1075 res += cgbRes;
rlm@1 1076
rlm@1 1077 if (soundEcho)
rlm@1 1078 {
rlm@1 1079 res *= 2;
rlm@1 1080 res += soundFilter[soundEchoIndex];
rlm@1 1081 res /= 2;
rlm@1 1082 soundFilter[soundEchoIndex++] = res;
rlm@1 1083 }
rlm@1 1084
rlm@1 1085 if (soundLowPass)
rlm@1 1086 {
rlm@1 1087 soundLeft[4] = soundLeft[3];
rlm@1 1088 soundLeft[3] = soundLeft[2];
rlm@1 1089 soundLeft[2] = soundLeft[1];
rlm@1 1090 soundLeft[1] = soundLeft[0];
rlm@1 1091 soundLeft[0] = res;
rlm@1 1092 res = (soundLeft[4] + 2 * soundLeft[3] + 8 * soundLeft[2] + 2 * soundLeft[1] +
rlm@1 1093 soundLeft[0]) / 14;
rlm@1 1094 }
rlm@1 1095
rlm@1 1096 bool noSpecialEffects = false;
rlm@1 1097 #if (defined(WIN32) && !defined(SDL))
rlm@1 1098 if (theApp.soundRecording || theApp.aviRecording || theApp.nvAudioLog)
rlm@1 1099 noSpecialEffects = true;
rlm@1 1100 #endif
rlm@1 1101
rlm@1 1102 if (!noSpecialEffects)
rlm@1 1103 {
rlm@1 1104 switch (soundVolume)
rlm@1 1105 {
rlm@1 1106 case 0:
rlm@1 1107 case 1:
rlm@1 1108 case 2:
rlm@1 1109 case 3:
rlm@1 1110 res *= (soundVolume + 1);
rlm@1 1111 break;
rlm@1 1112 case 4:
rlm@1 1113 res >>= 2;
rlm@1 1114 break;
rlm@1 1115 case 5:
rlm@1 1116 res >>= 1;
rlm@1 1117 break;
rlm@1 1118 }
rlm@1 1119 }
rlm@1 1120
rlm@1 1121 if (res > 32767)
rlm@1 1122 res = 32767;
rlm@1 1123 if (res < -32768)
rlm@1 1124 res = -32768;
rlm@1 1125
rlm@1 1126 if (soundReverse && !noSpecialEffects)
rlm@1 1127 {
rlm@1 1128 soundFinalWave[++soundBufferIndex] = res;
rlm@1 1129 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
rlm@1 1130 /*assert(false)*/;
rlm@1 1131 else
rlm@1 1132 soundFrameSound[++soundFrameSoundWritten] = res;
rlm@1 1133 }
rlm@1 1134 else
rlm@1 1135 {
rlm@1 1136 soundFinalWave[soundBufferIndex++] = res;
rlm@1 1137 if (soundFrameSoundWritten >= countof(soundFrameSound))
rlm@1 1138 /*assert(false)*/;
rlm@1 1139 else
rlm@1 1140 soundFrameSound[soundFrameSoundWritten++] = res;
rlm@1 1141 }
rlm@1 1142
rlm@1 1143 res = 0;
rlm@1 1144 cgbRes = 0;
rlm@1 1145
rlm@1 1146 if (soundBalance & 1)
rlm@1 1147 {
rlm@1 1148 cgbRes = ((s8)soundBuffer[0][soundIndex]);
rlm@1 1149 }
rlm@1 1150 if (soundBalance & 2)
rlm@1 1151 {
rlm@1 1152 cgbRes += ((s8)soundBuffer[1][soundIndex]);
rlm@1 1153 }
rlm@1 1154 if (soundBalance & 4)
rlm@1 1155 {
rlm@1 1156 cgbRes += ((s8)soundBuffer[2][soundIndex]);
rlm@1 1157 }
rlm@1 1158 if (soundBalance & 8)
rlm@1 1159 {
rlm@1 1160 cgbRes += ((s8)soundBuffer[3][soundIndex]);
rlm@1 1161 }
rlm@1 1162
rlm@1 1163 if ((soundControl & 0x0100) && (soundEnableFlag & 0x100))
rlm@1 1164 {
rlm@1 1165 if (!dsaRatio)
rlm@1 1166 res = ((s8)soundBuffer[4][soundIndex]) >> 1;
rlm@1 1167 else
rlm@1 1168 res = ((s8)soundBuffer[4][soundIndex]);
rlm@1 1169 }
rlm@1 1170
rlm@1 1171 if ((soundControl & 0x1000) && (soundEnableFlag & 0x200))
rlm@1 1172 {
rlm@1 1173 if (!dsbRatio)
rlm@1 1174 res += ((s8)soundBuffer[5][soundIndex]) >> 1;
rlm@1 1175 else
rlm@1 1176 res += ((s8)soundBuffer[5][soundIndex]);
rlm@1 1177 }
rlm@1 1178
rlm@1 1179 res = (res * 170);
rlm@1 1180 cgbRes = (cgbRes * 52 * soundLevel1);
rlm@1 1181
rlm@1 1182 switch (ratio)
rlm@1 1183 {
rlm@1 1184 case 0:
rlm@1 1185 case 3: // prohibited, but 25%
rlm@1 1186 cgbRes >>= 2;
rlm@1 1187 break;
rlm@1 1188 case 1:
rlm@1 1189 cgbRes >>= 1;
rlm@1 1190 break;
rlm@1 1191 case 2:
rlm@1 1192 break;
rlm@1 1193 }
rlm@1 1194
rlm@1 1195 res += cgbRes;
rlm@1 1196
rlm@1 1197 if (soundEcho)
rlm@1 1198 {
rlm@1 1199 res *= 2;
rlm@1 1200 res += soundFilter[soundEchoIndex];
rlm@1 1201 res /= 2;
rlm@1 1202 soundFilter[soundEchoIndex++] = res;
rlm@1 1203
rlm@1 1204 if (soundEchoIndex >= 4000)
rlm@1 1205 soundEchoIndex = 0;
rlm@1 1206 }
rlm@1 1207
rlm@1 1208 if (soundLowPass)
rlm@1 1209 {
rlm@1 1210 soundRight[4] = soundRight[3];
rlm@1 1211 soundRight[3] = soundRight[2];
rlm@1 1212 soundRight[2] = soundRight[1];
rlm@1 1213 soundRight[1] = soundRight[0];
rlm@1 1214 soundRight[0] = res;
rlm@1 1215 res = (soundRight[4] + 2 * soundRight[3] + 8 * soundRight[2] + 2 * soundRight[1] +
rlm@1 1216 soundRight[0]) / 14;
rlm@1 1217 }
rlm@1 1218
rlm@1 1219 if (!noSpecialEffects)
rlm@1 1220 {
rlm@1 1221 switch (soundVolume)
rlm@1 1222 {
rlm@1 1223 case 0:
rlm@1 1224 case 1:
rlm@1 1225 case 2:
rlm@1 1226 case 3:
rlm@1 1227 res *= (soundVolume + 1);
rlm@1 1228 break;
rlm@1 1229 case 4:
rlm@1 1230 res >>= 2;
rlm@1 1231 break;
rlm@1 1232 case 5:
rlm@1 1233 res >>= 1;
rlm@1 1234 break;
rlm@1 1235 }
rlm@1 1236 }
rlm@1 1237
rlm@1 1238 if (res > 32767)
rlm@1 1239 res = 32767;
rlm@1 1240 if (res < -32768)
rlm@1 1241 res = -32768;
rlm@1 1242
rlm@1 1243 if (soundReverse && !noSpecialEffects)
rlm@1 1244 {
rlm@1 1245 soundFinalWave[-1 + soundBufferIndex++] = res;
rlm@1 1246 if ((soundFrameSoundWritten) >= countof(soundFrameSound))
rlm@1 1247 /*assert(false)*/;
rlm@1 1248 else
rlm@1 1249 soundFrameSound[-1 + soundFrameSoundWritten++] = res;
rlm@1 1250 }
rlm@1 1251 else
rlm@1 1252 {
rlm@1 1253 soundFinalWave[soundBufferIndex++] = res;
rlm@1 1254 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
rlm@1 1255 /*assert(false)*/;
rlm@1 1256 else
rlm@1 1257 soundFrameSound[soundFrameSoundWritten++] = res;
rlm@1 1258 }
rlm@1 1259 }
rlm@1 1260
rlm@1 1261 void soundTick()
rlm@1 1262 {
rlm@1 1263 if (systemSoundOn)
rlm@1 1264 {
rlm@1 1265 if (soundMasterOn && !stopState)
rlm@1 1266 {
rlm@1 1267 soundChannel1();
rlm@1 1268 soundChannel2();
rlm@1 1269 soundChannel3();
rlm@1 1270 soundChannel4();
rlm@1 1271 soundDirectSoundA();
rlm@1 1272 soundDirectSoundB();
rlm@1 1273 soundMix();
rlm@1 1274 }
rlm@1 1275 else
rlm@1 1276 {
rlm@1 1277 soundFinalWave[soundBufferIndex++] = 0;
rlm@1 1278 soundFinalWave[soundBufferIndex++] = 0;
rlm@1 1279 if ((soundFrameSoundWritten + 1) >= countof(soundFrameSound))
rlm@1 1280 /*assert(false)*/;
rlm@1 1281 else
rlm@1 1282 {
rlm@1 1283 soundFrameSound[soundFrameSoundWritten++] = 0;
rlm@1 1284 soundFrameSound[soundFrameSoundWritten++] = 0;
rlm@1 1285 }
rlm@1 1286 }
rlm@1 1287
rlm@1 1288 soundIndex++;
rlm@1 1289
rlm@1 1290 if (2 * soundBufferIndex >= soundBufferLen)
rlm@1 1291 {
rlm@1 1292 if (systemSoundOn)
rlm@1 1293 {
rlm@1 1294 if (soundPaused)
rlm@1 1295 {
rlm@1 1296 soundResume();
rlm@1 1297 }
rlm@1 1298
rlm@1 1299 systemSoundWriteToBuffer();
rlm@1 1300 }
rlm@1 1301 soundIndex = 0;
rlm@1 1302 soundBufferIndex = 0;
rlm@1 1303 }
rlm@1 1304 }
rlm@1 1305 }
rlm@1 1306
rlm@1 1307 void soundShutdown()
rlm@1 1308 {
rlm@1 1309 systemSoundShutdown();
rlm@1 1310 }
rlm@1 1311
rlm@1 1312 void soundPause()
rlm@1 1313 {
rlm@1 1314 systemSoundPause();
rlm@1 1315 }
rlm@1 1316
rlm@1 1317 void soundResume()
rlm@1 1318 {
rlm@1 1319 systemSoundResume();
rlm@1 1320 }
rlm@1 1321
rlm@1 1322 void soundEnableChannels(int channels)
rlm@1 1323 {
rlm@1 1324 int c = (channels & 0x0f) << 4;
rlm@1 1325 soundEnableFlag |= ((channels & 0x30f) | c);
rlm@1 1326 }
rlm@1 1327
rlm@1 1328 void soundDisableChannels(int channels)
rlm@1 1329 {
rlm@1 1330 int c = (channels & 0x0f) << 4;
rlm@1 1331 soundEnableFlag &= ~((channels & 0x30f) | c);
rlm@1 1332 }
rlm@1 1333
rlm@1 1334 int soundGetEnabledChannels()
rlm@1 1335 {
rlm@1 1336 return (soundEnableFlag & 0x30f);
rlm@1 1337 }
rlm@1 1338
rlm@1 1339 #if 0
rlm@1 1340 // unused
rlm@1 1341 void soundMuteChannels(int channels)
rlm@1 1342 {
rlm@1 1343 soundMutedFlag |= channels & 0x30f;
rlm@1 1344 }
rlm@1 1345
rlm@1 1346 void soundUnmuteChannels(int channels)
rlm@1 1347 {
rlm@1 1348 soundMutedFlag &= ~(channels & 0x30f);
rlm@1 1349 }
rlm@1 1350
rlm@1 1351 int soundGetMutedChannels()
rlm@1 1352 {
rlm@1 1353 return (soundMutedFlag & 0x30f);
rlm@1 1354 }
rlm@1 1355 #endif
rlm@1 1356
rlm@1 1357 void soundReset()
rlm@1 1358 {
rlm@1 1359 systemSoundReset();
rlm@1 1360
rlm@1 1361 soundPaused = 1;
rlm@1 1362 soundPlay = 0;
rlm@1 1363 SOUND_CLOCK_TICKS = soundQuality * USE_TICKS_AS;
rlm@1 1364 soundTicks = SOUND_CLOCK_TICKS;
rlm@1 1365 soundNextPosition = 0;
rlm@1 1366 soundMasterOn = 1;
rlm@1 1367 soundIndex = 0;
rlm@1 1368 soundBufferIndex = 0;
rlm@1 1369 soundLevel1 = 7;
rlm@1 1370 soundLevel2 = 7;
rlm@1 1371
rlm@1 1372 sound1On = 0;
rlm@1 1373 sound1ATL = 0;
rlm@1 1374 sound1Skip = 0;
rlm@1 1375 sound1Index = 0;
rlm@1 1376 sound1Continue = 0;
rlm@1 1377 sound1EnvelopeVolume = 0;
rlm@1 1378 sound1EnvelopeATL = 0;
rlm@1 1379 sound1EnvelopeUpDown = 0;
rlm@1 1380 sound1EnvelopeATLReload = 0;
rlm@1 1381 sound1SweepATL = 0;
rlm@1 1382 sound1SweepATLReload = 0;
rlm@1 1383 sound1SweepSteps = 0;
rlm@1 1384 sound1SweepUpDown = 0;
rlm@1 1385 sound1SweepStep = 0;
rlm@1 1386 sound1Wave = soundWavePattern[2];
rlm@1 1387
rlm@1 1388 sound2On = 0;
rlm@1 1389 sound2ATL = 0;
rlm@1 1390 sound2Skip = 0;
rlm@1 1391 sound2Index = 0;
rlm@1 1392 sound2Continue = 0;
rlm@1 1393 sound2EnvelopeVolume = 0;
rlm@1 1394 sound2EnvelopeATL = 0;
rlm@1 1395 sound2EnvelopeUpDown = 0;
rlm@1 1396 sound2EnvelopeATLReload = 0;
rlm@1 1397 sound2Wave = soundWavePattern[2];
rlm@1 1398
rlm@1 1399 sound3On = 0;
rlm@1 1400 sound3ATL = 0;
rlm@1 1401 sound3Skip = 0;
rlm@1 1402 sound3Index = 0;
rlm@1 1403 sound3Continue = 0;
rlm@1 1404 sound3OutputLevel = 0;
rlm@1 1405 sound3Last = 0;
rlm@1 1406 sound3Bank = 0;
rlm@1 1407 sound3DataSize = 0;
rlm@1 1408 sound3ForcedOutput = 0;
rlm@1 1409
rlm@1 1410 sound4On = 0;
rlm@1 1411 sound4Clock = 0;
rlm@1 1412 sound4ATL = 0;
rlm@1 1413 sound4Skip = 0;
rlm@1 1414 sound4Index = 0;
rlm@1 1415 sound4ShiftRight = 0x7f;
rlm@1 1416 sound4NSteps = 0;
rlm@1 1417 sound4CountDown = 0;
rlm@1 1418 sound4Continue = 0;
rlm@1 1419 sound4EnvelopeVolume = 0;
rlm@1 1420 sound4EnvelopeATL = 0;
rlm@1 1421 sound4EnvelopeUpDown = 0;
rlm@1 1422 sound4EnvelopeATLReload = 0;
rlm@1 1423
rlm@1 1424 sound1On = 0;
rlm@1 1425 sound2On = 0;
rlm@1 1426 sound3On = 0;
rlm@1 1427 sound4On = 0;
rlm@1 1428
rlm@1 1429 int addr = 0x90;
rlm@1 1430
rlm@1 1431 while (addr < 0xA0)
rlm@1 1432 {
rlm@1 1433 ioMem[addr++] = 0x00;
rlm@1 1434 ioMem[addr++] = 0xff;
rlm@1 1435 }
rlm@1 1436
rlm@1 1437 addr = 0;
rlm@1 1438 while (addr < 0x20)
rlm@1 1439 {
rlm@1 1440 sound3WaveRam[addr++] = 0x00;
rlm@1 1441 sound3WaveRam[addr++] = 0xff;
rlm@1 1442 }
rlm@1 1443
rlm@1 1444 memset(soundFinalWave, 0, soundBufferLen);
rlm@1 1445
rlm@1 1446 memset(soundFilter, 0, sizeof(soundFilter));
rlm@1 1447 soundEchoIndex = 0;
rlm@1 1448 }
rlm@1 1449
rlm@1 1450 bool soundInit()
rlm@1 1451 {
rlm@1 1452 if (systemSoundInit())
rlm@1 1453 {
rlm@1 1454 memset(soundBuffer[0], 0, 735 * 2);
rlm@1 1455 memset(soundBuffer[1], 0, 735 * 2);
rlm@1 1456 memset(soundBuffer[2], 0, 735 * 2);
rlm@1 1457 memset(soundBuffer[3], 0, 735 * 2);
rlm@1 1458
rlm@1 1459 memset(soundFinalWave, 0, soundBufferLen);
rlm@1 1460
rlm@1 1461 soundPaused = 1;
rlm@1 1462 return true;
rlm@1 1463 }
rlm@1 1464 return false;
rlm@1 1465 }
rlm@1 1466
rlm@1 1467 void soundSetQuality(int quality)
rlm@1 1468 {
rlm@1 1469 if (soundQuality != quality && systemSoundCanChangeQuality())
rlm@1 1470 {
rlm@1 1471 if (!soundOffFlag)
rlm@1 1472 soundShutdown();
rlm@1 1473 soundQuality = quality;
rlm@1 1474 soundNextPosition = 0;
rlm@1 1475 if (!soundOffFlag)
rlm@1 1476 soundInit();
rlm@1 1477 SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
rlm@1 1478 soundIndex = 0;
rlm@1 1479 soundBufferIndex = 0;
rlm@1 1480 }
rlm@1 1481 else if (soundQuality != quality)
rlm@1 1482 {
rlm@1 1483 soundNextPosition = 0;
rlm@1 1484 SOUND_CLOCK_TICKS = USE_TICKS_AS * soundQuality;
rlm@1 1485 soundIndex = 0;
rlm@1 1486 soundBufferIndex = 0;
rlm@1 1487 }
rlm@1 1488 }
rlm@1 1489
rlm@1 1490 void soundSaveGame(gzFile gzFile)
rlm@1 1491 {
rlm@1 1492 soundTicks_int32 = (int32) soundTicks;
rlm@1 1493 SOUND_CLOCK_TICKS_int32 = (int32) SOUND_CLOCK_TICKS;
rlm@1 1494 soundDSBValue_int32 = (int32) soundDSBValue;
rlm@1 1495
rlm@1 1496 utilWriteData(gzFile, soundSaveStruct);
rlm@1 1497 utilWriteData(gzFile, soundSaveStructV2);
rlm@1 1498
rlm@1 1499 utilGzWrite(gzFile, &soundQuality, sizeof(int32));
rlm@1 1500 //utilWriteData(gzFile, soundSaveStructV3);
rlm@1 1501 }
rlm@1 1502
rlm@1 1503 void soundReadGame(gzFile gzFile, int version)
rlm@1 1504 {
rlm@1 1505 int32 oldSoundPaused = soundPaused;
rlm@1 1506 int32 oldSoundEnableFlag = soundEnableFlag;
rlm@1 1507 utilReadData(gzFile, soundSaveStruct);
rlm@1 1508 soundPaused = oldSoundPaused;
rlm@1 1509 soundEnableFlag = oldSoundEnableFlag;
rlm@1 1510
rlm@1 1511 if (version >= SAVE_GAME_VERSION_3)
rlm@1 1512 {
rlm@1 1513 utilReadData(gzFile, soundSaveStructV2);
rlm@1 1514 }
rlm@1 1515 else
rlm@1 1516 {
rlm@1 1517 sound3Bank = (ioMem[NR30] >> 6) & 1;
rlm@1 1518 sound3DataSize = (ioMem[NR30] >> 5) & 1;
rlm@1 1519 sound3ForcedOutput = (ioMem[NR32] >> 7) & 1;
rlm@1 1520 // nothing better to do here...
rlm@1 1521 memcpy(&sound3WaveRam[0x00], &ioMem[0x90], 0x10);
rlm@1 1522 memcpy(&sound3WaveRam[0x10], &ioMem[0x90], 0x10);
rlm@1 1523 }
rlm@1 1524 soundBufferIndex = soundIndex * 2;
rlm@1 1525
rlm@1 1526 int quality = 1;
rlm@1 1527 utilGzRead(gzFile, &quality, sizeof(int32));
rlm@1 1528 soundSetQuality(quality);
rlm@1 1529
rlm@1 1530 sound1Wave = soundWavePattern[ioMem[NR11] >> 6];
rlm@1 1531 sound2Wave = soundWavePattern[ioMem[NR21] >> 6];
rlm@1 1532
rlm@1 1533 //if(version >= SAVE_GAME_VERSION_14) {
rlm@1 1534 // utilReadData(gzFile, soundSaveStructV3);
rlm@1 1535 //}
rlm@1 1536 //else {
rlm@1 1537 soundTicks = (soundtick_t) soundTicks_int32;
rlm@1 1538 SOUND_CLOCK_TICKS = (soundtick_t) SOUND_CLOCK_TICKS_int32;
rlm@1 1539 //}
rlm@1 1540 soundDSBValue = (u8) (soundDSBValue_int32 & 0xff);
rlm@1 1541 }
rlm@1 1542