Skip to content

v1.2.3

Choose a tag to compare

@github-actions github-actions released this 01 Nov 12:43
62e63aa

1.2.3 - 2026-11-01

Numbers here describe the source in main, not a run on hardware: 1.2.3 is
built by CI from this commit, and nobody has had it on a calculator yet.

  • The calculator build has been failing since the Pi game landed:
    app_pi.c calls nt_append without including ui/numtext.h. The host
    preview took it as a warning and drew a perfect screenshot; the fxSDK build
    runs -Werror=implicit-function-declaration and stopped, so there has been no
    .g3a since 1.1.0 and the tagged release for 1.2.2 could not exist. The
    include is one line; the reason it went unseen for four merges is that the two
    builds disagreed about which warnings matter, so the preview now compiles with
    the same -Werror=implicit-function-declaration as the calculator and the
    candidate .g3a cannot be the only thing that finds it.

  • The committed WebAssembly build is rebuilt from these sources, so the
    simulator on the site is the same code as the screenshots again. Its smoke
    runs (down,exe and the worker path) pass. Unverified on device.

  • The screen checker can see a label sitting on a border: it compared
    rectangles, so two things that merely touched were "not overlapping" and
    passed. The menu's first-run hint spent eleven merged pull requests with its
    ascenders on the bottom tile border, and 97 green screenshots said nothing
    about it. scr_frame is traced now - scr_fill records only panels of 8x4 or
    more, and a two-pixel border is exactly the size that goes wrong - and a label
    within two pixels of any frame, inside or out, fails the run. Checked against
    the old layout: it reports the hint and nothing else, so the rule has teeth
    without inventing work on the other 96 screens. docs/design.md lists it.
    Unverified on device.

  • The softkey bar has room to breathe, and the first-run hint is no longer
    jammed into the tiles
    : a 10-pixel label in a 16-pixel bar left three pixels
    above and below, so the six labels read as text pressed into a slot rather
    than six buttons. The bar is 20 pixels now, dividers stop short of its top and
    bottom edges, a label keeps at least four pixels from the separator beside it
    and is ellipsised rather than run into its neighbour, and the bar grows into
    the content area on all thirteen screens at once because every screen places
    its footer relative to TH_SOFT_H. The menu's first-run hint also had its
    ascenders on the bottom tile border: it now has its own band, sized from the
    text, and the grid stops clear of it, so there are eight pixels above the
    words and five below. The line also lost the words "a tile" so it keeps a
    margin at both ends instead of running edge to edge. Unverified on device.

  • The site was not deploying at all: node scripts/gen-tools.mjs has failed
    on every push since the four V2 tools landed, because each says in its own
    words what it does and site/src/toolCopy.js still listed twenty-two of them.
    The build reported "registry tool "factor" (Prime factors) has no copy" and
    stopped, so the last successful deployment predates Prime factors, Percentages,
    the Formula book and the Pi game. All four are in toolCopy.js now, with their
    real screenshots, and are in the "own words" set that needs proofreading.

  • The download picks the newest build by version, not by file date: dist/
    is a git checkout, so every .g3a in it is written at the same moment and the
    order the filesystem hands back decided which one the page offered. It offered
    1.0.0 while 1.1.0 sat beside it. The fallback compares the numbers in the file
    name now, and a build's commit and date are dropped when the bytes came from a
    different file than the one BUILD.txt describes.

  • CodeRabbit, configured in the repository instead of a dashboard:
    .coderabbit.yaml tells the reviewer what this project actually breaks on -
    src/core must not include gint or libm, a screen may only use the nine
    palette colours with 2 px ink borders and a 3 px shadow under the selected
    item, a new core function needs a test with a concrete vector, a regenerated
    table is not a code change, and files are written to flash only at session
    end. Generated files, images, binaries and the site lockfile are out of scope,
    poems and UML diagrams are off, and automatic approvals are off because
    merging here depends on whether anyone ran the build on a calculator.
    tools/check_coderabbit.py parses the YAML with its own small reader - no new
    dependency - and rejects an unknown key, a path_instructions glob that
    matches no file (how a rule for a renamed directory stops applying), a tool
    switched on with no config file or for a language the repository does not
    contain, tabs and CRLF. make coderabbit-check runs it and CI runs that.
    Installing the GitHub App is the one step a commit cannot do;
    docs/CODERABBIT.md has the four clicks. Unverified on device.

  • A version number that moves with the work, and a check that it did: the
    tree said 1.1.0 through fourteen merged pull requests, so the About screen, the
    .g3a name and the website would have disagreed with the changelog the moment
    anything shipped. The rule is now that every change bumps the version in the
    same commit - patch for a fix or a doc, minor for a feature, major only for a
    storage-layout change - and the version of record is 1.2.0. tools/ bump_version.py rewrites version.txt, the src/version.h fallback and the
    example file name in CMakeLists.txt in one command (make bump-minor,
    make bump-patch), and --check compares those against the changelog heading
    and the README badge, naming each file that disagrees. make test runs it, and
    so does CI, so a forgotten bump fails a build instead of shipping. 21 Python
    tests cover the arithmetic and the rewriting, including that a bad version is
    refused before any file is touched. The README's version badge now links to the
    releases page rather than to releases/tag/v<version>, because between a bump
    and a release there is no such tag and a badge pointing at a 404 is a lie about
    a page. Unverified on device.

  • Percentages tool: the four questions a paper asks - percentage change,
    add or take a percentage, reverse percentage, compound growth or depreciation -
    on one Math screen, with the working written out under the answer. The point
    of the reverse question is that it divides (34 / (1 - 15/100) = 40), which is
    what people get wrong by adding 15% of 34 back on. src/core/percent.c with 41
    checks covers the vectors (500 at 4.5% for 7 years is 680.43; a car at 12% for
    5 years keeps 52.8%), zero years, a negative rate, and the three questions with
    no answer - a change from zero, a 100% discount, a period count outside 0..200

    • each of which is a sentence on screen rather than a 0 or an inf. One bug
      caught by the tests before the screen existed: the fast exponentiation gave up
      on an overflow by returning the principal, so a question with an unshowable
      answer said "no growth". Unverified on device.
  • The formula book: the IB AA HL, Physics 2025 and Chemistry 2025 booklet
    content, as a Study tile called Formula book. The booklets are plain text in
    Bench/formulas/, one .txt per booklet, so a teacher (or you) can add one
    without a rebuild - the list shows every file in the folder and its first #
    line as the description. The viewer scrolls a line at a time and jumps a
    topic at a time with LEFT/RIGHT, headings coloured red, blue and ink by
    level. New src/core/formula.c holds the line and heading arithmetic with 40
    checks, including that a jump ignores ### sub-headings - with those counted,
    a booklet with a heading every few lines moved five lines a press, which is
    not a section.
    The content is a transcription nobody has proofread yet: the PDFs print
    formulae as images, so the text was typed, and it is marked as unproofread in
    three places - the first line of every booklet, docs/samples/formulas/ needs-human-proofreading/README.md, and the help page. Treat an unproofed
    line as unchecked.

  • The Pi game: a Study tile. The digits you have earned stay on screen,
    grouped five to a line; type the next ones, EXE checks them, and the first
    wrong digit costs a life. Three lives, F2 gives the next digit away and costs
    one - a hint that is free is not part of a game - and the round ends with how
    far you got and the best of the session. Nothing is written to the card, so
    the best score lives and dies with the session, which is what the file-write
    rule allows. The digits are src/core/pi.c: 200 of them, and
    tests/test_pi.c checks the table against a Rabinowitz-Wagon spigot computed
    from the algorithm rather than copied - a typo in the table cannot hide by
    being duplicated in the test (40 checks, first 100 digits plus the human
    check that the 100th decimal is 9). pi_match stops at the first wrong digit
    so a guess that runs off the end cannot read past the table.
    Unverified on device.

  • Prime factors, on its own screen in Math: factorisation existed, three
    levels down a list of nine Number theory functions, which is not where anyone
    looks for it. The new screen takes a number up to 18 digits and shows the
    factorisation written out - 360 = 2^3 x 3^2 x 5 - with the four numbers that
    follow from it: divisor count, divisor sum, totient and square-free part, plus
    how many distinct primes and whether the number is a perfect square. F2 halves
    the number and factors again, which is the question that usually comes next.
    New in core/numtheory.c, each with vectors checked by hand (1091 checks in
    that suite): nt_factor_text (exact buffer arithmetic, so a text of exactly
    the buffer's length is accepted and one byte less refused),
    nt_divisor_count, nt_divisor_sum (the geometric series without a division,
    wrapping checked), nt_factor_radical and nt_factor_is_square.
    Unverified on device: how long the rho routine takes on a real CPU for a
    hard 18-digit semiprime, and the screen draws no progress bar because of it.

  • About says who made it: the page was one screenful of version numbers. It
    now says whose work it is (Sarang, github.com/sarang-cmd), what it is, how it
    was made - maths in plain C tested without a calculator, screens a thin layer
    over gint, every doc picture a real simulator frame, builds from GitHub
    Actions - and keeps the build facts and the Exam Mode promise at the end. The
    page is longer than the screen, so it scrolls with the bar and UP/DOWN;
    scrolling reuses core/help.c's tested rules. Tour 84 and 85 are its two
    ends. Also: src/version.h's fallback said 1.0.0 while version.txt said
    1.1.0, so the simulator's About screen was a release behind the add-in it was
    drawing - the fallback is 1.1.0 now. Unverified on device.

  • Three more settings, and three places they reach: Settings had five rows
    and two of them were read-only information. It has eight now, and each one
    does something:

    • Opens on - which category the home screen starts on, so someone who
      lives in Science does not press F3 every launch.
    • Show hint line - the first-run line on the home screen can be turned off
      for good without having to open Help first.
    • Pacer clock red at - minutes remaining when the Pacer's "Left mm:ss"
      line turns red, 0 to never. Default 5.

    All three are lines in Bench/state/settings.cfg as well, so they can be
    edited by hand, and a file from an older build still loads: the new keys are
    absent, the defaults stand (checked in tests/test_settings.c, 721 checks,
    including an out-of-range hand edit being clamped rather than rejected).
    Unverified on device.

  • The Tools category, centred: "so awkward" was about Tools holding two
    tiles hard against the left margin with a third of the screen empty beside
    them. A row that is not full is centred under the one above it now, which
    leaves a full row exactly where it was. src/core/layout.c (21 native checks:
    full and short rows, a row wider than the screen, an empty row, the per-row
    count at a page boundary). Study's fourth tile and Science's short row move
    with it, since they were the same shape of problem. Unverified on device.

  • The page indicator, and the missing Math title bar: a category with more
    than six tools paged with two 4 px squares and a hole punched in the current
    one - "too subtle" was the report, and it was right: at 384 px that reads as
    dust. The indicator is now a bordered pill reading 1 / 2 with an arrow on
    each side that leads somewhere (only the live ones are drawn; a greyed one
    would be shade on paper at 1.3:1, which the screen checker rejects). The pill
    takes the space it needs only in categories that page, so every other category
    keeps the full grid. Chasing it found a second bug: the centring maths counted
    every tool in the category rather than the tools on the page, so Math's nine
    tools meant three rows of height, a negative offset, and the first row drawn
    over the title bar - the Math category had no title at all since the V2 push.
    Both are fixed, and tests/test_pageind.c checks the label, the arrow states
    and the clamping (31 checks), including the 10 / 12 two-digit case and a
    buffer one byte too small. Unverified on device.

  • A scrollbar on every screen that scrolls: a Notes file, a deck list, the
    study log, the root finder's iteration table and a help page all scrolled with
    nothing on screen saying so. The bar is now three pixels wide (it was two, a
    hairline at 384 px), ink thumb on a shade track, 12:1 and 4:1 in the palette
    with no new colours. It is drawn only when there is something off-screen, and
    the position is a fraction of the list, so the last screen shows the thumb at
    the bottom and nothing is drawn for a list that fits. Unverified on
    device
    : the bar is checked in the simulator against the pixel rules
    (make check-screens), not on the calculator's panel.

  • A folder full of notes that the add-in could not see: three matching bugs,
    all on the way out of the filesystem rather than in it. The glob was built as
    * plus the extension, which CASIOWIN's BFile_FindFirst answers with nothing
    on some OS versions; the extension test was case sensitive, so a Windows copy
    saved as .MD was invisible; and the OS's ./.. entries were not filtered.
    The rules are now src/core/filelist.c (56 native checks: case, leading dots,
    separators, double extensions, a buffer one byte too small), the listing tries
    both wildcard spellings and filters in C, and the empty screen names the folder
    and says the case does not matter. Unverified on device: the two-glob retry
    exists because of how CASIOWIN is documented, and only a calculator can confirm
    which spelling its Fugue build wants.

  • EXIT goes back where you came from: closing a tool used to land on the home
    screen with Study selected, first tile, every single time - so a Maths or
    Science session meant walking back to the right category after every tool.
    The add-in now keeps a small stack of the screens it came through
    (src/core/nav.c, 525 native checks over push/pop, repeat pushes, a full
    stack and 500 random presses). EXIT and the help screen's way out both walk
    back one screen at a time, and the home screen remembers the category and the
    tile you were on instead of resetting itself. Two tour scripts record it:
    78_back_to_maths and 79_back_from_settings_about.

  • The browser simulator has the calculator's keypad: it was a flat 5-column
    grid that followed no physical keyboard - DEL next to 9, ALPHA where x² is,
    arrows spread over two rows. It is now the fx-CG 50 layout: six function keys
    with the case's own captions, the SHIFT/OPTN/VARS/MENU and ALPHA blocks, the
    four-way pad on the right where the real one sits, and 7-8-9-DEL-AC /
    4-5-6-×-÷ / 1-2-3-+-(−) / 0-.-×10ˣ-(−)-EXE. Keys Bench does not read are drawn
    as muted hardware rather than pretending to work; every live key is a real
    button with an aria-label. Checked at 320, 390 and 1280px: no horizontal
    scroll, smallest key 26px.

  • The diagnostic add-in is on the site and in dist/: Bench-spike-0.0.2.g3a
    is now published beside Bench's own .g3a - in dist/ with a SPIKE.txt
    manifest, and on the downloads page under "The diagnostic add-in" - instead of
    being reachable only as a CI artifact on blob storage. The patch
    (spike.diff) is downloadable from the same place, so the spike can be had
    even when no binary has been built. It is still labelled as a diagnostic
    everywhere and still never appears on a release or next to the install button.

  • The hero band stops cutting the g: the yellow behind "in one" was
    clipping the descender of the g in "eighteen". Two causes: Tailwind's
    text-5xl/text-6xl set their own line-height and were beating the h1's
    leading-[1.35], so the heading ran on a 1.0 line box; and the band was an
    inline box, which paints over the font's content area, which at 60px is taller
    than the line. The heading now sets its line-height at every breakpoint and
    the band is an inline-block at line-height 1. site/scripts/check-band.mjs
    counts the neighbour pixels the band covers - 331 at 1280px before, 0 at every
    width from 320 to 1440px now - and runs in CI after the width sweep.