Egy rubbs-boardot Commodore 64 is hívhat. A
session.petscii!PETSCII-re állítja a vonalat (40×25, a C64 színei és billentyűi), miközben a felette lévő kód továbbra is UTF-8-at és ANSI-t ír; aBBS::Terminalmegkérdezi a hívót, milyen géppel jött; a kétarcú board pedig ugyanazon a porton ad modern és C64-es arcot. Ez az oldal mindhármat bemutatja, a Feediát és az Alexandria BBS-t kidolgozott példaként használva, és leírja, hogyan kerül vonalra egy valódi vagy emulált C64. ABBS::Petsciia 0.15.0, aBBS::Terminala 0.16.0 óta van meg.
A Commodore 64-nek nincs hálózati portja. Egy terminálprogrammal és egy modemmel éri el a telnetes boardot:
| Elem | Amit a hívók használnak |
|---|---|
| Terminálprogram | CCGMS (CCGMS Future), StrikeTerm, vagy PC-n a SyncTERM C64 módban. PETSCII módban kell lennie (ASCII-fordítás nélkül), a kisbetűs karakterkészlettel. |
| Modem | WiFi-modem (Zimodem, WiModem232 és társaik) a user porton vagy egy SwiftLink/Turbo232 cartridge mögött, SwiftLinken jellemzően 38400 baud, RTS/CTS. ATDT host:port-tal tárcsázzák, pl. ATDT teletypegames.org:2323. |
Amit ebből a board lát:
Ezért tippel a rubbs C64-re, ha nem jön ablakméret, és ezért alakít át a PETSCII-vonal mindent egyes bájtokká escape-szekvenciák helyett.
A VICE emulátor (x64sc) eljátssza a C64-et, a SwiftLinket és a modemvonalat: a VICE RS-232 eszköze közvetlenül egy TCP-hoszthoz kapcsolódik (a +rsdev1ip232 nyers TCP-t jelent, IP232-protokoll nélkül), terminálprogramnak pedig egy lemezképről induló CCGMS szolgál.
# A C64 with a SwiftLink at $DE00 (NMI), its line connected to a board over TCP,
# CCGMS autostarted from a disk image; CCGMS's saved config sets the SwiftLink to 38400.
x64sc -silent +cart \
-acia1 -acia1base 0xDE00 -acia1irq 1 -acia1mode 1 -myaciadev 0 \
-rsdev1 127.0.0.1:2323 -rsdev1baud 38400 +rsdev1ip232 \
-autostart ccgms.d64
Az -rsdev1-gyel a kapcsolat már a CCGMS indulásakor nyitva van, így nem kell ATDT; a board felteszi az első kérdését, és a RETURN elfogadja a tippet (C64). A bájtokat emulátor nélkül is ellenőrizheted: kapcsolódj egy kis szkripttel, ne küldj NAWS-t, és nézd meg, mi jön vissza (lásd a példát a BBS::Terminal résznél).
session.petscii! és session.petscii?| Metódus | Mit csinál |
|---|---|
session.petscii! |
Mostantól a session egy C64-gyel beszél. A term_cols / term_rows értéket 40×25-re állítja, végleg kikapcsolja az egérjelentést (az enable_mouse ezután nem csinál semmit), nyersen elküldi a LOWERCASE, LOCK_CASE és CLEAR kódot (kisbetűs karakterkészlet, lezárt C= + Shift, üres képernyő), és egy BBS::Petscii::Encoder-t tesz a write elé. Másodszori hívásra nem csinál semmit. |
session.petscii? |
true, miután a petscii! lefutott. |
A petscii! után:
session.write az Encoderen megy át, így egy Flow, egy FakeOS, egy Application vagy egy door továbbra is UTF-8 szöveget ír ANSI-színekkel és kurzormozgással;readkey és a readline a C64 billentyűit dekódolja (lásd A C64 billentyűi lent);Egy 40 oszlopra rajzolt Flow, FakeOS vagy door változtatás nélkül fut C64-en; egy 80 oszlopra rajzolt tördelődik.
require 'bbs'
BBS.configure do |c|
c.flow = BBS::Flow.define do
call do |_ctx, runner|
session = runner.session
session.petscii!
session.write "\e[1;33mREADY.\e[0m\r\n"
session.write "#{session.term_cols}x#{session.term_rows}, petscii: #{session.petscii?}\r\n"
nil
end
end
end
BBS.start
BBS::Petscii konstansaiA konstansok a PETSCII-kódok egykarakteres UTF-8 stringként (a C0/C1 kódpontok), így közvetlenül beírhatók egy stringbe: a "#{BBS::Petscii::YELLOW}READY." sárga a C64-en.
| Konstans | Kód | Jelentés |
|---|---|---|
COLS, ROWS |
40, 25 | A C64 szöveges képernyője. |
CLEAR |
0x93 |
Képernyőtörlés, kurzor a bal felső sarokba. |
HOME |
0x13 |
Kurzor a bal felső sarokba. |
UP, DOWN, LEFT, RIGHT |
0x91, 0x11, 0x9d, 0x1d |
Kurzormozgás. |
RVS_ON, RVS_OFF |
0x12, 0x92 |
Inverz be és ki. A RETURN is kikapcsolja az inverzet. |
DEL |
0x14 |
Törlés (backspace) a C64-en. |
BELL |
0x07 |
Csengő. |
LOWERCASE, UPPERCASE |
0x0e, 0x8e |
Váltás a kisbetűs (szöveges) vagy a nagybetűs (grafikus) karakterkészletre. |
LOCK_CASE |
0x08 |
Lezárja a karakterkészletet, így a C= + Shift már nem vált. Ez az ASCII backspace-e, és az Encoder a 0x08-at kurzor-balra alakítja: nyersen küldd (a petscii! így tesz). |
CONTROLS |
tömb | A vezérlőbájtok, amelyeket az Encoder változatlanul továbbad a C64-nek. |
DEFAULT |
LIGHT_GREY |
A sima szöveg színe (\e[0m). |
A C64-nek 16 szövegszíne van. Mindegyik írható közvetlenül, a legtöbb ANSI-ból is elérhető.
| Konstans | Kód | Az ANSI, ami ezt adja |
|---|---|---|
WHITE |
0x05 |
\e[1;37m, \e[97m |
RED |
0x1c |
\e[31m |
GREEN |
0x1e |
\e[32m |
BLUE |
0x1f |
\e[34m |
ORANGE |
0x81 |
\e[33m (sötétsárga) |
BLACK |
0x90 |
(nincs: írd a konstanst) |
BROWN |
0x95 |
(nincs: írd a konstanst) |
LIGHT_RED |
0x96 |
\e[1;31m, \e[91m |
DARK_GREY |
0x97 |
\e[30m, \e[1;30m, \e[90m (a fekete sötétszürke: egy fekete-szürke door is olvasható maradjon a C64 fekete képernyőjén) |
GREY |
0x98 |
\e[2m, \e[2;37m (halvány) |
LIGHT_GREEN |
0x99 |
\e[1;32m, \e[92m |
LIGHT_BLUE |
0x9a |
\e[1;34m, \e[94m |
LIGHT_GREY |
0x9b |
\e[37m, \e[0m (az alapértelmezett) |
PURPLE |
0x9c |
\e[35m, \e[1;35m |
YELLOW |
0x9e |
\e[1;33m, \e[93m |
CYAN |
0x9f |
\e[36m, \e[1;36m |
A COLORS mind a 16-ot felsorolja; az ANSI_DARK és az ANSI_BRIGHT az ANSI-leképezés két sora (0–7. index = fekete, piros, zöld, sárga, kék, magenta, cián, fehér). A félkövér (1) a világos sort választja. A háttérszínek (40–47) és a 256 színű / truecolor kódok (38;5;n, 38;2;r;g;b, 48;…) elvesznek: a C64-terminál hátterét a terminálprogram adja.
A BBS::Petscii::Encoder#encode(data) egy stringet PETSCII-bájtokká alakít (bináris string). A session hívásonként egy Encodert tart, mert az Encodernek állapota van: a kurzor oszlopa, az aktuális szín, az inverz mód, és a két írás közé eső, félbevágott escape-szekvencia.
| Bemenet | Kimenet a C64-en |
|---|---|
A–Z / a–z |
PETSCII-módra felcserélve: A → 0xc1, a → 0x41, így a kisbetűs készletben helyes kis- és nagybetűként jelennek meg. |
Számjegyek, szóköz, !"#$%&'()*+,-./:;<=>?@[] |
Változatlanul. |
Keretrajzoló ─│┌┐└┘├┤┬┴┼ (szimpla, dupla, vastag, lekerekített) |
A C64 vonalas karakterei. A kisbetűs karakterkészletben nincs lekerekített sarok, ott a ╭╮╰╯ szögletes ┌┐└┘-ként látszik; a nagybetűs (grafikus) készletben megvan (Petscii::ROUNDED_CORNERS, a Petscii::Canvas rajzolja). |
█ |
Inverz szóköz. A ▀ ▐ inverz félblokk, a ▄ ▌ ▁ ▔ a C64 saját karaktere; a ░▒▓ egy sakktábla-minta, a ▖▗▘▝▚ a C64 negyedblokkjai. |
£ ← ↑ ✓ |
A C64 saját £, ←, ↑ és pipa karaktere. |
\ { } ~ ^ _ \| és ` | /, (, ), -, ↑, aláhúzás-karakter, függőleges vonal, '. |
|
Tipográfia – — ‘ ’ “ ” … · • ● ◄ ► → × ° |
A legközelebbi ASCII: -, ', ", ..., ., *, <, >, x, o. |
Ékezetes betűk á é ő ű Ä |
A betű ékezet nélkül (Unicode NFKD, a jelek elhagyva): á → a, Ő → O. ß → ss, π → pi. |
Minden más (€, emoji, CJK) |
?. |
\r\n |
Egy RETURN (0x0d). |
Magában álló \n |
Egy RETURN. |
Magában álló \r |
Vissza ugyanannak a sornak az elejére (RETURN + kurzor fel). |
\t |
Két szóköz. |
\b (0x08) |
Kurzor balra. |
\f (0x0c), \e[2J |
CLR. |
\e[H, \e[ROW;COLH, \e[…f |
HOME, majd annyi DOWN és RIGHT. |
\e[nA … \e[nD |
n × UP, DOWN, RIGHT, LEFT. |
\e[nG |
RETURN, UP, majd n−1 RIGHT (ugyanannak a sornak az n. oszlopa). |
\e[…m |
Szín és inverz (7 / 27), lásd a színtáblát. |
Egyéb escape-szekvenciák (\e[K, \e[?25l, \e(B, …) |
Elvesznek, akkor is, ha egy írás kettévágja őket. |
| PETSCII-vezérlőkódok (a konstansok) | Átmennek. |
Egyéb C0/C1 bájtok, DEL (0x7f) |
Elvesznek. |
A 40 oszlopos tördelés. Az Encoder számolja az oszlopokat. Egy pontosan 40 karakteres sornál a C64 magától sort tör; az utána jövő \r\n-t ilyenkor lenyeli, így nem keletkezik alatta üres sor.
Az érvénytelen UTF-8 kódolás előtt ?-re cserélődik.
Valódi bájtok, ruby -Ilib-bel a rubbs 1.0.0-n:
require 'bbs'
enc = BBS::Petscii::Encoder.new
hex = ->(s) { s.bytes.map { |b| format('%02x', b) }.join(' ') }
puts hex.(enc.encode("Hello, World!\r\n"))
# c8 45 4c 4c 4f 2c 20 d7 4f 52 4c 44 21 0d
puts hex.(enc.encode("\e[1;33mREADY.\e[0m\r\n"))
# 9e d2 c5 c1 c4 d9 2e 9b 0d (sárga, READY., világosszürke)
puts hex.(enc.encode("┌──┐\r\n│ok│\r\n└──┘\r\n"))
# b0 c0 c0 ae 0d dd 4f 4b dd 0d ad c0 c0 bd 0d
puts hex.(enc.encode("Árvíztűrő — 3…\r\n"))
# c1 52 56 49 5a 54 55 52 4f 20 2d 20 33 2e 2e 2e 0d
puts hex.(enc.encode("\e[2J\e[3;5Hx"))
# 93 13 11 11 1d 1d 1d 1d 58 (CLR, HOME, 2 x DOWN, 4 x RIGHT, x)
puts hex.(enc.encode("€ ☺"))
# 3f 20 3f
puts hex.(BBS::Petscii::Encoder.new.encode('a' * 40 + "\r\nb"))
# 41 negyvenszer, majd 42: a teli sor után nincs RETURN
e2 = BBS::Petscii::Encoder.new
puts hex.(e2.encode("\e[1;3")) + ' | ' + hex.(e2.encode("2mGo"))
# | 99 c7 4f (a szekvencia a második írásban fejeződik be: világoszöld)
BBS::Petscii.bytes és BBS::Petscii.key| Metódus | Mit csinál |
|---|---|
BBS::Petscii.bytes(codes) |
Egy PETSCII-kódpontokból (pl. a konstansokból) álló string bájtjai, bináris stringként. Ezzel küldhetsz PETSCII-t az Encoder megkerülésével. |
BBS::Petscii.key(byte) |
Egy C64-ről jött bájt billentyűként, ahogy a readkey adja vissza: Symbol, egykarakteres String, vagy nil, ha a bájt nem billentyű. PETSCII-vonalon a readkey és a readline ezt használja. A billentyűbájtok egyetlen táblában vannak, a Petscii::KEYS-ben (bájt → billentyű); a régi KEY_* konstansok az 1.0-ban megszűntek. |
BBS::Petscii.bytes("#{BBS::Petscii::LOWERCASE}#{BBS::Petscii::LOCK_CASE}#{BBS::Petscii::CLEAR}")
# => "\x0E\b\x93" (0e 08 93: what petscii! sends first)
[0x41, 0xc1, 0x0d, 0x14, 0x03, 0x5f, 0x85, 0x8c, 0x5c, 0xa0, 0x93].map { |b| BBS::Petscii.key(b) }
# => ["a", "A", :enter, :backspace, :escape, :escape, :f1, :f8, "£", " ", nil]
Átkapcsolt sessionön nyers PETSCII-t (az Encoder kihagyásával) a socketre írva küldhetsz: session.line.write(BBS::Petscii.bytes(BBS::Petscii::LOCK_CASE)).
PETSCII-vonalon a readkey ezeket adja:
| C64-billentyű | Bájt | readkey |
|---|---|---|
| Betű | 0x41–0x5a |
kisbetűs String ("a") |
| Shift + betű | 0xc1–0xda (vagy 0x61–0x7a) |
nagybetűs String ("A") |
| Számjegyek, szóköz, írásjelek | 0x20–0x40, [, ] |
az adott karakter |
£ |
0x5c |
"£" |
↑ |
0x5e |
"^" |
| Shift + szóköz | 0xa0 |
" " |
| RETURN | 0x0d |
:enter |
| INST/DEL | 0x14 |
:backspace |
| Kurzor le / fel | 0x11 / 0x91 |
:down / :up |
| Kurzor jobbra / balra | 0x1d / 0x9d |
:right / :left |
| CLR/HOME | 0x13 |
:home |
| RUN/STOP | 0x03 |
:escape |
← (bal felső billentyű) |
0x5f |
:escape |
| F1 … F8 | 0x85, 0x89, 0x86, 0x8a, 0x87, 0x8b, 0x88, 0x8c |
:f1 … :f8 |
| Minden más (színbillentyűk, CLR, …) | kimarad |
C64-en nincs :tab, nincs :ctrl_…, és nincs egér. Egy mindkét gépen működő board a RETURN-re, a kurzorbillentyűkre, a betűkre és a számjegyekre építsen, és a :escape-et vegye „vissza”-nak (a RUN/STOP és a ← is ezt adja).
A readline(mask:) PETSCII-vonalon ugyanezeket a billentyűket fogadja, PETSCII-ben visszhangoz (vagy a maszkot), és az INST/DEL egy teljes karaktert töröl. RETURN-re UTF-8 stringként adja vissza a sort.
A kétarcú boardnak az első képernyője előtt tudnia kell, hogy ANSI-t vagy PETSCII-t beszéljen. A BBS::Terminal (lib/bbs/terminal.rb) ez az első kérdés, közösen minden C64-es arcú boardnak.
MY BOARD
1 - MODERN (ANSI/XTERM, 256 COLORS)
2 - COMMODORE 64 (PETSCII, 40 COLUMNS)
YOUR TERMINAL [2]:
:ctrl_t-ként érkezik) törli a választást.| Konstans | Érték | Jelentés |
|---|---|---|
Terminal::SETTLE |
1.5 |
Ennyi másodpercig vár a guess a telnet-válaszokra. |
Terminal::WAIT |
60 |
Ennyi másodpercig vár a kérdés billentyűre, mielőtt az alapértelmezést veszi. |
Terminal::FACES |
hash | Arconként: a számjegy, a felirat és a kijelölő billentyűk. |
| Arc | Számjegy | Kijelölő billentyűk |
|---|---|---|
:modern |
1 |
1, a, A, m, M |
:petscii |
2 |
2, c, C, p, P |
Terminal.guess(session)BBS::Terminal.guess(session) # => :modern or :petscii
Meghívja a session.settle(timeout: 1.5)-öt: megvárja a kliens ablakméretét, és eldobja, amit közben gépel. A 40 oszlopnál szélesebb jelentett ablak :modern; a 40 vagy kevesebb oszlop, vagy ha semmilyen jelentés nem jön (a WiFi-modem mögötti C64 sima TCP-t beszél), :petscii.
Terminal.flow(title:, modern:, petscii:)BBS::Terminal.flow(title: 'My Board', modern: MODERN_FLOW, petscii: PETSCII_FLOW) # => a BBS::Flow
Az egész első lépés egy Flow-ként, a config.flow-ba téve:
Terminal::Question az 1.0 óta privát: kérdezni csak a Terminal.flow-val lehet); megszakadt vonalnál véget ér a hívás;:petscii-nél meghívja a session.petscii!-et; :modern-nél a session.enable_mouse-t, de csak ha a BBS.config.mouse be van kapcsolva (a 0.16.1 óta);ctx[:session_id] és minden, ami előtte bekerült).Az egér kapcsolása. Az egérjelentés egy escape-szekvenciával indul (\e[?1002h\e[?1006h), ami a C64-en szemét lenne. Ezért a kétarcú board config.mouse = true-t állít (a modern arc egeret akar) és config.mouse_on_connect = false-t (ne kapcsolja be a kérdés előtt); a Terminal.flow a modern választás után kapcsolja be.
BBS.configure do |config|
config.mouse = true
config.mouse_on_connect = false # the mouse's escape sequence is garbage on a C64
config.flow = BBS::Terminal.flow(title: 'My Board', modern: MODERN, petscii: PETSCII)
end
Amit a vonal visz (egy NAWS nélkül kapcsolódó szkript, majd RETURN):
board → caller ff fb 03 ff fb 01 ff fd 03 ff fd 1f telnet: WILL SGA, WILL ECHO, DO SGA, DO NAWS
...1.5 s, no NAWS from the caller...
board → caller "\r\n\r\nMY BOARD\r\n\r\n1 - MODERN ...\r\n2 - COMMODORE 64 ...\r\n\r\nYOUR TERMINAL [2]: "
caller → board 0d RETURN takes the guess
board → caller 32 0d 0a "2", new line
board → caller 0e 08 93 petscii!: LOWERCASE, LOCK_CASE, CLEAR
...the C64 face, in PETSCII...
Egy port, két arc: a hívó válaszol a Terminal kérdésére, és vagy
Application-t: ablakok, menüsor, egér, 80 vagy több oszlop, 256 szín; vagyA két arc a domain-kódon (adatok, service-ek) osztozik, a UI-ból semmin. A házi felépítés, ahogy a Feedia BBS, az Alexandria BBS és a Teletype BBS használja:
bbs.rb BBS.configure + BBS::Terminal.flow(modern:, petscii:)
lib/domain/… the data: feeds, Wikipedia, … (no UI)
lib/ui/modern.rb UI::Modern.flow(...) → a BBS::Flow that runs an Application
lib/ui/petscii.rb UI::Petscii.flow(...) → a BBS::Flow with one call step
lib/ui/petscii/screen.rb UI::Petscii::Screen → the 40×25 screen helpers
bbs/feedia-bbs/bbs.rb (egy RSS-olvasó):
require 'bbs'
require_relative 'lib/domain/feeds'
require_relative 'lib/domain/inbox'
require_relative 'lib/ui/modern'
require_relative 'lib/ui/petscii'
feeds = Feeds.load(ENV.fetch('FEEDIA_FEEDS', File.join(__dir__, 'config/feeds.yml')))
inbox = Inbox.new(path: ENV.fetch('FEEDIA_INBOX', File.join(__dir__, 'data/inbox.jsonl')),
webhook: ENV.fetch('FEEDIA_DISCORD_WEBHOOK', ''))
BBS.configure do |config|
config.mouse = true
config.mouse_on_connect = false
config.idle_seconds = 600
config.flow = BBS::Terminal.flow(title: 'Feedia', modern: UI::Modern.flow(feeds, inbox),
petscii: UI::Petscii.flow(feeds, inbox))
end
BBS.start
Az Alexandria BBS (bbs/alexandria-bbs/bbs.rb, Wikipédia telnetvonalon) ugyanez, a feeds és az inbox helyett Wikipedia.new(...)-val és title: 'Alexandria BBS'-szel.
BBS::Petscii::ScreenA PETSCII-arc nem Application-t használ: sorokat ír, ahogy egy C64-es board tette. Egy ilyen board képernyője a rubbs része, a BBS::Petscii::Screen (0.29 óta); minden board a lib/ui/petscii/screen.rb-ben leszármaztat belőle, ha saját metódusok kellenek. Az ötletei:
Színek ANSI-ként. A képernyő ANSI-színeket ír, amelyeket a PETSCII-vonal a C64 színeivé alakít. A rubbs szélességszámoló segédei (a FrameBuffer.wrap_ansi, az egyetlen sortördelő, és a clip_ansi) ismerik az ANSI-t, a PETSCII-vezérlőkódokat viszont szövegnek számolnák, így ANSI-val a tördelés helyes marad. A BBS::Petscii::Colors C64-es nevet ad a színeknek: WH YE CY LG GR DG LB BL GN RD PU OR, az inverz be- és kikapcsolása RV/RO. Ezek az egyetlen paletta, a BBS::Ansi színeinek C64-es nevei (a YE a BBS::Ansi::BRIGHT_YELLOW, az LG a BBS::Ansi::GREY, a szöveg színe).
module UI
module Petscii
BBS::Petscii::Colors.install(self) # bare WH, YE, LG … in every class nested here
class Screen < BBS::Petscii::Screen
def banner(text) = puts(" #{YE}#{text}#{LG}") # the board's own methods
end
end
end
A metódusai, mindegyik egy C64-es boardos szokás (alapból 40×25; a Screen.new(session, cols: 80, rows: 24) modern terminált is kiszolgál):
| Metódus | Mit csinál |
|---|---|
cls |
Törli a képernyőt: C64-en CLR, modern terminálon ANSI. |
title(text, right = '') |
Üres képernyő egy inverz cián címsor alatt, balra a text, jobbra a right (egy darabszám, egy nyelv), 39 oszlop szélesen. |
say(text, color: LG) |
38 oszlopra tördelt szöveg, egy szóközzel beljebb. A szín kulcsszó: say('Posted.', color: GN). |
rule(color: DG) |
Vízszintes vonal, 39 oszlop. |
key(timeout:) |
readkey, bontáskor IOError-t dob (így a call lépés csendben ér véget). |
choose(prompt, keys, back: 'q') |
Egybillentyűs kérdés: a keys (kisbetűk) egyikére vár, a RUN/STOP és a ← a back-et adja, a billentyűt nagybetűvel visszhangozza. |
ask(prompt, text:, mask:, max:) |
Egy BBS::Field-be gépelt sor, levágott szélekkel. |
edit(text = '', title:, single_line: false, max: nil) |
A teljes képernyős BBS::Editor a képernyő méretében: mentéskor a szöveg, kilépéskor nil. |
pause(text = 'return: back') |
Bármely billentyűre vár. |
page(heading, lines, right:, wait:, numbers:) |
Képernyőnként (20 sor) mutatja a sorokat a címsor alatt; RETURN-re jön a következő, a q vagy a RUN/STOP korábban kilép; numbers: true mellett a címsorban ott a 2/5. |
pick(heading, items, empty:, right:, commands:) { label } |
Számozott BBS::Selector.list a címsor alatt: kurzorral vagy a számmal választ, aztán RETURN; q, ← vagy RUN/STOP esetén nil. |
menu(items, back:) |
Egy BBS::Selector a kurzornál. |
actions(*pairs) |
Billentyűk egy sorban, kurzoros menüként: screen.actions(%w[r read], %w[q back]). |
plain(text) |
C64-en BBS::Petscii.plain(text): a tipográfiai jelek és az ékezetek ASCII-vé válnak, így a sor ott törik, ahol számolták. |
A képernyő minden menüje BBS::Selector, az alapszíneivel, a BBS::Selector::COLORS-szal (a text key bar heading about hint szerepek, a paletta C64-es neveivel). Ha egy board más láblécet szeretne, ebbe fésüli bele a sajátját: BBS::Selector::COLORS.merge(hint: "#{CY}#{RV}").
A 0.x-ről az 1.0-ra egy C64-es arc három helyen változik: a say(text, GN) és a rule(DG) helyett say(text, color: GN) és rule(color: DG) kell; az editor(max, title) helyett edit(title: title, max: max).to_s (kilépéskor nil-t ad); a Petscii::Screen::MENU pedig megszűnt, ezért a colors: MENU elhagyható, a MENU.merge(…) helyére BBS::Selector::COLORS.merge(…) kerül. A Petscii::Screen.plain helyett BBS::Petscii.plain van. A teljes lista a gem UPGRADING.md-jében.
Az arc flow-ja egyetlen call lépés, amely az egész hívást viszi, és egy második, amely elköszön; az elköszönés elkapja a bontási hibákat, mert egy menü közben bontó hívó ne hagyjon backtrace-t maga után:
def self.flow(feeds, inbox)
BBS::Flow.define do
call do |ctx, runner|
Reader.new(feeds, inbox, Screen.new(runner.session), ctx).run
nil
end
call do |_ctx, runner|
C64.goodbye(Screen.new(runner.session))
nil
rescue IOError, Errno::EPIPE, Errno::ECONNRESET
nil
end
end
end
A Reader maga a board: egy fejléc, egy F/S/W/Q menü, a feedek a pick-en át, egy elem a page-en át (a Markdownja BBS::Markdown.to_lines(body, width: 38, theme: {...})-val, a képernyő színeiben). Az Alexandria Proxy-ja ugyanilyen felépítésű: egy prompt, amely címet vár, a találatok a pick-en, egy szócikk szakaszai a page-en át.
Rajzolás 40 oszlopra. A logók inverz szóközökből állnak (RV + szóközök + RO), ezek mindkét gépen ugyanúgy látszanak; a keretrajzoló karakterek és a █ is rendben vannak, az Encoder leképezi őket. A képernyő a címsort és a vonalakat 39, a szöveget 38 oszlopon tartja; a pontosan 40 karakteres sor is működik, mert az Encoder lenyeli a C64 saját sortörése utáni RETURN-t.
Egy kicsi, futtatható board: hírek, modern terminálon egy Application, C64-en a rubbs BBS::Petscii::Screen-je.
require 'bbs'
NEWS = [
['Board opens', 'The board is open for callers from today. Call often, and tell your friends.'],
['PETSCII face', 'A Commodore 64 gets the same news on 40 columns, in PETSCII.']
].freeze
# The modern face: an Application with a mouse.
MODERN_APP = BBS::Application.define do
theme BBS::Theme.synchronet
body do
NEWS.each_with_index do |(title, text), i|
add BBS::Widgets::Label.new(text: "#{title}: #{text}", style_key: :text,
bounds: BBS::Widget::Rect.new(3, 3 + i, 74, 1))
end
end
status_hint('F10', 'Log off') { :halt }
end
MODERN = BBS::Flow.define do
app MODERN_APP
end
# The PETSCII face: a 40x25 screen, the news as a numbered cursor menu.
PETSCII = BBS::Flow.define do
call do |_ctx, runner|
screen = BBS::Petscii::Screen.new(runner.session)
while (item = screen.pick('my board', NEWS, right: 'q: log off', &:first))
title, text = item
screen.title(title)
screen.say(text)
screen.pause
end
nil
end
end
BBS.configure do |config|
config.mouse = true
config.mouse_on_connect = false
config.idle_seconds = 600
config.flow = BBS::Terminal.flow(title: 'My Board', modern: MODERN, petscii: PETSCII)
end
BBS.start
A C64 oldalán a RETURN utáni első képernyő így kezdődik (rubbs 1.0):
0e 08 93 petscii!: lowercase set, case locked, clear
93 9f 12 20 4d 59 20 42 4f 41 52 44 20 … 51 3a 20 4c 4f 47 20 4f 46 46 20 92 9b
CLEAR, cyan, RVS ON, " my board … q: log off ", RVS OFF, light grey
9f 12 20 31 20 c2 4f 41 52 44 20 4f 50 45 4e 53 20 … 92 9b 0d
the lit item: cyan, RVS ON, " 1 Board opens", RVS OFF
9e 20 32 20 9b d0 c5 d4 d3 c3 c9 c9 20 46 41 43 45 … 0d
yellow " 2 ", light grey "PETSCII face"
BBS::Flow-t futtatja mindkét arcon, a PETSCII-arcon a screens/petscii/ 40 oszlopra rajzolt ERB-képernyőivel: Impostor::Petscii.flow(sessions: store).BBS::FakeOS változtatás nélkül fut PETSCII-vonalon.BBS::Gateway a PETSCII-hívót továbbadja egy másik boardnak, és mivel nem jelent ablakméretet, a túloldali kétarcú board C64-re tippel (lásd Doorok).readkey, readline, settle, NAWScall lépés és a contextBBS::Gateway