From 2a1bc83e93911d1b17939b68c1f6035e57d8d160 Mon Sep 17 00:00:00 2001 From: Nigel Reed <nigel@nigelreed.net> Date: Tue, 11 Feb 2025 01:29:44 -0600 Subject: [PATCH 1/4] Initial changes to support MODE7 graphics natively Similar to PETSCII it will answer on a dedicated port. --- ctrl/sbbs.ini | 4 +++- ctrl/text.dat | 2 ++ exec/load/termdesc.js | 6 ++++++ exec/load/text.js | 4 +++- exec/load/userdefs.js | 2 +- exec/login.js | 2 +- exec/logon.js | 6 ++++++ exec/logonlist.js | 7 +++++++ src/sbbs3/answer.cpp | 3 +++ src/sbbs3/ars.c | 4 ++++ src/sbbs3/ars_defs.h | 2 ++ src/sbbs3/chk_ar.cpp | 14 ++++++++++++++ src/sbbs3/con_out.cpp | 12 ++++++++++++ src/sbbs3/logon.cpp | 4 ++-- src/sbbs3/main.cpp | 7 +++++++ src/sbbs3/newuser.cpp | 3 +++ src/sbbs3/prntfile.cpp | 5 +++++ src/sbbs3/sbbs.h | 2 ++ src/sbbs3/sbbs_ini.c | 6 ++++++ src/sbbs3/sbbsdefs.h | 6 ++++-- src/sbbs3/scfg/scfgsrvr.c | 31 +++++++++++++++++++------------ src/sbbs3/startup.h | 1 + src/sbbs3/text.h | 2 ++ src/sbbs3/text_defaults.c | 2 ++ src/sbbs3/text_id.c | 2 ++ src/sbbs3/userdat.c | 6 ++++++ src/sbbs3/useredit.cpp | 2 +- src/sbbs3/xtrn.cpp | 9 +++++++++ 28 files changed, 135 insertions(+), 21 deletions(-) diff --git a/ctrl/sbbs.ini b/ctrl/sbbs.ini index df19c8ae08..c47ddf1caa 100644 --- a/ctrl/sbbs.ini +++ b/ctrl/sbbs.ini @@ -77,7 +77,9 @@ Pet40Port = 64 ; TCP port for 80-column PETSCII connections (any terminal protocol): Pet80Port = 128 - ; Note on PETSCII support: you must add the same port(s) to one of your + ; TCP port for 40-column MODE7 connections (any termnial protocol): + Mode7Port = 5050 + ; Note on PETSCII and MODE7 support: you must add the same port(s) to one of your ; *Interface= values above to open/listen/accept connections on that port. ; Example: ; TelnetInterface = 71.95.196.34,71.95.196.34:64,71.95.196.34:128 diff --git a/ctrl/text.dat b/ctrl/text.dat index 7a9f5d4c73..424225c7e1 100644 --- a/ctrl/text.dat +++ b/ctrl/text.dat @@ -1124,3 +1124,5 @@ " %c \1g%.10s\1n %c %.127s%c" 935 QWKTagLineFmt "\1n\r\n\1b\1hQWK Control [\1c%s\1b]: \1g%s\r\n" 936 QWKControlCommand "Unrecognized Control Command!\1n\r\n" 937 QWKBadControlCommand +"Mode 7 terminal detected" 938 Mode7TerminalDetected +"Are you using a Mode 7 terminal" 939 Mode7TerminalQ diff --git a/exec/load/termdesc.js b/exec/load/termdesc.js index c514c06524..ed0135707a 100644 --- a/exec/load/termdesc.js +++ b/exec/load/termdesc.js @@ -22,6 +22,8 @@ function charset(term) term = console.term_supports(); if(term & USER_PETSCII) return "CBM-ASCII"; + if(term & USER_MODE7) + return "MODE7"; if(term & USER_UTF8) return "UTF-8"; if(term & USER_NO_EXASCII) @@ -62,6 +64,8 @@ function type(verbose, usr) var type = "DUMB"; if(term & USER_PETSCII) type = "PETSCII"; + if(term & USER_MODE7) + type = "MODE7"; if(term & USER_RIP) type = "RIP"; if(term & USER_ANSI) @@ -72,6 +76,8 @@ function type(verbose, usr) // Verbose if(term & USER_PETSCII) return ((usr.settings & USER_AUTOTERM) ? bbs.text(TerminalAutoDetect) : "") + "CBM/PETSCII"; + if(term & USER_MODE7) + return ((usr.settings & USER_AUTOTERM) ? bbs.text(TerminalAutoDetect) : "") + "MODE7"; return format("%s%s / %s %s%s%s" ,(usr.settings & USER_AUTOTERM) ? bbs.text(TerminalAutoDetect) : "" ,this.charset(term) diff --git a/exec/load/text.js b/exec/load/text.js index ab3fc80346..a780a76474 100644 --- a/exec/load/text.js +++ b/exec/load/text.js @@ -944,7 +944,9 @@ var QWKEndOfMessage=934; var QWKTagLineFmt=935; var QWKControlCommand=936; var QWKBadControlCommand=937; +var Mode7TerminalDetected=938; +var Mode7TerminalQ=939; -var TOTAL_TEXT=938; +var TOTAL_TEXT=940; this; diff --git a/exec/load/userdefs.js b/exec/load/userdefs.js index 4f7aad07d7..d09319efa7 100644 --- a/exec/load/userdefs.js +++ b/exec/load/userdefs.js @@ -24,7 +24,7 @@ const USER_AUTOTERM = (1<<17); // Autodetect terminal type const USER_COLDKEYS = (1<<18); // No hot-keys const USER_EXTDESC = (1<<19); // Extended file descriptions const USER_AUTOHANG = (1<<20); // Auto-hang-up after transfer -const USER_WIP = (1<<21); // Supports WIP terminal emulation +const USER_MODE7 = (1<<21); // BBC Micro Mode 7 terminal support const USER_AUTOLOGON = (1<<22); // AutoLogon via IP const USER_HTML = (1<<23); // Using Deuce's HTML terminal (*cough*) const USER_NOPAUSESPIN = (1<<24); // No spinning cursor at pause prompt diff --git a/exec/login.js b/exec/login.js index a4c7324916..347eb97e9e 100644 --- a/exec/login.js +++ b/exec/login.js @@ -27,7 +27,7 @@ if(!bbs.online) exit(); var inactive_hangup = parseInt(options.inactive_hangup, 10); if(inactive_hangup && inactive_hangup < console.max_socket_inactivity - && !(console.autoterm&(USER_ANSI | USER_PETSCII | USER_UTF8))) { + && !(console.autoterm&(USER_ANSI | USER_PETSCII | USER_UTF8 | USER_MODE7))) { console.max_socket_inactivity = inactive_hangup; log(LOG_NOTICE, "terminal not detected, reducing inactivity hang-up timeout to " + console.max_socket_inactivity + " seconds"); } diff --git a/exec/logon.js b/exec/logon.js index 6094ea5dda..5be63f0299 100644 --- a/exec/logon.js +++ b/exec/logon.js @@ -11,6 +11,12 @@ require("sbbsdefs.js", 'SS_RLOGIN'); require("nodedefs.js", 'NODE_QUIET'); + +if(console.term_supports(USER_MODE7)) { + log(LOG_DEBUG, "Setting users language to m7"); + user.lang = "m7"; +} + if(!bbs.mods.avatar_lib) bbs.mods.avatar_lib = load({}, 'avatar_lib.js'); if(!bbs.mods.logonlist_lib) diff --git a/exec/logonlist.js b/exec/logonlist.js index da7f527347..63b174aa0b 100644 --- a/exec/logonlist.js +++ b/exec/logonlist.js @@ -45,6 +45,13 @@ if(!js.global.bbs) { if(!bbs.mods.logonlist_lib) bbs.mods.logonlist_lib = load({}, 'logonlist_lib.js'); var options = load("modopts.js", "logonlist"); +function dump_objs(obj) { + Object.keys(obj).forEach(function (e) { + writeln(e + ': ' + JSON.stringify(obj[e])); + }); +} +dump_objs(options); +writeln("lang: " + user.lang); if(!options) options = {}; if(options.last_few_callers === undefined) diff --git a/src/sbbs3/answer.cpp b/src/sbbs3/answer.cpp index 2c0e2921b3..62a45ca9c9 100644 --- a/src/sbbs3/answer.cpp +++ b/src/sbbs3/answer.cpp @@ -553,6 +553,9 @@ bool sbbs_t::answer() SAFECOPY(terminal, "PETSCII"); outchar(FF); center(str); + } else if (autoterm & MODE7) { + SAFECOPY(terminal, "MODE7"); + center(str); } else { /* ANSI+ terminal detection */ putcom( "\r\n" /* locate cursor at column 1 */ "\x1b[s" /* save cursor position (necessary for HyperTerm auto-ANSI) */ diff --git a/src/sbbs3/ars.c b/src/sbbs3/ars.c index 9f1a995d16..2719f0a12b 100644 --- a/src/sbbs3/ars.c +++ b/src/sbbs3/ars.c @@ -337,6 +337,10 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf) artype = AR_PETSCII; i += 6; } + else if (!strnicmp(str + i, "MODE7", 5)) { + artype = AR_MODE7; + i += 4; + } else if (!strnicmp(str + i, "ASCII", 5)) { artype = AR_ASCII; i += 4; diff --git a/src/sbbs3/ars_defs.h b/src/sbbs3/ars_defs.h index 9d4c003bd5..fa5de50605 100644 --- a/src/sbbs3/ars_defs.h +++ b/src/sbbs3/ars_defs.h @@ -116,6 +116,7 @@ enum { /* Access requirement binaries */ , AR_UTF8 , AR_CP437 , AR_USERNAME + , AR_MODE7 }; enum ar_type { @@ -148,6 +149,7 @@ static inline enum ar_type ar_type(int artype) case AR_GUEST: case AR_QNODE: case AR_QUIET: + case AR_MODE7: return AR_BOOL; case AR_SUBCODE: case AR_DIRCODE: diff --git a/src/sbbs3/chk_ar.cpp b/src/sbbs3/chk_ar.cpp index 731c0796b7..ca0e4e7189 100644 --- a/src/sbbs3/chk_ar.cpp +++ b/src/sbbs3/chk_ar.cpp @@ -128,6 +128,20 @@ bool sbbs_t::ar_exp(const uchar **ptrptr, user_t* user, client_t* client) noaccess_val = PETSCII; } break; + case AR_MODE7: + { + int val = term_supports(); + val &= CHARSET_FLAGS; + if (val != CHARSET_MODE7) + result = _not; + else + result = !_not; + if (!result) { + noaccess_str = text[NoAccessTerminal]; + noaccess_val = MODE7; + } + } + break; case AR_ASCII: if ((term_supports() & CHARSET_FLAGS) != CHARSET_ASCII) result = _not; diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp index eda850dfd5..c1b99074af 100644 --- a/src/sbbs3/con_out.cpp +++ b/src/sbbs3/con_out.cpp @@ -245,6 +245,11 @@ unsigned char cp437_to_petscii(unsigned char ch) return ch; } +unsigned char cp437_to_mode7(unsigned char ch) +{ + return ch; +} + /* Perform PETSCII conversion to ANSI-BBS/CP437 */ int sbbs_t::petscii_to_ansibbs(unsigned char ch) { @@ -539,6 +544,9 @@ char* sbbs_t::term_type(user_t* user, int term, char* str, size_t size) if (term & PETSCII) safe_snprintf(str, size, "%sCBM/PETSCII" , (user->misc & AUTOTERM) ? text[TerminalAutoDetect] : nulstr); + else if (term & MODE7) + safe_snprintf(str, size, "%s/MODE7" + , (user->misc & AUTOTERM) ? text[TerminalAutoDetect] : nulstr); else safe_snprintf(str, size, "%s%s / %s %s%s%s" , (user->misc & AUTOTERM) ? text[TerminalAutoDetect] : nulstr @@ -560,6 +568,8 @@ const char* sbbs_t::term_type(int term) term = term_supports(); if (term & PETSCII) return "PETSCII"; + if (term & MODE7) + return "MODE7"; if (term & RIP) return "RIP"; if (term & ANSI) @@ -576,6 +586,8 @@ const char* sbbs_t::term_charset(int term) term = term_supports(); if (term & PETSCII) return "CBM-ASCII"; + if (term & MODE7) + return "MODE7"; if (term & UTF8) return "UTF-8"; if (term & NO_EXASCII) diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp index 5c3022c0ca..f9231b0929 100644 --- a/src/sbbs3/logon.cpp +++ b/src/sbbs3/logon.cpp @@ -182,8 +182,8 @@ bool sbbs_t::logon() } if ((useron.misc & AUTOTERM) - // User manually-enabled PETSCII, but they're logging in with an ANSI (auto-detected) terminal - || ((useron.misc & PETSCII) && (autoterm & ANSI))) { + // User manually-enabled PETSCII or MODE7, but they're logging in with an ANSI (auto-detected) terminal + || (((useron.misc & PETSCII) || (useron.misc & MODE7)) && (autoterm & ANSI))) { useron.misc &= ~(ANSI | RIP | CHARSET_FLAGS); useron.misc |= (AUTOTERM | autoterm); } diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 20bea4fad6..2b6feda0e5 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -24,6 +24,7 @@ #include "telnet.h" #include "netwrap.h" #include "petdefs.h" +#include "mode7defs.h" #include "filedat.h" #include "js_rtpool.h" #include "js_request.h" @@ -5663,6 +5664,12 @@ NO_SSH: sbbs->outcom(PETSCII_UPPERLOWER); } + if (inet_addrport(&local_addr) == startup->mode7_port) { + sbbs->autoterm = MODE7; + sbbs->cols = 40; + sbbs->rows = 25; + } + sbbs->bprintf("\r\n%s\r\n", VERSION_NOTICE); sbbs->bprintf("%s connection from: %s\r\n", client.protocol, host_ip); diff --git a/src/sbbs3/newuser.cpp b/src/sbbs3/newuser.cpp index 7775414cbc..e46c3b31bb 100644 --- a/src/sbbs3/newuser.cpp +++ b/src/sbbs3/newuser.cpp @@ -153,6 +153,9 @@ bool sbbs_t::newuser() autoterm |= PETSCII; outcom(PETSCII_UPPERLOWER); bputs(text[PetTerminalDetected]); + } else if (useron.misc & MODE7) { + autoterm |= MODE7; + bputs(text[Mode7TerminalDetected]); } else { if (!yesno(text[ExAsciiTerminalQ])) useron.misc |= NO_EXASCII; diff --git a/src/sbbs3/prntfile.cpp b/src/sbbs3/prntfile.cpp index caf470b4d5..71fc770859 100644 --- a/src/sbbs3/prntfile.cpp +++ b/src/sbbs3/prntfile.cpp @@ -22,6 +22,7 @@ #include "sbbs.h" #include "utf8.h" #include "petdefs.h" +#include "mode7defs.h" #ifndef PRINTFILE_MAX_LINE_LEN #define PRINTFILE_MAX_LINE_LEN (8 * 1024) @@ -54,6 +55,8 @@ bool sbbs_t::printfile(const char* fname, int mode, int org_cols, JSObject* obj) mode |= P_NOPAUSE; } else if (stricmp(p, ".seq") == 0) { mode |= P_PETSCII; + } else if (stricmp(p, ".m7") == 0) { + mode |= P_MODE7; } else if (stricmp(p, ".utf8") == 0) { mode |= P_UTF8; } @@ -283,6 +286,8 @@ bool sbbs_t::menu(const char *code, int mode, JSObject* obj) break; if ((term & PETSCII) && menu_exists(code, "seq", path)) break; + if ((term & MODE7) && menu_exists(code, "m7", path)) + break; if (term & NO_EXASCII) { next = "asc"; last = "msg"; diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 5723daed8b..411a1cfe29 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -981,6 +981,7 @@ public: bool saveline(void); bool restoreline(void); int petscii_to_ansibbs(unsigned char); + int mode7_to_ansibbs(unsigned char); size_t print_utf8_as_cp437(const char*, size_t); int attr(int); /* Change text color/attributes */ void ctrl_a(char); /* Performs Ctrl-Ax attribute changes */ @@ -1431,6 +1432,7 @@ extern "C" { /* con_out.cpp */ unsigned char cp437_to_petscii(unsigned char); + unsigned char cp437_to_mode7(unsigned char); /* xtrn.cpp */ bool native_executable(scfg_t*, const char* cmdline, int mode); diff --git a/src/sbbs3/sbbs_ini.c b/src/sbbs3/sbbs_ini.c index 6ba8123a24..a550ea306b 100644 --- a/src/sbbs3/sbbs_ini.c +++ b/src/sbbs3/sbbs_ini.c @@ -448,6 +448,9 @@ void sbbs_read_ini( bbs->pet80_port = iniGetShortInt(list, section, "Pet80Port", 128); + bbs->mode7_port + = iniGetShortInt(list, section, "Mode7Port", 5050); + bbs->ssh_port = iniGetShortInt(list, section, "SSHPort", 22); bbs->ssh_connect_timeout @@ -936,6 +939,9 @@ bool sbbs_write_ini( if (!iniSetUInt16(lp, section, "Pet80Port", bbs->pet80_port, &style)) break; + if (!iniSetUInt16(lp, section, "Mode7Port", bbs->mode7_port, &style)) + break; + if (strListCmp(bbs->ssh_interfaces, global->interfaces) == 0) iniRemoveValue(lp, section, "SSHInterface"); else if (!iniSetStringList(lp, section, "SSHInterface", ",", bbs->ssh_interfaces, &style)) diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index b4c285ca30..d1ac52f537 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -568,7 +568,7 @@ typedef enum { /* Values for xtrn_t.event */ #define COLDKEYS (1 << 18) /* No hot-keys */ #define EXTDESC (1 << 19) /* Extended file descriptions */ #define AUTOHANG (1 << 20) /* Auto-hang-up after transfer */ -#define WIP_UNUSED (1 << 21) /* Supports WIP terminal emulation */ +#define MODE7 (1 << 21) /* BBC Micro Mode 7 terminal support */ #define AUTOLOGON (1 << 22) /* AutoLogon via IP */ #define HTML_UNUSED (1 << 23) /* Using Zuul/HTML terminal */ #define NOPAUSESPIN (1 << 24) /* No spinning cursor at pause prompt */ @@ -579,9 +579,10 @@ typedef enum { /* Values for xtrn_t.event */ #define MOUSE (1U << 31) /* Mouse supported terminal */ #define TERM_FLAGS (ANSI | COLOR | RIP | SWAP_DELETE | ICE_COLOR | MOUSE | CHARSET_FLAGS) -#define CHARSET_FLAGS (NO_EXASCII | PETSCII | UTF8) +#define CHARSET_FLAGS (NO_EXASCII | PETSCII | UTF8 | MODE7) #define CHARSET_ASCII NO_EXASCII // US-ASCII #define CHARSET_PETSCII PETSCII // CBM-ASCII +#define CHARSET_MODE7 MODE7 // MODE 7 #define CHARSET_UTF8 UTF8 #define CHARSET_CP437 0 @@ -694,6 +695,7 @@ typedef enum { /* Values for xtrn_t.event */ #define P_REMOTE (1 << 18) /* Only print when online == ON_REMOTE */ #define P_INDENT (1 << 19) /* Indent lines to current cursor column */ #define P_ATCODES (1 << 20) /* Trusted @-codes in formatted string */ +#define P_MODE7 (1 << 21) /* Message is native Mode 7 */ /* Bits in 'mode' for listfiles */ #define FL_ULTIME (1 << 0) /* List files by upload time */ diff --git a/src/sbbs3/scfg/scfgsrvr.c b/src/sbbs3/scfg/scfgsrvr.c index 4e870ce2c3..b52ce44848 100644 --- a/src/sbbs3/scfg/scfgsrvr.c +++ b/src/sbbs3/scfg/scfgsrvr.c @@ -557,6 +557,8 @@ static void termsrvr_cfg(void) snprintf(opt[i++], MAX_OPLN, "%-30s%s", "40 Column PETSCII Support", startup.pet40_port ? str : strDisabled ); snprintf(str, sizeof str, "Port %u", startup.pet80_port); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "80 Column PETSCII Support", startup.pet80_port ? str : strDisabled); + snprintf(str, sizeof str, "Port %u", startup.mode7_port); + snprintf(opt[i++], MAX_OPLN, "%-30s%s", "BBC Mode 7 Support", startup.mode7_port ? str : strDisabled); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "DOS Program Support", startup.options & BBS_OPT_NO_DOS ? "No" : "Yes"); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "Max Concurrent Connections", maximum(startup.max_concurrent_connections)); snprintf(opt[i++], MAX_OPLN, "%-30s%s", "Max Login Inactivity", vduration(startup.max_login_inactivity)); @@ -621,9 +623,14 @@ static void termsrvr_cfg(void) startup.pet80_port = atoi(str); break; case 8: - startup.options ^= BBS_OPT_NO_DOS; + SAFEPRINTF(str, "%u", startup.mode7_port); + if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "BBC Mode 7 Port", str, 5, K_NUMBER | K_EDIT) > 0) + startup.mode7_port = atoi(str); break; case 9: + startup.options ^= BBS_OPT_NO_DOS; + break; + case 10: SAFECOPY(str, maximum(startup.max_concurrent_connections)); if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Concurrent (Unauthenticated) Connections", str, 10, K_EDIT) > 0) startup.max_concurrent_connections = atoi(str); @@ -637,7 +644,7 @@ static void termsrvr_cfg(void) "`Maximum User Inactivity` setting in `System->Advanced Options`.\n" \ "Normally, if enabled, this socket inactivity duration should be `longer`\n" \ "than the `Maximum User Inactivity` setting in `System->Advanced Options`.\n" - case 10: + case 11: uifc.helpbuf = "`Maximum Socket Inactivity at Login:`\n" "\n" @@ -651,7 +658,7 @@ static void termsrvr_cfg(void) if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Socket Inactivity at Login", str, 10, K_EDIT) > 0) startup.max_login_inactivity = (uint16_t)parse_duration(str); break; - case 11: + case 12: uifc.helpbuf = "`Maximum Socket Inactivity at New User Registration:`\n" "\n" @@ -665,7 +672,7 @@ static void termsrvr_cfg(void) if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Socket Inactivity at New User Registration", str, 10, K_EDIT) > 0) startup.max_newuser_inactivity = (uint16_t)parse_duration(str); break; - case 12: + case 13: uifc.helpbuf = "`Maximum Socket Inactivity during User Session:`\n" "\n" @@ -681,34 +688,34 @@ static void termsrvr_cfg(void) if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Maximum Socket Inactivity during User Session", str, 10, K_EDIT) > 0) startup.max_session_inactivity = (uint16_t)parse_duration(str); break; - case 13: + case 14: SAFEPRINTF(str, "%u", startup.outbuf_drain_timeout); if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Output Buffer Drain Timeout (milliseconds)", str, 5, K_NUMBER | K_EDIT) > 0) startup.outbuf_drain_timeout = atoi(str); break; - case 14: + case 15: startup.options ^= BBS_OPT_NO_EVENTS; break; - case 15: + case 16: if (startup.options & BBS_OPT_NO_EVENTS) break; startup.options ^= BBS_OPT_NO_QWK_EVENTS; break; - case 16: + case 17: if (startup.options & BBS_OPT_NO_EVENTS) break; uifc.list(WIN_MID | WIN_SAV, 0, 0, 0, &startup.event_log_level, 0, "Event Log Level", iniLogLevelStringList()); break; - case 17: + case 18: startup.options ^= BBS_OPT_NO_HOST_LOOKUP; break; - case 18: + case 19: getar("Terminal Server Login", startup.login_ars); break; - case 19: + case 20: js_startup_cfg(&startup.js); break; - case 20: + case 21: login_attempt_cfg(&startup.login_attempt); break; default: diff --git a/src/sbbs3/startup.h b/src/sbbs3/startup.h index bdefe555fa..58d70b865b 100644 --- a/src/sbbs3/startup.h +++ b/src/sbbs3/startup.h @@ -129,6 +129,7 @@ typedef struct { uint16_t rlogin_port; uint16_t pet40_port; // 40-column PETSCII terminal server uint16_t pet80_port; // 80-column PETSCII terminal server + uint16_t mode7_port; // 40-column MODE7 terminal server uint16_t ssh_port; uint16_t ssh_connect_timeout; int ssh_error_level; diff --git a/src/sbbs3/text.h b/src/sbbs3/text.h index b7097f503e..548c2785b4 100644 --- a/src/sbbs3/text.h +++ b/src/sbbs3/text.h @@ -954,6 +954,8 @@ enum text { ,QWKTagLineFmt ,QWKControlCommand ,QWKBadControlCommand + ,Mode7TerminalDetected + ,Mode7TerminalQ ,TOTAL_TEXT }; diff --git a/src/sbbs3/text_defaults.c b/src/sbbs3/text_defaults.c index 6c568a1ec9..4929b181ae 100644 --- a/src/sbbs3/text_defaults.c +++ b/src/sbbs3/text_defaults.c @@ -1507,4 +1507,6 @@ const char * const text_defaults[TOTAL_TEXT]={ "\x25\x73\x0d\x0a" // 936 QWKControlCommand ,"\x55\x6e\x72\x65\x63\x6f\x67\x6e\x69\x7a\x65\x64\x20\x43\x6f\x6e\x74\x72\x6f\x6c\x20\x43\x6f\x6d\x6d\x61\x6e\x64\x21\x01\x6e\x0d" "\x0a" // 937 QWKBadControlCommand + ,"\x4d\x6f\x64\x65\x20\x37\x20\x74\x65\x72\x6d\x69\x6e\x61\x6c\x20\x64\x65\x74\x65\x63\x74\x65\x64" // 938 Mode7TerminalDetected + ,"\x41\x72\x65\x20\x79\x6f\x75\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x4d\x6f\x64\x65\x20\x37\x20\x74\x65\x72\x6d\x69\x6e\x61\x6c" // 939 Mode7TerminalQ }; diff --git a/src/sbbs3/text_id.c b/src/sbbs3/text_id.c index abf977c944..213aaf1491 100644 --- a/src/sbbs3/text_id.c +++ b/src/sbbs3/text_id.c @@ -938,4 +938,6 @@ const char* const text_id[]={ ,"QWKTagLineFmt" ,"QWKControlCommand" ,"QWKBadControlCommand" + ,"Mode7TerminalDetected" + ,"Mode7TerminalQ" }; diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index 5d28ebe2d6..9049296eb1 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -2177,6 +2177,12 @@ static bool ar_exp(scfg_t* cfg, uchar **ptrptr, user_t* user, client_t* client) else result = !not; break; + case AR_MODE7: + if (user == NULL || (user->misc & CHARSET_FLAGS) != CHARSET_MODE7) + result = not; + else + result = !not; + break; case AR_ASCII: if (user == NULL || (user->misc & CHARSET_FLAGS) != CHARSET_ASCII) result = not; diff --git a/src/sbbs3/useredit.cpp b/src/sbbs3/useredit.cpp index eddc505f0c..77d9366f6c 100644 --- a/src/sbbs3/useredit.cpp +++ b/src/sbbs3/useredit.cpp @@ -880,7 +880,7 @@ void sbbs_t::user_config(user_t* user) case 'T': if (yesno(text[AutoTerminalQ])) { user->misc |= AUTOTERM; - user->misc &= ~(ANSI | RIP | PETSCII | UTF8); + user->misc &= ~(ANSI | RIP | PETSCII | UTF8 | MODE7); if (user == &useron) user->misc |= autoterm; } diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index 69b8ef8cd4..152d43e00f 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -214,6 +214,13 @@ static void petscii_convert(BYTE* buf, uint len) } } +static void mode7_convert(BYTE* buf, uint len) +{ + for (uint i = 0; i < len; i++) { + buf[i] = cp437_to_mode7(buf[i]); + } +} + static BYTE* cp437_to_utf8(BYTE* input, size_t& len, BYTE* outbuf, size_t maxlen) { size_t outlen = 0; @@ -1961,6 +1968,8 @@ int sbbs_t::external(const char* cmdline, int mode, const char* startup_dir) } if (term_supports(PETSCII)) petscii_convert(bp, output_len); + else if (term_supports(MODE7)) + mode7_convert(bp, output_len); else if (term_supports(UTF8)) bp = cp437_to_utf8(bp, output_len, utf8_buf, sizeof utf8_buf); } -- GitLab From ecfd1e1d0cf9d4f19d8f4f91c9b2eae93b8d0386 Mon Sep 17 00:00:00 2001 From: Nigel Reed <nigel@nigelreed.net> Date: Tue, 11 Feb 2025 17:28:16 -0600 Subject: [PATCH 2/4] More changes for MODE7 Updates for Mode 7 graphics --- exec/bullseye.js | 3 ++- exec/login.js | 5 +++-- exec/logon.js | 4 ---- exec/logonlist.js | 7 ------- exec/noyesbar.js | 15 +++++++++++---- exec/yesnobar.js | 17 ++++++++++++----- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/exec/bullseye.js b/exec/bullseye.js index a5f3e65dd7..c3de0da67e 100644 --- a/exec/bullseye.js +++ b/exec/bullseye.js @@ -7,6 +7,7 @@ // @format.tab-size 4, @format.use-tabs true require("sbbsdefs.js", "P_NOERROR"); +require("gettext.js", 'gettext'); "use strict"; @@ -48,7 +49,7 @@ if(bull.length < 1) { while(bbs.online && !js.terminated) { if(bbs.menu("../bullseye", P_NOERROR)) { - console.mnemonics("\r\nEnter number of bulletin or [~Quit]: "); + console.mnemonics(gettext("\r\nEnter number of bulletin or [~Quit]: ")); b = console.getnum(bull.length); } else { for(i = 0; i < bull.length; ++i) diff --git a/exec/login.js b/exec/login.js index 347eb97e9e..e97e2ce6ea 100644 --- a/exec/login.js +++ b/exec/login.js @@ -67,11 +67,12 @@ for(var c=0; c < options.login_prompts; c++) { if(!str.length) // blank continue; + // New user application? if(str.toUpperCase()=="NEW") { if(bbs.newuser()) { - bbs.logon(); - exit(); + bbs.logon(); + exit(); } continue; } diff --git a/exec/logon.js b/exec/logon.js index 5be63f0299..0b7feadc38 100644 --- a/exec/logon.js +++ b/exec/logon.js @@ -12,10 +12,6 @@ require("sbbsdefs.js", 'SS_RLOGIN'); require("nodedefs.js", 'NODE_QUIET'); -if(console.term_supports(USER_MODE7)) { - log(LOG_DEBUG, "Setting users language to m7"); - user.lang = "m7"; -} if(!bbs.mods.avatar_lib) bbs.mods.avatar_lib = load({}, 'avatar_lib.js'); diff --git a/exec/logonlist.js b/exec/logonlist.js index 63b174aa0b..da7f527347 100644 --- a/exec/logonlist.js +++ b/exec/logonlist.js @@ -45,13 +45,6 @@ if(!js.global.bbs) { if(!bbs.mods.logonlist_lib) bbs.mods.logonlist_lib = load({}, 'logonlist_lib.js'); var options = load("modopts.js", "logonlist"); -function dump_objs(obj) { - Object.keys(obj).forEach(function (e) { - writeln(e + ': ' + JSON.stringify(obj[e])); - }); -} -dump_objs(options); -writeln("lang: " + user.lang); if(!options) options = {}; if(options.last_few_callers === undefined) diff --git a/exec/noyesbar.js b/exec/noyesbar.js index 7855eb7c43..bd97f40539 100644 --- a/exec/noyesbar.js +++ b/exec/noyesbar.js @@ -8,6 +8,10 @@ const yes_key = yes_str[0]; const no_str = bbs.text(bbs.text.No); const no_key = no_str[0]; +var options = load("modopts.js", "noyesbar"); +if(!options) + options = {}; + while(console.question.substring(0, 2) == "\r\n") { console.crlf(); console.question = console.question.substring(2); @@ -18,18 +22,21 @@ if(console.question.substring(0, 2) == "\x01\?") { console.question = console.question.substring(2); } -console.putmsg("\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); +console.putmsg(options.noyes_question || "\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); var affirm = false; while(bbs.online && !js.terminated) { var str; if(affirm) - str = format("\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", no_str, yes_str); + str = format(options.highlight_yes_fmt || "\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", no_str, yes_str); else - str = format("\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", no_str, yes_str); + str = format(options.highlight_no_fmt || "\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", no_str, yes_str); console.print(str); var key = console.getkey(0).toUpperCase(); console.backspace(console.strlen(str)); - console.print("\x01n\x01h\x01>"); + if(console.term_supports(USER_MODE7)) + console.print(" "); + else + console.print("\x01n\x01h\x01>"); if(console.aborted) break; if(key == '\r') diff --git a/exec/yesnobar.js b/exec/yesnobar.js index 6b64c4a4ec..1b7f454ced 100644 --- a/exec/yesnobar.js +++ b/exec/yesnobar.js @@ -1,5 +1,4 @@ // JS version of yesnobar.src - require("sbbsdefs.js", "P_NOABORT"); "use strict"; @@ -9,6 +8,10 @@ const yes_key = yes_str[0]; const no_str = bbs.text(bbs.text.No); const no_key = no_str[0]; +var options = load("modopts.js", "yesnobar"); +if(!options) + options = {}; + while(console.question.substring(0, 2) == "\r\n") { console.crlf(); console.question = console.question.substring(2); @@ -19,18 +22,22 @@ if(console.question.substring(0, 2) == "\x01\?") { console.question = console.question.substring(2); } -console.putmsg("\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); +console.putmsg(options.yesno_question || "\x01n\x01b\x01h[\x01c@CHECKMARK@\x01b] \x01y@QUESTION->@? @CLEAR_HOT@", P_NOABORT); var affirm = true; while(bbs.online && !js.terminated) { var str; if(affirm) - str = format("\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", yes_str, no_str); + str = format(options.highlight_yes_fmt || "\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", no_str, yes_str); else - str = format("\x01n\x01b\x01h \x01~%s \x014\x01w\x01e[\x01~%s]", yes_str, no_str); + str = format(options.highlight_no_fmt || "\x01h\x014\x01w\x01e[\x01~%s]\x01n\x01b\x01h \x01~%s ", no_str, yes_str); console.print(str); var key = console.getkey(0).toUpperCase(); console.backspace(console.strlen(str)); - console.print("\x01n\x01h\x01>"); + if(console.term_supports(USER_MODE7)) + console.print(" "); + else + console.print("\x01n\x01h\x01>"); + if(console.aborted) break; if(key == '\r') -- GitLab From 6f6fefd041701deed1aa0a636c9ec0f1329bdd20 Mon Sep 17 00:00:00 2001 From: Nigel Reed <nigel@nigelreed.net> Date: Tue, 11 Feb 2025 18:11:22 -0600 Subject: [PATCH 3/4] New files for Mode 7 support This includes menu scripts and files, and some other .m7 files needed to get it to run. Keep in mind a lot of this is incomplete and still being developed. --- exec/mode7.js | 124 ++++++++++++++++++++++++ exec/mode7/mode7_chat.js | 142 +++++++++++++++++++++++++++ exec/mode7/mode7_email.js | 88 +++++++++++++++++ exec/mode7/mode7_forums.js | 167 ++++++++++++++++++++++++++++++++ src/xpdev/mode7defs.h | 72 ++++++++++++++ text/answer.m7 | 15 +++ text/bullseye.m7 | 6 ++ text/menu/mode7/mode7_chat.m7 | 4 + text/menu/mode7/mode7_email.m7 | 4 + text/menu/mode7/mode7_forums.m7 | 20 ++++ text/menu/mode7/mode7_main.m7 | 23 +++++ text/menu/msghdr.m7 | 6 ++ text/system.m7 | 16 +++ 13 files changed, 687 insertions(+) create mode 100644 exec/mode7.js create mode 100644 exec/mode7/mode7_chat.js create mode 100644 exec/mode7/mode7_email.js create mode 100755 exec/mode7/mode7_forums.js create mode 100644 src/xpdev/mode7defs.h create mode 100644 text/answer.m7 create mode 100755 text/bullseye.m7 create mode 100755 text/menu/mode7/mode7_chat.m7 create mode 100755 text/menu/mode7/mode7_email.m7 create mode 100755 text/menu/mode7/mode7_forums.m7 create mode 100755 text/menu/mode7/mode7_main.m7 create mode 100644 text/menu/msghdr.m7 create mode 100644 text/system.m7 diff --git a/exec/mode7.js b/exec/mode7.js new file mode 100644 index 0000000000..d930a277c2 --- /dev/null +++ b/exec/mode7.js @@ -0,0 +1,124 @@ +// Default/Classic Synchronet Command Shell +// replaces default.src/bin + +// @format.tab-size 4 + +"use strict"; + +require("sbbsdefs.js", "K_UPPER"); +require("userdefs.js", "UFLAG_T"); +require("nodedefs.js", "NODE_MAIN"); +require("key_defs.js", "KEY_UP"); +require("gettext.js", "gettext"); +load("termsetup.js"); +var shell = load({}, "shell_lib.js"); + +system.settings &= ~SYS_RA_EMU; // Use (R)e-read and (A)uto-reply keys + +const help_key = '?'; +// If user has unlimited time, display time-used rather than time-remaining +const time_code = user.security.exemptions & UFLAG_T ? "\x86Time Used: @TUSED@" : "\x86Time Left: @TLEFT@"; + +const main_menu = { + file: "mode7/mode7_main", + eval: 'bbs.main_cmds++', + node_action: NODE_MAIN, + prompt: time_code + + gettext("\x87->\x83Main\x87-> "), + command: { + 'C': { exec: 'mode7/mode7_chat.js' }, + 'D': { exec: 'eotl_xtrn.js' }, + 'E': { exec: 'mode7/mode7_email.js' }, + 'F': { exec: 'eotl_xfer.js' }, + 'G': { eval: 'shell.logoff(/* fast: */false)' }, + 'N': { exec: 'mode7/mode7_forums.js' }, + '/G': { eval: 'shell.logoff(/* fast: */true)' }, + '/O': { eval: 'shell.logoff(/* fast: */true)' }, + 'S': { exec: 'eotl_settings.js' }, + 'T': { exec: '../xtrn/ansiview/ansiview.js' }, + 'X': { exec: 'eotl_sysop.js' + ,ars: 'SYSOP' }, + '!': { eval: 'bbs.menu("sysmain")' + ,ars: 'SYSOP' }, + }, + nav: { + '\r': { }, + }, +}; + +var menu = main_menu; +var last_str_cmd = ""; + +// The menu-display/command-prompt loop +while(bbs.online && !js.terminated) { + if(!(user.settings & USER_EXPERT)) { + console.clear(); + bbs.menu(menu.file); + } + bbs.node_action = menu.node_action; + bbs.nodesync(); + eval(menu.eval); + console.newline(); + console.aborted = false; + console.putmsg(menu.prompt, P_SAVEATR); + var cmd = console.getkey(K_UPPER); + if(cmd > ' ') + console.print(cmd); + if(cmd == ';') { + cmd = console.getstr(); + if(cmd == '!') + cmd = last_str_cmd; +// var script = system.mods_dir + "str_cmds.js"; +// if(!file_exists(script)) +// script = system.exec_dir + "str_cmds.js"; +// js.exec(script, {}, cmd); + load({}, "str_cmds.js", cmd); + last_str_cmd = cmd; + continue; + } + if(cmd == '/') { + cmd = console.getkey(K_UPPER); + console.print(cmd); + cmd = '/' + cmd; + } + if(cmd > ' ') { + bbs.log_key(cmd, /* comma: */true); + } + console.newline(); + console.line_counter = 0; + if(cmd == help_key) { + if(user.settings & USER_EXPERT) + bbs.menu(menu.file); + continue; + } + var menu_cmd = menu.command[cmd]; + if(!menu_cmd) { + console.print("\r\n\x81" + gettext("Unrecognized command.")); + if(user.settings & USER_EXPERT) + console.print(" " + gettext("Hit") + "'" + help_key + "'" + gettext("for a menu.")); + console.newline(); + continue; + } + if(!bbs.compare_ars(menu_cmd.ars)) + console.print(menu_cmd.err); + else { + if(menu_cmd.msg) + console.print(menu_cmd.msg); + if(menu_cmd.eval) + eval(menu_cmd.eval); + if(menu_cmd.exec) { + var script = system.mods_dir + menu_cmd.exec; + if(!file_exists(script)) + script = system.exec_dir + menu_cmd.exec; + if(menu_cmd.args) + js.exec.apply(null, [script, {}].concat(menu_cmd.args)); + else + js.exec(script, {}); + } + } +} +// Can't do these statically through initialization: +main_menu.nav[KEY_UP] = { eval: 'shell.sub_up()' }; +main_menu.nav[KEY_DOWN] = { eval: 'shell.sub_down()' }; +main_menu.nav[KEY_RIGHT] = { eval: 'shell.grp_up()' }; +main_menu.nav[KEY_LEFT] = { eval: 'shell.grp_down()' }; diff --git a/exec/mode7/mode7_chat.js b/exec/mode7/mode7_chat.js new file mode 100644 index 0000000000..5be62f3afd --- /dev/null +++ b/exec/mode7/mode7_chat.js @@ -0,0 +1,142 @@ +// $Id: chat_sec.js,v 1.15 2020/01/05 23:50:35 rswindell Exp $ + +// Chat Section for any/all Synchronet command shells + +"use strict"; + +require("sbbsdefs.js", 'USER_EXPERT'); +require("nodedefs.js", 'NODE_CHAT'); +require("text.js", 'R_Chat'); + +// Over-ride these default values by creating/modifying the [chat] section in your ctrl/modopts.ini file +var options = load("modopts.js", "chat"); +if (!options) + options = load("modopts.js", "chat_sec"); +if (!options) + options = {}; +if (options.irc === undefined) + options.irc = true; +if (options.irc_server === undefined) + options.irc_server = "irc.synchro.net 6667"; +if (options.irc_channel === undefined) + options.irc_channel = "#Synchronet"; +if (options.irc_seclevel === undefined) + options.irc_seclevel = 90; +if (options.finger === undefined) + options.finger = true; +if (options.imsg === undefined) + options.imsg = true; + +if(user.security.restrictions & UFLAG_C) { + write(bbs.text(R_Chat)); + exit(0); +} + +// Set continue point for main menu commands +menu: +while(1) { + var str=""; + // Display TEXT\MENU\CHAT.* if not in expert mode + bbs.nodesync(); + if(!(user.settings & USER_EXPERT)) { + bbs.menu("mode7/mode7_chat"); + } + + // Update node status + bbs.node_action = NODE_CHAT; + bbs.nodesync(); + if(user.compare_ars("exempt T")) + console.putmsg ("\x86Time Used: @TUSED@"); + else + console.putmsg ("\x86Time Left: @TLEFT@"); + + // Display main Prompt + console.putmsg ("\x87->\x83Chat Menu\x87-> "); + + var keys = "ACEMNPQSTYWX?$%"; + if(options.imsg) + keys += "I"; + if(options.irc) + keys += "R"; + if(options.finger) + keys += "F"; + switch(console.getkeys(keys, K_UPPER)) { + case "S": + var val = user.chat_settings ^= CHAT_SPLITP; + writeln(""); + break; + case "A": + var val = user.chat_settings ^= CHAT_NOACT; + writeln(""); + system.node_list[bbs.node_num-1].misc ^= NODE_AOFF; + break; + case 'P': + var val = user.chat_settings ^= CHAT_NOPAGE; + writeln(""); + system.node_list[bbs.node_num-1].misc ^= NODE_POFF; + break; + case 'E': + if(user.compare_ars("SYSOP")) { + writeln(""); + system.operator_available = !system.operator_available; + } + break; + case 'F': + writeln(""); + load("finger.js"); + break; + case 'I': + writeln(""); + load({}, "sbbsimsg.js"); + break; + case 'R': + { + var server=options.irc_server; + if(user.security.level >= options.irc_seclevel || user.security.exemptions&UFLAG_C) { + write("\r\n\x01n\x01y\x01hIRC Server: "); + server=console.getstr(options.irc_server, 40, K_EDIT|K_LINE|K_AUTODEL); + if(console.aborted || server.length < 4) + break; + } + if(server.indexOf(' ') < 0) + server += " 6667"; + write("\r\n\x01n\x01y\x01hIRC Channel: "); + var channel=console.getstr(options.irc_channel, 40, K_EDIT|K_LINE|K_AUTODEL); + if(!console.aborted && channel.length) { + log("IRC to " + server + " " + channel); + bbs.replace_text(NodeActionCustom,"in Internet Relay Chat via " + client.protocol); + bbs.node_action = NODE_CUSTOM; + bbs.nodesync(); + bbs.exec("?irc -a " + server + " " + channel); // can't be load()ed because it calls exit() + bbs.revert_text(NodeActionCustom); + } + break; + } + case 'C': + bbs.multinode_chat(); + break; + case 'N': + bbs.private_chat(); + break; + case 'Y': + if(!bbs.page_sysop()) + bbs.page_guru(); + break; + case 'T': + bbs.page_guru(); + break; + case 'M': + bbs.exec_xtrn("MULTIRELAYCHAT"); + break; + case '?': + if(user.settings & USER_EXPERT) + bbs.menu("mode7/mode7_chat"); + break; + case 'Q': + break menu; + + default: + console.clear(); + break; + } +} diff --git a/exec/mode7/mode7_email.js b/exec/mode7/mode7_email.js new file mode 100644 index 0000000000..653d248173 --- /dev/null +++ b/exec/mode7/mode7_email.js @@ -0,0 +1,88 @@ +// E-mail Section + +// $Id: email_sec.js,v 1.10 2020/04/24 08:05:39 rswindell Exp $ + +// Note: this module replaces the old ### E-mail section ### Baja code in exec/*.src +// replace "call E-mail" with "exec_bin email_sec" + +require("sbbsdefs.js", "WM_NONE"); +require("userdefs.js", "USER_EXPERT"); +var text = bbs.mods.text; +if(!text) + text = load(bbs.mods.text = {}, "text.js"); +var userprops = bbs.mods.userprops; +if(!userprops) + userprops = load(bbs.mods.userprops = {}, "userprops.js"); +const ini_section = "netmail sent"; + +const NetmailAddressHistoryLength = 10; + +while(bbs.online) { + if(!(user.settings & USER_EXPERT)) + bbs.menu("mode7/mode7_email"); + + bbs.replace_text(720,'at email menu'); + bbs.node_action = NODE_CUSTOM; + bbs.nodesync(); + bbs.revert_text(720); + + writeln(); + if(user.compare_ars("exempt T")) + console.putmsg ("\x86Time Used: @TUSED@"); + else + console.putmsg ("\x86Time Left: @TLEFT@"); + + // Display main Prompt + console.putmsg ("\x87->\x83Email Menu\x87-> "); + + var wm_mode = WM_NONE; + var cmdkeys = "EFKNRSUQ?\r"; + switch(console.getkeys(cmdkeys,K_UPPER)) { + case 'R': // Read your mail + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to read emails\r\n"); + break; + } + bbs.read_mail(MAIL_YOUR, user.number); + break; + case 'U': // Read your un-read mail + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to read emails\r\n"); + break; + } + bbs.read_mail(MAIL_YOUR, user.number, LM_UNREAD|LM_REVERSE); + break; + case 'K': // Read/Kill sent mail + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to read emails\r\n"); + break; + } + bbs.read_mail(MAIL_SENT, user.number, LM_REVERSE); + break; + case 'E': // Send Feedback + bbs.email(/* user # */1, bbs.text(text.ReFeedback)); + break; + case 'F': + if(user.compare_ars("GUEST")) { + console.putmsg("Guests are not permitted to search emails\r\n"); + break; + } + bbs.exec("?../xtrn/DDMsgReader/DDMsgReader.js -search=keyword_search -subBoard=mail -startMode=list"); + break; + case 'S': // Send Mail + case 'N': // Send Mail + if(user.compare_ars("GUEST")) { + console.putmsg("You are not permitted to send mail as a guest\r\n"); + break; + } + bbs.exec("?/sbbs/xtrn/addressbook/addressbook.js",null,"/sbbs/xtrn/addressbook/"); + break; + case 'Q': // Quit + case '\r': + exit(0); + case '?': // Display menu + if(user.settings & USER_EXPERT) + bbs.menu("mode7/mode7_email.js"); + break; + } +} diff --git a/exec/mode7/mode7_forums.js b/exec/mode7/mode7_forums.js new file mode 100755 index 0000000000..1739b279a7 --- /dev/null +++ b/exec/mode7/mode7_forums.js @@ -0,0 +1,167 @@ +// Forums Section + +'use strict'; +require("sbbsdefs.js", "K_UPPER"); +require("userdefs.js", "USER_EXPERT"); +require("nodedefs.js", "NODE_MAIN"); +require("gettext.js", "gettext"); + +var shell = load({}, "shell_lib.js"); +var text = bbs.mods.text; +var last_str_cmd = ""; +if(!text) + text = load(bbs.mods.text = {}, "text.js"); + +main: +while(bbs.online && !console.aborted) { + console.aborted = false; + if(!(user.settings & USER_EXPERT)) { + console.home(); + bbs.menu("mode7/mode7_forums"); + } + + bbs.replace_text(720,'at forums menu via ' + client.protocol.toLowerCase()); + bbs.node_action = NODE_CUSTOM; + bbs.nodesync(); + bbs.revert_text(720); + + console.crlf(); + console.putmsg ("\x83@GRP@\x86<@GN@>\x83@SUB@\x86<@SN@>"); + console.crlf(); + console.crlf(); + if(user.compare_ars("exempt T")) + console.putmsg ("\x86Time Used: @TUSED@"); + else + console.putmsg ("\x86Time Left: @TLEFT@"); + + // Display main Prompt + console.putmsg ("\x87->\x83Forums\x87-> "); + + var cmd = console.getkey(K_UPPER); + console.print(cmd); + switch(cmd) { + case 'N': writeln('\r\n\x86' + gettext("New Message Scan")); + bbs.scan_subs(SCAN_NEW); + break; + case 'R': bbs.scan_msgs(); + break; + case 'L': bbs.list_msgs() + break; + case 'P': bbs.post_msg(); + break; + case 'C': writeln('\r\n\x86' + gettext("Continuous New Message Scan") + '\r\n'); + bbs.scan_subs(SCAN_CONT); + break; + case 'C': bbs.exec("?filescancfg.js"); + break; + case 'M': console.newline(); + var res = bbs.exec("?postpoll.js"); + if(console.aborted) { + console.aborted = false; + } + if(res > 1) + console.pause(); + break; + case 'V': bbs.exec("?scanpolls.js"); + break; + case 'T': console.home(); + bbs.qwk_sec() + break; + case 'J': shell.select_msg_area() + break; + case 'F': writeln('\r\n\x86' + gettext("Find Text in Messages") + '\r\n'); + bbs.scan_subs(SCAN_FIND); + break; + case 'S': writeln('\r\n\x86' + gettext("Scan for Messages Posted to You") + '\r\n'); + bbs.scan_subs(SCAN_TOYOU) + break; + case '&': console.home() + bbs.exec("?eotl_msgscanconf.js"); + break; + case '!': if (user.compare_ars("SYSOP")) + bbs.menu("sysmain"); + break; + case '*': shell.show_subs(bbs.curgrp) + break; + case '#': writeln('\r\n\x86' + gettext("Type the actual number, not the symbol.")); + console.pause(); + break; + case KEY_RIGHT: + case '>': + case '}': + case ')': + case '+': + shell.sub_up(); + break; + case KEY_LEFT: + case '<': + case '{': + case '(': + case '-': shell.sub_down(); + break; + case KEY_UP: + case ']': shell.grp_up(); + break; + case KEY_DOWN: + case '[': shell.grp_down(); + break; + case '?': // Display menu + if(user.settings & USER_EXPERT) + bbs.menu("mode7/mode7_forums"); + break; + case 'Q': exit(); + break; + } + if(cmd >= '1' && cmd <= '9') { + shell.get_sub_num(cmd); + continue; + } + if(cmd == ';' && user.compare_ars("SYSOP")) { + cmd = console.getstr(); + if(cmd == '!') + cmd = last_str_cmd; + var script = system.mods_dir + "str_cmds.js"; + if(!file_exists(script)) + script = system.exec_dir + "str_cmds.js"; + js.exec(script, {}, cmd); + last_str_cmd = cmd; + continue; + } + + if(cmd == '/') { + cmd = console.getkey(K_UPPER); + console.print(cmd); + switch(cmd) { + case 'D': if (user.compare_ars("REST NOT D")) { + writeln('\r\n\x86' + gettext("Download File(s) from User(s)")); + shell.download_user_files(); + } + continue main; + case 'F': writeln('\r\n\x86' + gettext("Find Text in Messages")); + bbs.scan_subs(SCAN_FIND); + continue main; + case 'N': bbs.scan_subs(SCAN_NEW, /* all */true); + continue main; + case 'U': writeln('\r\n\x86' + gettext("Upload File to User")); + shell.upload_user_file(); + continue main; + case 'O': shell.logoff(/* fast: */true); + continue main; + case 'S': bbs.scan_subs(SCAN_TOYOU, /* all */true) + continue main; + case '*': shell.show_grps(); + continue main; + case '#': writeln('\r\n\x86' + gettext("Type the actual number, not the symbol.")); + console.pause(); + continue main; + } + + if(cmd >= '1' && cmd <= '9') { + shell.get_grp_num(cmd); + continue; + } + + } + console.home(); + console.aborted = false; +} diff --git a/src/xpdev/mode7defs.h b/src/xpdev/mode7defs.h new file mode 100644 index 0000000000..2f3b279bcb --- /dev/null +++ b/src/xpdev/mode7defs.h @@ -0,0 +1,72 @@ +/* Commodore/PET definitions */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU Lesser General Public License for more details: lgpl.txt or * + * http://www.fsf.org/copyleft/lesser.html * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ +#ifndef _MODE7DFS_H_ +#define _MODE7DEFS_H_ + +enum mode7_char { + /* Colors */ + MODE7_ALPHA_RED = 129, + MODE7_ALPHA_GREEN = 130, + MODE7_ALPHA_YELLOW = 131, + MODE7_ALPHA_BLUE = 132, + MODE7_ALPHA_MAGENTA = 133, + MODE7_ALPHA_CYAN = 134, + MODE7_ALPHA_WHITE = 135, + MODE7_FLASH = 136, + MODE7_STEADY = 137, + MODE7_NORMAL_HEIGHT = 140, + MODE7_DOUBLE_HEIGHT = 141, + MODE7_GRAPHIC_RED = 145, + MODE7_GRAPHIC_GREEN = 146, + MODE7_GRAPHIC_YELLOW = 147, + MODE7_GRAPHIC_BLUE = 148, + MODE7_GRAPHIC_MAGENTA = 149, + MODE7_GRAPHIC_CYAN = 150, + MODE7_GRAPHIC_WHITE = 151, + MODE7_CONCEAL = 152, + MODE7_CONTIGUOUS_GFX = 153, + MODE7_SEPARATED_GFX = 154, + MODE7_BLACK_BG = 156, + MODE7_NEW_BG = 157, + MODE7_HOLD_GFX = 158, + MODE7_RELEASE_GFX = 159, + + /* Cursor movement */ + MODE7_LEFT = 8, + MODE7_RIGHT = 9, + MODE7_DOWN = 10, + MODE7_UP = 11, + MODE7_HOME = 30, + MODE7_CLEAR = 12, + /* Symbols (which don't align with ASCII) */ + MODE7_BRITPOUND = 96, + MODE7_QUARTER = 123, + MODE7_HALF = 92, + MODE7_THREE_QUARTER = 195, + MODE7_DIVIDE = 196 + /* Replacement chars (missing ASCII chars) */ +// PETSCII_BACKSLASH = '/', // the 109 graphics char is an 'M' in shifted/text mode :-( +// PETSCII_BACKTICK = 0xAD, // a graphics char actually +// PETSCII_TILDE = 0xA8, // a graphics char actually +// PETSCII_UNDERSCORE = 0xA4, // a graphics char actually +}; + +#endif /* Don't add anything after this line */ diff --git a/text/answer.m7 b/text/answer.m7 new file mode 100644 index 0000000000..e491c9f7c4 --- /dev/null +++ b/text/answer.m7 @@ -0,0 +1,15 @@ +�� �|,$|h4xl0|,h<th<|_<th<(|$ ��� s{5s{5�j5�pj7}ju�j5�jw � �///////,,.,,.,-.,,-.,-,,-.,-,/,//////// +CLIENT +�CONN: @CONN@ +�ADDR: @HOST@ +�IP : @IP@ +SERVER +�NAME:�@BBS@ +�ADDR: @HOSTNAME@ +�NODE: @NODE@ (of @TNODE@) +�TIME: @DATETIME@ @TIMEZONE@ +�ADMN: @SYSOP@ + +�If you are a new user to the system, +�type�"New"�now. Otherwise enter your +�username or number now. diff --git a/text/bullseye.m7 b/text/bullseye.m7 new file mode 100755 index 0000000000..343c8a2e31 --- /dev/null +++ b/text/bullseye.m7 @@ -0,0 +1,6 @@ +@CLS@���|l4|h4| | |$l<h4x|0|,�Last updated: �����{4oz%�0�0�1j5j5�j5s��Feb 5 2025 ��//,,.-,/,.,.,.-.-.,-.,,/////////////// �7````````````````````````````````````k �5���1 - Statistics for ��j �5���@BBS-L........................@��j +�5 j +�5���2 - New user instructions ��j �5 j �5���3 - About Synchronet ��j �5 j �5 j �5 j �5 j �5 j �`````````````````````````````````````` + +@EOF@ +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_NjT5oafEHxB8SbHmhp4-MPiwHMw8-iDrwyYemXI6QHAJ0v_9tN_pL_Yf2H9jqa6mv_U15_wcbLiQNUDJgyaoECBAcIr16xYuWrF6xcsXLFy1ctXLFq5YsXr169evXr169evXr16BAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQICbdGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aPWgJtQh0GxQLUFPph6aefTTj5oM2_kgQIECBAgQIECBAgOE9SAm1CHQcCFCprZi5cuXLly5cuXLly5cuXLly5cuXLoCA4T1ICbVAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECDUgJtQh0GyQLUE7L3QdeeXkg07ufTl1x9NO_dzQIECBAgOE9SAm1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICbUIdBs0C1BBxb-vRBT87sejlv3ZeiBAgQIECBAgQIDhPUgJtUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQINSAm1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICbVAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECDUgJtUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQINSAm1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICaNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=Jm00 diff --git a/text/menu/mode7/mode7_chat.m7 b/text/menu/mode7/mode7_chat.m7 new file mode 100755 index 0000000000..ac048cba1e --- /dev/null +++ b/text/menu/mode7/mode7_chat.m7 @@ -0,0 +1,4 @@ +@CLS@���|,h4h4xl0l< �Please use chat �����pj7k5�k5j5 �responsibly. ��//,,-.-.,-.-.///////////////////////// ���(C)hat multinode ����(N)ode to Node Chat ����(Y)ell for the Sysop ����(T)alk with the AI Guru ����(F)inger Remote Query ����(R)elay Chat (IRC) ����(I)nter BBS Instant Messaging ����(M)ulti Relay Chat ���� ��� ����(A)ctivity Alerts : @ALERTS|L3@ ����(P)aging Allowed : @PAGER|L3@ ����(S)plit Screen Chat : @SPLITP|L3@ �@SHOW:!SYSOP@���The Sysop is: @SYSAVAIL|L18@ �@SHOW@@SHOW:SYSOP@���(E)nable Paging : @SYSAVAILYN|L3@ ��� �@SHOW@��� (Q)uit to main menu � + +@EOF@ +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_FmhpoaeNjDY8QIEAOhsy4eeVB155UGPRh6IECBAgQHAJ0v_4am-tr_1tdTVAgQA-WXnw37uenFs8rkCBAgQIECBAcIr16xYtXLVyxauWrl69evXr169evXr169evXr169evXr16BAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIAZ0IohqdGHog29dnTTu35MqBAgQIECBAgQIECBAgQIECBAcBnQiicp35MqDpvQTt-TKgh6MPRAgQIECBAgQIECBAgQIEBwGdCKLKnLs2IM2_kg6aMqCn557-CBAgQIECBAgQIECBAgQHAZ0IoqKcOzWg76emhB00ZUEGSgj9eXVAgQIECBAgQIECBAcBnQiiMp07s-XkgpZdu_plQUeuXl5QIECBAgQIECBAgQIEBwGdCKKSnLsw-UEPRh6IFEmlDUoECBAgQIECBAgQIECBAgQHAZ0Iokqd3TLyQQoVNBJ3c-mHd0QTcvPnhz6d2dAgQIECBAcBnQiiap67OmlBSy7MPlBD0YeiBAgQIECBAgQIECBAgQIEBwGdCIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQHAh0GogqcfTT209PKCDsy8unNAgQOkECDMi0qlP5MZwECBAcCHQaigpw59O7Ogg7Nm_vlyIECBA6QQKEGPFpfJjOAgQIEBwIdBqKanhs09EFPHyy5dyCHow9EDpBAp0JkmpQ-TGcBAgQHAh0NApyJ9dAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAcBnQiBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIEBwYgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIBiBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=XN00 diff --git a/text/menu/mode7/mode7_email.m7 b/text/menu/mode7/mode7_email.m7 new file mode 100755 index 0000000000..2b94aef1be --- /dev/null +++ b/text/menu/mode7/mode7_email.m7 @@ -0,0 +1,4 @@ +@CLS@���|,_<<t_<th4| �Sending of spam is �����sj55�j7�j5�p �strictly prohibited. ��//,,-..,-.,-.,,/////////////////////// �7````````````````````````````````````k �5 �pppppp�j �5 �54<4 j�j �5 �55`5wj�j �5 �-,,,,.�j �5 j �5�(S) Send Local, QWK, or Email �j �5�(R) Read email sent to you �j �5�(U) Read your unread messages �j �5�(E) Email the Sysop �j �5�(F) Find text in emails �j �5�(K) Kill/Read sent mail �j �5 j �5 � (Q)uit to main menu �j �5 j �`````````````````````````````````````` + +@EOF@ +https://zxnet.co.uk/teletext/editor/`0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_FmB486YHnTQ0-IEAOnl3ZNO7Og35kHPhh2oNPNAgQHAJ0v_56mrX_qb_9TX_wQA-fTlpx9NnlBw5b9GnFp6Zci5AcIr16xYtXLli1csWrlixevXr169evXr169evXr169evXr16BAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQICjdGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aPWgKNUCBAgQIECBAgQIECBAgQIECBAgQIECBAgJ8OHDhw4FNSAo1QIECBAgQIECBAgQIECBAgQIECBAgQIECAm1aPGiDUU1ICjVAgQIECBAgQIECBAgQIECBAgQIECBAgQICbVqja99RTUgKNUCBAgQIECBAgQIECBAgQIECBAgQIECBAgJrVixYsXFNSAo1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICjUGopqUFPLuyIJm_Hh2LEFGvLWIN_JBF24dOxAgQIEBTUgKNQaikpQUsuHIgy7cOnYg55d3RB03oPO_qgQIECBAgQFNSAo1BqKqlBSy4ciDzv68kHXdyy4ciDbl588OfLzQIECBAU1ICjUGoiqUEXbh07EHTRlQU_PPfwQIECBAgQIECBAgQIEBTUgKNQaiMpQRtO7Ig6ZfHRBp3IMu3Dp2c0CBAgQIECBAgQFNSAo1BqJalBL07Ni-llw5EHPLu6INuHTsQIECBAgQIECBAU1ICjVAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECDUgKNUANAgQIECBAooqeunog6b0G3Dp3INuXd1QIECBAgQFNSAo1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAg1ICiNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=EA00 diff --git a/text/menu/mode7/mode7_forums.m7 b/text/menu/mode7/mode7_forums.m7 new file mode 100755 index 0000000000..76f89fa467 --- /dev/null +++ b/text/menu/mode7/mode7_forums.m7 @@ -0,0 +1,20 @@ +���|,h<|h<th4|_<<th<$�Please use +����`ju�j7}*u?j55�b{5�responsibly. +�//,/-,,-.,/,.-..,-,.///////////////////���(N)ew Message Scan +���(R)ead Messages +���(L)ist Messages +���(P)ost New Message +���(C)ontinuous New Scan +���(M)ake a Poll +���(V)iew/Vote in Poll +���(T)ransfer QWK Packet +���(F)ind Text in Messages +���(S)can For Messages to You +���(J)ump to New Area +���< > _ Select Subboard +���[ ] /_ Select Group +���(&) Message scan config + +���(Q)uit to Main Menu +@EOF@ +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_Fmh580POmhp8wPHnTQ8SA6GzLh55UHXnlQIECBAgQIAJ0v_R6uv_U3-qur_U1a_8XtqD5ZefDfu56cWzyuQIECBAgIr16xetWLFq5YvWLlq5csWrFy9evXr169evXr169evXr168GdCKJynL3QTcvPnhz5UFPHh3IECBAgQIECBAgQIECBAgQIAZ0IopKcuHIgm5efPDny80CBAgQIECBAgQIECBAgQIECBAgBnQiiYp08-iCbl588OfLzQIECBAgQIECBAgQIECBAgQIECAGdCKKCnfz6IJ2Xugm5efPDnyoECBAgQIECBAgQIECBAgQIAZ0Iohqd-7pp3dd_XmgnZe6Cnjw7kCBAgQIECBAgQIECBAgBnQiiapw68qDCgob9mxAgQIECBAgQIECBAgQIECBAgQIECAGdCKKynTl7r62_plQadyChv2bECBAgQIECBAgQIECBAgQIAZ0IoqKeWHdzzZeSCjXloKGHHry9ECBAgQIECBAgQIECBAgAnQ6iMp07siCpl8dEGncgm5efPDny80CBAgQIECBAgQIECACdDqKanHh3II2_kgm5efPDny80HTegs7-qBAgQIECBAgQIAh0GolKeu3gg6b0E7L3QQeWXCgQIECBAgQIECBAgQIECBAgCHQbxA-QX0CCnl2ZcfRBT64sW_DyyIECBAgQIECBAgQIECAIdB20F1AvvoKeXZlx9EEflv68ECBAgQIECBAgQIECBAgQIAh0GoTKUE3Lz54c-VBzx4dyDHv3ZtOdAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECAodBqKKnrp6IOm9BNw6dyCbl3dUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=TD00 diff --git a/text/menu/mode7/mode7_main.m7 b/text/menu/mode7/mode7_main.m7 new file mode 100755 index 0000000000..7936030474 --- /dev/null +++ b/text/menu/mode7/mode7_main.m7 @@ -0,0 +1,23 @@ +���|,$|h4xl0|,h4h4|,th<|_<th<(|$� +���s{5s{5�j5�pj7k5�`}ju�j5�jw �� +�//,,.,,.,-.,,-.-.,/,-,,-.,-,/,/////////���@DATETIMEZONE|C40@ +���(N)etworked Forums � �5 +�� � �5 +���(E)mail and Netmail � �5 +�� � �5 +���(F)ile Transfers � �5 +�� � �5 +���(C)hat and InterBBS Comms � �5 +�� � �5 +���(D)oors and External Programs� �5 +�� � �5 +���(S)ettings � �5 +�� � �5 +���(G)oodbye - Logoff � �5 +� ppppppppppppppppppppppppppppppppp5 +���CTRL-C�Abort Text Display +���CTRL-P�Send Private Messages +���CTRL-U�Display Who's Online +@EOF@ + +https://zxnet.co.uk/teletext/editor/#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECACdL_FiT5oaeNjD4s0NNDT4s6aHnzA86aHij4kQIECBAgQIAJ0vz9teftr_1Nf_DU31tf6P7q6_9TX_q7oP6BAgQIECBAgIr16xYuWLFyxauWLFq5auWL1i1YsWrli1YvWL169evXr169AgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIAh0OonKcvTvv5a8uRBG38uu3mgQIECBAgQIECAogONUCBAgCHUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQICiA41QIECAIdDqIqnbh07EGHdkQTsvTbh07ECBAgQIECBAgKIDjVAgQIAh1AgQIECBAgQIECBAgQIECBAgQIECBAgQIECAogONUCBAgCHQ6iMp07MqCpyw7uebLy5oECBAgQIECBAgQICiA41QIECAIdQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgKIDjVAgQIAh0OohqdGHogw7siCTu6ZeUKFTQQ9-3bzQIECAogONUCBAgCHUCBAgQIECBAgQIECBAgQIECBAgQIECBAgQICiA41QIECAIdDqIinfv5c0GHdkQRfHTLy3YdiChy35-WHbzKIDjVAgQIAh1AgQIECBAgQIECBAgQIECBAgQIECBAgQIECAogONUCBAgCHQ6impy9Omndn5oECBAgQIECBAgQIECBAgQICiA41QIECAIdQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgKIDjVAgQIAh0Oojqd-_Ji85UC1BM359-bMgQIECBAgQIECAogONUCBAgKIOHDhw4cOHDhw4cOHDhw4cOHDhw4cOHDhw4cOHDg1QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIAJ0HDqUpi2GHg4t_LogqZfHRBE08-GzD5QIECBAgQIECBAgAnQcOpSmLaAenl3ZEFDlp7YemVBNy8-eHPl5oECBAgQIECACdBw6lKYtqh4mnnw2YfKCvo3p-aCfu2ad2VAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA:PS=0:RE=0:zx=BU00 diff --git a/text/menu/msghdr.m7 b/text/menu/msghdr.m7 new file mode 100644 index 0000000000..8155870f61 --- /dev/null +++ b/text/menu/msghdr.m7 @@ -0,0 +1,6 @@ +���Subj:�@MSG_SUBJECT-L................@ +���Attr:�@MSG_ATTR-L...................@ +���To :�@MSG_TO-L.....................@ +���From:�@MSG_FROM-L...................@ +���Date:�@MSG_DATE-L..........@@MSG_TIMEZONE-L8@ + diff --git a/text/system.m7 b/text/system.m7 new file mode 100644 index 0000000000..4cb8c6f521 --- /dev/null +++ b/text/system.m7 @@ -0,0 +1,16 @@ +@CLS@@BBS@located in@LOCATION@ +with your sysop,@SYSOP@here to serve you. + +@HOSTNAME@is running@OS_VER@ +and has been online continuously for@UPTIME@hours. + +System Totals: + +Users: @TUSER|L.......@today: @STATS.NUSERS@ +Logons: @STATS.LOGONS|L@today: @STATS.LTODAY@ +Timeused: @STATS.TIMEON|L@today: @STATS.TTODAY@ +Messages: @TMSG|L........@today: @STATS.PTODAY@ +E-mail: @MAILW:0|L.....@today: @STATS.ETODAY@ +Feedback: @MAILW:1|L.....@today: @STATS.FTODAY@ +Files: @TFILE|L.......@today: @STATS.ULS@ + Downloaded today: @STATS.DLS@ (@STATS.DLB@ bytes) -- GitLab From e5b2ee64087fd4f95fb4e5277ac0b33236ca30e3 Mon Sep 17 00:00:00 2001 From: Nigel Reed <nigel@nigelreed.net> Date: Tue, 11 Feb 2025 19:08:42 -0600 Subject: [PATCH 4/4] Modified with Deuce's recommandation --- src/xpdev/mode7defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xpdev/mode7defs.h b/src/xpdev/mode7defs.h index 2f3b279bcb..4dd59ca0b3 100644 --- a/src/xpdev/mode7defs.h +++ b/src/xpdev/mode7defs.h @@ -60,8 +60,8 @@ enum mode7_char { MODE7_BRITPOUND = 96, MODE7_QUARTER = 123, MODE7_HALF = 92, - MODE7_THREE_QUARTER = 195, - MODE7_DIVIDE = 196 + MODE7_THREE_QUARTER = 125, + MODE7_DIVIDE = 126 /* Replacement chars (missing ASCII chars) */ // PETSCII_BACKSLASH = '/', // the 109 graphics char is an 'M' in shifted/text mode :-( // PETSCII_BACKTICK = 0xAD, // a graphics char actually -- GitLab