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
|