Skip to content
This repository was archived by the owner on Jun 28, 2025. It is now read-only.

Commit 57bd673

Browse files
committed
Preload 3DO sounds
1 parent 733c41a commit 57bd673

File tree

6 files changed

+71
-26
lines changed

6 files changed

+71
-26
lines changed

mixer.cpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <SDL.h>
88
#define MIX_INIT_FLUIDSYNTH MIX_INIT_MID // renamed with SDL2_mixer >= 2.0.2
99
#include <SDL_mixer.h>
10+
#include <map>
1011
#include "aifcplayer.h"
1112
#include "mixer.h"
1213
#include "sfxplayer.h"
@@ -126,6 +127,7 @@ struct Mixer_impl {
126127
Mix_Music *_music;
127128
MixerChannel _channels[kMixChannels]; // 0,3:left 1,2:right
128129
SfxPlayer *_sfx;
130+
std::map<int, Mix_Chunk *> _preloads; // AIFF preloads (3DO)
129131

130132
void init(bool softwareMixer) {
131133
memset(_sounds, 0, sizeof(_sounds));
@@ -168,12 +170,6 @@ struct Mixer_impl {
168170
Mix_Chunk *chunk = loadAndConvertWav(rw, 1, freq, kMixFormat, kMixSoundChannels, kMixFreq);
169171
playSound(channel, volume, chunk, loops);
170172
}
171-
void playSoundAiff(uint8_t channel, const uint8_t *data, uint8_t volume) {
172-
const uint32_t size = READ_BE_UINT32(data + 4) + 8;
173-
SDL_RWops *rw = SDL_RWFromConstMem(data, size);
174-
Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1);
175-
playSound(channel, volume, chunk);
176-
}
177173
void playSound(uint8_t channel, int volume, Mix_Chunk *chunk, int loops = 0) {
178174
stopSound(channel);
179175
if (chunk) {
@@ -267,6 +263,32 @@ struct Mixer_impl {
267263
}
268264
stopMusic();
269265
stopSfxMusic();
266+
for (std::map<int, Mix_Chunk *>::iterator it = _preloads.begin(); it != _preloads.end(); ++it) {
267+
debug(DBG_SND, "Flush preload %d", it->first);
268+
Mix_FreeChunk(it->second);
269+
}
270+
_preloads.clear();
271+
}
272+
273+
void preloadSoundAiff(int num, const uint8_t *data) {
274+
if (_preloads.find(num) != _preloads.end()) {
275+
warning("AIFF sound %d is already preloaded", num);
276+
} else {
277+
const uint32_t size = READ_BE_UINT32(data + 4) + 8;
278+
SDL_RWops *rw = SDL_RWFromConstMem(data, size);
279+
Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1);
280+
_preloads[num] = chunk;
281+
}
282+
}
283+
284+
void playSoundAiff(int channel, int num, int volume) {
285+
if (_preloads.find(num) == _preloads.end()) {
286+
warning("AIFF sound %d is not preloaded", num);
287+
} else {
288+
Mix_Chunk *chunk = _preloads[num];
289+
Mix_PlayChannel(channel, chunk, 0);
290+
Mix_Volume(channel, volume * MIX_MAX_VOLUME / 63);
291+
}
270292
}
271293
};
272294

@@ -308,13 +330,6 @@ void Mixer::playSoundWav(uint8_t channel, const uint8_t *data, uint16_t freq, ui
308330
}
309331
}
310332

