From 1f2d5b4fcfe59e36b8c0a9fec1551b42432397bb Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Thu, 4 Sep 2025 18:41:08 -0700 Subject: Refactor coordinate computation --- src/gfx2d.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file 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) { static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } +/// Map map coordinates to screen coordinates, both Cartesian. +static ivec2 map2screen( + ivec2 camera, int tile_width, int tile_height, int map_x, int map_y) { + return ivec2_add( + ivec2_neg(camera), + (ivec2){.x = map_x * tile_width, .y = map_y * tile_height}); +} + // Not actually used because we pre-compute the two axis vectors instead. // See make_iso_coord_system() and the other definition of iso2cart() below. // static inline ivec2 iso2cart(ivec2 iso, int s, int t, int w) { @@ -116,9 +124,10 @@ static ivec2 iso2cart( const CoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) { const ivec2 vx_offset = ivec2_scale(iso_space.x, iso_x); const ivec2 vy_offset = ivec2_scale(iso_space.y, iso_y); - const ivec2 screen_origin = + const ivec2 origin_world_space = ivec2_add(iso_space.o, ivec2_add(vx_offset, vy_offset)); - const ivec2 origin_view_space = ivec2_add(screen_origin, ivec2_neg(camera)); + const ivec2 origin_view_space = + ivec2_add(origin_world_space, ivec2_neg(camera)); return origin_view_space; } @@ -575,17 +584,23 @@ static void draw_rect( } /// Draw a tile. -/// -/// 'screen_origin' is the screen coordinates of the top diamond-corner of the -/// tile (the base tile for super tiles). -/// World (0, 0) -> (screen_width / 2, 0). -static void draw_tile(IsoGfx* iso, ivec2 screen_origin, Tile tile) { +static void draw_tile(IsoGfx* iso, Tile tile, int iso_x, int iso_y) { assert(iso); assert(iso->tileset); + assert(iso_x >= 0); + assert(iso_y >= 0); + assert(iso_x < iso->map->world_width); + assert(iso_y < iso->map->world_height); const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile); const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile); + // Compute the screen coordinates of the top diamond-corner of the tile (the + // base tile for super tiles). + // World (0, 0) -> (screen_width / 2, 0). + const ivec2 screen_origin = + iso2cart(iso->iso_space, iso->camera, iso_x, iso_y); + // Move from the top diamond-corner to the top-left corner of the tile image. // For regular tiles, tile height == base tile height, so the y offset is 0. // For super tiles, move as high up as the height of the tile. @@ -609,15 +624,14 @@ static void draw_map(IsoGfx* iso) { const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); // TODO: Culling. - // Ex: map the screen corners to tile space to cull. - // Ex: walk in screen space and fetch the tile. - // The tile-centric approach might be more cache-friendly since the - // screen-centric approach would juggle multiple tiles throughout the scan. + // Ex: map the screen corners to tile space to cull. + // Ex: walk in screen space and fetch the tile. + // The tile-centric approach might be more cache-friendly since the + // screen-centric approach would juggle multiple tiles throughout the scan. for (int wy = 0; wy < iso->map->world_height; ++wy) { for (int wx = 0; wx < iso->map->world_width; ++wx) { - const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); - const ivec2 screen_origin = iso2cart(iso->iso_space, iso->camera, wx, wy); - draw_tile(iso, screen_origin, tile); + const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); + draw_tile(iso, tile, wx, wy); } } } @@ -669,14 +683,7 @@ void isogfx_render(IsoGfx* iso) { } void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) { - assert(iso); - assert(x >= 0); - assert(y >= 0); - assert(x < iso->map->world_width); - assert(y < iso->map->world_height); - - const ivec2 screen_origin = iso2cart(iso->iso_space, iso->camera, x, y); - draw_tile(iso, screen_origin, tile); + draw_tile(iso, tile, x, y); } void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) { -- cgit v1.2.3