diff options
| -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 | ||
