diff --git a/src/custom_sfml_audio/fake_pitched_sound_stream.cpp b/src/custom_sfml_audio/fake_pitched_sound_stream.cpp index 458acb8..2bef4a7 100644 --- a/src/custom_sfml_audio/fake_pitched_sound_stream.cpp +++ b/src/custom_sfml_audio/fake_pitched_sound_stream.cpp @@ -14,7 +14,7 @@ FakePitchedSoundStream::FakePitchedSoundStream( pitch(pitch_), sample(std::make_shared()) { - if (not sample->loadFromFile(to_native_encoding(path_to_sample))) { + if (not sample->loadFromFile(to_sfml_string(path_to_sample))) { throw std::runtime_error(fmt::format("Could not load audio sample : {}", path_to_sample.string())); } finish_initializing_the_sample(); diff --git a/src/custom_sfml_audio/open_music.cpp b/src/custom_sfml_audio/open_music.cpp index d5e58ed..e1de517 100644 --- a/src/custom_sfml_audio/open_music.cpp +++ b/src/custom_sfml_audio/open_music.cpp @@ -25,7 +25,7 @@ OpenMusic::OpenMusic(const std::filesystem::path& filename) : m_file(), m_loopSpan(0, 0) { - if (not openFromFile(to_native_encoding(filename))) { + if (not openFromFile(to_sfml_string(filename))) { throw std::runtime_error("Could not open "+filename.string()); } } @@ -42,7 +42,7 @@ bool OpenMusic::openFromFile(const std::filesystem::path& filename) { stop(); // Open the underlying sound file - if (!m_file.openFromFile(to_native_encoding(filename))) { + if (!m_file.openFromFile(to_sfml_string(filename))) { return false; } diff --git a/src/editor_state.cpp b/src/editor_state.cpp index 50e3e97..1762594 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -1398,7 +1398,7 @@ void EditorState::reload_jacket() { if ( not std::filesystem::exists(jacket_path) - or not jacket->loadFromFile(to_native_encoding(jacket_path)) + or not jacket->loadFromFile(to_sfml_string(jacket_path)) ) { jacket.reset(); } else { @@ -1460,7 +1460,7 @@ void EditorState::reload_preview_audio() { const auto path = song_path->parent_path() / song.metadata.preview_file; preview_audio.emplace(); - if (not preview_audio->openFromFile(to_native_encoding(path))) { + if (not preview_audio->openFromFile(to_sfml_string(path))) { preview_audio.reset(); } }; diff --git a/src/ln_marker.hpp b/src/ln_marker.hpp index 49f3588..596cd35 100644 --- a/src/ln_marker.hpp +++ b/src/ln_marker.hpp @@ -67,7 +67,7 @@ std::array load_tex_with_prefix( ); std::filesystem::path texFile = folder / filename; sf::Texture tex; - if (!tex.loadFromFile(to_native_encoding(texFile))) { + if (!tex.loadFromFile(to_sfml_string(texFile))) { throw std::runtime_error(fmt::format( "Unable to load texture folder {}, failed on texture {}", folder.string(), diff --git a/src/main.cpp b/src/main.cpp index a3fa1dd..0662a3e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,7 +77,7 @@ int main() { std::filesystem::directory_iterator(assets_folder / "textures" / "markers")) { if (folder.is_directory()) { sf::Texture markerPreview; - markerPreview.loadFromFile(to_native_encoding(folder.path() / "ma15.png")); + markerPreview.loadFromFile(to_sfml_string(folder.path() / "ma15.png")); markerPreview.setSmooth(true); markerPreviews.insert({folder, markerPreview}); } diff --git a/src/marker.cpp b/src/marker.cpp index c1cc838..f5f63d1 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -22,7 +22,7 @@ Marker::Marker(const std::filesystem::path& folder_): const auto emplace_back = [&](std::vector& vec, const std::string& file){ auto& tex = vec.emplace_back(); const auto path = folder / file; - if (not tex.loadFromFile(to_native_encoding(path))) { + if (not tex.loadFromFile(to_sfml_string(path))) { throw std::runtime_error(fmt::format( "Unable to load marker {} - failed on image {}", folder.string(), diff --git a/src/playfield.cpp b/src/playfield.cpp index 0103389..349ca27 100644 --- a/src/playfield.cpp +++ b/src/playfield.cpp @@ -9,7 +9,7 @@ Playfield::Playfield(std::filesystem::path assets_folder) : long_note(assets_folder / "textures" / "long"), texture_path(assets_folder / texture_file) { - if (!base_texture.loadFromFile(to_native_encoding(texture_path))) { + if (!base_texture.loadFromFile(to_sfml_string(texture_path))) { std::cerr << "Unable to load texture " << texture_path; throw std::runtime_error("Unable to load texture " + texture_path.string()); } diff --git a/src/sound_effect.cpp b/src/sound_effect.cpp index 1741747..c0e8525 100644 --- a/src/sound_effect.cpp +++ b/src/sound_effect.cpp @@ -9,7 +9,7 @@ SoundEffect::SoundEffect(std::filesystem::path path) : shouldPlay(false), buffer(), volume(10) { - if (!buffer.loadFromFile(to_native_encoding(path))) { + if (!buffer.loadFromFile(to_sfml_string(path))) { throw std::runtime_error("Unable to load sound : " + path.string()); } diff --git a/src/utf8_sfml.cpp b/src/utf8_sfml.cpp new file mode 100644 index 0000000..bf3126d --- /dev/null +++ b/src/utf8_sfml.cpp @@ -0,0 +1,50 @@ +#include "utf8_sfml.hpp" +#include +#include +#include "nowide/fstream.hpp" + +#include "utf8_strings.hpp" + +feis::UTF8FileStream::UTF8FileStream(const std::filesystem::path& file) : + nowide_stream(to_utf8_encoded_string(file)), + path(file) +{} + +sf::Int64 feis::UTF8FileStream::read(void* data, sf::Int64 size) { + try { + nowide_stream.read(static_cast(data), size); + } catch (const std::ios_base::failure& e) { + return -1; + } + return nowide_stream.gcount(); +} + +sf::Int64 feis::UTF8FileStream::seek(sf::Int64 position) { + try { + nowide_stream.seekg(position, std::ios_base::beg); + return nowide_stream.tellg(); + } catch (const std::ios_base::failure& e) { + return -1; + } +} + +sf::Int64 feis::UTF8FileStream::tell() { + try { + return nowide_stream.tellg(); + } catch (const std::ios_base::failure& e) { + return -1; + } +} + +sf::Int64 feis::UTF8FileStream::getSize() { + try { + return std::filesystem::file_size(path); + } catch(std::filesystem::filesystem_error const& ex) { + return -1; + } +} + +bool feis::Music::open_from_file(const std::filesystem::path& file) { + file_stream.emplace(to_utf8_encoded_string(file)); + return this->openFromStream(*file_stream); +} \ No newline at end of file diff --git a/src/utf8_sfml.hpp b/src/utf8_sfml.hpp new file mode 100644 index 0000000..1d29eef --- /dev/null +++ b/src/utf8_sfml.hpp @@ -0,0 +1,38 @@ +/* UTF8-aware load_from_file functions for SFML objects, +uses nowide under the hood */ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace feis { + class UTF8FileStream : public sf::InputStream { + public: + UTF8FileStream(const std::filesystem::path& file); + sf::Int64 read(void* data, sf::Int64 size) override; + sf::Int64 seek(sf::Int64 position) override; + sf::Int64 tell() override; + sf::Int64 getSize() override; + private: + nowide::ifstream nowide_stream; + std::filesystem::path path; + }; + + template + bool load_from_file(T& object, const std::filesystem::path& file) { + UTF8FileStream f{file}; + return object.loadFromStream(f); + } + + class Music : public sf::Music { + public: + bool open_from_file(const std::filesystem::path& file); + protected: + std::optional file_stream; + }; +} \ No newline at end of file diff --git a/src/utf8_strings.cpp b/src/utf8_strings.cpp index 233e77a..0d17f16 100644 --- a/src/utf8_strings.cpp +++ b/src/utf8_strings.cpp @@ -1,4 +1,5 @@ #include "utf8_strings.hpp" +#include std::string to_utf8_encoded_string(const std::u8string& u8s) { std::string result{u8s.cbegin(), u8s.cend()}; @@ -18,6 +19,12 @@ std::filesystem::path to_path(const std::string& utf8s) { return std::filesystem::path{to_u8string(utf8s)}; } -std::string to_native_encoding(const std::filesystem::path& path) { +std::string to_sfml_string(const std::filesystem::path& path) { +#ifdef _WIN32 + const auto string_path = to_utf8_encoded_string(path); + const auto sfml_string_path = sf::String::fromUtf8(string_path.begin(), string_path.end()); + return sfml_string_path.toAnsiString(); +#else return path.string(); +#endif } \ No newline at end of file diff --git a/src/utf8_strings.hpp b/src/utf8_strings.hpp index 9906e90..e4d7f15 100644 --- a/src/utf8_strings.hpp +++ b/src/utf8_strings.hpp @@ -5,4 +5,4 @@ std::string to_utf8_encoded_string(const std::u8string& u8s); std::string to_utf8_encoded_string(const std::filesystem::path& path); std::u8string to_u8string(const std::string& utf8s); std::filesystem::path to_path(const std::string& utf8s); -std::string to_native_encoding(const std::filesystem::path& path); \ No newline at end of file +std::string to_sfml_string(const std::filesystem::path& path); \ No newline at end of file diff --git a/src/widgets/blank_screen.cpp b/src/widgets/blank_screen.cpp index 1399425..5c363aa 100644 --- a/src/widgets/blank_screen.cpp +++ b/src/widgets/blank_screen.cpp @@ -5,7 +5,7 @@ #include "utf8_strings.hpp" BlankScreen::BlankScreen(std::filesystem::path assets) : gris_de_fond(sf::Color(38, 38, 38)) { - if (!tex_FEIS_logo.loadFromFile(to_native_encoding(assets / "textures" / "FEIS_logo.png"))) { + if (!tex_FEIS_logo.loadFromFile(to_sfml_string(assets / "textures" / "FEIS_logo.png"))) { throw std::string("Unable to load assets/textures/FEIS_logo.png"); } tex_FEIS_logo.setSmooth(true); diff --git a/src/widgets/density_graph.cpp b/src/widgets/density_graph.cpp index 1b7a7ea..b204c86 100644 --- a/src/widgets/density_graph.cpp +++ b/src/widgets/density_graph.cpp @@ -10,7 +10,7 @@ DensityGraph::DensityGraph(std::filesystem::path assets, const config::Config& c texture_path(assets / texture_file), collision_zone(config.editor.collision_zone) { - if (!base_texture.loadFromFile(to_native_encoding(texture_path))) { + if (!base_texture.loadFromFile(to_sfml_string(texture_path))) { std::cerr << "Unable to load texture " << texture_path; throw std::runtime_error("Unable to load texture " + texture_path.string()); }