diff options
| author | B. Watson <urchlay@slackware.uk> | 2026-04-24 03:54:01 -0400 |
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2026-04-24 03:54:01 -0400 |
| commit | 715964c0b5ab8a2bc2b8ae8b7935e9ea0088e332 (patch) | |
| tree | 8d61003fadc3d3c7761394c517c4488c2b63743d /src/screen.c | |
| parent | 2ce1d0d8a2e7f79e1bb008836a4dca48adba867e (diff) | |
| download | fujinet-chat-715964c0b5ab8a2bc2b8ae8b7935e9ea0088e332.tar.gz | |
Dynamic screens. Still a bit flaky, but actually does work to some degree.
Diffstat (limited to 'src/screen.c')
| -rw-r--r-- | src/screen.c | 152 |
1 files changed, 69 insertions, 83 deletions
diff --git a/src/screen.c b/src/screen.c index e2ed12c..5d64ee4 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1,7 +1,6 @@ #include <atari.h> #include <string.h> -#include "addrs.h" #include "screen.h" #include "edbox.h" #include "indic8.h" @@ -14,16 +13,12 @@ area for extra scrollback. */ unsigned int *bonus_addrs = (unsigned int *)0xd4; /* aka FR0 */ -char scr_status[MAX_SCREENS]; - /* the screen that's currently displaying */ char scr_current; /* the screen that's currently being written to */ char scr_active; -char scr_names[7][32]; - static char xpos; void scr_waitvcount_116(void) { @@ -31,71 +26,49 @@ void scr_waitvcount_116(void) { /* NOP */; } -static void scr_clear(char s) { - if(bonus_addrs[s]) { - memclear(bonus_addrs[s], 1000); - strcpy(bonus_addrs[s], "This is bonus scrollback!"); - } - memclear(screen_top_addrs[s], 1000); - memclear(screen_bot_addrs[s], 1000); - memclear(scr_names[s], 32); -} - -static void scr_scroll(char s) { - if(bonus_addrs[s]) { - memmove(bonus_addrs[s], bonus_addrs[s] + 40, 960); - memmove(bonus_addrs[s] + 960, screen_top_addrs[s], 40); - } - memmove(screen_top_addrs[s], screen_top_addrs[s] + 40, 960); - memmove(screen_top_addrs[s] + 960, screen_bot_addrs[s], 40); - memmove(screen_bot_addrs[s], screen_bot_addrs[s] + 40, 920); - memclear(screen_lastlines[s], 40); -} - void scr_init(void) { int i; OS.sdmctl = 0; /* disappear the screen */ scr_waitvcount_116(); - *SDLST = DLIST_BOT_ADDR; + *SDLST = DLIST_VIS; OS.chbas = FONT_ADDR_HI; + init_pools(); + for(i = 0; i < MAX_SCREENS; i++) { - scr_clear(i); - scr_status[i] = SCR_UNUSED; + screens[i].status = SCR_UNUSED; } - strcpy(scr_names[0], "[server]"); - strcpy(scr_names[1], "[private]"); - scr_status[0] = scr_status[1] = SCR_INACTIVE; + scr_create("[server]"); + scr_create("[private]"); OS.sdmctl = 0x22; /* show the screen again */ scr_display(0); } -char scr_create(const char *name, char display) { - int i; +char scr_create(const char *name) { + char pool, i; /* don't create a duplicate screen */ if( (i = scr_getbyname(name)) ) return i; + pool = get_smallest_pool(); for(i = 0; i < MAX_SCREENS; i++) { - if(scr_status[i] == SCR_UNUSED) { - strcpy(scr_names[i], name); - scr_status[i] = SCR_INACTIVE; - if(display) { - scr_display(i); - } else { - scr_display(scr_current); - } + if(screens[i].status == SCR_UNUSED) { + pools[pool].screen_count++; + strcpy(screens[i].title, name); + screens[i].status = SCR_INACTIVE; + screens[i].pool = pool; + screens[i].line_list = (line_t *)END_MARKER; + screens[i].line_count = screens[i].scrollback_pos = 0; return i; } } - // scr_print_current("Can't create window (all in use)\n"); return 0xff; } @@ -104,66 +77,77 @@ void scr_destroy(char s) { if(s < 2 || s >= MAX_SCREENS) return; - scr_status[s] = SCR_UNUSED; - scr_names[s][0] = 0; - if(scr_current == s) - scr_display(0); - scr_clear(s); + // pool_reclaim_lines(screens[s].pool, screens[s].line_list); + pools[screens[s].pool].screen_count--; + + screens[s].title[0] = 0; + screens[s].status = SCR_UNUSED; + screens[s].pool = POOL_UNUSED; + screens[s].line_list = 0; + screens[s].line_count = screens[s].scrollback_pos = 0; +} + +void render_vis_buf(void) { + line_t *line; + u8 *vis; + int cnt; + + line = screens[scr_current].line_list; + + /* skip lines before the current scroll position */ + for(cnt = 0; cnt < screens[scr_current].scrollback_pos; cnt++) + line = line->next; + + /* point at bottom line of visbuf */ + vis = (u8 *)(SCR_VIS_BUF + LINE_LEN * (SCR_VIS_HEIGHT - 1)); + for(cnt = 0; cnt < SCR_VIS_HEIGHT; cnt++) { + memcpy(vis, line->data, LINE_LEN); + line = line->next; + vis -= LINE_LEN; + } } void scr_display(char s) { if(s >= MAX_SCREENS) return; - /* leave this out, for testing - if(scr_status[s] == SCR_UNUSED) + if(screens[s].status == SCR_UNUSED) return; - */ - scr_status[s] = SCR_INACTIVE; + screens[s].status = SCR_INACTIVE; scr_current = s; scr_waitvcount_116(); - *dlist_bot_lms = (u16)screen_bot_addrs[s]; + render_vis_buf(); scr_show_status(s); } -void scr_scrollback_bonus(void) { - if(bonus_addrs[scr_current]) { - scr_waitvcount_116(); - *dlist_top_lms = (u16)bonus_addrs[scr_current]; - } -} - void scr_scrollback(void) { - // OS.color2 = 0; - scr_waitvcount_116(); - *dlist_top_lms = (u16)screen_top_addrs[scr_current]; - *SDLST = (u16)dlist_top; + if(screens[scr_current].scrollback_pos <= screens[scr_current].line_count) { + screens[scr_current].scrollback_pos += SCR_VIS_HEIGHT; + scr_display(scr_current); + } } void scr_end_scrollback(void) { - // OS.color2 = 192; - scr_waitvcount_116(); - *SDLST = (u16)dlist_bot; + screens[scr_current].scrollback_pos = 0; + scr_display(scr_current); } void scr_show_status(char s) { int i; char *p, sc; - status_box[0] = s + 177; /* inverse number */ + status_box[0] = (s % 10) + 177; /* inverse number */ status_box[1] = ':'; - strncpy(status_box + 2, scr_names[s], 32); + strncpy(status_box + 2, screens[s].title, 32); - p = status_box + 53; /* up against the right border */ + p = status_box + 43; /* one space past the 2nd indicator */ - // *p++ = '<'; - // *p++ = 0xbc; // color2, maybe use? for(i = 0; i < MAX_SCREENS; i++) { - sc = i + '1'; - switch(scr_status[i]) { + sc = (i % 10) + '1'; + switch(screens[i].status) { case SCR_INACTIVE: /* color0 */ break; case SCR_ACTIVE: /* color1 */ @@ -176,12 +160,10 @@ void scr_show_status(char s) { sc |= 0xc0; break; default: - sc = '.'; + continue; /* don't show anything for unused */ } *p++ = sc; } - // *p++ = '>'; - // *p++ = 0xbe; if(!edbox_visible) { scr_waitvcount_116(); @@ -200,7 +182,7 @@ char scr_getbyname(const char *name) { if(!name) return 0; for(i = 2; i < MAX_SCREENS; i++) { - if(streq_i(name, scr_names[i])) + if(streq_i(name, screens[i].title)) return i; } @@ -223,6 +205,9 @@ void scr_eol_current(void) { if we're going to ever support utf-8, decode it here... also, 0x16 is supposed to be reverse video. not widely used/supported. eventually, this will be rewritten in asm anyway. */ +/* FIXME: There is a hidden assumption here: that a sequence of scr_putc(), + up to the \n that ends it, will all be sent to the same screen. + This is because there's only one xpos variable... */ void scr_putc(char s, char c) { u8 *dest; static char bold = 0; @@ -234,16 +219,17 @@ void scr_putc(char s, char c) { bold = 0; if(!xpos) return; - xpos = 40; + xpos = LINE_LEN; + if(s == scr_current) render_vis_buf(); return; } - if(xpos == 40) { - scr_scroll(s); + if(xpos == 0 || xpos == LINE_LEN) { + add_line(s); xpos = 0; } - dest = screen_lastlines[s] + xpos; + dest = screens[s].line_list->data + xpos; if(c & 0x80) { /* utf-8 (or maybe latin-1), we don't support it yet */ @@ -314,7 +300,7 @@ void scr_activate(char s) { } char *scr_get_cur_name(void) { - char *r = scr_names[scr_current]; + char *r = screens[scr_current].title; if(*r) return r; else |
