Functions

As with types, function names are prefixed with “vt”, to avoid collisions.

Note

  • Unless explicitly stated (e.g. positioning functions), NULL is not an expected input.

  • No function expects uninitialized or dangling pointers as input.

  • Sizes and lengths must always be greater than 0.

Miscellaneous

void vtAbout()

Prints info about VisualT.

Prints the version, build date, and GitHub website.

VTChar vtChar(char const *ltChar)

A helper function to convert a single-character literal string to a VTChar .

Return

The first character encoded in a VTChar , so that VisualT can process it.

Parameters
  • ltChar: a UTF8-encoded string containing a single character

Initializers, Releasers and Reallocators

Initializer functions initialize Objects. Be careful to not re-initialize Objects without releasing them before, or you’ll cause memory leaks.

They are called “initializers” (and not allocators) because the Object structure itself is not allocated, it’s just initialized. You are free to define an Object the way you want, like:

VTObj obj;
vtInitializeStrings(&obj, 1, LTSTRS{"An Object in the stack"});

or:

VTObj *obj = malloc(sizeof(VTObj));
vtInitializeStrings(obj, 1, LTSTRS{"An Object in the heap"});

Initializers always set the Object’s attributes to the following values:

attribute

default value

active Sprite

Sprite index 0

visibility flag

true

position

[0,0]

pen size

0

Note

Reallocators, like initializers, perform both memory deallocation and allocation to change the structure of an Object. They might seem convenient in several situations, but be aware of the potential performance impact of using them too often (irrelevant if confronted with I/O times).

void vtInitializeBlank(VTObj *obj, unsigned int sizesLength, VTSizes sizes)

Initializes *obj to a blank Object with sizesLength Sprites of sizes size.

vtInitializeBlank(&canvas, 2, LTSIZES{{10, 5},{5, 10}});
The example initializes canvas as an Object with two blank (transparent) Sprites, of dimensions 10x5 and 5x10 respectively. This initializer is convenient for setting up an empty canvas.

Parameters
  • obj: a pointer the Object to initialize

  • sizesLength: the length of sizes, equivalent to the number of Sprites

  • sizes: ( LTSIZES ) an array of integer pairs, each pair represent the dimension of the Sprite

void vtInitializeArray(VTObj *obj, VTChar const *v)

Initializes *obj from the native serialized Object array v.

VisualT has its own import and export format, consisting of a sequence of VTChar that can be embedded in the source as a literal array, or read from a file . Currently, the only way to serialize an Object is via vtSerialize() , but it’s still a quite powerful tool: it lets you leverage the library to programmatically compose complex scenes from simpler Objects, and then “bake” the result to a new, standalone Object.

Exporters for existing text-art editors may be created in the future.

Parameters
  • obj: a pointer to the Object to initialize

  • v: a serialized Object array

int vtInitializeFile(VTObj *obj, FILE *file)

Initializes *obj from the native serialized Object file pointed by file.

A serialized Object file is a plain text file containing a serialized Object array’s values separated by a space.

See

vtInitializeArray()

Return

A value < 0 if the operation failed. An attempt is always made to close file, even in case of failure, where *obj is left uninitialized.

Parameters
  • obj: a pointer the Object to initialize

  • file: a pointer to a serialized Object file

void vtInitializeStrings(VTObj *obj, unsigned int utf8StringsLength, VTStrs utf8Strings)

Initializes *obj from the array of strings utf8Strings of length utf8StringsLength.

This initializer is handy for creating Objects from strings on the go. Each VTStr becomes a Sprite, rows are delimited by line feeds \n. Each Sprite will be wide enough to accommodate the longest row, and trailing empty cells will be transparent. Normal space characters will be interpreted literally (opaque), but you can use \v to indicate an empty cell.

vtInitializeStrings(&obj, 3, LTSTRS{"sprite A","sprite\vB\nsecond\vrow"});
  • Sprite 1: width:8 height:1, fully opaque

  • Sprite 2: width:10 height:2, all empty cells are transparent

