Skip to content

Commit faadabb

Browse files
committed
Let a number end where the reader says it does
Four fixed boxes made 240 a dead end. No fourth digit takes 240x into 1..2048, so the reader who typed it found a box holding nothing but backspace, and the only way to mean 240 was to have known to type 0240 from the start. The field is variable length now. The ring carries the digits that still lead somewhere, then OK once what is typed already names a word, then backspace - the same ring Jade's index entry uses, where a short number also has to be able to stop early. 240 is three presses and an OK. Ending early is not a convenience here. Without it, three-digit numbers are not reachable at all except by a leading zero the reader has no reason to expect. OK appears only once the digits already name a word, so an empty field does not offer it. On a prefix like 20 it does appear, because 20 is both a number and a step towards 200x - both readings are live, which is why the reader is the one who says which was meant. A fourth digit still confirms itself: there is no fifth box to put an OK in. Going back from the confirmation reopens the fourth digit when it was the fourth digit that confirmed, and returns to the field untouched when the reader ended with OK.
1 parent 8ddba4a commit faadabb

2 files changed

Lines changed: 40 additions & 19 deletions

File tree

‎main/seedtool_app.c‎

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -883,13 +883,16 @@ static int enter_word(const size_t position, const size_t total, char* output, c
883883
* misread off paper is otherwise a different seed with no sign that anything
884884
* went wrong.
885885
*
886-
* Four boxes, always four, scrolled one at a time - the printed wordlist pads
887-
* to four digits and whoever reads `0004` off it types all four, so a fixed
888-
* width costs nothing and removes the Accept key along with the question of
889-
* when a number is finished. Only digits that still leave a word number
890-
* reachable are on the ring, which is what keeps 2049 untypeable while 2048
891-
* stays reachable; the ring carries a backspace past the last digit, the way
892-
* enter_value's own ring carries [back].
886+
* Up to four boxes, scrolled one at a time, and a number ends where the reader
887+
* says it does: `240` is typed as three digits, not as `0240`. The ring for the
888+
* current box carries the digits that still lead somewhere, then OK once what
889+
* is typed is already a word number, then backspace - the same ring Jade's
890+
* index entry uses, where a short number also has to be able to stop early.
891+
*
892+
* A fixed four-box field was tried first and was wrong: it made 240 a dead end,
893+
* since no fourth digit takes 240x into 1..2048, so the reader who typed it
894+
* found a box with nothing in it but backspace. Ending the number early is not
895+
* a convenience here, it is what makes three-digit numbers reachable at all.
893896
*
894897
* Replaces a twelve-key keypad the reader had to walk a cursor across. Two
895898
* buttons that mean "the digit goes up" and "the digit goes down" need no
@@ -907,7 +910,7 @@ static int enter_word_number(const size_t position, const size_t total, char* ou
907910
/* The ring for the current box: the digits still reachable, then backspace.
908911
* Rebuilt whenever the box changes, since which digits are reachable
909912
* depends on the ones already set. */
910-
char ring[SEEDTOOL_DIGITS + 1];
913+
char ring[SEEDTOOL_DIGITS + 2];
911914
size_t ring_len = 0, on = 0;
912915
bool rebuild = true;
913916

@@ -921,6 +924,14 @@ static int enter_word_number(const size_t position, const size_t total, char* ou
921924
ring[ring_len++] = (char)('0' + d);
922925
}
923926
}
927+
/* OK only once the digits already name a word - so it is absent on
928+
* an empty field and on a prefix like `20`, which is a real number
929+
* but is offered here as a step towards 200x rather than as 20
930+
* itself... which it also is. Both readings are live, which is
931+
* exactly why the reader has to say which one they meant. */
932+
if (seedtool_word_number(digits, at)) {
933+
ring[ring_len++] = SEEDTOOL_KEY_ACCEPT;
934+
}
924935
ring[ring_len++] = SEEDTOOL_KEY_BACKSPACE;
925936
on = 0;
926937
rebuild = false;
@@ -963,15 +974,19 @@ static int enter_word_number(const size_t position, const size_t total, char* ou
963974
rebuild = true;
964975
continue;
965976
}
966-
digits[at++] = ring[on];
967-
digits[at] = '\0';
968-
rebuild = true;
969-
if (at < SEEDTOOL_MAX_WORD_DIGITS) {
970-
continue;
977+
bool typed_last = false;
978+
if (ring[on] != SEEDTOOL_KEY_ACCEPT) {
979+
digits[at++] = ring[on];
980+
digits[at] = '\0';
981+
rebuild = true;
982+
/* A fourth digit has nowhere left to go, so it confirms itself
983+
* rather than asking for an OK the field has no box to show. */
984+
if (at < SEEDTOOL_MAX_WORD_DIGITS) {
985+
continue;
986+
}
987+
typed_last = true;
971988
}
972989

973-
/* Four digits in: the number is complete by construction, since the
974-
* ring never offered a digit that could not lead to one. */
975990
const unsigned number = seedtool_word_number(digits, at);
976991
const char* const word = number ? seedtool_word(number - 1) : NULL;
977992
char counted[32];
@@ -992,9 +1007,13 @@ static int enter_word_number(const size_t position, const size_t total, char* ou
9921007
seedtool_zero(shown, sizeof(shown));
9931008
return -1;
9941009
}
995-
/* Went back from the confirmation: the last digit reopens, so a wrong
996-
* final digit costs one press rather than the whole number. */
997-
digits[--at] = '\0';
1010+
/* Went back from the confirmation. A number that confirmed itself on a
1011+
* fourth digit reopens that digit, so a wrong last one costs a press
1012+
* rather than the whole number; one the reader ended with OK returns to
1013+
* the field exactly as it was, with the OK still on the ring. */
1014+
if (typed_last) {
1015+
digits[--at] = '\0';
1016+
}
9981017
rebuild = true;
9991018
}
10001019
}

‎main/seedtool_render.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,9 @@ void seedtool_render_digits(const char* title, const char* digits, const size_t
711711

712712
const char shown = digits[i];
713713
const int glyph_y = DIGIT_BOX_Y + (DIGIT_BOX_HEIGHT - tft_Ubuntu16[1]) / 2;
714-
if (shown == SEEDTOOL_KEY_BACKSPACE) {
714+
if (shown == SEEDTOOL_KEY_ACCEPT) {
715+
draw_centered_in(tft_Ubuntu16, "OK", x, DIGIT_BOX_WIDTH, glyph_y, selected ? COLOR_BLACK : COLOR_WHITE);
716+
} else if (shown == SEEDTOOL_KEY_BACKSPACE) {
715717
/* The way out of the field rides the same ring as the digits, so
716718
* the box shows the backspace glyph the keypad already uses for
717719
* it rather than a letter the reader has to decode. */

0 commit comments

Comments
 (0)