156 lines
3.9 KiB
C
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;
|
|
}
|