Types and errors

#include "libtini/types.h"

This header gives the result codes, the handle type and three functions that keep the first error of a frame. All other headers include this header. libtini.h includes all headers.

Language and calling convention

The headers use the C99 subset of cc65 2.19 on the 65C02. They use the default cc65 ABI. Functions that are not variadic use __fastcall__. The last argument goes in A/X/sreg, and the other arguments go on the C stack.

Public types are fixed-width types from stdint.h. No public enum has an ABI-sized type. The codes are macros of fixed-width types.

Types

ti_error

typedef uint8_t ti_error;

Each call that can fail returns a ti_error. TI_OK is zero, thus if (ti_init(1, 3)) is true when the call fails.

ti_handle

typedef uint16_t ti_handle;
#define TI_INVALID_HANDLE ((ti_handle)0)

A handle identifies a banked resource. Its value contains a resource slot and a generation. It is not an address. TI_INVALID_HANDLE is never a live handle. ti_res_alloc stores it when an allocation fails.

Result codes

ValueNameMeaning
0TI_OKThe call is complete.
1TI_E_ARGUMENTThe call cannot use an argument. Examples are a NULL structure pointer and a pointer to memory that the call cannot read. Other examples are a zero size, a colour above 15 and an incorrect file name.
2TI_E_STATEThe lifecycle state is incorrect. The module is not started or is already started, or the call needs a video session or scene that is not active.
3TI_E_RANGEA position, offset, length or value is outside its limit. This includes a near buffer outside its permitted region and a resource range past its end.
4TI_E_NOMEMNo resource slot is free, or the granted banks have no space. This code also shows a full keyboard queue.
5TI_E_HANDLEThe handle is not live. The program freed it, it comes from a previous ti_init, or it was never valid.
6TI_E_UNAVAILABLEA device or service is absent or not supported. The call finds this before it changes anything. This code also shows an empty key queue, a missing pack entry and spoken numbers without a number table.
7TI_E_TIMINGA clock gap or a timeout occurred, a publication is more than its byte budget or measured deadline, or a paddle did not finish.
8TI_E_BUSYAn ownership or priority conflict occurred, a call started while another call was in progress, or interrupts disturbed a measurement.
9TI_E_IOProDOS or the transport failed. When a submitted AMEM transfer fails, part of the destination can be changed.
10TI_E_FORMATAuthored data is not valid, for example a resource pack with an incorrect directory.
11TI_E_FULLA bounded queue or list is full: the speech queue or the sprite list of a scene.

The entry of each function in this reference gives the codes that it returns and the causes. One code can have a slightly different meaning in different modules. The function entry is the authority.

Keep the first error

These three functions let a game examine failures one time each frame. It does not have to examine the result of each call. The functions keep only the results that the game gives to ti_error_keep.

for (;;) {
    ti_error_keep(ti_gfx_text_opaque(&canvas, 250, 64, score_text, 9, 0));
    ti_error_keep(ti_gfx_present(&canvas, &score_box, 0));
    ti_error_keep(ti_scene_draw());
    if (ti_error_first()) break;        /* stop at the first failure */
}
show_error_code(ti_error_first());

ti_error_keep

ti_error ti_error_keep(ti_error e);

This function returns e without a change. When no error is kept and e is not zero, it keeps e. Because it returns its argument, it can enclose a call in a test: if (ti_error_keep(ti_init(1, 3))) goto done;

ti_error_first

ti_error ti_error_first(void);

This function returns the first nonzero result that ti_error_keep received since the program started or since ti_error_clear. When there is no kept error, it returns TI_OK.

ti_error_clear

void ti_error_clear(void);

This function removes the kept error. ti_error_keep then keeps the next failure that it receives.