Files
cat_frend_help_friend_good/cat_api.h
T
2026-04-17 17:42:07 -04:00

156 lines
3.9 KiB
C

#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;
}