- Added camera zoom rendering for tiles.
u32 j = 0;
r_color final_color;
u32 hover_color_shift = 0;
- struct u_vec2 t = u_tile_to_screen(x, y);
- struct u_vec2 tt = u_tile_to_screen(x+1, y+1);
- struct u_vec2 tl = u_tile_to_screen(x+2, y);
- struct u_vec2 tb = u_tile_to_screen(x+2, y-2);
+ struct t_camera *c = &t_main_camera;
+ i32 zoom_factor = t_camera_zoom_factor(c);
+ u32 tile_w = t_camera_zoom(c, R_TILE_W);
+ u32 tile_h = t_camera_zoom(c, R_TILE_H);
+ i32 zfx, zfy;
+
+ struct u_vec2 t = t_camera_zoom_vec2(c, u_tile_to_screen(x, y));
/* get mouse cursor and move by camera */
struct u_vec2 cursor_pos = u_world_to_camera(&t_main_camera, i_cursor_pos());
if (u_point_in_rect(cursor_pos.x, cursor_pos.y,
t.x, t.y,
- R_TILE_W, R_TILE_H)) {
+ tile_w, tile_h)) {
hover_color_shift = 1;
}
-
- /* do not draw if tile is not visible at all
- * also include a few points outside the camera to avoid tiles
- * popping in
- */
- if (!t_camera_is_visible_screen(&t_main_camera, t.x, t.y)
- && !t_camera_is_visible_screen(&t_main_camera, tt.x, tt.y)
- && !t_camera_is_visible_screen(&t_main_camera, tb.x, tb.y)
- && !t_camera_is_visible_screen(&t_main_camera, tl.x, tl.y)) {
- return;
- }
+
t = u_screen_to_camera(&t_main_camera, t);
/* converted origin point in isometric space */
/* draw a tile texture from origin */
for (i = 0; i < R_TILE_W; i++) {
for (j = 0; j < R_TILE_H; j++) {
- final_color = r_asset_fallback_tile[i + j * R_TILE_W] & color;
- final_color <<= hover_color_shift;
- r_draw_pixel(&r_framebuffer, t.x + i, t.y + j, final_color);
+ for (zfx = 0; zfx < zoom_factor; zfx++) {
+ for (zfy = 0; zfy < zoom_factor; zfy++) {
+ final_color = r_asset_fallback_tile[i + j * R_TILE_W] & color;
+ final_color <<= hover_color_shift;
+ r_draw_pixel(&r_framebuffer, t.x + zfx + i * zoom_factor, t.y + zfy + j * zoom_factor, final_color);
+ }
+ }
}
}
}
void r_draw_tile(struct t_tile *t, i32 x, i32 y) {
-
switch (t->type) {
case T_TILE_TYPE_NONE:
break;
#include "u_debug.h"
struct r_framebuffer r_framebuffer;
+struct r_render_state r_render_state;
void r_draw_pixel(struct r_framebuffer *fb, i32 x, i32 y, r_color color) {
r_target_color *pixel = LRTS_NULL;
void r_render_debug(void) {
struct lrts_state *state = lrts_state();
- u_debug_draw_text(0, 0, "FPS: %02d, Tick: %d", state->fps, state->tick_count);
+ u_debug_draw_text(0, 0, "FPS: %02d, Tick: %d, Frame: %d", state->fps, state->tick_count, state->frame_count);
}
void r_render_frame(void) {
state->frame_count++;
state->fps = u_cap_fps();
}
+
+void r_render_update_visible_tiles(void) {
+ i32 x, y;
+ struct u_vec2 t, tt, tl, tb;
+ struct t_camera *c = &t_main_camera;
+
+ r_render_state.start_tile.x = t_map.width;
+ r_render_state.start_tile.y = t_map.height;
+
+ for (x = 0; x < t_map.width; x++) {
+ for (y = 0; y < t_map.height; y++) {
+ t = t_camera_zoom_vec2(c, u_tile_to_screen(x, y));
+ tt = t_camera_zoom_vec2(c, u_tile_to_screen(x+1, y+1));
+ tl = t_camera_zoom_vec2(c, u_tile_to_screen(x+2, y));
+ tb = t_camera_zoom_vec2(c, u_tile_to_screen(x+2, y-2));
+
+ /* do not draw if tile is not visible at all
+ * also include a few points outside the camera to avoid tiles
+ * popping in
+ */
+ if (t_camera_is_visible_screen(&t_main_camera, t.x, t.y)
+ || t_camera_is_visible_screen(&t_main_camera, tt.x, tt.y)
+ || t_camera_is_visible_screen(&t_main_camera, tb.x, tb.y)
+ || t_camera_is_visible_screen(&t_main_camera, tl.x, tl.y)) {
+
+ if (r_render_state.end_tile.x < x) {
+ r_render_state.end_tile.x = x;
+ }
+ if (r_render_state.end_tile.y < y) {
+ r_render_state.end_tile.y = y;
+ }
+
+ if (r_render_state.start_tile.x > x) {
+ r_render_state.start_tile.x = x;
+ }
+
+ if (r_render_state.start_tile.y > y) {
+ r_render_state.start_tile.y = y;
+ }
+ }
+ }
+ }
+}
r_target_color *pixels;
};
+struct r_render_state {
+ struct u_vec2 start_tile;
+ struct u_vec2 end_tile;
+};
+
/* The global frame buffer.
* This needs to be initialized by the
* rendering platform
*/
extern struct r_framebuffer r_framebuffer;
+extern struct r_render_state r_render_state;
+
/* draws a singel pixel directly to a frame buffer */
void r_draw_pixel(struct r_framebuffer *fb, i32 x, i32 y, r_color color);
-void r_render_frame();
+void r_render_frame(void);
+
+/* updats visible tiles based on the current camera position */
+void r_render_update_visible_tiles(void);
#endif
c.viewport_y = viewport_y;
c.zoom = 1;
+ r_render_update_visible_tiles();
return c;
}
/* TODO: calculate min/max viewport based on map in a better way */
c->x += by_x;
c->y += by_y;
+ r_render_update_visible_tiles();
}
lrts_bool t_camera_is_visible_screen(struct t_camera *c, i32 x, i32 y) {
m.tiles[j * m.width + i].type = T_TILE_TYPE_GRASS;
}
}
-
+ r_render_update_visible_tiles();
return m;
}
void t_map_draw(struct t_map *m) {
i32 i, j;
- struct u_vec2 start;
- struct u_vec2 end;
-
- start.x = 0;
- start.y = 0;
-
- end.x = t_map.width;
- end.y = t_map.height;
+ struct u_vec2 start = r_render_state.start_tile;
+ struct u_vec2 end = r_render_state.end_tile;
for (i = start.x; i < end.x; i++) {
for (j = start.y; j < end.y; j++) {
/* char 0x2a */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* char 0x2b */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00,
/* char 0x2c */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x20, 0x00,
/* char 0x2d */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
/* char 0x2e */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
/* char 0x2f */
0x00, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
/* char 0x30 */