diff options
author | 3gg <3gg@shellblade.net> | 2025-07-19 12:57:36 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2025-07-19 12:57:36 -0700 |
commit | 6e0913a3f77354eab2eeceba66db7d1750e22581 (patch) | |
tree | 14ebb54f94be4af5bd5befcc9b61bd0f5d07a378 | |
parent | f14c43d6c08253a98a781e65067288a578d1115c (diff) |
Avoid recomputing the iso space
-rw-r--r-- | src/isogfx.c | 56 |
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 | ||
35 | typedef struct CoordSystem { | ||
36 | ivec2 o; // Origin. | ||
37 | ivec2 x; | ||
38 | ivec2 y; | ||
39 | } CoordSystem; | ||
40 | |||
35 | typedef struct Screen { | 41 | typedef struct Screen { |
36 | int width; | 42 | int width; |
37 | int height; | 43 | int height; |
@@ -48,6 +54,7 @@ typedef struct SpriteInstance { | |||
48 | 54 | ||
49 | typedef struct IsoGfx { | 55 | typedef 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. | ||
121 | static 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 | ||
217 | bool isogfx_load_world(IsoGfx* iso, const char* filepath) { | 240 | bool 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 | ||
266 | cleanup: | 291 | cleanup: |
@@ -462,24 +487,6 @@ void isogfx_update(IsoGfx* iso, double t) { | |||
462 | // Rendering and picking. | 487 | // Rendering and picking. |
463 | // ----------------------------------------------------------------------------- | 488 | // ----------------------------------------------------------------------------- |
464 | 489 | ||
465 | typedef 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. | ||
473 | static 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). |
485 | static ivec2 GetTileScreenOrigin( | 492 | static 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( | |||
620 | static void draw_sprites(IsoGfx* iso) { | 625 | static 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 | ||