/* * libcaca Colour ASCII-Art library * Copyright (c) 2002-2012 Sam Hocevar * All Rights Reserved * * This library is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What the Fuck You Want * to Public License, Version 2, as published by Sam Hocevar. See * http://www.wtfpl.net/ for more details. */ /* * This file contains glue code for applications using the pre-1.0 * libcaca API. */ #include "config.h" #if !defined(__KERNEL__) # include #endif #include "caca0.h" /* These variables are needed to emulate old non-thread safe behaviour */ caca_canvas_t *__caca0_cv = NULL; caca_display_t *__caca0_dp = NULL; unsigned char __caca0_fg = CACA_LIGHTGRAY; unsigned char __caca0_bg = CACA_BLACK; char __caca0_utf8[2] = " "; /* These functions are needed, too */ int __caca0_init(void); void __caca0_end(void); unsigned int __caca0_get_event(unsigned int, int); unsigned int __caca0_sqrt(unsigned int); int __caca0_get_feature(int); void __caca0_set_feature(int); char const *__caca0_get_feature_name(int); caca_canvas_t *__caca0_load_sprite(char const *); caca_dither_t *__caca0_create_bitmap(unsigned int, unsigned int, unsigned int, unsigned int, unsigned long int, unsigned long int, unsigned long int, unsigned long int); void __caca0_free_bitmap(caca_dither_t *); extern char const *__caca0_get_color_name(unsigned char); /* Emulation functions */ int __caca0_init(void) { __caca0_cv = caca_create_canvas(0, 0); if(!__caca0_cv) return -1; __caca0_dp = caca_create_display(__caca0_cv); if(!__caca0_dp) { caca_free_canvas(__caca0_cv); __caca0_cv = NULL; return -1; } __caca0_fg = CACA_LIGHTGRAY; __caca0_bg = CACA_BLACK; return 0; } void __caca0_end(void) { caca_free_display(__caca0_dp); __caca0_dp = NULL; caca_free_canvas(__caca0_cv); __caca0_cv = NULL; } unsigned int __caca0_get_event(unsigned int m, int t) { caca_event_t ev; int ret; ret = caca_get_event(__caca0_dp, (m >> 24) & 0x7f, &ev, t); if(!ret) return 0x00000000; switch(caca_get_event_type(&ev)) { case CACA_EVENT_KEY_PRESS: return 0x01000000 | caca_get_event_key_ch(&ev); case CACA_EVENT_KEY_RELEASE: return 0x02000000 | caca_get_event_key_ch(&ev); case CACA_EVENT_MOUSE_PRESS: return 0x04000000 | caca_get_event_mouse_button(&ev); case CACA_EVENT_MOUSE_RELEASE: return 0x08000000 | caca_get_event_mouse_button(&ev); case CACA_EVENT_MOUSE_MOTION: return 0x10000000 | ((caca_get_event_mouse_x(&ev) & 0xfff) << 12) | (caca_get_event_mouse_y(&ev) & 0xfff); case CACA_EVENT_RESIZE: return 0x20000000; default: break; } return 0x00000000; } unsigned int __caca0_sqrt(unsigned int a) { if(a == 0) return 0; if(a < 1000000000) { unsigned int x = a < 10 ? 1 : a < 1000 ? 10 : a < 100000 ? 100 : a < 10000000 ? 1000 : 10000; /* Newton's method. Three iterations would be more than enough. */ x = (x * x + a) / x / 2; x = (x * x + a) / x / 2; x = (x * x + a) / x / 2; x = (x * x + a) / x / 2; return x; } return 2 * __caca0_sqrt(a / 4); } static char const *features[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "16", "full16", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "none", "prefilter", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "none", "ordered2", "ordered4", "ordered8", "random" }; static caca_dither_t **bitmaps = NULL; static unsigned int nbitmaps = 0; static int background = 0x12; static int antialiasing = 0x22; static int dithering = 0x33; int __caca0_get_feature(int feature) { if(feature == 0x10) return background; if(feature == 0x20) return antialiasing; if(feature == 0x30) return dithering; return 0xffff; /* CACA_FEATURE_UNKNOWN */ } void __caca0_set_feature(int feature) { unsigned int i; switch(feature) { case 0x10: feature = 0x12; /* CACA_BACKGROUND_SOLID */ case 0x11: case 0x12: background = feature; for(i = 0; i < nbitmaps; i++) caca_set_dither_color(bitmaps[i], features[feature]); break; case 0x20: feature = 0x22; /* CACA_ANTIALIASING_PREFILTER */ case 0x21: case 0x22: antialiasing = feature; for(i = 0; i < nbitmaps; i++) caca_set_dither_antialias(bitmaps[i], features[feature]); break; case 0x30: feature = 0x33; /* CACA_DITHERING_ORDERED4 */ case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: dithering = feature; for(i = 0; i < nbitmaps; i++) caca_set_dither_algorithm(bitmaps[i], features[feature]); break; } } char const *__caca0_get_feature_name(int feature) { switch(feature) { case 0x11: return "black background"; case 0x12: return "solid background"; case 0x21: return "no antialiasing"; case 0x22: return "prefilter antialiasing"; case 0x31: return "no dithering"; case 0x32: return "2x2 ordered dithering"; case 0x33: return "4x4 ordered dithering"; case 0x34: return "8x8 ordered dithering"; case 0x35: return "random dithering"; default: return "unknown"; } } caca_canvas_t *__caca0_load_sprite(char const *file) { caca_canvas_t *cv; cv = caca_create_canvas(0, 0);; if(caca_import_canvas_from_file(cv, file, "") < 0) { caca_free_canvas(cv); return NULL; } return cv; } caca_dither_t *__caca0_create_bitmap(unsigned int bpp, unsigned int w, unsigned int h, unsigned int pitch, unsigned long int r, unsigned long int g, unsigned long int b, unsigned long int a) { caca_dither_t *d; d = caca_create_dither(bpp, w, h, pitch, r, g, b, a); if(!d) return NULL; caca_set_dither_color(d, features[background]); caca_set_dither_antialias(d, features[antialiasing]); caca_set_dither_algorithm(d, features[dithering]); /* Store bitmap in our list */ nbitmaps++; bitmaps = realloc(bitmaps, nbitmaps * (sizeof(caca_dither_t *))); bitmaps[nbitmaps - 1] = d; return d; } void __caca0_free_bitmap(caca_dither_t *d) { unsigned int i, found = 0; caca_free_dither(d); /* Remove bitmap from our list */ for(i = 0; i + 1 < nbitmaps; i++) { if(bitmaps[i] == d) found = 1; if(found) bitmaps[i] = bitmaps[i + 1]; } nbitmaps--; } char const *__caca0_get_color_name(unsigned char color) { static char const *color_names[] = { "black", "blue", "green", "cyan", "red", "magenta", "brown", "light gray", "dark gray", "light blue", "light green", "light cyan", "light red", "light magenta", "yellow", "white", }; if(color > 15) return "unknown"; return color_names[(unsigned int)color]; }