Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-2-2013-Decompilation
Path: blob/main/RSDKv4/Audio.hpp
817 views
1
#ifndef AUDIO_H
2
#define AUDIO_H
3
4
#define TRACK_COUNT (0x10)
5
#define SFX_COUNT (0x100)
6
#if !RETRO_USE_ORIGINAL_CODE
7
#define CHANNEL_COUNT (0x10) // 4 in the original, 16 for convenience
8
#else
9
#define CHANNEL_COUNT (0x4)
10
#endif
11
12
#define MAX_VOLUME (100)
13
14
#define MUSBUFFER_SIZE (0x200000)
15
#define STREAMFILE_COUNT (2)
16
17
#define MIX_BUFFER_SAMPLES (256)
18
19
#if RETRO_USING_SDL1 || RETRO_USING_SDL2
20
21
#define LockAudioDevice() SDL_LockAudio()
22
#define UnlockAudioDevice() SDL_UnlockAudio()
23
24
#else
25
#define LockAudioDevice() ;
26
#define UnlockAudioDevice() ;
27
#endif
28
29
struct TrackInfo {
30
char fileName[0x40];
31
bool trackLoop;
32
uint loopPoint;
33
};
34
35
struct StreamInfo {
36
OggVorbis_File vorbisFile;
37
int vorbBitstream;
38
#if RETRO_USING_SDL1
39
SDL_AudioSpec spec;
40
#endif
41
#if RETRO_USING_SDL2
42
SDL_AudioStream *stream;
43
#endif
44
Sint16 buffer[MIX_BUFFER_SAMPLES];
45
bool trackLoop;
46
uint loopPoint;
47
bool loaded;
48
};
49
50
struct SFXInfo {
51
char name[0x40];
52
Sint16 *buffer;
53
size_t length;
54
bool loaded;
55
};
56
57
struct ChannelInfo {
58
size_t sampleLength;
59
Sint16 *samplePtr;
60
int sfxID;
61
byte loopSFX;
62
sbyte pan;
63
};
64
65
struct StreamFile {
66
byte buffer[MUSBUFFER_SIZE];
67
int fileSize;
68
int filePos;
69
};
70
71
enum MusicStatuses {
72
MUSIC_STOPPED = 0,
73
MUSIC_PLAYING = 1,
74
MUSIC_PAUSED = 2,
75
MUSIC_LOADING = 3,
76
MUSIC_READY = 4,
77
};
78
79
extern int globalSFXCount;
80
extern int stageSFXCount;
81
82
extern int masterVolume;
83
extern int trackID;
84
extern int sfxVolume;
85
extern int bgmVolume;
86
extern bool audioEnabled;
87
88
extern bool musicEnabled;
89
extern int musicStatus;
90
extern int musicStartPos;
91
extern int musicPosition;
92
extern int musicRatio;
93
extern TrackInfo musicTracks[TRACK_COUNT];
94
95
extern int currentStreamIndex;
96
extern StreamFile streamFile[STREAMFILE_COUNT];
97
extern StreamInfo streamInfo[STREAMFILE_COUNT];
98
extern StreamFile *streamFilePtr;
99
extern StreamInfo *streamInfoPtr;
100
101
extern SFXInfo sfxList[SFX_COUNT];
102
extern char sfxNames[SFX_COUNT][0x40];
103
104
extern ChannelInfo sfxChannels[CHANNEL_COUNT];
105
106
#if RETRO_USING_SDL1 || RETRO_USING_SDL2
107
extern SDL_AudioSpec audioDeviceFormat;
108
#endif
109
110
int InitAudioPlayback();
111
void LoadGlobalSfx();
112
113
#if RETRO_USING_SDL1 || RETRO_USING_SDL2
114
#if !RETRO_USE_ORIGINAL_CODE
115
// These functions did exist, but with different signatures
116
void ProcessMusicStream(Sint32 *stream, size_t bytes_wanted);
117
void ProcessAudioPlayback(void *data, Uint8 *stream, int len);
118
void ProcessAudioMixing(Sint32 *dst, const Sint16 *src, int len, int volume, sbyte pan);
119
#endif
120
121
#if !RETRO_USE_ORIGINAL_CODE
122
inline void FreeMusInfo()
123
{
124
LockAudioDevice();
125
126
#if RETRO_USING_SDL2
127
if (streamInfo[currentStreamIndex].stream)
128
SDL_FreeAudioStream(streamInfo[currentStreamIndex].stream);
129
streamInfo[currentStreamIndex].stream = NULL;
130
#endif
131
132
ov_clear(&streamInfo[currentStreamIndex].vorbisFile);
133
134
#if RETRO_USING_SDL2
135
streamInfo[currentStreamIndex].stream = nullptr;
136
#endif
137
138
UnlockAudioDevice();
139
}
140
#endif
141
#else
142
void ProcessMusicStream() {}
143
void ProcessAudioPlayback() {}
144
void ProcessAudioMixing() {}
145
146
#if !RETRO_USE_ORIGINAL_CODE
147
inline void FreeMusInfo() { ov_clear(&streamInfo[currentStreamIndex].vorbisFile); }
148
#endif
149
#endif
150
151
void LoadMusic(void *userdata);
152
void SetMusicTrack(const char *filePath, byte trackID, bool loop, uint loopPoint);
153
void SwapMusicTrack(const char *filePath, byte trackID, uint loopPoint, uint ratio);
154
bool PlayMusic(int track, int musStartPos);
155
inline void StopMusic(bool setStatus)
156
{
157
if (setStatus)
158
musicStatus = MUSIC_STOPPED;
159
musicPosition = 0;
160
161
#if !RETRO_USE_ORIGINAL_CODE
162
LockAudioDevice();
163
FreeMusInfo();
164
UnlockAudioDevice();
165
#endif
166
}
167
168
void LoadSfx(char *filePath, byte sfxID);
169
void PlaySfx(int sfx, bool loop);
170
inline void StopSfx(int sfx)
171
{
172
for (int i = 0; i < CHANNEL_COUNT; ++i) {
173
if (sfxChannels[i].sfxID == sfx) {
174
MEM_ZERO(sfxChannels[i]);
175
sfxChannels[i].sfxID = -1;
176
}
177
}
178
}
179
void SetSfxAttributes(int sfx, int loopCount, sbyte pan);
180
181
void SetSfxName(const char *sfxName, int sfxID);
182
183
#if !RETRO_USE_ORIGINAL_CODE
184
// Helper Funcs
185
inline bool PlaySfxByName(const char *sfx, sbyte loopCnt)
186
{
187
char buffer[0x40];
188
int pos = 0;
189
while (*sfx) {
190
if (*sfx != ' ')
191
buffer[pos++] = *sfx;
192
sfx++;
193
}
194
buffer[pos] = 0;
195
196
for (int s = 0; s < globalSFXCount + stageSFXCount; ++s) {
197
if (StrComp(sfxNames[s], buffer)) {
198
PlaySfx(s, loopCnt);
199
return true;
200
}
201
}
202
return false;
203
}
204
inline bool StopSFXByName(const char *sfx)
205
{
206
char buffer[0x40];
207
int pos = 0;
208
while (*sfx) {
209
if (*sfx != ' ')
210
buffer[pos++] = *sfx;
211
sfx++;
212
}
213
buffer[pos] = 0;
214
215
for (int s = 0; s < globalSFXCount + stageSFXCount; ++s) {
216
if (StrComp(sfxNames[s], buffer)) {
217
StopSfx(s);
218
return true;
219
}
220
}
221
return false;
222
}
223
#endif
224
225
inline void SetMusicVolume(int volume)
226
{
227
if (volume < 0)
228
volume = 0;
229
if (volume > MAX_VOLUME)
230
volume = MAX_VOLUME;
231
232
masterVolume = volume;
233
}
234
235
inline void SetGameVolumes(int bgmVol, int sfxVol)
236
{
237
bgmVolume = bgmVol;
238
sfxVolume = sfxVol;
239
240
if (bgmVolume < 0)
241
bgmVolume = 0;
242
if (bgmVolume > MAX_VOLUME)
243
bgmVolume = MAX_VOLUME;
244
245
if (sfxVolume < 0)
246
sfxVolume = 0;
247
if (sfxVolume > MAX_VOLUME)
248
sfxVolume = MAX_VOLUME;
249
}
250
251
inline bool PauseSound()
252
{
253
if (musicStatus == MUSIC_PLAYING) {
254
musicStatus = MUSIC_PAUSED;
255
return true;
256
}
257
return false;
258
}
259
260
inline void ResumeSound()
261
{
262
if (musicStatus == MUSIC_PAUSED)
263
musicStatus = MUSIC_PLAYING;
264
}
265
266
inline void StopAllSfx()
267
{
268
#if !RETRO_USE_ORIGINAL_CODE
269
LockAudioDevice();
270
#endif
271
272
for (int i = 0; i < CHANNEL_COUNT; ++i) sfxChannels[i].sfxID = -1;
273
274
#if !RETRO_USE_ORIGINAL_CODE
275
UnlockAudioDevice();
276
#endif
277
}
278
inline void ReleaseGlobalSfx()
279
{
280
for (int i = globalSFXCount - 1; i >= 0; --i) {
281
if (sfxList[i].loaded) {
282
StrCopy(sfxList[i].name, "");
283
StrCopy(sfxNames[i], "");
284
if (sfxList[i].buffer)
285
free(sfxList[i].buffer);
286
287
sfxList[i].buffer = NULL;
288
sfxList[i].length = 0;
289
sfxList[i].loaded = false;
290
}
291
}
292
293
globalSFXCount = 0;
294
}
295
inline void ReleaseStageSfx()
296
{
297
for (int i = (stageSFXCount + globalSFXCount) - 1; i >= globalSFXCount; --i) {
298
if (sfxList[i].loaded) {
299
StrCopy(sfxList[i].name, "");
300
StrCopy(sfxNames[i], "");
301
if (sfxList[i].buffer)
302
free(sfxList[i].buffer);
303
304
sfxList[i].buffer = NULL;
305
sfxList[i].length = 0;
306
sfxList[i].loaded = false;
307
}
308
}
309
310
stageSFXCount = 0;
311
}
312
313
inline void ReleaseAudioDevice()
314
{
315
StopMusic(true);
316
StopAllSfx();
317
ReleaseStageSfx();
318
ReleaseGlobalSfx();
319
}
320
321
#endif // !AUDIO_H
322
323