6 #include "sdl/renderer.h"
7 #include "system/error.h"
16 SDL_Renderer *renderer;
20 static vec_t effective_ratio(const SDL_Rect *view_port);
21 static vec_t effective_scale(const SDL_Rect *view_port);
22 static vec_t camera_point(const camera_t *camera,
23 const SDL_Rect *view_port,
25 static rect_t camera_rect(const camera_t *camera,
26 const SDL_Rect *view_port,
28 static triangle_t camera_triangle(const camera_t *camera,
29 const SDL_Rect *view_port,
32 camera_t *create_camera(SDL_Renderer *renderer,
35 camera_t *camera = malloc(sizeof(camera_t));
38 throw_error(ERROR_TYPE_LIBC);
42 camera->position = vec(0.0f, 0.0f);
43 camera->debug_mode = 0;
44 camera->blackwhite_mode = 0;
45 camera->renderer = renderer;
51 void destroy_camera(camera_t *camera)
59 int camera_fill_rect(camera_t *camera,
66 SDL_RenderGetViewport(camera->renderer, &view_port);
68 const SDL_Rect sdl_rect = rect_for_sdl(
69 camera_rect(camera, &view_port, rect));
71 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
73 if (camera->debug_mode) {
74 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
75 throw_error(ERROR_TYPE_SDL2);
79 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
80 throw_error(ERROR_TYPE_SDL2);
85 if (SDL_RenderFillRect(camera->renderer, &sdl_rect) < 0) {
86 throw_error(ERROR_TYPE_SDL2);
93 int camera_draw_rect(camera_t * camera,
100 SDL_RenderGetViewport(camera->renderer, &view_port);
102 const SDL_Rect sdl_rect = rect_for_sdl(
103 camera_rect(camera, &view_port, rect));
105 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
107 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
108 throw_error(ERROR_TYPE_SDL2);
112 if (SDL_RenderDrawRect(camera->renderer, &sdl_rect) < 0) {
113 throw_error(ERROR_TYPE_SDL2);
120 int camera_draw_triangle(camera_t *camera,
127 SDL_RenderGetViewport(camera->renderer, &view_port);
129 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
131 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
132 throw_error(ERROR_TYPE_SDL2);
136 if (draw_triangle(camera->renderer, camera_triangle(camera, &view_port, t)) < 0) {
143 int camera_fill_triangle(camera_t *camera,
150 SDL_RenderGetViewport(camera->renderer, &view_port);
152 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
155 if (camera->debug_mode) {
156 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
157 throw_error(ERROR_TYPE_SDL2);
161 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
162 throw_error(ERROR_TYPE_SDL2);
167 if (fill_triangle(camera->renderer, camera_triangle(camera, &view_port, t)) < 0) {
174 int camera_render_text(camera_t *camera,
181 SDL_RenderGetViewport(camera->renderer, &view_port);
183 const vec_t scale = effective_scale(&view_port);
184 const vec_t screen_position = camera_point(camera, &view_port, position);
186 if (sprite_font_render_text(
190 vec(size.x * scale.x, size.y * scale.y),
191 camera->blackwhite_mode ? color_desaturate(color) : color,
199 int camera_clear_background(camera_t *camera,
202 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
204 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
205 throw_error(ERROR_TYPE_SDL2);
209 if (SDL_RenderClear(camera->renderer) < 0) {
210 throw_error(ERROR_TYPE_SDL2);
217 void camera_center_at(camera_t *camera, point_t position)
220 camera->position = position;
223 void camera_toggle_debug_mode(camera_t *camera)
226 camera->debug_mode = !camera->debug_mode;
229 void camera_disable_debug_mode(camera_t *camera)
232 camera->debug_mode = 0;
235 void camera_toggle_blackwhite_mode(camera_t *camera)
238 camera->blackwhite_mode = !camera->blackwhite_mode;
241 int camera_is_point_visible(const camera_t *camera, point_t p)
244 SDL_RenderGetViewport(camera->renderer, &view_port);
246 return rect_contains_point(
247 rect_from_sdl(&view_port),
248 camera_point(camera, &view_port, p));
251 rect_t camera_view_port(const camera_t *camera)
256 SDL_RenderGetViewport(camera->renderer, &view_port);
258 const vec_t s = effective_scale(&view_port);
259 const float w = (float) view_port.w * s.x;
260 const float h = (float) view_port.h * s.y;
262 return rect(camera->position.x - w * 0.5f,
263 camera->position.y - h * 0.5f,
267 /* ---------- Private Function ---------- */
269 static vec_t effective_ratio(const SDL_Rect *view_port)
271 if ((float) view_port->w / RATIO_X > (float) view_port->h / RATIO_Y) {
272 return vec(RATIO_X, (float) view_port->h / ((float) view_port->w / RATIO_X));
274 return vec((float) view_port->w / ((float) view_port->h / RATIO_Y), RATIO_Y);
278 static vec_t effective_scale(const SDL_Rect *view_port)
280 return vec_entry_div(
281 vec((float) view_port->w, (float) view_port->h),
282 vec_scala_mult(effective_ratio(view_port), 50.0f));
285 static vec_t camera_point(const camera_t *camera,
286 const SDL_Rect *view_port,
292 vec_sum(p, vec_neg(camera->position)),
293 effective_scale(view_port)),
294 vec((float) view_port->w * 0.5f,
295 (float) view_port->h * 0.5f));
298 static triangle_t camera_triangle(const camera_t *camera,
299 const SDL_Rect *view_port,
303 camera_point(camera, view_port, t.p1),
304 camera_point(camera, view_port, t.p2),
305 camera_point(camera, view_port, t.p3));
308 static rect_t camera_rect(const camera_t *camera,
309 const SDL_Rect *view_port,
312 return rect_from_vecs(
316 vec(rect.x, rect.y)),
318 effective_scale(view_port),
319 vec(rect.w, rect.h)));