diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/isogfx.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/isogfx.c b/src/isogfx.c index 0aaeb9d..5d23ae4 100644 --- a/src/isogfx.c +++ b/src/isogfx.c | |||
@@ -55,6 +55,7 @@ typedef struct SpriteInstance { | |||
55 | typedef struct IsoGfx { | 55 | typedef struct IsoGfx { |
56 | Screen screen; | 56 | Screen screen; |
57 | CoordSystem iso_space; | 57 | CoordSystem iso_space; |
58 | ivec2 camera; | ||
58 | double last_animation_time; | 59 | double last_animation_time; |
59 | Tile next_tile; // For procedurally-generated tiles. | 60 | Tile next_tile; // For procedurally-generated tiles. |
60 | Tm_Map* map; | 61 | Tm_Map* map; |
@@ -76,6 +77,8 @@ static inline ivec2 ivec2_scale(ivec2 a, int s) { | |||
76 | return (ivec2){.x = a.x * s, .y = a.y * s}; | 77 | return (ivec2){.x = a.x * s, .y = a.y * s}; |
77 | } | 78 | } |
78 | 79 | ||
80 | static inline ivec2 ivec2_neg(ivec2 a) { return (ivec2){.x = -a.x, .y = -a.y}; } | ||
81 | |||
79 | static inline ivec2 iso2cart(ivec2 iso, int s, int t, int w) { | 82 | static inline ivec2 iso2cart(ivec2 iso, int s, int t, int w) { |
80 | return (ivec2){.x = (iso.x - iso.y) * (s / 2) + (w / 2), | 83 | return (ivec2){.x = (iso.x - iso.y) * (s / 2) + (w / 2), |
81 | .y = (iso.x + iso.y) * (t / 2)}; | 84 | .y = (iso.x + iso.y) * (t / 2)}; |
@@ -490,13 +493,13 @@ void isogfx_update(IsoGfx* iso, double t) { | |||
490 | /// Get the screen position of the top diamond-corner of the tile at world | 493 | /// Get the screen position of the top diamond-corner of the tile at world |
491 | /// (x,y). | 494 | /// (x,y). |
492 | static ivec2 GetTileScreenOrigin( | 495 | static ivec2 GetTileScreenOrigin( |
493 | const CoordSystem iso_space, int world_x, int world_y) { | 496 | const CoordSystem iso_space, ivec2 camera, int world_x, int world_y) { |
494 | const ivec2 vx_offset = ivec2_scale(iso_space.x, world_x); | 497 | const ivec2 vx_offset = ivec2_scale(iso_space.x, world_x); |
495 | const ivec2 vy_offset = ivec2_scale(iso_space.y, world_y); | 498 | const ivec2 vy_offset = ivec2_scale(iso_space.y, world_y); |
496 | const ivec2 screen_origin = | 499 | const ivec2 screen_origin = |
497 | ivec2_add(iso_space.o, ivec2_add(vx_offset, vy_offset)); | 500 | ivec2_add(iso_space.o, ivec2_add(vx_offset, vy_offset)); |
498 | 501 | const ivec2 origin_view_space = ivec2_add(screen_origin, ivec2_neg(camera)); | |
499 | return screen_origin; | 502 | return origin_view_space; |
500 | } | 503 | } |
501 | 504 | ||
502 | static Pixel alpha_blend(Pixel src, Pixel dst) { | 505 | static Pixel alpha_blend(Pixel src, Pixel dst) { |
@@ -598,8 +601,9 @@ static void draw_world(IsoGfx* iso) { | |||
598 | // screen-centric approach would juggle multiple tiles throughout the scan. | 601 | // screen-centric approach would juggle multiple tiles throughout the scan. |
599 | for (int wy = 0; wy < iso->map->world_height; ++wy) { | 602 | for (int wy = 0; wy < iso->map->world_height; ++wy) { |
600 | for (int wx = 0; wx < iso->map->world_width; ++wx) { | 603 | for (int wx = 0; wx < iso->map->world_width; ++wx) { |
601 | const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); | 604 | const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); |
602 | const ivec2 screen_origin = GetTileScreenOrigin(iso->iso_space, wx, wy); | 605 | const ivec2 screen_origin = |
606 | GetTileScreenOrigin(iso->iso_space, iso->camera, wx, wy); | ||
603 | draw_tile(iso, screen_origin, tile); | 607 | draw_tile(iso, screen_origin, tile); |
604 | } | 608 | } |
605 | } | 609 | } |
@@ -631,11 +635,16 @@ static void draw_sprites(IsoGfx* iso) { | |||
631 | assert(sheet); | 635 | assert(sheet); |
632 | 636 | ||
633 | const ivec2 screen_origin = GetTileScreenOrigin( | 637 | const ivec2 screen_origin = GetTileScreenOrigin( |
634 | iso->iso_space, sprite->position.x, sprite->position.y); | 638 | iso->iso_space, iso->camera, sprite->position.x, sprite->position.y); |
635 | draw_sprite(iso, screen_origin, sprite, sheet); | 639 | draw_sprite(iso, screen_origin, sprite, sheet); |
636 | } | 640 | } |
637 | } | 641 | } |
638 | 642 | ||
643 | void isogfx_set_camera(IsoGfx* iso, int x, int y) { | ||
644 | assert(iso); | ||
645 | iso->camera = (ivec2){x, y}; | ||
646 | } | ||
647 | |||
639 | void isogfx_render(IsoGfx* iso) { | 648 | void isogfx_render(IsoGfx* iso) { |
640 | assert(iso); | 649 | assert(iso); |
641 | draw_world(iso); | 650 | draw_world(iso); |
@@ -649,7 +658,8 @@ void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) { | |||
649 | assert(x < iso->map->world_width); | 658 | assert(x < iso->map->world_width); |
650 | assert(y < iso->map->world_height); | 659 | assert(y < iso->map->world_height); |
651 | 660 | ||
652 | const ivec2 screen_origin = GetTileScreenOrigin(iso->iso_space, x, y); | 661 | const ivec2 screen_origin = |
662 | GetTileScreenOrigin(iso->iso_space, iso->camera, x, y); | ||
653 | draw_tile(iso, screen_origin, tile); | 663 | draw_tile(iso, screen_origin, tile); |
654 | } | 664 | } |
655 | 665 | ||