Skip to content

Commit 5eaf2ee

Browse files
SCROLLREGION
1 parent 0880bd0 commit 5eaf2ee

8 files changed

Lines changed: 201 additions & 34 deletions

File tree

include/basic/console.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ int64_t basic_capslock(struct basic_ctx* ctx);
131131
*/
132132
void input_statement(struct basic_ctx* ctx);
133133

134+
135+
/**
136+
* @brief Handle SCROLLREGION statement.
137+
*
138+
* @param ctx The BASIC context.
139+
*/
140+
void scrollregion_statement(struct basic_ctx* ctx);
141+
134142
/**
135143
* @brief Process GET statement to read a single keypress.
136144
*

include/basic/tokenizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ typedef void (*keyword_handler_t)(struct basic_ctx*);
202202
T(UNLOAD, STMT, NULL) /* 130 */ \
203203
T(ENVELOPE, STMT, envelope_statement) /* 131 */ \
204204
T(TONE, STMT, NULL) /* 132 */ \
205+
T(SCROLLREGION, STMT, scrollregion_statement) /* 133 */ \
205206

206207
GENERATE_ENUM_LIST(TOKEN, token_t)
207208

include/flanterm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ extern "C" {
4242
#define FLANTERM_CB_KBD_LEDS 60
4343
#define FLANTERM_CB_MODE 70
4444
#define FLANTERM_CB_LINUX 80
45+
#define FLANTERM_CB_SCROLL 90
4546

4647
#define FLANTERM_OOB_OUTPUT_OCRNL (1 << 0)
4748
#define FLANTERM_OOB_OUTPUT_OFDEL (1 << 1)

include/video.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,6 @@ unsigned char map_vga_to_ansi_bg(unsigned char colour);
256256

257257
void redefine_character(unsigned char c, uint8_t bitmap[8]);
258258

259-
void graphics_putstring(const char *s, int64_t x, int64_t y, int32_t colour);
259+
void graphics_putstring(const char *s, int64_t x, int64_t y, int32_t colour);
260+
261+
int add_scrollable(int64_t start, int64_t end);

os/programs/about.rrbasic

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,75 @@
1+
REM Retro Rocket "about" program.
2+
REM
3+
REM Similar to "neofetch".
4+
REM Be careful about where you write characters in the space where you
5+
REM plot the rocky PNG and colour palette spectrum. If you write a blank
6+
REM line anywhere, it will manifest as a vertical bar across the image
7+
REM when you scroll due to the way flanterm is optimised
8+
REM
19
SPRITELOAD owl,"/images/owl.png"
210
AUTOFLIP FALSE
3-
REM Go down 20 lines, then back up, to make room on screen for the images
4-
FOR Y = 0 TO 19
5-
PRINT ""
11+
REM Go down 25 lines, then back up, to make room on screen for the images
12+
FOR Y = 0 TO 24
13+
PRINT " "
614
NEXT
7-
CURSOR 0, CURRENTY - 19
15+
CURSOR 0, CURRENTY - 24
16+
STARTY=CURRENTY
817
SPRTOP=CURRENTY*8
918
COLOUR 14
10-
PRINT " Retro Rocket"
19+
Y=CURRENTY
20+
CURSOR 34,Y
21+
PRINT "Retro Rocket";
1122
COLOUR 7
12-
PRINT " ────────────"
23+
Y = Y + 1
24+
CURSOR 34,Y
25+
PRINT "────────────";
1326
COLOUR 14
14-
PRINT " OS: ";
27+
Y = Y + 1
28+
CURSOR 34,Y
29+
PRINT "OS: ";
1530
COLOUR 7
16-
PRINT "Retro Rocket 1.0"
31+
PRINT "Retro Rocket 1.0";
1732
COLOUR 14
18-
PRINT " Kernel: ";
33+
Y = Y + 1
34+
CURSOR 34,Y
35+
PRINT "Kernel: ";
1936
COLOUR 7
20-
PRINT "1.0"
37+
PRINT "1.0";
2138
COLOUR 14
22-
PRINT " Uptime: ";
39+
Y = Y + 1
40+
CURSOR 34,Y
41+
PRINT "Uptime: ";
2342
COLOUR 7
24-
PRINT UPTIME$
43+
PRINT UPTIME$;
2544
COLOUR 14
26-
PRINT " Shell: ";
45+
Y = Y + 1
46+
CURSOR 34,Y
47+
PRINT "Shell: ";
2748
COLOUR 7
28-
PRINT "rocketsh-2.0"
49+
PRINT "rocketsh-2.0";
2950
COLOUR 14
30-
PRINT " Memory: ";
51+
Y = Y + 1
52+
CURSOR 34,Y
53+
PRINT "Memory: ";
3154
COLOUR 7
3255
M_MEGS = MEMUSED / 1024 / 1024
3356
MT_MEGS = MEMORY / 1024 / 1024
34-
PRINT M_MEGS; "MiB / "; MT_MEGS ; "MiB"
57+
PRINT M_MEGS; "MiB / "; MT_MEGS ; "MiB";
3558
COLOUR 14
36-
PRINT " Resolution: ";
59+
Y = Y + 1
60+
CURSOR 34,Y
61+
PRINT "Resolution: ";
3762
COLOUR 7
38-
PRINT GRAPHICS_WIDTH; "x"; GRAPHICS_HEIGHT
63+
PRINT GRAPHICS_WIDTH; "x"; GRAPHICS_HEIGHT;
3964
COLOUR 14
40-
PRINT " CPU: ";
65+
Y = Y + 1
66+
CURSOR 34,Y
67+
PRINT "CPU: ";
4168
COLOUR 7
42-
PRINT CPUGETBRAND$(1)
43-
PRINT " ";
44-
GRADLEFT=CURRENTX*8
45-
GRADTOP=CURRENTY*8+8
46-
FOR N = 0 TO 14
47-
PRINT ""
48-
NEXT
69+
PRINT CPUGETBRAND$(1);
70+
GRADLEFT=34*8
71+
GRADTOP=CURRENTY*8+16
72+
CURSOR 0, CURRENTY + 17
4973
PLOT owl,32,SPRTOP
5074
X = GRADLEFT
5175
W = 128
@@ -88,4 +112,7 @@ FOR I = 0 TO W - 1
88112
LINE X, GRADTOP, X, GRADTOP + H
89113
X = X + 1
90114
NEXT
91-
AUTOFLIP TRUE
115+
AUTOFLIP TRUE
116+
PRINT " "
117+
ENDY=CURRENTY
118+
SCROLLREGION STARTY, ENDY - 1

src/basic/console.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ void cls_statement(struct basic_ctx* ctx)
139139
accept_or_return(NEWLINE, ctx);
140140
}
141141

