aboutsummaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2026-02-16 21:13:41 -0500
committerB. Watson <urchlay@slackware.uk>2026-02-16 21:13:41 -0500
commit5ab86143c9d0b0c86411f7067cf9649f7f0d3311 (patch)
tree44cc25726ebd6dd8c8e62876be25150a299a6c2f /src/screen.c
parent126c147638538ce54fc21a3803955b3693a99add (diff)
downloadfujinet-chat-5ab86143c9d0b0c86411f7067cf9649f7f0d3311.tar.gz
New UI stuff, not yet working.
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c222
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);
+ }
+}