Skip to content

Releases: coffeedevsolutions/OPHTML

Release list

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 15:35
60810bd

.uib format version 7, unchanged from 0.9.0. pip install ophtml and
npm install -g @ophtml/layout give you this release.

The console launcher

ophtml.elf turns any ps2ui theme into a game launcher: it loads USB, exFAT
HDD, MX4SIO and MMCE drivers, scans each drive for ISOs in OPL's DVD/ and
CD/ layout, fills whatever theme it finds, and hands the selected game to
Neutrino. A theme opts in by using names — nothing in C is the author's to
write.

It is experimental. It has been booted in an emulator in CI and never on a
PlayStation 2.
hw.yml boots a mock build in Play! and diffs its filled
list against the previewer drawing the same games, and console/tests covers
the file names, ISO9660, SYSTEM.CNF, the directory scan and Neutrino's
command line on the host. But no drive has been mounted and no game started on
real hardware: bench cases C1 through C8 in console/README.md are all
open
. Treat a first run on your own console as untested.

Start here: https://coffeedevsolutions.github.io/OPHTML/runtime/console-launcher/
— drive layout, installing Neutrino, putting your own theme.uib beside the
ELF, the names the launcher fills, the controls, and what each status line and
start-up colour means.

Downloads

file sha256
ophtml.elf 9b3f796cdaeb5f9d7bddf2b9979d138106323f07b17b4efb206c5cfe5480f10a
ophtml-mock.elf 9dfa8248bf0c543bee7a458041a54cfb18b49d2df28b2dc7360becd2a024c037

Built in the unpinned ps2dev container with:

mips64r5900el-ps2-elf-gcc (GCC) 15.2.0

ophtml-mock.elf is the mock build CI boots in Play!; ophtml.elf is the one
for a console.


.uib format version 7, unchanged from the release below.
Zero format moves have landed since 0.9.0, which is what a section
opened straight after a release should say: the release under it
shipped the format this tree still writes, so a blob baked here loads
under a 0.9.0 runtime and the other way round.

That count is the one number in this file that starts correct and
decays. It becomes one the moment a format move lands, and
tools/check-versions.py derives it from the section below rather than
reading it back, so the check fails the change that moves the format
without moving this line.

