Repository navigation
v1.2.3
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.ccallsnt_appendwithout includingui/numtext.h. The host
preview took it as a warning and drew a perfect screenshot; the fxSDK build
runs-Werror=implicit-function-declarationand stopped, so there has been no
.g3asince 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-declarationas the calculator and the
candidate.g3acannot 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,exeand 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_frameis traced now -scr_fillrecords 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.mdlists 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 toTH_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.mjshas failed
on every push since the four V2 tools landed, because each says in its own
words what it does andsite/src/toolCopy.jsstill 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 intoolCopy.jsnow, 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.g3ain 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 oneBUILD.txtdescribes. -
CodeRabbit, configured in the repository instead of a dashboard:
.coderabbit.yamltells the reviewer what this project actually breaks on -
src/coremust 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.pyparses the YAML with its own small reader - no new
dependency - and rejects an unknown key, apath_instructionsglob 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-checkruns it and CI runs that.
Installing the GitHub App is the one step a commit cannot do;
docs/CODERABBIT.mdhas 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
.g3aname 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.pyrewritesversion.txt, thesrc/version.hfallback and the
example file name inCMakeLists.txtin one command (make bump-minor,
make bump-patch), and--checkcompares those against the changelog heading
and the README badge, naming each file that disagrees.make testruns 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 toreleases/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.cwith 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.
- each of which is a sentence on screen rather than a 0 or an inf. One bug
-
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.txtper 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. Newsrc/core/formula.cholds 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 aresrc/core/pi.c: 200 of them, and
tests/test_pi.cchecks 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_matchstops 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 incore/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_radicalandnt_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 andUP/DOWN;
scrolling reusescore/help.c's tested rules. Tour 84 and 85 are its two
ends. Also:src/version.h's fallback said 1.0.0 whileversion.txtsaid
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.cfgas 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 intests/test_settings.c, 721 checks,
including an out-of-range hand edit being clamped rather than rejected).
Unverified on device. - Opens on - which category the home screen starts on, so someone who
-
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 reading1 / 2with 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, andtests/test_pageind.cchecks 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'sBFile_FindFirstanswers with nothing
on some OS versions; the extension test was case sensitive, so a Windows copy
saved as.MDwas invisible; and the OS's./..entries were not filtered.
The rules are nowsrc/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_mathsand79_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- indist/with aSPIKE.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 thegin "eighteen". Two causes: Tailwind's
text-5xl/text-6xlset their own line-height and were beating theh1'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.