summaryrefslogtreecommitdiff
path: root/src/gfx2d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gfx2d.c')
-rw-r--r--src/gfx2d.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/src/gfx2d.c b/src/gfx2d.c
index 14e0539..eaed2b8 100644
--- a/src/gfx2d.c
+++ b/src/gfx2d.c
@@ -26,6 +26,9 @@
26/// Take the minimum of two values. 26/// Take the minimum of two values.
27#define min(a, b) ((a) < (b) ? (a) : (b)) 27#define min(a, b) ((a) < (b) ? (a) : (b))
28 28
29/// The 0-tile denotes "no tile". The renderer skips drawing 0-tiles.
30static const Tile NoTile = 0;
31
29typedef struct ivec2 { 32typedef struct ivec2 {
30 int x, y; 33 int x, y;
31} ivec2; 34} ivec2;
@@ -606,6 +609,10 @@ static void draw_tile_ortho(Gfx2d* gfx, Tile tile, int x, int y) {
606 assert(x < gfx->map->world_width); 609 assert(x < gfx->map->world_width);
607 assert(y < gfx->map->world_height); 610 assert(y < gfx->map->world_height);
608 611
612 if (tile == NoTile) {
613 return;
614 }
615
609 const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); 616 const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile);
610 const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); 617 const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile);
611 618
@@ -626,6 +633,10 @@ static void draw_tile_iso(Gfx2d* gfx, Tile tile, int iso_x, int iso_y) {
626 assert(iso_x < gfx->map->world_width); 633 assert(iso_x < gfx->map->world_width);
627 assert(iso_y < gfx->map->world_height); 634 assert(iso_y < gfx->map->world_height);
628 635
636 if (tile == NoTile) {
637 return;
638 }
639
629 const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); 640 const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile);
630 const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); 641 const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile);
631 642
@@ -651,16 +662,21 @@ static void draw_map_ortho(Gfx2d* gfx) {
651 assert(gfx); 662 assert(gfx);
652 assert(gfx->map); 663 assert(gfx->map);
653 664
665 // Render the tiles that the camera view rectangle intersects.
666 // +1 when computing x1,y1 because the screen dimensions need not be a
667 // multiple of the base tile dimensions.
668 const int x_tiles = gfx->screen.width / gfx->map->base_tile_width;
669 const int y_tiles = gfx->screen.height / gfx->map->base_tile_height;
670 const int x0 = gfx->camera.x / gfx->map->base_tile_width;
671 const int y0 = gfx->camera.y / gfx->map->base_tile_height;
672 const int x1 = min(gfx->map->world_width, x0 + x_tiles + 1);
673 const int y1 = min(gfx->map->world_height, y0 + y_tiles + 1);
674
654 for (uint16_t l = 0; l < gfx->map->num_layers; ++l) { 675 for (uint16_t l = 0; l < gfx->map->num_layers; ++l) {
655 const Tm_Layer* layer = tm_map_get_layer(gfx->map, l); 676 const Tm_Layer* layer = tm_map_get_layer(gfx->map, l);
656 677
657 // TODO: This currently renders with tile granularity. Do so instead in 678 for (int wy = y0; wy < y1; ++wy) {
658 // terms of pixels for more accurate camera panning. The camera coordinates 679 for (int wx = x0; wx < x1; ++wx) {
659 // are already given in pixels.
660 for (int wy = gfx->camera.y / gfx->map->base_tile_height;
661 wy < gfx->map->world_height; ++wy) {
662 for (int wx = gfx->camera.x / gfx->map->base_tile_width;
663 wx < gfx->map->world_width; ++wx) {
664 const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); 680 const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy);
665 draw_tile_ortho(gfx, tile, wx, wy); 681 draw_tile_ortho(gfx, tile, wx, wy);
666 } 682 }
@@ -672,18 +688,19 @@ static void draw_map_iso(Gfx2d* gfx) {
672 assert(gfx); 688 assert(gfx);
673 assert(gfx->map); 689 assert(gfx->map);
674 690
675 // TODO: Support for multiple layers. 691 for (uint16_t l = 0; l < gfx->map->num_layers; ++l) {
676 const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); 692 const Tm_Layer* layer = tm_map_get_layer(gfx->map, l);
677 693
678 // TODO: Culling. 694 // TODO: Culling.
679 // Ex: map the screen corners to tile space to cull. 695 // Ex: map the screen corners to tile space to cull.
680 // Ex: walk in screen space and fetch the tile. 696 // Ex: walk in screen space and fetch the tile.
681 // The tile-centric approach might be more cache-friendly since the 697 // The tile-centric approach might be more cache-friendly since the
682 // screen-centric approach would juggle multiple tiles throughout the scan. 698 // screen-centric approach would juggle multiple tiles throughout the scan.
683 for (int wy = 0; wy < gfx->map->world_height; ++wy) { 699 for (int wy = 0; wy < gfx->map->world_height; ++wy) {
684 for (int wx = 0; wx < gfx->map->world_width; ++wx) { 700 for (int wx = 0; wx < gfx->map->world_width; ++wx) {
685 const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); 701 const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy);
686 draw_tile_iso(gfx, tile, wx, wy); 702 draw_tile_iso(gfx, tile, wx, wy);
703 }
687 } 704 }
688 } 705 }
689} 706}