summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-07-19 12:57:36 -0700
committer3gg <3gg@shellblade.net>2025-07-19 12:57:36 -0700
commit6e0913a3f77354eab2eeceba66db7d1750e22581 (patch)
tree14ebb54f94be4af5bd5befcc9b61bd0f5d07a378
parentf14c43d6c08253a98a781e65067288a578d1115c (diff)
Avoid recomputing the iso space
-rw-r--r--src/isogfx.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/src/isogfx.c b/src/isogfx.c
index e182dff..0aaeb9d 100644
--- a/src/isogfx.c
+++ b/src/isogfx.c
@@ -32,6 +32,12 @@ typedef struct vec2 {
32// Renderer state. 32// Renderer state.
33// ----------------------------------------------------------------------------- 33// -----------------------------------------------------------------------------
34 34
35typedef struct CoordSystem {
36 ivec2 o; // Origin.
37 ivec2 x;
38 ivec2 y;
39} CoordSystem;
40
35typedef struct Screen { 41typedef struct Screen {
36 int width; 42 int width;
37 int height; 43 int height;
@@ -48,6 +54,7 @@ typedef struct SpriteInstance {
48 54
49typedef struct IsoGfx { 55typedef struct IsoGfx {
50 Screen screen; 56 Screen screen;
57 CoordSystem iso_space;
51 double last_animation_time; 58 double last_animation_time;
52 Tile next_tile; // For procedurally-generated tiles. 59 Tile next_tile; // For procedurally-generated tiles.
53 Tm_Map* map; 60 Tm_Map* map;
@@ -109,6 +116,20 @@ static inline Pixel* screen_xy_mut(Screen* screen, int x, int y) {
109 return (Pixel*)screen_xy_const_ref(screen, x, y); 116 return (Pixel*)screen_xy_const_ref(screen, x, y);
110} 117}
111 118
119/// Create the basis for the isometric coordinate system with origin and vectors
120/// expressed in the Cartesian system.
121static CoordSystem make_iso_coord_system(
122 const Tm_Map* const map, const Screen* const screen) {
123 assert(map);
124 assert(screen);
125 const ivec2 o = {screen->width / 2, 0};
126 const ivec2 x = {
127 .x = map->base_tile_width / 2, .y = map->base_tile_height / 2};
128 const ivec2 y = {
129 .x = -map->base_tile_width / 2, .y = map->base_tile_height / 2};
130 return (CoordSystem){o, x, y};
131}
132
112// ----------------------------------------------------------------------------- 133// -----------------------------------------------------------------------------
113// Renderer, world and tile management. 134// Renderer, world and tile management.
114// ----------------------------------------------------------------------------- 135// -----------------------------------------------------------------------------
@@ -212,6 +233,8 @@ void isogfx_make_world(IsoGfx* iso, const WorldDesc* desc) {
212 *iso->tileset = (Ts_TileSet){ 233 *iso->tileset = (Ts_TileSet){
213 .num_tiles = desc->num_tiles, 234 .num_tiles = desc->num_tiles,
214 }; 235 };
236
237 iso->iso_space = make_iso_coord_system(iso->map, &iso->screen);
215} 238}
216 239
217bool isogfx_load_world(IsoGfx* iso, const char* filepath) { 240bool isogfx_load_world(IsoGfx* iso, const char* filepath) {
@@ -261,6 +284,8 @@ bool isogfx_load_world(IsoGfx* iso, const char* filepath) {
261 assert(ts_validate_tileset(tileset)); 284 assert(ts_validate_tileset(tileset));
262 assert(tm_validate_map(map, tileset)); 285 assert(tm_validate_map(map, tileset));
263 286
287 iso->iso_space = make_iso_coord_system(iso->map, &iso->screen);
288
264 success = true; 289 success = true;
265 290
266cleanup: 291cleanup:
@@ -462,24 +487,6 @@ void isogfx_update(IsoGfx* iso, double t) {
462// Rendering and picking. 487// Rendering and picking.
463// ----------------------------------------------------------------------------- 488// -----------------------------------------------------------------------------
464 489
465typedef struct CoordSystem {
466 ivec2 o; /// Origin.
467 ivec2 x;
468 ivec2 y;
469} CoordSystem;
470
471/// Create the basis for the isometric coordinate system with origin and vectors
472/// expressed in the Cartesian system.
473static CoordSystem make_iso_coord_system(const IsoGfx* iso) {
474 assert(iso);
475 const ivec2 o = {iso->screen.width / 2, 0};
476 const ivec2 x = {
477 .x = iso->map->base_tile_width / 2, .y = iso->map->base_tile_height / 2};
478 const ivec2 y = {
479 .x = -iso->map->base_tile_width / 2, .y = iso->map->base_tile_height / 2};
480 return (CoordSystem){o, x, y};
481}
482
483/// Get the screen position of the top diamond-corner of the tile at world 490/// Get the screen position of the top diamond-corner of the tile at world
484/// (x,y). 491/// (x,y).
485static ivec2 GetTileScreenOrigin( 492static ivec2 GetTileScreenOrigin(
@@ -582,8 +589,6 @@ static void draw_world(IsoGfx* iso) {
582 589
583 memset(iso->screen.pixels, 0, W * H * sizeof(Pixel)); 590 memset(iso->screen.pixels, 0, W * H * sizeof(Pixel));
584 591
585 const CoordSystem iso_space = make_iso_coord_system(iso);
586
587 const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); 592 const Tm_Layer* layer = tm_map_get_layer(iso->map, 0);
588 593
589 // TODO: Culling. 594 // TODO: Culling.
@@ -594,7 +599,7 @@ static void draw_world(IsoGfx* iso) {
594 for (int wy = 0; wy < iso->map->world_height; ++wy) { 599 for (int wy = 0; wy < iso->map->world_height; ++wy) {
595 for (int wx = 0; wx < iso->map->world_width; ++wx) { 600 for (int wx = 0; wx < iso->map->world_width; ++wx) {
596 const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); 601 const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy);
597 const ivec2 screen_origin = GetTileScreenOrigin(iso_space, wx, wy); 602 const ivec2 screen_origin = GetTileScreenOrigin(iso->iso_space, wx, wy);
598 draw_tile(iso, screen_origin, tile); 603 draw_tile(iso, screen_origin, tile);
599 } 604 }
600 } 605 }
@@ -620,15 +625,13 @@ static void draw_sprite(
620static void draw_sprites(IsoGfx* iso) { 625static void draw_sprites(IsoGfx* iso) {
621 assert(iso); 626 assert(iso);
622 627
623 const CoordSystem iso_space = make_iso_coord_system(iso);
624
625 for (const SpriteInstance* sprite = iso->head_sprite; sprite; 628 for (const SpriteInstance* sprite = iso->head_sprite; sprite;
626 sprite = sprite->next) { 629 sprite = sprite->next) {
627 const Ss_SpriteSheet* sheet = sprite->sheet; 630 const Ss_SpriteSheet* sheet = sprite->sheet;
628 assert(sheet); 631 assert(sheet);
629 632
630 const ivec2 screen_origin = 633 const ivec2 screen_origin = GetTileScreenOrigin(
631 GetTileScreenOrigin(iso_space, sprite->position.x, sprite->position.y); 634 iso->iso_space, sprite->position.x, sprite->position.y);
632 draw_sprite(iso, screen_origin, sprite, sheet); 635 draw_sprite(iso, screen_origin, sprite, sheet);
633 } 636 }
634} 637}
@@ -646,8 +649,7 @@ void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) {
646 assert(x < iso->map->world_width); 649 assert(x < iso->map->world_width);
647 assert(y < iso->map->world_height); 650 assert(y < iso->map->world_height);
648 651
649 const CoordSystem iso_space = make_iso_coord_system(iso); 652 const ivec2 screen_origin = GetTileScreenOrigin(iso->iso_space, x, y);
650 const ivec2 screen_origin = GetTileScreenOrigin(iso_space, x, y);
651 draw_tile(iso, screen_origin, tile); 653 draw_tile(iso, screen_origin, tile);
652} 654}
653 655