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