r_color final_color;
struct u_vec2 t = u_tile_to_screen(x, y);
t = u_screen_to_camera(&t_main_camera, t);
+
+ /* do not draw if tile is not visible at all */
+ if (!t_camera_is_visible_world(&t_main_camera, t.x, t.y)
+ && !t_camera_is_visible_world(&t_main_camera, t.x + R_TILE_W, t.y + R_TILE_H)) {
+ return;
+ }
/* converted origin point in isometric space */
#include "t_camera.h"
+#include "u_math.h"
struct t_camera t_main_camera;
}
void t_camera_scroll(struct t_camera *c, i32 by_x, i32 by_y) {
+ /* TODO: calculate min/max viewport based on map in a better way */
c->x += by_x;
c->y += by_y;
+}
+
+lrts_bool t_camera_is_visible_screen(struct t_camera *c, i32 x, i32 y) {
+ return u_point_in_rect(x, y, c->x, c->y, c->x + c->viewport_x, c->y + c->viewport_y);
+}
- /* TODO: calculate max viewport based on map */
- U_CLAMP(c->x, -4096, 4096);
- U_CLAMP(c->y, -4096, 4096);
+lrts_bool t_camera_is_visible_world(struct t_camera *c, i32 x, i32 y) {
+ struct u_vec2 t;
+ t.x = c->x;
+ t.y = c->y;
+
+ return u_point_in_rect(x, y, t.x, t.y, t.x + c->viewport_x, t.y + c->viewport_y);
}
/* adjusts a screen coodrinate by the camera offset */
struct u_vec2 u_screen_to_camera(struct t_camera *c, struct u_vec2 v);
+/* tests if a point is visible in screen sapce */
+lrts_bool t_camera_is_visible_screen(struct t_camera *c, i32 x, i32 y);
+
+/* tests if a point is visible in world space */
+lrts_bool t_camera_is_visible_world(struct t_camera *c, i32 x, i32 y);
+
#endif
struct u_vec2 start;
struct u_vec2 end;
- /* estimate the viewport based on the orthogonal map
- * This is not perfect, but it is good enough to avoid drawing a
- * full size map.
- */
- start.x = t_main_camera.x / R_TILE_W;
- start.y = t_main_camera.y / R_TILE_H;
-
- end.x = ((t_main_camera.x + t_main_camera.viewport_x) / R_TILE_W) * 2;
- end.y = ((t_main_camera.y + t_main_camera.viewport_y) / R_TILE_H) * 2;
-
start.x = 0;
start.y = 0;
+ end.x = t_map.width;
+ end.y = t_map.height;
+
for (i = start.x; i < end.x; i++) {
for (j = start.y; j < end.y; j++) {
r_draw_tile(&m->tiles[j * m->width + i], i, j);
return r;
}
+struct u_vec2 u_point_to_screen(i32 x, i32 y) {
+ struct u_vec2 r;
+
+ r.x = (x) + (y);
+ r.y = (y) - (x);
+
+ return r;
+}
+
lrts_bool u_point_in_rect(i32 x, i32 y, i32 rx, i32 ry, i32 rw, i32 rh) {
return x >= rx && x <= rx + rw
&& y >= ry && y <= ry + rh;
*/
struct u_vec2 u_tile_to_screen(i32 x, i32 y);
+/* convers a point to screen space */
+struct u_vec2 u_point_to_screen(i32 x, i32 y);
+
/* tests if a point is contained inside a rectangle */
lrts_bool u_point_in_rect(i32 x, i32 y, i32 rx, i32 ry, i32 rw, i32 rh);