1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-22 09:39:43 +01:00

Load and unload music files as needed

When VVVVVV is run on devices (such as the Nintendo Wii) that are memory
costrained, it's not possible to load all the music files at startup.

Therefore, change the MusicTrack contructor to only save the RWops
structure, and load the music data only when Play() gets called. Also,
when a song start playing we do unload the previous one.
This commit is contained in:
Alberto Mardegan 2024-01-23 18:38:28 +03:00
parent 448c4a5514
commit 349ab399dc

View file

@ -372,9 +372,20 @@ float SoundTrack::volume = 0.0f;
class MusicTrack class MusicTrack
{ {
public: public:
MusicTrack(SDL_RWops *rw) MusicTrack(SDL_RWops *rw, bool autoload = true)
{ {
SDL_zerop(this); SDL_zerop(this);
this->rw = rw;
this->autoload = autoload;
if (autoload)
{
Load();
}
}
void Load(void)
{
loaded = true;
read_buf = (Uint8*) SDL_malloc(rw->size(rw)); read_buf = (Uint8*) SDL_malloc(rw->size(rw));
SDL_RWread(rw, read_buf, rw->size(rw), 1); SDL_RWread(rw, read_buf, rw->size(rw), 1);
int err; int err;
@ -385,7 +396,7 @@ public:
{ {
vlog_error("Unable to create Vorbis handle, error %d", err); vlog_error("Unable to create Vorbis handle, error %d", err);
VVV_free(read_buf); VVV_free(read_buf);
goto end; return;
} }
vorbis_info = stb_vorbis_get_info(vorbis); vorbis_info = stb_vorbis_get_info(vorbis);
format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT; format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
@ -407,25 +418,54 @@ public:
vorbis_comment = stb_vorbis_get_comment(vorbis); vorbis_comment = stb_vorbis_get_comment(vorbis);
parseComments(this, vorbis_comment.comment_list, vorbis_comment.comment_list_length); parseComments(this, vorbis_comment.comment_list, vorbis_comment.comment_list_length);
valid = true; valid = true;
end:
SDL_RWclose(rw);
} }
void Dispose(void) void Unload(void)
{ {
if (!loaded)
{
return;
}
VVV_freefunc(stb_vorbis_close, vorbis); VVV_freefunc(stb_vorbis_close, vorbis);
VVV_free(read_buf); VVV_free(read_buf);
VVV_free(decoded_buf_playing); VVV_free(decoded_buf_playing);
VVV_free(decoded_buf_reserve); VVV_free(decoded_buf_reserve);
/* The song might get loaded again, so reset the read cursor */
SDL_RWseek(rw, 0, RW_SEEK_SET);
loaded = false;
}
void Dispose(void)
{
if (loaded)
{
Unload();
}
if (!IsHalted()) if (!IsHalted())
{ {
VVV_freefunc(FAudioVoice_DestroyVoice, musicVoice); VVV_freefunc(FAudioVoice_DestroyVoice, musicVoice);
} }
SDL_RWclose(rw);
} }
bool Play(bool loop) bool Play(bool loop)
{ {
Halt();
if (currentTrack != this)
{
if (currentTrack && !currentTrack->autoload)
{
currentTrack->Unload();
}
currentTrack = this;
}
if (!loaded)
{
Load();
}
if (!valid) if (!valid)
{ {
return false; return false;
@ -435,8 +475,6 @@ end:
sample_pos = 0; sample_pos = 0;
stb_vorbis_seek_start(vorbis); stb_vorbis_seek_start(vorbis);
Halt();
SDL_zero(callbacks); SDL_zero(callbacks);
callbacks.OnBufferStart = &MusicTrack::refillReserve; callbacks.OnBufferStart = &MusicTrack::refillReserve;
callbacks.OnBufferEnd = &MusicTrack::swapBuffers; callbacks.OnBufferEnd = &MusicTrack::swapBuffers;
@ -513,6 +551,7 @@ end:
} }
} }
SDL_RWops *rw;
stb_vorbis* vorbis; stb_vorbis* vorbis;
int channels; int channels;
Uint32 size; Uint32 size;
@ -527,9 +566,12 @@ end:
Uint8* decoded_buf_reserve; Uint8* decoded_buf_reserve;
Uint8* read_buf; Uint8* read_buf;
bool shouldloop; bool shouldloop;
bool loaded;
bool valid; bool valid;
bool autoload;
static bool paused; static bool paused;
static MusicTrack *currentTrack;
static FAudioSourceVoice* musicVoice; static FAudioSourceVoice* musicVoice;
static void refillReserve(FAudioVoiceCallback* callback, void* ctx) static void refillReserve(FAudioVoiceCallback* callback, void* ctx)
@ -709,6 +751,7 @@ end:
}; };
bool MusicTrack::paused = false; bool MusicTrack::paused = false;
FAudioSourceVoice* MusicTrack::musicVoice = NULL; FAudioSourceVoice* MusicTrack::musicVoice = NULL;
MusicTrack* MusicTrack::currentTrack = NULL;
musicclass::musicclass(void) musicclass::musicclass(void)
{ {
@ -833,7 +876,7 @@ void musicclass::init(void)
} \ } \
else \ else \
{ \ { \
musicTracks.push_back(MusicTrack(rw)); \ musicTracks.push_back(MusicTrack(rw, false)); \
} }
TRACK_NAMES(_) TRACK_NAMES(_)