bool debug_mode;
bool blackwhite_mode;
Point position;
+ float scale;
SDL_Renderer *renderer;
Sprite_font *font;
};
Camera *create_camera(SDL_Renderer *renderer,
Sprite_font *font)
{
- Camera *camera = nth_alloc(sizeof(Camera));
+ trace_assert(renderer);
+ trace_assert(font);
+
+ Camera *camera = nth_calloc(1, sizeof(Camera));
if (camera == NULL) {
return NULL;
}
camera->position = vec(0.0f, 0.0f);
+ camera->scale = 1.0f;
camera->debug_mode = 0;
camera->blackwhite_mode = 0;
camera->renderer = renderer;
camera->font,
camera->renderer,
screen_position,
- vec(size.x * scale.x, size.y * scale.y),
+ vec(size.x * scale.x * camera->scale, size.y * scale.y * camera->scale),
camera->blackwhite_mode ? color_desaturate(c) : c,
text) < 0) {
return -1;
camera->position = position;
}
+void camera_scale(Camera *camera, float scale)
+{
+ trace_assert(camera);
+ camera->scale = fmaxf(0.1f, scale);
+}
+
void camera_toggle_debug_mode(Camera *camera)
{
trace_assert(camera);
w, h);
}
+Rect camera_view_port_screen(const Camera *camera)
+{
+ trace_assert(camera);
+
+ SDL_Rect view_port;
+ SDL_RenderGetViewport(camera->renderer, &view_port);
+
+ return rect_from_sdl(&view_port);
+}
+
int camera_is_text_visible(const Camera *camera,
Vec size,
Vec position,
{
return vec_sum(
- vec_entry_mult(
- vec_sum(p, vec_neg(camera->position)),
- effective_scale(view_port)),
+ vec_scala_mult(
+ vec_entry_mult(
+ vec_sum(p, vec_neg(camera->position)),
+ effective_scale(view_port)),
+ camera->scale),
vec((float) view_port->w * 0.5f,
(float) view_port->h * 0.5f));
}
const SDL_Rect *view_port,
const Rect rect)
{
- return rect_from_vecs(
+ return rect_from_points(
camera_point(
camera,
view_port,
vec(rect.x, rect.y)),
- vec_entry_mult(
- effective_scale(view_port),
- vec(rect.w, rect.h)));
+ camera_point(
+ camera,
+ view_port,
+ vec(rect.x + rect.w, rect.y + rect.h)));
}
int camera_render_debug_rect(Camera *camera,
return 0;
}
+
+Vec camera_map_screen(const Camera *camera,
+ Sint32 x, Sint32 y)
+{
+ trace_assert(camera);
+
+ SDL_Rect view_port;
+ SDL_RenderGetViewport(camera->renderer, &view_port);
+
+ Vec es = effective_scale(&view_port);
+ es.x = 1.0f / es.x;
+ es.y = 1.0f / es.y;
+
+ const Vec p = vec((float) x, (float) y);
+
+ return vec_sum(
+ vec_entry_mult(
+ vec_scala_mult(
+ vec_sum(
+ p,
+ vec((float) view_port.w * -0.5f,
+ (float) view_port.h * -0.5f)),
+ 1.0f / camera->scale),
+ es),
+ camera->position);
+}
+
+int camera_fill_rect_screen(Camera *camera,
+ Rect rect,
+ Color color)
+{
+ trace_assert(camera);
+
+ const SDL_Rect sdl_rect = rect_for_sdl(rect);
+ const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
+
+ if (camera->debug_mode) {
+ if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
+ log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
+ return -1;
+ }
+ } else {
+ if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
+ log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
+ return -1;
+ }
+ }
+
+ if (SDL_RenderFillRect(camera->renderer, &sdl_rect) < 0) {
+ log_fail("SDL_RenderFillRect: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int camera_render_text_screen(Camera *camera,
+ const char *text,
+ Vec size,
+ Color color,
+ Vec position)
+{
+ trace_assert(camera);
+ trace_assert(text);
+
+ return sprite_font_render_text(
+ camera->font,
+ camera->renderer,
+ position,
+ size,
+ color,
+ text);
+}