311-
void Mixer::playSoundAiff(uint8_t channel, const uint8_t *data, uint8_t volume) {
312-
debug(DBG_SND, "Mixer::playSoundAiff(%d, %d)", channel, volume);
313-
if (_impl) {
314-
return _impl->playSoundAiff(channel, data, volume);
315-
}
316-
}
317-
318333
void Mixer::stopSound(uint8_t channel) {
319334
debug(DBG_SND, "Mixer::stopChannel(%d)", channel);
320335
if (_impl) {
@@ -384,3 +399,17 @@ void Mixer::stopAll() {
384399
return _impl->stopAll();
385400
}
386401
}
402+
403+
void Mixer::preloadSoundAiff(uint8_t num, const uint8_t *data) {
404+
debug(DBG_SND, "Mixer::preloadSoundAiff(num:%d, data:%p)", num, data);
405+
if (_impl) {
406+
return _impl->preloadSoundAiff(num, data);
407+
}
408+
}
409+
410+
void Mixer::playSoundAiff(uint8_t channel, uint8_t num, uint8_t volume) {
411+
debug(DBG_SND, "Mixer::playSoundAiff()");
412+
if (_impl) {
413+
return _impl->playSoundAiff(channel, num, volume);
414+
}
415+
}

mixer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ struct Mixer {
2525

2626
void playSoundRaw(uint8_t channel, const uint8_t *data, uint16_t freq, uint8_t volume);
2727
void playSoundWav(uint8_t channel, const uint8_t *data, uint16_t freq, uint8_t volume, uint8_t loop);
28-
void playSoundAiff(uint8_t channel, const uint8_t *data, uint8_t volume);
2928
void stopSound(uint8_t channel);
3029
void setChannelVolume(uint8_t channel, uint8_t volume);
3130
void playMusic(const char *path, uint8_t loop);
@@ -35,6 +34,8 @@ struct Mixer {
3534
void playSfxMusic(int num);
3635
void stopSfxMusic();
3736
void stopAll();
37+
void preloadSoundAiff(uint8_t num, const uint8_t *data);
38+
void playSoundAiff(uint8_t channel, uint8_t num, uint8_t volume);
3839
};
3940

4041
#endif

resource.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ static const int _memListBmp[] = {
408408
145, 144, 73, 72, 70, 69, 68, 67, -1
409409
};
410410

411-
void Resource::update(uint16_t num) {
411+
void Resource::update(uint16_t num, PreloadSoundProc preloadSound, void *data) {
412412
if (num > 16000) {
413413
_nextPart = num;
414414
return;
@@ -439,7 +439,11 @@ void Resource::update(uint16_t num) {
439439
if (num >= 2000) { // preload sounds
440440
const uint8_t *soundsList = getSoundsList3DO(num);
441441
for (int i = 0; soundsList[i] != 255; ++i) {
442-
loadDat(soundsList[i]);
442+
const int soundNum = soundsList[i];
443+
loadDat(soundNum);
444+
if (_memList[soundNum].status == STATUS_LOADED) {
445+
preloadSound(data, soundNum, _memList[soundNum].bufPtr);
446+
}
443447
}
444448
} else if (num >= 200) {
445449
loadBmp(num);

resource.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ struct ResourceWin31;
6464
struct Resource3do;
6565
struct Video;
6666

67+
typedef void (*PreloadSoundProc)(void *userdata, int num, const uint8_t *data);
68+
6769
struct Resource {
70+
6871
enum ResType {
6972
RT_SOUND = 0,
7073
RT_MUSIC = 1,
@@ -137,7 +140,7 @@ struct Resource {
137140
void load();
138141
void invalidateAll();
139142
void invalidateRes();
140-
void update(uint16_t num);
143+
void update(uint16_t num, PreloadSoundProc, void *);
141144
void loadBmp(int num);
142145
uint8_t *loadDat(int num);
143146
void loadFont();

script.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ void Script::op_playSound() {
354354
snd_playSound(resNum, freq, vol, channel);
355355
}
356356

357+
static void preloadSoundCb(void *userdata, int soundNum, const uint8_t *data) {
358+
((Script *)userdata)->snd_preloadSound(soundNum, data);
359+
}
360+
357361
void Script::op_updateResources() {
358362
uint16_t num = _scriptPtr.fetchWord();
359363
debug(DBG_SCRIPT, "Script::op_updateResources(%d)", num);
@@ -362,7 +366,7 @@ void Script::op_updateResources() {
362366
_mix->stopAll();
363367
_res->invalidateRes();
364368
} else {
365-
_res->update(num);
369+
_res->update(num, preloadSoundCb, this);
366370
}
367371
}
368372

@@ -748,6 +752,7 @@ void Script::snd_playSound(uint16_t resNum, uint8_t freq, uint8_t vol, uint8_t c
748752
if (freq > 39) {
749753
freq = 39;
750754
}
755+
channel &= 3;
751756
switch (_res->getDataType()) {
752757
case Resource::DT_20TH_EDITION:
753758
if (freq != 0) {
@@ -758,24 +763,20 @@ void Script::snd_playSound(uint16_t resNum, uint8_t freq, uint8_t vol, uint8_t c
758763
case Resource::DT_WIN31: {
759764
uint8_t *buf = _res->loadWav(resNum);
760765
if (buf) {
761-
_mix->playSoundWav(channel & 3, buf, getSoundFreq(freq), vol, getWavLooping(resNum));
766+
_mix->playSoundWav(channel, buf, getSoundFreq(freq), vol, getWavLooping(resNum));
762767
}
763768
}
764769
break;
765-
case Resource::DT_3DO: {
766-
MemEntry *me = &_res->_memList[resNum];
767-
if (me->status == Resource::STATUS_LOADED) {
768-
_mix->playSoundAiff(channel & 3, me->bufPtr, vol);
769-
}
770-
}
770+
case Resource::DT_3DO:
771+
_mix->playSoundAiff(channel, resNum, vol);
771772
break;
772773
case Resource::DT_AMIGA:
773774
case Resource::DT_ATARI:
774775
case Resource::DT_ATARI_DEMO:
775776
case Resource::DT_DOS: {
776777
MemEntry *me = &_res->_memList[resNum];
777778
if (me->status == Resource::STATUS_LOADED) {
778-
_mix->playSoundRaw(channel & 3, me->bufPtr, getSoundFreq(freq), vol);
779+
_mix->playSoundRaw(channel, me->bufPtr, getSoundFreq(freq), vol);
779780
}
780781
}
781782
break;
@@ -831,6 +832,12 @@ void Script::snd_playMusic(uint16_t resNum, uint16_t delay, uint8_t pos) {
831832
}
832833
}
833834

835+
void Script::snd_preloadSound(uint16_t resNum, const uint8_t *data) {
836+
if (_res->getDataType() == Resource::DT_3DO) {
837+
_mix->preloadSoundAiff(resNum, data);
838+
}
839+
}
840+
834841
void Script::fixUpPalette_changeScreen(int part, int screen) {
835842
int pal = -1;
836843
switch (part) {

script.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct Script {
109109

110110
void snd_playSound(uint16_t resNum, uint8_t freq, uint8_t vol, uint8_t channel);
111111
void snd_playMusic(uint16_t resNum, uint16_t delay, uint8_t pos);
112+
void snd_preloadSound(uint16_t resNum, const uint8_t *data);
112113

113114
void fixUpPalette_changeScreen(int part, int screen);
114115
};

0 commit comments

Comments
 (0)