summaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/screen.c b/src/screen.c
new file mode 100644
index 0000000..5e23e0b
--- /dev/null
+++ b/src/screen.c
@@ -0,0 +1,130 @@
+#include "screen.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.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));
+
+ SDL_Init(SDL_INIT_VIDEO);
+
+ screen->window =
+ SDL_CreateWindow(
+ title,
+ SDL_WINDOWPOS_CENTERED_DISPLAY(0),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(0),
+ screen->width,
+ screen->height,
+ 0
+ );
+
+ if (!screen->window) {
+ printf("fatal: failed to create sdl window\n");
+ exit(EXIT_FAILURE);
+ }
+
+ screen->renderer =
+ SDL_CreateRenderer(
+ screen->window,
+ -1,
+ SDL_RENDERER_ACCELERATED
+ | SDL_RENDERER_PRESENTVSYNC
+ );
+
+ if (!screen->renderer) {
+ printf("fatal: failed to create sdl renderer\n");
+ exit(EXIT_FAILURE);
+ }
+
+ screen->texture =
+ SDL_CreateTexture(
+ screen->renderer,
+ SDL_PIXELFORMAT_RGBA8888,
+ SDL_TEXTUREACCESS_STREAMING,
+ screen->width,
+ screen->height
+ );
+
+ if (!screen->texture) {
+ printf("fatal: failed to create window texture\n");
+ exit(EXIT_FAILURE);
+ }
+
+ screen->open = true;
+ screen->delta = 0;
+}
+
+static long last = 0;
+void poll_screen(Screen* screen) {
+ struct timespec spec;
+ clock_gettime(CLOCK_MONOTONIC, &spec);
+ long now = round(spec.tv_nsec / 1.0e6) + spec.tv_sec * 1000;
+ 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;
+ }
+ }
+
+ screen->key_state = SDL_GetKeyboardState(NULL);
+}
+
+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)
+ );
+ }
+ }
+ SDL_UnlockTexture(screen->texture);
+
+ SDL_SetRenderTarget(screen->renderer, NULL);
+ SDL_SetRenderDrawColor(screen->renderer, 0, 0, 0, 0xFF);
+ SDL_SetRenderDrawBlendMode(screen->renderer, SDL_BLENDMODE_NONE);
+
+ SDL_RenderClear(screen->renderer);
+ SDL_RenderCopyEx(
+ screen->renderer,
+ screen->texture,
+ NULL,
+ NULL,
+ 0.0,
+ NULL,
+ SDL_FLIP_VERTICAL);
+
+ SDL_RenderCopy(screen->renderer, NULL, NULL, &((SDL_Rect) { 0, 0, 512, 512 }));
+ SDL_RenderPresent(screen->renderer);
+}
+
+void free_screen(Screen* screen) {
+ SDL_DestroyTexture(screen->texture);
+ SDL_DestroyRenderer(screen->renderer);
+ SDL_DestroyWindow(screen->window);
+}
+
+bool key_pressed(Screen* screen, SDL_Scancode code) {
+ return screen->key_state[code & 0xFFFF];
+}