From 6db6d0c1bc3ff54c157d44ffc4f007d7ce65db0a Mon Sep 17 00:00:00 2001 From: Dmitry Marakasov Date: Sat, 27 Dec 2014 21:21:51 +0300 Subject: [PATCH] Implement most Surface functions --- SDL2pp/Surface.cc | 110 ++++++++++++++++++++++ SDL2pp/Surface.hh | 230 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 340 insertions(+) diff --git a/SDL2pp/Surface.cc b/SDL2pp/Surface.cc index 5aa6725..4f676d4 100644 --- a/SDL2pp/Surface.cc +++ b/SDL2pp/Surface.cc @@ -19,6 +19,8 @@ 3. This notice may not be removed or altered from any source distribution. */ +#include + #include #include @@ -26,6 +28,9 @@ namespace SDL2pp { +Surface::Surface(SDL_Surface* surface) : surface_(surface) { +} + Surface::Surface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { if ((surface_ = SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask)) == nullptr) throw Exception("SDL_CreateRGBSurface failed"); @@ -59,8 +64,113 @@ SDL_Surface* Surface::Get() const { return surface_; } +Surface Surface::Convert(const SDL_PixelFormat& format) { + SDL_Surface* surface = SDL_ConvertSurface(surface_, &format, 0); + if (surface == nullptr) + throw Exception("SDL_ConvertPixels failed"); + return surface; +} + +Surface Surface::Convert(Uint32 pixel_format) { + SDL_Surface* surface = SDL_ConvertSurfaceFormat(surface_, pixel_format, 0); + if (surface == nullptr) + throw Exception("SDL_ConvertPixels failed"); + return surface; +} + +void Surface::Blit(const Optional& srcrect, Surface& dst, const Rect& dstrect) { + SDL_Rect tmpdstrect = dstrect; // 4th argument is non-const; does it modify rect? + if (SDL_BlitSurface(surface_, srcrect ? &*srcrect : nullptr, dst.Get(), &tmpdstrect) != 0) + throw Exception("SDL_BlitSurface failed"); +} + +void Surface::BlitScaled(const Optional& srcrect, Surface& dst, const Optional& dstrect) { + SDL_Rect tmpdstrect; // 4th argument is non-const; does it modify rect? + if (dstrect) + tmpdstrect = *dstrect; + if (SDL_BlitScaled(surface_, srcrect ? &*srcrect : nullptr, dst.Get(), dstrect ? &tmpdstrect : nullptr) != 0) + throw Exception("SDL_BlitScaled failed"); +} + Surface::LockHandle Surface::Lock() { return LockHandle(this); } +Rect Surface::GetClipRect() const { + SDL_Rect rect; + SDL_GetClipRect(surface_, &rect); + return Rect(rect); +} + +Uint32 Surface::GetColorKey() const { + Uint32 key; + if (SDL_GetColorKey(surface_, &key) != 0) + throw Exception("SDL_GetColorKey failed"); + return key; +} + +Uint8 Surface::GetAlphaMod() const { + Uint8 alpha; + if (SDL_GetSurfaceAlphaMod(surface_, &alpha) != 0) + throw Exception("SDL_GetSurfaceAlphaMod failed"); + return alpha; +} + +SDL_BlendMode Surface::GetBlendMode() const { + SDL_BlendMode blendMode; + if (SDL_GetSurfaceBlendMode(surface_, &blendMode) != 0) + throw Exception("SDL_GetSurfaceBlendMode failed"); + return blendMode; +} + +void Surface::GetColorMod(Uint8& r, Uint8& g, Uint8& b) const { + if (SDL_GetSurfaceColorMod(surface_, &r, &g, &b) != 0) + throw Exception("SDL_GetSurfaceColorMod failed"); +} + +void Surface::SetClipRect(const Optional& rect) { + if (SDL_SetClipRect(surface_, rect ? &*rect : nullptr) != 0) + throw Exception("SDL_SetClipRect failed"); +} + +void Surface::SetColorKey(int flag, Uint32 key) { + if (SDL_SetColorKey(surface_, flag, key) != 0) + throw Exception("SDL_SetColorKey failed"); +} + +void Surface::SetAlphaMod(Uint8 alpha) { + if (SDL_SetSurfaceAlphaMod(surface_, alpha) != 0) + throw Exception("SDL_SetSurfaceAlphaMod failed"); +} + +void Surface::SetBlendMode(SDL_BlendMode blendMode) { + if (SDL_SetSurfaceBlendMode(surface_, blendMode) != 0) + throw Exception("SDL_SetSurfaceBlendMode failed"); +} + +void Surface::SetColorMod(Uint8 r, Uint8 g, Uint8 b) { + if (SDL_SetSurfaceColorMod(surface_, r, g, b) != 0) + throw Exception("SDL_SetSurfaceColorMod failed"); +} + +void Surface::SetRLE(int flag) { + if (SDL_SetSurfaceRLE(surface_, flag) != 0) + throw Exception("SDL_SetSurfaceRLE failed"); +} + +void Surface::FillRect(const Optional& rect, Uint32 color) { + if (SDL_FillRect(surface_, rect ? &*rect : nullptr, color) != 0) + throw Exception("SDL_FillRect failed"); +} + +void Surface::FillRects(const Rect* rects, int count, Uint32 color) { + std::vector sdl_rects; + sdl_rects.reserve(count); + for (const Rect* r = rects; r != rects + count; ++r) + sdl_rects.emplace_back(*r); + + if (SDL_FillRects(surface_, sdl_rects.data(), sdl_rects.size(), color) != 0) + throw Exception("SDL_FillRects failed"); +} + } diff --git a/SDL2pp/Surface.hh b/SDL2pp/Surface.hh index 67f3508..b547aa0 100644 --- a/SDL2pp/Surface.hh +++ b/SDL2pp/Surface.hh @@ -23,6 +23,10 @@ #define SDL2PP_SURFACE_HH #include +#include + +#include +#include struct SDL_Surface; struct SDL_PixelFormat; @@ -140,6 +144,16 @@ public: //////////////////////////////////////////////////////////// const SDL_PixelFormat& GetFormat() const; }; + +private: + //////////////////////////////////////////////////////////// + /// \brief Create surface taking existing SDL_surface structure + /// + /// \param surface Existing SDL_surface to manage + /// + //////////////////////////////////////////////////////////// + Surface(SDL_Surface* surface); + public: //////////////////////////////////////////////////////////// /// \brief Create RGB surface @@ -218,6 +232,60 @@ public: //////////////////////////////////////////////////////////// SDL_Surface* Get() const; + //////////////////////////////////////////////////////////// + /// \brief Copy an existing surface into a new one that is + /// optimized for blitting to a surface of a specified pixel format + /// + /// \param format SDL_PixelFormat structure that the new surface is optimized for + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_ConvertSurface + /// + //////////////////////////////////////////////////////////// + Surface Convert(const SDL_PixelFormat& format); + + //////////////////////////////////////////////////////////// + /// \brief Copy an existing surface to a new surface of the specified format + /// + /// \param pixel_format One of the enumerated values in SDL_PixelFormatEnum + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_PixelFormatEnum + /// \see http://wiki.libsdl.org/SDL_ConvertSurfaceFormat + /// + //////////////////////////////////////////////////////////// + Surface Convert(Uint32 pixel_format); + + //////////////////////////////////////////////////////////// + /// \brief Fast surface copy to a destination surface + /// + /// \param srcrect Rectangle to be copied, or NullOpt to copy the entire surface + /// \param dst Blit target surface + /// \param srcrect Rectangle that is copied into + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_BlitSurface + /// + //////////////////////////////////////////////////////////// + void Blit(const Optional& srcrect, Surface& dst, const Rect& dstrect); + + //////////////////////////////////////////////////////////// + /// \brief Scaled surface copy to a destination surface + /// + /// \param srcrect Rectangle to be copied, or NullOpt to copy the entire surface + /// \param dst Blit target surface + /// \param srcrect Rectangle that is copied into, or NullOpt to copy into entire surface + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_BlitScaled + /// + //////////////////////////////////////////////////////////// + void BlitScaled(const Optional& srcrect, Surface& dst, const Optional& dstrect); + //////////////////////////////////////////////////////////// /// \brief Lock surface for direct pixel access /// @@ -229,6 +297,168 @@ public: /// //////////////////////////////////////////////////////////// LockHandle Lock(); + + //////////////////////////////////////////////////////////// + /// \brief Get the clipping rectangle for a surface + /// + /// \return Rect filled in with the clipping rectangle for the surface + /// + /// \see http://wiki.libsdl.org/SDL_GetClipRect + /// + //////////////////////////////////////////////////////////// + Rect GetClipRect() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the color key (transparent pixel) for a surface + /// + /// \return Transparent pixel value + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetColorKey + /// + //////////////////////////////////////////////////////////// + Uint32 GetColorKey() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the additional alpha value used in blit operations + /// + /// \return Current alpha value + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetSurfaceAlphaMod + /// + //////////////////////////////////////////////////////////// + Uint8 GetAlphaMod() const; + + //////////////////////////////////////////////////////////// + /// \brief Get blend mode used for blit operations + /// + /// \return Current SDL_BlendMode + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetSurfaceBlendMode + /// + //////////////////////////////////////////////////////////// + SDL_BlendMode GetBlendMode() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the additional color value multiplied into blit operations + /// + /// \param r Variable to be filled in with the current red color value + /// \param g Variable to be filled in with the current green color value + /// \param b Variable to be filled in with the current blue color value + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_GetSurfaceColorMod + /// + //////////////////////////////////////////////////////////// + void GetColorMod(Uint8& r, Uint8& g, Uint8& b) const; + + //////////////////////////////////////////////////////////// + /// \brief Set the clipping rectangle for a surface + /// + /// \param rect SDL22::Rect representing the clipping rectangle, or NullOpt to disable clipping + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetClipRect + /// + //////////////////////////////////////////////////////////// + void SetClipRect(const Optional& rect = NullOpt); + + //////////////////////////////////////////////////////////// + /// \brief Set the color key (transparent pixel) in a surface + /// + /// \param flag True to enabled color key, false to disable + /// \param key Transparent pixel value + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetColorKey + /// + //////////////////////////////////////////////////////////// + void SetColorKey(int flag, Uint32 key); + + //////////////////////////////////////////////////////////// + /// \brief Set an additional alpha value used in blit operations + /// + /// \param alpha Alpha value multiplied into blit operations + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetSurfaceAlphaMod + /// + //////////////////////////////////////////////////////////// + void SetAlphaMod(Uint8 alpha = 255); + + //////////////////////////////////////////////////////////// + /// \brief Set the blend mode used for blit operations + /// + /// \param blendMode SDL_BlendMode to use for blit blending + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetSurfaceBlendMode + /// + //////////////////////////////////////////////////////////// + void SetBlendMode(SDL_BlendMode blendMode); + + //////////////////////////////////////////////////////////// + /// \brief Set an additional color value multiplied into blit operations + /// + /// \param r Red color value multiplied into blit operations + /// \param g Green color value multiplied into blit operations + /// \param b Blue color value multiplied into blit operations + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetSurfaceColorMod + /// + //////////////////////////////////////////////////////////// + void SetColorMod(Uint8 r = 255, Uint8 g = 255, Uint8 b = 255); + + //////////////////////////////////////////////////////////// + /// \brief Set the RLE acceleration hint for a surface + /// + /// \param flag 0 to disable, non-zero to enable RLE acceleration + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_SetSurfaceRLE + /// + //////////////////////////////////////////////////////////// + void SetRLE(int flag); + + //////////////////////////////////////////////////////////// + /// \brief Perform a fast fill of a rectangle with a specific color + /// + /// \param rect Rectangle to fill, or NullOpt to fill the entire surface + /// \param color Color to fill with + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_FillRect + /// + //////////////////////////////////////////////////////////// + void FillRect(const Optional& rect, Uint32 color); + + //////////////////////////////////////////////////////////// + /// \brief Perform a fast fill of a set of rectangles with a specific color + /// + /// \param rects Array rectangles to be filled + /// \param count Number of rectangles in the array + /// \param color Color to fill with + /// + /// \throws SDL2pp::Exception + /// + /// \see http://wiki.libsdl.org/SDL_FillRects + /// + //////////////////////////////////////////////////////////// + void FillRects(const Rect* rects, int count, Uint32 color); }; }