summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/camera.c76
-rw-r--r--src/camera.h14
-rw-r--r--src/main.c2
-rw-r--r--src/map.h12
-rw-r--r--src/renderer.c79
-rw-r--r--src/renderer.h10
-rw-r--r--src/screen.c70
-rw-r--r--src/screen.h25
8 files changed, 156 insertions, 132 deletions
diff --git a/src/camera.c b/src/camera.c
new file mode 100644
index 0000000..fa2d0e8
--- /dev/null
+++ b/src/camera.c
@@ -0,0 +1,76 @@
+#include "camera.h"
+
+#include <math.h>
+
+void init_camera(Camera* camera) {
+ camera->pos.x = 3;
+ camera->pos.y = 3;
+ camera->angle = PI / 4;
+ camera->fov = PI / 4;
+}
+
+#define MOVE_SPEED 1
+#define ROTATE_SPEED PI / 2
+#define FOV_CHANGE_SPEED .5
+#define PLAYER_SIZE .1
+
+void update_camera(Camera* camera, Screen* screen) {
+ double rotate = 0;
+
+ if (key_down(KEY_LEFT))
+ rotate -= ROTATE_SPEED;
+
+ if (key_down(KEY_RIGHT))
+ rotate += ROTATE_SPEED;
+
+ rotate *= screen->delta;
+ rotate += camera->angle;
+ while (rotate >= PI2) rotate -= PI2;
+ while (rotate < 0) rotate += PI2;
+ camera->angle = rotate;
+
+ v2 forward = { cos(camera->angle), sin(camera->angle) };
+ v2 left = { forward.y, -forward.x };
+ v2 move = { 0, 0 };
+
+ if (key_down(KEY_W)) {
+ move.x += forward.x;
+ move.y += forward.y;
+ }
+
+ if (key_down(KEY_S)) {
+ move.x -= forward.x;
+ move.y -= forward.y;
+ }
+
+ if (key_down(KEY_A)) {
+ move.x += left.x;
+ move.y += left.y;
+ }
+
+ if (key_down(KEY_D)) {
+ move.x -= left.x;
+ move.y -= left.y;
+ }
+
+ if (key_down(KEY_EQUALS)) {
+ camera->fov += FOV_CHANGE_SPEED * screen->delta;
+ }
+
+ if (key_down(KEY_MINUS)) {
+ camera->fov -= FOV_CHANGE_SPEED * screen->delta;
+ }
+
+ v2 hit_pos;
+ bool movex, movey;
+
+ cast_ray(camera->pos, sign(move.x) == 1 ? 0 : PI, &hit_pos);
+ movex = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE;
+
+ cast_ray(camera->pos, sign(move.y) == 1 ? PIH : -PIH, &hit_pos);
+ movey = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE;
+
+ if (movex) camera->pos.x += move.x * MOVE_SPEED * screen->delta;
+ if (movey) camera->pos.y += move.y * MOVE_SPEED * screen->delta;
+}
+
diff --git a/src/camera.h b/src/camera.h
new file mode 100644
index 0000000..cea1100
--- /dev/null
+++ b/src/camera.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "screen.h"
+#include "ray.h"
+
+typedef struct {
+ v2 pos;
+ float angle;
+ float fov;
+} Camera;
+
+void init_camera(Camera* camera);
+void update_camera(Camera* camera, Screen* screeen);
+
diff --git a/src/main.c b/src/main.c
index d51e6c3..e4872f3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,7 +13,7 @@ static void signal_handler() {
int main (void) {
Screen screen;
- init_screen(&screen, 2160, 1440, "Raycaster");
+ init_screen(&screen, 2160, 1440, "Raycaster", 60);
Camera camera;
init_camera(&camera);
diff --git a/src/map.h b/src/map.h
index 3e265b2..ecb60ef 100644
--- a/src/map.h
+++ b/src/map.h
@@ -2,6 +2,18 @@
#include <stdint.h>
+// #define MAP_SIZE 8
+// static uint8_t MAPDATA[MAP_SIZE * MAP_SIZE] = {
+// 1, 1, 1, 1, 1, 1, 1, 1,
+// 1, 0, 0, 0, 0, 0, 0, 1,
+// 1, 0, 0, 0, 0, 3, 0, 1,
+// 1, 0, 0, 0, 0, 0, 0, 1,
+// 1, 0, 2, 0, 4, 4, 0, 1,
+// 1, 0, 0, 0, 4, 0, 0, 1,
+// 1, 0, 3, 0, 0, 0, 0, 1,
+// 1, 1, 1, 1, 1, 1, 1, 1,
+// };
+
#define MAP_SIZE 8
static uint8_t MAPDATA[MAP_SIZE * MAP_SIZE] = {
1, 1, 1, 1, 1, 1, 1, 1,
diff --git a/src/renderer.c b/src/renderer.c
index 3841583..54d3bd0 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -3,90 +3,13 @@
#include "ray.h"
#include <math.h>
-#include <pthread.h>
#include <stdio.h>
#include <string.h>
-
-void init_camera(Camera* camera) {
- camera->pos.x = 3;
- camera->pos.y = 3;
- camera->angle = PI / 4;
-}
-
-static double fov = PI / 4;
-
-#define MOVE_SPEED 1
-#define ROTATE_SPEED PI / 2
-#define FOV_CHANGE_SPEED 1
-#define PLAYER_SIZE .1
-
-
-void update_camera(Camera* camera, Screen* screen) {
- double rotate = 0;
-
- if (key_down(KEY_LEFT))
- rotate -= ROTATE_SPEED;
-
- if (key_down(KEY_RIGHT))
- rotate += ROTATE_SPEED;
-
- rotate *= screen->delta;
- rotate += camera->angle;
- while (rotate >= PI2) rotate -= PI2;
- while (rotate < 0) rotate += PI2;
- camera->angle = rotate;
-
- v2 forward = { cos(camera->angle), sin(camera->angle) };
- v2 left = { forward.y, -forward.x };
- v2 move = { 0, 0 };
-
- if (key_down(KEY_W)) {
- move.x += forward.x;
- move.y += forward.y;
- }
-
- if (key_down(KEY_S)) {
- move.x -= forward.x;
- move.y -= forward.y;
- }
-
- if (key_down(KEY_A)) {
- move.x += left.x;
- move.y += left.y;
- }
-
- if (key_down(KEY_D)) {
- move.x -= left.x;
- move.y -= left.y;
- }
-
- if (key_down(KEY_EQUALS)) {
- fov += FOV_CHANGE_SPEED * screen->delta;
- }
-
- if (key_down(KEY_MINUS)) {
- fov -= FOV_CHANGE_SPEED * screen->delta;
- }
-
- v2 hit_pos;
- bool movex, movey;
-
- cast_ray(camera->pos, sign(move.x) == 1 ? 0 : PI, &hit_pos);
- movex = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE;
-
- cast_ray(camera->pos, sign(move.y) == 1 ? PIH : -PIH, &hit_pos);
- movey = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE;
-
- if (movex) camera->pos.x += move.x * MOVE_SPEED * screen->delta;
- if (movey) camera->pos.y += move.y * MOVE_SPEED * screen->delta;
-}
-
static void verline(Swapchain* swapchain, int x, int y0, int y1, uint32_t color) {
for (int y = y0; y <= y1; y++) {
swapchain->images[swapchain->image_current][(y * swapchain->width) + x] = color;
}
-
}
void render(Screen* screen, const Camera* camera) {
@@ -103,7 +26,7 @@ void render(Screen* screen, const Camera* camera) {
for (int x = 0; x < screen->swapchain.width; x++) {
const float xcam = (2 * (x / (float) (swapchain->width))) - 1;
- const float change = fov * atan(xcam);
+ const float change = camera->fov * atan(xcam);
const float theta = camera->angle + change;
v2 hit_pos;
diff --git a/src/renderer.h b/src/renderer.h
index 4bbc711..25ea62d 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -1,14 +1,6 @@
#pragma once
#include "screen.h"
-#include "ray.h"
-
-typedef struct {
- v2 pos;
- float angle;
-} Camera;
-
-void init_camera(Camera* camera);
-void update_camera(Camera* camera, Screen* screeen);
+#include "camera.h"
void render(Screen* screen, const Camera* camera);
diff --git a/src/screen.c b/src/screen.c
index 5e84038..86d829d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -5,10 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include <pthread.h>
-#include <unistd.h>
-#include <signal.h>
#define XLIB_ILLEGAL_ACCESS
#include <X11/X.h>
@@ -33,6 +30,8 @@ typedef struct {
XImage** images;
pthread_t update_thread;
pthread_mutex_t recreate_lock;
+ pthread_mutex_t lock;
+ uint16_t update_rate;
} WindowState;
static void init_x() {
@@ -173,7 +172,6 @@ void swapchain_next(Swapchain* swapchain) {
next += 1;
next %= 3;
}
-
swapchain->image_current = next;
pthread_mutex_unlock(&swapchain->lock);
}
@@ -184,28 +182,54 @@ void swapchain_submit(Swapchain* swapchain) {
pthread_mutex_unlock(&swapchain->lock);
}
+static long get_time() {
+ struct timespec spec;
+ clock_gettime(CLOCK_MONOTONIC, &spec);
+ return round(spec.tv_nsec / 1.0e6) + spec.tv_sec * 1000;
+}
+
+static void update_delta(float* delta, long* last) {
+ long now = get_time();
+ if (*last == 0) {
+ *delta = 0;
+ } else {
+ *delta = (now - *last) / 1000.0;
+ }
+ *last = now;
+}
+
static void* swapchain_thread(void* arg) {
struct Screen* screen = (struct Screen*) arg;
WindowState* state = (WindowState*) screen->internal;
+ long last = get_time();
+ float delta;
+
while (1) {
if (screen->swapchain.images == NULL) {
return NULL;
}
+
+ long now = last;
+ update_delta(&delta, &now);
+ if (delta < 1.0 / state->update_rate) {
+ continue;
+ } else {
+ last = now;
+ }
pthread_mutex_lock(&state->recreate_lock);
pthread_mutex_lock(&screen->swapchain.lock);
- int index = screen->swapchain.image_recent;
- screen->swapchain.image_front = index;
+ screen->swapchain.image_front = screen->swapchain.image_recent;
pthread_mutex_unlock(&screen->swapchain.lock);
XPutImage(
dpy,
state->window,
state->graphics_ctx,
- state->images[index],
+ state->images[screen->swapchain.image_front],
0, 0, 0, 0,
screen->swapchain.width,
screen->swapchain.height
@@ -213,8 +237,6 @@ static void* swapchain_thread(void* arg) {
XSync(dpy, 0);
pthread_mutex_unlock(&state->recreate_lock);
-
- usleep(1000 * 1000 / 60);
}
return NULL;
@@ -222,7 +244,7 @@ static void* swapchain_thread(void* arg) {
#define FRAMES 3
-void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const char* title) {
+void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const char* title, uint16_t update_rate) {
if (dpy == NULL) {
init_x();
@@ -233,6 +255,7 @@ void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const c
WindowState* state = malloc(sizeof(WindowState));
state->window = window;
+ state->update_rate = update_rate;
screen->swapchain = create_swapchain(width, height, FRAMES, bit_depth, state);
pthread_create(&state->update_thread, NULL, &swapchain_thread, screen);
@@ -242,23 +265,6 @@ void init_screen(struct Screen* screen, uint16_t width, uint16_t height, const c
count++;
}
-static long get_time() {
- struct timespec spec;
- clock_gettime(CLOCK_MONOTONIC, &spec);
- return round(spec.tv_nsec / 1.0e6) + spec.tv_sec * 1000;
-}
-
-static long last = 0;
-
-static void update_delta(struct Screen* screen) {
- long now = get_time();
- if (last == 0) {
- screen->delta = 0;
- } else {
- screen->delta = (now - last) / 1000.0;
- }
- last = now;
-}
static void handle_event(struct Screen* screen) {
XEvent event;
@@ -291,11 +297,11 @@ static void handle_event(struct Screen* screen) {
}
bool poll_screen(struct Screen* screen) {
-
while (XPending(dpy))
handle_event(screen);
- update_delta(screen);
+ static long last = 0;
+ update_delta(&screen->delta, &last);
return true;
}
@@ -320,13 +326,15 @@ void free_screen(struct Screen* screen) {
}
}
-bool key_pressed(int keycode) {
+bool key_pressed(int code) {
+ int keycode = code - dpy->min_keycode;
if (key_checked[keycode]) return false;
if (!key_state[keycode]) return false;
key_checked[keycode] = true;
return true;
}
-bool key_down(int keycode) {
+bool key_down(int code) {
+ int keycode = code - dpy->min_keycode;
return key_state[keycode];
}
diff --git a/src/screen.h b/src/screen.h
index 423af7e..23094bb 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -2,7 +2,6 @@
#define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112L
-// #define _POSIX_C_SOURCE 200809L
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
@@ -29,19 +28,19 @@ struct Screen {
#define Screen struct Screen
-#define KEY_W 17
-#define KEY_A 30
-#define KEY_S 31
-#define KEY_D 32
-#define KEY_UP 103
-#define KEY_DOWN 108
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_MINUS 12
-#define KEY_EQUALS 13
-#define KEY_ESC 1
+#define KEY_W 25
+#define KEY_A 38
+#define KEY_S 39
+#define KEY_D 40
+#define KEY_UP 111
+#define KEY_DOWN 116
+#define KEY_LEFT 113
+#define KEY_RIGHT 114
+#define KEY_MINUS 20
+#define KEY_EQUALS 21
+#define KEY_ESC 9
-void init_screen(Screen* screen, uint16_t width, uint16_t height, const char* title);
+void init_screen(Screen* screen, uint16_t width, uint16_t height, const char* title, uint16_t update_rate);
bool poll_screen(Screen* screen);
void free_screen(Screen* screen);