Tools
These are the host programs in tools/. They need Python 3.10 or newer. They use only the standard library of Python, unless their entry tells otherwise. Run them from the libtini/ folder.
| Tool | Function |
|---|---|
setup_inputs.py | Installs the pinned ProDOS input one time |
build.py | Builds the library, programs, games and disks |
assets.py | Converts images, fonts and maps. Builds resource packs. |
speech.py | Compiles phrase text to SSI-263 phonemes |
music.py | Compiles event scores and pattern songs |
midi.py | Arranges a MIDI file as a pattern song |
starfall_assets.py | The art converter of STARFALL |
disk.py | The ProDOS disk packager of the builds |
native_emulator.py | Builds and runs the development emulator |
profiler.py | Measures the time of game functions on the emulator |
benchmark.py | Measures library routines on the emulator |
web.py | Builds the browser player of a game |
check.py, test.py | Run the checks. See Checks. |
release.py | Builds again in an isolated folder, compares the results and writes release archives |
publish_docs.py | Copies this reference to a web site |
reference_guard.py | Records a fingerprint of a read-only reference checkout |
setup_inputs.py
python tools/setup_inputs.py
This tool downloads the official ProDOS 8 2.4.3 image of 140 KiB that tools/prodos-input.json names. It checks the SHA-256 and writes the image to build-inputs/prodos/ProDOS_2_4_3.po. If the file is already there, the tool only checks the hash.
This is the only tool that uses the network. The repository does not distribute ProDOS.
assets.py
python tools/assets.py image INPUT.ppm OUTPUT.ti4 --palette PALETTE.json [--palette-output FILE] [--masked] [--report FILE]
python tools/assets.py indexed INPUT.json OUTPUT.ti4 [--report FILE]
python tools/assets.py font INPUT.json OUTPUT.tif [--report FILE]
python tools/assets.py map INPUT.json OUTPUT.tim [--report FILE]
python tools/assets.py pack PACK.json OUTPUT.tpk [--report FILE]
| Command | Input | Output |
|---|---|---|
image | P3 or P6 PPM with 8-bit channels and 1-320 by 1-200 pixels. The tool gives each pixel the nearest palette colour. | TI4. --masked adds an opacity mask. --palette-output writes the 32-byte palette. |
indexed | JSON width, height, pixels (0-15) and optional masked | TI4 |
font | JSON width 1-8, height 1-16, first (default 32) and glyphs as rows of . and # | TIF |
map | JSON rows of tile numbers, 1-256 by 1-256, and optional tile_count | TIM |
pack | JSON entries. Each entry has a name and a path in the folder of the manifest. | TPK1 |
Each command prints the output size and the minimum number of 48,640-byte banks that it needs. With --report, it also writes these values to a file. The outputs contain no timestamps. Data formats gives the formats. Art, fonts, maps and packs shows how to use them.
speech.py
python tools/speech.py PHRASES.json --preview
python tools/speech.py PHRASES.json --output HEADER.h [--symbol NAME] [--no-numbers]
This tool compiles the text of each phrase to SSI-263 phoneme bytes. It uses a small English vocabulary and the pronunciations of the file. It stops for unknown words, unsupported characters and phrases of more than 255 phonemes.
The header defines each phrase name as its number. It also defines a ti_speech_bank with the name NAME (default ti_speech_assets). The bank contains the thirty number words, if you do not give --no-numbers. A bank holds a maximum of 225 phrases with number words, or 255 without them.
--preview prints the phonemes and an estimated length of each phrase at rate 10. It makes no sound.
music.py
python tools/music.py SOURCE.json --preview
python tools/music.py SOURCE.json --output HEADER.h [--symbol NAME] [--report FILE]
A document with events becomes a ti_music_event array with the name NAME (default score), and NAME_COUNT in capitals. A document with song becomes the pattern-song bytes in a uint8_t array, and NAME_SIZE.
The report gives the number of events or rows, the size, and the nominal length at 100 ticks a second. The header comment contains the optional credit string.
midi.py
python tools/midi.py TUNE.mid ARRANGEMENT.json --output SONG.json
This tool arranges a Standard MIDI File as a song document for music.py. It uses the bars, loop bar, rows per beat and tracks of the arrangement. For each channel, it prints the number of notes that no track uses. The tool only reads the MIDI file. Builds use the song document. See Arrange a MIDI file.
starfall_assets.py
python tools/starfall_assets.py --header build/starfall_assets.h [--preview build/starfall-art.ppm]
This tool checks the SHA-256 of the vendored Kenney archive in assets/starfall/. It reads the indexed PNG files of the archive with a small built-in PNG reader. It writes the sixteen 16x16 cells, the palette and the table of small images of STARFALL as a C header.
--preview writes an enlarged contact sheet. The tool is an example of a generator for one game. assets/starfall/README.md describes the conversion.
disk.py
This file is a library module, not a command. It writes deterministic ProDOS-order volumes with a root directory of seedling and sapling files. It copies the boot blocks and the unchanged PRODOS kernel from the installed release.
It checks the directory links, the block ownership, the allocation bitmap and each payload. build.py and the build.py of a separate project use it.
native_emulator.py
python tools/native_emulator.py --cc GCC [--rebuild] build
python tools/native_emulator.py --cc GCC run --disk DISK.po --system NAME.SYSTEM --profile vtw33 --frames 120 --screenshot OUT.png
python tools/native_emulator.py --cc GCC play --disk DISK.po --boot --rom ROM --slot7-rom C700 --slot7-c8-rom C800 [--video-rom CHARROM]
This tool builds the development machine of the repository, ../tools/appletini and ../demos/doom_gs/tools/a2vm. It uses GCC, does not change the sources, and makes build/native/libappletini.dll. It gives the other arguments to the runner.
--diskwith--systemstarts one SYS file through a ProDOS MLI stand-in.--bootboots the disk through ROMs. You must install the ROMs inbuild-inputs/.--profileisvtw33orturbo-f122.
This wrapper does not make sound. The emulator is GPL-3.0-only. No libtini program links it.
profiler.py
python tools/profiler.py --game starfall --cc65-home D:/Repos/cc65 --cc C:/msys64/ucrt64/bin/gcc.exe `
--key 13 --skip 360 --frames 1200 --count _sf_frames:4 _render _hud _field _ti_gfx_text_opaque
This tool boots a game that build.py built, from the installed ROMs. It waits for main, sends the keys in sequence and measures a window of emulator frames.
The time of a named function includes all that it calls, interrupts also. The report gives each call path, for example _hud/_field/_ti_gfx_text_opaque, with the number of calls, the milliseconds for each call and the part of the window.
Exported names come from the label file. Static C functions and other labels come from listings of the staged sources. For a name in more than one module, write module:name. --count LABEL:BYTES reports the change of a variable.
| Option | Default | Meaning |
|---|---|---|
--profile | vtw33 | Or turbo-f122 |
--wait | 600 | Frames after main starts |
--key | A key code or character. You can give it more than one time. | |
--key-frames | 30 | Frames after each key |
--skip | 0 | Frames before the window |
--frames | 600 | Frames in the window |
--output | build/profile/ | The JSON report |
benchmark.py
python tools/benchmark.py --cc65-home D:/Repos/cc65 --cc C:/msys64/ucrt64/bin/gcc.exe [--private] [--boot-roms build-inputs/native-roms] [--repeat 2]
This tool builds examples/benchmark.c as a separate program and disk, and runs it on the emulator. It measures cross-bank resource writes, reads, fills and copies, a full publication and a dirty rectangle. For each one, it records CPU cycles, profile clock ticks, instruction and I/O counts, and the modelled time. It checks each result.
--private also builds and measures the AMEM variant. --boot-roms boots through the installed ROMs, and then the emulated controller supplies AMEM. Repeated runs must give identical counters. The results go to build/benchmark/results.json. design/BENCHMARKS.md gives the results.
publish_docs.py
python tools/publish_docs.py DESTINATION [--base /libtini] [--home /] [--branch main]
This tool copies docs/ to a web site folder outside libtini. It changes the links of each page:
- A link to a page in
docs/becomes an absolute path under--base, without.html. For example,api/graphics.htmlbecomes/libtini/api/graphics. - A link to another file of the repository becomes a GitHub link on
--branch. - With
--home, a link to the site home goes below the libtini name.
The host must serve clean URLs: /libtini/start for start.html. The tool deletes DESTINATION only when it already contains a copy of the reference. The reference on appletini.org uses this command from the libtini/ folder:
python tools/publish_docs.py ../../appletini-one-website/public/libtini --base /libtini --home /
reference_guard.py
python tools/reference_guard.py ROOT RECORD.json
python tools/reference_guard.py ROOT RECORD.json --check
This tool records a fingerprint of the files of a reference checkout before you read it. With --check, it makes sure that no file changed. It is an audit tool. It is never a build input.