6 #include "sdl/renderer.h"
7 #include "system/error.h"
16 SDL_Renderer *renderer;
19 static vec_t effective_ratio(const SDL_Rect *view_port);
20 static vec_t effective_scale(const SDL_Rect *view_port);
21 static vec_t camera_point(const camera_t *camera,
22 const SDL_Rect *view_port,
24 static rect_t camera_rect(const camera_t *camera,
25 const SDL_Rect *view_port,
27 static triangle_t camera_triangle(const camera_t *camera,
28 const SDL_Rect *view_port,
31 camera_t *create_camera_from_renderer(SDL_Renderer *renderer)
33 camera_t *camera = malloc(sizeof(camera_t));
36 throw_error(ERROR_TYPE_LIBC);
40 camera->position = vec(0.0f, 0.0f);
41 camera->debug_mode = 0;
42 camera->blackwhite_mode = 0;
43 camera->renderer = renderer;
48 void destroy_camera(camera_t *camera)
56 int camera_fill_rect(const camera_t *camera,
63 SDL_RenderGetViewport(camera->renderer, &view_port);
65 const SDL_Rect sdl_rect = rect_for_sdl(
66 camera_rect(camera, &view_port, rect));
68 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
70 if (camera->debug_mode) {
71 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
72 throw_error(ERROR_TYPE_SDL2);
76 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
77 throw_error(ERROR_TYPE_SDL2);
82 if (SDL_RenderFillRect(camera->renderer, &sdl_rect) < 0) {
83 throw_error(ERROR_TYPE_SDL2);
90 int camera_draw_rect(const camera_t * camera,
97 SDL_RenderGetViewport(camera->renderer, &view_port);
99 const SDL_Rect sdl_rect = rect_for_sdl(
100 camera_rect(camera, &view_port, rect));
102 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
104 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
105 throw_error(ERROR_TYPE_SDL2);
109 if (SDL_RenderDrawRect(camera->renderer, &sdl_rect) < 0) {
110 throw_error(ERROR_TYPE_SDL2);
117 int camera_draw_triangle(const camera_t *camera,
124 SDL_RenderGetViewport(camera->renderer, &view_port);
126 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
128 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
129 throw_error(ERROR_TYPE_SDL2);
133 if (draw_triangle(camera->renderer, camera_triangle(camera, &view_port, t)) < 0) {
140 int camera_fill_triangle(const camera_t *camera,
147 SDL_RenderGetViewport(camera->renderer, &view_port);
149 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
153 if (camera->debug_mode) {
154 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
155 throw_error(ERROR_TYPE_SDL2);
159 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
160 throw_error(ERROR_TYPE_SDL2);
165 if (fill_triangle(camera->renderer, camera_triangle(camera, &view_port, t)) < 0) {
172 int camera_clear_background(const camera_t *camera,
175 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
177 if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
178 throw_error(ERROR_TYPE_SDL2);
182 if (SDL_RenderClear(camera->renderer) < 0) {
183 throw_error(ERROR_TYPE_SDL2);
190 void camera_present(const camera_t *camera)
192 SDL_RenderPresent(camera->renderer);
195 void camera_center_at(camera_t *camera, point_t position)
198 camera->position = position;
201 void camera_toggle_debug_mode(camera_t *camera)
204 camera->debug_mode = !camera->debug_mode;
207 void camera_disable_debug_mode(camera_t *camera)
210 camera->debug_mode = 0;
213 void camera_toggle_blackwhite_mode(camera_t *camera)
216 camera->blackwhite_mode = !camera->blackwhite_mode;
219 int camera_is_point_visible(const camera_t *camera, point_t p)
222 SDL_RenderGetViewport(camera->renderer, &view_port);
224 return rect_contains_point(
225 rect_from_sdl(&view_port),
226 camera_point(camera, &view_port, p));
229 rect_t camera_view_port(const camera_t *camera)
234 SDL_RenderGetViewport(camera->renderer, &view_port);
236 const vec_t s = effective_scale(&view_port);
237 const float w = (float) view_port.w * s.x;
238 const float h = (float) view_port.h * s.y;
240 return rect(camera->position.x - w * 0.5f,
241 camera->position.y - h * 0.5f,
246 /* ---------- Private Function ---------- */
248 static vec_t effective_ratio(const SDL_Rect *view_port)
250 if ((float) view_port->w / RATIO_X > (float) view_port->h / RATIO_Y) {
251 return vec(RATIO_X, (float) view_port->h / ((float) view_port->w / RATIO_X));
253 return vec((float) view_port->w / ((float) view_port->h / RATIO_Y), RATIO_Y);
257 static vec_t effective_scale(const SDL_Rect *view_port)
259 return vec_entry_div(
260 vec((float) view_port->w, (float) view_port->h),
261 vec_scala_mult(effective_ratio(view_port), 50.0f));
264 static vec_t camera_point(const camera_t *camera,
265 const SDL_Rect *view_port,
271 vec_sum(p, vec_neg(camera->position)),
272 effective_scale(view_port)),
273 vec((float) view_port->w * 0.5f,
274 (float) view_port->h * 0.5f));
277 static triangle_t camera_triangle(const camera_t *camera,
278 const SDL_Rect *view_port,
282 camera_point(camera, view_port, t.p1),
283 camera_point(camera, view_port, t.p2),
284 camera_point(camera, view_port, t.p3));
287 static rect_t camera_rect(const camera_t *camera,
288 const SDL_Rect *view_port,
291 return rect_from_vecs(
295 vec(rect.x, rect.y)),
297 effective_scale(view_port),
298 vec(rect.w, rect.h)));