summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--framebuffer.c6
-rw-r--r--main.c144
-rw-r--r--map.c6
4 files changed, 129 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index fde9f38..8df8c2a 100644
--- a/Makefile
+++ b/Makefile
@@ -4,10 +4,10 @@ CFLAGS=-Wall -Wpedantic -Wextra -Werror -O3
LINKERFLAGS=-lm
wafflestone: *.c *.h
- $(CC) $(CFLAGS) -o $(EXECUTABLE) framebuffer.c main.c $(LINKERFLAGS)
+ $(CC) $(CFLAGS) -o $(EXECUTABLE) framebuffer.c map.c main.c $(LINKERFLAGS)
debug: *.c *.h
- $(CC) -Wall -g -o $(EXECUTABLE) framebuffer.c main.c $(LINKERFLAGS)
+ $(CC) -Wall -g -o $(EXECUTABLE) framebuffer.c map.c main.c $(LINKERFLAGS)
.PHONY: clean
clean:
diff --git a/framebuffer.c b/framebuffer.c
index 32c0f0f..ce48f35 100644
--- a/framebuffer.c
+++ b/framebuffer.c
@@ -73,7 +73,11 @@ void fb_put(Framebuffer fb, size_t row, size_t col, Pixel pixel) {
}
void fb_vert_line(Framebuffer fb, size_t x, size_t y1, size_t y2, Pixel pixel) {
- assert(y2 >= y1);
+ if (y2 < y1) {
+ y2 ^= y1;
+ y1 ^= y2;
+ y2 ^= y1;
+ };
for (size_t y = y1; y <= y2; y++) {
fb.fb[y][x] = pixel;
diff --git a/main.c b/main.c
index 75bc451..fcfe166 100644
--- a/main.c
+++ b/main.c
@@ -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();
}
diff --git a/map.c b/map.c
index 3d81c00..dcf009d 100644
--- a/map.c
+++ b/map.c
@@ -10,7 +10,7 @@ Map map_new(size_t width, size_t height) {
map.tiles = malloc(sizeof(Pixel *) * height);
if (map.tiles == NULL) return map;
for (size_t row = 0; row < height; row++) {
- map.tiles[row] = malloc(sizeof(Pixel *) * width);
+ map.tiles[row] = malloc(sizeof(Pixel) * width);
if (map.tiles[row] == NULL) {
/* FIXME: free prev rows */
map.tiles = NULL;
@@ -45,11 +45,11 @@ Map map_default(void) {
/* Boundaries */
for (size_t x = 0; x < map.width; x++) { /* Horizontal */
- map.tiles[0][x] = P_MAGENTA;
+ map.tiles[0][x] = P_RED;
map.tiles[map.height - 1][x] = P_RED;
}
for (size_t y = 0; y < map.height; y++) { /* Vertical */
- map.tiles[y][0] = P_MAGENTA;
+ map.tiles[y][0] = P_RED;
map.tiles[y][map.width - 1] = P_RED;
}