titrmlib

A curses-style TUI library for the TI-84 Plus CE. Panels, widgets, scenes, dialogs, colors and text styles for CE C programs.

View the Project on GitHub gavinhsmith/titrmlib

titrmlib — notes for coding agents

titrmlib is a TUI framework for the TI-84 Plus CE, written in C for the CE C toolchain (CEdev) on top of graphx. It is a sibling of Tincan and TINCLIB (Wi-Fi/networking libraries for the same calculator, talking to an ESP board over serial), and gives those and other CE apps composable UI pieces in place of hand-written graphx code for every screen.

Project status

Update this section when a stage finishes or the release state changes.

Stage 1 (core library): complete as of 2026-09-23.

Version: TITRM_VERSION is "0.4.2". v0.1.0 through v0.4.2 are released; v0.3.0 added code page 437, v0.4.0 the formatting, v0.4.1 smaller memory use and v0.4.2 term_snprintf.

The ASCII glyphs have been checked on a real TI-84 Plus CE; the CP437 glyphs added in v0.3.0 and the styles added in v0.4.0 have only been checked in CEmu.

v0.4.0 (formatting): bold, italic, underline and strikethrough attributes, inline style escapes (TERM_S_BOLD etc.) and tab stops.

Phase 2: complete, merged to main in PR #1 and released as v0.2.0. The design and build order are in DESIGN.md. It added retained panels and change-based rendering, the key queue (keypadc input), app-driven focus, the new events, scenes, overlays, the revised widget set with the demo rebuilt on it, and color. Breaking API changes are fine until v1.0.

Core rules

Architecture

File Role
src/titrm.h The public API
src/titrm.c Cell grid, glyph drawing, panel tree, layout, focus, key translation, run loop
src/titrm_widgets.c Text (also logs), button, checkbox, list, input and progress widgets
src/titrm_internal.h Cell, panel and context structs, shared by the two .c files
src/titrm_font.c, titrm_chars.h, FONT.md Generated by tools/gen_font.py; never edit by hand
docs/ API reference generated from the doc comments in src/titrm.h by Doxygen + moxygen (make docs); never edit by hand. Every public declaration needs a /** */ comment inside its section’s @defgroup; regenerate after changing the header

Performance on the eZ80

Code that is cheap on a desktop can be slow here:

Update times (the app’s printing plus the frame) are measured by the perf hardware test against fixed budgets:

Update Emulated time Budget
Nothing changed ~1 ms 5 ms
One row changed ~48 ms 50 ms (the phase 2 goal)
Every cell changed ~466 ms 600 ms
Every cell changed, in color ~466 ms 600 ms

Most of a full-screen update is drawing 1,590 cells at ~0.2 ms each, plus a keypad scan per row. The widgets hardware test runs at the autotester’s default key speed, so it catches lost keys if frames or polling regress.

Testing

Details are in CONTRIBUTING.md. In short: