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:
parent
448c4a5514
commit
349ab399dc
1 changed files with 52 additions and 9 deletions
|
@ -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(_)
|
||||||
|
|
Loading…
Reference in a new issue