{"id":17231976,"url":"https://github.com/pushfoo/octo-termlib","last_synced_at":"2025-03-26T00:34:32.025Z","repository":{"id":205204818,"uuid":"713665142","full_name":"pushfoo/octo-termlib","owner":"pushfoo","description":"A terminal-like text library for XO-CHIP in assembly","archived":false,"fork":false,"pushed_at":"2024-03-30T04:00:02.000Z","size":104,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T21:22:34.222Z","etag":null,"topics":["assembly","assembly-language","chip-8","octojam","terminal","text-rendering","xo-chip"],"latest_commit_sha":null,"homepage":"","language":"Roff","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pushfoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-11-03T01:40:01.000Z","updated_at":"2024-07-02T20:07:02.000Z","dependencies_parsed_at":"2023-11-15T04:26:51.880Z","dependency_job_id":"84dbfd85-1604-4ff4-8a5f-1ac67b4280f7","html_url":"https://github.com/pushfoo/octo-termlib","commit_stats":null,"previous_names":["pushfoo/octo-termlib"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pushfoo%2Focto-termlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pushfoo%2Focto-termlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pushfoo%2Focto-termlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pushfoo%2Focto-termlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pushfoo","download_url":"https://codeload.github.com/pushfoo/octo-termlib/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245566176,"owners_count":20636396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assembly","assembly-language","chip-8","octojam","terminal","text-rendering","xo-chip"],"created_at":"2024-10-15T05:00:11.669Z","updated_at":"2025-03-26T00:34:32.007Z","avatar_url":"https://github.com/pushfoo.png","language":"Roff","readme":"# octo-termlib\n\n[itch]: https://pushfoo.itch.io/termlib-demo\n[octojam10]: https://itch.io/jam/octojam-10\n[chiplet]: https://github.com/gulrak/chiplet\n[octopus]: https://github.com/Timendus/chipcode/tree/main/octopus\n[octo]: https://github.com/JohnEarnest/Octo\n[xo-chip]: http://johnearnest.github.io/Octo/docs/XO-ChipSpecification.html\n[octo-ide]: http://johnearnest.github.io/Octo/\n\n**TL;DR**: A terminal-inspired text rendering library in [Octo][octo]\nfor [XO-CHIP][xo-chip].\n\nIt supports notions of foreground and background.\n\nLicense TBD, but there's [an interactive demo on itch.io][itch]. This\nproject was initially written as an [Octojam 10][octojam10] entry.\n\n\n## Quickstart\n\n1. Save [template.8o](template.8o) or copy it into the online [Octo IDE][octo-ide]\n2. Find the `Start of User code` heading\n3. Replace the code between it and the `End of User Code` heading to match the following:\n   ```\n   #######  Start of User code  #######\n\n   : main\n       hires\n       loop\n           clear \n           show-msg 0 0 message_string\n           v0 := key  # Wait for user input before looping\n       again\n   \n   : message_string\n       text \"^B3^F2\"\n       text \"PLANE 3 BG PLANE 2 TXT\\n\"\n       text \"^D\"  # Reset the colors\n       text \"PLANE 0 BG PLANE 3 TXT\\n\"\n       text \"^B2\" # Set BG plane to 3\n       text \"PLANE 2 BG PLANE 3 TXT\\\"\n       text \"\\0\" # \\0 ends the message.\n   \n   #######   End of User Code   ######\n   ```\n\nWhen you compile \u0026 run, you should see something like the following:\n\n![example output](docs/images/example_text.png)\n\nThe exact colors depend on your current XO-CHIP color palette.\n\n## Table of contents\n1.  [How big is it?](#how-big-is-it)\n2.  [Why build this?](#why-build-this)\n3.  [How does it work?](#how-does-it-work)\n4.  [Is it fast?](#is-it-fast)\n5.  [Syntax Details](#syntax-details)\n6.  [Design goals](#design-goals)\n7.  [Current limitations](#current-limitations)\n8.  [Inspiration](#inspiration)\n\n\n## How big is it?\n\n**TL;DR** It depends on which parts you use.\n\nThe demo built with `make demo-rom` takes up 1408 bytes.\nMost of that is the default character set found in: \n\n1. [src/default_font_data.8o](src/default_font_data.8o)\n2. [src/default_font_stringmodes.8o](src/default_font_data.8o)\n\nYou can override this data before importing [src/render_core.8o](src/render_core.8o)\nas described in [docs/style_conventions.8o](docs/style_conventions.md#includes--overrides).\n\nIf you define a character set with different contents or structure,\nyou may also have override the following:\n\n1. `show-msg` before importing `render_core.8o`\n2. Any character handlers you use from `render_impl.8o` before importing it\n\n## Why build this?\n\nI wanted:\n\n1.  A quickstart tool for rendering text in Octo projects\n2.  A configurable renderer to help restart work on\n    [Fontknife](https://github.com/pushfoo/Fontknife), another project\n    of mine\n3.  To learn about text formatting and rendering on low-resource and\n    retro platforms\n\nBash's color escapes are not the tool I was looking for:\n\n1.  Bash-style color escapes are hard to read:\n\n    | Bash-style escape                | octo-termlib syntax           |\n    |----------------------------------|-------------------------------|\n    | `\\e[37mLight gray foreground\\]`  | `^F1Light gray foreground^D`  |\n    | `\\e[41mRed background\\]`         | `^B2Red background^D`         |\n    | `\\e[41m\\e[37Both colors\\]\\]`     | `^B2^F3Both colors^D`         |\n\n2.  [Octo\\'s `:stringmode` macro](https://johnearnest.github.io/Octo/docs/Manual.html#strings)\n    does not support `\\e`\n3.  Substituting another escaped character would make them harder to\n    read\n4.  The substituted codes would end up using even more space than they\n    already do.\n5.  Processing them would be harder to implement in Octo.\n\n## How does it work?\n\n**TL;DR**: It reads certain character combinations as formatting control\ninstead of drawing them as sprites.\n\nLet's use the title screen from the demo above as an example. With the\nlibrary, drawing the formatted text on it consists of the following:\n\n1.  Declare the following label:\n\n    ```\n    : msg_title\n\n       text \"\\n\\n\"\n       text \"^F3^B0 TERM LIB DEMO \\n\"\n       text \"     ^F3^B2 PRESS ANY KEY ^D\\n\"\n       text \"       ^F1^B3 ALL TEXT DYNAMIC!\\0\"\n    ```\n\n2.  Call the drawing routine:\n \n    ```\n    show-msg 0 0 msg_title\n    \n    # Wait for input to allow observing the text\n    v0 := key\n    ```\n\nThe result:\n![The title screen of the demo on itch.io](docs/images/title_screen.png)\n\nEvery `^` starts an escape sequence which changes the drawing planes\ninstead of rendering as text. Some set non-default colors, while others\nrestore defaults.\n\n\nThe second screen shows off the full range of color combinations by\nusing the following syntax:\n\n```console\n: msg_all\n   text \"^F0^B0 0^F1^B0 1^F2^B0 2^F3^B0 3\\n\"\n   text \"^F0^B1 4^F1^B1 5^F2^B1 6^F3^B1 7\\n\"\n   text \"^F0^B2 8^F1^B2 9^F2^B210^F3^B211\\n\"\n   text \"^F0^B312^F1^B313^F2^B314^F3^B315\\0\"\n```\n\nThe result:\n![The result of the combo screen text](docs/images/combo_screen.png)\n\n## Is it fast?\n\n**TL;DR**: Fast enough for most use cases with plenty of room for\noptimizations.\n\nThe demo embedded on this page runs at 100 instructions / cycle. It will\nrun smoothly down to 30 instructions / cycle. After that point, pauses\nfrom string parsing become will grow more noticeable.\n\nSince there is a lot of room for optimization, it is unclear what the\nminimum instruction / cycle will be.\n\n## Syntax Details\n\n**TL;DR**: \\\"What if Bash color escapes were better?\\\"\n\nThe `^` character enters escape mode. To save CPU cycles and memory,\nthere is no closing tag and no stack. Instead, effects are applied\nimmediately. You can restore defaults by either binding them to a string\nto draw, or use the dedicated shortcut:\n\n| Name           | Escape code | Action(s)                                                                                   |\n|----------------|-------------|---------------------------------------------------------------------------------------------|\n| **D**efaults   | `^D`        | \u003col\u003e\u003cli\u003eSet `bg_color` to `0` invisble.\u003c/li\u003e\u003cli\u003eSet `fg_color` to `3` (Full color)\u003c/li\u003e\u003col\u003e |\n| **B**ackground | `^BN`       | Set the draw plane(s) for the flat character used to color the background layer             |\n| **F**oreground | `^FN`       | Set the draw plane(s) for the foreground layer.                                             |\n\n### As Regex\n\n**TL;DR**: There are interactive regex playgrounds linked below.\n\n| Regex Flavor           | Regex101 Link                             | Rough expression                       |\n|------------------------|-------------------------------------------|----------------------------------------|\n| ECMAScript/JavaScript  | [Try it](https://regex101.com/r/0366WB/)  | `/(\\^(?\u003caction\u003e[A-Z])(?\u003cnum\u003e\\d?)+)/`   |\n| Python                 | [Try it](https://regex101.com/r/4upDdM/)  | `r'\\^(?P\u003caction\u003e[A-Z])(?P\u003cnum\u003e\\d)?'`   |\n\n## Current Limitations\n\n**TL;DR**: There are a lot of brittle assumptions and no way to keep\n`vF` results.\n\nThe drawing layers imitate the concepts of other systems by using double\nlength sprites compatible with `plane 3`. Font data is expected to match\nthis standard. This is how the second screen generates all its color\ncombinations: XO-CHIP\\'s XOR-based allows effects like stenciling shapes\nout of single-color surfaces.\n\nDespite its potential, the current implementation is currently\nincomplete in ways which limit its use for more demanding tasks. Some of\nthe most important examples are outlined below.\n\n| Current Implementation                                    | Limitation                                                         |\n|-----------------------------------------------------------|--------------------------------------------------------------------|\n| No form of error handling in any shape                    | Bad input can break non-debugger status displays.                  |\n| One message position stored at time without caching       | Library best used for predictable state such as JRPG text boxes    |\n| Assumes monospace fonts                                   | Unexpected character sizes will not render highlighting correctly. |\n| Layer draw calls skip if their `plane` is 0               | Inconsistent timing if plane values change                         |\n| Storing `vF` from successive draw calls is unimplemented  | Can\\'t detect XOR collisions while batch drawing text              |\n\nSee the following to learn more:\n\n-   The [Inspiration](#inspiration) heading below\n-   The [XO-Chip documentation](http://johnearnest.github.io/Octo/docs/XO-ChipSpecification.html#bitplanes)\n\n### Planned Additions\n\n| Tentative Example        | Meaning                                       | Intended Purpose                          |\n|--------------------------|-----------------------------------------------|-------------------------------------------|\n| `text \"^R5^C5example\"`   | Jump drawing cursor to row 5, column 5        | Replacing or deleting specific characters |\n| `text \"^X51^Y23example\"` | Move the drawing cursor to screen pixel 51,32 | Fast kerning experimentation.             |\n| `text \"^E3\"`             | XOR entire screen with pixels using `plane 3` | Change / flash colors for errors          |\n\nFuture features could also include:\n\n-   Caching of rendered glyphs to speed up XOR-erasing specific parts\n-   Limited UI / widget features\n\n## Design goals\n\n**TL;DR**: Imitate some old terminal behaviors but with quality of life\nimprovements.\n\nThe CHIP-8 instruction set was originally designed for 1970s kit\ncomputers. This hardware was extremely limited, even when compared to\nthe era\\'s terminals and more some recent household appliances. For\nexample, these kit computers:\n\n-   ran at less than 2 MHz\n-   came with less than 2 KB of RAM\n\nSystems from this era made the most of their limited resources by\nreserving [control characters](https://en.wikipedia.org/wiki/Control_character) for\ncommunication and markup, as well as using [escape characters](https://en.wikipedia.org/wiki/Escape_character)\nto indicate changes in encoding.\n\nSince control characters are often represented with [caret notation](https://en.wikipedia.org/wiki/Caret_notation), this library\nre-uses it as a convenient default escape character. However, the final\nvalue is not converted to a byte literal but left as an ASCII `^`.\n\n[octo-debugger-doc]: https://johnearnest.github.io/Octo/docs/Manual.html#debugging\n\nIt has numerous advantages:\n\n1.  It works with the limitations of Octo\\'s `:stringmode` macros\n    without sacrificing any clarity\n2.  Combining styles is far more legible:\n3.  It\\'s easier to implement in Octo\n4.  It renders cleanly in [Octo\\'s debugger][octo-debugger-doc],\n    unlike unprintable byte literals\n5.  The resulting escapes are easier to distinguish than hex codes\n6.  It\\'s easier to enter than hex codes\n\nAside from wasting bytes, there seem to be few downsides, especially if\nyou are still prototyping. The `^` character seems to generally be\nunused in Octo projects due to poor legibility in pixel fonts,\nespecially at the supported screen resolutions.\n\n## Inspiration\n\n-   [rich](https://github.com/Textualize/rich), a Python terminal\n    formatting library\n-   Control \u0026 drawing behaviors from specific systems:\n    -   [Control codes used in teletext systems from same era as\n        CHIP-8](https://en.wikipedia.org/wiki/C0_and_C1_control_codes#Modified_C0_control_code_sets)\n    -   The [Varvara VM\\'s dual-layer screen\n        device](https://wiki.xxiivv.com/site/varvara.html#screen)\n    -   Python\\'s [history of multiple string formatting\n        techniques](https://docs.python.org/3/tutorial/inputoutput.html#fancier-output-formatting)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpushfoo%2Focto-termlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpushfoo%2Focto-termlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpushfoo%2Focto-termlib/lists"}