environment variables handling. Replaced that with three per-bitmap
functions: cucul_set_bitmap_antialias(), cucul_set_bitmap_color() and
cucul_set_bitmap_dithering().
* Added cucul_set_bitmap_brightness() and cucul_set_bitmap_contrast()
prototypes (but did not implement them yet).
* Added cucul_set_bitmap_charset() to choose what characters are going
to be used for the bitmap rendering.
* Removed the now useless cucul_get_feature(), cucul_set_feature() etc.
tags/v0.99.beta14
| @@ -30,8 +30,8 @@ | |||||
| * using the conio library, and on Windows systems using either slang or | * using the conio library, and on Windows systems using either slang or | ||||
| * ncurses (through Cygwin emulation) or conio. There is also a native X11 | * ncurses (through Cygwin emulation) or conio. There is also a native X11 | ||||
| * driver, and an OpenGL driver (through freeglut) that does not require a | * driver, and an OpenGL driver (through freeglut) that does not require a | ||||
| * text terminal. For machines without a screen, and with a valid tcp stack, | |||||
| * the network driver (BSD sockets) should perfectly fit your needs. | |||||
| * text terminal. For machines without a screen, the raw driver can be used | |||||
| * to send the output to another machine, using for instance cacaserver. | |||||
| * | * | ||||
| * \e libcaca is free software, released under the Do What The Fuck You | * \e libcaca is free software, released under the Do What The Fuck You | ||||
| * Want To Public License. This ensures that no one, not even the \e libcaca | * Want To Public License. This ensures that no one, not even the \e libcaca | ||||
| @@ -51,8 +51,8 @@ | |||||
| * \section env Environment variables | * \section env Environment variables | ||||
| * | * | ||||
| * Some environment variables can be used to change the behaviour of | * Some environment variables can be used to change the behaviour of | ||||
| * \e libcaca or \e libcucul without having to modify the program which | |||||
| * uses them. These variables are: | |||||
| * \e libcaca without having to modify the program which uses them. These | |||||
| * variables are: | |||||
| * | * | ||||
| * \li \b CACA_DRIVER: set the backend video driver. In order of preference: | * \li \b CACA_DRIVER: set the backend video driver. In order of preference: | ||||
| * - \c conio uses the DOS conio.h interface. | * - \c conio uses the DOS conio.h interface. | ||||
| @@ -60,30 +60,8 @@ | |||||
| * - \c slang uses the S-Lang library. | * - \c slang uses the S-Lang library. | ||||
| * - \c x11 uses the native X11 driver. | * - \c x11 uses the native X11 driver. | ||||
| * - \c gl uses freeglut and opengl libraries. | * - \c gl uses freeglut and opengl libraries. | ||||
| * - \c network uses BSD sockets calls. | |||||
| * | |||||
| * \li \b CUCUL_BACKGROUND: set the background type. | |||||
| * - \c solid uses solid coloured backgrounds for all characters. This | |||||
| * feature does not work with all terminal emulators. This is the | |||||
| * default choice. | |||||
| * - \c black uses only black backgrounds to render characters. | |||||
| * | |||||
| * \li \b CUCUL_ANTIALIASING: set the antialiasing mode. Antialiasing | |||||
| * smoothens the rendered image and avoids the commonly seen staircase | |||||
| * effect. | |||||
| * - \c none disables antialiasing. | |||||
| * - \c prefilter uses a simple prefilter antialiasing method. This is | |||||
| * the default choice. | |||||
| * | |||||
| * \li \b CUCUL_DITHERING: set the dithering mode. Dithering is necessary | |||||
| * when rendering a picture that has more colours than the usually | |||||
| * available palette. | |||||
| * - \c none disables dithering. | |||||
| * - \c ordered2 uses a 2x2 Bayer matrix for dithering. | |||||
| * - \c ordered4 uses a 4x4 Bayer matrix for dithering. This is the | |||||
| * default choice. | |||||
| * - \c ordered8 uses a 8x8 Bayer matrix for dithering. | |||||
| * - \c random uses random dithering. | |||||
| * - \c raw outputs to the standard output instead of rendering the | |||||
| * canvas. This is can be used together with cacaserver. | |||||
| * | * | ||||
| * \li \b CACA_GEOMETRY: set the video display size. The format of this | * \li \b CACA_GEOMETRY: set the video display size. The format of this | ||||
| * variable must be XxY, with X and Y being integer values. This option | * variable must be XxY, with X and Y being integer values. This option | ||||
| @@ -28,8 +28,6 @@ | |||||
| #include "cucul.h" | #include "cucul.h" | ||||
| #include "cucul_internals.h" | #include "cucul_internals.h" | ||||
| static void cucul_read_environment(cucul_t *); | |||||
| /** \brief Initialise a \e libcucul canvas. | /** \brief Initialise a \e libcucul canvas. | ||||
| * | * | ||||
| * This function initialises internal \e libcucul structures and the backend | * This function initialises internal \e libcucul structures and the backend | ||||
| @@ -48,8 +46,6 @@ cucul_t * cucul_create(unsigned int width, unsigned int height) | |||||
| { | { | ||||
| cucul_t *qq = malloc(sizeof(cucul_t)); | cucul_t *qq = malloc(sizeof(cucul_t)); | ||||
| cucul_read_environment(qq); | |||||
| qq->refcount = 0; | qq->refcount = 0; | ||||
| qq->fgcolor = CUCUL_COLOR_LIGHTGRAY; | qq->fgcolor = CUCUL_COLOR_LIGHTGRAY; | ||||
| @@ -201,103 +197,6 @@ char const *cucul_get_color_name(enum cucul_color color) | |||||
| return color_names[color]; | return color_names[color]; | ||||
| } | } | ||||
| /** \brief Get the current value of a feature. | |||||
| * | |||||
| * This function retrieves the value of an internal \e libcucul feature. A | |||||
| * generic feature value is expected, such as CUCUL_ANTIALIASING. | |||||
| * | |||||
| * \param feature The requested feature. | |||||
| * \return The current value of the feature or CUCUL_FEATURE_UNKNOWN if an | |||||
| * error occurred.. | |||||
| */ | |||||
| enum cucul_feature cucul_get_feature(cucul_t *qq, enum cucul_feature feature) | |||||
| { | |||||
| switch(feature) | |||||
| { | |||||
| case CUCUL_BACKGROUND: | |||||
| return qq->background; | |||||
| case CUCUL_ANTIALIASING: | |||||
| return qq->antialiasing; | |||||
| case CUCUL_DITHERING: | |||||
| return qq->dithering; | |||||
| default: | |||||
| return CUCUL_FEATURE_UNKNOWN; | |||||
| } | |||||
| } | |||||
| /** \brief Set a feature. | |||||
| * | |||||
| * This function sets an internal \e libcucul feature such as the antialiasing | |||||
| * or dithering modes. If a specific feature such as CUCUL_DITHERING_RANDOM, | |||||
| * cucul_set_feature() will set it immediately. If a generic feature is given | |||||
| * instead, such as CUCUL_DITHERING, the default value will be used instead. | |||||
| * | |||||
| * \param feature The requested feature. | |||||
| */ | |||||
| void cucul_set_feature(cucul_t *qq, enum cucul_feature feature) | |||||
| { | |||||
| switch(feature) | |||||
| { | |||||
| case CUCUL_BACKGROUND: | |||||
| feature = CUCUL_BACKGROUND_SOLID; | |||||
| case CUCUL_BACKGROUND_BLACK: | |||||
| case CUCUL_BACKGROUND_SOLID: | |||||
| qq->background = feature; | |||||
| break; | |||||
| case CUCUL_ANTIALIASING: | |||||
| feature = CUCUL_ANTIALIASING_PREFILTER; | |||||
| case CUCUL_ANTIALIASING_NONE: | |||||
| case CUCUL_ANTIALIASING_PREFILTER: | |||||
| qq->antialiasing = feature; | |||||
| break; | |||||
| case CUCUL_DITHERING: | |||||
| feature = CUCUL_DITHERING_FSTEIN; | |||||
| case CUCUL_DITHERING_NONE: | |||||
| case CUCUL_DITHERING_ORDERED2: | |||||
| case CUCUL_DITHERING_ORDERED4: | |||||
| case CUCUL_DITHERING_ORDERED8: | |||||
| case CUCUL_DITHERING_RANDOM: | |||||
| case CUCUL_DITHERING_FSTEIN: | |||||
| qq->dithering = feature; | |||||
| break; | |||||
| case CUCUL_FEATURE_UNKNOWN: | |||||
| break; | |||||
| } | |||||
| } | |||||
| /** \brief Translate a feature value into the feature's name. | |||||
| * | |||||
| * This function translates a cucul_feature enum into a human-readable | |||||
| * description string of the associated feature. | |||||
| * | |||||
| * \param feature The feature value. | |||||
| * \return A static string containing the feature's name. | |||||
| */ | |||||
| char const *cucul_get_feature_name(enum cucul_feature feature) | |||||
| { | |||||
| switch(feature) | |||||
| { | |||||
| case CUCUL_BACKGROUND_BLACK: return "black background"; | |||||
| case CUCUL_BACKGROUND_SOLID: return "solid background"; | |||||
| case CUCUL_ANTIALIASING_NONE: return "no antialiasing"; | |||||
| case CUCUL_ANTIALIASING_PREFILTER: return "prefilter antialiasing"; | |||||
| case CUCUL_DITHERING_NONE: return "no dithering"; | |||||
| case CUCUL_DITHERING_ORDERED2: return "2x2 ordered dithering"; | |||||
| case CUCUL_DITHERING_ORDERED4: return "4x4 ordered dithering"; | |||||
| case CUCUL_DITHERING_ORDERED8: return "8x8 ordered dithering"; | |||||
| case CUCUL_DITHERING_RANDOM: return "random dithering"; | |||||
| case CUCUL_DITHERING_FSTEIN: return "Floyd-Steinberg dithering"; | |||||
| default: return "unknown"; | |||||
| } | |||||
| } | |||||
| /** \brief Uninitialise \e libcucul. | /** \brief Uninitialise \e libcucul. | ||||
| * | * | ||||
| * This function frees all resources allocated by cucul_create(). After | * This function frees all resources allocated by cucul_create(). After | ||||
| @@ -380,52 +279,6 @@ void cucul_free_export(struct cucul_export *ex) | |||||
| * XXX: The following functions are local. | * XXX: The following functions are local. | ||||
| */ | */ | ||||
| static void cucul_read_environment(cucul_t * qq) | |||||
| { | |||||
| /* FIXME: if strcasecmp isn't available, use strcmp */ | |||||
| #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | |||||
| char *var; | |||||
| #endif | |||||
| cucul_set_feature(qq, CUCUL_BACKGROUND); | |||||
| cucul_set_feature(qq, CUCUL_ANTIALIASING); | |||||
| cucul_set_feature(qq, CUCUL_DITHERING); | |||||
| #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | |||||
| if((var = getenv("CUCUL_BACKGROUND")) && *var) | |||||
| { | |||||
| if(!strcasecmp("black", var)) | |||||
| cucul_set_feature(qq, CUCUL_BACKGROUND_BLACK); | |||||
| else if(!strcasecmp("solid", var)) | |||||
| cucul_set_feature(qq, CUCUL_BACKGROUND_SOLID); | |||||
| } | |||||
| if((var = getenv("CUCUL_ANTIALIASING")) && *var) | |||||
| { | |||||
| if(!strcasecmp("none", var)) | |||||
| cucul_set_feature(qq, CUCUL_ANTIALIASING_NONE); | |||||
| else if(!strcasecmp("prefilter", var)) | |||||
| cucul_set_feature(qq, CUCUL_ANTIALIASING_PREFILTER); | |||||
| } | |||||
| if((var = getenv("CUCUL_DITHERING")) && *var) | |||||
| { | |||||
| if(!strcasecmp("none", var)) | |||||
| cucul_set_feature(qq, CUCUL_DITHERING_NONE); | |||||
| else if(!strcasecmp("ordered2", var)) | |||||
| cucul_set_feature(qq, CUCUL_DITHERING_ORDERED2); | |||||
| else if(!strcasecmp("ordered4", var)) | |||||
| cucul_set_feature(qq, CUCUL_DITHERING_ORDERED4); | |||||
| else if(!strcasecmp("ordered8", var)) | |||||
| cucul_set_feature(qq, CUCUL_DITHERING_ORDERED8); | |||||
| else if(!strcasecmp("random", var)) | |||||
| cucul_set_feature(qq, CUCUL_DITHERING_RANDOM); | |||||
| else if(!strcasecmp("fstein", var)) | |||||
| cucul_set_feature(qq, CUCUL_DITHERING_FSTEIN); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| void _cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height) | void _cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height) | ||||
| { | { | ||||
| unsigned int x, y, old_width, old_height, new_size, old_size; | unsigned int x, y, old_width, old_height, new_size, old_size; | ||||
| @@ -34,68 +34,27 @@ extern "C" | |||||
| */ | */ | ||||
| enum cucul_color | enum cucul_color | ||||
| { | { | ||||
| CUCUL_COLOR_BLACK = 0, /**< The colour index for black. */ | |||||
| CUCUL_COLOR_BLUE = 1, /**< The colour index for blue. */ | |||||
| CUCUL_COLOR_GREEN = 2, /**< The colour index for green. */ | |||||
| CUCUL_COLOR_CYAN = 3, /**< The colour index for cyan. */ | |||||
| CUCUL_COLOR_RED = 4, /**< The colour index for red. */ | |||||
| CUCUL_COLOR_MAGENTA = 5, /**< The colour index for magenta. */ | |||||
| CUCUL_COLOR_BROWN = 6, /**< The colour index for brown. */ | |||||
| CUCUL_COLOR_LIGHTGRAY = 7, /**< The colour index for light gray. */ | |||||
| CUCUL_COLOR_DARKGRAY = 8, /**< The colour index for dark gray. */ | |||||
| CUCUL_COLOR_LIGHTBLUE = 9, /**< The colour index for blue. */ | |||||
| CUCUL_COLOR_LIGHTGREEN = 10, /**< The colour index for light green. */ | |||||
| CUCUL_COLOR_LIGHTCYAN = 11, /**< The colour index for light cyan. */ | |||||
| CUCUL_COLOR_LIGHTRED = 12, /**< The colour index for light red. */ | |||||
| CUCUL_COLOR_LIGHTMAGENTA = 13, /**< The colour index for light magenta. */ | |||||
| CUCUL_COLOR_YELLOW = 14, /**< The colour index for yellow. */ | |||||
| CUCUL_COLOR_WHITE = 15 /**< The colour index for white. */ | |||||
| CUCUL_COLOR_BLACK = 0x0, /**< The colour index for black. */ | |||||
| CUCUL_COLOR_BLUE = 0x1, /**< The colour index for blue. */ | |||||
| CUCUL_COLOR_GREEN = 0x2, /**< The colour index for green. */ | |||||
| CUCUL_COLOR_CYAN = 0x3, /**< The colour index for cyan. */ | |||||
| CUCUL_COLOR_RED = 0x4, /**< The colour index for red. */ | |||||
| CUCUL_COLOR_MAGENTA = 0x5, /**< The colour index for magenta. */ | |||||
| CUCUL_COLOR_BROWN = 0x6, /**< The colour index for brown. */ | |||||
| CUCUL_COLOR_LIGHTGRAY = 0x7, /**< The colour index for light gray. */ | |||||
| CUCUL_COLOR_DARKGRAY = 0x8, /**< The colour index for dark gray. */ | |||||
| CUCUL_COLOR_LIGHTBLUE = 0x9, /**< The colour index for blue. */ | |||||
| CUCUL_COLOR_LIGHTGREEN = 0xa, /**< The colour index for light green. */ | |||||
| CUCUL_COLOR_LIGHTCYAN = 0xb, /**< The colour index for light cyan. */ | |||||
| CUCUL_COLOR_LIGHTRED = 0xc, /**< The colour index for light red. */ | |||||
| CUCUL_COLOR_LIGHTMAGENTA = 0xd, /**< The colour index for light magenta. */ | |||||
| CUCUL_COLOR_YELLOW = 0xe, /**< The colour index for yellow. */ | |||||
| CUCUL_COLOR_WHITE = 0xf, /**< The colour index for white. */ | |||||
| CUCUL_COLOR_TRANSPARENT = 0xfe, /**< The transparent colour. */ | |||||
| CUCUL_COLOR_DEFAULT = 0xff, /**< The output driver's default colour. */ | |||||
| }; | }; | ||||
| /** \brief Internal features. | |||||
| * | |||||
| * Internal libcaca features such as the rendering method or the dithering | |||||
| * mode. | |||||
| */ | |||||
| enum cucul_feature | |||||
| { | |||||
| CUCUL_BACKGROUND = 0x10, /**< Properties of background characters. */ | |||||
| CUCUL_BACKGROUND_BLACK = 0x11, /**< Draw only black backgrounds. */ | |||||
| CUCUL_BACKGROUND_SOLID = 0x12, /**< Draw coloured solid backgorunds. */ | |||||
| #define CUCUL_BACKGROUND_MIN 0x11 /**< First background property */ | |||||
| #define CUCUL_BACKGROUND_MAX 0x12 /**< Last background property */ | |||||
| CUCUL_ANTIALIASING = 0x20, /**< Antialiasing features. */ | |||||
| CUCUL_ANTIALIASING_NONE = 0x21, /**< No antialiasing. */ | |||||
| CUCUL_ANTIALIASING_PREFILTER = 0x22, /**< Prefilter antialiasing. */ | |||||
| #define CUCUL_ANTIALIASING_MIN 0x21 /**< First antialiasing feature. */ | |||||
| #define CUCUL_ANTIALIASING_MAX 0x22 /**< Last antialiasing feature. */ | |||||
| CUCUL_DITHERING = 0x30, /**< Dithering methods */ | |||||
| CUCUL_DITHERING_NONE = 0x31, /**< No dithering. */ | |||||
| CUCUL_DITHERING_ORDERED2 = 0x32, /**< Ordered 2x2 Bayer dithering. */ | |||||
| CUCUL_DITHERING_ORDERED4 = 0x33, /**< Ordered 4x4 Bayer dithering. */ | |||||
| CUCUL_DITHERING_ORDERED8 = 0x34, /**< Ordered 8x8 Bayer dithering. */ | |||||
| CUCUL_DITHERING_RANDOM = 0x35, /**< Random dithering. */ | |||||
| CUCUL_DITHERING_FSTEIN = 0x36, /**< Floyd-Steinberg dithering. */ | |||||
| #define CUCUL_DITHERING_MIN 0x31 /**< First dithering feature. */ | |||||
| #define CUCUL_DITHERING_MAX 0x36 /**< Last dithering feature. */ | |||||
| CUCUL_FEATURE_UNKNOWN = 0xffff /**< Unknown feature. */ | |||||
| }; | |||||
| /* | |||||
| * Backwards compatibility macros | |||||
| */ | |||||
| #if !defined(_DOXYGEN_SKIP_ME) | |||||
| #define caca_dithering cucul_feature | |||||
| #define caca_set_dithering caca_set_feature | |||||
| #define caca_get_dithering_name caca_get_feature_name | |||||
| #define CACA_DITHER_NONE CUCUL_DITHERING_NONE | |||||
| #define CACA_DITHER_ORDERED CUCUL_DITHERING_ORDERED8 | |||||
| #define CACA_DITHER_RANDOM CUCUL_DITHERING_RANDOM | |||||
| #endif | |||||
| typedef struct cucul_context cucul_t; | typedef struct cucul_context cucul_t; | ||||
| /** \defgroup basic Basic functions | /** \defgroup basic Basic functions | ||||
| @@ -109,9 +68,6 @@ cucul_t * cucul_load(void *, unsigned int); | |||||
| void cucul_set_size(cucul_t *, unsigned int, unsigned int); | void cucul_set_size(cucul_t *, unsigned int, unsigned int); | ||||
| unsigned int cucul_get_width(cucul_t *); | unsigned int cucul_get_width(cucul_t *); | ||||
| unsigned int cucul_get_height(cucul_t *); | unsigned int cucul_get_height(cucul_t *); | ||||
| enum cucul_feature cucul_get_feature(cucul_t *, enum cucul_feature); | |||||
| void cucul_set_feature(cucul_t *, enum cucul_feature); | |||||
| char const *cucul_get_feature_name(enum cucul_feature); | |||||
| void cucul_free(cucul_t *); | void cucul_free(cucul_t *); | ||||
| /* @} */ | /* @} */ | ||||
| @@ -209,9 +165,21 @@ struct cucul_bitmap *cucul_create_bitmap(unsigned int, unsigned int, | |||||
| void cucul_set_bitmap_palette(struct cucul_bitmap *, | void cucul_set_bitmap_palette(struct cucul_bitmap *, | ||||
| unsigned int r[], unsigned int g[], | unsigned int r[], unsigned int g[], | ||||
| unsigned int b[], unsigned int a[]); | unsigned int b[], unsigned int a[]); | ||||
| void cucul_set_bitmap_brightness(struct cucul_bitmap *, float); | |||||
| void cucul_set_bitmap_gamma(struct cucul_bitmap *, float); | void cucul_set_bitmap_gamma(struct cucul_bitmap *, float); | ||||
| void cucul_draw_bitmap(cucul_t *, int, int, int, int, struct cucul_bitmap const *, void *); | |||||
| void cucul_set_bitmap_invert(struct cucul_bitmap *, unsigned char); | |||||
| void cucul_set_bitmap_contrast(struct cucul_bitmap *, float); | |||||
| void cucul_set_bitmap_invert(struct cucul_bitmap *, int); | |||||
| void cucul_set_bitmap_antialias(struct cucul_bitmap *, int); | |||||
| void cucul_set_bitmap_color(struct cucul_bitmap *, char const *); | |||||
| char const * const * cucul_get_bitmap_color_list(struct cucul_bitmap const *); | |||||
| void cucul_set_bitmap_charset(struct cucul_bitmap *, char const *); | |||||
| char const * const * cucul_get_bitmap_charset_list(struct cucul_bitmap | |||||
| const *); | |||||
| void cucul_set_bitmap_dithering(struct cucul_bitmap *, char const *); | |||||
| char const * const * cucul_get_bitmap_dithering_list(struct cucul_bitmap | |||||
| const *); | |||||
| void cucul_draw_bitmap(cucul_t *, int, int, int, int, | |||||
| struct cucul_bitmap const *, void *); | |||||
| void cucul_free_bitmap(struct cucul_bitmap *); | void cucul_free_bitmap(struct cucul_bitmap *); | ||||
| /* @} */ | /* @} */ | ||||
| @@ -43,9 +43,6 @@ struct cucul_context | |||||
| enum cucul_color fgcolor; | enum cucul_color fgcolor; | ||||
| enum cucul_color bgcolor; | enum cucul_color bgcolor; | ||||
| /* Internal libcucul features */ | |||||
| enum cucul_feature background, antialiasing, dithering; | |||||
| unsigned int refcount; | unsigned int refcount; | ||||
| }; | }; | ||||
| @@ -100,12 +100,14 @@ int main(int argc, char **argv) | |||||
| bounds = (bounds + 1) % 2; | bounds = (bounds + 1) % 2; | ||||
| display_menu(); | display_menu(); | ||||
| break; | break; | ||||
| #if 0 | |||||
| case 'd': | case 'd': | ||||
| case 'D': | case 'D': | ||||
| dithering = (dithering + 1) % 5; | dithering = (dithering + 1) % 5; | ||||
| cucul_set_feature(qq, dithering); | cucul_set_feature(qq, dithering); | ||||
| display_menu(); | display_menu(); | ||||
| break; | break; | ||||
| #endif | |||||
| case 'c': | case 'c': | ||||
| demo = demo_color; | demo = demo_color; | ||||
| break; | break; | ||||
| @@ -217,8 +219,8 @@ static void display_menu(void) | |||||
| outline == 0 ? "none" : outline == 1 ? "solid" : "thin"); | outline == 0 ? "none" : outline == 1 ? "solid" : "thin"); | ||||
| cucul_printf(qq, 4, 18, "'b': drawing boundaries: %s", | cucul_printf(qq, 4, 18, "'b': drawing boundaries: %s", | ||||
| bounds == 0 ? "screen" : "infinite"); | bounds == 0 ? "screen" : "infinite"); | ||||
| cucul_printf(qq, 4, 19, "'d': dithering (%s)", | |||||
| cucul_get_feature_name(dithering)); | |||||
| //cucul_printf(qq, 4, 19, "'d': dithering (%s)", | |||||
| // cucul_get_feature_name(dithering)); | |||||
| cucul_putstr(qq, 4, yo - 2, "'q': quit"); | cucul_putstr(qq, 4, yo - 2, "'q': quit"); | ||||