diff --git a/examples/android/app/src/main/jni/main.cpp b/examples/android/app/src/main/jni/main.cpp index e66403138..abc025e29 100644 --- a/examples/android/app/src/main/jni/main.cpp +++ b/examples/android/app/src/main/jni/main.cpp @@ -86,13 +86,13 @@ int main(int argc, char* argv[]) sf::RenderWindow window(screen, ""); window.setFramerateLimit(30); - const auto texture = sf::Texture::loadFromFile("image.png").value(); + const auto texture = sf::Texture::createFromFile("image.png").value(); sf::Sprite image(texture); image.setPosition(sf::Vector2f(screen.size) / 2.f); image.setOrigin(sf::Vector2f(texture.getSize()) / 2.f); - const auto font = sf::Font::openFromFile("tuffy.ttf").value(); + const auto font = sf::Font::createFromFile("tuffy.ttf").value(); sf::Text text(font, "Tap anywhere to move the logo.", 64); text.setFillColor(sf::Color::Black); diff --git a/examples/cocoa/CocoaAppDelegate.mm b/examples/cocoa/CocoaAppDelegate.mm index 27463b520..327f3a916 100644 --- a/examples/cocoa/CocoaAppDelegate.mm +++ b/examples/cocoa/CocoaAppDelegate.mm @@ -52,9 +52,9 @@ struct SFMLmainWindow std::filesystem::path resPath{[[[NSBundle mainBundle] resourcePath] tostdstring]}; sf::RenderWindow renderWindow; - sf::Font font{sf::Font::openFromFile(resPath / "tuffy.ttf").value()}; + sf::Font font{sf::Font::createFromFile(resPath / "tuffy.ttf").value()}; sf::Text text{font}; - sf::Texture logo{sf::Texture::loadFromFile(resPath / "logo.png").value()}; + sf::Texture logo{sf::Texture::createFromFile(resPath / "logo.png").value()}; sf::Sprite sprite{logo}; sf::Color background{sf::Color::Blue}; }; diff --git a/examples/event_handling/EventHandling.cpp b/examples/event_handling/EventHandling.cpp index 6211611bb..263a7b382 100644 --- a/examples/event_handling/EventHandling.cpp +++ b/examples/event_handling/EventHandling.cpp @@ -316,7 +316,7 @@ private: // Member data //////////////////////////////////////////////////////////// sf::RenderWindow m_window{sf::VideoMode({800u, 600u}), "SFML Event Handling", sf::Style::Titlebar | sf::Style::Close}; - const sf::Font m_font{sf::Font::openFromFile("resources/tuffy.ttf").value()}; + const sf::Font m_font{sf::Font::createFromFile("resources/tuffy.ttf").value()}; sf::Text m_logText{m_font, "", 20}; sf::Text m_handlerText{m_font, "Current Handler: Classic", 24}; sf::Text m_instructions{m_font, "Press Enter to change handler type", 24}; diff --git a/examples/island/Island.cpp b/examples/island/Island.cpp index 09df89cc6..fb02ec8fe 100644 --- a/examples/island/Island.cpp +++ b/examples/island/Island.cpp @@ -91,7 +91,7 @@ int main() sf::RenderWindow window(sf::VideoMode({windowWidth, windowHeight}), "SFML Island", sf::Style::Titlebar | sf::Style::Close); window.setVerticalSyncEnabled(true); - const auto font = sf::Font::openFromFile("resources/tuffy.ttf").value(); + const auto font = sf::Font::createFromFile("resources/tuffy.ttf").value(); // Create all of our graphics resources sf::Text hudText(font); @@ -120,7 +120,7 @@ int main() { statusText.setString("Shaders and/or Vertex Buffers Unsupported"); } - else if (!(terrainShader = sf::Shader::loadFromFile("resources/terrain.vert", "resources/terrain.frag"))) + else if (!(terrainShader = sf::Shader::createFromFile("resources/terrain.vert", "resources/terrain.frag"))) { statusText.setString("Failed to load shader program"); } diff --git a/examples/joystick/Joystick.cpp b/examples/joystick/Joystick.cpp index 36a572512..011ef33cb 100644 --- a/examples/joystick/Joystick.cpp +++ b/examples/joystick/Joystick.cpp @@ -94,7 +94,7 @@ int main() window.setVerticalSyncEnabled(true); // Open the text font - const auto font = sf::Font::openFromFile("resources/tuffy.ttf").value(); + const auto font = sf::Font::createFromFile("resources/tuffy.ttf").value(); // Set up our string conversion parameters sstr.precision(2); diff --git a/examples/opengl/OpenGL.cpp b/examples/opengl/OpenGL.cpp index 7678e162b..ed369639d 100644 --- a/examples/opengl/OpenGL.cpp +++ b/examples/opengl/OpenGL.cpp @@ -58,11 +58,11 @@ int main() window.setMaximumSize(sf::Vector2u(1200, 900)); // Create a sprite for the background - const auto backgroundTexture = sf::Texture::loadFromFile(resourcesDir() / "background.jpg", sRgb).value(); + const auto backgroundTexture = sf::Texture::createFromFile(resourcesDir() / "background.jpg", sRgb).value(); const sf::Sprite background(backgroundTexture); // Create some text to draw on top of our OpenGL object - const auto font = sf::Font::openFromFile(resourcesDir() / "tuffy.ttf").value(); + const auto font = sf::Font::createFromFile(resourcesDir() / "tuffy.ttf").value(); sf::Text text(font, "SFML / OpenGL demo"); sf::Text sRgbInstructions(font, "Press space to toggle sRGB conversion"); @@ -75,7 +75,7 @@ int main() mipmapInstructions.setPosition({200.f, 550.f}); // Load a texture to apply to our 3D cube - auto texture = sf::Texture::loadFromFile(resourcesDir() / "logo.png").value(); + auto texture = sf::Texture::createFromFile(resourcesDir() / "logo.png").value(); // Attempt to generate a mipmap for our cube texture // We don't check the return value here since @@ -219,7 +219,7 @@ int main() if (mipmapEnabled) { // We simply reload the texture to disable mipmapping - texture = sf::Texture::loadFromFile(resourcesDir() / "logo.png").value(); + texture = sf::Texture::createFromFile(resourcesDir() / "logo.png").value(); // Rebind the texture sf::Texture::bind(&texture); diff --git a/examples/raw_input/RawInput.cpp b/examples/raw_input/RawInput.cpp index bb6a73b0f..2faeb9be5 100644 --- a/examples/raw_input/RawInput.cpp +++ b/examples/raw_input/RawInput.cpp @@ -19,7 +19,7 @@ int main() window.setVerticalSyncEnabled(true); // Open the application font - const auto font = sf::Font::openFromFile("resources/tuffy.ttf").value(); + const auto font = sf::Font::createFromFile("resources/tuffy.ttf").value(); // Create the mouse position text sf::Text mousePosition(font, "", 20); diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp index 7f2190a1d..5e4543c09 100644 --- a/examples/shader/Shader.cpp +++ b/examples/shader/Shader.cpp @@ -278,11 +278,11 @@ private: //////////////////////////////////////////////////////////// std::optional tryLoadPixelate() { - auto texture = sf::Texture::loadFromFile("resources/background.jpg"); + auto texture = sf::Texture::createFromFile("resources/background.jpg"); if (!texture.has_value()) return std::nullopt; - auto shader = sf::Shader::loadFromFile("resources/pixelate.frag", sf::Shader::Type::Fragment); + auto shader = sf::Shader::createFromFile("resources/pixelate.frag", sf::Shader::Type::Fragment); if (!shader.has_value()) return std::nullopt; @@ -291,7 +291,7 @@ std::optional tryLoadPixelate() std::optional tryLoadWaveBlur(const sf::Font& font) { - auto shader = sf::Shader::loadFromFile("resources/wave.vert", "resources/blur.frag"); + auto shader = sf::Shader::createFromFile("resources/wave.vert", "resources/blur.frag"); if (!shader.has_value()) return std::nullopt; @@ -300,7 +300,7 @@ std::optional tryLoadWaveBlur(const sf::Font& font) std::optional tryLoadStormBlink() { - auto shader = sf::Shader::loadFromFile("resources/storm.vert", "resources/blink.frag"); + auto shader = sf::Shader::createFromFile("resources/storm.vert", "resources/blink.frag"); if (!shader.has_value()) return std::nullopt; @@ -317,21 +317,21 @@ std::optional tryLoadEdge() surface->setSmooth(true); // Load the background texture - auto backgroundTexture = sf::Texture::loadFromFile("resources/sfml.png"); + auto backgroundTexture = sf::Texture::createFromFile("resources/sfml.png"); if (!backgroundTexture.has_value()) return std::nullopt; backgroundTexture->setSmooth(true); // Load the entity texture - auto entityTexture = sf::Texture::loadFromFile("resources/devices.png"); + auto entityTexture = sf::Texture::createFromFile("resources/devices.png"); if (!entityTexture.has_value()) return std::nullopt; entityTexture->setSmooth(true); // Load the shader - auto shader = sf::Shader::loadFromFile("resources/edge.frag", sf::Shader::Type::Fragment); + auto shader = sf::Shader::createFromFile("resources/edge.frag", sf::Shader::Type::Fragment); if (!shader.has_value()) return std::nullopt; @@ -350,16 +350,16 @@ std::optional tryLoadGeometry() return std::nullopt; // Load the logo texture - auto logoTexture = sf::Texture::loadFromFile("resources/logo.png"); + auto logoTexture = sf::Texture::createFromFile("resources/logo.png"); if (!logoTexture.has_value()) return std::nullopt; logoTexture->setSmooth(true); // Load the shader - auto shader = sf::Shader::loadFromFile("resources/billboard.vert", - "resources/billboard.geom", - "resources/billboard.frag"); + auto shader = sf::Shader::createFromFile("resources/billboard.vert", + "resources/billboard.geom", + "resources/billboard.frag"); if (!shader.has_value()) return std::nullopt; @@ -394,7 +394,7 @@ int main() window.setVerticalSyncEnabled(true); // Open the application font - const auto font = sf::Font::openFromFile("resources/tuffy.ttf").value(); + const auto font = sf::Font::createFromFile("resources/tuffy.ttf").value(); // Create the effects std::optional pixelateEffect = tryLoadPixelate(); @@ -418,7 +418,7 @@ int main() std::size_t current = 0; // Create the messages background - const auto textBackgroundTexture = sf::Texture::loadFromFile("resources/text-background.png").value(); + const auto textBackgroundTexture = sf::Texture::createFromFile("resources/text-background.png").value(); sf::Sprite textBackground(textBackgroundTexture); textBackground.setPosition({0.f, 520.f}); textBackground.setColor(sf::Color(255, 255, 255, 200)); diff --git a/examples/sound/Sound.cpp b/examples/sound/Sound.cpp index 3e27dae01..99f95ccc2 100644 --- a/examples/sound/Sound.cpp +++ b/examples/sound/Sound.cpp @@ -13,7 +13,7 @@ void playSound() { // Load a sound buffer from a wav file - const auto buffer = sf::SoundBuffer::loadFromFile("resources/killdeer.wav").value(); + const auto buffer = sf::SoundBuffer::createFromFile("resources/killdeer.wav").value(); // Display sound information std::cout << "killdeer.wav:" << '\n' @@ -46,7 +46,7 @@ void playSound() void playMusic(const std::filesystem::path& filename) { // Load an ogg music file - auto music = sf::Music::openFromFile("resources" / filename).value(); + auto music = sf::Music::createFromFile("resources" / filename).value(); // Display music information std::cout << filename << ":" << '\n' diff --git a/examples/sound_effects/SoundEffects.cpp b/examples/sound_effects/SoundEffects.cpp index 623be7d86..b98e0ffcb 100644 --- a/examples/sound_effects/SoundEffects.cpp +++ b/examples/sound_effects/SoundEffects.cpp @@ -115,7 +115,7 @@ public: m_listener.setFillColor(sf::Color::Red); // Load the music file - if (!(m_music = sf::Music::openFromFile(resourcesDir() / "doodle_pop.ogg"))) + if (!(m_music = sf::Music::createFromFile(resourcesDir() / "doodle_pop.ogg"))) { std::cerr << "Failed to load " << (resourcesDir() / "doodle_pop.ogg").string() << std::endl; std::abort(); @@ -177,7 +177,7 @@ public: m_volumeText(getFont(), "Volume: " + std::to_string(m_volume)) { // Load the music file - if (!(m_music = sf::Music::openFromFile(resourcesDir() / "doodle_pop.ogg"))) + if (!(m_music = sf::Music::createFromFile(resourcesDir() / "doodle_pop.ogg"))) { std::cerr << "Failed to load " << (resourcesDir() / "doodle_pop.ogg").string() << std::endl; std::abort(); @@ -283,7 +283,7 @@ public: makeCone(m_soundConeInner, innerConeAngle); // Load the music file - if (!(m_music = sf::Music::openFromFile(resourcesDir() / "doodle_pop.ogg"))) + if (!(m_music = sf::Music::createFromFile(resourcesDir() / "doodle_pop.ogg"))) { std::cerr << "Failed to load " << (resourcesDir() / "doodle_pop.ogg").string() << std::endl; std::abort(); @@ -677,7 +677,7 @@ protected: m_instructions.setPosition({windowWidth / 2.f - 250.f, windowHeight * 3.f / 4.f}); // Load the music file - if (!(m_music = sf::Music::openFromFile(resourcesDir() / "doodle_pop.ogg"))) + if (!(m_music = sf::Music::createFromFile(resourcesDir() / "doodle_pop.ogg"))) { std::cerr << "Failed to load " << (resourcesDir() / "doodle_pop.ogg").string() << std::endl; std::abort(); @@ -1077,7 +1077,7 @@ int main() window.setVerticalSyncEnabled(true); // Open the application font and pass it to the Effect class - const auto font = sf::Font::openFromFile(resourcesDir() / "tuffy.ttf").value(); + const auto font = sf::Font::createFromFile(resourcesDir() / "tuffy.ttf").value(); Effect::setFont(font); // Create the effects @@ -1106,7 +1106,7 @@ int main() effects[current]->start(); // Create the messages background - const auto textBackgroundTexture = sf::Texture::loadFromFile(resourcesDir() / "text-background.png").value(); + const auto textBackgroundTexture = sf::Texture::createFromFile(resourcesDir() / "text-background.png").value(); sf::Sprite textBackground(textBackgroundTexture); textBackground.setPosition({0.f, 520.f}); textBackground.setColor(sf::Color(255, 255, 255, 200)); diff --git a/examples/tennis/Tennis.cpp b/examples/tennis/Tennis.cpp index 3e71dafa5..4d5b0ab08 100644 --- a/examples/tennis/Tennis.cpp +++ b/examples/tennis/Tennis.cpp @@ -49,11 +49,11 @@ int main() window.setVerticalSyncEnabled(true); // Load the sounds used in the game - const auto ballSoundBuffer = sf::SoundBuffer::loadFromFile(resourcesDir() / "ball.wav").value(); + const auto ballSoundBuffer = sf::SoundBuffer::createFromFile(resourcesDir() / "ball.wav").value(); sf::Sound ballSound(ballSoundBuffer); // Create the SFML logo texture: - const auto sfmlLogoTexture = sf::Texture::loadFromFile(resourcesDir() / "sfml_logo.png").value(); + const auto sfmlLogoTexture = sf::Texture::createFromFile(resourcesDir() / "sfml_logo.png").value(); sf::Sprite sfmlLogo(sfmlLogoTexture); sfmlLogo.setPosition({170.f, 50.f}); @@ -82,7 +82,7 @@ int main() ball.setOrigin({ballRadius / 2.f, ballRadius / 2.f}); // Open the text font - const auto font = sf::Font::openFromFile(resourcesDir() / "tuffy.ttf").value(); + const auto font = sf::Font::createFromFile(resourcesDir() / "tuffy.ttf").value(); // Initialize the pause message sf::Text pauseMessage(font); diff --git a/examples/vulkan/Vulkan.cpp b/examples/vulkan/Vulkan.cpp index afa2a79a9..315b6f8fd 100644 --- a/examples/vulkan/Vulkan.cpp +++ b/examples/vulkan/Vulkan.cpp @@ -923,7 +923,7 @@ public: // Use the vertex shader SPIR-V code to create a vertex shader module { - auto file = sf::FileInputStream::open("resources/shader.vert.spv"); + auto file = sf::FileInputStream::create("resources/shader.vert.spv"); if (!file) { vulkanAvailable = false; @@ -951,7 +951,7 @@ public: // Use the fragment shader SPIR-V code to create a fragment shader module { - auto file = sf::FileInputStream::open("resources/shader.frag.spv"); + auto file = sf::FileInputStream::create("resources/shader.frag.spv"); if (!file) { vulkanAvailable = false; @@ -1801,7 +1801,7 @@ public: void setupTextureImage() { // Load the image data - const auto maybeImageData = sf::Image::loadFromFile("resources/logo.png"); + const auto maybeImageData = sf::Image::createFromFile("resources/logo.png"); if (!maybeImageData) { diff --git a/examples/win32/Win32.cpp b/examples/win32/Win32.cpp index 79922d0e7..c5679cf05 100644 --- a/examples/win32/Win32.cpp +++ b/examples/win32/Win32.cpp @@ -111,8 +111,8 @@ int main() sf::RenderWindow sfmlView2(view2); // Load some textures to display - const auto texture1 = sf::Texture::loadFromFile("resources/image1.jpg").value(); - const auto texture2 = sf::Texture::loadFromFile("resources/image2.jpg").value(); + const auto texture1 = sf::Texture::createFromFile("resources/image1.jpg").value(); + const auto texture2 = sf::Texture::createFromFile("resources/image2.jpg").value(); sf::Sprite sprite1(texture1); sf::Sprite sprite2(texture2); sprite1.setOrigin(sf::Vector2f(texture1.getSize()) / 2.f); diff --git a/include/SFML/Audio/InputSoundFile.hpp b/include/SFML/Audio/InputSoundFile.hpp index 0e6c872a8..07ff47b17 100644 --- a/include/SFML/Audio/InputSoundFile.hpp +++ b/include/SFML/Audio/InputSoundFile.hpp @@ -52,6 +52,15 @@ class InputStream; class SFML_AUDIO_API InputSoundFile { public: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Construct an input sound file that is not associated + /// with a file to read. + /// + //////////////////////////////////////////////////////////// + InputSoundFile() = default; + //////////////////////////////////////////////////////////// /// \brief Open a sound file from the disk for reading /// @@ -65,13 +74,58 @@ public: /// /// \param filename Path of the sound file to load /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromFile(const std::filesystem::path& filename); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromMemory(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromStream(InputStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Create a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC, MP3. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// Because of minimp3_ex limitation, for MP3 files with big (>16kb) APEv2 tag, + /// it may not be properly removed, tag data will be treated as MP3 data + /// and there is a low chance of garbage decoded at the end of file. + /// See also: https://github.com/lieff/minimp3 + /// + /// \param filename Path of the sound file to load + /// /// \return Input sound file if the file was successfully opened, otherwise `std::nullopt` /// //////////////////////////////////////////////////////////// - [[nodiscard]] static std::optional openFromFile(const std::filesystem::path& filename); + [[nodiscard]] static std::optional createFromFile(const std::filesystem::path& filename); //////////////////////////////////////////////////////////// - /// \brief Open a sound file in memory for reading + /// \brief Create a sound file in memory for reading /// /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. @@ -82,10 +136,10 @@ public: /// \return Input sound file if the file was successfully opened, otherwise `std::nullopt` /// //////////////////////////////////////////////////////////// - [[nodiscard]] static std::optional openFromMemory(const void* data, std::size_t sizeInBytes); + [[nodiscard]] static std::optional createFromMemory(const void* data, std::size_t sizeInBytes); //////////////////////////////////////////////////////////// - /// \brief Open a sound file from a custom stream for reading + /// \brief Create a sound file from a custom stream for reading /// /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. @@ -95,7 +149,7 @@ public: /// \return Input sound file if the file was successfully opened, otherwise `std::nullopt` /// //////////////////////////////////////////////////////////// - [[nodiscard]] static std::optional openFromStream(InputStream& stream); + [[nodiscard]] static std::optional createFromStream(InputStream& stream); //////////////////////////////////////////////////////////// /// \brief Get the total number of audio samples in the file @@ -212,14 +266,6 @@ public: void close(); private: - //////////////////////////////////////////////////////////// - /// \brief Default constructor - /// - /// Useful for implementing close() - /// - //////////////////////////////////////////////////////////// - InputSoundFile() = default; - //////////////////////////////////////////////////////////// /// \brief Deleter for input streams that only conditionally deletes /// @@ -237,16 +283,6 @@ private: bool owned{true}; }; - //////////////////////////////////////////////////////////// - /// \brief Constructor from reader, stream, and attributes - /// - //////////////////////////////////////////////////////////// - InputSoundFile(std::unique_ptr&& reader, - std::unique_ptr&& stream, - std::uint64_t sampleCount, - unsigned int sampleRate, - std::vector&& channelMap); - //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// @@ -275,7 +311,7 @@ private: /// Usage example: /// \code /// // Open a sound file -/// auto file = sf::InputSoundFile::openFromFile("music.ogg").value(); +/// auto file = sf::InputSoundFile::createFromFile("music.ogg").value(); /// /// // Print the sound attributes /// std::cout << "duration: " << file.getDuration().asSeconds() << '\n' diff --git a/include/SFML/Audio/Music.hpp b/include/SFML/Audio/Music.hpp index 7d69b99ce..546fe220b 100644 --- a/include/SFML/Audio/Music.hpp +++ b/include/SFML/Audio/Music.hpp @@ -66,6 +66,14 @@ public: // Define the relevant Span types using TimeSpan = Span