diff options
| author | Kirill Petrashin <kirill8201@yandex.ru> | 2026-06-29 19:51:00 +0300 |
|---|---|---|
| committer | Kirill Petrashin <kirill8201@yandex.ru> | 2026-06-29 19:51:00 +0300 |
| commit | 6fcb46123c154b3360640c0c0be611fde74ffe57 (patch) | |
| tree | 125026cce731ace22d35867ec1dcd56e7e009f2d /main.c | |
| parent | b7bab0bc3c2c82d5f356ae525397396a63db6cdf (diff) | |
| download | wafflestone-6fcb46123c154b3360640c0c0be611fde74ffe57.tar.xz | |
Implement a raycaster
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 144 |
1 files changed, 119 insertions, 25 deletions
@@ -4,49 +4,143 @@ #include <unistd.h> #include "framebuffer.h" +#include "map.h" int main(void) { setlocale(LC_ALL,""); term_init(); - //fprintf(stderr, "%zux%zu\n", term_width, term_height); Framebuffer fb = fb_new(term_width, term_height); - fb_fill(fb, P_RED); + fb_clear(fb); - char c; - const float k_x = 0.1; - const float k_t = 0.1; - size_t t = 0; - long text_x = 0, text_y = 0; - while(1) { - fb_fill(fb, P_RED); + 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(); - /* Sine wave */ + /* TODO: figure out the clock */ + + while(1) { for (size_t x = 0; x < term_width; x++) { - size_t y = ((sin(k_x * x + k_t * t) + 1.0) / 2 * term_height / 2) + (size_t)(term_height / 4); - fb_vert_line(fb, x, y, term_height - 1, P_GREEN); - } + 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; - fb_text_no_bg(fb, text_x, text_y, "testing", C_BLACK); + size_t map_x = (size_t) pos_x; + size_t map_y = (size_t) pos_y; - fb_print(fb); + 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); - /* Handle input */ - if (get_input(c) != 0) { - switch(c) { - case 'q': goto quit; break; - case 'h': text_x -= 1; break; - case 'l': text_x += 1; break; - case 'k': text_y -= 1; break; - case 'j': text_y += 1; break; + 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; - t++; + 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(); } |
