]> 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 c0f6b97441faf14ed866279a00d738ae011384d1..c1831522ce9a3a4e982de85d58bbb87d44e27a69 100644 (file)
@@ -1,12 +1,12 @@
 #include <SDL2/SDL.h>
-#include <assert.h>
+#include "system/stacktrace.h"
 #include <math.h>
 #include <stdbool.h>
 
 #include "camera.h"
 #include "sdl/renderer.h"
-#include "system/error.h"
 #include "system/nth_alloc.h"
+#include "system/log.h"
 
 #define RATIO_X 16.0f
 #define RATIO_Y 9.0f
@@ -15,6 +15,7 @@ struct Camera {
     bool debug_mode;
     bool blackwhite_mode;
     Point position;
+    float scale;
     SDL_Renderer *renderer;
     Sprite_font *font;
 };
@@ -32,16 +33,19 @@ static Triangle camera_triangle(const Camera *camera,
                                   const Triangle t);
 
 Camera *create_camera(SDL_Renderer *renderer,
-                        Sprite_font *font)
+                      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) {
-        throw_error(ERROR_TYPE_LIBC);
         return NULL;
     }
 
     camera->position = vec(0.0f, 0.0f);
+    camera->scale = 1.0f;
     camera->debug_mode = 0;
     camera->blackwhite_mode = 0;
     camera->renderer = renderer;
