#include #include #include #include #include "framebuffer.h" #include "map.h" int main(void) { setlocale(LC_ALL,""); term_init(); Framebuffer fb = fb_new(term_width, term_height); fb_clear(fb); double pos_x = 15, pos_y = 15; /* Player pos */ double dir_x = -1, dir_y = 0; /* Player direction vector */ double plane_x = 0, plane_y = 1; /* Player camera plane vector, perpendicular to dir vector */ Map map = map_default(); /* TODO: figure out the clock */ while(1) { for (size_t x = 0; x < term_width; x++) { double cam_x = 2 * x / (double)term_width - 1; double raydir_x = dir_x + plane_x * cam_x; double raydir_y = dir_y + plane_y * cam_x; size_t map_x = (size_t) pos_x; size_t map_y = (size_t) pos_y; double sidedist_x, sidedist_y; double deltadist_x = (raydir_x == 0) ? 1e30 : fabs(1 / raydir_x); double deltadist_y = (raydir_y == 0) ? 1e30 : fabs(1 / raydir_y); int step_x, step_y; int hit = 0; int side; if (raydir_x < 0) { step_x = -1; sidedist_x = (pos_x - map_x) * deltadist_x; } else { step_x = 1; sidedist_x = (map_x + 1.0 - pos_x) * deltadist_x; } if (raydir_y < 0) { step_y = -1; sidedist_y = (pos_y - map_y) * deltadist_y; } else { step_y = 1; sidedist_y = (map_y + 1.0 - pos_y) * deltadist_y; } /* DDA */ while (!hit) { if (sidedist_x < sidedist_y) { sidedist_x += deltadist_x; map_x += step_x; side = 0; } else { sidedist_y += deltadist_y; map_y += step_y; side = 1; } if (map.tiles[map_y][map_x].ch != '\0') hit = 1; } double dist; if (side == 0) dist = sidedist_x - deltadist_x; else dist = sidedist_y - deltadist_y; int lineheight = term_height / dist; int line_start = -lineheight / 2 + term_height / 2; if (line_start < 0) line_start = 0; int line_end = lineheight / 2 + term_height / 2; if ((size_t)line_end >= term_height) line_end = term_height - 1; Pixel p = map.tiles[map_y][map_x]; if (side == 1) { p.fg.r /= 2; p.fg.g /= 2; p.fg.b /= 2; p.bg.r /= 2; p.bg.g /= 2; p.bg.b /= 2; } fb_vert_line(fb, x, line_start, line_end, p); } fb_print(fb); fb_clear(fb); char c; double old_dir_x; double old_plane_x; if(get_input(c)) { switch (c) { case 'q': goto quit; break; case 'w': if(map.tiles[(size_t)(pos_y)][(size_t)(pos_x + dir_x * 0.1)].ch == '\0') pos_x += dir_x * 0.1; if(map.tiles[(size_t)(pos_y + dir_y * 0.1)][(size_t)(pos_x)].ch == '\0') pos_y += dir_y * 0.1; break; case 's': if(map.tiles[(size_t)(pos_y)][(size_t)(pos_x - dir_x * 0.1)].ch == '\0') pos_x -= dir_x * 0.1; if(map.tiles[(size_t)(pos_y - dir_y * 0.1)][(size_t)(pos_x)].ch == '\0') pos_y -= dir_y * 0.1; break; /* TODO: figure out strafing case 'a': pos_y -= 1; break; case 'd': pos_y += 1; break; */ case 'j': old_dir_x = dir_x; dir_x = dir_x * cos(M_PI / 12) - dir_y * sin(M_PI / 12); dir_y = old_dir_x * sin(M_PI / 12) + dir_y * cos(M_PI / 12); old_plane_x = plane_x; plane_x = plane_x * cos(M_PI / 12) - plane_y * sin(M_PI / 12); plane_y = old_plane_x * sin(M_PI / 12) + plane_y * cos(M_PI / 12); break; case 'l': old_dir_x = dir_x; dir_x = dir_x * cos(-M_PI / 12) - dir_y * sin(-M_PI / 12); dir_y = old_dir_x * sin(-M_PI / 12) + dir_y * cos(-M_PI / 12); old_plane_x = plane_x; plane_x = plane_x * cos(-M_PI / 12) - plane_y * sin(-M_PI / 12); plane_y = old_plane_x * sin(-M_PI / 12) + plane_y * cos(-M_PI / 12); break; } } } quit: map_free(&map); fb_free(&fb); term_cleanup(); }