Parameters
  • obj: a pointer to the Object to initialize

  • utf8StringsLength: the length of utf8Strings, equivalent to the number of Sprites

  • utf8Strings: ( LTSTRS ) an array of UTF8 strings, each string becomes a Sprite

void vtInitializeObj(VTObj *restrict obj, VTObj const *restrict src)

Initializes *obj as a clone of *src.

This initializer effectively creates a deep clone of an Object, all the data in the heap is copied. It goes without saying that *obj must be uninitialized, and *src must not, hence the restrict qualifier.

Parameters
  • obj: a pointer to the Object to initialize

  • src: a pointer to the source Object

void vtRelease(unsigned int objsLength, VTObj const *restrict const *objs)

Frees the dynamic memory of all the Objects referenced in the array objs.

Once released, and Object can be re-initialized safely. You might notice that this function doesn’t accept a plain vtObjs , but a restricted qualified variant. This to emphasize that the same Object can’t be released twice, not even instances.

Parameters
  • objsLength: the length of objs

  • objs: ( LTOBJS ) an array of pointers to the Objects you want to release

void vtCloneSprite(VTObj const *dest, unsigned int spriteDest, VTObj const *src, unsigned int spriteSrc)

A reallocator that replaces Sprite n°spriteDest of *dest with a clone of Sprite n°spriteSrc of *src.

The source and destination Sprites must be different.

Parameters
  • dest: a pointer to the Object with the Sprite to replace

  • spriteDest: the to-be-replaced Sprite number

  • src: a pointer to the Object with the Sprite to clone

  • spriteSrc: the to-be-cloned Sprite number

void vtResize(VTObj *obj, unsigned int width, unsigned int height)

A reallocator that resizes *obj’ Sprite to the defined width and height. The Sprite is cleared in the process.

This comes handy when you need to resize the canvas.

Parameters
  • obj: a pointer to the Object whose Sprite you want to resize

  • width: the new width

  • height: the new height

Drawing

void vtRender(VTObj const *canvas, unsigned int objsLength, VTObjs objs)

Draws all the Objects referenced in the objs array onto the *canvas.

This is the main function that renders your scene. The last Object in the array will be in the topmost layer, followed by the others. Hidden Objects will be skipped.

vtRender(&canvas, 3, LTOBJS{&objA, &objB, &objC});
The main difference from vtStamp() , is that the canvas is cleared in the process.

Parameters
  • canvas: a pointer to the Object that will act as the canvas

  • objsLength: the length of objs

  • objs: ( LTOBJS ) an array of pointers to the Objects you want to render

void vtStamp(VTObj const *canvas, unsigned int objsLength, VTObjs objs)

Stamps all the Objects referenced in the objs array onto the *canvas.

The main difference compared to vtRender() , is that the pre-existing content on the canvas is left intact, so every Object must be drawn completely, starting from index 0, and eventually overwritten by the following Objects.

Parameters
  • canvas: a pointer to the Object that will act as the canvas

  • objsLength: the length of objs

  • objs: ( LTOBJS ) an array of pointers to the Objects you want to stamp

void vtSetText(VTObj *obj, VTSetTextMode mode, VTStr utf8String)

Sets *obj’s active Sprite content to utf8String.

  • In VTFIT mode, the Sprite will be resized (thus reallocated) to fit the content in utf8String.

  • In VTCROP mode, everything that goes outside the active Sprite is instead dropped. The parsing is done the same as in vtInitializeStrings() .

vtSetText(&obj, LTSTR "A\vKaomoji\n\v(o˘◡˘o)");
Parameters
  • obj: a pointer to the Object

  • mode: selects the draw mode

  • utf8String: ( LTSTR ) an UTF8 string

void vtClear(VTObj const *obj)

Clears *obj’s active Sprite. Clearing a Sprite sets all its cell to 0 (transparent).

Equivalent to fill(&obj, 0);.

Parameters
  • obj: a pointer to the Object you want to clear

