8 #include "./renderer.h"
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(point_t position)
33 camera_t *camera = malloc(sizeof(camera_t));
36 throw_error(ERROR_TYPE_LIBC);
40 camera->position = position;
41 camera->debug_mode = 0;
42 camera->blackwhite_mode = 0;
47 void destroy_camera(camera_t *camera)
55 int camera_fill_rect(const camera_t *camera,
64 SDL_RenderGetViewport(render, &view_port);
66 const SDL_Rect sdl_rect = rect_for_sdl(
67 camera_rect(camera, &view_port, rect));
69 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
71 if (SDL_SetRenderDrawColor(render, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
72 throw_error(ERROR_TYPE_SDL2);
76 if (camera->debug_mode) {
77 if (SDL_RenderDrawRect(render, &sdl_rect) < 0) {
78 throw_error(ERROR_TYPE_SDL2);
82 if (SDL_RenderFillRect(render, &sdl_rect) < 0) {
83 throw_error(ERROR_TYPE_SDL2);
91 int camera_draw_rect(const camera_t * camera,
100 SDL_RenderGetViewport(render, &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(render, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
108 throw_error(ERROR_TYPE_SDL2);
112 if (SDL_RenderDrawRect(render, &sdl_rect) < 0) {
113 throw_error(ERROR_TYPE_SDL2);
120 int camera_draw_triangle(const camera_t *camera,
121 SDL_Renderer *render,
129 SDL_RenderGetViewport(render, &view_port);
131 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
133 if (SDL_SetRenderDrawColor(render, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
134 throw_error(ERROR_TYPE_SDL2);
138 if (draw_triangle(render, camera_triangle(camera, &view_port, t)) < 0) {
145 int camera_fill_triangle(const camera_t *camera,
146 SDL_Renderer *render,
154 SDL_RenderGetViewport(render, &view_port);
156 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
158 if (SDL_SetRenderDrawColor(render, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
159 throw_error(ERROR_TYPE_SDL2);
163 if (camera->debug_mode) {
164 if (draw_triangle(render, camera_triangle(camera, &view_port, t)) < 0) {
169 if (fill_triangle(render, camera_triangle(camera, &view_port, t)) < 0) {
177 int camera_clear_background(const camera_t *camera,
178 SDL_Renderer *render,
181 const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
183 if (SDL_SetRenderDrawColor(render, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
184 throw_error(ERROR_TYPE_SDL2);
188 if (SDL_RenderClear(render) < 0) {
189 throw_error(ERROR_TYPE_SDL2);
196 void camera_center_at(camera_t *camera, point_t position)
199 camera->position = position;
202 void camera_toggle_debug_mode(camera_t *camera)
205 camera->debug_mode = !camera->debug_mode;
208 void camera_toggle_blackwhite_mode(camera_t *camera)
211 camera->blackwhite_mode = !camera->blackwhite_mode;
214 int camera_is_point_visible(const camera_t *camera, SDL_Renderer *renderer, point_t p)
217 SDL_RenderGetViewport(renderer, &view_port);
219 return rect_contains_point(
220 rect_from_sdl(&view_port),
221 camera_point(camera, &view_port, p));
224 /* ---------- Private Function ---------- */
226 static vec_t effective_ratio(const SDL_Rect *view_port)
228 if ((float) view_port->w / RATIO_X > (float) view_port->h / RATIO_Y) {
229 return vec(RATIO_X, (float) view_port->h / ((float) view_port->w / RATIO_X));
231 return vec((float) view_port->w / ((float) view_port->h / RATIO_Y), RATIO_Y);
235 static vec_t effective_scale(const SDL_Rect *view_port)
237 return vec_entry_div(
238 vec((float) view_port->w, (float) view_port->h),
239 vec_scala_mult(effective_ratio(view_port), 50.0f));
242 static vec_t camera_point(const camera_t *camera,
243 const SDL_Rect *view_port,
249 vec_sum(p, vec_neg(camera->position)),
250 effective_scale(view_port)),
251 vec((float) view_port->w * 0.5f,
252 (float) view_port->h * 0.5f));
255 static triangle_t camera_triangle(const camera_t *camera,
256 const SDL_Rect *view_port,
260 camera_point(camera, view_port, t.p1),
261 camera_point(camera, view_port, t.p2),
262 camera_point(camera, view_port, t.p3));
265 static rect_t camera_rect(const camera_t *camera,
266 const SDL_Rect *view_port,
269 return rect_from_vecs(
273 vec(rect.x, rect.y)),
275 effective_scale(view_port),
276 vec(rect.w, rect.h)));