diff options
Diffstat (limited to 'plat.c')
-rw-r--r-- | plat.c | 449 |
1 files changed, 46 insertions, 403 deletions
@@ -1,82 +1,66 @@ #include "plat.h" #include "config.h" -extern void prog_init(void*); -extern void prog_update(void); -extern void prog_deinit(void); - #ifdef plat_posix #define _POSIX_SOURCE #define _GNU_SOURCE -#include "std_printers.c" -#include <dirent.h> -#include <fcntl.h> -#include <signal.h> +#include <stdarg.h> #include <stdio.h> +#include <unistd.h> #include <stdlib.h> +#include <dirent.h> #include <string.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <time.h> -#include <unistd.h> -static clockid_t global_clock; -static unsigned long global_freq; +extern int fileno(FILE*); -void init_timer(void) { - struct timespec ts; +void print(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vfprintf(stdout, fmt, args); + va_end(args); +} - global_clock = CLOCK_REALTIME; - global_freq = 1000000000; +void print_err(const char* fmt, ...) { + va_list args; + va_start(args, fmt); -#if defined(_POSIX_MONOTONIC_CLOCK) - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { - global_clock = CLOCK_MONOTONIC; + if (isatty(fileno(stderr))) { + fprintf(stderr, "\033[31;31m"); } -#endif -} -static unsigned long get_timer() { - struct timespec ts; + vfprintf(stderr, fmt, args); - clock_gettime(global_clock, &ts); - return - (unsigned long)ts.tv_sec * global_freq + - (unsigned long)ts.tv_nsec; -} + if (isatty(fileno(stderr))) { + fprintf(stderr, "\033[0m"); + } -unsigned long get_current_time() { - return get_timer(); + va_end(args); } -void sleep_ns(unsigned long ns) { - struct timespec t = { 0 }; - t.tv_nsec = ns; - nanosleep(&t, &t); -} +void print_war(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + + if (isatty(fileno(stderr))) { + fprintf(stderr, "\033[31;35m"); + } -unsigned char* load_binary(const char* n, int* size) { - FILE* f; - int s; - void* b; - f = fopen(n, "r"); - if (!f) { - print_err("Failed to open %s.\n", n); - pbreak(error_file_not_found); - return 0; + vfprintf(stderr, fmt, args); + + if (isatty(fileno(stderr))) { + fprintf(stderr, "\033[0m"); } - fseek(f, 0, SEEK_END); - s = ftell(f); - rewind(f); - b = malloc(s); - s = fread(b, 1, s, f); - if (size) *size = s; - return b; + + va_end(args); } -void free_file(void* p) { - free(p); +void pbreak(Error code) { +#if defined(DEBUG) && defined(plat_x86) + __asm__("int3;"); + (void)code; +#else + exit(code); +#endif } void iter_dir(const char* path, Dir_Iter fn, void* u) { @@ -104,359 +88,18 @@ void iter_dir(const char* path, Dir_Iter fn, void* u) { else fn(u, buf); } + closedir(di); } -#endif - -#ifdef plat_x11 - -#define Font RX11Font -#include <stdlib.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#undef RX11Font - -#include "rcache.h" - -#define txt_buf_max 32 - -struct { - int w, h, run; - Display* d; - Window wi; - GC gc; - XImage* bb; - Colour* bp, * fb; - Atom wm_p, wm_d; - char txt_buf[txt_buf_max]; - char raw_buf[txt_buf_max]; - int txt_len; - int mx, my, scrx, scry; -} app; -static MBtn mheld_btns[mbtn_count]; -static MBtn mpressed_btns[mbtn_count]; -static MBtn mreleased_btns[mbtn_count]; - -static void reset_keys(void) { - int i; - for (i = 0; i < mbtn_count; i++) { - mpressed_btns[i] = 0; - mreleased_btns[i] = 0; - } -} - -void init_app_render(const XWindowAttributes* wa) { - Colour* p, * fb; - Display* d; - XImage* bb; - int w, h; - d = app.d; - w = app.w; - h = app.h; - p = (Colour*)malloc(sizeof *p * w * h); - fb = (Colour*)malloc(sizeof *fb * w * h); - bb = app.bb; - if (bb) { - XDestroyImage(bb); - } - if (!p) { - print_err("Out of memory.\n"); - pbreak(error_out_of_memory); - } - bb = XCreateImage( - d, - wa->visual, - wa->depth, - ZPixmap, - 0, - (char*)p, - w, - h, - 32, - w * sizeof *p - ); - if (!bb) { - print_err("Failed to create X11 backbuffer.\n"); - pbreak(error_platform_error); - } - app.bp = p; - app.fb = fb; - app.bb = bb; -} - -void init_app(void) { - Window w, r; - Display* d; - GC gc; - unsigned rm, bm; - XWindowAttributes wa; - app.run = 0; - d = XOpenDisplay(0); - if (!d) { - print_err("Failed to open X11 display.\n"); - pbreak(error_platform_error); - return; - } - r = DefaultRootWindow(d); - app.wm_p = XInternAtom( - d, - "WM_PROTOCOLS", - 0 - ); - app.wm_d = XInternAtom( - d, - "WM_DELETE_WINDOW", - 0 - ); - w = XCreateSimpleWindow( - d, - r, - 0, - 0, - default_window_w, - default_window_h, - 0, - WhitePixel(d, 0), - BlackPixel(d, 0) - ); - XSetWMProtocols(d, w, &app.wm_d, 1); - XStoreName(d, w, app_name); - XSelectInput( - d, - w, - ExposureMask | - KeyPressMask | - KeyReleaseMask | - PointerMotionMask | - ButtonPressMask | - ButtonReleaseMask - ); - XClearWindow(d, w); - XMapRaised(d, w); - gc = XCreateGC(d, w, 0, 0); - if (!gc) { - print_err("Failed to create graphics context.\n"); - pbreak(error_platform_error); - return; - } - XGetWindowAttributes(d, w, &wa); - if (wa.depth != 24 && wa.depth != 32) { - print_err("Only true colour displays are supported.\n"); - pbreak(error_platform_error); - } - rm = wa.visual->red_mask & 0x1000000; - bm = wa.visual->blue_mask & 0xffffff; - if ((rm == 0xff && bm == 0xff0000)) { - print_war("Detected BGR. Colours will look fucked.\n"); - } - app.d = d; - app.gc = gc; - app.w = wa.width; - app.h = wa.height; - app.run = 1; - app.wi = w; - app.bb = 0; - init_app_render(&wa); -} - -void deinit_app(void) { - XDestroyWindow(app.d, app.wi); - XDestroyImage(app.bb); - XCloseDisplay(app.d); -} +extern int prog_main(void*); -void update_events(void) { - XWindowAttributes wa; - Display* d; - Window w; - XEvent e; - Rectangle r; - int mb; - d = app.d; - w = app.wi; - reset_keys(); - app.scrx = app.scry = 0; - while (XPending(d)) { - XNextEvent(d, &e); - switch (e.type) { - case ClientMessage: - if ( - (Atom)e.xclient.data.l[0] == - app.wm_d - ) { - app.run = 0; - } - break; - case Expose: - XGetWindowAttributes(d, w, &wa); - if ( - wa.width != app.w || - wa.height != app.h - ) { - app.w = wa.width; - app.h = wa.height; - init_app_render(&wa); - } - r.x = 0; - r.y = 0; - r.w = app.w; - r.h = app.h; - rc_invalidate(&r); - break; - case MotionNotify: - app.mx = e.xmotion.x; - app.my = e.xmotion.y; - break; - case ButtonPress: - switch (e.xbutton.button) { - case 1: - case 2: - case 3: - mb = e.xbutton.button - 1; - mheld_btns[mb] = 1; - mpressed_btns[mb] = 1; - break; - } - break; - case ButtonRelease: - switch (e.xbutton.button) { - case 1: - case 2: - case 3: - mb = e.xbutton.button - 1; - mheld_btns[mb] = 0; - mreleased_btns[mb] = 1; - break; - case 4: - app.scry--; - break; - case 5: - app.scry++; - break; - case 6: - app.scrx--; - break; - case 7: - app.scrx++; - break; - } - break; - default: - break; - } - } -} - -int main(int argc, const char** argv) { +int main() { + int r; void* mem; - unsigned long now, next; - long ts; - (void)argc; - (void)argv; - init_timer(); mem = malloc(memory_size); - if (!mem) { - print_err("Out of memory.\n"); - return error_out_of_memory; - } - init_app(); - next = get_current_time(); - prog_init(mem); - while (app.run) { - now = get_current_time(); - while (now >= next) { - update_events(); - prog_update(); - next += ms_per_frame * 1000000; - } - ts = next - now; - if (ts > 0) - sleep_ns(ts); - } - prog_deinit(); - deinit_app(); + r = prog_main(mem); free(mem); - return 0; -} - -void plat_present( - int x, - int y, - int w, - int h -) { - const Colour* src; - Colour* dst; - int i, j; - int ex, ey; - int s; - ex = x + w; - ey = y + h; - dst = app.bp + x + y * app.w; - src = app.fb + x + y * app.w; - s = app.w - w; - for (j = y; j < ey; j++) { - for (i = x; i < ex; i++) { - dst->r = src->b; - dst->g = src->g; - dst->b = src->r; - dst->a = src->a; - dst++; - src++; - } - dst += s; - src += s; - } - XPutImage( - app.d, - app.wi, - app.gc, - app.bb, - x, y, - x, y, - w, h - ); -} - -Colour* get_fb(void) { - return app.fb; -} - -int get_render_w(void) { - return app.w; -} - -int get_render_h(void) { - return app.h; -} - -int get_mouse_x(void) { - return app.mx; -} - -int get_mouse_y(void) { - return app.my; -} - -int get_mscroll_x(void) { - return app.scrx; -} - -int get_mscroll_y(void) { - return app.scry; -} - -int mbtn_pressed(MBtn btn) { - return mheld_btns[btn]; -} - -int mbtn_just_pressed(MBtn btn) { - return mpressed_btns[btn]; -} - -int mbtn_just_released(MBtn btn) { - return mreleased_btns[btn]; + return r; } #endif - |