This commit is contained in:
Tobin
2026-04-17 17:42:07 -04:00
commit 27a3bbde96
4 changed files with 217 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
*.swp
bin/
+155
View File
@@ -0,0 +1,155 @@
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
enum cat_events
{
QUIT,
KEYDOWN,
KEYUP,
MOUSEMOVE,
MOUSEDOWN,
MOUSEUP
};
struct cat_event
{
enum cat_events type;
char key;
unsigned char mouse_button;
int mousex;
int mousey;
};
/* SDL stuff */
static unsigned int* fg_framebuffer = NULL;
static unsigned int* bg_framebuffer = NULL;
static unsigned int* comp_framebuffer = NULL;
static SDL_Window* window = NULL;
static SDL_Renderer* renderer = NULL;
static SDL_Texture* texture = NULL;
static int screen_width = 0;
static int screen_height = 0;
void cat_pixel(int layer, int visible, int x, int y, unsigned char r, unsigned char g, unsigned char b)
{
if (comp_framebuffer == NULL)
{
printf("Warning: tried to write a pixel while screen uninitialized\n");
return;
}
if (x >= screen_width || y >= screen_height)
{
printf("Warning: (%u, %u): coordinate off screen\n", x, y);
return;
}
unsigned int draw_color = (r << 16) + (g << 8) + b;
if (visible) draw_color += 0xff000000;
if (layer) fg_framebuffer[y * screen_width + x] = draw_color;
else bg_framebuffer[y * screen_width + x] = draw_color;
}
void cat_de_init_screen(void)
{
if (window != NULL) SDL_DestroyWindow(window);
window = NULL;
renderer = NULL;
texture = NULL;
free(fg_framebuffer);
free(bg_framebuffer);
free(comp_framebuffer);
fg_framebuffer = NULL; /* this might be redundant */
bg_framebuffer = NULL;
comp_framebuffer = NULL;
}
void cat_create_window(int w, int h)
{
screen_width = w;
screen_height = h;
if (window != NULL || renderer != NULL || texture != NULL) cat_de_init_screen();
fg_framebuffer = malloc(screen_width * screen_height * sizeof(unsigned int));
bg_framebuffer = malloc(screen_width * screen_height * sizeof(unsigned int));
comp_framebuffer = malloc(screen_width * screen_height * sizeof(unsigned int));
window = SDL_CreateWindow("cfhfg", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, screen_width, screen_height, SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(window, -1, 0);
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, screen_width, screen_height);
SDL_ShowCursor(SDL_DISABLE);
}
void comp_buffers(void)
{
int x, y; for (y = 0; y < screen_height; y++)
{
for (x = 0; x < screen_width; x++)
{
if (fg_framebuffer[y * screen_width + x] & 0xff000000)
comp_framebuffer[y * screen_width + x] = fg_framebuffer[y * screen_width + x];
else comp_framebuffer[y * screen_width + x] = bg_framebuffer[y * screen_width + x] | 0xff000000;
/* TODO decide if this should be left
as 0 if "erasing", to make a black
pixel, ignoring other color info */
}
}
}
void cat_render(void)
{
comp_buffers();
SDL_UpdateTexture(texture, NULL, (const void*)comp_framebuffer, screen_width * sizeof(unsigned int));
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
void cat_init(void)
{
SDL_Init(SDL_INIT_EVERYTHING);
}
void cat_fill(int layer, int visible, int x, int y, int w, int h, unsigned char r, unsigned char g, unsigned char b)
{
int cy, cx;
for (cy = 0; cy < h; cy++)
for (cx = 0; cx < w; cx++)
cat_pixel(layer, visible, cx + x, cy + y, r, g, b);
}
/* TODO: cat bresenham */
struct cat_event* cat_get_event(void)
{
struct cat_event* out = malloc(sizeof(struct cat_event));
SDL_Event e;
(void)SDL_PollEvent(&e);
if (e.type == SDL_QUIT) out->type = QUIT;
else if (e.type == SDL_KEYDOWN)
{
out->type = KEYDOWN;
out->key = (e.key.keysym.sym);
}
else if (e.type == SDL_KEYUP)
{
out->type = KEYUP;
out->key = (e.key.keysym.sym);
}
else if (e.type == SDL_MOUSEMOTION)
{
out->type = MOUSEMOVE;
out->mousex = e.motion.x;
out->mousey = e.motion.y;
}
else if (e.type == SDL_MOUSEBUTTONDOWN)
{
out->type = MOUSEDOWN;
out->mouse_button = e.button.button;
}
else if (e.type == SDL_MOUSEBUTTONUP)
{
out->type = MOUSEUP;
out->mouse_button = e.button.button;
}
else return NULL;
return out;
}
+54
View File
@@ -0,0 +1,54 @@
#include "cat_api.h"
#include <time.h>
#define NS_PER_TICK 30000000
void bye(void)
{
printf("bye!\n");
exit(0);
}
void process_input(void)
{
struct cat_event* e = cat_get_event();
if (e == NULL) return;
if (e->type == QUIT) bye();
else if (e->type == KEYDOWN) printf("keypress! %c\n", e->key);
else if (e->type == KEYUP) printf("key up! %c\n", e->key);
else if (e->type == MOUSEMOVE) printf("mouse move! (%d, %d)\n", e->mousex, e->mousey);
else if (e->type == MOUSEDOWN) printf("mouse down! %02x\n", e->mouse_button);
else if (e->type == MOUSEUP) printf("mouse up! %02x\n", e->mouse_button);
}
static long last_sec = 0;
static long last_nsec = 0;
void tick(void)
{
/* run every N milliseconds... nanoseconds? idk */
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
if (last_sec == 0) goto yes;
else if ((t.tv_sec - last_sec) > 0) goto yes;
else if ((t.tv_nsec - last_nsec) > NS_PER_TICK) goto yes;
else return;
yes: last_sec = t.tv_sec;
last_nsec = t.tv_nsec;
}
void game_loop(void)
{
process_input();
tick();
cat_render();
}
int main(int argc, char** argv)
{
cat_init();
cat_create_window(1920, 1080);
cat_fill(0, 1, 0, 0, screen_width - 1, screen_height - 1, 132, 155, 132);
while (1) game_loop();
return 0;
}
+6
View File
@@ -0,0 +1,6 @@
all:
if ! [ -d bin ]; then mkdir bin; fi
cc -o bin/cfhfg main.c -lSDL2
run: all
bin/cfhfg