summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-09-04 18:41:08 -0700
committer3gg <3gg@shellblade.net>2025-09-04 18:41:08 -0700
commit1f2d5b4fcfe59e36b8c0a9fec1551b42432397bb (patch)
treea70968fbef6dbe2c5606ee4db5506677305f92fa
parent83ae1c229683fd4df973edf76948248dee0fb118 (diff)
Refactor coordinate computation
-rw-r--r--src/gfx2d.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/src/gfx2d.c b/src/gfx2d.c
index 9767308..1c3cc39 100644
--- a/src/gfx2d.c
+++ b/src/gfx2d.c
@@ -85,6 +85,14 @@ static inline vec2 vec2_add(vec2 a, vec2 b) {
85 85
86static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } 86static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; }
87 87
88/// Map map coordinates to screen coordinates, both Cartesian.
89static ivec2 map2screen(
90 ivec2 camera, int tile_width, int tile_height, int map_x, int map_y) {
91 return ivec2_add(
92 ivec2_neg(camera),
93 (ivec2){.x = map_x * tile_width, .y = map_y * tile_height});
94}
95
88// Not actually used because we pre-compute the two axis vectors instead. 96// Not actually used because we pre-compute the two axis vectors instead.
89// See make_iso_coord_system() and the other definition of iso2cart() below. 97// See make_iso_coord_system() and the other definition of iso2cart() below.
90// static inline ivec2 iso2cart(ivec2 iso, int s, int t, int w) { 98// static inline ivec2 iso2cart(ivec2 iso, int s, int t, int w) {
@@ -116,9 +124,10 @@ static ivec2 iso2cart(
116 const CoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) { 124 const CoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) {
117 const ivec2 vx_offset = ivec2_scale(iso_space.x, iso_x); 125 const ivec2 vx_offset = ivec2_scale(iso_space.x, iso_x);
118 const ivec2 vy_offset = ivec2_scale(iso_space.y, iso_y); 126 const ivec2 vy_offset = ivec2_scale(iso_space.y, iso_y);
119 const ivec2 screen_origin = 127 const ivec2 origin_world_space =
120 ivec2_add(iso_space.o, ivec2_add(vx_offset, vy_offset)); 128 ivec2_add(iso_space.o, ivec2_add(vx_offset, vy_offset));
121 const ivec2 origin_view_space = ivec2_add(screen_origin, ivec2_neg(camera)); 129 const ivec2 origin_view_space =
130 ivec2_add(origin_world_space, ivec2_neg(camera));
122 return origin_view_space; 131 return origin_view_space;
123} 132}
124 133
@@ -575,17 +584,23 @@ static void draw_rect(
575} 584}
576 585
577/// Draw a tile. 586/// Draw a tile.
578/// 587static void draw_tile(IsoGfx* iso, Tile tile, int iso_x, int iso_y) {
579/// 'screen_origin' is the screen coordinates of the top diamond-corner of the
580/// tile (the base tile for super tiles).
581/// World (0, 0) -> (screen_width / 2, 0).
582static void draw_tile(IsoGfx* iso, ivec2 screen_origin, Tile tile) {
583 assert(iso); 588 assert(iso);
584 assert(iso->tileset); 589 assert(iso->tileset);
590 assert(iso_x >= 0);
591 assert(iso_y >= 0);
592 assert(iso_x < iso->map->world_width);
593 assert(iso_y < iso->map->world_height);
585 594
586 const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile); 595 const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile);
587 const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile); 596 const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile);
588 597
598 // Compute the screen coordinates of the top diamond-corner of the tile (the
599 // base tile for super tiles).
600 // World (0, 0) -> (screen_width / 2, 0).
601 const ivec2 screen_origin =
602 iso2cart(iso->iso_space, iso->camera, iso_x, iso_y);
603
589 // Move from the top diamond-corner to the top-left corner of the tile image. 604 // Move from the top diamond-corner to the top-left corner of the tile image.
590 // For regular tiles, tile height == base tile height, so the y offset is 0. 605 // For regular tiles, tile height == base tile height, so the y offset is 0.
591 // For super tiles, move as high up as the height of the tile. 606 // For super tiles, move as high up as the height of the tile.
@@ -609,15 +624,14 @@ static void draw_map(IsoGfx* iso) {
609 const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); 624 const Tm_Layer* layer = tm_map_get_layer(iso->map, 0);
610 625
611 // TODO: Culling. 626 // TODO: Culling.
612 // Ex: map the screen corners to tile space to cull. 627 // Ex: map the screen corners to tile space to cull.
613 // Ex: walk in screen space and fetch the tile. 628 // Ex: walk in screen space and fetch the tile.
614 // The tile-centric approach might be more cache-friendly since the 629 // The tile-centric approach might be more cache-friendly since the
615 // screen-centric approach would juggle multiple tiles throughout the scan. 630 // screen-centric approach would juggle multiple tiles throughout the scan.
616 for (int wy = 0; wy < iso->map->world_height; ++wy) { 631 for (int wy = 0; wy < iso->map->world_height; ++wy) {
617 for (int wx = 0; wx < iso->map->world_width; ++wx) { 632 for (int wx = 0; wx < iso->map->world_width; ++wx) {
618 const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); 633 const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy);
619 const ivec2 screen_origin = iso2cart(iso->iso_space, iso->camera, wx, wy); 634 draw_tile(iso, tile, wx, wy);
620 draw_tile(iso, screen_origin, tile);
621 } 635 }
622 } 636 }
623} 637}
@@ -669,14 +683,7 @@ void isogfx_render(IsoGfx* iso) {
669} 683}
670 684
671void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) { 685void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) {
672 assert(iso); 686 draw_tile(iso, tile, x, y);
673 assert(x >= 0);
674 assert(y >= 0);
675 assert(x < iso->map->world_width);
676 assert(y < iso->map->world_height);
677
678 const ivec2 screen_origin = iso2cart(iso->iso_space, iso->camera, x, y);
679 draw_tile(iso, screen_origin, tile);
680} 687}
681 688
682void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) { 689void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) {