#include #include #include "addrs.h" #include "screen.h" #define SDLST ((u16 *)0x0230) 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; 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_status[i] = SCR_UNUSED; } strcpy(scr_names[0], "[server]"); strcpy(scr_names[1], "[private]"); scr_status[0] = scr_status[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_status[i] == SCR_UNUSED) { strcpy(scr_names[i], name); scr_status[i] = SCR_INACTIVE; scr_topics[i][0] = '\0'; if(display) { scr_display(i); } else { scr_display(scr_current); } return i; } } // scr_print_current("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_status[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_status[s] == SCR_UNUSED) return; */ scr_status[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_status[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_print_current(const char *text) { scr_print(scr_current, text); } void scr_print_active(const char *text) { scr_print(scr_active, text); } void scr_print_server(const char *text) { scr_print(SCR_SERVER, text); } void scr_print_priv(const char *text) { scr_print(SCR_SERVER, text); } void scr_activate(char s) { if(s != scr_current) { scr_status[s] = SCR_ACTIVE; scr_show_status(scr_current); } scr_active = s; }