Added

  • The OPHTML console: any ps2ui theme, driven as a game launcher
    (console/).
    Until now a baked UI could draw a game list and do
    nothing with it: the runtime is display-only by design, and device
    I/O and launching were the app's to write, so nobody's UI could list
    or start a game. ophtml.elf loads USB, exFAT HDD, MX4SIO and MMCE
    drivers, scans each drive for ISOs in OPL's DVD/ and CD/ layout
    (title IDs from the name or the disc's SYSTEM.CNF), fills whatever
    theme it finds — theme.uib beside the ELF, then OPHTML/theme.uib
    on a drive, then the built-in examples/console — and hands the
    selected game to Neutrino with -qb through elf-loader's no-reset
    entry point, so Neutrino reads it through the drivers the console
    loaded. A theme opts in by using names (game-{i} rows,
    game-{i}-title, sel-title, status and the rest in
    console/README.md), every one optional; nothing in C is the
    author's to write. Proven so far: console/tests on the host (file
    names, ISO9660, SYSTEM.CNF, the directory scan, Neutrino's command
    line), and hw.yml booting a MOCK build in Play! and diffing its
    filled list against the previewer drawing the same games. Not yet:
    no drive has been mounted and no game started on a console. Bench
    cases C1–C8 in console/README.md are that evidence, and each is
    open.

  • A console theme can be checked, previewed and navigated before it
    reaches a console.
    ps2ui check holds any blob with numbered
    game-N rows or slots to the console's contract: an error for a row the console would
    leave on its placeholder (a gap in game-N, rows on a screen it never
    opens, a slot for a row that doesn't exist), a warning for a name it
    never fills (game-0-titel, with "did you mean 'title'?"), a slot too
    short for what it writes, or rows with no title; ps2ui-check --console forces it on a blob with none. sel-* and status alone
    do not opt a blob in, because other UIs use them for their own panels
    (channel-6 has five sel-* slots); a blob with no numbered row gets
    none of these results, so every other blob's count is unchanged. ps2ui serve --console fills a theme with the mock games
    and walks its list the way the console does. And hw.yml now presses
    buttons at the console in Play! — Down three times, R1, L1 — and
    diffs each frame against the previewer replaying the same keys
    (worst tile 14.4-15.1 correct, 62-72 for a selection or window one
    step off). That build runs on the ROM's pad modules, because Play!
    gives the SDK's sio2man+freepad no input after an IOP reset
    (measured against the ROM pair, which it does answer); so it proves
    the console's navigation, and freepad stays bench case C8. The
    contract, the mock list and the list window now live in
    ps2ui_bake/console.py, which the check, the server and CI's
    reference frames all read.

  • Hard caps on what an untrusted theme may ask the compilers for. A
    theme is a file somebody else wrote, and the compilers accepted
    whatever it asked for. Four caps now, each measured before it was
    chosen: canvas dimensions at 2048, elements at 10000, nesting at 64,
    and a source image at 32 megapixels. Every one is overridable in
    ps2ui.json beside vramBudget -- {"limits": {"nodes": 40000}} --
    because a cap with no escape gets edited out of the source by the
    first person it blocks.

    The numbers come from the shipped corpus rather than from taste.
    Across all 17 screens in examples/ and fixtures/, counted with the
    compiler's own walk after data-repeat expands, the largest is 93
    elements at depth 5, every supported mode is 640x448 or 640x512, and
    the largest source image is 1984x1408. The headroom is each cap's
    own: about 108x for elements, about 13x for depth, and for the canvas
    none of that kind at all, because 2048 is the widest framebuffer the
    hardware scans out rather than a multiple of anything the corpus
    says. "An order of magnitude above the biggest real thing" stood
    here until it was read back against the three.

    They fail rather than warn, which is the opposite of what
    check-doc-impact.py argues for itself and right for the same reason:
    a warning is correct where the work might be fine, and a PlayStation 2
    cannot display a 30000px canvas under any circumstances.

    The escape hatch broke two verbs before it worked. ps2ui check was
    sent a --limit it does not take, and ps2ui dev was sent one it
    did not take either -- the project-file page had listed limits as
    reaching dev the whole time -- so a project declaring any cap got
    unrecognized arguments from the first and a bare usage line from
    the second, while ps2ui build on the same file was fine. Both are
    fixed, and the fence is a test that reads the spawned tool's own
    parser rather than a list maintained beside it. And the flag reached
    both --help outputs before it reached any page that quotes one: the
    two CLI pages and the diagnostics catalogue now carry --limit, the
    three layout caps, the header-read image refusal and the scan-out
    refusal, and a test holds each quoted usage line to the line its bin
    prints, because nothing tied the two together. Re-running every
    sabotage after that found one more: each cap has a test that its
    check fires, and the image cap was the one whose number nothing
    read, so raising it to ten billion left the whole suite green. It is
    held to the corpus, to the default an ordinary bake gets, and to the
    figure the project-file page prints. ps2ui-bake --limit nodes=5 says so too now: a real cap, correctly spelled, handed to
    the tool that does not enforce it, answered until now by
    "takes imagePixels=N with N a positive integer" -- a complaint
    about the 5.

  • The console launcher can be downloaded, and the docs site says how
    to run it.
    Until now ophtml.elf existed only as a CI artifact,
    which needs a GitHub login and expires after fourteen days, or as a
    Docker build of this repository. console-release.yml now runs when
    a version is tagged: it bakes the built-in theme, builds ophtml.elf
    and ophtml-mock.elf from the tag, and attaches both with
    SHA256SUMS to that tag's GitHub Release. A tag with no release gets
    a draft, and a person publishes it (docs/releasing.md step 8b).

    The new site page, Console launcher, covers the drive layout,
    installing Neutrino, putting your own theme.uib beside the ELF,
    the names the launcher fills, the controls, and what each status
    line and start-up colour means. It opens by saying the launcher has
    booted only in an emulator, and it points at the bench cases that
    are still open.

  • A released CHANGELOG section is held to its tag. A merge in #166
    put four entries into the released ## 0.8.0 section with no conflict
    marker, and every tools/check-*.py passed on that state (F53).
    check-versions.py rule 23 now compares each release tag's section,
    heading and body, with git show <tag>:CHANGELOG.md, and fails on a
    difference. The one legitimate difference, v0.3.0's "Tagged and
    published" paragraph written after its tag, is recorded with its
    reason and pinned by hash, so it excuses that text and nothing else.
    The rule runs on pull requests too, which is where that merge was.

  • The .uib loader is fuzzed (S2). runtime/tests/fuzz_load.c
    runs libFuzzer over ps2ui_arena_size, ps2ui_load and everything a
    program does with a blob that loaded, under ASan and UBSan, seeded
    from every blob the repository builds, with each mutation's CRC
    rewritten the way a hostile file would carry one. ci.yml gives it
    60 seconds on e...

Read more