1 #include "ge211_sprites.hxx"
2 #include "ge211_error.hxx"
12 using namespace detail;
15 Sprite_set::Sprite_set() {}
21 sprites_.emplace_back(sprite, xy, z, t);
28 int z,
const Transform& transform) NOEXCEPT
32 void Placed_sprite::render(Renderer& dst)
const
34 sprite->render(dst, xy, transform);
37 bool operator<(
const Placed_sprite& s1,
const Placed_sprite& s2) NOEXCEPT
42 Dims<int> Texture_sprite::dimensions()
const
44 return get_texture_().dimensions();
47 void Texture_sprite::render(Renderer& renderer,
49 const Transform& transform)
const
52 renderer.copy(get_texture_(), position);
54 renderer.copy(get_texture_(), position, transform);
57 void Texture_sprite::prepare(
const Renderer& renderer)
const
59 renderer.prepare(get_texture_());
72 return raw_surface_(
"Render_sprite::raw_surface");
77 auto* surface = raw_surface_(
"Render_sprite::fill_surface");
78 SDL_FillRect(surface,
nullptr, color.to_sdl_(surface->format));
83 fill_rectangle_(rect, color,
"Render_sprite::fill_rectangle");
88 fill_rectangle_({xy.
x, xy.
y, 1, 1}, color,
"Render_sprite::set_pixel");
91 const Texture& Render_sprite::get_texture_()
const
96 void Render_sprite::fill_rectangle_(
Rect<int> rect,
Color color,
char const* who)
98 auto* surface = raw_surface_(who);
99 SDL_Rect rect_buf = rect;
100 SDL_FillRect(surface, &rect_buf, color.to_sdl_(surface->format));
103 Borrowed<SDL_Surface> Render_sprite::raw_surface_(
char const* who)
105 SDL_Surface* result = texture_.raw_surface();
106 if (result)
return result;
108 throw Late_paint_error{who};
111 Uniq_SDL_Surface Render_sprite::create_surface_(Dims<int> dimensions)
113 SDL_Surface* surface =
114 SDL_CreateRGBSurfaceWithFormat(0,
118 SDL_PIXELFORMAT_RGBA32);
120 throw Host_error{
"Could not create sprite surface"};
122 return Uniq_SDL_Surface(surface);
129 static Dims<int> check_rectangle_dimensions(Dims<int> dims)
131 if (dims.width <= 0 || dims.height <= 0) {
132 throw Client_logic_error(
133 "Rectangle_sprite: width and height must both be positive");
150 static Dims<int> compute_circle_dimensions(
int radius)
156 return {radius * 2, radius * 2};
162 const int cx = radius;
163 const int cy = radius;
165 for (
int y = 0; y < radius; ++y) {
166 for (
int x = 0; x < radius; ++x) {
167 if (x * x + y * y < radius * radius) {
168 set_pixel({cx + x, cy + y}, color);
169 set_pixel({cx + x, cy - y - 1}, color);
170 set_pixel({cx - x - 1, cy + y}, color);
171 set_pixel({cx - x - 1, cy - y - 1}, color);
182 int Circle_sprite::radius_()
const
188 Image_sprite::load_texture_(
const std::string& filename)
190 File_resource file(filename);
191 SDL_Surface* raw = IMG_Load_RW(file.get_raw(), 0);
192 if (raw)
return Texture(raw);
194 throw Image_error::could_not_load(filename);
198 : texture_{load_texture_(filename)} {}
200 const Texture& Image_sprite::get_texture_()
const
206 Text_sprite::create_texture(
const Builder& config)
215 if (config.word_wrap() > 0) {
216 raw = TTF_RenderUTF8_Blended_Wrapped(
217 config.font().get_raw_(),
219 config.color().to_sdl_(),
220 static_cast<uint32_t
>(config.word_wrap()));
222 auto render = config.antialias() ?
223 &TTF_RenderUTF8_Blended :
224 &TTF_RenderUTF8_Solid;
225 raw = render(config.font().get_raw_(),
227 config.color().to_sdl_());
231 throw Host_error{
"Could not render text: “" + message +
"”"};
237 : texture_{create_texture(config)} {}
246 const Texture& Text_sprite::get_texture_()
const
248 assert_initialized_();
252 void Text_sprite::assert_initialized_()
const
254 if (texture_.empty())
255 throw Client_logic_error{
"Attempt to render empty Text_sprite"};
259 : message_{}, font_{&font}, color_{
Color::white()}, antialias_{
true},
264 message_.str(message);
282 antialias_ = antialias;
288 if (word_wrap < 0) word_wrap = 0;
289 word_wrap_ =
static_cast<uint32_t
>(word_wrap);
300 return message_.str();
320 return static_cast<int>(word_wrap_);
325 texture_ = create_texture(config);
330 return texture_.empty();
333 Text_sprite::operator bool()
const
343 void Multiplexed_sprite::render(detail::Renderer& renderer,
347 const Sprite& selection = select_(since_.elapsed_time());
348 selection.render(renderer, position, transform);