#include #include #include #include #include #include #include #include #include #define FONT_WIDTH ( 9) #define FONT_HEIGHT (18) static unsigned int * * render_texture = NULL; static int * render_texture_w = NULL; static int * render_texture_h = NULL; static int render_texture_count = 0; static unsigned int * font = NULL; static unsigned int * mono = NULL; static int screen_width = 1800; static int screen_height = 900; static xcb_window_t window = 0; static xcb_gcontext_t context = 0; static xcb_pixmap_t pixmap = 0; static xcb_connection_t * connection = NULL; static xcb_screen_t * screen = NULL; static xcb_image_t * image = NULL; static unsigned int * framebuffer = NULL; static unsigned int * import_png (char * path, int * w, int * h) { unsigned int buffer [1024*1024] = { 0 }; unsigned int * data = NULL; png_image temporary = { 0 }; temporary.version = PNG_IMAGE_VERSION; if (! png_image_begin_read_from_file (& temporary, path)) printf ("PNG: image begin read from file fuck up!\n"); temporary.format = PNG_FORMAT_BGRA; if (! png_image_finish_read (& temporary, NULL, buffer, 0, NULL)) printf ("PNG: image finish read fuck up!\n"); if (w != NULL) * w = temporary.width; if (h != NULL) * h = temporary.height; if (buffer == NULL) printf ("PNG: empty buffer fuck up!\n"); png_image_free (& temporary); data = calloc (temporary.width * temporary.height, sizeof (* data)); if (data == NULL) printf ("PNG: empty data fuck up!\n"); memcpy (data, buffer, temporary.width * temporary.height * sizeof (* data)); return (data); } static void render_clean_up (void) { int i; printf ("Deinitializing graphical components...\n"); for (i = 0; i < render_texture_count; ++i) free (render_texture [i]); free (render_texture); free (font); free (mono); xcb_free_gc (connection, context); xcb_free_pixmap (connection, pixmap); xcb_destroy_window (connection, window); xcb_disconnect (connection); } extern int signal_x; extern int signal_y; extern int cursor_mode; extern int signal_mode; extern int engine_active; extern int window_width (void); extern int window_height (void); extern void render_sprite (int sprite, int x, int y, int u, int v, int width, int height); extern void render_string (char * string, int x, int y, int colour, char monospace); extern void engine_configure (void); extern void engine_synchronize (void); extern int sprite_import (char * path); extern int sprite_width (int index); extern int sprite_height (int index); int signal_x = 0; int signal_y = 0; int cursor_mode = 0; int signal_mode = 0; int engine_active = 0; int window_width (void) { return (screen_width); } int window_height (void) { return (screen_height); } void render_sprite (int sprite, int x, int y, int u, int v, int width, int height) { int sprite_x, sprite_y; width = (width < 0) ? -width : width; height = (height < 0) ? -height : height; if ((x < 0) || (y < 0) || (x > window_width () - width) || (y > window_height () - height)) { return; } for (sprite_y = 0; sprite_y < height; ++sprite_y) { for (sprite_x = 0; sprite_x < width; ++sprite_x) { int o = (sprite_y + y) * window_width () + (sprite_x + x); int s = (sprite_y + v) * sprite_width (sprite) + (sprite_x + u); framebuffer [o] = ((render_texture [sprite] [s] & 0XFF000000) < 0X04) ? framebuffer [o] : render_texture [sprite] [s]; } } } void render_string (char * string, int x, int y, int colour, char monospace) { /*Vector2 position = { 4, 4 }; Color new_tint = { 255, 255, 255, 255 }; position.x += x; position.y += y; new_tint.r = ((colour & 0XFF0000) >> 16) % 256; new_tint.g = ((colour & 0X00FF00) >> 8) % 256; new_tint.b = ((colour & 0X0000FF) >> 0) % 256; DrawTextPro ((monospace != 0) ? mono : font, string, position, dump, 0.0, 24, 6, new_tint); */ (void) string; (void) x; (void) y; (void) colour; (void) monospace; } void engine_configure (void) { unsigned int values [2] = { 0, XCB_EVENT_MASK_NO_EVENT | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_RESIZE_REDIRECT | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_POINTER_MOTION }; engine_active = 1; printf ("Initializing graphical components...\n"); font = import_png ("./sprite/font/font.png", NULL, NULL); mono = import_png ("./sprite/font/mono.png", NULL, NULL); connection = xcb_connect (NULL, NULL); screen = xcb_setup_roots_iterator (xcb_get_setup (connection)) . data; values [0] = screen -> black_pixel; window = xcb_generate_id (connection); context = xcb_generate_id (connection); pixmap = xcb_generate_id (connection); xcb_create_window (connection, screen -> root_depth, window, screen -> root, 0, 0, (uint16_t) window_width (), (uint16_t) window_height (), 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen -> root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, values); xcb_map_window (connection, window); xcb_change_property (connection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, sizeof ("-- Chads of Might & Magic --"), "-- Chads of Might & Magic --"); xcb_create_pixmap (connection, screen -> root_depth, pixmap, window, (uint16_t) window_width (), (uint16_t) window_height ()); xcb_create_gc (connection, context, pixmap, 0, NULL); xcb_flush (connection); atexit (render_clean_up); } void engine_synchronize (void) { xcb_generic_event_t * event = NULL; if (framebuffer != NULL) { image = xcb_image_create_native (connection, (uint16_t) screen_width, (uint16_t) screen_height, XCB_IMAGE_FORMAT_Z_PIXMAP, screen -> root_depth, framebuffer, (uint32_t) (screen_width * screen_height * (int32_t) sizeof (* framebuffer)), (uint8_t *) framebuffer); xcb_image_put (connection, pixmap, context, image, 0, 0, 0); xcb_image_destroy (image); xcb_copy_area (connection, pixmap, window, context, 0, 0, 0, 0, (uint16_t) screen_width, (uint16_t) screen_height); } event = xcb_wait_for_event (connection); if (event == NULL) { return; } else if ((event->response_type & 127) == XCB_EXPOSE) { xcb_flush (connection); } else if ((event->response_type & 127) == XCB_KEY_PRESS) { printf ("Key: %i\n", ((xcb_key_press_event_t *) event)->detail); switch (((xcb_key_press_event_t *) event)->detail) { case 24: engine_active = 0; break; case 25: cursor_mode = 4; break; case 26: cursor_mode = 5; break; case 27: cursor_mode = 6; break; case 28: cursor_mode = 7; break; default: break; } } else if ((event->response_type & 127) == XCB_BUTTON_PRESS) { xcb_button_press_event_t * button_press_event = (xcb_button_press_event_t *) event; cursor_mode = button_press_event->detail; } else if ((event->response_type & 127) == XCB_MOTION_NOTIFY) { xcb_motion_notify_event_t * button_press_event = (xcb_motion_notify_event_t *) event; signal_x = button_press_event->event_x; signal_y = button_press_event->event_y; } free (event); framebuffer = calloc ((size_t) (screen_width * screen_height), sizeof (* framebuffer)); signal_mode = 0; } int import_sprite (char * path) { ++render_texture_count; render_texture = realloc (render_texture, (unsigned long int) render_texture_count * sizeof (* render_texture)); render_texture_w = realloc (render_texture_w, (unsigned long int) render_texture_count * sizeof (* render_texture_w)); render_texture_h = realloc (render_texture_h, (unsigned long int) render_texture_count * sizeof (* render_texture_h)); render_texture [render_texture_count - 1] = import_png (path, & render_texture_w [render_texture_count - 1], & render_texture_h [render_texture_count - 1]); if (render_texture [render_texture_count - 1] == NULL) { printf ("\033[1;31m%3i : '%60s';\033[0m\n", render_texture_count - 1, path); } return (render_texture_count - 1); } int sprite_width (int index) { return (render_texture_w [index]); } int sprite_height (int index) { return (render_texture_h [index]); }