void vtFill(VTObj const *obj, VTChar fillChar)

Sets every cell of *obj’s active Sprite to the character in fillChar.

vtFill(&obj, vtChar(LTSTR "▀"));
Parameters
  • obj: a pointer to the Object you want to fill

  • fillChar: ( vtChar() ) the character you want to fill the obj with

void vtReplace(VTObj const *obj, VTChar oldChar, VTChar newChar)

Replaces every cell of *obj’s active Sprite containing oldChar with newChar.

Parameters
  • obj: a pointer to the Object

  • oldChar: ( vtChar() ) the character you want to replace

  • newChar: ( vtChar() ) the replacing character

void vtShift(VTObj const *obj, VTDirection direction, int amount)

Shifts the content of *obj’s active Sprite by amount cells in the specified direction.

Trailing cells will be empty.

Parameters
  • obj: a pointer to the Object

  • direction: in which direction to perform the shift

  • amount: the shift amount. Negative values are supported

void vtRotate(VTObj const *obj, VTDirection direction, int amount)

Rotates each row/column of *obj’s active Sprite by amount cells in the specified direction.

Parameters
  • obj: a pointer to the Object

  • direction: in which direction to perform the row/column rotation

  • amount: the rotation amount. Negative values are supported

void vtOverlay(VTObj const *dest, unsigned int spriteDest, VTObj const *src, unsigned int spriteSrc)

Draws the content of *src’s Sprite n°spriteSrc onto *dest’s Sprite n°spriteDest of the same size.

This function exists to solve a very specific task: to flatten the canvas layers. You can set up a canvas with two or more Sprites of the same size, and use them as layers (e.g. render layer + pen layer). This function lets you overlay a Sprite on another, even if they belong to the same Object.

Parameters
  • dest: a pointer to the Object with the Sprite on which to draw

  • spriteDest: the to-be-drawn onto Sprite number

  • src: a pointer to the Object with the Sprite to overlay

  • spriteSrc: the to-be-overlaid Sprite number

void vtDrawAxes(VTObj const *obj)

Draws a visual representation of the coordinate system on *obj’s active Sprite.

Parameters
  • obj: a pointer to the Object

Printers

void vtPrint(VTObj const *obj, bool border)

Prints *obj to stdout. If border is true, also prints a frame around the output.

The printing is row-buffered: a buffer large enough to store an entire row (a little bit more than 4*width Bytes) is allocated and deallocated by the function. The last character printed is always a line feed \n.

Parameters
  • obj: a pointer to the Object you want to print

  • border: print the frame?

size_t vtPrintToString(VTObj const *obj, bool border, uint8_t **utf8Buffer)

Prints *obj to *utf8Buffer, behaves the same as vtPrint() . If *utf8Buffer==NULL, the buffer will be allocated automatically. There will be no line feed \n at the end.

  • Usage example 1: the output buffer is allocated by the function:

    unsigned char *s = NULL; // remember to initialize the pointer to NULL!
    size_t size = printToString(&obj, true, &s); // size = strlen(s) + 1('\0')
    puts(s);
    free(s); // remember to free the buffer!
    

  • Usage example 2: the output buffer is allocated by the user:

    unsigned char *s = malloc(vtPrintStringSize(&obj, true)); // remember to use the same border value
    size_t size = printToString(&obj, true, &s); // size = strlen(s) + 1('\0')
    puts(s);
    free(s); // remember to free the buffer!
    
    If the provided buffer isn’t large enough, the function will cause memory corruption. Use vtPrintStringSize() to get the minimum required size.

Return

The amount of bytes written by the function, must be ≥ to the size of *utf8Buffer.

Parameters
  • obj: a pointer to the Object you want to print

  • border: print the frame?

  • utf8Buffer: a pointer to a pointer to a char buffer. *utf8Buffer will be allocated (thus overwritten) if NULL

size_t vtPrintStringSize(VTObj const *obj, bool border)

Calculates the size of the buffer that *obj would occupy if printed. With or without border.

