summaryrefslogtreecommitdiff
path: root/src/gfx2d.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-09-06 10:50:07 -0700
committer3gg <3gg@shellblade.net>2025-09-06 10:50:07 -0700
commitf46c66485b758385417431d290e1a2958dececea (patch)
tree1ff44a03edfa6d8237a7a0ac962ab4344a0477e0 /src/gfx2d.c
parentc8fdef3b8f9b2eaab5fdccc9f8a9888d12972cc5 (diff)
Implement camera clipping for ortho maps
Diffstat (limited to 'src/gfx2d.c')
-rw-r--r--src/gfx2d.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/src/gfx2d.c b/src/gfx2d.c
index f609c98..f1f26cb 100644
--- a/src/gfx2d.c
+++ b/src/gfx2d.c
@@ -20,6 +20,12 @@
20/// Time between animation updates. 20/// Time between animation updates.
21#define ANIMATION_UPDATE_DELTA (1.0 / ANIMATION_FPS) 21#define ANIMATION_UPDATE_DELTA (1.0 / ANIMATION_FPS)
22 22
23/// Take the maximum of two values.
24#define max(a, b) ((a) > (b) ? (a) : (b))
25
26/// Take the minimum of two values.
27#define min(a, b) ((a) < (b) ? (a) : (b))
28
23typedef struct ivec2 { 29typedef struct ivec2 {
24 int x, y; 30 int x, y;
25} ivec2; 31} ivec2;
@@ -565,7 +571,6 @@ static void draw_rect(
565 571
566 // Rect origin can be outside screen bounds, so we must offset accordingly to 572 // Rect origin can be outside screen bounds, so we must offset accordingly to
567 // draw only the visible portion. 573 // draw only the visible portion.
568#define max(a, b) (a > b ? a : b)
569 const int px_offset = max(0, -top_left.x); 574 const int px_offset = max(0, -top_left.x);
570 const int py_offset = max(0, -top_left.y); 575 const int py_offset = max(0, -top_left.y);
571 576
@@ -763,13 +768,11 @@ static void draw_sprites(Gfx2d* gfx) {
763 } 768 }
764} 769}
765 770
766void gfx2d_set_camera(Gfx2d* gfx, int x, int y) { 771void gfx2d_render(Gfx2d* gfx, int camera_x, int camera_y) {
767 assert(gfx);
768 gfx->camera = (ivec2){x, y};
769}
770
771void gfx2d_render(Gfx2d* gfx) {
772 assert(gfx); 772 assert(gfx);
773 // Storing the camera mostly for debugging convenience. It could otherwise be
774 // passed around.
775 gfx->camera = (ivec2){camera_x, camera_y};
773 draw_map(gfx); 776 draw_map(gfx);
774 draw_sprites(gfx); 777 draw_sprites(gfx);
775} 778}
@@ -789,6 +792,40 @@ void gfx2d_draw_tile(Gfx2d* gfx, int x, int y, Tile tile) {
789 } 792 }
790} 793}
791 794
795static void clip_camera_ortho(const Gfx2d* gfx, float* x, float* y) {
796 assert(gfx);
797 assert(gfx->map);
798
799 if (x != nullptr) {
800 const int width_pixels = gfx->map->world_width * gfx->map->base_tile_width;
801 const int x_max = width_pixels - gfx->screen.width;
802 *x = min((float)x_max, max(0.F, *x));
803 }
804 if (y != nullptr) {
805 const int height_pixels =
806 gfx->map->world_height * gfx->map->base_tile_height;
807 const int y_max = height_pixels - gfx->screen.height;
808 *y = min((float)y_max, max(0.F, *y));
809 }
810}
811
812void gfx2d_clip_camera(const Gfx2d* gfx, float* x, float* y) {
813 assert(gfx);
814 assert(gfx->map);
815 assert(x);
816 assert(y);
817
818 const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags;
819 switch (flags->orientation) {
820 case Tm_Orthogonal:
821 clip_camera_ortho(gfx, x, y);
822 break;
823 case Tm_Isometric:
824 // TODO: Clip camera in isometric maps.
825 break;
826 }
827}
828
792void gfx2d_get_screen_size(const Gfx2d* gfx, int* width, int* height) { 829void gfx2d_get_screen_size(const Gfx2d* gfx, int* width, int* height) {
793 assert(gfx); 830 assert(gfx);
794 assert(width); 831 assert(width);