@@ -52,7 +56,7 @@ Camera *create_camera(SDL_Renderer *renderer,
 
 void destroy_camera(Camera *camera)
 {
-    assert(camera);
+    trace_assert(camera);
 
     free(camera);
 }
@@ -61,7 +65,7 @@ int camera_fill_rect(Camera *camera,
                      Rect rect,
                      Color color)
 {
-    assert(camera);
+    trace_assert(camera);
 
     SDL_Rect view_port;
     SDL_RenderGetViewport(camera->renderer, &view_port);
@@ -73,18 +77,18 @@ int camera_fill_rect(Camera *camera,
 
     if (camera->debug_mode) {
         if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
-            throw_error(ERROR_TYPE_SDL2);
+            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) {
-            throw_error(ERROR_TYPE_SDL2);
+            log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
             return -1;
         }
     }
 
     if (SDL_RenderFillRect(camera->renderer, &sdl_rect) < 0) {
-        throw_error(ERROR_TYPE_SDL2);
+        log_fail("SDL_RenderFillRect: %s\n", SDL_GetError());
         return -1;
     }
 
@@ -95,7 +99,7 @@ int camera_draw_rect(Camera * camera,
                      Rect rect,
                      Color color)
 {
-    assert(camera);
+    trace_assert(camera);
 
     SDL_Rect view_port;
     SDL_RenderGetViewport(camera->renderer, &view_port);
@@ -106,12 +110,12 @@ int camera_draw_rect(Camera * camera,
     const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
 
     if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
-        throw_error(ERROR_TYPE_SDL2);
+        log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
         return -1;
     }
 
     if (SDL_RenderDrawRect(camera->renderer, &sdl_rect) < 0) {
-        throw_error(ERROR_TYPE_SDL2);
+        log_fail("SDL_RenderDrawRect: %s\n", SDL_GetError());
         return -1;
     }
 
@@ -122,7 +126,7 @@ int camera_draw_triangle(Camera *camera,
                          Triangle t,
                          Color color)
 {
-    assert(camera);
+    trace_assert(camera);
 
     SDL_Rect view_port;
     SDL_RenderGetViewport(camera->renderer, &view_port);
@@ -130,7 +134,7 @@ int camera_draw_triangle(Camera *camera,
     const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
 
     if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
-        throw_error(ERROR_TYPE_SDL2);
+        log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
         return -1;
     }
 
@@ -145,7 +149,7 @@ int camera_fill_triangle(Camera *camera,
                          Triangle t,
                          Color color)
 {
-    assert(camera);
+    trace_assert(camera);
 
     SDL_Rect view_port;
     SDL_RenderGetViewport(camera->renderer, &view_port);
@@ -155,12 +159,12 @@ int camera_fill_triangle(Camera *camera,
 
     if (camera->debug_mode) {
         if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a / 2) < 0) {
-            throw_error(ERROR_TYPE_SDL2);
+            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) {
-            throw_error(ERROR_TYPE_SDL2);
+            log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
             return -1;
         }
     }
@@ -188,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;
@@ -201,8 +205,8 @@ int camera_render_debug_text(Camera *camera,
                              const char *text,
                              Vec position)
 {
-    assert(camera);
-    assert(text);
+    trace_assert(camera);
+    trace_assert(text);
 
     if (!camera->debug_mode) {
         return 0;
@@ -212,7 +216,7 @@ int camera_render_debug_text(Camera *camera,
             camera,
             text,
             vec(2.0f, 2.0f),
-            color(0.0f, 0.0f, 0.0f, 1.0f),
+            rgba(0.0f, 0.0f, 0.0f, 1.0f),
             position) < 0) {
         return -1;
     }
@@ -226,12 +230,12 @@ int camera_clear_background(Camera *camera,
     const SDL_Color sdl_color = color_for_sdl(camera->blackwhite_mode ? color_desaturate(color) : color);
 
     if (SDL_SetRenderDrawColor(camera->renderer, sdl_color.r, sdl_color.g, sdl_color.b, sdl_color.a) < 0) {
-        throw_error(ERROR_TYPE_SDL2);
+        log_fail("SDL_SetRenderDrawColor: %s\n", SDL_GetError());
         return -1;
     }
 
     if (SDL_RenderClear(camera->renderer) < 0) {
-        throw_error(ERROR_TYPE_SDL2);
+        log_fail("SDL_RenderClear: %s\n", SDL_GetError());
         return -1;
     }
 
@@ -240,25 +244,31 @@ int camera_clear_background(Camera *camera,
 
 void camera_center_at(Camera *camera, Point position)
 {
-    assert(camera);
+    trace_assert(camera);
     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)
 {
-    assert(camera);
+    trace_assert(camera);
     camera->debug_mode = !camera->debug_mode;
 }
 
 void camera_disable_debug_mode(Camera *camera)
 {
-    assert(camera);
+    trace_assert(camera);
     camera->debug_mode = 0;
 }
 
 void camera_toggle_blackwhite_mode(Camera *camera)
 {
-    assert(camera);
+    trace_assert(camera);
     camera->blackwhite_mode = !camera->blackwhite_mode;
 }
 
@@ -274,7 +284,7 @@ int camera_is_point_visible(const Camera *camera, Point p)
 
 Rect camera_view_port(const Camera *camera)
 {
-    assert(camera);
+    trace_assert(camera);
 
     SDL_Rect view_port;
     SDL_RenderGetViewport(camera->renderer, &view_port);
@@ -288,13 +298,23 @@ 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,
                            const char *text)
 {
-    assert(camera);
-    assert(text);
+    trace_assert(camera);
+    trace_assert(text);
 
     SDL_Rect view_port;
     SDL_RenderGetViewport(camera->renderer, &view_port);
@@ -335,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));
 }
@@ -356,12 +378,104 @@ 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)),
+        camera_point(
+            camera,
+            view_port,
+            vec(rect.x + rect.w, rect.y + rect.h)));
+}
+
+int camera_render_debug_rect(Camera *camera,
+                             Rect rect,
+                             Color c)
+{
+    trace_assert(camera);
+
+    if (!camera->debug_mode) {
+        return 0;
+    }
+
+    if (camera_fill_rect(camera, rect, c) < 0) {
+        return -1;
+    }
+
+    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(
-            effective_scale(view_port),
-            vec(rect.w, rect.h)));
+            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);
 }