| @@ -6,8 +6,6 @@ | |||
| - allow to change the canvas size in a per-frame basis. | |||
| - export attribute parsing functions such as attr_to_ansi4fg etc. | |||
| - add cursor support in the canvas, so that we can load ANSI files | |||
| in stream mode. | |||
| \subsection indep API-independent stuff | |||
| @@ -41,6 +41,55 @@ | |||
| #include "cucul.h" | |||
| #include "cucul_internals.h" | |||
| /** \brief Set cursor position. | |||
| * | |||
| * Put the cursor at the given coordinates. Functions making use of the | |||
| * cursor will use the new values. Setting the cursor position outside the | |||
| * canvas is legal but the cursor will not be shown. | |||
| * | |||
| * This function never fails. | |||
| * | |||
| * \param cv A handle to the libcucul canvas. | |||
| * \param x X cursor coordinate. | |||
| * \param y Y cursor coordinate. | |||
| * \return This function always returns 0. | |||
| */ | |||
| int cucul_gotoxy(cucul_canvas_t *cv, int x, int y) | |||
| { | |||
| cv->frames[cv->frame].x = x; | |||
| cv->frames[cv->frame].y = y; | |||
| return 0; | |||
| } | |||
| /** \brief Get X cursor position. | |||
| * | |||
| * Retrieve the X coordinate of the cursor's position. | |||
| * | |||
| * This function never fails. | |||
| * | |||
| * \param cv A handle to the libcucul canvas. | |||
| * \return The cursor's X coordinate. | |||
| */ | |||
| int cucul_get_cursor_x(cucul_canvas_t *cv) | |||
| { | |||
| return cv->frames[cv->frame].x; | |||
| } | |||
| /** \brief Get Y cursor position. | |||
| * | |||
| * Retrieve the Y coordinate of the cursor's position. | |||
| * | |||
| * This function never fails. | |||
| * | |||
| * \param cv A handle to the libcucul canvas. | |||
| * \return The cursor's Y coordinate. | |||
| */ | |||
| int cucul_get_cursor_y(cucul_canvas_t *cv) | |||
| { | |||
| return cv->frames[cv->frame].y; | |||
| } | |||
| /** \brief Print an ASCII or Unicode character. | |||
| * | |||
| * Print an ASCII or Unicode character at the given coordinates, using | |||
| @@ -264,6 +313,54 @@ int cucul_clear_canvas(cucul_canvas_t *cv) | |||
| return 0; | |||
| } | |||
| /** \brief Set cursor handle. | |||
| * | |||
| * Set the canvas' handle. Blitting functions will use the handle value | |||
| * to put the canvas at the proper coordinates. | |||
| * | |||
| * This function never fails. | |||
| * | |||
| * \param cv A handle to the libcucul canvas. | |||
| * \param x X handle coordinate. | |||
| * \param y Y handle coordinate. | |||
| * \return This function always returns 0. | |||
| */ | |||
| int cucul_set_canvas_handle(cucul_canvas_t *cv, int x, int y) | |||
| { | |||
| cv->frames[cv->frame].handlex = x; | |||
| cv->frames[cv->frame].handley = y; | |||
| return 0; | |||
| } | |||
| /** \brief Get X handle position. | |||
| * | |||
| * Retrieve the X coordinate of the canvas' handle. | |||
| * | |||
| * This function never fails. | |||
| * | |||
| * \param cv A handle to the libcucul canvas. | |||
| * \return The canvas' handle's X coordinate. | |||
| */ | |||
| int cucul_get_canvas_handle_x(cucul_canvas_t *cv) | |||
| { | |||
| return cv->frames[cv->frame].handlex; | |||
| } | |||
| /** \brief Get Y handle position. | |||
| * | |||
| * Retrieve the Y coordinate of the canvas' handle. | |||
| * | |||
| * This function never fails. | |||
| * | |||
| * \param cv A handle to the libcucul canvas. | |||
| * \return The canvas' handle's Y coordinate. | |||
| */ | |||
| int cucul_get_canvas_handle_y(cucul_canvas_t *cv) | |||
| { | |||
| return cv->frames[cv->frame].handley; | |||
| } | |||
| /** \brief Blit a canvas onto another one. | |||
| * | |||
| * Blit a canvas onto another one at the given coordinates. | |||
| @@ -43,6 +43,9 @@ | |||
| * \e libcucul function to be called in a function. cucul_free_canvas() | |||
| * should be called at the end of the program to free all allocated resources. | |||
| * | |||
| * Both the cursor and the canvas' handle are initialised at the top-left | |||
| * corner. | |||
| * | |||
| * If an error occurs, NULL is returned and \b errno is set accordingly: | |||
| * - \c ENOMEM Not enough memory for the requested canvas size. | |||
| * | |||
| @@ -78,6 +81,8 @@ cucul_canvas_t * cucul_create_canvas(unsigned int width, unsigned int height) | |||
| cv->frames[0].width = cv->frames[0].height = 0; | |||
| cv->frames[0].chars = NULL; | |||
| cv->frames[0].attrs = NULL; | |||
| cv->frames[0].x = cv->frames[0].y = 0; | |||
| cv->frames[0].handlex = cv->frames[0].handley = 0; | |||
| cv->frames[0].curattr = cv->curattr; | |||
| if(_cucul_set_canvas_size(cv, width, height) < 0) | |||
| @@ -89,6 +89,9 @@ int cucul_rand(int, int); | |||
| * | |||
| * @{ */ | |||
| #define CUCUL_MAGIC_FULLWIDTH 0x000ffffe /**< Used to indicate that the previous character was a fullwidth glyph. */ | |||
| int cucul_gotoxy(cucul_canvas_t *, int, int); | |||
| int cucul_get_cursor_x(cucul_canvas_t *); | |||
| int cucul_get_cursor_y(cucul_canvas_t *); | |||
| unsigned long int cucul_get_attr(cucul_canvas_t *, int, int); | |||
| int cucul_set_attr(cucul_canvas_t *, unsigned long int); | |||
| int cucul_putattr(cucul_canvas_t *, int, int, unsigned long int); | |||
| @@ -99,6 +102,9 @@ unsigned long int cucul_getchar(cucul_canvas_t *, int, int); | |||
| int cucul_putstr(cucul_canvas_t *, int, int, char const *); | |||
| int cucul_printf(cucul_canvas_t *, int, int, char const *, ...); | |||
| int cucul_clear_canvas(cucul_canvas_t *); | |||
| int cucul_set_canvas_handle(cucul_canvas_t *, int, int); | |||
| int cucul_get_canvas_handle_x(cucul_canvas_t *); | |||
| int cucul_get_canvas_handle_y(cucul_canvas_t *); | |||
| int cucul_blit(cucul_canvas_t *, int, int, cucul_canvas_t const *, | |||
| cucul_canvas_t const *); | |||
| int cucul_set_canvas_boundaries(cucul_canvas_t *, int, int, | |||
| @@ -28,6 +28,8 @@ struct cucul_frame | |||
| uint32_t *attrs; | |||
| /* Painting context */ | |||
| int x, y; | |||
| int handlex, handley; | |||
| uint32_t curattr; | |||
| }; | |||
| @@ -171,14 +171,14 @@ static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) | |||
| * - 16 bytes for the canvas header | |||
| * - 24 bytes for the frame info | |||
| * 8 bytes for each character cell */ | |||
| *bytes = 44 + 8 * cv->width * cv->height; | |||
| *bytes = 52 + 8 * cv->width * cv->height; | |||
| cur = data = malloc(*bytes); | |||
| /* magic */ | |||
| cur += sprintf(cur, "%s", "\xCA\xCA" "CV"); | |||
| /* canvas_header */ | |||
| cur += sprintu32(cur, 16 + 24); | |||
| cur += sprintu32(cur, 16 + 32 * 1); | |||
| cur += sprintu32(cur, cv->width * cv->height * 8); | |||
| cur += sprintu16(cur, 0x0001); | |||
| cur += sprintu32(cur, 1); | |||
| @@ -189,8 +189,10 @@ static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) | |||
| cur += sprintu32(cur, cv->height); | |||
| cur += sprintu32(cur, 0); | |||
| cur += sprintu32(cur, cv->curattr); | |||
| cur += sprintu32(cur, 0); | |||
| cur += sprintu32(cur, 0); | |||
| cur += sprintu32(cur, cv->frames[0].x); | |||
| cur += sprintu32(cur, cv->frames[0].y); | |||
| cur += sprintu32(cur, cv->frames[0].handlex); | |||
| cur += sprintu32(cur, cv->frames[0].handley); | |||
| /* canvas_data */ | |||
| for(n = cv->height * cv->width; n--; ) | |||
| @@ -236,6 +238,8 @@ static void *export_caca(cucul_canvas_t *cv, unsigned long int *bytes) | |||
| * uint32_t duration; // Frame duration in milliseconds, 0 to | |||
| * // not specify a duration | |||
| * uint32_t attr; // Graphics context attribute | |||
| * int32_t cursor_x; // Cursor X coordinate | |||
| * int32_t cursor_y; // Cursor Y coordinate | |||
| * int32_t handle_x; // Handle X coordinate | |||
| * int32_t handle_y; // Handle Y coordinate | |||
| * } | |||
| @@ -114,6 +114,9 @@ int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int id) | |||
| for(f = cv->framecount - 1; f > id; f--) | |||
| cv->frames[f] = cv->frames[f - 1]; | |||
| if(cv->frame >= id) | |||
| cv->frame++; | |||
| cv->frames[id].width = cv->width; | |||
| cv->frames[id].height = cv->height; | |||
| cv->frames[id].chars = malloc(size * sizeof(uint32_t)); | |||
| @@ -122,8 +125,10 @@ int cucul_create_canvas_frame(cucul_canvas_t *cv, unsigned int id) | |||
| memcpy(cv->frames[id].attrs, cv->attrs, size * sizeof(uint32_t)); | |||
| cv->frames[id].curattr = cv->curattr; | |||
| if(cv->frame >= id) | |||
| cv->frame++; | |||
| cv->frames[id].x = cv->frames[cv->frame].x; | |||
| cv->frames[id].y = cv->frames[cv->frame].y; | |||
| cv->frames[id].handlex = cv->frames[cv->frame].handlex; | |||
| cv->frames[id].handley = cv->frames[cv->frame].handley; | |||
| return 0; | |||
| } | |||
| @@ -247,14 +247,14 @@ static long int import_caca(cucul_canvas_t *cv, | |||
| if(size < 4 + control_size + data_size) | |||
| return 0; | |||
| if(control_size < 16 + frames * 24) | |||
| if(control_size < 16 + frames * 32) | |||
| goto invalid_caca; | |||
| for(expected_size = 0, f = 0; f < frames; f++) | |||
| { | |||
| unsigned int width, height, duration; | |||
| uint32_t attr; | |||
| int x, y; | |||
| int x, y, handlex, handley; | |||
| width = sscanu32(buf + 4 + 16 + f * 24); | |||
| height = sscanu32(buf + 4 + 16 + f * 24 + 4); | |||
| @@ -262,6 +262,8 @@ static long int import_caca(cucul_canvas_t *cv, | |||
| attr = sscanu32(buf + 4 + 16 + f * 24 + 12); | |||
| x = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 16); | |||
| y = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 20); | |||
| handlex = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 24); | |||
| handley = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 28); | |||
| expected_size += width * height * 8; | |||
| } | |||
| @@ -283,6 +285,10 @@ static long int import_caca(cucul_canvas_t *cv, | |||
| } | |||
| cv->curattr = sscanu32(buf + 4 + 16 + 12); | |||
| cv->frames[0].x = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 16); | |||
| cv->frames[0].y = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 20); | |||
| cv->frames[0].handlex = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 24); | |||
| cv->frames[0].handley = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 28); | |||
| return 4 + control_size + data_size; | |||