This is useful if you want to allocate the buffer yourself when using vtPrintToString() .

Return

The size of the buffer *obj would occupy if printed.

Parameters
  • obj: a pointer to the Object you want to process

  • border: add the frame to the calculation?

Sprite Operations

unsigned int vtSprites(VTObj const *obj)

Gets *obj’s amount of Sprites.

Return

The amount of Sprites.

Parameters
  • obj: a pointer to the Object

unsigned int vtSpriteInd(VTObj const *obj)

Gets the index of *obj’s active Sprite.

Return

The index of the active Sprite.

Parameters
  • obj: a pointer to the Object

void vtNextSprite(VTObj *obj)

Sets *obj’s next Sprite as active.

Parameters
  • obj: a pointer to the Object

void vtPrecSprite(VTObj *obj)

Sets *obj’s preceding Sprite as active.

Parameters
  • obj: a pointer to the Object

void vtSetSprite(VTObj *obj, unsigned int index)

Sets *obj’s Sprite of index index as active.

Parameters
  • obj: a pointer to the Object

  • index: the index of the Sprite you want to set as active

int vtWidth(VTObj const *obj)

Gets the width of *obj’s active Sprite.

Return

The width of the active Sprite.

Parameters
  • obj: a pointer to the Object

int vtHeight(VTObj const *obj)

Gets the height of *obj’s active Sprite.

Return

The height of the active Sprite.

Parameters
  • obj: a pointer to the Object

int vtExtremum(VTObj const *obj, VTDirection direction)

Gets the maximum visible coordinate (extrema) of *obj’s active Sprite in the specified direction.

Return

The maximum visible coordinate of the active Sprite.

Parameters
  • obj: a pointer to the Object

  • direction: the axis direction

Object Operations

bool vtVisible(VTObj const *obj)

Gets *obj’s visibility flag.

Return

true if the Object is visible, false otherwise.

Parameters
  • obj: a pointer to the Object

void vtShow(VTObj *obj)

Sets *obj’s visibility flag to true.

Parameters
  • obj: a pointer to the Object

void vtHide(VTObj *obj)

Sets *obj’s visibility flag to false.

Parameters
  • obj: a pointer to the Object

void vtSetVisibility(VTObj *obj, bool visible)

Sets *obj’s visibility flag to visible.

Parameters
  • obj: a pointer to the Object

  • visible: the new value

void vtSerialize(VTObj const *obj, unsigned int *v)

Exports *obj as a serialized object, and writes it to the array *v if v!=NULL, otherwise to stdout.

If the provided array isn’t large enough, the function will cause memory corruption. Use vtSerializedArraySize() to get the minimum required size.

Parameters
  • obj: a pointer to the processed Object

  • v: nullable: a pointer to a uint32_t array

size_t vtSerializedArraySize(VTObj const *obj)

Calculates the size of the array that *obj would occupy if serialized.

This is useful if you want to allocate the array yourself when using vtSerialize() .

Return

The size of the array.

Parameters
  • obj: a pointer to the processed Object

Pen Operations

VTChar vtPenChar(VTObj const *obj)

Gets *obj’s pen character.

Return

The pen character of the Object.

Parameters
  • obj: a pointer to the Object

unsigned short vtPenSize(VTObj const *obj)

Gets *obj’s pen size.

Return

The pen size of the Object.

Parameters
  • obj: a pointer to the Object

void vtSetPenSize(VTObj *obj, unsigned short size)

Sets *obj’s pen size to size.

Parameters
  • obj: a pointer to the Object

  • size: the new size, if outside of the [1,6] interval, the pen size defaults to 1

void vtSetPenChar(VTObj *obj, VTChar penChar)

Sets *obj’s pen character to penChar.

Parameters
  • obj: a pointer to the Object

  • penChar: ( vtChar() ) the new value

Movement

Movement functions move the Objects in the scene by manipulating their coordinates.
They aren’t simple setters, because if the canvas parameter is not VTMV, the Object will leave a trail. Read the pen introduction to know more.