142-
void gotoxy_statement(struct basic_ctx* ctx)
143-
{
142+
void gotoxy_statement(struct basic_ctx* ctx) {
144143
accept_or_return(CURSOR, ctx);
145144
int64_t x = expr(ctx);
146145
accept_or_return(COMMA, ctx);
@@ -149,6 +148,15 @@ void gotoxy_statement(struct basic_ctx* ctx)
149148
accept_or_return(NEWLINE, ctx);
150149
}
151150

151+
void scrollregion_statement(struct basic_ctx* ctx) {
152+
accept_or_return(SCROLLREGION, ctx);
153+
int64_t top = expr(ctx) * 8;
154+
accept_or_return(COMMA, ctx);
155+
int64_t bottom = expr(ctx) * 8 + 8;
156+
add_scrollable(top, bottom);
157+
accept_or_return(NEWLINE, ctx);
158+
}
159+
152160
void print_statement(struct basic_ctx* ctx) {
153161
accept_or_return(PRINT, ctx);
154162
const char* out = printable_syntax(ctx);

src/flanterm/fb.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ static void flanterm_fb_revscroll(struct flanterm_context *_ctx) {
263263
static void flanterm_fb_scroll(struct flanterm_context *_ctx) {
264264
struct flanterm_fb_context *ctx = (void *) _ctx;
265265

266-
for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols;
267-
i < _ctx->scroll_bottom_margin * _ctx->cols; i++) {
266+
for (size_t i = (_ctx->scroll_top_margin + 1) * _ctx->cols; i < _ctx->scroll_bottom_margin * _ctx->cols; i++) {
268267
struct flanterm_fb_char *c;
269268
struct flanterm_fb_queue_item *q = ctx->map[i];
270269
if (q != NULL) {
@@ -283,6 +282,10 @@ static void flanterm_fb_scroll(struct flanterm_context *_ctx) {
283282
for (size_t i = 0; i < _ctx->cols; i++) {
284283
push_to_queue(_ctx, &empty, i, _ctx->scroll_bottom_margin - 1);
285284
}
285+
286+
if (_ctx->callback != NULL) {
287+
_ctx->callback(_ctx, FLANTERM_CB_SCROLL, 0, 0, 0);
288+
}
286289
}
287290

288291
static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) {

src/video.c

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ volatile struct limine_framebuffer_request framebuffer_request = {
77
.revision = 0,
88
};
99

10+
11+
#define MAX_SCROLLABLES 256
12+
13+
typedef struct scrollable_graphics_t {
14+
int64_t start;
15+
int64_t end;
16+
} scrollable_graphics_t;
17+
18+
static scrollable_graphics_t scrollables[MAX_SCROLLABLES];
19+
static int scrollable_count = 0;
20+
1021
struct limine_framebuffer *fb = NULL;
1122
static uint64_t bytes_per_pixel = 32;
1223
static void *rr_fb_front = NULL;
@@ -91,6 +102,45 @@ static uint8_t font_data[] = { // 8x8
91102
0x00, 0x2e, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x38, 0x08, 0x38, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92103
};
93104

105+
106+
/* Insert a band [start, end), keeping the list sorted by start */
107+
int add_scrollable(int64_t start, int64_t end) {
108+
if (scrollable_count >= MAX_SCROLLABLES) {
109+
return -1; /* list full */
110+
}
111+
112+
int pos = 0;
113+
while (pos < scrollable_count && scrollables[pos].start < start) {
114+
pos++;
115+
}
116+
117+
/* shift up to make room */
118+
for (int i = scrollable_count; i > pos; i--) {
119+
scrollables[i] = scrollables[i - 1];
120+
}
121+
122+
scrollables[pos].start = start;
123+
scrollables[pos].end = end;
124+
scrollable_count++;
125+
126+
return 0;
127+
}
128+
129+
/* Remove a band matching [start, end) */
130+
int remove_scrollable(int64_t start, int64_t end) {
131+
for (int i = 0; i < scrollable_count; i++) {
132+
if (scrollables[i].start == start && scrollables[i].end == end) {
133+
/* shift down */
134+
for (int j = i; j < scrollable_count - 1; j++) {
135+
scrollables[j] = scrollables[j + 1];
136+
}
137+
scrollable_count--;
138+
return 0;
139+
}
140+
}
141+
return -1; /* not found */
142+
}
143+
94144
void rr_console_init_from_limine(void) {
95145
fb = framebuffer_request.response->framebuffers[0];
96146
dprintf("fb front: %lx\n", (uint64_t)fb->address);
@@ -218,11 +268,78 @@ void terminal_callback(struct flanterm_context *ctx, uint64_t type, uint64_t x,
218268
switch (type) {
219269
case FLANTERM_CB_BELL:
220270
beep(1000);
221-
break;
271+
break;
222272
case FLANTERM_CB_POS_REPORT:
223273
current_x = x - 1;
224274
current_y = y - 1;
225-
break;
275+
break;
276+
case FLANTERM_CB_SCROLL: {
277+
int stride = rr_fb_pitch;
278+
int delta_px = 8;
279+
bool moved = false;
280+
281+
for (int i = 0; i < scrollable_count;) {
282+
if (scrollable_count == 0) {
283+
break;
284+
}
285+
286+
scrollable_graphics_t *s = &scrollables[i];
287+
int height = (int)(s->end - s->start);
288+
289+
if (height <= 0) {
290+
/* drop invalid band */
291+
for (int j = i; j < scrollable_count - 1; j++) {
292+
scrollables[j] = scrollables[j + 1];
293+
}
294+
scrollable_count--;
295+
continue;
296+
}
297+
298+
int new_start = s->start - delta_px;
299+
int new_end = s->end - delta_px;
300+
301+
int dst_row = new_start;
302+
int src_row = s->start;
303+
int rows = height;
304+
305+
/* trim off rows above the top */
306+
if (dst_row < 0) {
307+
int cut = -dst_row;
308+
dst_row = 0;
309+
src_row += cut;
310+
rows -= cut;
311+
}
312+
313+
/* trim if bottom goes past screen (end is exclusive) */
314+
if (dst_row + rows > screen_graphics_y) {
315+
rows = screen_graphics_y - dst_row;
316+
}
317+
318+
if (rows > 0) {
319+
uint8_t *dst = (uint8_t *)rr_fb_back + (long)dst_row * stride;
320+
uint8_t *src = (uint8_t *)rr_fb_back + (long)src_row * stride;
321+
memmove(dst, src, (size_t)rows * stride);
322+
moved = true;
323+
}
324+
325+
s->start = new_start;
326+
s->end = new_end;
327+
328+
if (s->end <= 0 || s->start >= screen_graphics_y) {
329+
for (int j = i; j < scrollable_count - 1; j++) {
330+
scrollables[j] = scrollables[j + 1];
331+
}
332+
scrollable_count--;
333+
continue;
334+
}
335+
336+
i++;
337+
}
338+
if (moved) {
339+
set_video_dirty_area(0, screen_graphics_y);
340+
}
341+
break;
342+
}
226343
}
227344
wait_state = false;
228345
}

0 commit comments

Comments
 (0)