diff options
Diffstat (limited to 'gfx-iso/src/isogfx.c')
-rw-r--r-- | gfx-iso/src/isogfx.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/gfx-iso/src/isogfx.c b/gfx-iso/src/isogfx.c index 27981f9..b38efe7 100644 --- a/gfx-iso/src/isogfx.c +++ b/gfx-iso/src/isogfx.c | |||
@@ -52,14 +52,22 @@ static inline ivec2 iso2cart(ivec2 iso, int s, int t, int w) { | |||
52 | .x = (iso.x - iso.y) * (s / 2) + (w / 2), .y = (iso.x + iso.y) * (t / 2)}; | 52 | .x = (iso.x - iso.y) * (s / 2) + (w / 2), .y = (iso.x + iso.y) * (t / 2)}; |
53 | } | 53 | } |
54 | 54 | ||
55 | // Method 1. | ||
56 | // static inline vec2 cart2iso(vec2 cart, int s, int t, int w) { | ||
57 | // const double x = cart.x - (double)(w / 2); | ||
58 | // const double xiso = (x * t + cart.y * s) / (double)(s * t); | ||
59 | // return (vec2){ | ||
60 | // .x = (int)(xiso), .y = (int)((2.0 / (double)t) * cart.y - xiso)}; | ||
61 | //} | ||
62 | |||
63 | // Method 2. | ||
55 | static inline vec2 cart2iso(vec2 cart, int s, int t, int w) { | 64 | static inline vec2 cart2iso(vec2 cart, int s, int t, int w) { |
56 | const double one_over_s = 1. / (double)s; | 65 | const double one_over_s = 1. / (double)s; |
57 | const double one_over_t = 1. / (double)t; | 66 | const double one_over_t = 1. / (double)t; |
58 | const double x = cart.x - (double)(w / 2); | 67 | const double x = cart.x - (double)(w / 2); |
59 | |||
60 | return (vec2){ | 68 | return (vec2){ |
61 | .x = (int)(one_over_s * x + one_over_t * cart.y), | 69 | .x = (one_over_s * x + one_over_t * cart.y), |
62 | .y = (int)(-one_over_s * x + one_over_t * cart.y)}; | 70 | .y = (-one_over_s * x + one_over_t * cart.y)}; |
63 | } | 71 | } |
64 | 72 | ||
65 | Pixel* tile_xy_mut(const IsoGfx* iso, TileData* tile, int x, int y) { | 73 | Pixel* tile_xy_mut(const IsoGfx* iso, TileData* tile, int x, int y) { |
@@ -120,7 +128,7 @@ static inline Pixel* screen_xy_mut(IsoGfx* iso, int x, int y) { | |||
120 | return &iso->screen[y * iso->screen_width + x]; | 128 | return &iso->screen[y * iso->screen_width + x]; |
121 | } | 129 | } |
122 | 130 | ||
123 | static void draw_tile(IsoGfx* iso, ivec2 so, Tile tile) { | 131 | static void draw_tile(IsoGfx* iso, ivec2 origin, Tile tile) { |
124 | assert(iso); | 132 | assert(iso); |
125 | 133 | ||
126 | const TileData* data = mempool_get_block(&iso->tiles, tile); | 134 | const TileData* data = mempool_get_block(&iso->tiles, tile); |
@@ -129,8 +137,8 @@ static void draw_tile(IsoGfx* iso, ivec2 so, Tile tile) { | |||
129 | for (int py = 0; py < iso->tile_height; ++py) { | 137 | for (int py = 0; py < iso->tile_height; ++py) { |
130 | for (int px = 0; px < iso->tile_width; ++px) { | 138 | for (int px = 0; px < iso->tile_width; ++px) { |
131 | const Pixel colour = tile_xy(iso, data, px, py); | 139 | const Pixel colour = tile_xy(iso, data, px, py); |
132 | const int sx = so.x + px; | 140 | const int sx = origin.x + px; |
133 | const int sy = so.y + py; | 141 | const int sy = origin.y + py; |
134 | if ((sx >= 0) && (sy >= 0) && (sx < iso->screen_width) && | 142 | if ((sx >= 0) && (sy >= 0) && (sx < iso->screen_width) && |
135 | (sy < iso->screen_height)) { | 143 | (sy < iso->screen_height)) { |
136 | const uint8_t mask = iso->tile_mask[py * iso->tile_width + px]; | 144 | const uint8_t mask = iso->tile_mask[py * iso->tile_width + px]; |
@@ -154,8 +162,9 @@ static void draw(IsoGfx* iso) { | |||
154 | const ivec2 x = {.x = iso->tile_width / 2, .y = iso->tile_height / 2}; | 162 | const ivec2 x = {.x = iso->tile_width / 2, .y = iso->tile_height / 2}; |
155 | const ivec2 y = {.x = -iso->tile_width / 2, .y = iso->tile_height / 2}; | 163 | const ivec2 y = {.x = -iso->tile_width / 2, .y = iso->tile_height / 2}; |
156 | 164 | ||
157 | // TODO: Since the world will generally be larger than the screen, it | 165 | // TODO: Culling. |
158 | // would be best to walk in screen space and fetch the tile. | 166 | // Ex: map the screen corners to tile space to cull. |
167 | // Ex: walk in screen space and fetch the tile. | ||
159 | // The tile-centric approach might be more cache-friendly, however, since the | 168 | // The tile-centric approach might be more cache-friendly, however, since the |
160 | // screen-centric approach would juggle multiple tiles throughout the scan. | 169 | // screen-centric approach would juggle multiple tiles throughout the scan. |
161 | for (int ty = 0; ty < iso->world_height; ++ty) { | 170 | for (int ty = 0; ty < iso->world_height; ++ty) { |
@@ -312,15 +321,13 @@ void isogfx_pick_tile( | |||
312 | (vec2){.x = xcart, .y = ycart}, iso->tile_width, iso->tile_height, | 321 | (vec2){.x = xcart, .y = ycart}, iso->tile_width, iso->tile_height, |
313 | iso->screen_width); | 322 | iso->screen_width); |
314 | 323 | ||
315 | const int x = (int)xy_iso.x; | 324 | if ((0 <= xy_iso.x) && (xy_iso.x < iso->world_width) && (0 <= xy_iso.y) && |
316 | const int y = (int)xy_iso.y; | 325 | (xy_iso.y < iso->world_height)) { |
317 | 326 | *xiso = (int)xy_iso.x; | |
318 | if ((0 <= x) && (x < iso->world_width) && (0 <= y) && | 327 | *yiso = (int)xy_iso.y; |
319 | (y < iso->world_height)) { | ||
320 | *xiso = x; | ||
321 | *yiso = y; | ||
322 | } else { | 328 | } else { |
323 | *xiso = -1; | 329 | *xiso = -1; |
330 | *yiso = -1; | ||
324 | } | 331 | } |
325 | } | 332 | } |
326 | 333 | ||