]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/camera.c
Merge pull request #1 from tsoding/master
[nothing.git] / src / game / camera.c
index c40de20866ac4ff727d719ce75e43d95d632da48..c1831522ce9a3a4e982de85d58bbb87d44e27a69 100644 (file)
@@ -15,6 +15,7 @@ struct Camera {
     bool debug_mode;
     bool blackwhite_mode;
     Point position;
+    float scale;
     SDL_Renderer *renderer;
     Sprite_font *font;
 };
@@ -34,13 +35,17 @@ static Triangle camera_triangle(const Camera *camera,
 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;
@@ -187,7 +192,7 @@ int camera_render_text(Camera *camera,
             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;
@@ -243,6 +248,12 @@ void camera_center_at(Camera *camera, Point position)
     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);
@@ -287,6 +298,16 @@ Rect camera_view_port(const Camera *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,
@@ -334,9 +355,11 @@ static Vec camera_point(const Camera *camera,
 
 {
     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));
 }
@@ -355,14 +378,15 @@ static Rect camera_rect(const Camera *camera,
                           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,
@@ -381,3 +405,77 @@ 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);
+}