#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
bool debug_mode;
bool blackwhite_mode;
Point position;
+ float scale;
SDL_Renderer *renderer;
Sprite_font *font;
};
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;
void destroy_camera(Camera *camera)
{
- assert(camera);
+ trace_assert(camera);
free(camera);
}
Rect rect,
Color color)
{
- assert(camera);
+ trace_assert(camera);
SDL_Rect view_port;
SDL_RenderGetViewport(camera->renderer, &view_port);
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;
}
Rect rect,
Color color)
{
- assert(camera);
+ trace_assert(camera);
SDL_Rect view_port;
SDL_RenderGetViewport(camera->renderer, &view_port);
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;
}
Triangle t,
Color color)
{
- assert(camera);
+ trace_assert(camera);
SDL_Rect view_port;
SDL_RenderGetViewport(camera->renderer, &view_port);
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;
}
Triangle t,
Color color)
{
- assert(camera);
+ trace_assert(camera);
SDL_Rect view_port;
SDL_RenderGetViewport(camera->renderer, &view_port);
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;
}
}
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;
const char *text,
Vec position)
{
- assert(camera);
- assert(text);
+ trace_assert(camera);
+ trace_assert(text);
if (!camera->debug_mode) {
return 0;
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;
}
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;
}
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;
}
Rect camera_view_port(const Camera *camera)
{
- assert(camera);
+ trace_assert(camera);
SDL_Rect view_port;
SDL_RenderGetViewport(camera->renderer, &view_port);
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);
{
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)),
+ 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);
}