int vtXPosition(VTObj const *obj)

Gets *obj’s x position.

Return

The x position of the Object.

Parameters
  • obj: a pointer to the Object

int vtYPosition(VTObj const *obj)

Gets *obj’s y position.

Return

The y position of the Object.

Parameters
  • obj: a pointer to the Object

void vtGotoXY(VTObj const *canvas, VTObj *obj, int x, int y)

Moves *obj to the x;y position. The movement will leave a pen trail on the *canvas, if !=VTMV.

Parameters
  • canvas: nullable: a pointer to the Object the pen will draw onto, usually the canvas

  • obj: a pointer to the Object

  • x: the target x coordinate

  • y: the target y coordinate

void vtGotoX(VTObj const *canvas, VTObj *obj, int x)

Moves *obj to x. The movement will leave a pen trail on the *canvas, if specified.

Parameters
  • canvas: nullable: a pointer to the Object the pen will draw onto, usually the canvas

  • obj: a pointer to the Object

  • x: the target x coordinate

void vtGotoY(VTObj const *canvas, VTObj *obj, int y)

Moves *obj to y. The movement will leave a pen trail on the *canvas, if specified.

Parameters
  • canvas: nullable: a pointer to the Object the pen will draw onto, usually the canvas

  • obj: a pointer to the Object

  • y: the target y coordinate

void vtChangeX(VTObj const *canvas, VTObj *obj, int x)

Changes *obj’s x position by x. The movement will leave a pen trail on the *canvas, if specified.

Parameters
  • canvas: nullable: a pointer to the Object the pen will draw onto, usually the canvas

  • obj: a pointer to the Object

  • x: the x coordinate shift

void vtChangeY(VTObj const *canvas, VTObj *obj, int y)

Changes *obj’s y position by y. The movement will leave a pen trail on the *canvas, if specified.

Parameters
  • canvas: nullable: a pointer to the Object the pen will draw onto, usually the canvas

  • obj: a pointer to the Object

  • y: the y coordinate shift

void vtAlign(VTObj *obj, VTDirection direction)

Modifies *obj’s coordinates so that the specified position matches with the Object position.

Parameters
  • obj: a pointer to the Object

  • direction: how to align the Object, see VTDirection

Sensors

Sensor functions can detect if an Object is touching (overlapping) something else in the scene.

bool vtIsTouching(VTObj const *canvas, VTObj const *obj, unsigned int objsLength, VTObjs objs)

Detects if *obj is overlapping any of the Objects referenced in objs.

This sensor detects pixel perfect Object-on-Object collisions, in the space delimited by the *canvas. Transparent pixels won’t be considered. This is the slowest sensor, as it also allocates memory.

Return

true if there is a collision, false otherwise.

Parameters
  • canvas: a pointer to the Object whose area will be searched for collisions, usually the canvas

  • obj: a pointer to the Object you want to process

  • objsLength: the length of objs

  • objs: ( LTOBJS ) an array of pointers to the Objects you want to consider in the test

bool vtIsTouchingGlyph(VTObj const *canvas, VTObj const *obj, VTChar testChar)

Detects if *obj is overlapping any cell in the *canvas containing testChar.

This sensor detects pixel perfect Object-on-char collisions. Transparent pixels won’t be considered.

Return

true if there is a collision, false otherwise.

Parameters
  • canvas: a pointer to the Object whose area will be searched for collisions, usually the canvas

  • obj: a pointer to the Object you want to process

  • testChar: ( ltChar() ) the character you want to test

bool vtIsOutside(VTObj const *canvas, VTObj const *obj)

Detects if *obj is spilling outside the *canvas area.

This sensor detects pixel perfect Object-on-area collisions. Transparent pixels won’t be considered.

Return

true if there is a collision, false otherwise.

Parameters
  • canvas: a pointer to the Object whose area will be tested, usually the canvas

  • obj: a pointer to the Object you want to process