summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile2
-rw-r--r--src/main.c13
-rw-r--r--src/renderer.c44
-rw-r--r--src/screen.c299
-rw-r--r--src/screen.h34
5 files changed, 271 insertions, 121 deletions
diff --git a/Makefile b/Makefile
index 5c79afe..dfb9014 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ CCFLAGS = -std=c99 -Wall -Wextra -pedantic -O2
CCFLAGS += $(INCFLAGS)
LDFLAGS += $(INCFLAGS)
-LDFLAGS += -lSDL2
+LDFLAGS += -lX11
LDFLAGS += -lm
BIN = bin
diff --git a/src/main.c b/src/main.c
index 36b819f..385d0d1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,20 +1,21 @@
#include "renderer.h"
#include "screen.h"
+#include <stdio.h>
+#include <stdlib.h>
+
int main (void) {
Screen screen;
- init_screen(&screen, "test", 1920, 1080);
+ init_screen(&screen, 2160, 1440);
Camera camera;
init_camera(&camera);
-
- while(screen.open) {
- poll_screen(&screen);
- draw_screen(&screen);
+
+ while (poll_screen(&screen)) {
render(&screen, &camera);
-
update_camera(&camera, &screen);
}
+
free_screen(&screen);
return EXIT_SUCCESS;
diff --git a/src/renderer.c b/src/renderer.c
index c64be51..a77f855 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -19,16 +19,16 @@ static double fov = PI / 4;
#define FOV_CHANGE_SPEED 1
#define PLAYER_SIZE .1
+
void update_camera(Camera* camera, Screen* screen) {
double rotate = 0;
- if (key_pressed(screen, SDL_SCANCODE_LEFT))
+ if (key_down(KEY_LEFT))
rotate -= ROTATE_SPEED;
- if (key_pressed(screen, SDL_SCANCODE_RIGHT))
+ if (key_down(KEY_RIGHT))
rotate += ROTATE_SPEED;
-
rotate *= screen->delta;
rotate += camera->angle;
while (rotate >= PI2) rotate -= PI2;
@@ -39,31 +39,31 @@ void update_camera(Camera* camera, Screen* screen) {
v2 left = { forward.y, -forward.x };
v2 move = { 0, 0 };
- if (key_pressed(screen, SDL_SCANCODE_W)) {
+ if (key_down(KEY_W)) {
move.x += forward.x;
move.y += forward.y;
}
- if (key_pressed(screen, SDL_SCANCODE_S)) {
+ if (key_down(KEY_S)) {
move.x -= forward.x;
move.y -= forward.y;
}
- if (key_pressed(screen, SDL_SCANCODE_A)) {
+ if (key_down(KEY_A)) {
move.x += left.x;
move.y += left.y;
}
- if (key_pressed(screen, SDL_SCANCODE_D)) {
+ if (key_down(KEY_D)) {
move.x -= left.x;
move.y -= left.y;
}
- if (key_pressed(screen, SDL_SCANCODE_EQUALS)) {
+ if (key_down(KEY_EQUALS)) {
fov += FOV_CHANGE_SPEED * screen->delta;
}
- if (key_pressed(screen, SDL_SCANCODE_MINUS)) {
+ if (key_down(KEY_MINUS)) {
fov -= FOV_CHANGE_SPEED * screen->delta;
}
@@ -94,6 +94,7 @@ void render(Screen* screen, const Camera* camera) {
};
for (int x = 0; x < screen->width; x++) {
+
const float xcam = (2 * (x / (float) (screen->width))) - 1;
const float change = fov * atan(xcam);
const float theta = camera->angle + change;
@@ -109,20 +110,31 @@ void render(Screen* screen, const Camera* camera) {
uint32_t color;
switch (hit) {
case 1: color = 0xFF0000FF; break;
- case 2: color = 0x00FF00FF; break;
- case 3: color = 0x0000FFFF; break;
- case 4: color = 0xFF00FFFF; break;
- case 5: color = 0x00FFFFFF; break;
- default: color = 0x000000FF; break;
+ case 2: color = 0xFF00FF00; break;
+ case 3: color = 0xFFFF0000; break;
+ case 4: color = 0xFFFF00FF; break;
+ case 5: color = 0xFFFFFF00; break;
+ default: color = 0xFF000000; break;
}
+ // switch (hit) {
+ // case 1: color = 0xFF0000FF; break;
+ // case 2: color = 0x00FF00FF; break;
+ // case 3: color = 0x0000FFFF; break;
+ // case 4: color = 0xFF00FFFF; break;
+ // case 5: color = 0x00FFFFFF; break;
+ // default: color = 0x000000FF; break;
+ // }
const int
h = (int) (screen->height / len),
y0 = max((screen->height / 2) - (h / 2), 0),
y1 = min((screen->height / 2) + (h / 2), screen->height - 1);
- verline(screen, x, 0, y0, 0x202020FF);
+ verline(screen, x, 0, y0, 0xFF202020);
verline(screen, x, y0, y1, color);
- verline(screen, x, y1, screen->height - 1, 0x505050FF);
+ verline(screen, x, y1, screen->height - 1, 0xFF505050);
+ // verline(screen, x, 0, y0, 0x202020FF);
+ // verline(screen, x, y0, y1, color);
+ // verline(screen, x, y1, screen->height - 1, 0x505050FF);
}
}
diff --git a/src/screen.c b/src/screen.c
index 5e23e0b..dca9b79 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1,130 +1,257 @@
#include "screen.h"
+#include <X11/X.h>
+#undef Screen
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <sys/select.h>
-void init_screen(Screen* screen, const char* title, uint16_t width, uint16_t height) {
- screen->width = width;
- screen->height = height;
- size_t pixel_count = screen->width * screen->height;
- screen->pixels = malloc(pixel_count * sizeof(uint32_t));
- memset(screen->pixels, 0, pixel_count * sizeof(uint32_t));
+#define XLIB_ILLEGAL_ACCESS
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
- SDL_Init(SDL_INIT_VIDEO);
+static Display* dpy;
+static int scr;
+static Window root;
- screen->window =
- SDL_CreateWindow(
- title,
- SDL_WINDOWPOS_CENTERED_DISPLAY(0),
- SDL_WINDOWPOS_CENTERED_DISPLAY(0),
- screen->width,
- screen->height,
- 0
- );
+static int count = 0;
+static size_t bit_depth = sizeof(uint32_t) * 8;
+static int key_count;
- if (!screen->window) {
- printf("fatal: failed to create sdl window\n");
- exit(EXIT_FAILURE);
- }
+static bool* key_state;
+static bool* key_checked;
- screen->renderer =
- SDL_CreateRenderer(
- screen->window,
- -1,
- SDL_RENDERER_ACCELERATED
- | SDL_RENDERER_PRESENTVSYNC
- );
+typedef struct {
+ Window window;
+ GC graphics_ctx;
+ Pixmap pixel_map;
+ XImage* image;
+ int width, height;
+} WindowState;
- if (!screen->renderer) {
- printf("fatal: failed to create sdl renderer\n");
+static void init_x() {
+ if ((dpy = XOpenDisplay(NULL)) == NULL) {
+ printf("error: failed to open x11 display\n");
exit(EXIT_FAILURE);
}
- screen->texture =
- SDL_CreateTexture(
- screen->renderer,
- SDL_PIXELFORMAT_RGBA8888,
- SDL_TEXTUREACCESS_STREAMING,
- screen->width,
- screen->height
- );
+#ifdef DEBUG
+ XSynchronize(dpy, True);
+#endif
+
+ scr = DefaultScreen(dpy);
+ root = RootWindow(dpy, scr);
+
+ key_count = dpy->max_keycode - dpy->min_keycode;
+ key_state = malloc(sizeof(bool) * key_count);
+ key_checked = malloc(sizeof(bool) * key_count);
+}
+
+static Window create_window(int x, int y, int w, int h, int d) {
+
+ XVisualInfo vis_info;
+ if(!XMatchVisualInfo(dpy, scr, d, TrueColor, &vis_info)) {
+ printf("error: %d depth not supported\n", d);
+ exit(EXIT_FAILURE);
+ }
+
+ Visual* visual = vis_info.visual;;
- if (!screen->texture) {
- printf("fatal: failed to create window texture\n");
- exit(EXIT_FAILURE);
+ XSetWindowAttributes xwa;
+ xwa.background_pixel = 0;
+ xwa.border_pixel = 0;
+ xwa.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask;
+ xwa.colormap = XCreateColormap(dpy, root, visual, AllocNone);
+
+ long wm = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
+
+ Window window = XCreateWindow(dpy, root, x, y, w, h, 0, d, InputOutput, visual, wm, &xwa);
+
+ return window;
+}
+
+static XImage* create_image(int width, int height) {
+ return XCreateImage(
+ dpy,
+ CopyFromParent,
+ bit_depth,
+ ZPixmap,
+ 0,
+ malloc(width * height * bit_depth / 8),
+ width,
+ height,
+ bit_depth,
+ 0
+ );
+}
+
+
+void init_screen(struct Screen* screen, uint16_t width, uint16_t height) {
+
+ if (dpy == NULL) {
+ init_x();
}
- screen->open = true;
+ screen->width = width;
+ screen->height = height;
screen->delta = 0;
+
+ size_t pixel_count = screen->width * screen->height;
+
+ screen->pixels = malloc(pixel_count * bit_depth / 8);
+ memset(screen->pixels, 0, pixel_count * bit_depth / 8);
+
+ Window window = create_window(0, 0, width, height, bit_depth);
+ XMapWindow(dpy, window);
+
+ Pixmap pixel_map = XCreatePixmap(dpy, window, width, height, bit_depth);
+
+ GC gc = XCreateGC(dpy, pixel_map, 0, NULL);
+
+ WindowState* state = malloc(sizeof(WindowState));
+ state->window = window;
+ state->graphics_ctx = gc;
+ state->pixel_map = pixel_map;
+
+ XWindowAttributes xwa;
+ XGetWindowAttributes(dpy, window, &xwa);
+ state->width = xwa.width;
+ state->height = xwa.height;
+ screen->internal = state;
+
+ XImage* image = create_image(state->width, state->height);
+ state->image = image;
+
+ count++;
}
-static long last = 0;
-void poll_screen(Screen* screen) {
+static long get_time() {
struct timespec spec;
clock_gettime(CLOCK_MONOTONIC, &spec);
- long now = round(spec.tv_nsec / 1.0e6) + spec.tv_sec * 1000;
+ 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;
-
- SDL_Event ev;
- while (SDL_PollEvent(&ev)) {
- switch (ev.type) {
- case SDL_QUIT:
- screen->open = false;
- break;
- default:
- break;
+}
+
+static void draw_screen(struct Screen* screen) {
+ WindowState* state = (WindowState*) screen->internal;
+
+ uint32_t* src = screen->pixels;
+ uint32_t* dst = (uint32_t*) state->image->data;
+
+ float x_step = screen->width / (float) state->width;
+ float y_step = screen->height / (float) state->height;
+
+ for (int x = 0; x < state->width; x++) {
+ int px = (int) (x * x_step);
+
+ for (int y = 0; y < state->height; y++) {
+ int py = (int) (y * y_step);
+
+ dst[x + y * state->width] = src[px + py * screen->width];
}
}
- screen->key_state = SDL_GetKeyboardState(NULL);
+ XPutImage(
+ dpy,
+ state->window,
+ state->graphics_ctx,
+ state->image,
+ 0, 0, 0, 0,
+ state->width,
+ state->height
+ );
}
-void draw_screen(Screen* screen) {
- void *px;
- int pitch;
- SDL_LockTexture(screen->texture, NULL, &px, &pitch);
- {
- for (uint16_t y = 0; y < screen->height; y++) {
- memcpy(
- &((uint8_t*) px)[y * pitch],
- &screen->pixels[y * screen->width],
- screen->width * sizeof(uint32_t)
- );
+
+static void handle_event(WindowState* state) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+
+ switch(event.type) {
+
+ case KeyPress: {
+ XKeyEvent xkpe = event.xkey;
+ uint32_t code = xkpe.keycode - dpy->min_keycode;
+ key_state[code] = true;
+ key_checked[code] = false;
+ break;
+ }
+
+ case KeyRelease: {
+ XKeyEvent xkre = event.xkey;
+ uint32_t code = xkre.keycode - dpy->min_keycode;
+ key_state[code] = false;
+ break;
+ }
+
+ case ConfigureNotify: {
+ XConfigureEvent xce = event.xconfigure;
+ state->width = xce.width;
+ state->height = xce.height;
+
+ XDestroyImage(state->image);
+ state->image = create_image(state->width, state->height);
+
+ break;
}
+
+ default: break;
}
- SDL_UnlockTexture(screen->texture);
+}
- SDL_SetRenderTarget(screen->renderer, NULL);
- SDL_SetRenderDrawColor(screen->renderer, 0, 0, 0, 0xFF);
- SDL_SetRenderDrawBlendMode(screen->renderer, SDL_BLENDMODE_NONE);
+bool poll_screen(struct Screen* screen) {
- SDL_RenderClear(screen->renderer);
- SDL_RenderCopyEx(
- screen->renderer,
- screen->texture,
- NULL,
- NULL,
- 0.0,
- NULL,
- SDL_FLIP_VERTICAL);
+ draw_screen(screen);
+
+ WindowState* state = (WindowState*) screen->internal;
+
+ while (XPending(dpy))
+ handle_event(state);
+
+ update_delta(screen);
+ return true;
+}
- SDL_RenderCopy(screen->renderer, NULL, NULL, &((SDL_Rect) { 0, 0, 512, 512 }));
- SDL_RenderPresent(screen->renderer);
+void free_screen(struct Screen* screen) {
+ WindowState* state = (WindowState*) screen->internal;
+
+ XUnmapWindow(dpy, state->window);
+ XFreePixmap(dpy, state->pixel_map);
+ XDestroyImage(state->image);
+ XFreeGC(dpy, state->graphics_ctx);
+ XDestroyWindow(dpy, state->window);
+ free(screen->internal);
+
+ count--;
+
+ if(count == 0) {
+ XCloseDisplay(dpy);
+ free(key_state);
+ free(key_checked);
+ }
}
-void free_screen(Screen* screen) {
- SDL_DestroyTexture(screen->texture);
- SDL_DestroyRenderer(screen->renderer);
- SDL_DestroyWindow(screen->window);
+bool key_pressed(int keycode) {
+ if (key_checked[keycode]) return false;
+ if (!key_state[keycode]) return false;
+ key_checked[keycode] = true;
+ return true;
}
-bool key_pressed(Screen* screen, SDL_Scancode code) {
- return screen->key_state[code & 0xFFFF];
+bool key_down(int keycode) {
+ return key_state[keycode];
}
diff --git a/src/screen.h b/src/screen.h
index 1b601d8..c2165f9 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -1,24 +1,34 @@
#pragma once
#define _POSIX_C_SOURCE 200809L
-#include <SDL2/SDL.h>
+#include <stdint.h>
#include <stdbool.h>
-typedef struct {
+struct Screen {
uint16_t width;
uint16_t height;
- SDL_Window* window;
- SDL_Renderer* renderer;
- SDL_Texture* texture;
uint32_t* pixels;
- const uint8_t* key_state;
- bool open;
float delta;
-} Screen;
+ void* internal;
+};
-void init_screen(Screen* screen, const char* title, uint16_t width, uint16_t height);
-void draw_screen(Screen* screen);
-void poll_screen(Screen* 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
+
+void init_screen(Screen* screen, uint16_t width, uint16_t height);
+bool poll_screen(Screen* screen);
void free_screen(Screen* screen);
-bool key_pressed(Screen* screen, SDL_Scancode code);
+bool key_pressed(int keycode);
+bool key_down(int keycode);