diff options
| author | B. Watson <urchlay@slackware.uk> | 2026-02-16 21:13:41 -0500 |
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2026-02-16 21:13:41 -0500 |
| commit | 5ab86143c9d0b0c86411f7067cf9649f7f0d3311 (patch) | |
| tree | 44cc25726ebd6dd8c8e62876be25150a299a6c2f /src/screen.c | |
| parent | 126c147638538ce54fc21a3803955b3693a99add (diff) | |
| download | fujinet-chat-5ab86143c9d0b0c86411f7067cf9649f7f0d3311.tar.gz | |
New UI stuff, not yet working.
Diffstat (limited to 'src/screen.c')
| -rw-r--r-- | src/screen.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/screen.c b/src/screen.c new file mode 100644 index 0000000..7f34331 --- /dev/null +++ b/src/screen.c @@ -0,0 +1,222 @@ +#include <atari.h> +#include <string.h> + +#include "addrs.h" +#include "screen.h" + +#define SDLST ((u16 *)0x0230) + +char scr_active[MAX_SCREENS]; + +/* the screen that's currently displaying */ +char scr_current; + +static char scr_names[7][32]; +static char scr_topics[7][40]; + +static char xpos; + +void scr_waitvcount(u8 c) { + while(ANTIC.vcount < c) + /* NOP */; +} + +static void scr_clear(char s) { + memset(screen_addrs[s], 0, SCREEN_SIZE); + memset(scr_names[s], 0, 32); + memset(scr_topics[s], 0, LINE_SIZE); +} + +static void scr_scroll(char s) { + memmove(screen_addrs[s], screen_addrs[s] + 40, 880); + memset(screen_botlines[s], 0, 40); +} + +void scr_init(void) { + int i, old_dma; + + old_dma = OS.sdmctl; + OS.sdmctl = 0; + scr_waitvcount(112); /* after the last GR.0 line */ + *SDLST = DLIST_ADDR; + OS.chbas = FONT_ADDR_HI; + + for(i = 0; i < MAX_SCREENS; i++) { + scr_clear(i); + scr_active[i] = SCR_UNUSED; + } + + strcpy(scr_names[0], "[server]"); + strcpy(scr_names[1], "[private]"); + scr_active[0] = scr_active[1] = SCR_INACTIVE; + + OS.sdmctl = old_dma; + + scr_display(0); +} + +char scr_create(const char *name, char display) { + int i; + + for(i = 0; i < MAX_SCREENS; i++) { + if(scr_active[i] == SCR_UNUSED) { + strcpy(scr_names[i], name); + scr_active[i] = SCR_INACTIVE; + scr_topics[i][0] = '\0'; + if(display) + scr_display(i); + else + scr_display(scr_current); + return i; + } + } + + // scr_print(SCR_CURR, "Can't create window (all in use)\n"); + return 0xff; +} + +void scr_destroy(char s) { + /* <2 because screens 0 and 1 (server and private) cannot be destroyed */ + if(s < 2 || s >= MAX_SCREENS) + return; + + scr_active[s] = SCR_UNUSED; + if(scr_current == s) + scr_display(0); +} + +void scr_set_topic(char s, const char *topic) { + strncpy(scr_topics[s], topic, 40); +} + +void scr_display(char s) { + if(s >= MAX_SCREENS) + return; + + /* leave this out, for testing + if(scr_active[s] == SCR_UNUSED) + return; + */ + + scr_active[s] = SCR_INACTIVE; + scr_current = s; + + scr_waitvcount(112); + *dlist_top_lms = (u16)screen_addrs[s]; + + scr_show_status(s); +} + +void scr_show_status(char s) { + int i; + char *p, sc; + + status_box[0] = s + 177; /* inverse number */ + status_box[1] = ':'; + strncpy(status_box + 2, scr_names[s], 32); + strncpy(status_box + 40, scr_topics[s], 40); + + p = status_box + 33; + for(i = 0; i < MAX_SCREENS; i++) { + switch(scr_active[i]) { + case SCR_ACTIVE: + sc = 128 | ('1' + i); break; + case SCR_INACTIVE: + sc = '1' + i; break; + default: + sc = ' '; + } + *p++ = sc; + } + + scr_waitvcount(112); + *dlist_bottom_lms = (u16)status_box; +} + +void scr_refresh(void) { + scr_display(scr_current); +} + +char scr_getbyname(const char *name) { + char i; + + for(i = 2; i < MAX_SCREENS; i++) { + if(strcasecmp(name, scr_names[i]) == 0) + return i; + } + + return 0; +} + +/* TODO: skip color codes (start with 0x03 or 0x04). + 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. */ +void scr_putc(char s, char c) { + u8 *dest; + static char bold = 0; + + if(s == SCR_CURR) + s = scr_current; + + if(c == '\n') { + bold = 0; + if(!xpos) + return; + xpos = 40; + return; + } + + if(xpos == 40) { + scr_scroll(s); + xpos = 0; + } + + dest = screen_botlines[s] + xpos; + + if(c & 0x80) { + /* utf-8 (or maybe latin-1), we don't support it yet */ + c = 0xbf; /* inverse ? */ + } else if(c == 0x02) { + bold = !bold; + return; + } else if(c == 0x1d) { + /* italics */ + c = '/'; + } else if(c == 0x1e) { + /* strikethru */ + c = '-'; + } else if(c == 0x1f) { + /* underline */ + c = '_'; + } else if(c == 0x0f) { + /* all formatting off */ + bold = 0; + return; + } else if(c < 0x20) { + /* unsupported control character */ + c += 192; + } + + if(bold) c |= 0x80; + + *dest = c; + xpos++; +} + +void scr_print(char s, const char *text) { + while(*text) { + scr_putc(s, *text); + if(*text == '\n') + break; + text++; + } + scr_activate(s); +} + +void scr_activate(char s) { + if(s != scr_current) { + scr_active[s] = SCR_ACTIVE; + scr_show_status(scr_current); + } +} |
