diff --git a/misc/FFNx.toml b/misc/FFNx.toml index 4e5ac548..b8da00c6 100644 --- a/misc/FFNx.toml +++ b/misc/FFNx.toml @@ -103,6 +103,8 @@ #[EXTERNAL SFX EXTENSION] # The type of file to search for. By default is ogg. +# You can use a list to specify multiple extensions, ordered by priority. +# Example: ["ogg", "flac"] # Supported extensions: # - ogg, mp3, flac, wav #~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -131,6 +133,8 @@ #[EXTERNAL MUSIC EXTENSION] # The type of file to search for. By default is ogg. +# You can use a list to specify multiple extensions, ordered by priority. +# Example: ["minipsf", "ogg"] # Supported extensions: # - https://github.com/losnoco/vgmstream#supported-file-types # - psf, psf2, minipsf, minipsf2 (PSF and PSF2) if you provide the Highly Experimental BIOS @@ -152,6 +156,8 @@ #[EXTERNAL VOICE EXTENSION] # The type of file to search for. By default is ogg. +# You can use a list to specify multiple extensions, ordered by priority. +# Example: ["ogg", "flac"] # Supported extensions: # - ogg, mp3, flac, wav #~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/audio.cpp b/src/audio.cpp index dababcaa..8ecfc632 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -60,20 +60,43 @@ void NxAudioEngine::loadConfig() } template -void NxAudioEngine::getFilenameFullPath(char *_out, T _key, NxAudioEngineLayer _type) +bool NxAudioEngine::getFilenameFullPath(char *_out, T _key, NxAudioEngineLayer _type) { + std::vector extensions; + switch(_type) { case NxAudioEngineLayer::NXAUDIOENGINE_SFX: - sprintf(_out, "%s/%s/%d.%s", basedir, external_sfx_path.c_str(), _key, external_sfx_ext.c_str()); + extensions = external_sfx_ext; + break; + case NxAudioEngineLayer::NXAUDIOENGINE_MUSIC: + extensions = external_music_ext; + break; + case NxAudioEngineLayer::NXAUDIOENGINE_VOICE: + extensions = external_voice_ext; + break; + } + + for (auto extension: extensions) { + switch (_type) + { + case NxAudioEngineLayer::NXAUDIOENGINE_SFX: + sprintf(_out, "%s/%s/%d.%s", basedir, external_sfx_path.c_str(), _key, extension.c_str()); break; case NxAudioEngineLayer::NXAUDIOENGINE_MUSIC: - sprintf(_out, "%s/%s/%s.%s", basedir, external_music_path.c_str(), _key, external_music_ext.c_str()); + sprintf(_out, "%s/%s/%s.%s", basedir, external_music_path.c_str(), _key, extension.c_str()); break; case NxAudioEngineLayer::NXAUDIOENGINE_VOICE: - sprintf(_out, "%s/%s/%s.%s", basedir, external_voice_path.c_str(), _key, external_voice_ext.c_str()); + sprintf(_out, "%s/%s/%s.%s", basedir, external_voice_path.c_str(), _key, extension.c_str()); break; + } + + if (fileExists(_out)) { + return true; + } } + + return false; } bool NxAudioEngine::fileExists(const char* filename) @@ -142,13 +165,9 @@ void NxAudioEngine::cleanup() // SFX bool NxAudioEngine::canPlaySFX(int id) { - struct stat dummy; - char filename[MAX_PATH]; - getFilenameFullPath(filename, id, NxAudioEngineLayer::NXAUDIOENGINE_SFX); - - return (stat(filename, &dummy) == 0); + return getFilenameFullPath(filename, id, NxAudioEngineLayer::NXAUDIOENGINE_SFX); } void NxAudioEngine::loadSFX(int id) @@ -161,11 +180,11 @@ void NxAudioEngine::loadSFX(int id) { char filename[MAX_PATH]; - getFilenameFullPath(filename, id, NxAudioEngineLayer::NXAUDIOENGINE_SFX); + bool exists = getFilenameFullPath(filename, id, NxAudioEngineLayer::NXAUDIOENGINE_SFX); if (trace_all || trace_sfx) trace("NxAudioEngine::%s: %s\n", __func__, filename); - if (fileExists(filename)) + if (exists) { SoLoud::Wav* sfx = new SoLoud::Wav(); @@ -251,13 +270,9 @@ void NxAudioEngine::setSFXSpeed(float speed, int channel) // Music bool NxAudioEngine::canPlayMusic(const char* name) { - struct stat dummy; - char filename[MAX_PATH]; - getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_MUSIC); - - return (stat(filename, &dummy) == 0); + return getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_MUSIC); } SoLoud::AudioSource* NxAudioEngine::loadMusic(const char* name) @@ -265,11 +280,11 @@ SoLoud::AudioSource* NxAudioEngine::loadMusic(const char* name) SoLoud::AudioSource* music = nullptr; char filename[MAX_PATH]; - getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_MUSIC); + bool exists = getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_MUSIC); if (trace_all || trace_music) trace("NxAudioEngine::%s: %s\n", __func__, filename); - if (fileExists(filename)) + if (exists) { if (_openpsf_loaded) { SoLoud::OpenPsf* openpsf = new SoLoud::OpenPsf(); @@ -589,24 +604,20 @@ void NxAudioEngine::setMusicLooping(bool looping) // Voice bool NxAudioEngine::canPlayVoice(const char* name) { - struct stat dummy; - char filename[MAX_PATH]; - getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_VOICE); - - return (stat(filename, &dummy) == 0); + return getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_VOICE); } void NxAudioEngine::playVoice(const char* name) { char filename[MAX_PATH]; - getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_VOICE); + bool exists = getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_VOICE); if (trace_all || trace_voice) trace("NxAudioEngine::%s: %s\n", __func__, filename); - if (fileExists(filename)) + if (exists) { SoLoud::WavStream* voice = new SoLoud::WavStream(); diff --git a/src/audio.h b/src/audio.h index fd64cdf8..9d3e0895 100644 --- a/src/audio.h +++ b/src/audio.h @@ -94,8 +94,9 @@ class NxAudioEngine SoLoud::handle _voiceHandle = NXAUDIOENGINE_INVALID_HANDLE; // MISC + // Returns false if the file does not exist template - void getFilenameFullPath(char *_out, T _key, NxAudioEngineLayer _type); + bool getFilenameFullPath(char *_out, T _key, NxAudioEngineLayer _type); bool fileExists(const char* filename); diff --git a/src/audio/openpsf/openpsf.cpp b/src/audio/openpsf/openpsf.cpp index 3826259f..b4e6b0c7 100644 --- a/src/audio/openpsf/openpsf.cpp +++ b/src/audio/openpsf/openpsf.cpp @@ -121,11 +121,6 @@ namespace SoLoud return FILE_NOT_FOUND; } - if (!Psf::is_our_path(aFilename, external_music_ext.c_str())) { - error("Incompatible file extension %s\n", external_music_ext.c_str()); - return FILE_LOAD_FAILED; - } - stop(); stream = new Psf(PsfFlags::PsfDefaults, 0); diff --git a/src/cfg.cpp b/src/cfg.cpp index d5946583..462b0d08 100644 --- a/src/cfg.cpp +++ b/src/cfg.cpp @@ -29,14 +29,14 @@ bool enable_ffmpeg_videos; std::string ffmpeg_video_ext; bool use_external_sfx; std::string external_sfx_path; -std::string external_sfx_ext; +std::vector external_sfx_ext; bool use_external_music; bool external_music_resume; std::string external_music_path; -std::string external_music_ext; +std::vector external_music_ext; std::string he_bios_path; std::string external_voice_path; -std::string external_voice_ext; +std::vector external_voice_ext; bool enable_voice_music_fade; long external_voice_music_fade_volume; bool save_textures; @@ -90,6 +90,22 @@ double speedhack_max; double speedhack_min; bool enable_animated_textures; +std::vector get_string_or_array_of_strings(const toml::node_view &node) +{ + if (node.is_array()) { + toml::array* a = node.as_array(); + if (a && a->is_homogeneous(toml::node_type::string)) { + std::vector ret(a->size()); + for (toml::array::iterator it = a->begin(); it != a->end(); ++it) { + ret.push_back((*it).value_or("")); + } + return ret; + } + } + + return std::vector(1, node.value_or("")); +} + void read_cfg() { toml::parse_result config; @@ -116,14 +132,14 @@ void read_cfg() ffmpeg_video_ext = config["ffmpeg_video_ext"].value_or(""); use_external_sfx = config["use_external_sfx"].value_or(false); external_sfx_path = config["external_sfx_path"].value_or(""); - external_sfx_ext = config["external_sfx_ext"].value_or(""); + external_sfx_ext = get_string_or_array_of_strings(config["external_sfx_ext"]); use_external_music = config["use_external_music"].value_or(false); external_music_resume = config["external_music_resume"].value_or(true); external_music_path = config["external_music_path"].value_or(""); - external_music_ext = config["external_music_ext"].value_or(""); + external_music_ext = get_string_or_array_of_strings(config["external_music_ext"]); he_bios_path = config["he_bios_path"].value_or(""); external_voice_path = config["external_voice_path"].value_or(""); - external_voice_ext = config["external_voice_ext"].value_or(""); + external_voice_ext = get_string_or_array_of_strings(config["external_voice_ext"]); enable_voice_music_fade = config["enable_voice_music_fade"].value_or(false); external_voice_music_fade_volume = config["external_voice_music_fade_volume"].value_or(25); save_textures = config["save_textures"].value_or(false); @@ -281,20 +297,20 @@ void read_cfg() external_sfx_path = "sfx"; // EXTERNAL SFX EXTENSION - if (external_sfx_ext.empty()) - external_sfx_ext = "ogg"; + if (external_sfx_ext.empty() || external_sfx_ext.front().empty()) + external_sfx_ext = std::vector(1, "ogg"); // EXTERNAL MUSIC EXTENSION - if (external_music_ext.empty()) - external_music_ext = "ogg"; + if (external_music_ext.empty() || external_music_ext.front().empty()) + external_music_ext = std::vector(1, "ogg"); // EXTERNAL VOICE PATH if (external_voice_path.empty()) external_voice_path = "voice"; // EXTERNAL VOICE EXTENSION - if (external_voice_ext.empty()) - external_voice_ext = "ogg"; + if (external_voice_ext.empty() || external_voice_ext.front().empty()) + external_voice_ext = std::vector(1, "ogg"); // MOD PATH if (mod_path.empty()) diff --git a/src/cfg.h b/src/cfg.h index d2a07539..f987c367 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include "log.h" #define RENDERER_BACKEND_AUTO 0 @@ -36,14 +37,14 @@ extern bool enable_ffmpeg_videos; extern std::string ffmpeg_video_ext; extern bool use_external_sfx; extern std::string external_sfx_path; -extern std::string external_sfx_ext; +extern std::vector external_sfx_ext; extern bool use_external_music; extern bool external_music_resume; extern std::string external_music_path; -extern std::string external_music_ext; +extern std::vector external_music_ext; extern std::string he_bios_path; extern std::string external_voice_path; -extern std::string external_voice_ext; +extern std::vector external_voice_ext; extern bool enable_voice_music_fade; extern long external_voice_music_fade_volume; extern bool save_textures;