Skip to content

Commit e26e59d

Browse files
committed
textat x,y
1 parent 7fcd019 commit e26e59d

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,27 @@ Run this once after unpacking, and macOS will stop treating the binary as “fro
8585

8686
- **`SLEEP`**: pause execution for a number of 60 Hz “ticks” (e.g., `SLEEP 60` ≈ 1 second).
8787

88+
### Screen coordinates and cursor positioning
89+
90+
- **Coordinate system**:
91+
- `LOCATE col, row` and `TEXTAT col, row, text` both use **0‑based** screen coordinates, where `0,0` is the top‑left corner.
92+
- Internally these are mapped to ANSI escape sequences as `ESC[row+1;col+1H`.
93+
- **`LOCATE`**:
94+
- Moves the cursor without printing: e.g. `LOCATE 10,5` positions the cursor at column 10, row 5 before the next `PRINT`.
95+
- **`TEXTAT`**:
96+
- `TEXTAT x, y, text` moves the cursor to `(x, y)` and writes `text` directly at that absolute position.
97+
- `text` is any string expression, for example: `TEXTAT 0, 0, "SCORE: " + STR$(S)`.
98+
- **Keeping final text visible**:
99+
- Terminals often print the shell prompt immediately after your program exits; if your last output is on the bottom row, an implicit newline or prompt can scroll it off‑screen.
100+
- To make sure your final UI remains visible, **explicitly position the cursor after your last `TEXTAT`/`LOCATE` output**, for example:
101+
102+
```basic
103+
LOCATE 0, 22
104+
PRINT "PRESS ANY KEY TO CONTINUE";
105+
```
106+
107+
- This ensures the cursor (and thus any following prompt) appears where you expect, rather than accidentally pushing your last line out of view.
108+
88109

89110
## 🎛️ Usage
90111

basic.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ static void statement_read(char **p);
219219
static void print_value(struct value *v);
220220
static void print_spaces(int count);
221221
static void statement_sleep(char **p);
222+
static void statement_textat(char **p);
222223
static void statement_def(char **p);
223224
static void statement_get(char **p);
224225
static void do_sleep_ticks(double ticks);
@@ -2090,6 +2091,45 @@ static void statement_print(char **p)
20902091
}
20912092

20922093

2094+
static void statement_textat(char **p)
2095+
{
2096+
struct value vx, vy, vtext;
2097+
int x, y;
2098+
2099+
/* TEXTAT x, y, text */
2100+
vx = eval_expr(p);
2101+
ensure_num(&vx);
2102+
skip_spaces(p);
2103+
if (**p != ',') {
2104+
runtime_error("TEXTAT: expected ',' after X");
2105+
return;
2106+
}
2107+
(*p)++;
2108+
2109+
vy = eval_expr(p);
2110+
ensure_num(&vy);
2111+
skip_spaces(p);
2112+
if (**p != ',') {
2113+
runtime_error("TEXTAT: expected ',' after Y");
2114+
return;
2115+
}
2116+
(*p)++;
2117+
2118+
vtext = eval_expr(p);
2119+
ensure_str(&vtext);
2120+
2121+
x = (int)vx.num;
2122+
if (x < 0) x = 0;
2123+
y = (int)vy.num;
2124+
if (y < 0) y = 0;
2125+
2126+
/* Move cursor with ANSI: rows/cols are 1-based */
2127+
printf("\033[%d;%dH", y + 1, x + 1);
2128+
fputs(vtext.str, stdout);
2129+
fflush(stdout);
2130+
}
2131+
2132+
20932133
static void statement_locate(char **p)
20942134
{
20952135
// Passed as LOCATE x, y
@@ -2538,6 +2578,11 @@ static void execute_statement(char **p)
25382578
statement_let(p);
25392579
return;
25402580
}
2581+
if (c == 'T' && starts_with_kw(*p, "TEXTAT")) {
2582+
*p += 6;
2583+
statement_textat(p);
2584+
return;
2585+
}
25412586
if (c == 'L' && starts_with_kw(*p, "LOCATE")) {
25422587
*p += 6;
25432588
statement_locate(p);

0 commit comments

Comments
 (0)