diff --git a/CSFML/src/Audio/CustomSoundRecorder.cpp b/CSFML/src/Audio/CustomSoundRecorder.cpp index a3f69417..e19dfc12 100644 --- a/CSFML/src/Audio/CustomSoundRecorder.cpp +++ b/CSFML/src/Audio/CustomSoundRecorder.cpp @@ -18,16 +18,13 @@ class sfCustomSoundRecorder final : public sf::SoundRecorder { myStopCb(onStop), myUserData(userData) { } - virtual void setProcessingInterval(int64_t interval) final { - sf::SoundRecorder::setProcessingInterval(sf::microseconds(interval)); - } private: virtual bool onStart() final { return myStartCb(myUserData); } - virtual bool onProcessSamples(const sf::Int16 *samples, std::size_t sampleCount) final { + virtual bool onProcessSamples(const std::int16_t *samples, std::size_t sampleCount) final { return myProcessCb(samples, sampleCount, myUserData); } @@ -64,10 +61,6 @@ extern "C" unsigned int sfCustomSoundRecorder_getSampleRate(const sfCustomSoundR return soundRecorder->getSampleRate(); } -extern "C" void sfCustomSoundRecorder_setProcessingInterval(sfCustomSoundRecorder *soundRecorder, int64_t interval) { - soundRecorder->setProcessingInterval(interval); -} - extern "C" bool sfCustomSoundRecorder_setDevice(sfCustomSoundRecorder *soundRecorder, const char *name) { return soundRecorder->setDevice(name); } diff --git a/CSFML/src/Audio/CustomSoundStream.cpp b/CSFML/src/Audio/CustomSoundStream.cpp index 80ab04fe..365e9dba 100644 --- a/CSFML/src/Audio/CustomSoundStream.cpp +++ b/CSFML/src/Audio/CustomSoundStream.cpp @@ -1,3 +1,4 @@ +#include "SFML/Audio/SoundChannel.hpp" #include "System/Vector3.hpp" #include #include @@ -11,10 +12,11 @@ class sfCustomSoundStream final : public sf::SoundStream { sfCustomSoundStreamSeekCb onSeek, unsigned int channelCount, unsigned int sampleRate, + const std::vector *channel, void *userData) : myGetDataCb(onGetData), mySeekCallCb(onSeek), myUserData(userData) { - initialize(channelCount, sampleRate); + initialize(channelCount, sampleRate, *channel); } private: @@ -35,8 +37,9 @@ extern "C" sfCustomSoundStream *sfCustomSoundStream_new(sfCustomSoundStreamGetDa sfCustomSoundStreamSeekCb onSeek, unsigned int channelCount, unsigned int sampleRate, + const std::vector *channel, void *userData) { - return new sfCustomSoundStream(onGetData, onSeek, channelCount, sampleRate, userData); + return new sfCustomSoundStream(onGetData, onSeek, channelCount, sampleRate, channel, userData); } extern "C" void sfCustomSoundStream_del(sfCustomSoundStream *soundStream) { @@ -68,6 +71,10 @@ extern "C" unsigned int sfCustomSoundStream_getSampleRate(const sfCustomSoundStr return soundStream->getSampleRate(); } +extern "C" const std::vector *sfCustomSoundStream_getChannelMap(const sfCustomSoundStream *soundStream) { + return new std::vector(soundStream->getChannelMap()); +} + extern "C" void sfCustomSoundStream_setPitch(sfCustomSoundStream *soundStream, float pitch) { soundStream->setPitch(pitch); } @@ -76,8 +83,8 @@ extern "C" void sfCustomSoundStream_setVolume(sfCustomSoundStream *soundStream, soundStream->setVolume(volume); } -extern "C" void sfCustomSoundStream_setPosition(sfCustomSoundStream *soundStream, sfVector3f position) { - soundStream->setPosition(position.x, position.y, position.z); +extern "C" void sfCustomSoundStream_setPosition(sfCustomSoundStream *soundStream, sf::Vector3f position) { + soundStream->setPosition(position); } extern "C" void sfCustomSoundStream_setRelativeToListener(sfCustomSoundStream *soundStream, bool relative) { @@ -96,8 +103,8 @@ extern "C" void sfCustomSoundStream_setPlayingOffset(sfCustomSoundStream *soundS soundStream->setPlayingOffset(sf::microseconds(timeOffset)); } -extern "C" void sfCustomSoundStream_setLoop(sfCustomSoundStream *soundStream, bool loop) { - soundStream->setLoop(loop); +extern "C" void sfCustomSoundStream_setLooping(sfCustomSoundStream *soundStream, bool loop) { + soundStream->setLooping(loop); } extern "C" float sfCustomSoundStream_getPitch(const sfCustomSoundStream *soundStream) { @@ -125,8 +132,8 @@ extern "C" float sfCustomSoundStream_getAttenuation(const sfCustomSoundStream *s return soundStream->getAttenuation(); } -extern "C" bool sfCustomSoundStream_getLoop(const sfCustomSoundStream *soundStream) { - return soundStream->getLoop(); +extern "C" bool sfCustomSoundStream_isLooping(const sfCustomSoundStream *soundStream) { + return soundStream->isLooping(); } extern "C" int64_t sfCustomSoundStream_getPlayingOffset(const sfCustomSoundStream *soundStream) { diff --git a/CSFML/src/Audio/Listener.cpp b/CSFML/src/Audio/Listener.cpp index 63c3b3b5..ba36a6ce 100644 --- a/CSFML/src/Audio/Listener.cpp +++ b/CSFML/src/Audio/Listener.cpp @@ -9,29 +9,29 @@ extern "C" float sfListener_getGlobalVolume(void) { return sf::Listener::getGlobalVolume(); } -extern "C" void sfListener_setPosition(sfVector3f position) { - sf::Listener::setPosition(position.x, position.y, position.z); +extern "C" void sfListener_setPosition(sf::Vector3f position) { + sf::Listener::setPosition(position); } -extern "C" sfVector3f sfListener_getPosition() { +extern "C" sf::Vector3f sfListener_getPosition() { sf::Vector3f pos = sf::Listener::getPosition(); return {pos.x, pos.y, pos.z}; } -extern "C" void sfListener_setDirection(sfVector3f direction) { - sf::Listener::setDirection(direction.x, direction.y, direction.z); +extern "C" void sfListener_setDirection(sf::Vector3f direction) { + sf::Listener::setDirection(direction); } -extern "C" sfVector3f sfListener_getDirection() { +extern "C" sf::Vector3f sfListener_getDirection() { sf::Vector3f dir = sf::Listener::getDirection(); return {dir.x, dir.y, dir.z}; } -extern "C" void sfListener_setUpVector(sfVector3f upVector) { - sf::Listener::setUpVector(upVector.x, upVector.y, upVector.z); +extern "C" void sfListener_setUpVector(sf::Vector3f upVector) { + sf::Listener::setUpVector(upVector); } -extern "C" sfVector3f sfListener_getUpVector() { +extern "C" sf::Vector3f sfListener_getUpVector() { sf::Vector3f vec = sf::Listener::getUpVector(); return {vec.x, vec.y, vec.z}; } diff --git a/CSFML/src/Audio/Music.cpp b/CSFML/src/Audio/Music.cpp index 7e388412..905eb719 100644 --- a/CSFML/src/Audio/Music.cpp +++ b/CSFML/src/Audio/Music.cpp @@ -17,7 +17,7 @@ extern "C" void sfMusic_del(sf::Music *music) { } extern "C" bool sfMusic_openFromFile(sf::Music *music, const char *filename) { - return music->openFromFile(filename); + return music->openFromFile(std::filesystem::path(filename)); } extern "C" bool sfMusic_openFromMemory(sf::Music *music, const uint8_t *data, size_t sizeInBytes) { @@ -28,12 +28,12 @@ extern "C" bool sfMusic_openFromStream(sf::Music *music, sfInputStreamHelper *st return music->openFromStream(*stream); } -extern "C" void sfMusic_setLoop(sf::Music *music, bool loop) { - music->setLoop(loop != 0); +extern "C" void sfMusic_setLooping(sf::Music *music, bool loop) { + music->setLooping(loop != 0); } -extern "C" bool sfMusic_getLoop(const sf::Music *music) { - return music->getLoop(); +extern "C" bool sfMusic_isLooping(const sf::Music *music) { + return music->isLooping(); } extern "C" int64_t sfMusic_getDuration(const sf::Music *music) { @@ -46,8 +46,8 @@ extern "C" sfTimeSpan sfMusic_getLoopPoints(const sf::Music *music) { } extern "C" void sfMusic_setLoopPoints(sf::Music *music, sfTimeSpan timePoints) { - music->setLoopPoints(sf::Music::TimeSpan(sf::microseconds(timePoints.offset), - sf::microseconds(timePoints.length))); + music->setLoopPoints({sf::microseconds(timePoints.offset), + sf::microseconds(timePoints.length)}); } extern "C" void sfMusic_play(sf::Music *music) { @@ -87,8 +87,8 @@ extern "C" void sfMusic_setVolume(sf::Music *music, float volume) { music->setVolume(volume); } -extern "C" void sfMusic_setPosition(sf::Music *music, sfVector3f position) { - music->setPosition(sf::Vector3f(position.x, position.y, position.z)); +extern "C" void sfMusic_setPosition(sf::Music *music, sf::Vector3f position) { + music->setPosition(position); } extern "C" void sfMusic_setRelativeToListener(sf::Music *music, bool relative) { diff --git a/CSFML/src/Audio/Sound.cpp b/CSFML/src/Audio/Sound.cpp index 08d9f570..14d32c2b 100644 --- a/CSFML/src/Audio/Sound.cpp +++ b/CSFML/src/Audio/Sound.cpp @@ -1,9 +1,11 @@ #include "System/Vector3.hpp" -#include +#include +#include +#include #include -extern "C" sf::Sound *sfSound_new(void) { - return new sf::Sound; +extern "C" sf::Sound *sfSound_new(const sf::SoundBuffer *buffer) { + return new sf::Sound(*buffer); } extern "C" sf::Sound *sfSound_cpy(const sf::Sound *sound) { @@ -31,16 +33,15 @@ extern "C" void sfSound_setBuffer(sf::Sound *sound, const sf::SoundBuffer *buffe } extern "C" const sf::SoundBuffer *sfSound_getBuffer(const sf::Sound *sound) { - const sf::Sound *s = sound; - return s->getBuffer(); + return &sound->getBuffer(); } -extern "C" void sfSound_setLoop(sf::Sound *sound, bool loop) { - sound->setLoop(loop); +extern "C" void sfSound_setLooping(sf::Sound *sound, bool loop) { + sound->setLooping(loop); } -extern "C" bool sfSound_getLoop(const sf::Sound *sound) { - return sound->getLoop(); +extern "C" bool sfSound_isLooping(const sf::Sound *sound) { + return sound->isLooping(); } extern "C" sf::Sound::Status sfSound_getStatus(const sf::Sound *sound) { @@ -72,7 +73,7 @@ extern "C" void sfSound_setAttenuation(sf::Sound *sound, float attenuation) { } extern "C" void sfSound_setPlayingOffset(sf::Sound *sound, int64_t timeOffset) { - sound->setPlayingOffset(sf::microseconds(timeOffset)); + sound->setPlayingOffset(std::chrono::microseconds(timeOffset)); } extern "C" float sfSound_getPitch(const sf::Sound *sound) { diff --git a/CSFML/src/Audio/SoundBuffer.cpp b/CSFML/src/Audio/SoundBuffer.cpp index a611661e..9bc2d55f 100644 --- a/CSFML/src/Audio/SoundBuffer.cpp +++ b/CSFML/src/Audio/SoundBuffer.cpp @@ -26,8 +26,8 @@ extern "C" bool sfSoundBuffer_loadFromStream(sf::SoundBuffer *buffer, sfInputStr return buffer->loadFromStream(*stream); } -extern "C" bool sfSoundBuffer_loadFromSamples(sf::SoundBuffer *buffer, const int16_t *samples, uint64_t sampleCount, unsigned int channelCount, unsigned int sampleRate) { - return buffer->loadFromSamples(samples, sampleCount, channelCount, sampleRate); +extern "C" bool sfSoundBuffer_loadFromSamples(sf::SoundBuffer *buffer, const int16_t *samples, uint64_t sampleCount, unsigned int channelCount, unsigned int sampleRate, const std::vector *channelMap) { + return buffer->loadFromSamples(samples, sampleCount, channelCount, sampleRate, *channelMap); } extern "C" bool sfSoundBuffer_saveToFile(const sf::SoundBuffer *soundBuffer, const char *filename) { diff --git a/CSFML/src/Audio/SoundChannel.cpp b/CSFML/src/Audio/SoundChannel.cpp new file mode 100644 index 00000000..a5152fbe --- /dev/null +++ b/CSFML/src/Audio/SoundChannel.cpp @@ -0,0 +1,15 @@ +#include "Audio/SoundChannel.hpp" +#include +#include + +extern "C" std::size_t sfSoundChannelVector_getLength(const std::vector *vec) { + return vec->size(); +} + +extern "C" const sf::SoundChannel *sfSoundChannelVector_getData(const std::vector *vec) { + return vec->data(); +} + +extern "C" void sfSoundChannelVector_del(const std::vector *vec) { + delete vec; +} diff --git a/CSFML/src/Audio/SoundChannel.hpp b/CSFML/src/Audio/SoundChannel.hpp new file mode 100644 index 00000000..bfd6f594 --- /dev/null +++ b/CSFML/src/Audio/SoundChannel.hpp @@ -0,0 +1,24 @@ +#pragma once + +enum sfSoundChannel { + Unspecified, + Mono, + FrontLeft, + FrontRight, + FrontCenter, + FrontLeftOfCenter, + FrontRightOfCenter, + LowFrequencyEffects, + BackLeft, + BackRight, + BackCenter, + SideLeft, + SideRight, + TopCenter, + TopFrontLeft, + TopFrontRight, + TopFrontCenter, + TopBackLeft, + TopBackRight, + TopBackCenter +}; diff --git a/CSFML/src/Graphics/BlendMode.hpp b/CSFML/src/Graphics/BlendMode.hpp new file mode 100644 index 00000000..e5980c9a --- /dev/null +++ b/CSFML/src/Graphics/BlendMode.hpp @@ -0,0 +1,43 @@ +#pragma once +//////////////////////////////////////////////////////////// +/// \brief Enumeration of the blending factors +/// +//////////////////////////////////////////////////////////// +typedef enum { + sfBlendFactorZero, ///< (0, 0, 0, 0) + sfBlendFactorOne, ///< (1, 1, 1, 1) + sfBlendFactorSrcColor, ///< (src.r, src.g, src.b, src.a) + sfBlendFactorOneMinusSrcColor, ///< (1, 1, 1, 1) - (src.r, src.g, src.b, src.a) + sfBlendFactorDstColor, ///< (dst.r, dst.g, dst.b, dst.a) + sfBlendFactorOneMinusDstColor, ///< (1, 1, 1, 1) - (dst.r, dst.g, dst.b, dst.a) + sfBlendFactorSrcAlpha, ///< (src.a, src.a, src.a, src.a) + sfBlendFactorOneMinusSrcAlpha, ///< (1, 1, 1, 1) - (src.a, src.a, src.a, src.a) + sfBlendFactorDstAlpha, ///< (dst.a, dst.a, dst.a, dst.a) + sfBlendFactorOneMinusDstAlpha ///< (1, 1, 1, 1) - (dst.a, dst.a, dst.a, dst.a) +} sfBlendFactor; + +//////////////////////////////////////////////////////////// +/// \brief Enumeration of the blending equations +/// +//////////////////////////////////////////////////////////// +typedef enum { + sfBlendEquationAdd, ///< Pixel = Src * SrcFactor + Dst * DstFactor + sfBlendEquationSubtract, ///< Pixel = Src * SrcFactor - Dst * DstFactor + sfBlendEquationReverseSubtract, ///< Pixel = Dst * DstFactor - Src * SrcFactor + sfBlendEquationMin, ///< Pixel = min(Dst, Src) + sfBlendEquationMax ///< Pixel = max(Dst, Src) +} sfBlendEquation; + +//////////////////////////////////////////////////////////// +/// \brief Blending mode for drawing +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfBlendFactor colorSrcFactor; ///< Source blending factor for the color channels + sfBlendFactor colorDstFactor; ///< Destination blending factor for the color channels + sfBlendEquation colorEquation; ///< Blending equation for the color channels + sfBlendFactor alphaSrcFactor; ///< Source blending factor for the alpha channel + sfBlendFactor alphaDstFactor; ///< Destination blending factor for the alpha channel + sfBlendEquation alphaEquation; ///< Blending equation for the alpha channel +} sfBlendMode; diff --git a/CSFML/src/Graphics/CircleShape.cpp b/CSFML/src/Graphics/CircleShape.cpp index b88f5c12..66104974 100644 --- a/CSFML/src/Graphics/CircleShape.cpp +++ b/CSFML/src/Graphics/CircleShape.cpp @@ -18,19 +18,19 @@ extern "C" void sfCircleShape_del(sf::CircleShape *shape) { } extern "C" void sfCircleShape_setPosition(sf::CircleShape *shape, sfVector2f position) { - shape->setPosition(position.x, position.y); + shape->setPosition(sf::Vector2f(position.x, position.y)); } extern "C" void sfCircleShape_setRotation(sf::CircleShape *shape, float angle) { - shape->setRotation(angle); + shape->setRotation(sf::degrees(angle)); } extern "C" void sfCircleShape_setScale(sf::CircleShape *shape, sfVector2f scale) { - shape->setScale(scale.x, scale.y); + shape->setScale(sf::Vector2f(scale.x, scale.y)); } extern "C" void sfCircleShape_setOrigin(sf::CircleShape *shape, sfVector2f origin) { - shape->setOrigin(origin.x, origin.y); + shape->setOrigin(sf::Vector2f(origin.x, origin.y)); } extern "C" sfVector2f sfCircleShape_getPosition(const sf::CircleShape *shape) { @@ -39,7 +39,7 @@ extern "C" sfVector2f sfCircleShape_getPosition(const sf::CircleShape *shape) { } extern "C" float sfCircleShape_getRotation(const sf::CircleShape *shape) { - return shape->getRotation(); + return shape->getRotation().asDegrees(); } extern "C" sfVector2f sfCircleShape_getScale(const sf::CircleShape *shape) { @@ -53,15 +53,15 @@ extern "C" sfVector2f sfCircleShape_getOrigin(const sf::CircleShape *shape) { } extern "C" void sfCircleShape_move(sf::CircleShape *shape, sfVector2f offset) { - shape->move(offset.x, offset.y); + shape->move(sf::Vector2f(offset.x, offset.y)); } extern "C" void sfCircleShape_rotate(sf::CircleShape *shape, float angle) { - shape->rotate(angle); + shape->rotate(sf::degrees(angle)); } extern "C" void sfCircleShape_scale(sf::CircleShape *shape, sfVector2f factors) { - shape->scale(factors.x, factors.y); + shape->scale(sf::Vector2f(factors.x, factors.y)); } extern "C" sf::Transform const *sfCircleShape_getTransform(const sf::CircleShape *shape) { @@ -77,7 +77,7 @@ extern "C" void sfCircleShape_setTexture(sf::CircleShape *shape, const sf::Textu } extern "C" void sfCircleShape_setTextureRect(sf::CircleShape *shape, sfIntRect rect) { - shape->setTextureRect(sf::IntRect(rect.left, rect.top, rect.width, rect.height)); + shape->setTextureRect({sf::Vector2i(rect.position.x, rect.position.y), sf::Vector2i(rect.size.x, rect.size.y)}); } extern "C" void sfCircleShape_setFillColor(sf::CircleShape *shape, sfColor color) { @@ -98,7 +98,7 @@ extern "C" const sf::Texture *sfCircleShape_getTexture(const sf::CircleShape *sh extern "C" sfIntRect sfCircleShape_getTextureRect(const sf::CircleShape *shape) { sf::IntRect rect = shape->getTextureRect(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfColor sfCircleShape_getFillColor(const sf::CircleShape *shape) { @@ -138,10 +138,10 @@ extern "C" void sfCircleShape_setPointCount(sf::CircleShape *shape, size_t count extern "C" sfFloatRect sfCircleShape_getLocalBounds(const sf::CircleShape *shape) { sf::FloatRect rect = shape->getLocalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfFloatRect sfCircleShape_getGlobalBounds(const sf::CircleShape *shape) { sf::FloatRect rect = shape->getGlobalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } diff --git a/CSFML/src/Graphics/ConvexShape.cpp b/CSFML/src/Graphics/ConvexShape.cpp index d6016e6d..b0d65ce0 100644 --- a/CSFML/src/Graphics/ConvexShape.cpp +++ b/CSFML/src/Graphics/ConvexShape.cpp @@ -18,19 +18,19 @@ extern "C" void sfConvexShape_del(sf::ConvexShape *shape) { } extern "C" void sfConvexShape_setPosition(sf::ConvexShape *shape, sfVector2f position) { - shape->setPosition(position.x, position.y); + shape->setPosition(sf::Vector2f(position.x, position.y)); } extern "C" void sfConvexShape_setRotation(sf::ConvexShape *shape, float angle) { - shape->setRotation(angle); + shape->setRotation(sf::degrees(angle)); } extern "C" void sfConvexShape_setScale(sf::ConvexShape *shape, sfVector2f scale) { - shape->setScale(scale.x, scale.y); + shape->setScale(sf::Vector2f(scale.x, scale.y)); } extern "C" void sfConvexShape_setOrigin(sf::ConvexShape *shape, sfVector2f origin) { - shape->setOrigin(origin.x, origin.y); + shape->setOrigin(sf::Vector2f(origin.x, origin.y)); } extern "C" sfVector2f sfConvexShape_getPosition(const sf::ConvexShape *shape) { @@ -39,7 +39,7 @@ extern "C" sfVector2f sfConvexShape_getPosition(const sf::ConvexShape *shape) { } extern "C" float sfConvexShape_getRotation(const sf::ConvexShape *shape) { - return shape->getRotation(); + return shape->getRotation().asDegrees(); } extern "C" sfVector2f sfConvexShape_getScale(const sf::ConvexShape *shape) { @@ -53,15 +53,15 @@ extern "C" sfVector2f sfConvexShape_getOrigin(const sf::ConvexShape *shape) { } extern "C" void sfConvexShape_move(sf::ConvexShape *shape, sfVector2f offset) { - shape->move(offset.x, offset.y); + shape->move(sf::Vector2f(offset.x, offset.y)); } extern "C" void sfConvexShape_rotate(sf::ConvexShape *shape, float angle) { - shape->rotate(angle); + shape->rotate(sf::degrees(angle)); } extern "C" void sfConvexShape_scale(sf::ConvexShape *shape, sfVector2f factors) { - shape->scale(factors.x, factors.y); + shape->scale(sf::Vector2f(factors.x, factors.y)); } extern "C" sf::Transform const *sfConvexShape_getTransform(const sf::ConvexShape *shape) { @@ -77,7 +77,7 @@ extern "C" void sfConvexShape_setTexture(sf::ConvexShape *shape, const sf::Textu } extern "C" void sfConvexShape_setTextureRect(sf::ConvexShape *shape, sfIntRect rect) { - shape->setTextureRect(sf::IntRect(rect.left, rect.top, rect.width, rect.height)); + shape->setTextureRect({{rect.position.x, rect.position.y}, {rect.size.x, rect.size.y}}); } extern "C" void sfConvexShape_setFillColor(sf::ConvexShape *shape, sfColor color) { @@ -98,7 +98,7 @@ extern "C" const sf::Texture *sfConvexShape_getTexture(const sf::ConvexShape *sh extern "C" sfIntRect sfConvexShape_getTextureRect(const sf::ConvexShape *shape) { sf::IntRect rect = shape->getTextureRect(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfColor sfConvexShape_getFillColor(const sf::ConvexShape *shape) { @@ -129,15 +129,15 @@ extern "C" void sfConvexShape_setPointCount(sf::ConvexShape *shape, size_t count } extern "C" void sfConvexShape_setPoint(sf::ConvexShape *shape, size_t index, sfVector2f point) { - shape->setPoint(index, sf::Vector2f(point.x, point.y)); + shape->setPoint(index, sf::Vector2f({point.x, point.y})); } extern "C" sfFloatRect sfConvexShape_getLocalBounds(const sf::ConvexShape *shape) { sf::FloatRect rect = shape->getLocalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfFloatRect sfConvexShape_getGlobalBounds(const sf::ConvexShape *shape) { sf::FloatRect rect = shape->getGlobalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } diff --git a/CSFML/src/Graphics/CoordinateType.hpp b/CSFML/src/Graphics/CoordinateType.hpp new file mode 100644 index 00000000..0455bb61 --- /dev/null +++ b/CSFML/src/Graphics/CoordinateType.hpp @@ -0,0 +1,10 @@ +#pragma once + +//////////////////////////////////////////////////////////// +/// \brief Types of texture coordinates that can be used for rendering. +/// +//////////////////////////////////////////////////////////// +typedef enum { + sfCoordinateTypeNormalized, ///< sfTexture coordinates in range [0 .. 1]. + sfCoordinateTypePixels ///< sfTexture coordinates in range [0 .. size]. +} sfCoordinateType; diff --git a/CSFML/src/Graphics/CustomShape.cpp b/CSFML/src/Graphics/CustomShape.cpp index 1204b413..d75d9118 100644 --- a/CSFML/src/Graphics/CustomShape.cpp +++ b/CSFML/src/Graphics/CustomShape.cpp @@ -1,5 +1,7 @@ #include "Graphics/Color.hpp" #include "Graphics/Rect.hpp" +#include "SFML/System/Angle.hpp" +#include "SFML/System/Vector2.hpp" #include "System/Vector2.hpp" #include #include @@ -23,7 +25,7 @@ class sfCustomShape final : public sf::Shape { virtual sf::Vector2f getPoint(std::size_t index) const final { sfVector2f point = myGetPointCb(index, myUserData); - return sf::Vector2f(point.x, point.y); + return sf::Vector2f({point.x, point.y}); } using sf::Shape::update; @@ -45,19 +47,19 @@ extern "C" void sfCustomShape_del(sfCustomShape *shape) { } extern "C" void sfCustomShape_setPosition(sfCustomShape *shape, sfVector2f position) { - shape->setPosition(position.x, position.y); + shape->setPosition(sf::Vector2f(position.x, position.y)); } extern "C" void sfCustomShape_setRotation(sfCustomShape *shape, float angle) { - shape->setRotation(angle); + shape->setRotation(sf::degrees(angle)); } extern "C" void sfCustomShape_setScale(sfCustomShape *shape, sfVector2f scale) { - shape->setScale(scale.x, scale.y); + shape->setScale(sf::Vector2f(scale.x, scale.y)); } extern "C" void sfCustomShape_setOrigin(sfCustomShape *shape, sfVector2f origin) { - shape->setOrigin(origin.x, origin.y); + shape->setOrigin(sf::Vector2f(origin.x, origin.y)); } extern "C" sfVector2f sfCustomShape_getPosition(const sfCustomShape *shape) { @@ -66,7 +68,7 @@ extern "C" sfVector2f sfCustomShape_getPosition(const sfCustomShape *shape) { } extern "C" float sfCustomShape_getRotation(const sfCustomShape *shape) { - return shape->getRotation(); + return shape->getRotation().asDegrees(); } extern "C" sfVector2f sfCustomShape_getScale(const sfCustomShape *shape) { @@ -80,15 +82,15 @@ extern "C" sfVector2f sfCustomShape_getOrigin(const sfCustomShape *shape) { } extern "C" void sfCustomShape_move(sfCustomShape *shape, sfVector2f offset) { - shape->move(offset.x, offset.y); + shape->move(sf::Vector2f(offset.x, offset.y)); } extern "C" void sfCustomShape_rotate(sfCustomShape *shape, float angle) { - shape->rotate(angle); + shape->rotate(sf::degrees(angle)); } extern "C" void sfCustomShape_scale(sfCustomShape *shape, sfVector2f factors) { - shape->scale(factors.x, factors.y); + shape->scale(sf::Vector2f(factors.x, factors.y)); } extern "C" sf::Transform const *sfCustomShape_getTransform(const sfCustomShape *shape) { @@ -104,7 +106,7 @@ extern "C" void sfCustomShape_setTexture(sfCustomShape *shape, const sf::Texture } extern "C" void sfCustomShape_setTextureRect(sfCustomShape *shape, sfIntRect rect) { - shape->setTextureRect(sf::IntRect(rect.left, rect.top, rect.width, rect.height)); + shape->setTextureRect({{rect.position.x, rect.position.y}, {rect.size.x, rect.size.y}}); } extern "C" void sfCustomShape_setFillColor(sfCustomShape *shape, sfColor color) { @@ -125,7 +127,7 @@ extern "C" const sf::Texture *sfCustomShape_getTexture(const sfCustomShape *shap extern "C" sfIntRect sfCustomShape_getTextureRect(const sfCustomShape *shape) { sf::IntRect rect = shape->getTextureRect(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfColor sfCustomShape_getFillColor(const sfCustomShape *shape) { @@ -153,12 +155,12 @@ extern "C" sfVector2f sfCustomShape_getPoint(const sfCustomShape *shape, size_t extern "C" sfFloatRect sfCustomShape_getLocalBounds(const sfCustomShape *shape) { sf::FloatRect rect = shape->getLocalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfFloatRect sfCustomShape_getGlobalBounds(const sfCustomShape *shape) { sf::FloatRect rect = shape->getGlobalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" void sfCustomShape_update(sfCustomShape *shape) { diff --git a/CSFML/src/Graphics/Font.cpp b/CSFML/src/Graphics/Font.cpp index acd91059..9e544925 100644 --- a/CSFML/src/Graphics/Font.cpp +++ b/CSFML/src/Graphics/Font.cpp @@ -22,23 +22,23 @@ extern "C" sf::Font *sfFont_cpy(const sf::Font *font) { } extern "C" bool sfFont_loadFromFile(sf::Font *font, const char *filename) { - return font->loadFromFile(filename); + return font->openFromFile(filename); } extern "C" bool sfFont_loadFromMemory(sf::Font *font, const uint8_t *data, size_t sizeInBytes) { - return font->loadFromMemory(data, sizeInBytes); + return font->openFromMemory(data, sizeInBytes); } extern "C" bool sfFont_loadFromStream(sf::Font *font, sfInputStreamHelper *stream) { - return font->loadFromStream(*stream); + return font->openFromStream(*stream); } extern "C" sfGlyph sfFont_getGlyph(const sf::Font *font, uint32_t codePoint, unsigned int characterSize, bool bold, float outlineThickness) { sf::Glyph glyph = font->getGlyph(codePoint, characterSize, bold, outlineThickness); return { glyph.advance, - {glyph.bounds.left, glyph.bounds.top, glyph.bounds.width, glyph.bounds.height}, - {glyph.textureRect.left, glyph.textureRect.top, glyph.textureRect.width, glyph.textureRect.height}}; + {glyph.bounds.position.x, glyph.bounds.position.y, glyph.bounds.size.x, glyph.bounds.size.y}, + {glyph.textureRect.position.x, glyph.textureRect.position.y, glyph.textureRect.size.x, glyph.textureRect.size.y}}; } extern "C" float sfFont_getKerning(const sf::Font *font, uint32_t first, uint32_t second, unsigned int characterSize) { diff --git a/CSFML/src/Graphics/Image.cpp b/CSFML/src/Graphics/Image.cpp index 83b9258d..2c8962ae 100644 --- a/CSFML/src/Graphics/Image.cpp +++ b/CSFML/src/Graphics/Image.cpp @@ -17,12 +17,12 @@ extern "C" void sfImage_del(sf::Image *image) { delete image; } -extern "C" void sfImage_create_w_h_color(sf::Image *image, unsigned int width, unsigned int height, sfColor color) { - image->create(width, height, sf::Color(color.r, color.g, color.b, color.a)); +extern "C" void sfImage_resizeWithColor(sf::Image *image, sfVector2u size, sfColor color) { + image->resize({size.x, size.y}, sf::Color(color.r, color.g, color.b, color.a)); } -extern "C" void sfImage_create_w_h_pixels(sf::Image *image, unsigned int width, unsigned int height, const uint8_t *data) { - image->create(width, height, data); +extern "C" void sfImage_resizeWithPixels(sf::Image *image, sfVector2u size, const uint8_t *pixels) { + image->resize({size.x, size.y}, pixels); } extern "C" bool sfImage_loadFromFile(sf::Image *image, const char *filename) { @@ -45,17 +45,17 @@ extern "C" void sfImage_createMaskFromColor(sf::Image *image, sfColor colorKey, image->createMaskFromColor(sf::Color(colorKey.r, colorKey.g, colorKey.b, colorKey.a), alpha); } -extern "C" void sfImage_copy(sf::Image *image, const sf::Image *source, unsigned int destX, unsigned int destY, sfIntRect sourceRect, bool applyAlpha) { - sf::IntRect sfmlRect(sourceRect.left, sourceRect.top, sourceRect.width, sourceRect.height); - image->copy(*source, destX, destY, sfmlRect, applyAlpha); +extern "C" bool sfImage_copy(sf::Image *image, const sf::Image *source, sfVector2u dest, sfIntRect sourceRect, bool applyAlpha) { + sf::IntRect sfmlRect = {{sourceRect.position.x, sourceRect.position.y}, {sourceRect.size.x, sourceRect.size.y}}; + return image->copy(*source, sf::Vector2u(dest.x, dest.y), sfmlRect, applyAlpha); } -extern "C" void sfImage_setPixel(sf::Image *image, unsigned int x, unsigned int y, sfColor color) { - image->setPixel(x, y, sf::Color(color.r, color.g, color.b, color.a)); +extern "C" void sfImage_setPixel(sf::Image *image, sfVector2u coords, sfColor color) { + image->setPixel(sf::Vector2u(coords.x, coords.y), sf::Color(color.r, color.g, color.b, color.a)); } -extern "C" sfColor sfImage_getPixel(const sf::Image *image, unsigned int x, unsigned int y) { - sf::Color color = image->getPixel(x, y); +extern "C" sfColor sfImage_getPixel(const sf::Image *image, sfVector2u coords) { + sf::Color color = image->getPixel(sf::Vector2u(coords.x, coords.y)); return sfColor{color.r, color.g, color.b, color.a}; } diff --git a/CSFML/src/Graphics/PrimitiveType.hpp b/CSFML/src/Graphics/PrimitiveType.hpp new file mode 100644 index 00000000..409d01ad --- /dev/null +++ b/CSFML/src/Graphics/PrimitiveType.hpp @@ -0,0 +1,10 @@ +#pragma once + +typedef enum { + sfPoints, + sfLines, + sfLineStrip, + sfTriangles, + sfTriangleStrip, + sfTriangleFan, +} sfPrimitiveType; diff --git a/CSFML/src/Graphics/Rect.hpp b/CSFML/src/Graphics/Rect.hpp index 041868f0..eb370d09 100644 --- a/CSFML/src/Graphics/Rect.hpp +++ b/CSFML/src/Graphics/Rect.hpp @@ -1,18 +1,15 @@ #ifndef SFML_RECT_H #define SFML_RECT_H +#include "System/Vector2.hpp" struct sfFloatRect { - float left; - float top; - float width; - float height; + sfVector2f position; + sfVector2f size; }; struct sfIntRect { - int left; - int top; - int width; - int height; + sfVector2i position; + sfVector2i size; }; #endif // SFML_RECT_H diff --git a/CSFML/src/Graphics/RectangleShape.cpp b/CSFML/src/Graphics/RectangleShape.cpp index 7afa9a5d..4858d396 100644 --- a/CSFML/src/Graphics/RectangleShape.cpp +++ b/CSFML/src/Graphics/RectangleShape.cpp @@ -1,5 +1,6 @@ #include "Graphics/Color.hpp" #include "Graphics/Rect.hpp" +#include "SFML/System/Vector2.hpp" #include "System/Vector2.hpp" #include #include @@ -18,19 +19,19 @@ extern "C" void sfRectangleShape_del(sf::RectangleShape *shape) { } extern "C" void sfRectangleShape_setPosition(sf::RectangleShape *shape, sfVector2f position) { - shape->setPosition(position.x, position.y); + shape->setPosition(sf::Vector2f(position.x, position.y)); } extern "C" void sfRectangleShape_setRotation(sf::RectangleShape *shape, float angle) { - shape->setRotation(angle); + shape->setRotation(sf::degrees(angle)); } extern "C" void sfRectangleShape_setScale(sf::RectangleShape *shape, sfVector2f scale) { - shape->setScale(scale.x, scale.y); + shape->setScale(sf::Vector2f(scale.x, scale.y)); } extern "C" void sfRectangleShape_setOrigin(sf::RectangleShape *shape, sfVector2f origin) { - shape->setOrigin(origin.x, origin.y); + shape->setOrigin(sf::Vector2f(origin.x, origin.y)); } extern "C" sfVector2f sfRectangleShape_getPosition(const sf::RectangleShape *shape) { @@ -39,7 +40,7 @@ extern "C" sfVector2f sfRectangleShape_getPosition(const sf::RectangleShape *sha } extern "C" float sfRectangleShape_getRotation(const sf::RectangleShape *shape) { - return shape->getRotation(); + return shape->getRotation().asDegrees(); } extern "C" sfVector2f sfRectangleShape_getScale(const sf::RectangleShape *shape) { @@ -53,15 +54,15 @@ extern "C" sfVector2f sfRectangleShape_getOrigin(const sf::RectangleShape *shape } extern "C" void sfRectangleShape_move(sf::RectangleShape *shape, sfVector2f offset) { - shape->move(offset.x, offset.y); + shape->move(sf::Vector2f(offset.x, offset.y)); } extern "C" void sfRectangleShape_rotate(sf::RectangleShape *shape, float angle) { - shape->rotate(angle); + shape->rotate(sf::degrees(angle)); } extern "C" void sfRectangleShape_scale(sf::RectangleShape *shape, sfVector2f factors) { - shape->scale(factors.x, factors.y); + shape->scale(sf::Vector2f(factors.x, factors.y)); } extern "C" sf::Transform const *sfRectangleShape_getTransform(const sf::RectangleShape *shape) { @@ -77,7 +78,7 @@ extern "C" void sfRectangleShape_setTexture(sf::RectangleShape *shape, const sf: } extern "C" void sfRectangleShape_setTextureRect(sf::RectangleShape *shape, sfIntRect rect) { - shape->setTextureRect(sf::IntRect(rect.left, rect.top, rect.width, rect.height)); + shape->setTextureRect({{rect.position.x, rect.position.y}, {rect.size.x, rect.size.y}}); } extern "C" void sfRectangleShape_setFillColor(sf::RectangleShape *shape, sfColor color) { @@ -98,7 +99,7 @@ extern "C" const sf::Texture *sfRectangleShape_getTexture(const sf::RectangleSha extern "C" sfIntRect sfRectangleShape_getTextureRect(const sf::RectangleShape *shape) { sf::IntRect rect = shape->getTextureRect(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfColor sfRectangleShape_getFillColor(const sf::RectangleShape *shape) { @@ -125,7 +126,7 @@ extern "C" sfVector2f sfRectangleShape_getPoint(const sf::RectangleShape *shape, } extern "C" void sfRectangleShape_setSize(sf::RectangleShape *shape, sfVector2f size) { - shape->setSize(sf::Vector2f(size.x, size.y)); + shape->setSize(sf::Vector2f({size.x, size.y})); } extern "C" sfVector2f sfRectangleShape_getSize(const sf::RectangleShape *shape) { @@ -135,10 +136,10 @@ extern "C" sfVector2f sfRectangleShape_getSize(const sf::RectangleShape *shape) extern "C" sfFloatRect sfRectangleShape_getLocalBounds(const sf::RectangleShape *shape) { sf::FloatRect rect = shape->getLocalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfFloatRect sfRectangleShape_getGlobalBounds(const sf::RectangleShape *shape) { sf::FloatRect rect = shape->getGlobalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } diff --git a/CSFML/src/Graphics/RenderStates.hpp b/CSFML/src/Graphics/RenderStates.hpp new file mode 100644 index 00000000..733e3ee8 --- /dev/null +++ b/CSFML/src/Graphics/RenderStates.hpp @@ -0,0 +1,20 @@ +//////////////////////////////////////////////////////////// +/// \brief Define the states used for drawing to a RenderTarget +/// +//////////////////////////////////////////////////////////// +#include "Graphics/BlendMode.hpp" +#include "Graphics/CoordinateType.hpp" +#include "Graphics/StencilMode.hpp" +#include "Graphics/Transform.hpp" +#include +#include + +typedef struct +{ + sfBlendMode blendMode; ///< Blending mode + sfStencilMode stencilMode; //!< Stencil mode + sfTransform transform; ///< Transform + sfCoordinateType coordinateType; //!< Texture coordinate type + const sf::Texture *texture; ///< Texture + const sf::Shader *shader; ///< Shader +} sfRenderStates; diff --git a/CSFML/src/Graphics/RenderTexture.cpp b/CSFML/src/Graphics/RenderTexture.cpp index 6dc447d0..76bbc407 100644 --- a/CSFML/src/Graphics/RenderTexture.cpp +++ b/CSFML/src/Graphics/RenderTexture.cpp @@ -1,5 +1,7 @@ +#include "Graphics/PrimitiveType.hpp" #include "Graphics/Rect.hpp" #include "Graphics/Color.hpp" +#include "SFML/Graphics/PrimitiveType.hpp" #include "SFML/Window/ContextSettings.hpp" #include "System/Vector2.hpp" #include @@ -19,8 +21,8 @@ extern "C" void sfRenderTexture_del(sf::RenderTexture *renderTexture) { delete renderTexture; } -extern "C" bool sfRenderTexture_create(sf::RenderTexture *renderTexture, unsigned int width, unsigned int height, const sf::ContextSettings *settings) { - return renderTexture->create(width, height, *settings); +extern "C" bool sfRenderTexture_resize(sf::RenderTexture *texture, sfVector2u size, const sf::ContextSettings *settings) { + return texture->resize({size.x, size.y}, *settings); } extern "C" sfVector2u sfRenderTexture_getSize(const sf::RenderTexture *renderTexture) { @@ -58,26 +60,26 @@ extern "C" const sf::View *sfRenderTexture_getDefaultView(const sf::RenderTextur extern "C" sfIntRect sfRenderTexture_getViewport(const sf::RenderTexture *renderTexture, const sf::View *view) { sf::IntRect rect = renderTexture->getViewport(*view); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfVector2f sfRenderTexture_mapPixelToCoords(const sf::RenderTexture *renderTexture, sfVector2i point) { - sf::Vector2f result = renderTexture->mapPixelToCoords(sf::Vector2i(point.x, point.y)); + sf::Vector2f result = renderTexture->mapPixelToCoords(sf::Vector2i({point.x, point.y})); return {result.x, result.y}; } extern "C" sfVector2f sfRenderTexture_mapPixelToCoords_View(const sf::RenderTexture *renderTexture, sfVector2i point, const sf::View *targetView) { - sf::Vector2f result = renderTexture->mapPixelToCoords(sf::Vector2i(point.x, point.y), *targetView); + sf::Vector2f result = renderTexture->mapPixelToCoords(sf::Vector2i({point.x, point.y}), *targetView); return {result.x, result.y}; } extern "C" sfVector2i sfRenderTexture_mapCoordsToPixel(const sf::RenderTexture *renderTexture, sfVector2f point) { - sf::Vector2i result = renderTexture->mapCoordsToPixel(sf::Vector2f(point.x, point.y)); + sf::Vector2i result = renderTexture->mapCoordsToPixel(sf::Vector2f({point.x, point.y})); return {result.x, result.y}; } extern "C" sfVector2i sfRenderTexture_mapCoordsToPixel_View(const sf::RenderTexture *renderTexture, sfVector2f point, const sf::View *targetView) { - sf::Vector2i result = renderTexture->mapCoordsToPixel(sf::Vector2f(point.x, point.y), *targetView); + sf::Vector2i result = renderTexture->mapCoordsToPixel(sf::Vector2f({point.x, point.y}), *targetView); return {result.x, result.y}; } @@ -105,8 +107,8 @@ extern "C" void sfRenderTexture_drawVertexBuffer(sf::RenderTexture *renderTextur extern "C" void sfRenderTexture_drawPrimitives(sf::RenderTexture *renderTexture, const sf::Vertex *vertices, size_t vertexCount, - sf::PrimitiveType type, const sf::RenderStates *states) { - renderTexture->draw(vertices, vertexCount, type, *states); + sfPrimitiveType type, const sf::RenderStates *states) { + renderTexture->draw(vertices, vertexCount, static_cast(type), *states); } extern "C" void sfRenderTexture_pushGLStates(sf::RenderTexture *renderTexture) { @@ -130,7 +132,7 @@ extern "C" void sfRenderTexture_setSmooth(sf::RenderTexture *renderTexture, bool } extern "C" unsigned int sfRenderTexture_getMaximumAntialiasingLevel() { - return sf::RenderTexture::getMaximumAntialiasingLevel(); + return sf::RenderTexture::getMaximumAntiAliasingLevel(); } extern "C" bool sfRenderTexture_isSmooth(const sf::RenderTexture *renderTexture) { diff --git a/CSFML/src/Graphics/RenderWindow.cpp b/CSFML/src/Graphics/RenderWindow.cpp index 8be72feb..e369fb95 100644 --- a/CSFML/src/Graphics/RenderWindow.cpp +++ b/CSFML/src/Graphics/RenderWindow.cpp @@ -1,7 +1,11 @@ +#include "Graphics/PrimitiveType.hpp" #include "Graphics/Rect.hpp" #include "Graphics/Color.hpp" +#include "SFML/Graphics/PrimitiveType.hpp" #include "System/Vector2.hpp" +#include "Window/Event.hpp" #include "Window/VideoMode.hpp" +#include "Window/Window.hpp" #include #include #include @@ -11,12 +15,15 @@ #include #include #include +#include #include +// Debug ONLY +#include -extern "C" sf::RenderWindow *sfRenderWindow_new_mtss(sfVideoMode mode, const uint32_t *title, uint32_t style, const sf::ContextSettings *settings) { +extern "C" sf::RenderWindow *sfRenderWindow_new_mtsss(sfVideoMode mode, const uint32_t *title, uint32_t style, sfState state, const sf::ContextSettings *settings) { // Convert video mode - sf::VideoMode videoMode(mode.width, mode.height, mode.bitsPerPixel); - return new sf::RenderWindow(videoMode, title, style, *settings); + sf::VideoMode videoMode(sf::Vector2u(mode.size.x, mode.size.y), mode.bitsPerPixel); + return new sf::RenderWindow(videoMode, (char32_t *)title, style, to_state(state), *settings); } extern "C" sf::RenderWindow *sfRenderWindow_new_handle_settings(sf::WindowHandle handle, const sf::ContextSettings *settings) { @@ -27,13 +34,6 @@ extern "C" void sfRenderWindow_del(sf::RenderWindow *renderWindow) { delete renderWindow; } -extern "C" void sfRenderWindow_create_mtss(sf::RenderWindow *renderWindow, sfVideoMode mode, const uint32_t *title, uint32_t style, const sf::ContextSettings *settings) { - // Convert video mode - sf::VideoMode videoMode(mode.width, mode.height, mode.bitsPerPixel); - // Create the window - renderWindow->create(videoMode, title, style, *settings); -} - extern "C" void sfRenderWindow_close(sf::RenderWindow *renderWindow) { renderWindow->close(); } @@ -46,12 +46,12 @@ extern "C" const sf::ContextSettings *sfRenderWindow_getSettings(const sf::Rende return &renderWindow->getSettings(); } -extern "C" bool sfRenderWindow_pollEvent(sf::RenderWindow *renderWindow, sf::Event *event) { - return renderWindow->pollEvent(*event); +extern "C" bool sfRenderWindow_pollEvent(sf::RenderWindow *renderWindow, sfEvent *event) { + return convertEvent(renderWindow->pollEvent(), *event); } -extern "C" bool sfRenderWindow_waitEvent(sf::RenderWindow *renderWindow, sf::Event *event) { - return renderWindow->waitEvent(*event); +extern "C" bool sfRenderWindow_waitEvent(sf::RenderWindow *renderWindow, sfEvent *event, const int64_t timeout) { + return convertEvent(renderWindow->waitEvent(sf::Time(std::chrono::microseconds(timeout))), *event); } extern "C" sfVector2i sfRenderWindow_getPosition(const sf::RenderWindow *renderWindow) { @@ -69,7 +69,7 @@ extern "C" sfVector2u sfRenderWindow_getSize(const sf::RenderWindow *renderWindo } extern "C" void sfRenderWindow_setSize(sf::RenderWindow *renderWindow, sfVector2u size) { - renderWindow->setSize(sf::Vector2u(size.x, size.y)); + renderWindow->setSize(sf::Vector2u({size.x, size.y})); } extern "C" bool sfRenderWindow_isSrgb(const sf::RenderWindow *renderWindow) { @@ -77,11 +77,11 @@ extern "C" bool sfRenderWindow_isSrgb(const sf::RenderWindow *renderWindow) { } extern "C" void sfRenderWindow_setUnicodeTitle(sf::RenderWindow *renderWindow, const uint32_t *title) { - renderWindow->setTitle(title); + renderWindow->setTitle((char32_t *)title); } -extern "C" void sfRenderWindow_setIcon(sf::RenderWindow *renderWindow, unsigned int width, unsigned int height, const uint8_t *pixels) { - renderWindow->setIcon(width, height, pixels); +extern "C" void sfRenderWindow_setIcon(sf::RenderWindow *renderWindow, sfVector2u size, const uint8_t *pixels) { + renderWindow->setIcon(sf::Vector2u({size.x, size.y}), pixels); } extern "C" void sfRenderWindow_setVisible(sf::RenderWindow *renderWindow, bool visible) { @@ -132,8 +132,8 @@ extern "C" void sfRenderWindow_setJoystickThreshold(sf::RenderWindow *renderWind renderWindow->setJoystickThreshold(threshold); } -extern "C" sf::WindowHandle sfRenderWindow_getSystemHandle(const sf::RenderWindow *renderWindow) { - return renderWindow->getSystemHandle(); +extern "C" sf::WindowHandle sfRenderWindow_getNativeHandle(const sf::RenderWindow *renderWindow) { + return renderWindow->getNativeHandle(); } extern "C" void sfRenderWindow_clear(sf::RenderWindow *renderWindow, sfColor color) { @@ -154,26 +154,26 @@ extern "C" const sf::View *sfRenderWindow_getDefaultView(const sf::RenderWindow extern "C" sfIntRect sfRenderWindow_getViewport(const sf::RenderWindow *renderWindow, const sf::View *view) { sf::IntRect rect = renderWindow->getViewport(*view); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfVector2f sfRenderWindow_mapPixelToCoords(const sf::RenderWindow *renderWindow, sfVector2i point) { - sf::Vector2f vec2 = renderWindow->mapPixelToCoords(sf::Vector2i(point.x, point.y)); + sf::Vector2f vec2 = renderWindow->mapPixelToCoords(sf::Vector2i({point.x, point.y})); return {vec2.x, vec2.y}; } extern "C" sfVector2f sfRenderWindow_mapPixelToCoords_View(const sf::RenderWindow *renderWindow, sfVector2i point, const sf::View *targetView) { - sf::Vector2f vec2 = renderWindow->mapPixelToCoords(sf::Vector2i(point.x, point.y), *targetView); + sf::Vector2f vec2 = renderWindow->mapPixelToCoords(sf::Vector2i({point.x, point.y}), *targetView); return {vec2.x, vec2.y}; } extern "C" sfVector2i sfRenderWindow_mapCoordsToPixel(const sf::RenderWindow *renderWindow, sfVector2f point) { - sf::Vector2i vec2 = renderWindow->mapCoordsToPixel(sf::Vector2f(point.x, point.y)); + sf::Vector2i vec2 = renderWindow->mapCoordsToPixel(sf::Vector2f({point.x, point.y})); return {vec2.x, vec2.y}; } extern "C" sfVector2i sfRenderWindow_mapCoordsToPixel_View(const sf::RenderWindow *renderWindow, sfVector2f point, const sf::View *targetView) { - sf::Vector2i vec2 = renderWindow->mapCoordsToPixel(sf::Vector2f(point.x, point.y), *targetView); + sf::Vector2i vec2 = renderWindow->mapCoordsToPixel(sf::Vector2f({point.x, point.y}), *targetView); return {vec2.x, vec2.y}; } @@ -201,8 +201,8 @@ extern "C" void sfRenderWindow_drawVertexBuffer(sf::RenderWindow *renderWindow, extern "C" void sfRenderWindow_drawPrimitives(sf::RenderWindow *renderWindow, const sf::Vertex *vertices, size_t vertexCount, - sf::PrimitiveType type, const sf::RenderStates *states) { - renderWindow->draw(vertices, vertexCount, type, *states); + sfPrimitiveType type, const sf::RenderStates *states) { + renderWindow->draw(vertices, vertexCount, static_cast(type), *states); } extern "C" void sfRenderWindow_pushGLStates(sf::RenderWindow *renderWindow) { diff --git a/CSFML/src/Graphics/Sprite.cpp b/CSFML/src/Graphics/Sprite.cpp index d0a25ec5..a15db916 100644 --- a/CSFML/src/Graphics/Sprite.cpp +++ b/CSFML/src/Graphics/Sprite.cpp @@ -1,12 +1,13 @@ #include "Graphics/Color.hpp" #include "Graphics/Rect.hpp" +#include "SFML/System/Vector2.hpp" #include "System/Vector2.hpp" #include #include #include -extern "C" sf::Sprite *sfSprite_new(void) { - return new sf::Sprite; +extern "C" sf::Sprite *sfSprite_new(const sf::Texture *texture, const sfIntRect rect) { + return new sf::Sprite(*texture, {sf::Vector2i(rect.position.x, rect.position.y), sf::Vector2i(rect.size.x, rect.size.y)}); } extern "C" sf::Sprite *sfSprite_cpy(const sf::Sprite *sprite) { @@ -18,19 +19,19 @@ extern "C" void sfSprite_del(sf::Sprite *sprite) { } extern "C" void sfSprite_setPosition(sf::Sprite *sprite, sfVector2f position) { - sprite->setPosition(position.x, position.y); + sprite->setPosition(sf::Vector2f(position.x, position.y)); } extern "C" void sfSprite_setRotation(sf::Sprite *sprite, float angle) { - sprite->setRotation(angle); + sprite->setRotation(sf::degrees(angle)); } extern "C" void sfSprite_setScale(sf::Sprite *sprite, sfVector2f scale) { - sprite->setScale(scale.x, scale.y); + sprite->setScale(sf::Vector2f(scale.x, scale.y)); } extern "C" void sfSprite_setOrigin(sf::Sprite *sprite, sfVector2f origin) { - sprite->setOrigin(origin.x, origin.y); + sprite->setOrigin(sf::Vector2f(origin.x, origin.y)); } extern "C" sfVector2f sfSprite_getPosition(const sf::Sprite *sprite) { @@ -39,7 +40,7 @@ extern "C" sfVector2f sfSprite_getPosition(const sf::Sprite *sprite) { } extern "C" float sfSprite_getRotation(const sf::Sprite *sprite) { - return sprite->getRotation(); + return sprite->getRotation().asDegrees(); } extern "C" sfVector2f sfSprite_getScale(const sf::Sprite *sprite) { @@ -53,15 +54,15 @@ extern "C" sfVector2f sfSprite_getOrigin(const sf::Sprite *sprite) { } extern "C" void sfSprite_move(sf::Sprite *sprite, sfVector2f offset) { - sprite->move(offset.x, offset.y); + sprite->move(sf::Vector2f(offset.x, offset.y)); } extern "C" void sfSprite_rotate(sf::Sprite *sprite, float angle) { - sprite->rotate(angle); + sprite->rotate(sf::degrees(angle)); } extern "C" void sfSprite_scale(sf::Sprite *sprite, sfVector2f factors) { - sprite->scale(factors.x, factors.y); + sprite->scale(sf::Vector2f(factors.x, factors.y)); } extern "C" sf::Transform const *sfSprite_getTransform(const sf::Sprite *sprite) { @@ -76,8 +77,8 @@ extern "C" void sfSprite_setTexture(sf::Sprite *sprite, const sf::Texture *textu sprite->setTexture(*texture, resetRect); } -extern "C" void sfSprite_setTextureRect(sf::Sprite *sprite, sfIntRect rectangle) { - sprite->setTextureRect(sf::IntRect(rectangle.left, rectangle.top, rectangle.width, rectangle.height)); +extern "C" void sfSprite_setTextureRect(sf::Sprite *sprite, sfIntRect rect) { + sprite->setTextureRect({{rect.position.x, rect.position.y}, {rect.size.x, rect.size.y}}); } extern "C" void sfSprite_setColor(sf::Sprite *sprite, sfColor color) { @@ -85,12 +86,12 @@ extern "C" void sfSprite_setColor(sf::Sprite *sprite, sfColor color) { } extern "C" const sf::Texture *sfSprite_getTexture(const sf::Sprite *sprite) { - return sprite->getTexture(); + return &sprite->getTexture(); } extern "C" sfIntRect sfSprite_getTextureRect(const sf::Sprite *sprite) { sf::IntRect rect = sprite->getTextureRect(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.position.y}; } extern "C" sfColor sfSprite_getColor(const sf::Sprite *sprite) { @@ -100,10 +101,10 @@ extern "C" sfColor sfSprite_getColor(const sf::Sprite *sprite) { extern "C" sfFloatRect sfSprite_getLocalBounds(const sf::Sprite *sprite) { sf::FloatRect rect = sprite->getLocalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.position.y}; } extern "C" sfFloatRect sfSprite_getGlobalBounds(const sf::Sprite *sprite) { sf::FloatRect rect = sprite->getGlobalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.position.y}; } diff --git a/CSFML/src/Graphics/StencilMode.hpp b/CSFML/src/Graphics/StencilMode.hpp new file mode 100644 index 00000000..5dc3d1ae --- /dev/null +++ b/CSFML/src/Graphics/StencilMode.hpp @@ -0,0 +1,92 @@ +#pragma once +#include + +//////////////////////////////////////////////////////// +/// \brief Enumeration of the stencil test comparisons that can be performed +/// +/// The comparisons are mapped directly to their OpenGL equivalents, +/// specified by `glStencilFunc()`. +//////////////////////////////////////////////////////// +typedef enum { + sfStencilComparisonNever, //!< The stencil test never passes + sfStencilComparisonLess, //!< The stencil test passes if the new value is less than the value in the stencil buffer + sfStencilComparisonLessEqual, //!< The stencil test passes if the new value is less than or equal to the value in the stencil buffer + sfStencilComparisonGreater, //!< The stencil test passes if the new value is greater than the value in the stencil buffer + sfStencilComparisonGreaterEqual, //!< The stencil test passes if the new value is greater than or equal to the value in the stencil buffer + sfStencilComparisonEqual, //!< The stencil test passes if the new value is strictly equal to the value in the stencil buffer + sfStencilComparisonNotEqual, //!< The stencil test passes if the new value is strictly unequal to the value in the stencil buffer + sfStencilComparisonAlways //!< The stencil test always passes +} sfStencilComparison; + +//////////////////////////////////////////////////////// +/// \brief Enumeration of the stencil buffer update operations +/// +/// The update operations are mapped directly to their OpenGL equivalents, +/// specified by `glStencilOp()`. +//////////////////////////////////////////////////////// +typedef enum { + sfStencilUpdateOperationKeep, //!< If the stencil test passes, the value in the stencil buffer is not modified + sfStencilUpdateOperationZero, //!< If the stencil test passes, the value in the stencil buffer is set to zero + sfStencilUpdateOperationReplace, //!< If the stencil test passes, the value in the stencil buffer is set to the new value + sfStencilUpdateOperationIncrement, //!< If the stencil test passes, the value in the stencil buffer is incremented and if required clamped + sfStencilUpdateOperationDecrement, //!< If the stencil test passes, the value in the stencil buffer is decremented and if required clamped + sfStencilUpdateOperationInvert, //!< If the stencil test passes, the value in the stencil buffer is bitwise inverted +} sfStencilUpdateOperation; + +//////////////////////////////////////////////////////// +/// \brief Stencil value type (also used as a mask) +/// +//////////////////////////////////////////////////////// +typedef struct +{ + unsigned int value; //!< The stored stencil value +} sfStencilValue; + +//////////////////////////////////////////////////////////// +/// \brief Stencil modes for drawing +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfStencilComparison stencilComparison; //!< The comparison we're performing the stencil test with + sfStencilUpdateOperation stencilUpdateOperation; //!< The update operation to perform if the stencil test passes + sfStencilValue stencilReference; //!< The reference value we're performing the stencil test with + sfStencilValue stencilMask; //!< The mask to apply to both the reference value and the value in the stencil buffer + bool stencilOnly; //!< Whether we should update the color buffer in addition to the stencil buffer +} sfStencilMode; + +//////////////////////////////////////////////////////////// +// Convert sf::StencilValue to sfStencilValue +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sfStencilValue convertStencilValue(const sf::StencilValue value) { + return {value.value}; +} + +//////////////////////////////////////////////////////////// +// Convert sfStencilValue to sf::StencilValue +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sf::StencilValue convertStencilValue(const sfStencilValue value) { + return {value.value}; +} + +//////////////////////////////////////////////////////////// +// Convert sf::StencilMode to sfStencilMode +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sfStencilMode convertStencilMode(const sf::StencilMode value) { + return {static_cast(value.stencilComparison), + static_cast(value.stencilUpdateOperation), + convertStencilValue(value.stencilReference), + convertStencilValue(value.stencilMask), + value.stencilOnly}; +} + +//////////////////////////////////////////////////////////// +// Convert sfStencilMode to sf::StencilMode +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sf::StencilMode convertStencilMode(const sfStencilMode value) { + return {static_cast(value.stencilComparison), + static_cast(value.stencilUpdateOperation), + convertStencilValue(value.stencilReference), + convertStencilValue(value.stencilMask), + value.stencilOnly}; +} diff --git a/CSFML/src/Graphics/Text.cpp b/CSFML/src/Graphics/Text.cpp index e44f51ab..12d3d5f3 100644 --- a/CSFML/src/Graphics/Text.cpp +++ b/CSFML/src/Graphics/Text.cpp @@ -1,12 +1,13 @@ #include "Graphics/Color.hpp" #include "Graphics/Rect.hpp" +#include "SFML/Graphics/Font.hpp" #include "System/Vector2.hpp" #include #include #include -extern "C" sf::Text *sfText_new(void) { - return new sf::Text; +extern "C" sf::Text *sfText_new(const sf::Font *font, const uint32_t *string, unsigned int size) { + return new sf::Text(*font, (char32_t *)string, size); } extern "C" sf::Text *sfText_cpy(const sf::Text *text) { @@ -18,19 +19,19 @@ extern "C" void sfText_del(sf::Text *text) { } extern "C" void sfText_setPosition(sf::Text *text, sfVector2f position) { - text->setPosition(position.x, position.y); + text->setPosition(sf::Vector2f(position.x, position.y)); } extern "C" void sfText_setRotation(sf::Text *text, float angle) { - text->setRotation(angle); + text->setRotation(sf::degrees(angle)); } extern "C" void sfText_setScale(sf::Text *text, sfVector2f scale) { - text->setScale(scale.x, scale.y); + text->setScale(sf::Vector2f(scale.x, scale.y)); } extern "C" void sfText_setOrigin(sf::Text *text, sfVector2f origin) { - text->setOrigin(origin.x, origin.y); + text->setOrigin(sf::Vector2f(origin.x, origin.y)); } extern "C" sfVector2f sfText_getPosition(const sf::Text *text) { @@ -39,7 +40,7 @@ extern "C" sfVector2f sfText_getPosition(const sf::Text *text) { } extern "C" float sfText_getRotation(const sf::Text *text) { - return text->getRotation(); + return text->getRotation().asDegrees(); } extern "C" sfVector2f sfText_getScale(const sf::Text *text) { @@ -53,15 +54,15 @@ extern "C" sfVector2f sfText_getOrigin(const sf::Text *text) { } extern "C" void sfText_move(sf::Text *text, sfVector2f offset) { - text->move(offset.x, offset.y); + text->move(sf::Vector2f(offset.x, offset.y)); } extern "C" void sfText_rotate(sf::Text *text, float angle) { - text->rotate(angle); + text->rotate(sf::degrees(angle)); } extern "C" void sfText_scale(sf::Text *text, sfVector2f factors) { - text->scale(factors.x, factors.y); + text->scale(sf::Vector2f(factors.x, factors.y)); } extern "C" sf::Transform const *sfText_getTransform(const sf::Text *text) { @@ -73,7 +74,7 @@ extern "C" sf::Transform const *sfText_getInverseTransform(const sf::Text *text) } extern "C" void sfText_setUnicodeString(sf::Text *text, const uint32_t *string) { - text->setString(sf::String(string)); + text->setString(sf::String((char32_t *)string)); } extern "C" void sfText_setFont(sf::Text *text, const sf::Font *font) { @@ -109,11 +110,11 @@ extern "C" void sfText_setOutlineThickness(sf::Text *text, float thickness) { } extern "C" const uint32_t *sfText_getUnicodeString(const sf::Text *text) { - return text->getString().getData(); + return (uint32_t *)text->getString().getData(); } extern "C" const sf::Font *sfText_getFont(const sf::Text *text) { - return text->getFont(); + return &text->getFont(); } extern "C" unsigned int sfText_getCharacterSize(const sf::Text *text) { @@ -153,10 +154,10 @@ extern "C" sfVector2f sfText_findCharacterPos(const sf::Text *text, size_t index extern "C" sfFloatRect sfText_getLocalBounds(const sf::Text *text) { sf::FloatRect rect = text->getLocalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } extern "C" sfFloatRect sfText_getGlobalBounds(const sf::Text *text) { sf::FloatRect rect = text->getGlobalBounds(); - return {rect.left, rect.top, rect.width, rect.height}; + return {rect.position.x, rect.position.y, rect.size.x, rect.size.y}; } diff --git a/CSFML/src/Graphics/Texture.cpp b/CSFML/src/Graphics/Texture.cpp index 7f8a9a80..f3a67dc9 100644 --- a/CSFML/src/Graphics/Texture.cpp +++ b/CSFML/src/Graphics/Texture.cpp @@ -1,4 +1,5 @@ #include "Graphics/Rect.hpp" +#include "SFML/Graphics/Image.hpp" #include "System/InputStreamHelper.hpp" #include "System/Vector2.hpp" #include @@ -17,24 +18,24 @@ extern "C" void sfTexture_del(sf::Texture *texture) { delete texture; } -extern "C" bool sfTexture_create(sf::Texture *tex, unsigned int width, unsigned int height) { - return tex->create(width, height); +extern "C" bool sfTexture_resize(sf::Texture *texture, sfVector2u size, bool sRgb) { + return texture->resize({size.x, size.y}, sRgb); } -extern "C" bool sfTexture_loadFromFile(sf::Texture *tex, const char *filename, const sfIntRect area) { - return tex->loadFromFile(filename, sf::IntRect(area.left, area.top, area.width, area.height)); +extern "C" bool sfTexture_loadFromFile(sf::Texture *tex, const char *filename, bool sRgb, const sfIntRect area) { + return tex->loadFromFile(filename, sRgb, {{area.position.x, area.position.y}, {area.size.x, area.size.y}}); } -extern "C" bool sfTexture_loadFromMemory(sf::Texture *tex, const void *data, size_t sizeInBytes, const sfIntRect area) { - return tex->loadFromMemory(data, sizeInBytes, sf::IntRect(area.left, area.top, area.width, area.height)); +extern "C" bool sfTexture_loadFromMemory(sf::Texture *tex, const void *data, size_t sizeInBytes, bool sRgb, const sfIntRect area) { + return tex->loadFromMemory(data, sizeInBytes, sRgb, {{area.position.x, area.position.y}, {area.size.x, area.size.y}}); } -extern "C" bool sfTexture_loadFromStream(sf::Texture *tex, sfInputStreamHelper *stream, const sfIntRect area) { - return tex->loadFromStream(*stream, sf::IntRect(area.left, area.top, area.width, area.height)); +extern "C" bool sfTexture_loadFromStream(sf::Texture *tex, sfInputStreamHelper *stream, bool sRgb, const sfIntRect area) { + return tex->loadFromStream(*stream, sRgb, {{area.position.x, area.position.y}, {area.size.x, area.size.y}}); } -extern "C" bool sfTexture_loadFromImage(sf::Texture *tex, const sf::Image *image, const sfIntRect area) { - return tex->loadFromImage(*image, sf::IntRect(area.left, area.top, area.width, area.height)); +extern "C" bool sfTexture_loadFromImage(sf::Texture *tex, const sf::Image *image, bool sRgb, const sfIntRect area) { + return tex->loadFromImage(*image, sRgb, {{area.position.x, area.position.y}, {area.size.x, area.size.y}}); } extern "C" sfVector2u sfTexture_getSize(const sf::Texture *texture) { @@ -46,24 +47,24 @@ extern "C" sf::Image *sfTexture_copyToImage(const sf::Texture *texture) { return new sf::Image(texture->copyToImage()); } -extern "C" void sfTexture_updateFromPixels(sf::Texture *texture, const uint8_t *pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y) { - texture->update(pixels, width, height, x, y); +extern "C" void sfTexture_updateFromPixels(sf::Texture *texture, const uint8_t *pixels, sfVector2u size, sfVector2u dest) { + texture->update(pixels, {size.x, size.y}, {dest.x, dest.y}); } -extern "C" void sfTexture_updateFromTexture(sf::Texture *destination, const sf::Texture *texture, unsigned int x, unsigned int y) { - destination->update(*texture, x, y); +extern "C" void sfTexture_updateFromTexture(sf::Texture *destination, const sf::Texture *texture, sfVector2u dest) { + destination->update(*texture, {dest.x, dest.y}); } -extern "C" void sfTexture_updateFromImage(sf::Texture *texture, const sf::Image *image, unsigned int x, unsigned int y) { - texture->update(*image, x, y); +extern "C" void sfTexture_updateFromImage(sf::Texture *texture, const sf::Image *image, sfVector2u dest) { + texture->update(*image, {dest.x, dest.y}); } -extern "C" void sfTexture_updateFromWindow(sf::Texture *texture, const sf::Window *window, unsigned int x, unsigned int y) { - texture->update(*window, x, y); +extern "C" void sfTexture_updateFromWindow(sf::Texture *texture, const sf::Window *window, sfVector2u dest) { + texture->update(*window, {dest.x, dest.y}); } -extern "C" void sfTexture_updateFromRenderWindow(sf::Texture *texture, const sf::RenderWindow *renderWindow, unsigned int x, unsigned int y) { - texture->update(*renderWindow, x, y); +extern "C" void sfTexture_updateFromRenderWindow(sf::Texture *texture, const sf::RenderWindow *renderWindow, sfVector2u dest) { + texture->update(*renderWindow, {dest.x, dest.y}); } extern "C" void sfTexture_setSmooth(sf::Texture *texture, bool smooth) { @@ -74,10 +75,6 @@ extern "C" bool sfTexture_isSmooth(const sf::Texture *texture) { return texture->isSmooth(); } -extern "C" void sfTexture_setSrgb(sf::Texture *texture, bool sRgb) { - texture->setSrgb(sRgb); -} - extern "C" bool sfTexture_isSrgb(const sf::Texture *texture) { return texture->isSrgb(); } diff --git a/CSFML/src/Graphics/Transform.cpp b/CSFML/src/Graphics/Transform.cpp index bb6fcfc7..eabeb385 100644 --- a/CSFML/src/Graphics/Transform.cpp +++ b/CSFML/src/Graphics/Transform.cpp @@ -4,35 +4,35 @@ #include extern "C" sfVector2f sfTransform_transformPoint(const sf::Transform *transform, sfVector2f point) { - sf::Vector2f vec2 = transform->transformPoint(point.x, point.y); + sf::Vector2f vec2 = transform->transformPoint({point.x, point.y}); return {vec2.x, vec2.y}; } extern "C" sfFloatRect sfTransform_transformRect(const sf::Transform *transform, sfFloatRect rectangle) { - sf::FloatRect rect = transform->transformRect(sf::FloatRect(rectangle.left, rectangle.top, rectangle.width, rectangle.height)); - return {rect.left, rect.top, rect.width, rect.height}; + sf::FloatRect rect = transform->transformRect({{rectangle.position.x, rectangle.position.y}, {rectangle.size.x, rectangle.size.y}}); + return {{rect.position.x, rect.position.y}, {rect.size.x, rect.size.y}}; } extern "C" void sfTransform_combine(sf::Transform *transform, const sf::Transform *other) { transform->combine(*other); } -extern "C" void sfTransform_translate(sf::Transform *transform, float x, float y) { - transform->translate(x, y); +extern "C" void sfTransform_translate(sf::Transform *transform, sfVector2f offset) { + transform->translate({offset.x, offset.y}); } extern "C" void sfTransform_rotate(sf::Transform *transform, float angle) { - transform->rotate(angle); + transform->rotate(sf::degrees(angle)); } -extern "C" void sfTransform_rotateWithCenter(sf::Transform *transform, float angle, float centerX, float centerY) { - transform->rotate(angle, centerX, centerY); +extern "C" void sfTransform_rotateWithCenter(sf::Transform *transform, float angle, sfVector2f center) { + transform->rotate(sf::degrees(angle), {center.x, center.y}); } -extern "C" void sfTransform_scale(sf::Transform *transform, float scaleX, float scaleY) { - transform->scale(scaleX, scaleY); +extern "C" void sfTransform_scale(sf::Transform *transform, sfVector2f scale) { + transform->scale({scale.x, scale.y}); } -extern "C" void sfTransform_scaleWithCenter(sf::Transform *transform, float scaleX, float scaleY, float centerX, float centerY) { - transform->scale(scaleX, scaleY, centerX, centerY); +extern "C" void sfTransform_scaleWithCenter(sf::Transform *transform, sfVector2f scale, sfVector2f center) { + transform->scale({scale.x, scale.y}, {center.x, center.y}); } diff --git a/CSFML/src/Graphics/Transform.hpp b/CSFML/src/Graphics/Transform.hpp new file mode 100644 index 00000000..c5451e70 --- /dev/null +++ b/CSFML/src/Graphics/Transform.hpp @@ -0,0 +1,30 @@ +//////////////////////////////////////////////////////////// +/// \brief Encapsulate a 3x3 transform matrix +/// +//////////////////////////////////////////////////////////// +#include +typedef struct +{ + float matrix[9]; +} sfTransform; + +//////////////////////////////////////////////////////////// +// Convert sf::Transform to sfTransform +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sfTransform convertTransform(const sf::Transform &transform) { + const float *m = transform.getMatrix(); + return {m[0], m[4], m[12], m[1], m[5], m[13], m[3], m[7], m[15]}; +} + +//////////////////////////////////////////////////////////// +// Convert sfTransform to sf::Transform +//////////////////////////////////////////////////////////// +[[nodiscard]] inline sf::Transform convertTransform(const sfTransform &transform) { + const float *m = transform.matrix; + + // clang-format off + return {m[0], m[1], m[2], + m[3], m[4], m[5], + m[6], m[7], m[8]}; + // clang-format on +} diff --git a/CSFML/src/Graphics/VertexBuffer.cpp b/CSFML/src/Graphics/VertexBuffer.cpp index ad3579d6..3ab3234d 100644 --- a/CSFML/src/Graphics/VertexBuffer.cpp +++ b/CSFML/src/Graphics/VertexBuffer.cpp @@ -1,3 +1,5 @@ +#include "Graphics/PrimitiveType.hpp" +#include "SFML/Graphics/PrimitiveType.hpp" #include "SFML/Graphics/RenderTarget.hpp" #include #include @@ -38,12 +40,12 @@ extern "C" unsigned int sfVertexBuffer_getNativeHandle(const sf::VertexBuffer *v return vertexBuffer->getNativeHandle(); } -extern "C" void sfVertexBuffer_setPrimitiveType(sf::VertexBuffer *vertexBuffer, sf::PrimitiveType type) { - vertexBuffer->setPrimitiveType(type); +extern "C" void sfVertexBuffer_setPrimitiveType(sf::VertexBuffer *vertexBuffer, sfPrimitiveType type) { + vertexBuffer->setPrimitiveType(static_cast(type)); } -extern "C" sf::PrimitiveType sfVertexBuffer_getPrimitiveType(const sf::VertexBuffer *vertexBuffer) { - return vertexBuffer->getPrimitiveType(); +extern "C" sfPrimitiveType sfVertexBuffer_getPrimitiveType(const sf::VertexBuffer *vertexBuffer) { + return static_cast(vertexBuffer->getPrimitiveType()); } extern "C" void sfVertexBuffer_setUsage(sf::VertexBuffer *vertexBuffer, sf::VertexBuffer::Usage usage) { diff --git a/CSFML/src/Graphics/View.cpp b/CSFML/src/Graphics/View.cpp index e0cebfb9..c34feccd 100644 --- a/CSFML/src/Graphics/View.cpp +++ b/CSFML/src/Graphics/View.cpp @@ -15,23 +15,19 @@ extern "C" sf::View *sfView_cpy(const sf::View *view) { } extern "C" void sfView_setCenter(sf::View *view, sfVector2f center) { - view->setCenter(center.x, center.y); + view->setCenter({center.x, center.y}); } extern "C" void sfView_setSize(sf::View *view, sfVector2f size) { - view->setSize(size.x, size.y); + view->setSize({size.x, size.y}); } extern "C" void sfView_setRotation(sf::View *view, float angle) { - view->setRotation(angle); + view->setRotation(sf::degrees(angle)); } extern "C" void sfView_setViewport(sf::View *view, sfFloatRect viewport) { - view->setViewport(sf::FloatRect(viewport.left, viewport.top, viewport.width, viewport.height)); -} - -extern "C" void sfView_reset(sf::View *view, sfFloatRect rectangle) { - view->reset(sf::FloatRect(rectangle.left, rectangle.top, rectangle.width, rectangle.height)); + view->setViewport({{viewport.position.x, viewport.position.y}, {viewport.size.x, viewport.size.y}}); } extern "C" sfVector2f sfView_getCenter(const sf::View *view) { @@ -45,20 +41,20 @@ extern "C" sfVector2f sfView_getSize(const sf::View *view) { } extern "C" float sfView_getRotation(const sf::View *view) { - return view->getRotation(); + return view->getRotation().asDegrees(); } extern "C" sfFloatRect sfView_getViewport(const sf::View *view) { sf::FloatRect rect = view->getViewport(); - return {rect.left, rect.top, rect.width, rect.height}; + return {{rect.position.x, rect.position.y}, {rect.size.x, rect.size.y}}; } extern "C" void sfView_move(sf::View *view, sfVector2f offset) { - view->move(offset.x, offset.y); + view->move({offset.x, offset.y}); } extern "C" void sfView_rotate(sf::View *view, float angle) { - view->rotate(angle); + view->rotate(sf::degrees(angle)); } extern "C" void sfView_zoom(sf::View *view, float factor) { diff --git a/CSFML/src/System/Clock.cpp b/CSFML/src/System/Clock.cpp index 13c69b2d..d8d458e5 100644 --- a/CSFML/src/System/Clock.cpp +++ b/CSFML/src/System/Clock.cpp @@ -1,3 +1,4 @@ +#include #include extern "C" sf::Clock *sfClock_new(void) { @@ -8,10 +9,10 @@ extern "C" void sfClock_delete(sf::Clock *clock) { delete clock; } -extern "C" sf::Int64 sfClock_getElapsedTime(const sf::Clock *clock) { +extern "C" int64_t sfClock_getElapsedTime(const sf::Clock *clock) { return clock->getElapsedTime().asMicroseconds(); } -extern "C" sf::Int64 sfClock_restart(sf::Clock *clock) { +extern "C" int64_t sfClock_restart(sf::Clock *clock) { return clock->restart().asMicroseconds(); } diff --git a/CSFML/src/System/InputStreamHelper.hpp b/CSFML/src/System/InputStreamHelper.hpp index 95532328..71ebb88e 100644 --- a/CSFML/src/System/InputStreamHelper.hpp +++ b/CSFML/src/System/InputStreamHelper.hpp @@ -4,8 +4,8 @@ #include #include -typedef int64_t (*sfInputStreamHelperReadCb)(void *data, int64_t size, void *userData); -typedef int64_t (*sfInputStreamHelperSeekCb)(int64_t position, void *userData); +typedef int64_t (*sfInputStreamHelperReadCb)(void *data, size_t size, void *userData); +typedef int64_t (*sfInputStreamHelperSeekCb)(size_t position, void *userData); typedef int64_t (*sfInputStreamHelperTellCb)(void *userData); typedef int64_t (*sfInputStreamHelperGetSizeCb)(void *userData); @@ -14,19 +14,19 @@ struct sfInputStreamHelper final : public sf::InputStream { sfInputStreamHelperSeekCb seek, sfInputStreamHelperTellCb tell, sfInputStreamHelperGetSizeCb getSize, void *userData); - virtual sf::Int64 read(void *data, sf::Int64 size) final { + virtual std::optional read(void *data, std::size_t size) final { return readCb(data, size, userData); } - virtual sf::Int64 seek(sf::Int64 position) final { + virtual std::optional seek(std::size_t position) final { return seekCb(position, userData); } - virtual sf::Int64 tell() final { + virtual std::optional tell() final { return tellCb(userData); } - virtual sf::Int64 getSize() final { + virtual std::optional getSize() final { return getSizeCb(userData); } sfInputStreamHelperReadCb readCb; diff --git a/CSFML/src/System/SfString.cpp b/CSFML/src/System/SfString.cpp index 037d56f9..20a0b8ac 100644 --- a/CSFML/src/System/SfString.cpp +++ b/CSFML/src/System/SfString.cpp @@ -4,8 +4,8 @@ extern "C" std::size_t sfString_getLength(const sf::String *string) { return string->getSize(); } -extern "C" const sf::Uint32 *sfString_getData(const sf::String *string) { - return string->getData(); +extern "C" const uint32_t *sfString_getData(const sf::String *string) { + return (uint32_t *) string->getData(); } extern "C" void sfString_delete(sf::String *string) { diff --git a/CSFML/src/System/Sleep.cpp b/CSFML/src/System/Sleep.cpp index eec702fc..cc775be7 100644 --- a/CSFML/src/System/Sleep.cpp +++ b/CSFML/src/System/Sleep.cpp @@ -1,5 +1,7 @@ +#include #include +#include -extern "C" void sfSleep(sf::Int64 duration_ms) { +extern "C" void sfSleep(int64_t duration_ms) { sf::sleep(sf::microseconds(duration_ms)); } diff --git a/CSFML/src/Window/Clipboard.cpp b/CSFML/src/Window/Clipboard.cpp index 00b231ab..a122df0d 100644 --- a/CSFML/src/Window/Clipboard.cpp +++ b/CSFML/src/Window/Clipboard.cpp @@ -1,10 +1,10 @@ +#include #include -#include extern "C" sf::String *sfClipboard_getUnicodeString() { return new sf::String(sf::Clipboard::getString()); } extern "C" void sfClipboard_setUnicodeString(const uint32_t *text) { - sf::Clipboard::setString(text); + sf::Clipboard::setString((char32_t *) text); } diff --git a/CSFML/src/Window/Cursor.cpp b/CSFML/src/Window/Cursor.cpp index eda627cb..fd99c664 100644 --- a/CSFML/src/Window/Cursor.cpp +++ b/CSFML/src/Window/Cursor.cpp @@ -1,19 +1,23 @@ +#include "Window/Cursor.hpp" #include "System/Vector2.hpp" #include -#include -extern "C" sf::Cursor *sfCursor_new() { - return new sf::Cursor; -} +extern "C" sf::Cursor *sfCursor_createFromPixels(const uint8_t *pixels, sfVector2u size, sfVector2u hotspot) { + auto cursor = sf::Cursor::createFromPixels(pixels, {size.x, size.y}, {hotspot.x, hotspot.y}); + if (!cursor) + return nullptr; -extern "C" void sfCursor_del(sf::Cursor *cursor) { - delete cursor; + return new sf::Cursor{std::move(*cursor)}; } -extern "C" bool sfCursor_loadFromPixels(sf::Cursor *cursor, const uint8_t *pixels, sfVector2u size, sfVector2u hotspot) { - return cursor->loadFromPixels(pixels, sf::Vector2u(size.x, size.y), sf::Vector2u(hotspot.x, hotspot.y)); +extern "C" sf::Cursor *sfCursor_createFromSystem(sfCursorType type) { + auto cursor = sf::Cursor::createFromSystem(static_cast(type)); + if (!cursor) + return nullptr; + + return new sf::Cursor{std::move(*cursor)}; } -extern "C" bool sfCursor_loadFromSystem(sf::Cursor *cursor, sf::Cursor::Type type) { - return cursor->loadFromSystem(type); +extern "C" void sfCursor_del(sf::Cursor *cursor) { + delete cursor; } diff --git a/CSFML/src/Window/Cursor.hpp b/CSFML/src/Window/Cursor.hpp new file mode 100644 index 00000000..b1988e28 --- /dev/null +++ b/CSFML/src/Window/Cursor.hpp @@ -0,0 +1,24 @@ +#pragma once +enum sfCursorType { + Arrow, //!< Arrow cursor (default) + ArrowWait, //!< Busy arrow cursor + Wait, //!< Busy cursor + Text, //!< I-beam, cursor when hovering over a field allowing text entry + Hand, //!< Pointing hand cursor + SizeHorizontal, //!< Horizontal double arrow cursor + SizeVertical, //!< Vertical double arrow cursor + SizeTopLeftBottomRight, //!< Double arrow cursor going from top-left to bottom-right + SizeBottomLeftTopRight, //!< Double arrow cursor going from bottom-left to top-right + SizeLeft, //!< Left arrow cursor on Linux, same as SizeHorizontal on other platforms + SizeRight, //!< Right arrow cursor on Linux, same as SizeHorizontal on other platforms + SizeTop, //!< Up arrow cursor on Linux, same as SizeVertical on other platforms + SizeBottom, //!< Down arrow cursor on Linux, same as SizeVertical on other platforms + SizeTopLeft, //!< Top-left arrow cursor on Linux, same as SizeTopLeftBottomRight on other platforms + SizeBottomRight, //!< Bottom-right arrow cursor on Linux, same as SizeTopLeftBottomRight on other platforms + SizeBottomLeft, //!< Bottom-left arrow cursor on Linux, same as SizeBottomLeftTopRight on other platforms + SizeTopRight, //!< Top-right arrow cursor on Linux, same as SizeBottomLeftTopRight on other platforms + SizeAll, //!< Combination of SizeHorizontal and SizeVertical + Cross, //!< Crosshair cursor + Help, //!< Help cursor + NotAllowed //!< Action not allowed cursor +}; diff --git a/CSFML/src/Window/Event.hpp b/CSFML/src/Window/Event.hpp new file mode 100644 index 00000000..03a410f3 --- /dev/null +++ b/CSFML/src/Window/Event.hpp @@ -0,0 +1,291 @@ +#pragma once + +#include "System/Vector2.hpp" +#include "System/Vector3.hpp" +#include "Window/Joystick.hpp" +#include "Window/Keyboard.hpp" +#include "Window/Mouse.hpp" +#include "Window/Sensor.hpp" +#include +#include +#include + +//////////////////////////////////////////////////////////// +/// \brief Definition of all the event types +/// +//////////////////////////////////////////////////////////// +typedef enum { + sfEvtClosed, ///< The window requested to be closed (no data) + sfEvtResized, ///< The window was resized (data in event.size) + sfEvtFocusLost, ///< The window lost the focus (no data) + sfEvtFocusGained, ///< The window gained the focus (no data) + sfEvtTextEntered, ///< A character was entered (data in event.text) + sfEvtKeyPressed, ///< A key was pressed (data in event.key) + sfEvtKeyReleased, ///< A key was released (data in event.key) + sfEvtMouseWheelScrolled, ///< The mouse wheel was scrolled (data in event.mouseWheelScroll) + sfEvtMouseButtonPressed, ///< A mouse button was pressed (data in event.mouseButton) + sfEvtMouseButtonReleased, ///< A mouse button was released (data in event.mouseButton) + sfEvtMouseMoved, ///< The mouse cursor moved (data in event.mouseMove) + sfEvtMouseMovedRaw, ///< The mouse cursor moved (data in event.mouseMove) + sfEvtMouseEntered, ///< The mouse cursor entered the area of the window (no data) + sfEvtMouseLeft, ///< The mouse cursor left the area of the window (no data) + sfEvtJoystickButtonPressed, ///< A joystick button was pressed (data in event.joystickButton) + sfEvtJoystickButtonReleased, ///< A joystick button was released (data in event.joystickButton) + sfEvtJoystickMoved, ///< The joystick moved along an axis (data in event.joystickMove) + sfEvtJoystickConnected, ///< A joystick was connected (data in event.joystickConnect) + sfEvtJoystickDisconnected, ///< A joystick was disconnected (data in event.joystickConnect) + sfEvtTouchBegan, ///< A touch event began (data in event.touch) + sfEvtTouchMoved, ///< A touch moved (data in event.touch) + sfEvtTouchEnded, ///< A touch event ended (data in event.touch) + sfEvtSensorChanged, ///< A sensor value changed (data in event.sensor) + + sfEvtCount ///< Keep last -- the total number of event types +} sfEventType; + +//////////////////////////////////////////////////////////// +/// \brief Keyboard event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfKeyCode code; + sfScancode scancode; + bool alt; + bool control; + bool shift; + bool system; +} sfKeyEvent; + +//////////////////////////////////////////////////////////// +/// \brief Text event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + uint32_t unicode; +} sfTextEvent; + +//////////////////////////////////////////////////////////// +/// \brief Mouse move event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfVector2i position; +} sfMouseMoveEvent; + +//////////////////////////////////////////////////////////// +/// \brief Mouse move raw event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfVector2i delta; +} sfMouseMoveRawEvent; + +//////////////////////////////////////////////////////////// +/// \brief Mouse buttons events parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfMouseButton button; + sfVector2i position; +} sfMouseButtonEvent; + +//////////////////////////////////////////////////////////// +/// \brief Mouse wheel events parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfMouseWheel wheel; + float delta; + sfVector2i position; +} sfMouseWheelScrollEvent; + +//////////////////////////////////////////////////////////// +/// \brief Joystick axis move event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + unsigned int joystickId; + sfJoystickAxis axis; + float position; +} sfJoystickMoveEvent; + +//////////////////////////////////////////////////////////// +/// \brief Joystick buttons events parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + unsigned int joystickId; + unsigned int button; +} sfJoystickButtonEvent; + +//////////////////////////////////////////////////////////// +/// \brief Joystick connection/disconnection event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + unsigned int joystickId; +} sfJoystickConnectEvent; + +//////////////////////////////////////////////////////////// +/// \brief Size events parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfVector2u size; +} sfSizeEvent; + +//////////////////////////////////////////////////////////// +/// \brief Touch events parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + unsigned int finger; + sfVector2i position; +} sfTouchEvent; + +//////////////////////////////////////////////////////////// +/// \brief Sensor event parameters +/// +//////////////////////////////////////////////////////////// +typedef struct +{ + sfEventType type; + sfSensorType sensorType; + sfVector3f value; +} sfSensorEvent; + +//////////////////////////////////////////////////////////// +/// \brief sfEvent defines a system event and its parameters +/// +//////////////////////////////////////////////////////////// +typedef union { + sfEventType type; ///< Type of the event + sfSizeEvent size; ///< Size event parameters + sfKeyEvent key; ///< Key event parameters + sfTextEvent text; ///< Text event parameters + sfMouseMoveEvent mouseMove; ///< Mouse move event parameters + sfMouseMoveRawEvent mouseMoveRaw; ///< Mouse move raw event parameters + sfMouseButtonEvent mouseButton; ///< Mouse button event parameters + sfMouseWheelScrollEvent mouseWheelScroll; ///< Mouse wheel event parameters + sfJoystickMoveEvent joystickMove; ///< Joystick move event parameters + sfJoystickButtonEvent joystickButton; ///< Joystick button event parameters + sfJoystickConnectEvent joystickConnect; ///< Joystick (dis)connect event parameters + sfTouchEvent touch; ///< Touch events parameters + sfSensorEvent sensor; ///< Sensor event parameters +} sfEvent; + +[[nodiscard]] inline bool convertEvent(const std::optional &sfmlEvent, sfEvent &event) { + if (!sfmlEvent) + return false; + + if (sfmlEvent->is()) { + event.type = sfEvtClosed; + } else if (const auto *resized = sfmlEvent->getIf()) { + event.type = sfEvtResized; + event.size.size = {resized->size.x, resized->size.y}; + } else if (sfmlEvent->is()) { + event.type = sfEvtFocusLost; + } else if (sfmlEvent->is()) { + event.type = sfEvtFocusGained; + } else if (const auto *textEntered = sfmlEvent->getIf()) { + event.type = sfEvtTextEntered; + event.text.unicode = textEntered->unicode; + } else if (const auto *keyReleased = sfmlEvent->getIf()) { + event.type = sfEvtKeyReleased; + event.key.code = static_cast(keyReleased->code); + event.key.scancode = static_cast(keyReleased->scancode); + event.key.alt = keyReleased->alt; + event.key.control = keyReleased->control; + event.key.shift = keyReleased->shift; + event.key.system = keyReleased->system; + } else if (const auto *keyPressed = sfmlEvent->getIf()) { + event.type = sfEvtKeyPressed; + event.key.code = static_cast(keyPressed->code); + event.key.scancode = static_cast(keyPressed->scancode); + event.key.alt = keyPressed->alt; + event.key.control = keyPressed->control; + event.key.shift = keyPressed->shift; + event.key.system = keyPressed->system; + } else if (const auto *mouseWheelScrolled = sfmlEvent->getIf()) { + event.type = sfEvtMouseWheelScrolled; + event.mouseWheelScroll.wheel = static_cast(mouseWheelScrolled->wheel); + event.mouseWheelScroll.delta = mouseWheelScrolled->delta; + event.mouseWheelScroll.position = {mouseWheelScrolled->position.x, mouseWheelScrolled->position.y}; + } else if (const auto *mouseButtonPressed = sfmlEvent->getIf()) { + event.type = sfEvtMouseButtonPressed; + event.mouseButton.button = static_cast(mouseButtonPressed->button); + event.mouseButton.position = {mouseButtonPressed->position.x, mouseButtonPressed->position.y}; + } else if (const auto *mouseButtonReleased = sfmlEvent->getIf()) { + event.type = sfEvtMouseButtonReleased; + event.mouseButton.button = static_cast(mouseButtonReleased->button); + event.mouseButton.position = {mouseButtonReleased->position.x, mouseButtonReleased->position.y}; + } else if (const auto *mouseMoved = sfmlEvent->getIf()) { + event.type = sfEvtMouseMoved; + event.mouseMove.position = {mouseMoved->position.x, mouseMoved->position.y}; + } else if (const auto *mouseMovedRaw = sfmlEvent->getIf()) { + event.type = sfEvtMouseMovedRaw; + event.mouseMoveRaw.delta = {mouseMovedRaw->delta.x, mouseMovedRaw->delta.y}; + } else if (sfmlEvent->is()) { + event.type = sfEvtMouseEntered; + } else if (sfmlEvent->is()) { + event.type = sfEvtMouseLeft; + } else if (const auto *joystickButtonPressed = sfmlEvent->getIf()) { + event.type = sfEvtJoystickButtonPressed; + event.joystickButton.joystickId = joystickButtonPressed->joystickId; + event.joystickButton.button = joystickButtonPressed->button; + } else if (const auto *joystickButtonReleased = sfmlEvent->getIf()) { + event.type = sfEvtJoystickButtonReleased; + event.joystickButton.joystickId = joystickButtonReleased->joystickId; + event.joystickButton.button = joystickButtonReleased->button; + } else if (const auto *joystickMoved = sfmlEvent->getIf()) { + event.type = sfEvtJoystickMoved; + event.joystickMove.joystickId = joystickMoved->joystickId; + event.joystickMove.axis = static_cast(joystickMoved->axis); + event.joystickMove.position = joystickMoved->position; + } else if (const auto *joystickConnected = sfmlEvent->getIf()) { + event.type = sfEvtJoystickConnected; + event.joystickConnect.joystickId = joystickConnected->joystickId; + } else if (const auto *joystickDisconnected = sfmlEvent->getIf()) { + event.type = sfEvtJoystickDisconnected; + event.joystickConnect.joystickId = joystickDisconnected->joystickId; + } else if (const auto *touchBegan = sfmlEvent->getIf()) { + event.type = sfEvtTouchBegan; + event.touch.finger = touchBegan->finger; + event.touch.position = {touchBegan->position.x, touchBegan->position.y}; + } else if (const auto *touchMoved = sfmlEvent->getIf()) { + event.type = sfEvtTouchMoved; + event.touch.finger = touchMoved->finger; + event.touch.position = {touchMoved->position.x, touchMoved->position.y}; + } else if (const auto *touchEnded = sfmlEvent->getIf()) { + event.type = sfEvtTouchEnded; + event.touch.finger = touchEnded->finger; + event.touch.position = {touchEnded->position.x, touchEnded->position.y}; + } else if (const auto *sensorChanged = sfmlEvent->getIf()) { + event.type = sfEvtSensorChanged; + event.sensor.sensorType = static_cast(sensorChanged->type); + event.sensor.value = {sensorChanged->value.x, sensorChanged->value.y, sensorChanged->value.z}; + } + + return true; +} diff --git a/CSFML/src/Window/Joystick.cpp b/CSFML/src/Window/Joystick.cpp index 505ebf2a..4bf2e42b 100644 --- a/CSFML/src/Window/Joystick.cpp +++ b/CSFML/src/Window/Joystick.cpp @@ -1,3 +1,4 @@ +#include "Window/Joystick.hpp" #include extern "C" bool sfJoystick_isConnected(unsigned int joystick) { @@ -8,16 +9,16 @@ extern "C" unsigned int sfJoystick_getButtonCount(unsigned int joystick) { return sf::Joystick::getButtonCount(joystick); } -extern "C" bool sfJoystick_hasAxis(unsigned int joystick, sf::Joystick::Axis axis) { - return sf::Joystick::hasAxis(joystick, axis); +extern "C" bool sfJoystick_hasAxis(unsigned int joystick, sfJoystickAxis axis) { + return sf::Joystick::hasAxis(joystick, static_cast(axis)); } extern "C" bool sfJoystick_isButtonPressed(unsigned int joystick, unsigned int button) { return sf::Joystick::isButtonPressed(joystick, button); } -extern "C" float sfJoystick_getAxisPosition(unsigned int joystick, sf::Joystick::Axis axis) { - return sf::Joystick::getAxisPosition(joystick, axis); +extern "C" float sfJoystick_getAxisPosition(unsigned int joystick, sfJoystickAxis axis) { + return sf::Joystick::getAxisPosition(joystick, static_cast(axis)); } extern "C" sf::Joystick::Identification *sfJoystick_getIdentification(unsigned int joystick) { diff --git a/CSFML/src/Window/Joystick.hpp b/CSFML/src/Window/Joystick.hpp new file mode 100644 index 00000000..b9503bd2 --- /dev/null +++ b/CSFML/src/Window/Joystick.hpp @@ -0,0 +1,12 @@ +#pragma once + +typedef enum { + sfJoystickX, + sfJoystickY, + sfJoystickZ, + sfJoystickR, + sfJoystickU, + sfJoystickV, + sfJoystickPovX, + sfJoystickPovY +} sfJoystickAxis; diff --git a/CSFML/src/Window/Keyboard.hpp b/CSFML/src/Window/Keyboard.hpp new file mode 100644 index 00000000..0dcc46f5 --- /dev/null +++ b/CSFML/src/Window/Keyboard.hpp @@ -0,0 +1,257 @@ +#pragma once +typedef enum { + sfKeyUnknown = -1, + sfKeyA, + sfKeyB, + sfKeyC, + sfKeyD, + sfKeyE, + sfKeyF, + sfKeyG, + sfKeyH, + sfKeyI, + sfKeyJ, + sfKeyK, + sfKeyL, + sfKeyM, + sfKeyN, + sfKeyO, + sfKeyP, + sfKeyQ, + sfKeyR, + sfKeyS, + sfKeyT, + sfKeyU, + sfKeyV, + sfKeyW, + sfKeyX, + sfKeyY, + sfKeyZ, + sfKeyNum0, + sfKeyNum1, + sfKeyNum2, + sfKeyNum3, + sfKeyNum4, + sfKeyNum5, + sfKeyNum6, + sfKeyNum7, + sfKeyNum8, + sfKeyNum9, + sfKeyEscape, + sfKeyLControl, + sfKeyLShift, + sfKeyLAlt, + sfKeyLSystem, + sfKeyRControl, + sfKeyRShift, + sfKeyRAlt, + sfKeyRSystem, + sfKeyMenu, + sfKeyLBracket, + sfKeyRBracket, + sfKeySemicolon, + sfKeyComma, + sfKeyPeriod, + sfKeyApostrophe, + sfKeySlash, + sfKeyBackslash, + sfKeyGrave, + sfKeyEqual, + sfKeyHyphen, + sfKeySpace, + sfKeyEnter, + sfKeyBackspace, + sfKeyTab, + sfKeyPageUp, + sfKeyPageDown, + sfKeyEnd, + sfKeyHome, + sfKeyInsert, + sfKeyDelete, + sfKeyAdd, + sfKeySubtract, + sfKeyMultiply, + sfKeyDivide, + sfKeyLeft, + sfKeyRight, + sfKeyUp, + sfKeyDown, + sfKeyNumpad0, + sfKeyNumpad1, + sfKeyNumpad2, + sfKeyNumpad3, + sfKeyNumpad4, + sfKeyNumpad5, + sfKeyNumpad6, + sfKeyNumpad7, + sfKeyNumpad8, + sfKeyNumpad9, + sfKeyF1, + sfKeyF2, + sfKeyF3, + sfKeyF4, + sfKeyF5, + sfKeyF6, + sfKeyF7, + sfKeyF8, + sfKeyF9, + sfKeyF10, + sfKeyF11, + sfKeyF12, + sfKeyF13, + sfKeyF14, + sfKeyF15, + sfKeyPause, +} sfKeyCode; + +typedef enum { + sfScanUnknown = -1, + sfScanA = 0, + sfScanB, + sfScanC, + sfScanD, + sfScanE, + sfScanF, + sfScanG, + sfScanH, + sfScanI, + sfScanJ, + sfScanK, + sfScanL, + sfScanM, + sfScanN, + sfScanO, + sfScanP, + sfScanQ, + sfScanR, + sfScanS, + sfScanT, + sfScanU, + sfScanV, + sfScanW, + sfScanX, + sfScanY, + sfScanZ, + sfScanNum1, + sfScanNum2, + sfScanNum3, + sfScanNum4, + sfScanNum5, + sfScanNum6, + sfScanNum7, + sfScanNum8, + sfScanNum9, + sfScanNum0, + sfScanEnter, + sfScanEscape, + sfScanBackspace, + sfScanTab, + sfScanSpace, + sfScanHyphen, + sfScanEqual, + sfScanLBracket, + sfScanRBracket, + + sfScanBackslash, + sfScanSemicolon, + sfScanApostrophe, + sfScanGrave, + sfScanComma, + sfScanPeriod, + sfScanSlash, + sfScanF1, + sfScanF2, + sfScanF3, + sfScanF4, + sfScanF5, + sfScanF6, + sfScanF7, + sfScanF8, + sfScanF9, + sfScanF10, + sfScanF11, + sfScanF12, + sfScanF13, + sfScanF14, + sfScanF15, + sfScanF16, + sfScanF17, + sfScanF18, + sfScanF19, + sfScanF20, + sfScanF21, + sfScanF22, + sfScanF23, + sfScanF24, + sfScanCapsLock, + sfScanPrintScreen, + sfScanScrollLock, + sfScanPause, + sfScanInsert, + sfScanHome, + sfScanPageUp, + sfScanDelete, + sfScanEnd, + sfScanPageDown, + sfScanRight, + sfScanLeft, + sfScanDown, + sfScanUp, + sfScanNumLock, + sfScanNumpadDivide, + sfScanNumpadMultiply, + sfScanNumpadMinus, + sfScanNumpadPlus, + sfScanNumpadEqual, + sfScanNumpadEnter, + sfScanNumpadDecimal, + sfScanNumpad1, + sfScanNumpad2, + sfScanNumpad3, + sfScanNumpad4, + sfScanNumpad5, + sfScanNumpad6, + sfScanNumpad7, + sfScanNumpad8, + sfScanNumpad9, + sfScanNumpad0, + + sfScanNonUsBackslash, + sfScanApplication, + sfScanExecute, + sfScanModeChange, + sfScanHelp, + sfScanMenu, + sfScanSelect, + sfScanRedo, + sfScanUndo, + sfScanCut, + sfScanCopy, + sfScanPaste, + sfScanVolumeMute, + sfScanVolumeUp, + sfScanVolumeDown, + sfScanMediaPlayPause, + sfScanMediaStop, + sfScanMediaNextTrack, + sfScanMediaPreviousTrack, + sfScanLControl, + sfScanLShift, + sfScanLAlt, + sfScanLSystem, + sfScanRControl, + sfScanRShift, + sfScanRAlt, + sfScanRSystem, + sfScanBack, + sfScanForward, + sfScanRefresh, + sfScanStop, + sfScanSearch, + sfScanFavorites, + sfScanHomePage, + sfScanLaunchApplication1, + sfScanLaunchApplication2, + sfScanLaunchMail, + sfScanLaunchMediaSelect, +} sfScancode; diff --git a/CSFML/src/Window/Mouse.cpp b/CSFML/src/Window/Mouse.cpp index f4db91f8..779c3562 100644 --- a/CSFML/src/Window/Mouse.cpp +++ b/CSFML/src/Window/Mouse.cpp @@ -1,9 +1,10 @@ +#include "Window/Mouse.hpp" #include "System/Vector2.hpp" #include #include -extern "C" bool sfMouse_isButtonPressed(sf::Mouse::Button button) { - return sf::Mouse::isButtonPressed(button); +extern "C" bool sfMouse_isButtonPressed(sfMouseButton button) { + return sf::Mouse::isButtonPressed(static_cast(button)); } extern "C" sfVector2i sfMouse_getPosition() { diff --git a/CSFML/src/Window/Mouse.hpp b/CSFML/src/Window/Mouse.hpp new file mode 100644 index 00000000..c8a1f8d5 --- /dev/null +++ b/CSFML/src/Window/Mouse.hpp @@ -0,0 +1,14 @@ +#pragma once + +typedef enum { + sfMouseLeft, + sfMouseRight, + sfMouseMiddle, + sfMouseButtonExtra1, + sfMouseButtonExtra2, +} sfMouseButton; + +typedef enum { + sfMouseVerticalWheel, + sfMouseHorizontalWheel +} sfMouseWheel; diff --git a/CSFML/src/Window/Sensor.cpp b/CSFML/src/Window/Sensor.cpp index 1b9f6bac..fb888a95 100644 --- a/CSFML/src/Window/Sensor.cpp +++ b/CSFML/src/Window/Sensor.cpp @@ -1,15 +1,16 @@ +#include "Window/Sensor.hpp" #include "System/Vector3.hpp" #include -extern "C" bool sfSensor_isAvailable(sf::Sensor::Type sensor) { - return sf::Sensor::isAvailable(sensor); +extern "C" bool sfSensor_isAvailable(sfSensorType sensor) { + return sf::Sensor::isAvailable(static_cast(sensor)); } -extern "C" void sfSensor_setEnabled(sf::Sensor::Type sensor, bool enabled) { - sf::Sensor::setEnabled(sensor, enabled); +extern "C" void sfSensor_setEnabled(sfSensorType sensor, bool enabled) { + sf::Sensor::setEnabled(static_cast(sensor), enabled); } -extern "C" sfVector3f sfSensor_getValue(sf::Sensor::Type sensor) { - sf::Vector3f val = sf::Sensor::getValue(sensor); +extern "C" sfVector3f sfSensor_getValue(sfSensorType sensor) { + sf::Vector3f val = sf::Sensor::getValue(static_cast(sensor)); return {val.x, val.y, val.z}; } diff --git a/CSFML/src/Window/Sensor.hpp b/CSFML/src/Window/Sensor.hpp new file mode 100644 index 00000000..889da1e1 --- /dev/null +++ b/CSFML/src/Window/Sensor.hpp @@ -0,0 +1,10 @@ +#pragma once + +typedef enum { + sfSensorAccelerometer, + sfSensorGyroscope, + sfSensorMagnetometer, + sfSensorGravity, + sfSensorUserAcceleration, + sfSensorOrientation, +} sfSensorType; diff --git a/CSFML/src/Window/VideoMode.cpp b/CSFML/src/Window/VideoMode.cpp index d1d295ca..fbc94227 100644 --- a/CSFML/src/Window/VideoMode.cpp +++ b/CSFML/src/Window/VideoMode.cpp @@ -5,7 +5,7 @@ extern "C" sfVideoMode sfVideoMode_getDesktopMode(void) { sf::VideoMode vm = sf::VideoMode::getDesktopMode(); - return {vm.width, vm.height, vm.bitsPerPixel}; + return {{vm.size.x, vm.size.y}, vm.bitsPerPixel}; } extern "C" const std::vector *sfVideoMode_getFullscreenModes() { @@ -13,7 +13,7 @@ extern "C" const std::vector *sfVideoMode_getFullscreenModes() { } extern "C" bool sfVideoMode_isValid(sfVideoMode mode) { - return sf::VideoMode(mode.width, mode.height, mode.bitsPerPixel).isValid(); + return sf::VideoMode(sf::Vector2(mode.size.x, mode.size.y), mode.bitsPerPixel).isValid(); } extern "C" std::size_t sfVideoModeVector_getLength(const std::vector *vec) { diff --git a/CSFML/src/Window/VideoMode.hpp b/CSFML/src/Window/VideoMode.hpp index 235d13cf..e3486513 100644 --- a/CSFML/src/Window/VideoMode.hpp +++ b/CSFML/src/Window/VideoMode.hpp @@ -1,9 +1,9 @@ #ifndef SFML_VIDEOMODE_H #define SFML_VIDEOMODE_H +#include "System/Vector2.hpp" struct sfVideoMode { - unsigned int width; - unsigned int height; + sfVector2u size; unsigned int bitsPerPixel; }; diff --git a/CSFML/src/Window/Window.cpp b/CSFML/src/Window/Window.cpp index 7855672b..720d2221 100644 --- a/CSFML/src/Window/Window.cpp +++ b/CSFML/src/Window/Window.cpp @@ -1,8 +1,26 @@ +#include "SFML/System/Time.hpp" +#include "SFML/System/Vector2.hpp" #include "System/Vector2.hpp" #include "Window/VideoMode.hpp" +#include "Window/Window.hpp" +#include "Window/Event.hpp" +#include #include #include +#include #include +#include + +sf::State to_state(const sfState state) { + switch (state) { + case sfState::Windowed: + return sf::State::Windowed; + case sfState::Fullscreen: + return sf::State::Fullscreen; + default: + throw std::invalid_argument("Unreachable Pattern"); + } +} extern "C" sf::Window *sfWindow_new() { return new sf::Window; @@ -13,10 +31,10 @@ extern "C" void sfWindow_del(sf::Window *window) { } // Create with (mode, title, style, settings) -extern "C" void sfWindow_create_mtss(sf::Window *window, sfVideoMode mode, const uint32_t *title, uint32_t style, const sf::ContextSettings *settings) { +extern "C" void sfWindow_create_mtsss(sf::Window *window, sfVideoMode mode, const uint32_t *title, uint32_t style, sfState state, const sf::ContextSettings *settings) { // Convert video mode - sf::VideoMode videoMode(mode.width, mode.height, mode.bitsPerPixel); - window->create(videoMode, title, style, *settings); + sf::VideoMode videoMode(sf::Vector2u(mode.size.x, mode.size.y), mode.bitsPerPixel); + window->create(videoMode, (char32_t *)title, style, to_state(state), *settings); } extern "C" void sfWindow_create_handle_settings(sf::Window *window, sf::WindowHandle handle, const sf::ContextSettings *settings) { @@ -35,12 +53,12 @@ extern "C" const sf::ContextSettings *sfWindow_getSettings(const sf::Window *win return &window->getSettings(); } -extern "C" bool sfWindow_pollEvent(sf::Window *window, sf::Event *event) { - return window->pollEvent(*event); +extern "C" bool sfWindow_pollEvent(sf::Window *window, sfEvent *event) { + return convertEvent(window->pollEvent(), *event); } -extern "C" bool sfWindow_waitEvent(sf::Window *window, sf::Event *event) { - return window->waitEvent(*event); +extern "C" bool sfWindow_waitEvent(sf::Window *window, sfEvent *event, const int64_t timeout) { + return convertEvent(window->waitEvent(sf::Time(std::chrono::microseconds(timeout))), *event); } extern "C" sfVector2i sfWindow_getPosition(const sf::Window *window) { @@ -58,15 +76,15 @@ extern "C" sfVector2u sfWindow_getSize(const sf::Window *window) { } extern "C" void sfWindow_setSize(sf::Window *window, sfVector2u size) { - window->setSize(sf::Vector2u(size.x, size.y)); + window->setSize(sf::Vector2u({size.x, size.y})); } extern "C" void sfWindow_setUnicodeTitle(sf::Window *window, const uint32_t *title) { - window->setTitle(title); + window->setTitle((char32_t *)title); } -extern "C" void sfWindow_setIcon(sf::Window *window, unsigned int width, unsigned int height, const uint8_t *pixels) { - window->setIcon(width, height, pixels); +extern "C" void sfWindow_setIcon(sf::Window *window, sfVector2u size, const uint8_t *pixels) { + window->setIcon(sf::Vector2u({size.x, size.y}), pixels); } extern "C" void sfWindow_setVisible(sf::Window *window, bool visible) { @@ -118,6 +136,6 @@ extern "C" void sfWindow_setJoystickThreshold(sf::Window *window, float threshol window->setJoystickThreshold(threshold); } -extern "C" sf::WindowHandle sfWindow_getSystemHandle(const sf::Window *window) { - return window->getSystemHandle(); +extern "C" sf::WindowHandle sfWindow_getNativeHandle(const sf::Window *window) { + return window->getNativeHandle(); } diff --git a/CSFML/src/Window/Window.hpp b/CSFML/src/Window/Window.hpp new file mode 100644 index 00000000..b58062a1 --- /dev/null +++ b/CSFML/src/Window/Window.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +enum sfState { + Windowed, + Fullscreen +}; + +sf::State to_state(const sfState state); diff --git a/SFML b/SFML index 5383d2b3..8db4a58c 160000 --- a/SFML +++ b/SFML @@ -1 +1 @@ -Subproject commit 5383d2b3948f805af55c9f8a4587ac72ec5981d1 +Subproject commit 8db4a58ce05775a72b9846155aa66dbc16b9cc46 diff --git a/build.rs b/build.rs index f9eb7827..fb9f17d6 100644 --- a/build.rs +++ b/build.rs @@ -80,6 +80,7 @@ fn static_link_linux( if feat_window { println!("cargo:rustc-link-lib=dylib=GL"); println!("cargo:rustc-link-lib=dylib=X11"); + println!("cargo:rustc-link-lib=Xi"); println!("cargo:rustc-link-lib=dylib=Xcursor"); println!("cargo:rustc-link-lib=dylib=Xrandr"); } @@ -242,6 +243,7 @@ fn main() { "CSFML/src/Audio/Listener.cpp", "CSFML/src/Audio/Music.cpp", "CSFML/src/Audio/Sound.cpp", + "CSFML/src/Audio/SoundChannel.cpp", "CSFML/src/Audio/SoundBuffer.cpp", "CSFML/src/Audio/SoundBufferRecorder.cpp", "CSFML/src/Audio/SoundRecorder.cpp", diff --git a/examples/borrowed-resources.rs b/examples/borrowed-resources.rs index d6e06daf..47d80983 100644 --- a/examples/borrowed-resources.rs +++ b/examples/borrowed-resources.rs @@ -16,6 +16,7 @@ fn main() -> SfResult<()> { (800, 600), "Borrowed resources", Style::CLOSE, + Default::default(), &Default::default(), )?; window.set_vertical_sync_enabled(true); @@ -32,9 +33,8 @@ fn main() -> SfResult<()> { circle.set_position((100.0, 100.0)); // Create a Sprite. - let mut sprite = Sprite::new(); + let mut sprite = Sprite::with_texture(&frank); // Have it use the same texture as the circle. - sprite.set_texture(&frank, true); sprite.set_position((400.0, 300.0)); sprite.set_scale(0.5); @@ -50,19 +50,10 @@ fn main() -> SfResult<()> { // Create an initialized text using the font. let title = Text::new("Borrowed resources example!", &font, 50); - // Create a second text using the same font. - // This time, we create and initialize it separately. - let mut second_text = Text::default(); - second_text.set_string("This text shares the same font with the title!"); - second_text.set_font(&font); - second_text.set_fill_color(Color::GREEN); - second_text.set_position((10.0, 350.0)); - second_text.set_character_size(20); - // Create a third text using the same font. - let mut third_text = Text::new("This one too!", &font, 20); - third_text.set_position((300.0, 100.0)); - third_text.set_fill_color(Color::RED); + let mut second_text = Text::new("This one too!", &font, 20); + second_text.set_position((300.0, 100.0)); + second_text.set_fill_color(Color::RED); 'mainloop: loop { while let Some(event) = window.poll_event() { @@ -81,7 +72,6 @@ fn main() -> SfResult<()> { window.draw(&convex_shape); window.draw(&title); window.draw(&second_text); - window.draw(&third_text); // Little test here for `Shape::points` let mut circ = CircleShape::new(4.0, 30); diff --git a/examples/cursor.rs b/examples/cursor.rs index 8c23c911..1c8ffb0f 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -3,7 +3,7 @@ use sfml::{ graphics::{ Color, Font, Rect, RectangleShape, RenderTarget, RenderWindow, Shape, Text, Transformable, }, - system::Vector2, + system::{Vector2, Vector2i}, window::{ContextSettings, Cursor, CursorType, Event, Style, mouse}, }; @@ -21,8 +21,8 @@ fn gridindex( grid.get_mut(y * DRAW_GRID_WH as usize + x) } -fn mouse_over(rect: &Rect, mouse_x: i32, mouse_y: i32) -> bool { - rect.contains(Vector2::new(mouse_x, mouse_y)) +fn mouse_over(rect: &Rect, mouse_position: Vector2i) -> bool { + rect.contains(mouse_position) } enum ButtonStyle { @@ -40,8 +40,8 @@ fn draw_button( render_window: &mut RenderWindow, style: ButtonStyle, ) { - shape.set_position((rect.left as f32, rect.top as f32)); - shape.set_size((rect.width as f32, rect.height as f32)); + shape.set_position(rect.position.as_other()); + shape.set_size(rect.size.as_other()); let (rect_fill, rect_outline, text_fill) = match style { ButtonStyle::Normal => (Color::TRANSPARENT, Color::WHITE, Color::WHITE), ButtonStyle::Highlighted => (Color::WHITE, Color::WHITE, Color::BLACK), @@ -50,7 +50,7 @@ fn draw_button( }; shape.set_outline_color(rect_outline); shape.set_fill_color(rect_fill); - text.set_position((rect.left as f32 + 12.0, rect.top as f32 + 8.0)); + text.set_position((rect.position.x as f32 + 12.0, rect.position.y as f32 + 8.0)); text.set_fill_color(text_fill); text.set_string(string); render_window.draw(shape); @@ -71,21 +71,20 @@ fn bstyle(highlighted: bool, selected: bool, error: bool) -> ButtonStyle { fn main() -> SfResult<()> { example_ensure_right_working_dir(); - - let mut cursor = Cursor::from_system(CursorType::Arrow)?; let mut rw = RenderWindow::new( (800, 800), "SFML cursor example", Style::CLOSE, + Default::default(), &ContextSettings::default(), )?; rw.set_vertical_sync_enabled(true); let font = Font::from_file("sansation.ttf")?; let mut failed_index = usize::MAX; let mut selected_index = usize::MAX; - let set_button = Rect::new(348, 500, 100, 32); - let hotspot_button = Rect::new(458, 500, 100, 32); - let clear_button = Rect::new(568, 500, 100, 32); + let set_button = Rect::new(Vector2::new(348, 500), Vector2::new(100, 32)); + let hotspot_button = Rect::new(Vector2::new(458, 500), Vector2::new(100, 32)); + let clear_button = Rect::new(Vector2::new(568, 500), Vector2::new(100, 32)); let mut pixel_grid = [false; DRAW_GRID_WH as usize * DRAW_GRID_WH as usize]; let mut hotspot_selection = false; let mut hotspot_selected = false; @@ -117,7 +116,10 @@ fn main() -> SfResult<()> { CursorType::NotAllowed, ]; for i in 0..cursor_types.len() { - buttons.push(Rect::new(16, 16 + i as i32 * 36, 250, 32)); + buttons.push(Rect::new( + Vector2::new(16, 16 + i as i32 * 36), + Vector2::new(250, 32), + )); } while rw.is_open() { @@ -126,13 +128,12 @@ fn main() -> SfResult<()> { Event::Closed => rw.close(), Event::MouseButtonPressed { button: mouse::Button::Left, - x, - y, + position, } => { for (i, b) in buttons.iter().enumerate() { - if mouse_over(b, x, y) { - match cursor.load_from_system(cursor_types[i]) { - Ok(()) => { + if mouse_over(b, position) { + match Cursor::from_system(cursor_types[i]) { + Ok(cursor) => { unsafe { rw.set_mouse_cursor(&cursor); } @@ -145,7 +146,7 @@ fn main() -> SfResult<()> { } } } - if mouse_over(&set_button, x, y) { + if mouse_over(&set_button, position) { let mut pixels = [0; DRAW_GRID_WH as usize * DRAW_GRID_WH as usize * 4]; for (i, px) in pixel_grid.iter().enumerate() { let offset = i * 4; @@ -157,12 +158,12 @@ fn main() -> SfResult<()> { } } unsafe { - match cursor.load_from_pixels( + match Cursor::from_pixels( &pixels, Vector2::new(DRAW_GRID_WH as u32, DRAW_GRID_WH as u32), hotspot, ) { - Ok(()) => { + Ok(cursor) => { rw.set_mouse_cursor(&cursor); } Err(e) => { @@ -172,13 +173,13 @@ fn main() -> SfResult<()> { } modif = false; } - if mouse_over(&clear_button, x, y) { + if mouse_over(&clear_button, position) { for px in pixel_grid.iter_mut() { *px = false; } modif = true; } - if mouse_over(&hotspot_button, x, y) { + if mouse_over(&hotspot_button, position) { hotspot_selection = true; } } @@ -201,17 +202,17 @@ fn main() -> SfResult<()> { let mp = rw.mouse_position(); let mut highlight_index = usize::MAX; for (i, b) in buttons.iter().enumerate() { - if mouse_over(b, mp.x, mp.y) { + if mouse_over(b, mp) { highlight_index = i; } } - if mouse_over(&set_button, mp.x, mp.y) { + if mouse_over(&set_button, mp) { set_button_highlighted = true; } - if mouse_over(&hotspot_button, mp.x, mp.y) { + if mouse_over(&hotspot_button, mp) { hotspot_button_highlighted = true; } - if mouse_over(&clear_button, mp.x, mp.y) { + if mouse_over(&clear_button, mp) { clear_button_highlighted = true; } // Grid interactions diff --git a/examples/custom-drawable.rs b/examples/custom-drawable.rs index a141e754..27e2c7e4 100644 --- a/examples/custom-drawable.rs +++ b/examples/custom-drawable.rs @@ -43,6 +43,7 @@ fn main() -> SfResult<()> { [800, 600], "Custom drawable", Style::CLOSE, + Default::default(), &Default::default(), )?; window.set_vertical_sync_enabled(true); diff --git a/examples/custom-shape.rs b/examples/custom-shape.rs index d4452203..9cbdbcbe 100644 --- a/examples/custom-shape.rs +++ b/examples/custom-shape.rs @@ -48,6 +48,7 @@ fn main() -> SfResult<()> { [800, 600], "Custom shape", Style::DEFAULT, + Default::default(), &Default::default(), )?; let clock = Clock::start()?; diff --git a/examples/custom-sound-recorder.rs b/examples/custom-sound-recorder.rs index 783b2d7c..d795615d 100644 --- a/examples/custom-sound-recorder.rs +++ b/examples/custom-sound-recorder.rs @@ -1,6 +1,9 @@ use { sfml::{ - audio::{Sound, SoundBuffer, SoundRecorder, SoundRecorderDriver, capture}, + audio::{ + Sound, SoundBuffer, SoundRecorder, SoundRecorderDriver, capture, + sound_channel::SoundChannel, + }, graphics::{Color, Font, RectangleShape, RenderTarget, RenderWindow, Text, Transformable}, window::{Event, Key, Style}, }, @@ -75,6 +78,7 @@ fn main() -> Result<(), Box> { (800, 600), "Custom sound recorder", Style::CLOSE, + Default::default(), &Default::default(), )?; rw.set_vertical_sync_enabled(true); @@ -85,7 +89,7 @@ fn main() -> Result<(), Box> { let mut started = false; let mut snd_buf = SoundBuffer::new()?; let mut samp_accum = Vec::new(); - let mut sound = Some(Sound::new()); + let mut sound = Some(Sound::new(&snd_buf)); let mut selected_dev_idx = 0; let mut mode = Mode::Main; let mut input_buf = String::new(); diff --git a/examples/custom-sound-stream.rs b/examples/custom-sound-stream.rs index 2185dedd..890748f8 100644 --- a/examples/custom-sound-stream.rs +++ b/examples/custom-sound-stream.rs @@ -1,5 +1,5 @@ use sfml::{ - audio::{SoundStatus, SoundStream, SoundStreamPlayer}, + audio::{SoundStatus, SoundStream, SoundStreamPlayer, sound_channel::SoundChannel}, system::Time, }; diff --git a/examples/mouse.rs b/examples/mouse.rs index d6eb7cde..85a3f83a 100644 --- a/examples/mouse.rs +++ b/examples/mouse.rs @@ -9,6 +9,7 @@ fn main() -> SfResult<()> { (800, 600), "Mouse events", Style::CLOSE, + Default::default(), &Default::default(), )?; window.set_mouse_cursor_visible(false); @@ -32,21 +33,47 @@ fn main() -> SfResult<()> { while let Some(ev) = window.poll_event() { match ev { Event::Closed => break 'mainloop, - Event::MouseWheelScrolled { wheel, delta, x, y } => { - push_text!(x, y, "Scroll: {:?}, {}, {}, {}", wheel, delta, x, y); + Event::MouseWheelScrolled { + wheel, + delta, + position, + } => { + push_text!( + position.x, + position.y, + "Scroll: {:?}, {}, {}, {}", + wheel, + delta, + position.x, + position.y + ); } - Event::MouseButtonPressed { button, x, y } => { - push_text!(x, y, "Press: {:?}, {}, {}", button, x, y); + Event::MouseButtonPressed { button, position } => { + push_text!( + position.x, + position.y, + "Press: {:?}, {}, {}", + button, + position.x, + position.y + ); } - Event::MouseButtonReleased { button, x, y } => { - push_text!(x, y, "Release: {:?}, {}, {}", button, x, y); + Event::MouseButtonReleased { button, position } => { + push_text!( + position.x, + position.y, + "Release: {:?}, {}, {}", + button, + position.x, + position.y + ); } Event::KeyPressed { code, .. } => { if code == Key::W { window.set_mouse_position(Vector2i::new(400, 300)); } else if code == Key::D { let dm = VideoMode::desktop_mode(); - let center = Vector2i::new(dm.width as i32 / 2, dm.height as i32 / 2); + let center = Vector2i::new(dm.size.x as i32 / 2, dm.size.y as i32 / 2); mouse::set_desktop_position(center); } else if code == Key::V { cursor_visible = !cursor_visible; @@ -87,7 +114,7 @@ fn main() -> SfResult<()> { .global_bounds() .intersection(&texts[j].global_bounds()) { - texts[j].move_((0., -intersect.height)); + texts[j].move_((0., -intersect.size.y)); } } } diff --git a/examples/opengl.rs b/examples/opengl.rs index b3a5afc0..c4acbb23 100644 --- a/examples/opengl.rs +++ b/examples/opengl.rs @@ -30,13 +30,13 @@ fn main() -> SfResult<()> { (800, 600), "SFML graphics with OpenGL", Style::default(), + Default::default(), &ctx_sett, )?; window.set_vertical_sync_enabled(true); let mut bg_tex = Texture::new()?; - bg_tex.set_srgb(srgb); - bg_tex.load_from_file("opengl-background.jpg", IntRect::default())?; + bg_tex.load_from_file("opengl-background.jpg", srgb, IntRect::default())?; let bg_sprite = Sprite::with_texture(&bg_tex); let font = Font::from_file("sansation.ttf")?; @@ -136,10 +136,10 @@ fn main() -> SfResult<()> { srgb = !srgb; window.close(); } - Event::Resized { width, height } => { + Event::Resized { size } => { window.set_active(true)?; unsafe { - gl::glViewport(0, 0, width as _, height as _); + gl::glViewport(0, 0, size.x as _, size.y as _); } window.set_active(false)?; } diff --git a/examples/pong.rs b/examples/pong.rs index 400cb015..b0e3c634 100644 --- a/examples/pong.rs +++ b/examples/pong.rs @@ -8,7 +8,7 @@ use { Transformable, }, system::{Clock, Time, Vector2f}, - window::{ContextSettings, Event, Key, Scancode, Style}, + window::{ContextSettings, Event, Key, Scancode, Style, window_enums::State}, }, std::{env, f32::consts::PI}, }; @@ -48,6 +48,7 @@ fn main() -> SfResult<()> { [game_width, game_height], "SFML Pong", Style::CLOSE, + State::Windowed, &context_settings, )?; let context_settings = window.settings(); @@ -88,12 +89,13 @@ fn main() -> SfResult<()> { let font = Font::from_file("sansation.ttf")?; // Initialize the pause message - let mut pause_message = Text::default(); - pause_message.set_font(&font); - pause_message.set_character_size(40); + let mut pause_message = Text::new( + "Welcome to SFML pong!\nPress space to start the game", + &font, + 40, + ); pause_message.set_position((170., 150.)); pause_message.set_fill_color(Color::WHITE); - pause_message.set_string("Welcome to SFML pong!\nPress space to start the game"); // Define the paddles properties let mut ai_timer = Clock::start()?; diff --git a/examples/rc-resources.rs b/examples/rc-resources.rs index 21f3582a..7bfa86df 100644 --- a/examples/rc-resources.rs +++ b/examples/rc-resources.rs @@ -5,17 +5,20 @@ use sfml::{ Shape, Sprite, Texture, Transformable, }, system::Vector2f, - window::{Event, Key, Style, clipboard}, + window::{Event, Key, Style, clipboard, window_enums::State}, }; include!("../example_common.rs"); +enum EitherResource { + Sprite(RcSprite), + Text(RcText), +} + struct FloatingResource { up: bool, left: bool, - render_sprite: bool, - sprite: RcSprite, - text: RcText, + either_resource: EitherResource, speed: f32, } @@ -24,80 +27,76 @@ impl FloatingResource { Self { up, left, - sprite: RcSprite::with_texture(texture), - text: Default::default(), + either_resource: EitherResource::Sprite(RcSprite::with_texture(texture)), speed, - render_sprite: true, } } fn with_font(font: &RcFont, up: bool, left: bool, speed: f32) -> Self { - let mut self_ = Self { + let mut text = RcText::new("", font, 16); + text.scale(Vector2f::new(2., 2.)); + Self { up, left, - sprite: Default::default(), - text: RcText::new("", font, 16), + either_resource: EitherResource::Text(text), speed, - render_sprite: false, - }; - self_.text.scale(Vector2f::new(2., 2.)); - - self_ + } } fn render(&self, window: &mut RenderWindow) { - if self.render_sprite { - window.draw(&self.sprite) - } else { - window.draw(&self.text) + match &self.either_resource { + EitherResource::Sprite(sprite) => window.draw(sprite), + EitherResource::Text(text) => window.draw(text), } } fn move_resources(&mut self, window_size: Vector2f) { - if self.render_sprite { - // Modify the sprite position freely - if self.sprite.position().y <= 0f32 { - self.up = false; - } - if self.sprite.position().y + self.sprite.global_bounds().height >= window_size.y { - self.up = true; - } - if self.sprite.position().x <= 0f32 { - self.left = false; - } - if self.sprite.position().x + self.sprite.global_bounds().width >= window_size.x { - self.left = true; - } + match &mut self.either_resource { + EitherResource::Sprite(sprite) => { + if sprite.position().y <= 0f32 { + self.up = false; + } + if sprite.position().y + sprite.global_bounds().size.y >= window_size.y { + self.up = true; + } + if sprite.position().x <= 0f32 { + self.left = false; + } + if sprite.position().x + sprite.global_bounds().size.x >= window_size.x { + self.left = true; + } - self.sprite.set_position( - self.sprite.position() - + Vector2f::new( - if self.left { -self.speed } else { self.speed }, - if self.up { -self.speed } else { self.speed }, - ), - ); - } else { - // Modify the sprite position freely - if self.text.position().y <= 0f32 { - self.up = false; - } - if self.text.position().y + self.text.global_bounds().height >= window_size.y { - self.up = true; - } - if self.text.position().x <= 0f32 { - self.left = false; - } - if self.text.position().x + self.text.global_bounds().width >= window_size.x { - self.left = true; + sprite.set_position( + sprite.position() + + Vector2f::new( + if self.left { -self.speed } else { self.speed }, + if self.up { -self.speed } else { self.speed }, + ), + ); } + EitherResource::Text(text) => { + // Modify the sprite position freely + if text.position().y <= 0f32 { + self.up = false; + } + if text.position().y + text.global_bounds().size.y >= window_size.y { + self.up = true; + } + if text.position().x <= 0f32 { + self.left = false; + } + if text.position().x + text.global_bounds().size.x >= window_size.x { + self.left = true; + } - self.text.set_position( - self.text.position() - + Vector2f::new( - if self.left { -self.speed } else { self.speed }, - if self.up { -self.speed } else { self.speed }, - ), - ); + text.set_position( + text.position() + + Vector2f::new( + if self.left { -self.speed } else { self.speed }, + if self.up { -self.speed } else { self.speed }, + ), + ); + } } } } @@ -121,8 +120,13 @@ fn get_set_smooth_rc_text(font: &RcFont) -> RcText { fn main() -> SfResult<()> { example_ensure_right_working_dir(); - let mut window = - RenderWindow::new((800, 600), "SFML window", Style::CLOSE, &Default::default())?; + let mut window = RenderWindow::new( + (800, 600), + "SFML window", + Style::CLOSE, + State::Windowed, + &Default::default(), + )?; window.set_framerate_limit(60); // Create a new texture. @@ -189,7 +193,9 @@ fn main() -> SfResult<()> { // Update floating_resource positions so they move around on the screen for floating_resource in &mut floating_resources { floating_resource.move_resources(Vector2f::new(800f32, 600f32)); - floating_resource.text.set_string(&text_buf); + if let EitherResource::Text(text) = &mut floating_resource.either_resource { + text.set_string(&text_buf); + } } window.clear(Color::BLACK); diff --git a/examples/resource-holder.rs b/examples/resource-holder.rs index 354e99d4..717cfc9f 100644 --- a/examples/resource-holder.rs +++ b/examples/resource-holder.rs @@ -6,7 +6,7 @@ use { audio::{Sound, SoundBuffer}, cpp::FBox, graphics::{Color, RenderTarget, RenderWindow, Sprite, Texture}, - window::{Event, Key, Style}, + window::{Event, Key, Style, window_enums::State}, }, std::{collections::HashMap, hash::Hash}, }; @@ -63,6 +63,7 @@ fn main() -> SfResult<()> { (800, 600), "Resource holder test", Style::CLOSE, + State::Windowed, &Default::default(), )?; rw.set_vertical_sync_enabled(true); diff --git a/examples/shader.rs b/examples/shader.rs index f999ab2f..29436475 100644 --- a/examples/shader.rs +++ b/examples/shader.rs @@ -8,8 +8,8 @@ use { RenderTexture, RenderWindow, Shader, ShaderType, Sprite, Text, Texture, Transform, Transformable, Vertex, }, - system::{Clock, Vector2f}, - window::{Event, Key, Style}, + system::{Clock, Vector2, Vector2f}, + window::{Event, Key, Style, window_enums::State}, }, }; @@ -27,10 +27,8 @@ struct Pixelate<'t> { impl<'t> Pixelate<'t> { fn new(texture: &'t Texture) -> SfResult { - let mut sprite = Sprite::new(); - sprite.set_texture(texture, false); Ok(Self { - sprite, + sprite: Sprite::with_texture(texture), shader: Shader::from_file("pixelate.frag", ShaderType::Fragment)?, }) } @@ -182,7 +180,7 @@ struct Edge<'t> { impl<'t> Edge<'t> { fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult { - let mut surface = RenderTexture::new(800, 600)?; + let mut surface = RenderTexture::new(Vector2::new(800, 600))?; surface.set_smooth(true); let mut bg_sprite = Sprite::with_texture(bg_texture); bg_sprite.set_position((135., 100.)); @@ -191,7 +189,7 @@ impl<'t> Edge<'t> { for i in 0..6 { entities.push(Sprite::with_texture_and_rect( entity_texture, - IntRect::new(96 * i, 0, 96, 96), + IntRect::new(Vector2::new(96 * i, 0), Vector2::new(96, 96)), )); } @@ -302,7 +300,7 @@ impl Drawable for Geometry<'_> { impl Effect for Geometry<'_> { fn update(&mut self, _t: f32, x: f32, y: f32) -> SfResult<()> { self.transform = Transform::IDENTITY; - self.transform.translate(400., 300.); + self.transform.translate(Vector2::new(400., 300.)); self.transform.rotate(x * 360.0); let size = 25. + y.abs() * 50.; self.shader.set_uniform_vec2("size", size.into())?; @@ -321,6 +319,7 @@ fn main() -> SfResult<()> { (800, 600), "SFML Shader", Style::TITLEBAR | Style::CLOSE, + State::Windowed, &Default::default(), )?; window.set_vertical_sync_enabled(true); diff --git a/examples/spritemark.rs b/examples/spritemark.rs index 8f435a6c..ef766d75 100644 --- a/examples/spritemark.rs +++ b/examples/spritemark.rs @@ -7,8 +7,8 @@ use { sfml::{ SfResult, graphics::{ - Color, Font, PrimitiveType, Rect, RenderStates, RenderTarget, RenderWindow, Text, - Texture, Transform, Vertex, View, + Color, Font, PrimitiveType, RenderStates, RenderTarget, RenderWindow, Text, Texture, + Transform, Vertex, View, }, system::{Clock, Vector2, Vector2f, Vector2i}, window::{ContextSettings, Event, Key, Style, VideoMode, mouse::Button}, @@ -67,6 +67,7 @@ fn main() -> SfResult<()> { native_mode, "Spritemark", Style::default(), + Default::default(), &ContextSettings::default(), )?; window.set_position(Vector2::new(0, 0)); @@ -85,7 +86,6 @@ fn main() -> SfResult<()> { let mut sec_clock = Clock::start()?; let mut fps = 0; let mut lmb_down = false; - let mut view = View::new()?; while window.is_open() { while let Some(event) = window.poll_event() { @@ -107,8 +107,8 @@ fn main() -> SfResult<()> { } => { lmb_down = false; } - Event::Resized { width, height } => { - view.reset(Rect::new(0., 0., width as f32, height as f32)); + Event::Resized { size } => { + let view = View::with_center_and_size(Vector2::new(0., 0.), size.as_other()); window.set_view(&view); } _ => {} @@ -132,8 +132,8 @@ fn main() -> SfResult<()> { let size = f32::from(SUBIMAGE_SIZE); let tex_x = f32::from(obj.image_id) * size; let mut tf = Transform::default(); - tf.translate(obj.position.x, obj.position.y); - tf.rotate_with_center(obj.angle, size / 2.0, size / 2.0); + tf.translate(obj.position); + tf.rotate_with_center(obj.angle, Vector2::new(size / 2., size / 2.)); buf.push(Vertex { color: Color::WHITE, position: tf.transform_point(Vector2f::new(0., 0.)), @@ -158,7 +158,7 @@ fn main() -> SfResult<()> { } window.clear(Color::BLACK); rs.texture = Some(&texture); - window.draw_primitives(&buf, PrimitiveType::QUADS, &rs); + window.draw_primitives(&buf, PrimitiveType::TRIANGLE_STRIP, &rs); rs.texture = None; text.set_string(&format!("{} sprites\n{fps} fps", objects.len())); window.draw_text(&text, &rs); diff --git a/examples/unicode-text-entry.rs b/examples/unicode-text-entry.rs index 3070c60f..614960ed 100644 --- a/examples/unicode-text-entry.rs +++ b/examples/unicode-text-entry.rs @@ -4,7 +4,7 @@ use sfml::{ Color, Font, RectangleShape, RenderTarget, RenderWindow, Shape, Text, TextStyle, Transformable, }, - window::{Event, Key, Style, clipboard}, + window::{Event, Key, Style, clipboard, window_enums::State}, }; include!("../example_common.rs"); @@ -16,6 +16,7 @@ fn main() -> SfResult<()> { (800, 600), "◢◤ Unicode text entry ◥◣", Style::CLOSE, + State::Windowed, &Default::default(), )?; window.set_vertical_sync_enabled(true); diff --git a/examples/vertex-arrays.rs b/examples/vertex-arrays.rs index 4099dc00..4e00cc6c 100644 --- a/examples/vertex-arrays.rs +++ b/examples/vertex-arrays.rs @@ -12,6 +12,7 @@ fn main() -> SfResult<()> { (800, 600), "Vertex array example", Style::CLOSE, + Default::default(), &Default::default(), )?; window.set_vertical_sync_enabled(true); diff --git a/examples/vertex-buffers.rs b/examples/vertex-buffers.rs index 96911ce6..718d7c2b 100644 --- a/examples/vertex-buffers.rs +++ b/examples/vertex-buffers.rs @@ -3,7 +3,7 @@ use sfml::{ graphics::{ Color, PrimitiveType, RenderTarget, RenderWindow, Vertex, VertexBuffer, VertexBufferUsage, }, - window::{Event, Style, mouse::Button}, + window::{Event, Style, mouse::Button, window_enums::State}, }; fn main() -> SfResult<()> { @@ -11,6 +11,7 @@ fn main() -> SfResult<()> { (800, 600), "SFML VertexBuffer accessors Example", Style::CLOSE, + State::Windowed, &Default::default(), )?; window.set_vertical_sync_enabled(true); @@ -36,11 +37,10 @@ fn main() -> SfResult<()> { Event::Closed => break 'mainloop, Event::MouseButtonPressed { button: Button::Left, - x, - y, + position, } => { vertices.push(Vertex::with_pos_color( - (x as f32, y as f32).into(), + (position.x as f32, position.y as f32).into(), Color::GREEN, )); vertex_buffer.update(&vertices, 0)?; diff --git a/examples/window-test.rs b/examples/window-test.rs index 5e34f382..d4549fc2 100644 --- a/examples/window-test.rs +++ b/examples/window-test.rs @@ -1,7 +1,7 @@ use sfml::{ SfResult, graphics::{Color, Font, RenderTarget, RenderWindow, Text, Transformable}, - window::{ContextSettings, Event, Key, Style, VideoMode}, + window::{ContextSettings, Event, Key, Style, VideoMode, window_enums::State}, }; struct WindowConfig { @@ -33,6 +33,7 @@ fn main() -> SfResult<()> { configs[cfg_idx].mode, "Window test", Style::CLOSE, + State::Windowed, &ContextSettings::default(), )?; let font = Font::from_memory_static(include_bytes!("resources/sansation.ttf"))?; @@ -51,15 +52,24 @@ fn main() -> SfResult<()> { } Key::Enter => match configs.get(cfg_idx) { Some(cfg) => { - rw.recreate(cfg.mode, cfg.title, cfg.style, &ContextSettings::default()) + rw = RenderWindow::new( + cfg.mode, + cfg.title, + cfg.style, + State::Windowed, + &ContextSettings::default(), + )? } None => match fs_modes.get(cfg_idx - configs.len()) { - Some(mode) => rw.recreate( - *mode, - "Fullscreen", - Style::FULLSCREEN, - &ContextSettings::default(), - ), + Some(mode) => { + rw = RenderWindow::new( + *mode, + "Fullscreen", + Default::default(), + State::Fullscreen, + &ContextSettings::default(), + )? + } None => { eprintln!("Invalid index: {cfg_idx}"); } @@ -113,7 +123,7 @@ fn main() -> SfResult<()> { txt.set_position((x, y)); txt.set_string(&format!( "{}x{}x{}", - mode.width, mode.height, mode.bits_per_pixel + mode.size.x, mode.size.y, mode.bits_per_pixel )); rw.draw(&txt); i += 1; diff --git a/src/audio/capture.rs b/src/audio/capture.rs index aaf73575..08e5c8bb 100644 --- a/src/audio/capture.rs +++ b/src/audio/capture.rs @@ -4,7 +4,6 @@ use { audio::SoundBuffer, cpp::{CppString, CppVector, FBox}, ffi::audio as ffi, - system::Time, }, std::{ffi::CString, os::raw::c_void, ptr::NonNull}, }; @@ -193,22 +192,6 @@ impl<'a, R: SoundRecorder> SoundRecorderDriver<'a, R> { pub fn channel_count(&self) -> u32 { unsafe { ffi::sfCustomSoundRecorder_getChannelCount(self.handle.as_ptr()) } } - /// Set the processing interval. - /// - /// The processing interval controls the period between calls to - /// [`SoundRecorder::on_process_samples`]. - /// You may want to use a small interval if you want to process the recorded data in real time, - /// for example. - /// - /// Note: this is only a hint, the actual period may vary. - /// So don't rely on this parameter to implement precise timing. - /// - /// The default processing interval is 100 ms. - pub fn set_processing_interval(&mut self, interval: Time) { - unsafe { - ffi::sfCustomSoundRecorder_setProcessingInterval(self.handle.as_ptr(), interval.raw()) - } - } /// Get the name of the current audio capture device. #[must_use] pub fn device(&self) -> &CppString { diff --git a/src/audio/mod.rs b/src/audio/mod.rs index bbf3a63f..6c51e1cb 100644 --- a/src/audio/mod.rs +++ b/src/audio/mod.rs @@ -19,6 +19,7 @@ pub mod listener; mod music; mod sound; mod sound_buffer; +pub mod sound_channel; mod sound_source; mod sound_status; mod sound_stream; diff --git a/src/audio/music.rs b/src/audio/music.rs index accb7d2c..5ca93d33 100644 --- a/src/audio/music.rs +++ b/src/audio/music.rs @@ -168,7 +168,7 @@ impl Music<'_> { /// Return true if the music is looping, false otherwise #[must_use] pub fn is_looping(&self) -> bool { - unsafe { ffi::audio::sfMusic_getLoop(self.music) } + unsafe { ffi::audio::sfMusic_isLooping(self.music) } } /// Get the total duration of a music /// @@ -240,7 +240,7 @@ impl Music<'_> { /// /// By default, the music will *not* loop. pub fn set_looping(&mut self, looping: bool) { - unsafe { ffi::audio::sfMusic_setLoop(self.music, looping) } + unsafe { ffi::audio::sfMusic_setLooping(self.music, looping) } } /// Change the current playing position of a music /// diff --git a/src/audio/sound.rs b/src/audio/sound.rs index c0c8eebd..6c16d1ec 100644 --- a/src/audio/sound.rs +++ b/src/audio/sound.rs @@ -50,8 +50,8 @@ impl<'buf> Sound<'buf> { /// /// Panics on allocation failure #[must_use] - pub fn new() -> Self { - let s = unsafe { ffi::audio::sfSound_new() }; + pub fn new(sound_buffer: &'buf SoundBuffer) -> Self { + let s = unsafe { ffi::audio::sfSound_new(sound_buffer) }; Sound { handle: NonNull::new(s).expect("Failed to create Sound"), buffer: PhantomData, @@ -61,7 +61,7 @@ impl<'buf> Sound<'buf> { /// Create a new `Sound` with a buffer #[must_use] pub fn with_buffer(buffer: &'buf SoundBuffer) -> Self { - let mut s = Sound::new(); + let mut s = Sound::new(buffer); s.set_buffer(buffer); s } @@ -105,7 +105,7 @@ impl<'buf> Sound<'buf> { /// Return true if the sound is looping, false otherwise #[must_use] pub fn is_looping(&self) -> bool { - unsafe { ffi::audio::sfSound_getLoop(self.handle.as_ptr()) } + unsafe { ffi::audio::sfSound_isLooping(self.handle.as_ptr()) } } /// Get the current status of a sound (stopped, paused, playing) @@ -136,7 +136,7 @@ impl<'buf> Sound<'buf> { impl<'buf> Sound<'buf> { /// Sets whether this sound should loop or not. pub fn set_looping(&mut self, looping: bool) { - unsafe { ffi::audio::sfSound_setLoop(self.handle.as_ptr(), looping) } + unsafe { ffi::audio::sfSound_setLooping(self.handle.as_ptr(), looping) } } /// Change the current playing position of a sound @@ -159,12 +159,6 @@ impl<'buf> Sound<'buf> { } } -impl Default for Sound<'_> { - fn default() -> Self { - Self::new() - } -} - impl Clone for Sound<'_> { fn clone(&self) -> Self { let s = unsafe { ffi::audio::sfSound_cpy(self.handle.as_ptr()) }; diff --git a/src/audio/sound_buffer.rs b/src/audio/sound_buffer.rs index 23b19bf8..bf7d36b9 100644 --- a/src/audio/sound_buffer.rs +++ b/src/audio/sound_buffer.rs @@ -1,4 +1,5 @@ use { + super::sound_channel::SoundChannel, crate::{ IntoSfResult, SfResult, cpp::FBox, @@ -83,9 +84,10 @@ impl SoundBuffer { samples: &[i16], channel_count: u32, sample_rate: u32, + channel_map: &[SoundChannel], ) -> SfResult> { let mut new = Self::new()?; - new.load_from_samples(samples, channel_count, sample_rate)?; + new.load_from_samples(samples, channel_count, sample_rate, channel_map)?; Ok(new) } /// Load sound data from a file. @@ -119,6 +121,7 @@ impl SoundBuffer { samples: &[i16], channel_count: u32, sample_rate: u32, + channel_map: &[SoundChannel], ) -> SfResult<()> { unsafe { ffi::audio::sfSoundBuffer_loadFromSamples( @@ -127,6 +130,7 @@ impl SoundBuffer { samples.len() as _, channel_count, sample_rate, + channel_map.as_ptr().cast(), ) } .into_sf_result() diff --git a/src/audio/sound_channel.rs b/src/audio/sound_channel.rs new file mode 100644 index 00000000..120621c1 --- /dev/null +++ b/src/audio/sound_channel.rs @@ -0,0 +1,53 @@ +use crate::{ + cpp::{CppVector, CppVectorItem}, + ffi::audio as ffi, +}; + +/// Types of sound channels that can be read/written form sound buffers/files +/// +/// In multi-channel audio, each sound channel can be +/// assigned a position. The position of the channel is +/// used to determine where to place a sound when it +/// is spatialized. Assigning an incorrect sound channel +/// will result in multi-channel audio being positioned +/// incorrectly when using spatialization. +#[repr(C)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +#[allow(missing_docs)] +pub enum SoundChannel { + #[default] + Unspecified, + Mono, + FrontLeft, + FrontRight, + FrontCenter, + FrontLeftOfCenter, + FrontRightOfCenter, + LowFrequencyEffects, + BackLeft, + BackRight, + BackCenter, + SideLeft, + SideRight, + TopCenter, + TopFrontLeft, + TopFrontRight, + TopFrontCenter, + TopBackLeft, + TopBackRight, + TopBackCenter, +} + +unsafe impl CppVectorItem for SoundChannel { + fn get_data(vec: &crate::cpp::CppVector) -> *const Self { + unsafe { ffi::sfSoundChannelVector_getData(vec) } + } + + fn get_len(vec: &CppVector) -> usize { + unsafe { ffi::sfSoundChannelVector_getLength(vec) } + } + + fn del(vec: &mut CppVector) { + unsafe { ffi::sfSoundChannelVector_del(vec) } + } +} diff --git a/src/audio/sound_stream.rs b/src/audio/sound_stream.rs index 2d3e2770..e5d4f17c 100644 --- a/src/audio/sound_stream.rs +++ b/src/audio/sound_stream.rs @@ -1,6 +1,8 @@ use { + super::sound_channel::SoundChannel, crate::{ audio::{SoundSource, SoundStatus}, + cpp::CppVector, ffi::audio::*, system::{Time, Vector3f}, }, @@ -23,6 +25,11 @@ pub trait SoundStream: Send { fn channel_count(&self) -> u32; /// Get the stream sample rate of the stream. fn sample_rate(&self) -> u32; + /// This is used to map a sample in the sample stream to a + /// position during spatialization. + /// + /// Return Map of position in sample frame to sound channel} + fn get_channel_map(&self) -> Vec; } /// Player for custom streamed audio sources. See [`SoundStream`]. @@ -81,6 +88,7 @@ impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> { pub fn new(sound_stream: &'a mut S) -> Self { let channel_count = sound_stream.channel_count(); let sample_rate = sound_stream.sample_rate(); + let channel_map = sound_stream.get_channel_map(); let sound_stream: *mut S = sound_stream; Self { handle: unsafe { @@ -89,6 +97,7 @@ impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> { Some(seek_callback::), channel_count, sample_rate, + channel_map.as_ptr().cast(), sound_stream.cast(), )) .expect("Failed to create SoundStreamPlayer") @@ -159,10 +168,18 @@ impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> { pub fn sample_rate(&self) -> u32 { unsafe { sfCustomSoundStream_getSampleRate(self.handle.as_ptr()) } } + /// This is used to map a sample in the sample stream to a + /// position during spatialization. + /// + /// Return Map of position in sample frame to sound channel + #[must_use] + pub fn channel_map(&self) -> &'static CppVector { + unsafe { &*sfCustomSoundStream_getChannelMap(self.handle.as_ptr()) } + } /// Tell whether or not the stream is in loop mode. #[must_use] pub fn is_looping(&self) -> bool { - unsafe { sfCustomSoundStream_getLoop(self.handle.as_ptr()) } + unsafe { sfCustomSoundStream_isLooping(self.handle.as_ptr()) } } /// Set whether or not the stream should loop after reaching the end. /// @@ -170,7 +187,7 @@ impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> { /// until it is stopped or `set_looping(false)` is called. /// The default looping state for streams is false. pub fn set_looping(&mut self, looping: bool) { - unsafe { sfCustomSoundStream_setLoop(self.handle.as_ptr(), looping) } + unsafe { sfCustomSoundStream_setLooping(self.handle.as_ptr(), looping) } } } diff --git a/src/ffi/audio.rs b/src/ffi/audio.rs index 24c91ec1..c70d0e7f 100644 --- a/src/ffi/audio.rs +++ b/src/ffi/audio.rs @@ -1,6 +1,7 @@ pub use crate::ffi::*; use { super::system::sfInputStreamHelper, + crate::audio::sound_channel::SoundChannel as sfSoundChannel, crate::cpp::{CppString as sfStdString, CppStringVector as sfStdStringVector}, }; @@ -13,6 +14,7 @@ decl_opaque! { } pub type sfSoundBuffer = crate::audio::SoundBuffer; +pub(crate) type sfSoundChannelVector = crate::cpp::CppVector; #[repr(C)] pub struct sfSoundStreamChunk { diff --git a/src/ffi/audio_bindgen.rs b/src/ffi/audio_bindgen.rs index 8c02066b..bc2b5eb1 100644 --- a/src/ffi/audio_bindgen.rs +++ b/src/ffi/audio_bindgen.rs @@ -9,13 +9,12 @@ pub fn sfCustomSoundRecorder_del(soundRecorder: *mut sfCustomSoundRecorder); pub fn sfCustomSoundRecorder_start(soundRecorder: *mut sfCustomSoundRecorder, sampleRate: c_uint) -> bool; pub fn sfCustomSoundRecorder_stop(soundRecorder: *mut sfCustomSoundRecorder); pub fn sfCustomSoundRecorder_getSampleRate(soundRecorder: *const sfCustomSoundRecorder) -> c_uint; -pub fn sfCustomSoundRecorder_setProcessingInterval(soundRecorder: *mut sfCustomSoundRecorder, interval: i64); pub fn sfCustomSoundRecorder_setDevice(soundRecorder: *mut sfCustomSoundRecorder, name: *const c_char) -> bool; pub fn sfCustomSoundRecorder_getDevice(soundRecorder: *mut sfCustomSoundRecorder) -> *const sfStdString; pub fn sfCustomSoundRecorder_setChannelCount(soundRecorder: *mut sfCustomSoundRecorder, channelCount: c_uint); pub fn sfCustomSoundRecorder_getChannelCount(soundRecorder: *const sfCustomSoundRecorder) -> c_uint; // CustomSoundStream.cpp -pub fn sfCustomSoundStream_new(onGetData: sfCustomSoundStreamGetDataCb, onSeek: sfCustomSoundStreamSeekCb, channelCount: c_uint, sampleRate: c_uint, userData: *mut c_void) -> *mut sfCustomSoundStream; +pub fn sfCustomSoundStream_new(onGetData: sfCustomSoundStreamGetDataCb, onSeek: sfCustomSoundStreamSeekCb, channelCount: c_uint, sampleRate: c_uint, channel: *const sfSoundChannelVector, userData: *mut c_void) -> *mut sfCustomSoundStream; pub fn sfCustomSoundStream_del(soundStream: *mut sfCustomSoundStream); pub fn sfCustomSoundStream_play(soundStream: *mut sfCustomSoundStream); pub fn sfCustomSoundStream_pause(soundStream: *mut sfCustomSoundStream); @@ -23,6 +22,7 @@ pub fn sfCustomSoundStream_stop(soundStream: *mut sfCustomSoundStream); pub fn sfCustomSoundStream_getStatus(soundStream: *const sfCustomSoundStream) -> sfSoundStreamStatus; pub fn sfCustomSoundStream_getChannelCount(soundStream: *const sfCustomSoundStream) -> c_uint; pub fn sfCustomSoundStream_getSampleRate(soundStream: *const sfCustomSoundStream) -> c_uint; +pub fn sfCustomSoundStream_getChannelMap(soundStream: *const sfCustomSoundStream) -> *const sfSoundChannelVector; pub fn sfCustomSoundStream_setPitch(soundStream: *mut sfCustomSoundStream, pitch: f32); pub fn sfCustomSoundStream_setVolume(soundStream: *mut sfCustomSoundStream, volume: f32); pub fn sfCustomSoundStream_setPosition(soundStream: *mut sfCustomSoundStream, position: sfVector3f); @@ -30,14 +30,14 @@ pub fn sfCustomSoundStream_setRelativeToListener(soundStream: *mut sfCustomSound pub fn sfCustomSoundStream_setMinDistance(soundStream: *mut sfCustomSoundStream, distance: f32); pub fn sfCustomSoundStream_setAttenuation(soundStream: *mut sfCustomSoundStream, attenuation: f32); pub fn sfCustomSoundStream_setPlayingOffset(soundStream: *mut sfCustomSoundStream, timeOffset: i64); -pub fn sfCustomSoundStream_setLoop(soundStream: *mut sfCustomSoundStream, loop_: bool); +pub fn sfCustomSoundStream_setLooping(soundStream: *mut sfCustomSoundStream, loop_: bool); pub fn sfCustomSoundStream_getPitch(soundStream: *const sfCustomSoundStream) -> f32; pub fn sfCustomSoundStream_getVolume(soundStream: *const sfCustomSoundStream) -> f32; pub fn sfCustomSoundStream_getPosition(soundStream: *const sfCustomSoundStream) -> sfVector3f; pub fn sfCustomSoundStream_isRelativeToListener(soundStream: *const sfCustomSoundStream) -> bool; pub fn sfCustomSoundStream_getMinDistance(soundStream: *const sfCustomSoundStream) -> f32; pub fn sfCustomSoundStream_getAttenuation(soundStream: *const sfCustomSoundStream) -> f32; -pub fn sfCustomSoundStream_getLoop(soundStream: *const sfCustomSoundStream) -> bool; +pub fn sfCustomSoundStream_isLooping(soundStream: *const sfCustomSoundStream) -> bool; pub fn sfCustomSoundStream_getPlayingOffset(soundStream: *const sfCustomSoundStream) -> i64; // Listener.cpp pub fn sfListener_setGlobalVolume(volume: f32); @@ -54,8 +54,8 @@ pub fn sfMusic_del(music: *mut sfMusic); pub fn sfMusic_openFromFile(music: *mut sfMusic, filename: *const c_char) -> bool; pub fn sfMusic_openFromMemory(music: *mut sfMusic, data: *const u8, sizeInBytes: usize) -> bool; pub fn sfMusic_openFromStream(music: *mut sfMusic, stream: *mut sfInputStreamHelper) -> bool; -pub fn sfMusic_setLoop(music: *mut sfMusic, loop_: bool); -pub fn sfMusic_getLoop(music: *const sfMusic) -> bool; +pub fn sfMusic_setLooping(music: *mut sfMusic, loop_: bool); +pub fn sfMusic_isLooping(music: *const sfMusic) -> bool; pub fn sfMusic_getDuration(music: *const sfMusic) -> i64; pub fn sfMusic_getLoopPoints(music: *const sfMusic) -> sfTimeSpan; pub fn sfMusic_setLoopPoints(music: *mut sfMusic, timePoints: sfTimeSpan); @@ -80,7 +80,7 @@ pub fn sfMusic_isRelativeToListener(music: *const sfMusic) -> bool; pub fn sfMusic_getMinDistance(music: *const sfMusic) -> f32; pub fn sfMusic_getAttenuation(music: *const sfMusic) -> f32; // Sound.cpp -pub fn sfSound_new() -> *mut sfSound; +pub fn sfSound_new(buffer: *const sfSoundBuffer) -> *mut sfSound; pub fn sfSound_cpy(sound: *const sfSound) -> *mut sfSound; pub fn sfSound_del(sound: *mut sfSound); pub fn sfSound_play(sound: *mut sfSound); @@ -88,8 +88,8 @@ pub fn sfSound_pause(sound: *mut sfSound); pub fn sfSound_stop(sound: *mut sfSound); pub fn sfSound_setBuffer(sound: *mut sfSound, buffer: *const sfSoundBuffer); pub fn sfSound_getBuffer(sound: *const sfSound) -> *const sfSoundBuffer; -pub fn sfSound_setLoop(sound: *mut sfSound, loop_: bool); -pub fn sfSound_getLoop(sound: *const sfSound) -> bool; +pub fn sfSound_setLooping(sound: *mut sfSound, loop_: bool); +pub fn sfSound_isLooping(sound: *const sfSound) -> bool; pub fn sfSound_getStatus(sound: *const sfSound) -> sfSoundStatus; pub fn sfSound_setPitch(sound: *mut sfSound, pitch: f32); pub fn sfSound_setVolume(sound: *mut sfSound, volume: f32); @@ -112,7 +112,7 @@ pub fn sfSoundBuffer_cpy(soundBuffer: *const sfSoundBuffer) -> *mut sfSoundBuffe pub fn sfSoundBuffer_loadFromFile(buffer: *mut sfSoundBuffer, filename: *const c_char) -> bool; pub fn sfSoundBuffer_loadFromMemory(buffer: *mut sfSoundBuffer, data: *const u8, sizeInBytes: usize) -> bool; pub fn sfSoundBuffer_loadFromStream(buffer: *mut sfSoundBuffer, stream: *mut sfInputStreamHelper) -> bool; -pub fn sfSoundBuffer_loadFromSamples(buffer: *mut sfSoundBuffer, samples: *const i16, sampleCount: u64, channelCount: c_uint, sampleRate: c_uint) -> bool; +pub fn sfSoundBuffer_loadFromSamples(buffer: *mut sfSoundBuffer, samples: *const i16, sampleCount: u64, channelCount: c_uint, sampleRate: c_uint, channelMap: *const sfSoundChannelVector) -> bool; pub fn sfSoundBuffer_saveToFile(soundBuffer: *const sfSoundBuffer, filename: *const c_char) -> bool; pub fn sfSoundBuffer_getSamples(soundBuffer: *const sfSoundBuffer) -> *const i16; pub fn sfSoundBuffer_getSampleCount(soundBuffer: *const sfSoundBuffer) -> u64; @@ -128,6 +128,10 @@ pub fn sfSoundBufferRecorder_getSampleRate(soundBufferRecorder: *const sfSoundBu pub fn sfSoundBufferRecorder_getBuffer(soundBufferRecorder: *const sfSoundBufferRecorder) -> *const sfSoundBuffer; pub fn sfSoundBufferRecorder_setDevice(soundBufferRecorder: *mut sfSoundBufferRecorder, name: *const c_char) -> bool; pub fn sfSoundBufferRecorder_getDevice(soundBufferRecorder: *mut sfSoundBufferRecorder) -> *const sfStdString; +// SoundChannel.cpp +pub fn sfSoundChannelVector_getLength(vec: *const sfSoundChannelVector) -> usize; +pub fn sfSoundChannelVector_getData(vec: *const sfSoundChannelVector) -> *const sfSoundChannel; +pub fn sfSoundChannelVector_del(vec: *const sfSoundChannelVector); // SoundRecorder.cpp pub fn sfSoundRecorder_isAvailable() -> bool; pub fn sfSoundRecorder_getDefaultDevice() -> *mut sfStdString; diff --git a/src/ffi/graphics.rs b/src/ffi/graphics.rs index f1bb9f20..54c04680 100644 --- a/src/ffi/graphics.rs +++ b/src/ffi/graphics.rs @@ -27,6 +27,7 @@ type sfImage = crate::graphics::Image; type sfRenderWindow = crate::graphics::RenderWindow; type sfRenderTexture = crate::graphics::RenderTexture; type sfVertexBuffer = crate::graphics::VertexBuffer; +pub(crate) type sfState = crate::window::window_enums::State; /// Enumeration of the blending factors. /// @@ -70,6 +71,10 @@ pub enum BlendEquation { Subtract, /// `pixel = dst * dst_factor - src * src_factor` ReverseSubtract, + /// `pixel = min(Dst, Src)` + Min, + /// `pixel = max(Dst, Src)` + Max, } /// Blending modes for drawing. @@ -135,6 +140,102 @@ pub struct BlendMode { pub alpha_equation: BlendEquation, } +/// Enumeration of the stencil test comparisons that can be performed +/// The comparisons are mapped directly to their OpenGL equivalents, +/// specified by `glStencilFunc()`. +#[repr(C)] +#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)] +pub enum StencilComparison { + /// The stencil test never passes + Never, + /// The stencil test passes if the new value is less than the value in the stencil buffer + Less, + /// The stencil test passes if the new value is less than or equal to the value in the stencil buffer + LessEqual, + /// The stencil test passes if the new value is greater than the value in the stencil buffer + Greater, + /// The stencil test passes if the new value is greater than or equal to the value in the stencil buffer + GreaterEqual, + /// The stencil test passes if the new value is strictly equal to the value in the stencil buffer + Equal, + /// The stencil test passes if the new value is strictly unequal to the value in the stencil buffer + NotEqual, + /// The stencil test always passes + #[default] + Always, +} + +/// Enumeration of the stencil buffer update operations +/// +/// The update operations are mapped directly to their OpenGL equivalents, +/// specified by `glStencilOp()`. +#[repr(C)] +#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)] +pub enum StencilUpdateOperation { + /// If the stencil test passes, the value in the stencil buffer is not modified + #[default] + Keep, + /// If the stencil test passes, the value in the stencil buffer is set to zero + Zero, + /// If the stencil test passes, the value in the stencil buffer is set to the new value + Replace, + /// If the stencil test passes, the value in the stencil buffer is incremented and if required clamped + Increment, + /// If the stencil test passes, the value in the stencil buffer is decremented and if required clamped + Decrement, + /// If the stencil test passes, the value in the stencil buffer is bitwise inverted + Invert, +} + +/// Stencil value type (also used as a mask) +#[repr(C)] +#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)] +pub struct StencilValue { + /// The stored stencil value + value: u32, +} + +/// Stencil modes for drawing +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct StencilMode { + /// The comparison we're performing the stencil test with + comparison: StencilComparison, + /// The update operation to perform if the stencil test passes + update_operation: StencilUpdateOperation, + /// The reference value we're performing the stencil test with + reference: StencilValue, + /// The mask to apply to both the reference value and the value in the stencil buffer + mask: StencilValue, + /// Whether we should update the color buffer in addition to the stencil buffer + only: bool, +} + +impl StencilMode { + pub const DEFAULT: Self = Self { + comparison: StencilComparison::Always, + update_operation: StencilUpdateOperation::Keep, + reference: StencilValue { value: 0 }, + mask: StencilValue { value: u32::MAX }, + only: false, + }; +} + +impl Default for StencilMode { + fn default() -> Self { + Self::DEFAULT + } +} +/// Types of texture coordinates that can be used for rendering. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum CoordinateType { + /// Texture coordinates in range [0 .. 1]. + sfCoordinateTypeNormalized, + /// Texture coordinates in range [0 .. size]. + sfCoordinateTypePixels, +} + /// Types of shaders #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -271,8 +372,6 @@ pub enum sfPrimitiveType { TriangleStrip, /// List of connected triangles, a point uses the common center and the previous point to form a triangle TriangleFan, - /// List of individual quads - Quads, } type sfColor = Color; diff --git a/src/ffi/graphics_bindgen.rs b/src/ffi/graphics_bindgen.rs index f845e860..9efd6bf4 100644 --- a/src/ffi/graphics_bindgen.rs +++ b/src/ffi/graphics_bindgen.rs @@ -122,16 +122,16 @@ pub fn sfFont_getInfo(font: *const sfFont) -> sfFontInfo; pub fn sfImage_new() -> *mut sfImage; pub fn sfImage_cpy(image: *const sfImage) -> *mut sfImage; pub fn sfImage_del(image: *mut sfImage); -pub fn sfImage_create_w_h_color(image: *mut sfImage, width: c_uint, height: c_uint, color: sfColor); -pub fn sfImage_create_w_h_pixels(image: *mut sfImage, width: c_uint, height: c_uint, data: *const u8); +pub fn sfImage_resizeWithColor(image: *mut sfImage, size: sfVector2u, color: sfColor); +pub fn sfImage_resizeWithPixels(image: *mut sfImage, size: sfVector2u, pixels: *const u8); pub fn sfImage_loadFromFile(image: *mut sfImage, filename: *const c_char) -> bool; pub fn sfImage_loadFromMemory(image: *mut sfImage, data: *const u8, sizeInBytes: usize) -> bool; pub fn sfImage_loadFromStream(image: *mut sfImage, stream: *mut sfInputStreamHelper) -> bool; pub fn sfImage_saveToFile(image: *const sfImage, filename: *const c_char) -> bool; pub fn sfImage_createMaskFromColor(image: *mut sfImage, colorKey: sfColor, alpha: u8); -pub fn sfImage_copy(image: *mut sfImage, source: *const sfImage, destX: c_uint, destY: c_uint, sourceRect: sfIntRect, applyAlpha: bool); -pub fn sfImage_setPixel(image: *mut sfImage, x: c_uint, y: c_uint, color: sfColor); -pub fn sfImage_getPixel(image: *const sfImage, x: c_uint, y: c_uint) -> sfColor; +pub fn sfImage_copy(image: *mut sfImage, source: *const sfImage, dest: sfVector2u, sourceRect: sfIntRect, applyAlpha: bool) -> bool; +pub fn sfImage_setPixel(image: *mut sfImage, coords: sfVector2u, color: sfColor); +pub fn sfImage_getPixel(image: *const sfImage, coords: sfVector2u) -> sfColor; pub fn sfImage_getPixelsPtr(image: *const sfImage) -> *const u8; pub fn sfImage_getSize(image: *const sfImage) -> sfVector2u; pub fn sfImage_flipHorizontally(image: *mut sfImage); @@ -172,7 +172,7 @@ pub fn sfRectangleShape_getGlobalBounds(shape: *const sfRectangleShape) -> sfFlo // RenderTexture.cpp pub fn sfRenderTexture_new() -> *mut sfRenderTexture; pub fn sfRenderTexture_del(renderTexture: *mut sfRenderTexture); -pub fn sfRenderTexture_create(renderTexture: *mut sfRenderTexture, width: c_uint, height: c_uint, settings: *const sfContextSettings) -> bool; +pub fn sfRenderTexture_resize(texture: *mut sfRenderTexture, size: sfVector2u, settings: *const sfContextSettings) -> bool; pub fn sfRenderTexture_getSize(renderTexture: *const sfRenderTexture) -> sfVector2u; pub fn sfRenderTexture_isSrgb(renderTexture: *const sfRenderTexture) -> bool; pub fn sfRenderTexture_setActive(renderTexture: *mut sfRenderTexture, active: bool) -> bool; @@ -205,22 +205,21 @@ pub fn sfRenderTexture_setRepeated(renderTexture: *mut sfRenderTexture, repeated pub fn sfRenderTexture_isRepeated(renderTexture: *const sfRenderTexture) -> bool; pub fn sfRenderTexture_generateMipmap(renderTexture: *mut sfRenderTexture) -> bool; // RenderWindow.cpp -pub fn sfRenderWindow_new_mtss(mode: sfVideoMode, title: *const u32, style: u32, settings: *const sfContextSettings) -> *mut sfRenderWindow; +pub fn sfRenderWindow_new_mtsss(mode: sfVideoMode, title: *const u32, style: u32, state: sfState, settings: *const sfContextSettings) -> *mut sfRenderWindow; pub fn sfRenderWindow_new_handle_settings(handle: sfWindowHandle, settings: *const sfContextSettings) -> *mut sfRenderWindow; pub fn sfRenderWindow_del(renderWindow: *mut sfRenderWindow); -pub fn sfRenderWindow_create_mtss(renderWindow: *mut sfRenderWindow, mode: sfVideoMode, title: *const u32, style: u32, settings: *const sfContextSettings); pub fn sfRenderWindow_close(renderWindow: *mut sfRenderWindow); pub fn sfRenderWindow_isOpen(renderWindow: *const sfRenderWindow) -> bool; pub fn sfRenderWindow_getSettings(renderWindow: *const sfRenderWindow) -> *const sfContextSettings; pub fn sfRenderWindow_pollEvent(renderWindow: *mut sfRenderWindow, event: *mut sfEvent) -> bool; -pub fn sfRenderWindow_waitEvent(renderWindow: *mut sfRenderWindow, event: *mut sfEvent) -> bool; +pub fn sfRenderWindow_waitEvent(renderWindow: *mut sfRenderWindow, event: *mut sfEvent, timeout: i64) -> bool; pub fn sfRenderWindow_getPosition(renderWindow: *const sfRenderWindow) -> sfVector2i; pub fn sfRenderWindow_setPosition(renderWindow: *mut sfRenderWindow, position: sfVector2i); pub fn sfRenderWindow_getSize(renderWindow: *const sfRenderWindow) -> sfVector2u; pub fn sfRenderWindow_setSize(renderWindow: *mut sfRenderWindow, size: sfVector2u); pub fn sfRenderWindow_isSrgb(renderWindow: *const sfRenderWindow) -> bool; pub fn sfRenderWindow_setUnicodeTitle(renderWindow: *mut sfRenderWindow, title: *const u32); -pub fn sfRenderWindow_setIcon(renderWindow: *mut sfRenderWindow, width: c_uint, height: c_uint, pixels: *const u8); +pub fn sfRenderWindow_setIcon(renderWindow: *mut sfRenderWindow, size: sfVector2u, pixels: *const u8); pub fn sfRenderWindow_setVisible(renderWindow: *mut sfRenderWindow, visible: bool); pub fn sfRenderWindow_setVerticalSyncEnabled(renderWindow: *mut sfRenderWindow, enabled: bool); pub fn sfRenderWindow_setMouseCursorVisible(renderWindow: *mut sfRenderWindow, visible: bool); @@ -233,7 +232,7 @@ pub fn sfRenderWindow_hasFocus(renderWindow: *const sfRenderWindow) -> bool; pub fn sfRenderWindow_display(renderWindow: *mut sfRenderWindow); pub fn sfRenderWindow_setFramerateLimit(renderWindow: *mut sfRenderWindow, limit: c_uint); pub fn sfRenderWindow_setJoystickThreshold(renderWindow: *mut sfRenderWindow, threshold: f32); -pub fn sfRenderWindow_getSystemHandle(renderWindow: *const sfRenderWindow) -> sfWindowHandle; +pub fn sfRenderWindow_getNativeHandle(renderWindow: *const sfRenderWindow) -> sfWindowHandle; pub fn sfRenderWindow_clear(renderWindow: *mut sfRenderWindow, color: sfColor); pub fn sfRenderWindow_setView(renderWindow: *mut sfRenderWindow, view: *const sfView); pub fn sfRenderWindow_getView(renderWindow: *const sfRenderWindow) -> *const sfView; @@ -296,7 +295,7 @@ pub fn sfShader_bind(shader: *const sfShader); pub fn sfShader_isAvailable() -> bool; pub fn sfShader_isGeometryAvailable() -> bool; // Sprite.cpp -pub fn sfSprite_new() -> *mut sfSprite; +pub fn sfSprite_new(texture: *const sfTexture, rect: sfIntRect) -> *mut sfSprite; pub fn sfSprite_cpy(sprite: *const sfSprite) -> *mut sfSprite; pub fn sfSprite_del(sprite: *mut sfSprite); pub fn sfSprite_setPosition(sprite: *mut sfSprite, position: sfVector2f); @@ -313,7 +312,7 @@ pub fn sfSprite_scale(sprite: *mut sfSprite, factors: sfVector2f); pub fn sfSprite_getTransform(sprite: *const sfSprite) -> *const sfTransform; pub fn sfSprite_getInverseTransform(sprite: *const sfSprite) -> *const sfTransform; pub fn sfSprite_setTexture(sprite: *mut sfSprite, texture: *const sfTexture, resetRect: bool); -pub fn sfSprite_setTextureRect(sprite: *mut sfSprite, rectangle: sfIntRect); +pub fn sfSprite_setTextureRect(sprite: *mut sfSprite, rect: sfIntRect); pub fn sfSprite_setColor(sprite: *mut sfSprite, color: sfColor); pub fn sfSprite_getTexture(sprite: *const sfSprite) -> *const sfTexture; pub fn sfSprite_getTextureRect(sprite: *const sfSprite) -> sfIntRect; @@ -321,7 +320,7 @@ pub fn sfSprite_getColor(sprite: *const sfSprite) -> sfColor; pub fn sfSprite_getLocalBounds(sprite: *const sfSprite) -> sfFloatRect; pub fn sfSprite_getGlobalBounds(sprite: *const sfSprite) -> sfFloatRect; // Text.cpp -pub fn sfText_new() -> *mut sfText; +pub fn sfText_new(font: *const sfFont, string: *const u32, size: c_uint) -> *mut sfText; pub fn sfText_cpy(text: *const sfText) -> *mut sfText; pub fn sfText_del(text: *mut sfText); pub fn sfText_setPosition(text: *mut sfText, position: sfVector2f); @@ -362,21 +361,20 @@ pub fn sfText_getGlobalBounds(text: *const sfText) -> sfFloatRect; pub fn sfTexture_new() -> *mut sfTexture; pub fn sfTexture_cpy(texture: *const sfTexture) -> *mut sfTexture; pub fn sfTexture_del(texture: *mut sfTexture); -pub fn sfTexture_create(tex: *mut sfTexture, width: c_uint, height: c_uint) -> bool; -pub fn sfTexture_loadFromFile(tex: *mut sfTexture, filename: *const c_char, area: sfIntRect) -> bool; -pub fn sfTexture_loadFromMemory(tex: *mut sfTexture, data: *const c_void, sizeInBytes: usize, area: sfIntRect) -> bool; -pub fn sfTexture_loadFromStream(tex: *mut sfTexture, stream: *mut sfInputStreamHelper, area: sfIntRect) -> bool; -pub fn sfTexture_loadFromImage(tex: *mut sfTexture, image: *const sfImage, area: sfIntRect) -> bool; +pub fn sfTexture_resize(texture: *mut sfTexture, size: sfVector2u, sRgb: bool) -> bool; +pub fn sfTexture_loadFromFile(tex: *mut sfTexture, filename: *const c_char, sRgb: bool, area: sfIntRect) -> bool; +pub fn sfTexture_loadFromMemory(tex: *mut sfTexture, data: *const c_void, sizeInBytes: usize, sRgb: bool, area: sfIntRect) -> bool; +pub fn sfTexture_loadFromStream(tex: *mut sfTexture, stream: *mut sfInputStreamHelper, sRgb: bool, area: sfIntRect) -> bool; +pub fn sfTexture_loadFromImage(tex: *mut sfTexture, image: *const sfImage, sRgb: bool, area: sfIntRect) -> bool; pub fn sfTexture_getSize(texture: *const sfTexture) -> sfVector2u; pub fn sfTexture_copyToImage(texture: *const sfTexture) -> *mut sfImage; -pub fn sfTexture_updateFromPixels(texture: *mut sfTexture, pixels: *const u8, width: c_uint, height: c_uint, x: c_uint, y: c_uint); -pub fn sfTexture_updateFromTexture(destination: *mut sfTexture, texture: *const sfTexture, x: c_uint, y: c_uint); -pub fn sfTexture_updateFromImage(texture: *mut sfTexture, image: *const sfImage, x: c_uint, y: c_uint); -pub fn sfTexture_updateFromWindow(texture: *mut sfTexture, window: *const sfWindow, x: c_uint, y: c_uint); -pub fn sfTexture_updateFromRenderWindow(texture: *mut sfTexture, renderWindow: *const sfRenderWindow, x: c_uint, y: c_uint); +pub fn sfTexture_updateFromPixels(texture: *mut sfTexture, pixels: *const u8, size: sfVector2u, dest: sfVector2u); +pub fn sfTexture_updateFromTexture(destination: *mut sfTexture, texture: *const sfTexture, dest: sfVector2u); +pub fn sfTexture_updateFromImage(texture: *mut sfTexture, image: *const sfImage, dest: sfVector2u); +pub fn sfTexture_updateFromWindow(texture: *mut sfTexture, window: *const sfWindow, dest: sfVector2u); +pub fn sfTexture_updateFromRenderWindow(texture: *mut sfTexture, renderWindow: *const sfRenderWindow, dest: sfVector2u); pub fn sfTexture_setSmooth(texture: *mut sfTexture, smooth: bool); pub fn sfTexture_isSmooth(texture: *const sfTexture) -> bool; -pub fn sfTexture_setSrgb(texture: *mut sfTexture, sRgb: bool); pub fn sfTexture_isSrgb(texture: *const sfTexture) -> bool; pub fn sfTexture_setRepeated(texture: *mut sfTexture, repeated: bool); pub fn sfTexture_isRepeated(texture: *const sfTexture) -> bool; @@ -389,11 +387,11 @@ pub fn sfTexture_getMaximumSize() -> c_uint; pub fn sfTransform_transformPoint(transform: *const sfTransform, point: sfVector2f) -> sfVector2f; pub fn sfTransform_transformRect(transform: *const sfTransform, rectangle: sfFloatRect) -> sfFloatRect; pub fn sfTransform_combine(transform: *mut sfTransform, other: *const sfTransform); -pub fn sfTransform_translate(transform: *mut sfTransform, x: f32, y: f32); +pub fn sfTransform_translate(transform: *mut sfTransform, offset: sfVector2f); pub fn sfTransform_rotate(transform: *mut sfTransform, angle: f32); -pub fn sfTransform_rotateWithCenter(transform: *mut sfTransform, angle: f32, centerX: f32, centerY: f32); -pub fn sfTransform_scale(transform: *mut sfTransform, scaleX: f32, scaleY: f32); -pub fn sfTransform_scaleWithCenter(transform: *mut sfTransform, scaleX: f32, scaleY: f32, centerX: f32, centerY: f32); +pub fn sfTransform_rotateWithCenter(transform: *mut sfTransform, angle: f32, center: sfVector2f); +pub fn sfTransform_scale(transform: *mut sfTransform, scale: sfVector2f); +pub fn sfTransform_scaleWithCenter(transform: *mut sfTransform, scale: sfVector2f, center: sfVector2f); // VertexBuffer.cpp pub fn sfVertexBuffer_new() -> *mut sfVertexBuffer; pub fn sfVertexBuffer_cpy(vertexBuffer: *const sfVertexBuffer) -> *mut sfVertexBuffer; @@ -418,7 +416,6 @@ pub fn sfView_setCenter(view: *mut sfView, center: sfVector2f); pub fn sfView_setSize(view: *mut sfView, size: sfVector2f); pub fn sfView_setRotation(view: *mut sfView, angle: f32); pub fn sfView_setViewport(view: *mut sfView, viewport: sfFloatRect); -pub fn sfView_reset(view: *mut sfView, rectangle: sfFloatRect); pub fn sfView_getCenter(view: *const sfView) -> sfVector2f; pub fn sfView_getSize(view: *const sfView) -> sfVector2f; pub fn sfView_getRotation(view: *const sfView) -> f32; diff --git a/src/ffi/window.rs b/src/ffi/window.rs index bae0c02d..9adae2a5 100644 --- a/src/ffi/window.rs +++ b/src/ffi/window.rs @@ -10,6 +10,7 @@ pub(super) type sfWindow = crate::window::Window; pub(super) type sfCursor = crate::window::Cursor; pub(crate) type sfVideoModeVector = crate::cpp::CppVector; pub(super) type sfContext = crate::window::Context; +pub(crate) type sfState = crate::window::window_enums::State; /// Enumeration of the native system cursor types. /// @@ -45,26 +46,47 @@ pub(super) type sfContext = crate::window::Context; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[allow(missing_docs)] pub enum sfCursorType { + /// Arrow cursor (default) Arrow, + /// Busy arrow cursor ArrowWait, + /// Busy cursor Wait, + /// I-beam, cursor when hovering over a field allowing text entry Text, + /// Pointing hand cursor Hand, + /// Horizontal double arrow cursor SizeHorizontal, + /// Vertical double arrow cursor SizeVertical, + /// Double arrow cursor going from top-left to bottom-right SizeTopLeftBottomRight, + /// Double arrow cursor going from bottom-left to top-right SizeBottomLeftTopRight, + /// Left arrow cursor on Linux, same as SizeHorizontal on other platforms SizeLeft, + /// Right arrow cursor on Linux, same as SizeHorizontal on other platforms SizeRight, + /// Up arrow cursor on Linux, same as SizeVertical on other platforms SizeTop, + /// Down arrow cursor on Linux, same as SizeVertical on other platforms SizeBottom, + /// Top-left arrow cursor on Linux, same as SizeTopLeftBottomRight on other platforms SizeTopLeft, + /// Bottom-right arrow cursor on Linux, same as SizeTopLeftBottomRight on other platforms SizeBottomRight, + /// Bottom-left arrow cursor on Linux, same as SizeBottomLeftTopRight on other platforms SizeBottomLeft, + /// Top-right arrow cursor on Linux, same as SizeBottomLeftTopRight on other platforms SizeTopRight, + /// Combination of SizeHorizontal and SizeVertical SizeAll, + /// Crosshair cursor Cross, + /// Help cursor Help, + /// Action not allowed cursor NotAllowed, } @@ -132,8 +154,7 @@ pub struct sfContextSettings { #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct SizeEvent { - pub(crate) width: c_uint, - pub(crate) height: c_uint, + pub(crate) size: sfVector2u, } #[repr(C)] @@ -156,24 +177,27 @@ pub(crate) struct TextEvent { #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct MouseMoveEvent { - pub(crate) x: c_int, - pub(crate) y: c_int, + pub(crate) position: sfVector2i, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct MouseMoveRawEvent { + pub(crate) delta: sfVector2i, } #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct MouseButtonEvent { pub(crate) button: MouseButton, - pub(crate) x: c_int, - pub(crate) y: c_int, + pub(crate) position: sfVector2i, } #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct MouseWheelEvent { pub(crate) delta: c_int, - pub(crate) x: c_int, - pub(crate) y: c_int, + pub(crate) position: sfVector2i, } #[repr(C)] @@ -181,8 +205,7 @@ pub(crate) struct MouseWheelEvent { pub(crate) struct MouseWheelScrollEvent { pub(crate) wheel: MouseWheel, pub(crate) delta: f32, - pub(crate) x: c_int, - pub(crate) y: c_int, + pub(crate) position: sfVector2i, } #[repr(C)] @@ -210,17 +233,14 @@ pub(crate) struct JoystickButtonEvent { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct TouchEvent { pub(crate) finger: c_uint, - pub(crate) x: c_int, - pub(crate) y: c_int, + pub(crate) position: sfVector2i, } #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] pub(crate) struct SensorEvent { pub(crate) type_: crate::ffi::window::sfSensorType, - pub(crate) x: f32, - pub(crate) y: f32, - pub(crate) z: f32, + pub(crate) value: sfVector3f, } #[repr(C)] @@ -229,16 +249,16 @@ pub(crate) struct SensorEvent { pub(crate) enum EventType { Closed, Resized, - LostFocus, - GainedFocus, + FocusLost, + FocusGained, TextEntered, KeyPressed, KeyReleased, - MouseWheelMoved, MouseWheelScrolled, MouseButtonPressed, MouseButtonReleased, MouseMoved, + MouseMovedRaw, MouseEntered, MouseLeft, JoystickButtonPressed, @@ -268,6 +288,7 @@ pub(crate) union EventUnion { pub(crate) key: KeyEvent, pub(crate) text: TextEvent, pub(crate) mouse_move: MouseMoveEvent, + pub(crate) mouse_move_raw: MouseMoveRawEvent, pub(crate) mouse_button: MouseButtonEvent, pub(crate) mouse_wheel: MouseWheelEvent, pub(crate) mouse_wheel_scroll: MouseWheelScrollEvent, @@ -319,8 +340,8 @@ pub enum MouseButton { Left, Right, Middle, - XButton1, - XButton2, + Extra1, + Extra2, } type sfMouseButton = MouseButton; @@ -383,10 +404,10 @@ pub enum Key { Semicolon, Comma, Period, - Quote, + Apostrophe, Slash, Backslash, - Tilde, + Grave, Equal, Hyphen, Space, @@ -589,7 +610,6 @@ pub enum Scancode { LaunchApplication2, LaunchMail, LaunchMediaSelect, - ScancodeCount, } type sfKeyboardKey = Key; @@ -619,9 +639,6 @@ pub enum sfSensorType { UserAcceleration, ///< Measures the absolute 3D orientation (degrees) Orientation, - - ///< Keep last -- the total number of sensor types - Count, } type sfGlFunctionPointer = *const c_void; diff --git a/src/ffi/window_bindgen.rs b/src/ffi/window_bindgen.rs index ccb843b1..edf8a863 100644 --- a/src/ffi/window_bindgen.rs +++ b/src/ffi/window_bindgen.rs @@ -15,10 +15,9 @@ pub fn sfContext_getActiveContextId() -> u64; pub fn sfContext_getActiveContext() -> *const sfContext; pub fn sfContext_getFunction(name: *const c_char) -> sfGlFunctionPointer; // Cursor.cpp -pub fn sfCursor_new() -> *mut sfCursor; +pub fn sfCursor_createFromPixels(pixels: *const u8, size: sfVector2u, hotspot: sfVector2u) -> *mut sfCursor; +pub fn sfCursor_createFromSystem(type_: sfCursorType) -> *mut sfCursor; pub fn sfCursor_del(cursor: *mut sfCursor); -pub fn sfCursor_loadFromPixels(cursor: *mut sfCursor, pixels: *const u8, size: sfVector2u, hotspot: sfVector2u) -> bool; -pub fn sfCursor_loadFromSystem(cursor: *mut sfCursor, type_: sfCursorType) -> bool; // Joystick.cpp pub fn sfJoystick_isConnected(joystick: c_uint) -> bool; pub fn sfJoystick_getButtonCount(joystick: c_uint) -> c_uint; @@ -57,19 +56,19 @@ pub fn sfVideoModeVector_getData(vec: *const sfVideoModeVector) -> *const sfVide // Window.cpp pub fn sfWindow_new() -> *mut sfWindow; pub fn sfWindow_del(window: *mut sfWindow); -pub fn sfWindow_create_mtss(window: *mut sfWindow, mode: sfVideoMode, title: *const u32, style: u32, settings: *const sfContextSettings); +pub fn sfWindow_create_mtsss(window: *mut sfWindow, mode: sfVideoMode, title: *const u32, style: u32, state: sfState, settings: *const sfContextSettings); pub fn sfWindow_create_handle_settings(window: *mut sfWindow, handle: sfWindowHandle, settings: *const sfContextSettings); pub fn sfWindow_close(window: *mut sfWindow); pub fn sfWindow_isOpen(window: *const sfWindow) -> bool; pub fn sfWindow_getSettings(window: *const sfWindow) -> *const sfContextSettings; pub fn sfWindow_pollEvent(window: *mut sfWindow, event: *mut sfEvent) -> bool; -pub fn sfWindow_waitEvent(window: *mut sfWindow, event: *mut sfEvent) -> bool; +pub fn sfWindow_waitEvent(window: *mut sfWindow, event: *mut sfEvent, timeout: i64) -> bool; pub fn sfWindow_getPosition(window: *const sfWindow) -> sfVector2i; pub fn sfWindow_setPosition(window: *mut sfWindow, position: sfVector2i); pub fn sfWindow_getSize(window: *const sfWindow) -> sfVector2u; pub fn sfWindow_setSize(window: *mut sfWindow, size: sfVector2u); pub fn sfWindow_setUnicodeTitle(window: *mut sfWindow, title: *const u32); -pub fn sfWindow_setIcon(window: *mut sfWindow, width: c_uint, height: c_uint, pixels: *const u8); +pub fn sfWindow_setIcon(window: *mut sfWindow, size: sfVector2u, pixels: *const u8); pub fn sfWindow_setVisible(window: *mut sfWindow, visible: bool); pub fn sfWindow_setMouseCursorVisible(window: *mut sfWindow, visible: bool); pub fn sfWindow_setMouseCursorGrabbed(window: *mut sfWindow, grabbed: bool); @@ -82,6 +81,6 @@ pub fn sfWindow_hasFocus(window: *const sfWindow) -> bool; pub fn sfWindow_display(window: *mut sfWindow); pub fn sfWindow_setFramerateLimit(window: *mut sfWindow, limit: c_uint); pub fn sfWindow_setJoystickThreshold(window: *mut sfWindow, threshold: f32); -pub fn sfWindow_getSystemHandle(window: *const sfWindow) -> sfWindowHandle; +pub fn sfWindow_getNativeHandle(window: *const sfWindow) -> sfWindowHandle; } \ No newline at end of file diff --git a/src/graphics/image.rs b/src/graphics/image.rs index d8e28707..8275dc19 100644 --- a/src/graphics/image.rs +++ b/src/graphics/image.rs @@ -27,12 +27,10 @@ impl Image { FBox::new(unsafe { ffi::sfImage_new() }).into_sf_result() } /// Create a new `Image` filled with a solid color. - /// - /// See [`Self::recreate_solid`]. - pub fn new_solid(width: u32, height: u32, color: Color) -> SfResult> { - let mut new = Self::new()?; - new.recreate_solid(width, height, color); - Ok(new) + pub fn new_solid(size: Vector2u, color: Color) -> SfResult> { + let mut img = Self::new()?; + img.resize_with_color(size, color); + Ok(img) } /// Create a new `Image` from the provided RGBA pixel data. /// @@ -41,12 +39,10 @@ impl Image { /// # Safety /// /// Also see [`Self::recreate_from_pixels`]. - pub unsafe fn from_pixels(width: u32, height: u32, data: &[u8]) -> SfResult> { - let mut new = Self::new()?; - unsafe { - new.recreate_from_pixels(width, height, data); - } - Ok(new) + pub unsafe fn from_pixels(size: Vector2u, data: &[u8]) -> SfResult> { + let mut img = Self::new()?; + img.resize_with_pixels(size, data); + Ok(img) } /// Create a new `Image` from an image file on the filesystem. /// @@ -72,22 +68,6 @@ impl Image { new.load_from_stream(stream)?; Ok(new) } - /// Recreate with the given size, filled with a solid color. - pub fn recreate_solid(&mut self, width: u32, height: u32, color: Color) { - unsafe { - ffi::sfImage_create_w_h_color(self, width, height, color); - } - } - /// Recreate from the provided RGBA pixel data. - /// - /// # Safety - /// - /// `data` is assumed to contain 32-bit RGBA pixels, and match the given size. - pub unsafe fn recreate_from_pixels(&mut self, width: u32, height: u32, data: &[u8]) { - unsafe { - ffi::sfImage_create_w_h_pixels(self, width, height, data.as_ptr()); - } - } /// Load from image file data on the filesystem. /// /// The supported image formats are bmp, png, tga, jpg, gif, @@ -135,8 +115,8 @@ impl Image { /// This function doesn't check the validity of the pixel /// coordinates, using out-of-range values will result in /// an undefined behaviour. - pub unsafe fn set_pixel_unchecked(&mut self, x: u32, y: u32, color: Color) { - unsafe { ffi::sfImage_setPixel(self, x, y, color) } + pub unsafe fn set_pixel_unchecked(&mut self, coords: Vector2u, color: Color) { + unsafe { ffi::sfImage_setPixel(self, coords, color) } } /// Change the color of a pixel in an image @@ -145,24 +125,24 @@ impl Image { /// * x - X coordinate of pixel to change /// * y - Y coordinate of pixel to change /// * color - New color of the pixel - pub fn set_pixel(&mut self, x: u32, y: u32, color: Color) -> Result<(), PixelAccessError> { + pub fn set_pixel(&mut self, coords: Vector2u, color: Color) -> Result<(), PixelAccessError> { let image_size = self.size(); - if x >= image_size.x { + if coords.x >= image_size.x { return Err(PixelAccessError::XTooLarge { - x, + x: coords.x, width: image_size.x - 1, }); } - if y >= image_size.y { + if coords.y >= image_size.y { return Err(PixelAccessError::YTooLarge { - y, + y: coords.y, height: image_size.y - 1, }); } // Since we check for index validity before setting the pixel, it is safe unless the // image has been unloaded, but I doubt you can even do that. - unsafe { ffi::sfImage_setPixel(self, x, y, color) } + unsafe { ffi::sfImage_setPixel(self, coords, color) } Ok(()) } /// Get the color of a pixel in an image @@ -179,8 +159,8 @@ impl Image { /// coordinates, using out-of-range values will result in /// an undefined behaviour. #[must_use] - pub unsafe fn pixel_at_unchecked(&self, x: u32, y: u32) -> Color { - unsafe { ffi::sfImage_getPixel(self, x, y) } + pub unsafe fn pixel_at_unchecked(&self, coords: Vector2u) -> Color { + unsafe { ffi::sfImage_getPixel(self, coords) } } /// Get the color of a pixel in an image @@ -191,15 +171,15 @@ impl Image { /// /// Return the Color of the pixel at coordinates (x, y) #[must_use] - pub fn pixel_at(&self, x: u32, y: u32) -> Option { + pub fn pixel_at(&self, coords: Vector2u) -> Option { let image_size = self.size(); - if image_size.x <= x || image_size.y <= y { + if image_size.x <= coords.x || image_size.y <= coords.y { return None; } // Since we check for index validity before getting the pixel, it is safe unless the // image has been unloaded, but I doubt you can even do that. - unsafe { Some(ffi::sfImage_getPixel(self, x, y)) } + unsafe { Some(ffi::sfImage_getPixel(self, coords)) } } /// Return the memory buffer of this image. @@ -262,17 +242,30 @@ impl Image { pub fn copy_image( &mut self, source: &Image, - dest_x: u32, - dest_y: u32, + dest: Vector2u, source_rect: IntRect, apply_alpha: bool, - ) { - unsafe { ffi::sfImage_copy(self, source, dest_x, dest_y, source_rect, apply_alpha) } + ) -> SfResult<()> { + unsafe { ffi::sfImage_copy(self, source, dest, source_rect, apply_alpha) }.into_sf_result() } } /// Etc. impl Image { + /// Resize the image and fill it with a unique color + pub fn resize_with_color(&mut self, size: Vector2u, color: Color) { + unsafe { + ffi::sfImage_resizeWithColor(self, size, color); + } + } + /// Resize the image from an array of pixels + /// + /// The pixel array is assumed to contain 32-bits RGBA pixels, + /// and have the given `size`. If not, this is an undefined behavior. + /// If `pixels` is `nullptr`, an empty image is created. + pub fn resize_with_pixels(&mut self, size: Vector2u, data: &[u8]) { + unsafe { ffi::sfImage_resizeWithPixels(self, size, data.as_ptr()) } + } /// Save an image to a file on disk /// /// The format of the image is automatically deduced from diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs index 1a08f7c9..dba78b92 100644 --- a/src/graphics/mod.rs +++ b/src/graphics/mod.rs @@ -1,5 +1,7 @@ //! 2D graphics module: sprites, text, shapes.. +use crate::system::Vector2f; + #[doc(inline)] pub use self::blend_mode::BlendMode; pub use { @@ -100,7 +102,10 @@ pub fn vertex_array_bounds(vertices: &[Vertex]) -> FloatRect { bottom = pos.y } } - FloatRect::new(left, top, right - left, bottom - top) + FloatRect::new( + Vector2f::new(left, top), + Vector2f::new(right - left, bottom - top), + ) } else { FloatRect::default() } diff --git a/src/graphics/primitive_type.rs b/src/graphics/primitive_type.rs index b550b006..148fe26b 100644 --- a/src/graphics/primitive_type.rs +++ b/src/graphics/primitive_type.rs @@ -24,6 +24,4 @@ impl PrimitiveType { /// List of connected triangles, a point uses the common center /// and the previous point to form a triangle. pub const TRIANGLE_FAN: Self = Self(ffi::graphics::sfPrimitiveType::TriangleFan); - /// List of individual quads (deprecated, don't work with OpenGL ES) - pub const QUADS: Self = Self(ffi::graphics::sfPrimitiveType::Quads); } diff --git a/src/graphics/rc_font.rs b/src/graphics/rc_font.rs index 65cef3f5..83ab214c 100644 --- a/src/graphics/rc_font.rs +++ b/src/graphics/rc_font.rs @@ -288,6 +288,16 @@ impl RcFont { self.font.borrow_mut().set_smooth(smooth) } + /// Get the source font of an [`RcFont`] + /// + /// It let's you temprorarily borrow the [`Font`] bieng held by [`RcFont`]. + /// This may be useful for many things like using a temporary text object. + /// + /// Returns [`Font`] + pub fn raw_font(&self) -> &Font { + unsafe { &*self.font.as_ptr() } + } + /// INTERNAL FUNCTION ONLY /// Allows other rc variants to request a weak pointer to the texture pub(super) fn downgrade(&self) -> std::rc::Weak>> { diff --git a/src/graphics/rc_sprite.rs b/src/graphics/rc_sprite.rs index 2376f1f6..ade9fe32 100644 --- a/src/graphics/rc_sprite.rs +++ b/src/graphics/rc_sprite.rs @@ -1,4 +1,5 @@ use { + super::Rect, crate::{ cpp::FBox, ffi::graphics as ffi, @@ -34,20 +35,6 @@ pub struct RcSprite { } impl RcSprite { - /// Create a new sprite - /// - /// # Panics - /// - /// Panics if for some reason a `Sprite` can't be created. - #[must_use] - pub fn new() -> Self { - let sp = unsafe { ffi::sfSprite_new() }; - Self { - handle: NonNull::new(sp).expect("Failed to create Sprite"), - texture: Weak::new(), - } - } - fn texture_exists(&self) -> bool { self.texture.strong_count() != 0 } @@ -59,17 +46,23 @@ impl RcSprite { /// Create a new sprite with a texture #[must_use] pub fn with_texture(texture: &RcTexture) -> RcSprite { - let mut sprite = Self::new(); - sprite.set_texture(texture, true); - sprite + Self::with_texture_and_rect( + texture, + Rect { + position: Default::default(), + size: texture.size().as_other(), + }, + ) } /// Create a new sprite with a texture and a source rectangle #[must_use] pub fn with_texture_and_rect(texture: &RcTexture, rect: IntRect) -> RcSprite { - let mut sprite = Self::with_texture(texture); - sprite.set_texture_rect(rect); - sprite + let sp = unsafe { ffi::sfSprite_new(texture.raw_texture(), rect) }; + RcSprite { + handle: NonNull::new(sp).expect("Failed to create Sprite"), + texture: texture.downgrade(), + } } /// Change the source texture of a sprite @@ -229,12 +222,6 @@ impl RcSprite { } } -impl Default for RcSprite { - fn default() -> Self { - Self::new() - } -} - impl Clone for RcSprite { /// Return a new Sprite or panic! if there is not enough memory fn clone(&self) -> Self { diff --git a/src/graphics/rc_text.rs b/src/graphics/rc_text.rs index dff32d7b..f2413fb5 100644 --- a/src/graphics/rc_text.rs +++ b/src/graphics/rc_text.rs @@ -48,11 +48,13 @@ impl RcText { /// * font - The [`RcFont`] to display the `RcText` /// * characterSize - The size of the `RcText` pub fn new(string: S, font: &RcFont, character_size: u32) -> Self { - let mut text = Self::default(); - text.set_string(string); - text.set_font(font); - text.set_character_size(character_size); - text + let text = string.with_as_sfstr(|sfstr| unsafe { + ffi::sfText_new(font.raw_font(), sfstr.as_ptr(), character_size) + }); + RcText { + handle: NonNull::new(text).expect("Failed to create Text"), + font: font.downgrade(), + } } fn font_exists(&self) -> bool { @@ -310,16 +312,6 @@ impl RcText { } } -impl Default for RcText { - fn default() -> Self { - let text = unsafe { ffi::sfText_new() }; - Self { - handle: NonNull::new(text).expect("Failed to create Text"), - font: Weak::new(), - } - } -} - impl Clone for RcText { /// Return a new Text or panic! if there is not enough memory fn clone(&self) -> Self { diff --git a/src/graphics/rc_texture.rs b/src/graphics/rc_texture.rs index 744ef067..20508e16 100644 --- a/src/graphics/rc_texture.rs +++ b/src/graphics/rc_texture.rs @@ -113,16 +113,6 @@ impl RcTexture { }) } - /// Create the texture. - /// - /// If this function fails, the texture is left unchanged. - /// - /// Returns whether creation was successful. - #[must_use = "Check if texture was created successfully"] - pub fn create(&mut self, width: u32, height: u32) -> SfResult<()> { - self.texture.borrow_mut().create(width, height) - } - /// Get the source texture of an [`RcTexture`] /// /// It let's you temporarily borrow the [`Texture`] being held by an [`RcTexture`]. @@ -145,8 +135,8 @@ impl RcTexture { /// # Arguments /// * mem - Pointer to the file data in memory /// * area - Area of the image to load - pub fn load_from_memory(&mut self, mem: &[u8], area: IntRect) -> SfResult<()> { - self.texture.borrow_mut().load_from_memory(mem, area) + pub fn load_from_memory(&mut self, mem: &[u8], srgb: bool, area: IntRect) -> SfResult<()> { + self.texture.borrow_mut().load_from_memory(mem, srgb, area) } /// Load texture from a stream (a struct implementing Read + Seek) @@ -162,17 +152,22 @@ impl RcTexture { pub fn load_from_stream( &mut self, stream: &mut T, + srgb: bool, area: IntRect, ) -> SfResult<()> { - self.texture.borrow_mut().load_from_stream(stream, area) + self.texture + .borrow_mut() + .load_from_stream(stream, srgb, area) } /// Load texture from a file /// /// # Arguments /// * filename - Path of the image file to load - pub fn load_from_file(&mut self, filename: &str, area: IntRect) -> SfResult<()> { - self.texture.borrow_mut().load_from_file(filename, area) + pub fn load_from_file(&mut self, filename: &str, srgb: bool, area: IntRect) -> SfResult<()> { + self.texture + .borrow_mut() + .load_from_file(filename, srgb, area) } /// Convenience method to easily create and load a `RcTexture` from a file. @@ -194,8 +189,8 @@ impl RcTexture { /// /// # Arguments /// * image - Image to upload to the texture - pub fn load_from_image(&mut self, image: &Image, area: IntRect) -> SfResult<()> { - self.texture.borrow_mut().load_from_image(image, area) + pub fn load_from_image(&mut self, image: &Image, srgb: bool, area: IntRect) -> SfResult<()> { + self.texture.borrow_mut().load_from_image(image, srgb, area) } /// Update a part of the texture from the contents of a window. @@ -205,8 +200,8 @@ impl RcTexture { /// # Safety /// No additional check is performed on the size of the window, passing an invalid combination /// of window size and offset will lead to an _undefined behavior_. - pub unsafe fn update_from_window(&mut self, window: &Window, x: u32, y: u32) { - unsafe { self.texture.borrow_mut().update_from_window(window, x, y) } + pub unsafe fn update_from_window(&mut self, window: &Window, dest: Vector2u) { + unsafe { self.texture.borrow_mut().update_from_window(window, dest) } } /// Update a part of the texture from the contents of a render window. @@ -219,13 +214,12 @@ impl RcTexture { pub unsafe fn update_from_render_window( &mut self, render_window: &RenderWindow, - x: u32, - y: u32, + dest: Vector2u, ) { unsafe { self.texture .borrow_mut() - .update_from_render_window(render_window, x, y) + .update_from_render_window(render_window, dest) } } @@ -236,8 +230,8 @@ impl RcTexture { /// # Safety /// No additional check is performed on the size of the image, passing an invalid combination /// of image size and offset will lead to an _undefined behavior_. - pub unsafe fn update_from_image(&mut self, image: &Image, x: u32, y: u32) { - unsafe { self.texture.borrow_mut().update_from_image(image, x, y) } + pub unsafe fn update_from_image(&mut self, image: &Image, dest: Vector2u) { + unsafe { self.texture.borrow_mut().update_from_image(image, dest) } } /// Update a part of this texture from another texture. @@ -248,8 +242,8 @@ impl RcTexture { /// No additional check is performed on the size of the texture, /// passing an invalid combination of texture size and offset will /// lead to an _undefined behavior_. - pub unsafe fn update_from_texture(&mut self, texture: &Texture, x: u32, y: u32) { - unsafe { self.texture.borrow_mut().update_from_texture(texture, x, y) } + pub unsafe fn update_from_texture(&mut self, texture: &Texture, dest: Vector2u) { + unsafe { self.texture.borrow_mut().update_from_texture(texture, dest) } } /// Update a part of the texture from an array of pixels. @@ -262,10 +256,10 @@ impl RcTexture { /// # Panics /// /// Panics the provided parameters would result in out of bounds access. - pub fn update_from_pixels(&mut self, pixels: &[u8], width: u32, height: u32, x: u32, y: u32) { + pub fn update_from_pixels(&mut self, pixels: &[u8], size: Vector2u, dest: Vector2u) { self.texture .borrow_mut() - .update_from_pixels(pixels, width, height, x, y) + .update_from_pixels(pixels, size, dest) } /// Enable or disable the smooth filter on a texture @@ -306,24 +300,6 @@ impl RcTexture { Texture::maximum_size() } - /// Enable or disable conversion from sRGB. - /// - /// When providing texture data from an image file or memory, it can either be stored in a - /// linear color space or an sRGB color space. Most digital images account for gamma correction - /// already, so they would need to be "uncorrected" back to linear color space before being - /// processed by the hardware. The hardware can automatically convert it from the sRGB - /// color space to a linear color space when it gets sampled. When the rendered image gets - /// output to the final framebuffer, it gets converted back to sRGB. - /// - /// After enabling or disabling sRGB conversion, make sure to reload the texture data in - /// order for the setting to take effect. - /// - /// This option is only useful in conjunction with an sRGB capable framebuffer. - /// This can be requested during window creation. - pub fn set_srgb(&mut self, srgb: bool) { - self.texture.borrow_mut().set_srgb(srgb) - } - /// Generate a mipmap using the current texture data. /// /// Mipmaps are pre-computed chains of optimized textures. Each level of texture in a mipmap diff --git a/src/graphics/rect.rs b/src/graphics/rect.rs index 600fa0e9..fe4bdf25 100644 --- a/src/graphics/rect.rs +++ b/src/graphics/rect.rs @@ -1,3 +1,6 @@ +use std::ops::Div; + +use num_traits::One; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use { @@ -11,14 +14,10 @@ use { #[derive(Clone, PartialEq, Eq, Debug, Copy, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Rect { - /// Left coordinate of the rectangle. - pub left: T, - /// Top coordinate of the rectangle. - pub top: T, - /// Width of the rectangle. - pub width: T, - /// Height of the rectangle. - pub height: T, + /// Position of the top left corner of the rectangle + pub position: Vector2, + /// Size of the rectangle + pub size: Vector2, } /// A [`Rect`] of `i32`. @@ -33,36 +32,11 @@ impl Rect { /// /// ``` /// # use sfml::graphics::Rect; - /// let rect = Rect::new(10, 10, 10, 10); - /// ``` - pub const fn new(left: T, top: T, width: T, height: T) -> Self { - Rect { - left, - top, - width, - height, - } - } - - /// Construct a rectangle from its position and size. - /// - /// # Usage Example - /// - /// ``` - /// # use sfml::graphics::Rect; /// # use sfml::system::Vector2; - /// let a = Vector2::new(10, 20); - /// let b = Vector2::new(30, 40); - /// let rect = Rect::from_vecs(a, b); - /// assert_eq!(rect, Rect::new(10, 20, 30, 40)); + /// let rect = Rect::new(Vector2u::new(10, 10), Vector2u::new(10, 10)); /// ``` - pub fn from_vecs(pos: Vector2, size: Vector2) -> Rect { - Rect { - left: pos.x, - top: pos.y, - width: size.x, - height: size.y, - } + pub const fn new(position: Vector2, size: Vector2) -> Self { + Rect { position, size } } /// Lossless conversion into `Rect`. @@ -83,10 +57,8 @@ impl Rect { T: Into, { Rect { - top: self.top.into(), - left: self.left.into(), - width: self.width.into(), - height: self.height.into(), + position: self.position.into_other(), + size: self.size.into_other(), } } /// Fallible conversion into `Rect` @@ -111,10 +83,8 @@ impl Rect { T: TryInto, { Ok(Rect { - left: self.left.try_into()?, - top: self.top.try_into()?, - width: self.width.try_into()?, - height: self.height.try_into()?, + position: self.position.try_into_other()?, + size: self.size.try_into_other()?, }) } /// Lossy conversion into `Rect` @@ -135,40 +105,10 @@ impl Rect { T: AsPrimitive, { Rect { - left: self.left.as_(), - top: self.top.as_(), - width: self.width.as_(), - height: self.height.as_(), + position: self.position.as_other(), + size: self.size.as_other(), } } - - /// Get the position of the rectangle's top-left corner - /// - /// # Usage Example - /// - /// ``` - /// # use sfml::graphics::Rect; - /// # use sfml::system::Vector2; - /// let a = Rect::new(1, 2, 3, 4); - /// assert_eq!(a.position(), Vector2::new(1, 2)); - /// ``` - pub fn position(self) -> Vector2 { - Vector2::new(self.left, self.top) - } - - /// Get the size of the rectangle - /// - /// # Usage Example - /// - /// ``` - /// # use sfml::graphics::Rect; - /// # use sfml::system::Vector2; - /// let a = Rect::new(1, 2, 3, 4); - /// assert_eq!(a.size(), Vector2::new(3, 4)); - /// ``` - pub fn size(self) -> Vector2 { - Vector2::new(self.width, self.height) - } } impl + Sub + Copy> Rect { @@ -191,29 +131,9 @@ impl + Sub + Copy> Rect { /// ``` #[inline] pub fn contains(self, point: Vector2) -> bool { - self.contains2(point.x, point.y) - } - - /// Check if a point is inside the rectangle's area. - /// - /// # Usage Example - /// - /// ``` - /// # use sfml::graphics::Rect; - /// // Passing case - /// let a = Rect::new(0, 0, 4, 4); - /// assert!(a.contains2(2, 2)); - /// - /// // Failing case - /// let a = Rect::new(0, 0, 1, 1); - /// assert!(!a.contains2(20, 10)); - /// ``` - pub fn contains2(self, x: T, y: T) -> bool { - // Based on SFML's implementation. - // Rectangles with negative dimensions are allowed. - let (min_x, max_x) = min_max(self.left, self.left + self.width); - let (min_y, max_y) = min_max(self.top, self.top + self.height); - x >= min_x && x < max_x && y >= min_y && y < max_y + let (min_x, max_x) = min_max(self.position.x, self.position.x + self.size.x); + let (min_y, max_y) = min_max(self.position.y, self.position.y + self.size.y); + point.x >= min_x && point.x < max_x && point.y >= min_y && point.y < max_y } /// Returns the intersection between two rectangles, if any. @@ -237,10 +157,10 @@ impl + Sub + Copy> Rect { pub fn intersection(self, other: &Rect) -> Option> { // Based on SFML's implementation. // Compute the min and max coordinates on various axes. - let (r1_min_x, r1_max_x) = min_max(self.left, self.left + self.width); - let (r1_min_y, r1_max_y) = min_max(self.top, self.top + self.height); - let (r2_min_x, r2_max_x) = min_max(other.left, other.left + other.width); - let (r2_min_y, r2_max_y) = min_max(other.top, other.top + other.height); + let (r1_min_x, r1_max_x) = min_max(self.position.x, self.position.x + self.size.x); + let (r1_min_y, r1_max_y) = min_max(self.position.y, self.position.y + self.size.y); + let (r2_min_x, r2_max_x) = min_max(other.position.x, other.position.x + other.size.x); + let (r2_min_y, r2_max_y) = min_max(other.position.y, other.position.y + other.size.y); // Compute the intersection. let left = max(r1_min_x, r2_min_x); let top = max(r1_min_y, r2_min_y); @@ -248,13 +168,34 @@ impl + Sub + Copy> Rect { let bottom = min(r1_max_y, r2_max_y); // Return the result. if left < right && top < bottom { - Some(Rect::new(left, top, right - left, bottom - top)) + Some(Rect::new( + Vector2::new(left, top), + Vector2::new(right - left, bottom - top), + )) } else { None } } } +impl Rect +where + T: Div + One + Add + Copy, +{ + /// Return the position of the center of the rectangle + /// + /// # Usage Example + /// ``` + /// #use sfml::graphics::Rect; + /// let a = Rect::new(0, 0, 2, 2).center(); + /// assert_eq!(a, Vector2::new(1, 1)); + /// ```` + pub fn center(self) -> Vector2 { + let two = T::one() + T::one(); + self.position + self.size / two + } +} + #[inline] fn min(a: T, b: T) -> T { if a < b { a } else { b } diff --git a/src/graphics/rectangle_shape.rs b/src/graphics/rectangle_shape.rs index c76262a9..e01e52b3 100644 --- a/src/graphics/rectangle_shape.rs +++ b/src/graphics/rectangle_shape.rs @@ -55,8 +55,8 @@ impl<'s> RectangleShape<'s> { #[must_use] pub fn from_rect(rect: FloatRect) -> Self { let mut shape = Self::new(); - shape.set_size((rect.width, rect.height)); - shape.set_position((rect.left, rect.top)); + shape.set_size(rect.size); + shape.set_position(rect.position); shape } diff --git a/src/graphics/render_states.rs b/src/graphics/render_states.rs index 288087d0..e5b4f610 100644 --- a/src/graphics/render_states.rs +++ b/src/graphics/render_states.rs @@ -1,4 +1,7 @@ -use crate::graphics::{BlendMode, Shader, Texture, Transform}; +use crate::{ + ffi::graphics::{CoordinateType, StencilMode}, + graphics::{BlendMode, Shader, Texture, Transform}, +}; /// Define the states used for drawing to a [`RenderTarget`]. /// @@ -53,8 +56,12 @@ use crate::graphics::{BlendMode, Shader, Texture, Transform}; pub struct RenderStates<'texture, 'shader, 'shader_texture: 'shader> { /// The blending mode pub blend_mode: BlendMode, + /// The Stencil mode + pub stencil_mode: StencilMode, /// The transform pub transform: Transform, + /// Texture coordinate type + pub coordinate_type: CoordinateType, /// The texture that will be bound pub texture: Option<&'texture Texture>, /// The shader that will be used @@ -67,7 +74,9 @@ impl RenderStates<'_, '_, '_> { /// This can be used in a const context, unlike the [`Default`] implementation. pub const DEFAULT: Self = Self { blend_mode: BlendMode::ALPHA, + stencil_mode: StencilMode::DEFAULT, transform: Transform::IDENTITY, + coordinate_type: CoordinateType::sfCoordinateTypePixels, texture: None, shader: None, }; diff --git a/src/graphics/render_texture.rs b/src/graphics/render_texture.rs index 56f66484..f306093c 100644 --- a/src/graphics/render_texture.rs +++ b/src/graphics/render_texture.rs @@ -22,8 +22,8 @@ impl RenderTexture { /// # Arguments /// * width - Width of the render texture /// * height - Height of the render texture - pub fn new(width: u32, height: u32) -> SfResult> { - Self::with_settings(width, height, &ContextSettings::default()) + pub fn new(size: Vector2u) -> SfResult> { + Self::with_settings(size, &ContextSettings::default()) } /// Create a `RenderTexture` with the given `ContextSettings`. @@ -36,25 +36,15 @@ impl RenderTexture { /// * width - Width of the render-texture /// * height - Height of the render-texture /// * settings - Additional settings for the underlying OpenGL texture and context - pub fn with_settings( - width: u32, - height: u32, - settings: &ContextSettings, - ) -> SfResult> { + pub fn with_settings(size: Vector2u, settings: &ContextSettings) -> SfResult> { let mut new = FBox::new(unsafe { ffi::sfRenderTexture_new() }).into_sf_result()?; - new.recreate(width, height, settings)?; + new.resize(size, settings)?; Ok(new) } - /// Recreate this `RenderTexture` with the given width, height, and settings. - pub fn recreate( - &mut self, - width: u32, - height: u32, - settings: &ContextSettings, - ) -> SfResult<()> { - unsafe { ffi::sfRenderTexture_create(self, width, height, settings) }.into_sf_result() - } + pub fn resize(&mut self, size: Vector2u, settings: &ContextSettings) -> SfResult<()> { + unsafe { ffi::sfRenderTexture_resize(self, size, settings) }.into_sf_result() + } /// Update the contents of the target texture pub fn display(&mut self) { unsafe { ffi::sfRenderTexture_display(self) } diff --git a/src/graphics/render_window.rs b/src/graphics/render_window.rs index dd8f9e84..be4b32c3 100644 --- a/src/graphics/render_window.rs +++ b/src/graphics/render_window.rs @@ -7,8 +7,11 @@ use crate::{ RcText, RectangleShape, RenderStates, RenderTarget, Sprite, Text, Vertex, VertexBuffer, View, }, - system::{SfStrConv, Vector2f, Vector2i, Vector2u}, - window::{ContextSettings, Cursor, Event, Handle, Style, VideoMode, thread_safety}, + system::{SfStrConv, Time, Vector2f, Vector2i, Vector2u}, + window::{ + ContextSettings, Cursor, Event, Handle, Style, VideoMode, thread_safety, + window_enums::State, + }, }; decl_opaque! { @@ -46,37 +49,24 @@ impl RenderWindow { mode: V, title: S, style: Style, + state: State, settings: &ContextSettings, ) -> SfResult> { thread_safety::set_window_thread(); title.with_as_sfstr(|sfstr| { let ptr = unsafe { - ffi::sfRenderWindow_new_mtss(mode.into(), sfstr.as_ptr(), style.bits(), settings) + ffi::sfRenderWindow_new_mtsss( + mode.into(), + sfstr.as_ptr(), + style.bits(), + state, + settings, + ) }; FBox::new(ptr).ok_or(SfError::CallFailed) }) } - /// Recreate with new settings. See [`Self::new`] for more information. - pub fn recreate, S: SfStrConv>( - &mut self, - mode: V, - title: S, - style: Style, - settings: &ContextSettings, - ) { - thread_safety::set_window_thread(); - - title.with_as_sfstr(|sfstr| unsafe { - ffi::sfRenderWindow_create_mtss( - self, - mode.into(), - sfstr.as_ptr(), - style.bits(), - settings, - ); - }); - } /// Create a render window from an existing platform-specific window handle /// @@ -131,9 +121,11 @@ impl RenderWindow { /// sleep as long as no new event is received. /// /// Returns `Some(event)` or `None` if an error has occured - pub fn wait_event(&mut self) -> Option { + pub fn wait_event(&mut self, timeout: Time) -> Option { let mut event = std::mem::MaybeUninit::uninit(); - let have_event = unsafe { ffi::sfRenderWindow_waitEvent(self, event.as_mut_ptr()) }; + let have_event = unsafe { + ffi::sfRenderWindow_waitEvent(self, event.as_mut_ptr(), timeout.as_microseconds()) + }; if have_event { unsafe { Event::from_raw(&event.assume_init()) } } else { @@ -297,8 +289,8 @@ impl RenderWindow { /// `pixels` not being at least `width * height * 4` will likely cause undefined behavior. /// /// Platform-specific behavior is also unclear (limits on max size, etc). - pub unsafe fn set_icon(&mut self, width: u32, height: u32, pixels: &[u8]) { - unsafe { ffi::sfRenderWindow_setIcon(self, width, height, pixels.as_ptr()) } + pub unsafe fn set_icon(&mut self, size: Vector2u, pixels: &[u8]) { + unsafe { ffi::sfRenderWindow_setIcon(self, size, pixels.as_ptr()) } } /// Close a render window and destroy all the attached resources @@ -412,7 +404,7 @@ impl RenderWindow { /// doesn't support, or implement a temporary workaround until a bug is fixed. #[must_use] pub fn system_handle(&self) -> Handle { - unsafe { ffi::sfRenderWindow_getSystemHandle(self) } + unsafe { ffi::sfRenderWindow_getNativeHandle(self) } } } diff --git a/src/graphics/sprite.rs b/src/graphics/sprite.rs index d3ba76fd..5fc53081 100644 --- a/src/graphics/sprite.rs +++ b/src/graphics/sprite.rs @@ -1,4 +1,5 @@ use { + super::Rect, crate::{ ffi::graphics as ffi, graphics::{ @@ -27,34 +28,26 @@ pub struct Sprite<'s> { } impl<'s> Sprite<'s> { - /// Create a new sprite - /// - /// # Panics - /// - /// Panics if a new `Sprite` can't be created for some reason. - #[must_use] - pub fn new() -> Sprite<'s> { - let sp = unsafe { ffi::sfSprite_new() }; - Sprite { - handle: NonNull::new(sp).expect("Failed to create Sprite"), - texture: PhantomData, - } - } - /// Create a new sprite with a texture #[must_use] pub fn with_texture(texture: &'s Texture) -> Sprite<'s> { - let mut sprite = Sprite::new(); - sprite.set_texture(texture, true); - sprite + Self::with_texture_and_rect( + texture, + Rect { + position: Default::default(), + size: texture.size().as_other(), + }, + ) } /// Create a new sprite with a texture and a source rectangle #[must_use] pub fn with_texture_and_rect(texture: &'s Texture, rect: IntRect) -> Self { - let mut sprite = Sprite::with_texture(texture); - sprite.set_texture_rect(rect); - sprite + let sp = unsafe { ffi::sfSprite_new(texture, rect) }; + Sprite { + handle: NonNull::new(sp).expect("Failed to create Sprite"), + texture: PhantomData, + } } /// Change the source texture of a sprite @@ -163,12 +156,6 @@ impl<'s> Sprite<'s> { } } -impl Default for Sprite<'_> { - fn default() -> Self { - Self::new() - } -} - impl<'s> Clone for Sprite<'s> { /// Return a new Sprite or panic! if there is not enough memory fn clone(&self) -> Sprite<'s> { diff --git a/src/graphics/text.rs b/src/graphics/text.rs index f905f8af..4326d856 100644 --- a/src/graphics/text.rs +++ b/src/graphics/text.rs @@ -37,11 +37,13 @@ impl<'s> Text<'s> { /// * font - The font to display the Text /// * characterSize - The size of the Text pub fn new(string: S, font: &'s Font, character_size: u32) -> Text<'s> { - let mut text = Text::default(); - text.set_string(string); - text.set_font(font); - text.set_character_size(character_size); - text + let text = string.with_as_sfstr(|sfstr| unsafe { + ffi::sfText_new(font, sfstr.as_ptr(), character_size) + }); + Text { + handle: NonNull::new(text).expect("Failed to create Text"), + font: PhantomData, + } } /// Set the string of a text @@ -247,16 +249,6 @@ impl<'s> Text<'s> { } } -impl Default for Text<'_> { - fn default() -> Self { - let text = unsafe { ffi::sfText_new() }; - Self { - handle: NonNull::new(text).expect("Failed to create Text"), - font: PhantomData, - } - } -} - impl<'s> Clone for Text<'s> { /// Return a new Text or panic! if there is not enough memory fn clone(&self) -> Text<'s> { diff --git a/src/graphics/texture.rs b/src/graphics/texture.rs index 004eff49..2d85165c 100644 --- a/src/graphics/texture.rs +++ b/src/graphics/texture.rs @@ -1,8 +1,9 @@ use { + self::ffi::sfTexture_resize, crate::{ IntoSfResult, SfError, SfResult, cpp::FBox, - ffi::graphics::{self as ffi, sfTexture_create}, + ffi::graphics::{self as ffi}, graphics::{Image, IntRect, RenderWindow}, system::{InputStream, Vector2u}, window::Window, @@ -56,20 +57,15 @@ pub Texture; /// Creation and loading impl Texture { - /// Create the texture. - /// - /// If this function fails, the texture is left unchanged. - /// - /// Returns whether creation was successful. - #[must_use = "Check if texture was created successfully"] - pub fn create(&mut self, width: u32, height: u32) -> SfResult<()> { - unsafe { sfTexture_create(self, width, height) }.into_sf_result() - } /// Creates a new `Texture` pub fn new() -> SfResult> { FBox::new(unsafe { ffi::sfTexture_new() }).into_sf_result() } + pub fn resize(&mut self, size: Vector2u, srgb: bool) -> SfResult<()> { + unsafe { sfTexture_resize(self, size, srgb) }.into_sf_result() + } + /// Load texture from memory /// /// The `area` argument can be used to load only a sub-rectangle of the whole image. @@ -80,9 +76,9 @@ impl Texture { /// # Arguments /// * mem - Pointer to the file data in memory /// * area - Area of the image to load - pub fn load_from_memory(&mut self, mem: &[u8], area: IntRect) -> SfResult<()> { + pub fn load_from_memory(&mut self, mem: &[u8], srgb: bool, area: IntRect) -> SfResult<()> { unsafe { - ffi::sfTexture_loadFromMemory(self, mem.as_ptr().cast(), mem.len(), area) + ffi::sfTexture_loadFromMemory(self, mem.as_ptr().cast(), mem.len(), srgb, area) .into_sf_result() } } @@ -100,11 +96,13 @@ impl Texture { pub fn load_from_stream( &mut self, stream: &mut T, + srgb: bool, area: IntRect, ) -> SfResult<()> { let mut input_stream = InputStream::new(stream); unsafe { - ffi::sfTexture_loadFromStream(self, &mut *input_stream.stream, area).into_sf_result() + ffi::sfTexture_loadFromStream(self, &mut *input_stream.stream, srgb, area) + .into_sf_result() } } @@ -112,22 +110,22 @@ impl Texture { /// /// # Arguments /// * filename - Path of the image file to load - pub fn load_from_file(&mut self, filename: &str, area: IntRect) -> SfResult<()> { + pub fn load_from_file(&mut self, filename: &str, srgb: bool, area: IntRect) -> SfResult<()> { let c_str = CString::new(filename)?; - unsafe { ffi::sfTexture_loadFromFile(self, c_str.as_ptr(), area).into_sf_result() } + unsafe { ffi::sfTexture_loadFromFile(self, c_str.as_ptr(), srgb, area).into_sf_result() } } /// Convenience method to easily create and load a `Texture` from a file. pub fn from_file(filename: &str) -> SfResult> { let mut new = Self::new()?; - new.load_from_file(filename, IntRect::default())?; + new.load_from_file(filename, Default::default(), IntRect::default())?; Ok(new) } /// Convenience method to easily create and load a `Texture` from an iamge. - pub fn from_image(image: &Image, area: IntRect) -> SfResult> { + pub fn from_image(image: &Image, srgb: bool, area: IntRect) -> SfResult> { let mut new = Self::new()?; - new.load_from_image(image, area)?; + new.load_from_image(image, srgb, area)?; Ok(new) } @@ -140,8 +138,8 @@ impl Texture { /// If you want the entire image then use a default `IntRect`. /// If the area rectangle crosses the bounds of the image, /// it is adjusted to fit the image size. - pub fn load_from_image(&mut self, image: &Image, area: IntRect) -> SfResult<()> { - unsafe { ffi::sfTexture_loadFromImage(self, image, area).into_sf_result() } + pub fn load_from_image(&mut self, image: &Image, srgb: bool, area: IntRect) -> SfResult<()> { + unsafe { ffi::sfTexture_loadFromImage(self, image, srgb, area).into_sf_result() } } } @@ -213,23 +211,6 @@ impl Texture { pub fn set_repeated(&mut self, repeated: bool) { unsafe { ffi::sfTexture_setRepeated(self, repeated) } } - /// Enable or disable conversion from sRGB. - /// - /// When providing texture data from an image file or memory, it can either be stored in a - /// linear color space or an sRGB color space. Most digital images account for gamma correction - /// already, so they would need to be "uncorrected" back to linear color space before being - /// processed by the hardware. The hardware can automatically convert it from the sRGB - /// color space to a linear color space when it gets sampled. When the rendered image gets - /// output to the final framebuffer, it gets converted back to sRGB. - /// - /// After enabling or disabling sRGB conversion, make sure to reload the texture data in - /// order for the setting to take effect. - /// - /// This option is only useful in conjunction with an sRGB capable framebuffer. - /// This can be requested during window creation. - pub fn set_srgb(&mut self, srgb: bool) { - unsafe { ffi::sfTexture_setSrgb(self, srgb) } - } } /// OpenGL interop @@ -270,8 +251,8 @@ impl Texture { /// # Safety /// No additional check is performed on the size of the window, passing an invalid combination /// of window size and offset will lead to an _undefined behavior_. - pub unsafe fn update_from_window(&mut self, window: &Window, x: u32, y: u32) { - unsafe { ffi::sfTexture_updateFromWindow(self, window, x, y) } + pub unsafe fn update_from_window(&mut self, window: &Window, dest: Vector2u) { + unsafe { ffi::sfTexture_updateFromWindow(self, window, dest) } } /// Update a part of the texture from the contents of a render window. @@ -284,10 +265,9 @@ impl Texture { pub unsafe fn update_from_render_window( &mut self, render_window: &RenderWindow, - x: u32, - y: u32, + dest: Vector2u, ) { - unsafe { ffi::sfTexture_updateFromRenderWindow(self, render_window, x, y) } + unsafe { ffi::sfTexture_updateFromRenderWindow(self, render_window, dest) } } /// Update a part of the texture from an image. @@ -297,8 +277,8 @@ impl Texture { /// # Safety /// No additional check is performed on the size of the image, passing an invalid combination /// of image size and offset will lead to an _undefined behavior_. - pub unsafe fn update_from_image(&mut self, image: &Image, x: u32, y: u32) { - unsafe { ffi::sfTexture_updateFromImage(self, image, x, y) } + pub unsafe fn update_from_image(&mut self, image: &Image, dest: Vector2u) { + unsafe { ffi::sfTexture_updateFromImage(self, image, dest) } } /// Update a part of this texture from another texture. @@ -309,8 +289,8 @@ impl Texture { /// No additional check is performed on the size of the texture, /// passing an invalid combination of texture size and offset will /// lead to an _undefined behavior_. - pub unsafe fn update_from_texture(&mut self, texture: &Texture, x: u32, y: u32) { - unsafe { ffi::sfTexture_updateFromTexture(self, texture, x, y) } + pub unsafe fn update_from_texture(&mut self, texture: &Texture, dest: Vector2u) { + unsafe { ffi::sfTexture_updateFromTexture(self, texture, dest) } } /// Update a part of the texture from an array of pixels. @@ -323,14 +303,14 @@ impl Texture { /// # Panics /// /// Panics the provided parameters would result in out of bounds access. - pub fn update_from_pixels(&mut self, pixels: &[u8], width: u32, height: u32, x: u32, y: u32) { + pub fn update_from_pixels(&mut self, pixels: &[u8], size: Vector2u, dest: Vector2u) { let my_dims = self.size(); assert!( - x + width <= my_dims.x - && y + height <= my_dims.y - && pixels.len() == (width * height * 4) as usize + dest.x + size.x <= my_dims.x + && dest.y + size.y <= my_dims.y + && pixels.len() == (size.x * size.y * 4) as usize ); - unsafe { ffi::sfTexture_updateFromPixels(self, pixels.as_ptr(), width, height, x, y) } + unsafe { ffi::sfTexture_updateFromPixels(self, pixels.as_ptr(), size, dest) } } /// Swap the contents of this texture with those of another. diff --git a/src/graphics/transform.rs b/src/graphics/transform.rs index c077e452..c132d621 100644 --- a/src/graphics/transform.rs +++ b/src/graphics/transform.rs @@ -109,8 +109,8 @@ impl Transform { /// # Arguments /// * x - Offset to apply on X axis /// * y - Offset to apply on Y axis - pub fn translate(&mut self, x: f32, y: f32) { - unsafe { ffi::sfTransform_translate(self, x, y) } + pub fn translate(&mut self, translate: Vector2f) { + unsafe { ffi::sfTransform_translate(self, translate) } } /// Combine the current transform with a rotation @@ -132,8 +132,8 @@ impl Transform { /// * angle - Rotation angle, in degrees /// * `center_x` - X coordinate of the center of rotation /// * `center_y` - Y coordinate of the center of rotation - pub fn rotate_with_center(&mut self, angle: f32, center_x: f32, center_y: f32) { - unsafe { ffi::sfTransform_rotateWithCenter(self, angle, center_x, center_y) } + pub fn rotate_with_center(&mut self, angle: f32, center: Vector2f) { + unsafe { ffi::sfTransform_rotateWithCenter(self, angle, center) } } /// Combine the current transform with a scaling @@ -141,8 +141,8 @@ impl Transform { /// # Arguments /// * `scale_x` - Scaling factor on the X axis /// * `scale_y` - Scaling factor on the Y axis - pub fn scale(&mut self, scale_x: f32, scale_y: f32) { - unsafe { ffi::sfTransform_scale(self, scale_x, scale_y) } + pub fn scale(&mut self, scale: Vector2f) { + unsafe { ffi::sfTransform_scale(self, scale) } } /// Combine the current transform with a scaling @@ -157,8 +157,8 @@ impl Transform { /// * `scale_y` - Scaling factor on Y axis /// * `center_x` - X coordinate of the center of scaling /// * `center_y` - Y coordinate of the center of scaling - pub fn scale_with_center(&mut self, scale_x: f32, scale_y: f32, center_x: f32, center_y: f32) { - unsafe { ffi::sfTransform_scaleWithCenter(self, scale_x, scale_y, center_x, center_y) } + pub fn scale_with_center(&mut self, scale: Vector2f, center: Vector2f) { + unsafe { ffi::sfTransform_scaleWithCenter(self, scale, center) } } /// Apply a transform to a 2D point diff --git a/src/graphics/view.rs b/src/graphics/view.rs index fbcaacb9..8a09c18f 100644 --- a/src/graphics/view.rs +++ b/src/graphics/view.rs @@ -41,10 +41,12 @@ impl View { /// /// # Arguments /// * rectangle - The rectangle defining the zone to display - pub fn from_rect(rectangle: FloatRect) -> SfResult> { - let mut new = Self::new()?; - new.reset(rectangle); - Ok(new) + pub fn from_rect(rectangle: FloatRect) -> FBox { + let mut view: FBox = Default::default(); + view.set_center(rectangle.center()); + view.set_size(rectangle.size); + + view } } @@ -156,16 +158,6 @@ impl View { pub fn set_viewport(&mut self, viewport: FloatRect) { unsafe { ffi::sfView_setViewport(self, viewport) } } - - /// Reset a view to the given rectangle - /// - /// Note that this function resets the rotation angle to 0. - /// - /// # Arguments - /// * rectangle - Rectangle defining the zone to display - pub fn reset(&mut self, rectangle: FloatRect) { - unsafe { ffi::sfView_reset(self, rectangle) } - } } impl ToOwned for View { diff --git a/src/window/context.rs b/src/window/context.rs index 918cd024..6e002ccc 100644 --- a/src/window/context.rs +++ b/src/window/context.rs @@ -71,8 +71,14 @@ impl Context { fn test_settings() { use {crate::window::Window, std::thread}; - let window = - Window::new_open((32, 32), "test", Default::default(), &Default::default()).unwrap(); + let window = Window::new_open( + (32, 32), + "test", + Default::default(), + Default::default(), + &Default::default(), + ) + .unwrap(); let win_settings = *window.settings(); thread::spawn(move || { let context = Context::new().unwrap(); diff --git a/src/window/cursor.rs b/src/window/cursor.rs index 03f4f927..6a308e9d 100644 --- a/src/window/cursor.rs +++ b/src/window/cursor.rs @@ -1,7 +1,7 @@ use crate::{ IntoSfResult, SfResult, cpp::FBox, - ffi::window::{self as ffi, sfCursor_loadFromPixels, sfCursor_loadFromSystem, sfCursor_new}, + ffi::window::{self as ffi}, system::Vector2u, }; @@ -33,44 +33,8 @@ impl Drop for Cursor { /// Creation impl Cursor { - /// # Safety - /// - /// Must be inited with [`Self::load_from_pixels`] or [`Self::load_from_system`] - unsafe fn new() -> SfResult> { - FBox::new(unsafe { sfCursor_new() }).into_sf_result() - } /// Create a new `Cursor` from the provided image data. /// - /// See [`Self::load_from_pixels`]. - /// - /// # Safety - /// - /// Also see [`Self::load_from_pixels`]. - pub unsafe fn from_pixels( - pixels: &[u8], - size: Vector2u, - hotspot: Vector2u, - ) -> SfResult> { - unsafe { - let mut new = Self::new()?; - new.load_from_pixels(pixels, size, hotspot)?; - Ok(new) - } - } - /// Create a new `Cursor` from a native system cursor. - pub fn from_system(type_: Type) -> SfResult> { - unsafe { - let mut new = Self::new()?; - new.load_from_system(type_)?; - Ok(new) - } - } -} - -/// Loading -impl Cursor { - /// Load the cursor with the provided image data. - /// /// `pixels` must be an array of width by height pixels in 32-bit RGBA format. /// If not, this will cause undefined behavior. /// @@ -105,15 +69,15 @@ impl Cursor { /// > I noticed that on at least Linux X11, if the size of the image is not a power of 2, /// > the image is loaded in a wrong way that doesn't respect the dimensions. This is also /// > why I decided to leave this function unsafe. - pub unsafe fn load_from_pixels( - &mut self, + pub unsafe fn from_pixels( pixels: &[u8], size: Vector2u, hotspot: Vector2u, - ) -> SfResult<()> { - unsafe { sfCursor_loadFromPixels(self, pixels.as_ptr(), size, hotspot) }.into_sf_result() + ) -> SfResult> { + FBox::new(unsafe { sfCursor_createFromPixels(pixels.as_ptr(), size, hotspot) }) + .into_sf_result() } - /// Load a native system cursor. + /// Create a new `Cursor` from a native system cursor. /// /// Refer to the list of cursor available on each system (see `CursorType`) to /// know whether a given cursor is expected to load successfully or @@ -123,9 +87,11 @@ impl Cursor { /// - `type_`: Native system cursor type /// /// Returns an error if the cursor type is not supported by the operating system. - pub fn load_from_system(&mut self, type_: Type) -> SfResult<()> { - unsafe { sfCursor_loadFromSystem(self, type_) }.into_sf_result() + pub fn from_system(type_: Type) -> SfResult> { + FBox::new(unsafe { sfCursor_createFromSystem(type_) }).into_sf_result() } } pub use ffi::sfCursorType as Type; + +use self::ffi::{sfCursor_createFromPixels, sfCursor_createFromSystem}; diff --git a/src/window/event.rs b/src/window/event.rs index ff380ee4..751052e0 100644 --- a/src/window/event.rs +++ b/src/window/event.rs @@ -1,4 +1,4 @@ -use crate::ffi::{window as ffi, window::EventType}; +use crate::ffi::window::{self as ffi, EventType}; /// Defines a system event and its parameters. /// @@ -20,15 +20,13 @@ pub enum Event { Closed, /// The window was resized Resized { - /// The new width of the window - width: u32, - /// The new height of the window - height: u32, + /// New size, in pixels + size: ffi::sfVector2u, }, /// The window lost the focus - LostFocus, + FocusLost, /// The window gained the focus - GainedFocus, + FocusGained, /// A character was entered TextEntered { /// The character entered by the user @@ -64,9 +62,6 @@ pub enum Event { /// Is system released too? system: bool, }, - #[doc(hidden)] - /// Do not use. Needed for compatibility with SFML. - MouseWheelMoved, /// The mouse wheel was scrolled MouseWheelScrolled { /// Which wheel (for mice with multiple ones). @@ -74,35 +69,54 @@ pub enum Event { /// Wheel offset (positive is up/left, negative is down/right). /// High-precision mice may use non-integral offsets. delta: f32, - /// X position of the mouse pointer, relative to the left of the owner window. - x: i32, - /// Y position of the mouse pointer, relative to the top of the owner window. - y: i32, + /// Position of the mouse pointer, relative to the top left of the owner window + position: ffi::sfVector2i, }, /// A mouse button was pressed MouseButtonPressed { /// Code of the button that has been pressed. button: ffi::MouseButton, - /// X position of the mouse pointer, relative to the left of the owner window. - x: i32, - /// Y position of the mouse pointer, relative to the top of the owner window. - y: i32, + /// Position of the mouse pointer, relative to the top left of the owner window + position: ffi::sfVector2i, }, /// A mouse button was released MouseButtonReleased { /// Code of the button that has been pressed. button: ffi::MouseButton, - /// X position of the mouse pointer, relative to the left of the owner window. - x: i32, - /// Y position of the mouse pointer, relative to the top of the owner window. - y: i32, + /// Position of the mouse pointer, relative to the top left of the owner window + position: ffi::sfVector2i, }, /// The mouse cursor moved MouseMoved { - /// X position of the mouse pointer, relative to the left of the owner window. - x: i32, - /// Y position of the mouse pointer, relative to the top of the owner window. - y: i32, + /// Position of the mouse pointer, relative to the top left of the owner window + position: ffi::sfVector2i, + }, + /// Raw mouse input data comes unprocessed from the + /// operating system hence "raw". While the MouseMoved + /// position value is dependent on the screen resolution, + /// raw data is not. If the physical mouse is moved too + /// little to cause the screen cursor to move at least a + /// single pixel, no MouseMoved event will be generated. In + /// contrast, any movement information generated by the + /// mouse independent of its sensor resolution will always + /// generate a `MouseMovedRaw` event. + /// + /// In addition to screen resolution independence, raw + /// mouse data also does not have mouse acceleration or + /// smoothing applied to it as MouseMoved does. + /// + /// Raw mouse movement data is intended for controlling + /// non-cursor movement, e.g. controlling the camera + /// orientation in a first person view, whereas MouseMoved + /// is intended primarily for controlling things related to + /// the screen cursor hence the additional processing + /// applied to it. + /// + /// Currently, raw mouse input events will only be generated + /// on Windows and Linux. + MouseMovedRaw { + /// Delta movement of the mouse since the last event + delta: ffi::sfVector2i, }, /// The mouse cursor entered the area of the window MouseEntered, @@ -159,58 +173,42 @@ pub enum Event { TouchBegan { /// Index of the finger in case of multi-touch events. finger: u32, - /// X position of the touch, relative to the left of the owner window. - x: i32, - /// Y position of the touch, relative to the top of the owner window. - y: i32, + /// Start position of the touch, relative to the top left of the owner window + position: ffi::sfVector2i, }, /// A touch moved TouchMoved { /// Index of the finger in case of multi-touch events. finger: u32, - /// X position of the touch, relative to the left of the owner window. - x: i32, - /// Y position of the touch, relative to the top of the owner window. - y: i32, + /// Start position of the touch, relative to the top left of the owner window + position: ffi::sfVector2i, }, /// A touch event ended TouchEnded { /// Index of the finger in case of multi-touch events. finger: u32, - /// X position of the touch, relative to the left of the owner window. - x: i32, - /// Y position of the touch, relative to the top of the owner window. - y: i32, + /// Start position of the touch, relative to the top left of the owner window + position: ffi::sfVector2i, }, /// A sensor value changed SensorChanged { /// Type of the sensor. type_: ffi::window::sfSensorType, - /// Current value of the sensor on X axis. - x: f32, - /// Current value of the sensor on Y axis. - y: f32, - /// Current value of the sensor on Z axis. - z: f32, + /// Current value of the sensor on the X, Y, and Z axes + value: ffi::sfVector3f, }, } impl Event { pub(crate) unsafe fn from_raw(event: &ffi::Event) -> Option { use crate::window::Event::*; - let evt = match event.type_ { EventType::Closed => Closed, - EventType::Resized => { - let e = unsafe { event.union.size }; - - Resized { - width: e.width, - height: e.height, - } - } - EventType::LostFocus => LostFocus, - EventType::GainedFocus => GainedFocus, + EventType::Resized => Resized { + size: unsafe { event.union.size.size }, + }, + EventType::FocusLost => FocusLost, + EventType::FocusGained => FocusGained, EventType::TextEntered => TextEntered { unicode: std::char::from_u32(unsafe { event.union.text.unicode }) .expect("Invalid unicode encountered on TextEntered event"), @@ -234,22 +232,21 @@ impl Event { EventType::MouseWheelScrolled => MouseWheelScrolled { wheel: unsafe { event.union.mouse_wheel_scroll.wheel }, delta: unsafe { event.union.mouse_wheel_scroll.delta }, - x: unsafe { event.union.mouse_wheel_scroll.x }, - y: unsafe { event.union.mouse_wheel_scroll.y }, + position: unsafe { event.union.mouse_wheel_scroll.position }, }, EventType::MouseButtonPressed => MouseButtonPressed { button: unsafe { event.union.mouse_button.button }, - x: unsafe { event.union.mouse_button.x }, - y: unsafe { event.union.mouse_button.y }, + position: unsafe { event.union.mouse_button.position }, }, EventType::MouseButtonReleased => MouseButtonReleased { button: unsafe { event.union.mouse_button.button }, - x: unsafe { event.union.mouse_button.x }, - y: unsafe { event.union.mouse_button.y }, + position: unsafe { event.union.mouse_button.position }, }, EventType::MouseMoved => MouseMoved { - x: unsafe { event.union.mouse_move.x }, - y: unsafe { event.union.mouse_move.y }, + position: unsafe { event.union.mouse_button.position }, + }, + EventType::MouseMovedRaw => MouseMovedRaw { + delta: unsafe { event.union.mouse_move_raw.delta }, }, EventType::MouseEntered => MouseEntered, EventType::MouseLeft => MouseLeft, @@ -274,26 +271,20 @@ impl Event { }, EventType::TouchBegan => TouchBegan { finger: unsafe { event.union.touch.finger }, - x: unsafe { event.union.touch.x }, - y: unsafe { event.union.touch.y }, + position: unsafe { event.union.mouse_button.position }, }, EventType::TouchMoved => TouchMoved { finger: unsafe { event.union.touch.finger }, - x: unsafe { event.union.touch.x }, - y: unsafe { event.union.touch.y }, + position: unsafe { event.union.mouse_button.position }, }, EventType::TouchEnded => TouchEnded { finger: unsafe { event.union.touch.finger }, - x: unsafe { event.union.touch.x }, - y: unsafe { event.union.touch.y }, + position: unsafe { event.union.mouse_button.position }, }, EventType::SensorChanged => SensorChanged { type_: unsafe { event.union.sensor.type_ }, - x: unsafe { event.union.sensor.x }, - y: unsafe { event.union.sensor.y }, - z: unsafe { event.union.sensor.z }, + value: unsafe { event.union.sensor.value }, }, - EventType::MouseWheelMoved => Event::MouseWheelMoved, }; Some(evt) } diff --git a/src/window/mod.rs b/src/window/mod.rs index e58c103c..c3ae5df3 100644 --- a/src/window/mod.rs +++ b/src/window/mod.rs @@ -7,9 +7,9 @@ pub use { cursor::{Cursor, Type as CursorType}, event::Event, keyboard::{Key, set_virtual_keyboard_visible}, - style::Style, video_mode::VideoMode, window::{Handle, Window}, + window_enums::Style, }, crate::ffi::window::Scancode, }; @@ -23,9 +23,9 @@ pub mod joystick; mod keyboard; pub mod mouse; pub mod sensor; -mod style; pub(crate) mod thread_safety; pub mod touch; mod video_mode; #[expect(clippy::module_inception)] mod window; +pub mod window_enums; diff --git a/src/window/sensor.rs b/src/window/sensor.rs index 9041fa1f..ae7aec8f 100644 --- a/src/window/sensor.rs +++ b/src/window/sensor.rs @@ -90,6 +90,4 @@ impl Type { pub const USER_ACCELERATION: Self = Self(sfSensorType::UserAcceleration); /// Measures the absolute 3D orientation (degrees) pub const ORIENTATION: Self = Self(sfSensorType::Orientation); - /// The total number of sensor types. - pub const COUNT: sfSensorType = sfSensorType::Count; } diff --git a/src/window/video_mode.rs b/src/window/video_mode.rs index c9da72c9..7ccc8947 100644 --- a/src/window/video_mode.rs +++ b/src/window/video_mode.rs @@ -1,6 +1,7 @@ use crate::{ cpp::{CppVector, CppVectorItem}, ffi::window as ffi, + system::{Vector2, Vector2u}, window::thread_safety, }; @@ -24,12 +25,10 @@ use crate::{ /// the desktop: [`VideoMode::desktop_mode`]. This allows to build windows with the same size or /// pixel depth as the current resolution. #[repr(C)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct VideoMode { - /// Video mode width, in pixels - pub width: std::ffi::c_uint, - /// Video mode height, in pixels - pub height: std::ffi::c_uint, + /// Video mode size, in pixels + pub size: Vector2, /// Video mode pixel depth, in bits per pixels pub bits_per_pixel: std::ffi::c_uint, } @@ -37,10 +36,9 @@ pub struct VideoMode { impl VideoMode { /// Constructs a new `VideoMode` from the given parameters. #[must_use] - pub const fn new(width: u32, height: u32, bits_per_pixel: u32) -> Self { + pub const fn new(size: Vector2u, bits_per_pixel: u32) -> Self { Self { - width, - height, + size, bits_per_pixel, } } @@ -84,23 +82,30 @@ impl VideoMode { } } -impl From<(u32, u32)> for VideoMode { - /// Constructs a `VideoMode` from `(w, h)`. Bit depth is 32. - fn from((w, h): (u32, u32)) -> Self { - Self::new(w, h, 32) +impl From for VideoMode { + /// Constructs a `VideoMode` from `Vector2`. Bit depth is 32. + fn from(size: Vector2u) -> Self { + Self::new(size, 32) } } impl From<[u32; 2]> for VideoMode { /// Constructs a `VideoMode` from `[w, h]`. Bit depth is 32. fn from([w, h]: [u32; 2]) -> Self { - Self::new(w, h, 32) + Self::new(Vector2::new(w, h), 32) + } +} + +impl From<(u32, u32)> for VideoMode { + /// Constructs a `VideoMode` from `(w, h)`. Bit depth is 32. + fn from(size: (u32, u32)) -> Self { + Self::new(size.into(), 32) } } impl Default for VideoMode { fn default() -> Self { - Self::new(0, 0, 0) + Self::new(Vector2::new(0, 0), 0) } } diff --git a/src/window/window.rs b/src/window/window.rs index 44a6a291..3f04f9cc 100644 --- a/src/window/window.rs +++ b/src/window/window.rs @@ -2,10 +2,12 @@ use crate::{ IntoSfResult, SfResult, cpp::FBox, ffi::window as ffi, - system::{SfStrConv, Vector2i, Vector2u}, + system::{SfStrConv, Time, Vector2i, Vector2u}, window::{ContextSettings, Cursor, Event, Style, VideoMode, thread_safety}, }; +use super::window_enums::State; + /// The system native window handle type. Can be used to create an SFML Window /// from an existing system window. pub type Handle = ffi::sfWindowHandle; @@ -40,10 +42,11 @@ impl Window { mode: V, title: S, style: Style, + state: State, settings: &ContextSettings, ) -> SfResult> { let mut new = Self::new()?; - new.open(mode, title, style, settings); + new.open(mode, title, style, state, settings); Ok(new) } /// Open the window with the specified parameters @@ -69,11 +72,19 @@ impl Window { mode: V, title: S, style: Style, + state: State, settings: &ContextSettings, ) { thread_safety::set_window_thread(); title.with_as_sfstr(|sfstr| unsafe { - ffi::sfWindow_create_mtss(self, mode.into(), sfstr.as_ptr(), style.bits(), settings) + ffi::sfWindow_create_mtsss( + self, + mode.into(), + sfstr.as_ptr(), + style.bits(), + state, + settings, + ) }) } @@ -106,7 +117,7 @@ impl Window { /// doesn't support, or implement a temporary workaround until a bug is fixed. #[must_use] pub fn system_handle(&self) -> Handle { - unsafe { ffi::sfWindow_getSystemHandle(self) } + unsafe { ffi::sfWindow_getNativeHandle(self) } } /// Pop the event on top of event queue, if any, and return it @@ -138,9 +149,10 @@ impl Window { /// sleep as long as no new event is received. /// /// Returns `Some(event)` or `None` if an error has occured - pub fn wait_event(&mut self) -> Option { + pub fn wait_event(&mut self, timeout: Time) -> Option { let mut event = std::mem::MaybeUninit::uninit(); - let have_event = unsafe { ffi::sfWindow_waitEvent(self, event.as_mut_ptr()) }; + let have_event = + unsafe { ffi::sfWindow_waitEvent(self, event.as_mut_ptr(), timeout.as_microseconds()) }; if have_event { unsafe { Event::from_raw(&event.assume_init()) } } else { @@ -161,8 +173,8 @@ impl Window { /// `pixels` not being at least `width * height * 4` will likely cause undefined behavior. /// /// Platform-specific behavior is also unclear (limits on max size, etc). - pub unsafe fn set_icon(&mut self, width: u32, height: u32, pixels: &[u8]) { - unsafe { ffi::sfWindow_setIcon(self, width, height, pixels.as_ptr()) } + pub unsafe fn set_icon(&mut self, size: Vector2u, pixels: &[u8]) { + unsafe { ffi::sfWindow_setIcon(self, size, pixels.as_ptr()) } } /// Close a window and destroy all the attached resources @@ -206,7 +218,11 @@ impl Window { /// # Arguments /// * title - New title pub fn set_title(&mut self, title: S) { - title.with_as_sfstr(|sfstr| unsafe { ffi::sfWindow_setUnicodeTitle(self, sfstr.as_ptr()) }) + unsafe { + title.with_as_sfstr(|sfstr| { + ffi::sfWindow_setUnicodeTitle(self, sfstr.as_ptr()); + }) + } } /// Show or hide a window diff --git a/src/window/style.rs b/src/window/window_enums.rs similarity index 79% rename from src/window/style.rs rename to src/window/window_enums.rs index 6b08414a..de535dd8 100644 --- a/src/window/style.rs +++ b/src/window/window_enums.rs @@ -26,3 +26,14 @@ impl Default for Style { Self::DEFAULT } } + +#[repr(C)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +/// Available window state of your window +pub enum State { + #[default] + /// Windowed mode + Windowed, + /// Fullscreen mode + Fullscreen, +}