Browse Source

♻️ Make `SFileRw` own the Storm file handle

All of our use-cases for `SDL_RWops` Storm file require closing the file
when closing the `SDL_RWops` -- doing this automatically simplifies the
code.
pull/1820/head
Gleb Mazovetskiy 5 years ago committed by Anders Jenbo
parent
commit
5820948761
  1. 25
      Source/sound.cpp
  2. 1
      Source/storm/storm_sdl_rw.cpp
  3. 2
      Source/storm/storm_sdl_rw.h
  4. 16
      Source/utils/soundsample.cpp
  5. 4
      Source/utils/soundsample.h

25
Source/sound.cpp

@ -26,8 +26,6 @@
namespace devilution {
bool gbSndInited;
/** Handle to the music Storm file. */
HANDLE sghMusic;
/** The active background music track id. */
_music_id sgnMusicTrack = NUM_MUSIC;
@ -39,16 +37,15 @@ std::optional<Aulib::Stream> music;
char *musicBuffer;
#endif
void LoadMusic()
void LoadMusic(HANDLE handle)
{
#ifndef DISABLE_STREAMING_MUSIC
SDL_RWops *musicRw = SFileRw_FromStormHandle(sghMusic);
SDL_RWops *musicRw = SFileRw_FromStormHandle(handle);
#else
int bytestoread = SFileGetFileSize(sghMusic, 0);
int bytestoread = SFileGetFileSize(handle, 0);
musicBuffer = (char *)DiabloAllocPtr(bytestoread);
SFileReadFile(sghMusic, musicBuffer, bytestoread, NULL, 0);
SFileCloseFile(sghMusic);
sghMusic = NULL;
SFileReadFile(handle, musicBuffer, bytestoread, NULL, 0);
SFileCloseFile(handle);
SDL_RWops *musicRw = SDL_RWFromConstMem(musicBuffer, bytestoread);
#endif
@ -60,10 +57,7 @@ void CleanupMusic()
{
music = std::nullopt;
sgnMusicTrack = NUM_MUSIC;
#ifndef DISABLE_STREAMING_MUSIC
SFileCloseFile(sghMusic);
sghMusic = nullptr;
#else
#ifdef DISABLE_STREAMING_MUSIC
if (musicBuffer != nullptr) {
mem_free_dbg(musicBuffer);
musicBuffer = nullptr;
@ -246,11 +240,12 @@ void music_start(uint8_t nTrack)
trackPath = sgszSpawnMusicTracks[nTrack];
else
trackPath = sgszMusicTracks[nTrack];
success = SFileOpenFile(trackPath, &sghMusic);
HANDLE handle;
success = SFileOpenFile(trackPath, &handle);
if (!success) {
sghMusic = nullptr;
handle = nullptr;
} else {
LoadMusic();
LoadMusic(handle);
if (!music->open()) {
LogError(LogCategory::Audio, "Aulib::Stream::open (from music_start): {}", SDL_GetError());
CleanupMusic();

1
Source/storm/storm_sdl_rw.cpp

@ -71,6 +71,7 @@ static int SFileRwRead(struct SDL_RWops *context, void *ptr, int size, int maxnu
static int SFileRwClose(struct SDL_RWops *context)
{
SFileCloseFile(SFileRwGetHandle(context));
delete context;
return 0;
}

2
Source/storm/storm_sdl_rw.h

@ -9,7 +9,7 @@ namespace devilution {
/**
* @brief Creates a read-only SDL_RWops from a Storm file handle.
*
* Does not close the handle when it gets closed.
* Closes the handle when it gets closed.
*/
SDL_RWops *SFileRw_FromStormHandle(HANDLE handle);

16
Source/utils/soundsample.cpp

@ -20,20 +20,11 @@
namespace devilution {
SoundSample::~SoundSample()
{
if (file_handle_ != nullptr)
SFileCloseFile(file_handle_);
}
void SoundSample::Release()
{
stream_ = nullptr;
file_data_ = nullptr;
file_data_size_ = 0;
if (file_handle_ != nullptr)
SFileCloseFile(file_handle_);
file_handle_ = nullptr;
};
/**
@ -78,17 +69,16 @@ void SoundSample::Stop()
int SoundSample::SetChunkStream(std::string filePath)
{
file_path_ = std::move(filePath);
if (!SFileOpenFile(file_path_.c_str(), &file_handle_)) {
HANDLE handle;
if (!SFileOpenFile(file_path_.c_str(), &handle)) {
LogError(LogCategory::Audio, "SFileOpenFile failed (from SoundSample::SetChunkStream): {}", SErrGetLastError());
return -1;
}
stream_ = std::make_unique<Aulib::Stream>(SFileRw_FromStormHandle(file_handle_), std::make_unique<Aulib::DecoderDrwav>(),
stream_ = std::make_unique<Aulib::Stream>(SFileRw_FromStormHandle(handle), std::make_unique<Aulib::DecoderDrwav>(),
std::make_unique<Aulib::ResamplerSpeex>(sgOptions.Audio.nResamplingQuality), /*closeRw=*/true);
if (!stream_->open()) {
stream_ = nullptr;
SFileCloseFile(file_handle_);
file_handle_ = nullptr;
LogError(LogCategory::Audio, "Aulib::Stream::open (from SoundSample::SetChunkStream): {}", SDL_GetError());
return -1;
}

4
Source/utils/soundsample.h

@ -16,7 +16,6 @@ public:
SoundSample() = default;
SoundSample(SoundSample &&) noexcept = default;
SoundSample &operator=(SoundSample &&) noexcept = default;
~SoundSample();
void Release();
bool IsPlaying();
@ -51,8 +50,7 @@ private:
ArraySharedPtr<std::uint8_t> file_data_;
std::size_t file_data_size_;
// Streaming audio fields:
HANDLE file_handle_ = nullptr;
// Set for streaming audio to allow for duplicating it:
std::string file_path_;
std::unique_ptr<Aulib::Stream> stream_;

Loading…
Cancel
Save