5
5
#include " fmt.h"
6
6
#if defined(YGOPRO_USE_IRRKLANG)
7
7
#include " SoundBackends/irrklang/sound_irrklang.h"
8
- #define BACKEND SoundIrrklang
9
- #elif defined(YGOPRO_USE_SDL_MIXER)
8
+ #endif
9
+ #if defined(YGOPRO_USE_SDL_MIXER)
10
10
#include " SoundBackends/sdlmixer/sound_sdlmixer.h"
11
- #define BACKEND SoundMixer
12
- #elif defined(YGOPRO_USE_SFML)
11
+ #endif
12
+ #if defined(YGOPRO_USE_SFML)
13
13
#include " SoundBackends/sfml/sound_sfml.h"
14
- #define BACKEND SoundSFML
15
- #elif defined(YGOPRO_USE_MINIAUDIO)
14
+ #endif
15
+ #if defined(YGOPRO_USE_MINIAUDIO)
16
16
#include " SoundBackends/miniaudio/sound_miniaudio.h"
17
- #define BACKEND SoundMiniaudio
18
17
#endif
19
18
20
19
namespace ygo {
21
- SoundManager::SoundManager (double sounds_volume, double music_volume, bool sounds_enabled, bool music_enabled) {
22
- #ifdef BACKEND
23
- epro::print (" Using: " STR (BACKEND)" for audio playback.\n " );
20
+ namespace {
21
+ std::unique_ptr<SoundBackend> make_backend (SoundManager::BACKEND backend) {
22
+ switch (backend) {
23
+ #ifdef YGOPRO_USE_IRRKLANG
24
+ case SoundManager::IRRKLANG:
25
+ return std::make_unique<SoundIrrklang>();
26
+ #endif
27
+ #ifdef YGOPRO_USE_SDL_MIXER
28
+ case SoundManager::SDL:
29
+ return std::make_unique<SoundMixer>();
30
+ #endif
31
+ #ifdef YGOPRO_USE_SFML
32
+ case SoundManager::SFML:
33
+ return std::make_unique<SoundSFML>();
34
+ #endif
35
+ #ifdef YGOPRO_USE_MINIAUDIO
36
+ case SoundManager::MINIAUDIO:
37
+ return std::make_unique<SoundMiniaudio>();
38
+ #endif
39
+ default :
40
+ epro::print (" Backend not compiled in.\n " );
41
+ [[fallthrough]];
42
+ case SoundManager::NONE:
43
+ return nullptr ;
44
+ }
45
+ }
46
+ }
47
+
48
+ SoundManager::SoundManager (double sounds_volume, double music_volume, bool sounds_enabled, bool music_enabled, BACKEND backend) {
49
+ epro::print (" Using: {} for audio playback.\n " , backend);
50
+ if (backend == NONE) {
51
+ soundsEnabled = musicEnabled = false ;
52
+ return ;
53
+ }
24
54
working_dir = Utils::ToUTF8IfNeeded (Utils::GetWorkingDirectory ());
25
55
soundsEnabled = sounds_enabled;
26
56
musicEnabled = music_enabled;
27
57
try {
28
- auto tmp_mixer = std::make_unique<BACKEND>();
58
+ auto tmp_mixer = make_backend (backend);
59
+ if (!tmp_mixer) {
60
+ epro::print (" Failed to initialize audio backend:\n " );
61
+ soundsEnabled = musicEnabled = false ;
62
+ return ;
63
+ }
29
64
tmp_mixer->SetMusicVolume (music_volume);
30
65
tmp_mixer->SetSoundVolume (sounds_volume);
31
66
mixer = std::move (tmp_mixer);
@@ -46,19 +81,13 @@ SoundManager::SoundManager(double sounds_volume, double music_volume, bool sound
46
81
RefreshBGMList ();
47
82
RefreshSoundsList ();
48
83
RefreshChantsList ();
49
- #else
50
- epro::print (" No audio backend available.\n Audio will be disabled.\n " );
51
- soundsEnabled = musicEnabled = false ;
52
- return ;
53
- #endif // BACKEND
54
84
}
55
85
bool SoundManager::IsUsable () {
56
86
return mixer != nullptr ;
57
87
}
58
88
void SoundManager::RefreshBGMList () {
59
89
if (!IsUsable ())
60
90
return ;
61
- #ifdef BACKEND
62
91
Utils::MakeDirectory (EPRO_TEXT (" ./sound/BGM/" ));
63
92
Utils::MakeDirectory (EPRO_TEXT (" ./sound/BGM/duel" ));
64
93
Utils::MakeDirectory (EPRO_TEXT (" ./sound/BGM/menu" ));
@@ -77,12 +106,10 @@ void SoundManager::RefreshBGMList() {
77
106
RefreshBGMDir (EPRO_TEXT (" disadvantage" ), BGM::DISADVANTAGE);
78
107
RefreshBGMDir (EPRO_TEXT (" win" ), BGM::WIN);
79
108
RefreshBGMDir (EPRO_TEXT (" lose" ), BGM::LOSE);
80
- #endif
81
109
}
82
110
void SoundManager::RefreshSoundsList () {
83
111
if (!IsUsable ())
84
112
return ;
85
- #ifdef BACKEND
86
113
static constexpr std::pair<SFX, epro::path_stringview> fx[]{
87
114
{SUMMON, EPRO_TEXT (" ./sound/summon.{}" sv)},
88
115
{SPECIAL_SUMMON, EPRO_TEXT (" ./sound/specialsummon.{}" sv)},
@@ -119,23 +146,19 @@ void SoundManager::RefreshSoundsList() {
119
146
}
120
147
}
121
148
}
122
- #endif
123
149
}
124
150
void SoundManager::RefreshBGMDir (epro::path_stringview path, BGM scene) {
125
151
if (!IsUsable ())
126
152
return ;
127
- #ifdef BACKEND
128
153
for (auto & file : Utils::FindFiles (epro::format (EPRO_TEXT (" ./sound/BGM/{}" ), path), mixer->GetSupportedMusicExtensions ())) {
129
154
auto conv = Utils::ToUTF8IfNeeded (epro::format (EPRO_TEXT (" {}/{}" ), path, file));
130
155
BGMList[BGM::ALL].push_back (conv);
131
156
BGMList[scene].push_back (std::move (conv));
132
157
}
133
- #endif
134
158
}
135
159
void SoundManager::RefreshChantsList () {
136
160
if (!IsUsable ())
137
161
return ;
138
- #ifdef BACKEND
139
162
static constexpr std::pair<CHANT, epro::path_stringview> types[]{
140
163
{CHANT::SUMMON, EPRO_TEXT (" summon" sv)},
141
164
{CHANT::ATTACK, EPRO_TEXT (" attack" sv)},
@@ -158,23 +181,19 @@ void SoundManager::RefreshChantsList() {
158
181
}
159
182
}
160
183
}
161
- #endif
162
184
}
163
185
void SoundManager::PlaySoundEffect (SFX sound) {
164
186
if (!IsUsable ())
165
187
return ;
166
- #ifdef BACKEND
167
188
if (!soundsEnabled) return ;
168
189
if (sound >= SFX::SFX_TOTAL_SIZE) return ;
169
190
const auto & soundfile = SFXList[sound];
170
191
if (soundfile.empty ()) return ;
171
192
mixer->PlaySound (soundfile);
172
- #endif
173
193
}
174
194
void SoundManager::PlayBGM (BGM scene, bool loop) {
175
195
if (!IsUsable ())
176
196
return ;
177
- #ifdef BACKEND
178
197
if (!musicEnabled)
179
198
return ;
180
199
auto & list = BGMList[scene];
@@ -194,80 +213,59 @@ void SoundManager::PlayBGM(BGM scene, bool loop) {
194
213
currentlyLooping = loop;
195
214
mixer->LoopMusic (loop);
196
215
}
197
- #endif
198
216
}
199
217
bool SoundManager::PlayChant (CHANT chant, uint32_t code) {
200
218
if (!IsUsable ())
201
219
return false ;
202
- #ifdef BACKEND
203
220
if (!soundsEnabled) return false ;
204
221
auto key = std::make_pair (chant, code);
205
222
auto chant_it = ChantsList.find (key);
206
223
if (chant_it == ChantsList.end ())
207
224
return false ;
208
225
return mixer->PlaySound (chant_it->second );
209
- #else
210
- return false ;
211
- #endif
212
226
}
213
227
void SoundManager::SetSoundVolume (double volume) {
214
228
if (!IsUsable ())
215
229
return ;
216
- #ifdef BACKEND
217
230
mixer->SetSoundVolume (volume);
218
- #endif
219
231
}
220
232
void SoundManager::SetMusicVolume (double volume) {
221
233
if (!IsUsable ())
222
234
return ;
223
- #ifdef BACKEND
224
235
mixer->SetMusicVolume (volume);
225
- #endif
226
236
}
227
237
void SoundManager::EnableSounds (bool enable) {
228
238
if (!IsUsable ())
229
239
return ;
230
- #ifdef BACKEND
231
240
if (!(soundsEnabled = enable))
232
241
mixer->StopSounds ();
233
- #endif
234
242
}
235
243
void SoundManager::EnableMusic (bool enable) {
236
244
if (!IsUsable ())
237
245
return ;
238
- #ifdef BACKEND
239
246
if (!(musicEnabled = enable))
240
247
mixer->StopMusic ();
241
- #endif
242
248
}
243
249
void SoundManager::StopSounds () {
244
250
if (!IsUsable ())
245
251
return ;
246
- #ifdef BACKEND
247
252
mixer->StopSounds ();
248
- #endif
249
253
}
250
254
void SoundManager::StopMusic () {
251
255
if (!IsUsable ())
252
256
return ;
253
- #ifdef BACKEND
254
257
mixer->StopMusic ();
255
- #endif
256
258
}
257
259
void SoundManager::PauseMusic (bool pause) {
258
260
if (!IsUsable ())
259
261
return ;
260
- #ifdef BACKEND
261
262
mixer->PauseMusic (pause );
262
- #endif
263
263
}
264
264
265
265
void SoundManager::Tick () {
266
266
if (!IsUsable ())
267
267
return ;
268
- #ifdef BACKEND
269
268
mixer->Tick ();
270
- #endif
271
269
}
272
270
273
271
} // namespace ygo
0 commit comments