123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #include "simple/support/function_utils.hpp"
- #include "simple/support/enum.hpp"
- #include "simple/sdlcore/utils.hpp"
- #include "surface.h"
- using simple::support::to_integer;
- namespace simple::graphical
- {
- surface::surface(const char* filename)
- : sdl_surface_wrapper(SDL_LoadBMP(filename), SDL_FreeSurface),
- _format(this->guts()->format)
- {}
- surface::surface(const surface& other)
- : sdl_surface_wrapper
- (
- #if SDL_VERSION_ATLEAST(2,0,6)
- SDL_DuplicateSurface(other.guts().get()),
- #else
- SDL_ConvertSurface(other.guts().get(), other.guts()->format, other.guts()->flags),
- #endif
- SDL_FreeSurface
- ),
- _format(this->guts()->format)
- {}
- surface::surface(int2 size, const pixel_format& format)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurface
- (
- 0,
- size.x(), size.y(),
- format.bits(),
- format.red_mask(), format.green_mask(), format.blue_mask(), format.alpha_mask()
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format)
- {
- if(format.palette())
- SDL_SetSurfacePalette(guts().get(), format.guts().get()->palette);
- }
- surface::surface(byte* pixels, int2 size, const pixel_format& format, int pitch)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceFrom
- (
- pixels,
- size.x(), size.y(),
- format.bits(),
- pitch ? pitch : format.bytes() * size.x(),
- format.red_mask(), format.green_mask(), format.blue_mask(), format.alpha_mask()
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format)
- {
- if(format.palette())
- SDL_SetSurfacePalette(guts().get(), format.guts().get()->palette);
- }
- surface::surface(std::unique_ptr<byte[]> pixels, int2 size, const pixel_format& format, int pitch)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceFrom
- (
- pixels.get(),
- size.x(), size.y(),
- format.bits(),
- pitch ? pitch : format.bytes() * size.x(),
- format.red_mask(), format.green_mask(), format.blue_mask(), format.alpha_mask()
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format),
- pixels_owner(pixels.release(), [](byte* x){ delete [] x; }) // hmmm... weird... but true
- {
- if(format.palette())
- SDL_SetSurfacePalette(guts().get(), format.guts().get()->palette);
- }
- surface::surface(std::unique_ptr<byte[], void(*)(byte*)> pixels, int2 size, const pixel_format& format, int pitch)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceFrom
- (
- pixels.get(),
- size.x(), size.y(),
- format.bits(),
- pitch ? pitch : format.bytes() * size.x(),
- format.red_mask(), format.green_mask(), format.blue_mask(), format.alpha_mask()
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format),
- pixels_owner(std::move(pixels))
- {
- if(format.palette())
- SDL_SetSurfacePalette(guts().get(), format.guts().get()->palette);
- }
- #if SDL_VERSION_ATLEAST(2,0,5)
- surface::surface(int2 size, pixel_format::type format)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceWithFormat
- (
- 0,
- size.x(), size.y(),
- 0,
- to_integer(format)
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format)
- {}
- surface::surface(byte* pixels, int2 size, pixel_format::type format, int pitch)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceWithFormatFrom
- (
- pixels,
- size.x(), size.y(),
- 0,
- pitch ? pitch : SDL_BYTESPERPIXEL(to_integer(format)) * size.x(),
- to_integer(format)
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format)
- {}
- surface::surface(std::unique_ptr<byte[]> pixels, int2 size, pixel_format::type format, int pitch)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceWithFormatFrom
- (
- pixels.get(),
- size.x(), size.y(),
- 0,
- pitch ? pitch : SDL_BYTESPERPIXEL(to_integer(format)) * size.x(),
- to_integer(format)
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format),
- pixels_owner(pixels.release(), [](byte* x){ delete [] x; })
- {}
- surface::surface(std::unique_ptr<byte[], void(*)(byte*)> pixels, int2 size, pixel_format::type format, int pitch)
- : sdl_surface_wrapper
- (
- SDL_CreateRGBSurfaceWithFormatFrom
- (
- pixels.get(),
- size.x(), size.y(),
- 0,
- pitch ? pitch : SDL_BYTESPERPIXEL(to_integer(format)) * size.x(),
- to_integer(format)
- ),
- SDL_FreeSurface
- ),
- _format(this->guts()->format),
- pixels_owner(std::move(pixels))
- {}
- #endif
- surface::surface(SDL_Surface* guts, Deleter deleter)
- : sdl_surface_wrapper(guts, deleter),
- _format(this->guts()->format)
- {}
- surface::free_pixel_format::free_pixel_format(SDL_PixelFormat* guts)
- : pixel_format(guts, support::nop)
- {}
- const pixel_format& surface::format() const
- {
- return _format;
- }
- int2 surface::size() const
- {
- return {guts()->w, guts()->h};
- }
- blend_mode surface::blend() const noexcept
- {
- SDL_BlendMode result;
- SDL_GetSurfaceBlendMode(guts().get(), &result);
- return static_cast<blend_mode>(result);
- }
- void surface::blend(blend_mode new_value) const noexcept
- {
- SDL_SetSurfaceBlendMode
- (
- guts().get(),
- static_cast<SDL_BlendMode>(support::to_integer(new_value))
- );
- }
- uint8_t surface::alpha() const noexcept
- {
- uint8_t result;
- SDL_GetSurfaceAlphaMod(guts().get(), &result);
- return result;
- }
- void surface::alpha(uint8_t new_value) const noexcept
- {
- SDL_SetSurfaceAlphaMod(guts().get(), new_value);
- }
- rgb_pixel surface::color() const noexcept
- {
- rgb_pixel result;
- SDL_GetSurfaceColorMod(guts().get(), &result.r(), &result.g(), &result.b());
- return result;
- }
- void surface::color(rgb_pixel new_value) const noexcept
- {
- SDL_SetSurfaceColorMod(guts().get(), new_value.r(), new_value.g(), new_value.b());
- }
- pixel_writer_variant pixel_writer_from_format(pixel_byte* data, int2 size, int pitch, int bpp)
- {
- int2 raw_size = size;
- raw_size.x() *= bpp;
- switch(bpp)
- {
- case 2:
- return pixel_writer<uint16_t, pixel_byte>(
- data, raw_size, pitch);
- case 3:
- return pixel_writer<rgb_pixel, pixel_byte>(
- data, raw_size, pitch);
- case 4:
- return pixel_writer<rgba_pixel, pixel_byte>(
- data, raw_size, pitch);
- default:
- return pixel_writer<pixel_byte>(
- data, raw_size, pitch);
- }
- }
- pixel_writer_variant surface::pixels() const noexcept
- {
- return pixel_writer_from_format(
- reinterpret_cast<byte*>(guts()->pixels),
- size(), guts()->pitch, format().bytes());
- }
- void surface::save(const char* filename) const
- {
- sdlcore::utils::throw_error(SDL_SaveBMP(guts().get(), filename));
- }
- } // namespace simple::graphical
|