diff options
-rw-r--r-- | src/gfx2d.c | 51 |
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 | ||
86 | static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } | 86 | static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } |
87 | 87 | ||
88 | /// Map map coordinates to screen coordinates, both Cartesian. | ||
89 | static 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 | /// | 587 | static 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). | ||
582 | static 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 | ||
671 | void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) { | 685 | void 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 | ||
682 | void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) { | 689 | void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) { |