-
Notifications
You must be signed in to change notification settings - Fork 6
Xover zh_tw
Xover 列表系統是 MapleBBS 3.x 中所大量使用的列表顯示系統。
不同於 Pirate BBS 原本的 i_read
列表系統只能用在文章與信件列表,Xover 列表系統能夠用來顯示任何的列表。
本文所提到的 BBS 系統間的衍生關係,可見 TANet BBS 家族譜系圖,其中須注意:
- WindTop BBS 3.0x 是在 WindTop BBS 2.3x 基礎上,加入 MapleBBS 3.0x 的元素改版而來,主要架構已屬於 MapleBBS 3.x
- DreamBBS 2010 是 WindTop BBS 3.0x 的後代分支,因此主要架構也屬於 MapleBBS 3.x
- 現在的 DreamBBS v1 及更新版本是 DreamBBS 2010 的後代,架構上也屬於 MapleBBS 3.x
- DreamBBS 2010 是 WindTop BBS 3.0x 的後代分支,因此主要架構也屬於 MapleBBS 3.x
Pirate BBS MapleBBS 2.36 PttBBS FireBird BBS 2.51 Formosa BBS 1.1.1 |
Formosa BBS 1.4.1 | MapleBBS 3 | |
---|---|---|---|
列表主程式檔名 | read.c |
cursor.c |
xover.c |
列表主函式 | i_read() |
cursor_menu() |
xover() |
用途 | 文章與信件列表 - 精華區、看板列表 (Formosa BBS 1.1.1) - 好友列表 (FireBird BBS 2.51) |
主選單、文章、精華區、 投票、信件、看板、分類看板、 使用者、好友列表 - 可處理大部分全螢幕列表 |
除主選單外的大部分全螢幕列表 |
其它列表的處理方法 | 寫新的列表處理函式 | 用 cursor_menu() 改寫 |
- 用 xover() 改寫 - 寫新的列表顯示函式,用 xo_cursor() 處理游標位置 - DreamBBS v3.0 不再使用 xo_cursor() ,將其移除 |
i_read(direct, dotitle, doentry, rcmdlist)
char *direct ;
int (*dotitle)() ;
char *(*doentry)() ;
struct one_key *rcmdlist ;
void
i_read(int cmdmode, const char *direct, void (*dotitle) (),
void (*doentry) (), const onekey_t * rcmdlist, int bidcache)
- 多出參數
cmdmode
和bidcache
int cursor_menu( int y, int x,
char *direct,
struct one_key *comm,
int hdrsize,
int *ccur,
void (*cm_title) (),
void (*cm_btitle) (),
void (*cm_entry) (int, void *, int, int, int, int),
int (*cm_get) (char *, void *, int, int),
int (*cm_max) (char *, int),
int (*cm_findkey) (char *, void *, int, int ),
int opt, int autowarp)
- 參數
dotitle
更名為cm_title
- 參數
doentry
更名為cm_entry
- 參數
rcmdlist
更名為comm
- 多出參數
y
,x
,hdrsize
,ccur
,cm_btitle
,cm_get
,cm_max
,cm_findkey
,opt
, &autowarp
- 無參數
cmdmode
和bidcache
- 共 14 個參數
void
xover(int cmd)
- 參數
cmdmode
併入XZ::mode
- 參數
direct
併入XZ::dir
- 參數
dotitle
和doentry
放入 callback list - 參數
rcmdlist
併入XZ::cb
- DreamBBS v3.0: 改併入
XO::cb
- DreamBBS v3.0: 改併入
- 無參數
bidcache
(使用bbstate
+currbid
)
- Pirate BBS (1.9) 使用者列表的顯示函式與其參數(無游標,只能換頁)
printcuent(uentp)
struct user_info *uentp ;
- PttBBS (r4903) 使用者列表的游標及顯示函式與其參數
static void
pickup(pickup_t * currpickup, int pickup_way, int *page,
int *nfriend, int *myfriend, int *friendme, int *bfriend, int *badfriend)
8 個參數
static void
draw_pickup(int drawall, pickup_t * pickup, int pickup_way,
int page, int show_mode, int show_uid, int show_board,
int show_pid, int myfriend, int friendme, int bfriend, int badfriend)
12 個參數
- MapleBBS 3 的
xo_cursor()
與其參數 (取自 DreamBBS v2.0)
int
xo_cursor(
int ch, int pagemax, int num,
int *pageno, int *cur, int *redraw)
6 個參數
Pirate BBS MapleBBS 2.36 PttBBS FireBird BBS 2.51 MapleBBS 2.39 WD BBS Formosa BBS |
MapleBBS 3 | |
---|---|---|
按鍵處理函式 | - i_read() (Pirate BBS & Formosa BBS 1.1.1) - cursor_menu() (Formosa BBS 1.4.1) - i_read_key() (etc.) |
- xover() - xover_exec_cb() & xover_key() (DreamBBS v3) |
Callback 列表資料結構 | - struct one_key[] - onekey_t[126] (PttBBS) |
- KeyFunc[] - std::unordered_map<unsigned int, XoFunc> (DreamBBS v3; C++) |
Callback 列表結尾或條件 | - !one_key::fptr - !one_key::key (MapleBBS 2.39) - (固定長度) (PttBBS) - one_key::key == 'h' && (currmode & MODE_DIGEST) (MapleBBS 2.36, MapleBBS 2.39, & WD BBS) |
- KeyFunc::key == 'h' - KeyFunc::first == 'h' (DreamBBS v3; C) - std::unordered_map::end() (DreamBBS v3; C++) |
Callback 取得方法 | - Loop/O(n) - Direct indexing/O(1) (PttBBS) |
- Loop/O(n) - Hash table/O(1) (DreamBBS v3; C++) |
Pirate BBS MapleBBS 2.36 PttBBS FireBird BBS 2.51 MapleBBS 2.39 WD BBS |
Formosa BBS | MapleBBS 3 | |
---|---|---|---|
嘗試取得已載入列表的游標 | getkeep() |
(Array indexing) - 或不儲存 (1.4.1) |
xo_get() - 或不儲存 |
游標資料結構儲存空間取得 | (malloc() ) |
Statically allocated - 或 stack-based (1.4.1) |
xo_new() - 或 stack-based |
游標資料結構 | - struct keeploc - keeploc_t (PttBBS) |
(None) | XO |
游標紀錄資料結構 | - struct keeploc * - struct keepsome * (PttBBS) |
(None) | XO * |
游標紀錄儲存 | - struct keeploc *keeplist - struct keepsome *keeplist (PttBBS) |
- int t_top[TREASURE_DEPTH], t_cur[TREASURE_DEPTH] int mailtop, mailcur; (1.1.1) - (各自儲存或不儲存) (1.4.1) |
XO *xo_root - 或不儲存 |
游標紀錄儲存可見度 | Function-scope global | File-scope global | File-scope global |
游標紀錄資料結構類型 | - Singly linked list - Singly linked block (1 block = KEEPSLOT (10 )) (PttBBS) |
Array | Singly linked list |
游標資料取得方法 | - Loop/String comparison - Loop/Board number comparison (MapleBBS 2.39) - Loop/String hash (PttBBS) |
Array indexing | Loop/String comparison |
Pirate BBS MapleBBS 2.36 PttBBS FireBird BBS 2.51 MapleBBS 2.39 WD BBS |
Formosa BBS | MapleBBS 3 | |
---|---|---|---|
列表資料結構 | - struct fileheader - fileheader_t (PttBBS) - (any; 另有 struct fileheader ) (FireBird BBS 2.51) |
- FILEHEADER (1.1.1) - (any; 另有 FILEHEADER ) (1.4.1) |
(any; 另有 HDR 對應 struct fileheader ) |
列表資料儲存 (全域變數) | - struct fileheader *files - fileheader_t *headers (PttBBS) - char *pnt (FireBird BBS 2.51) |
- FILEHEADER *fheads (1.1.1) - char hdrs[MAX_SCREEN_SIZE * MAX_HDRSIZE] (1.4.1) |
- 通常為 char xo_pool[] - 通常為 char *xo_pool_base (DreamBBS v3) |
列表資料儲存空間取得 | - calloc() - calloc() + realloc() (PttBBS) |
- malloc() (1.1.1) - Statically allocated (1.4.1) |
- 通常為 statically allocated - 通常為 mmap() (DreamBBS v3) |
列表資料取得 | - get_records() - get_records_and_bottom() (PttBBS) |
- get_list() (1.1.1) - *_get() (1.4.1) |
通常為 xo_load()
|
列表資料取得方法 |
lseek() + read() 載入部分列表 |
lseek() + read() 載入部分列表 - 或用 memcpy() 取得已載入資料的一部分 (1.4.1) |
- 通常為 lseek() + read() 載入部分列表 - 通常為 mmap() 映射整個列表 (DreamBBS v3) |
使用場合 | Pirate BBS MapleBBS 2.36 PttBBS FireBird BBS 2.51 |
Formosa BBS | MapleBBS 2.39 WD BBS |
MapleBBS 3 |
---|---|---|---|---|
什麼都不做 | DONOTHING |
- R_NO /B_NO /M_NO (定義一致) (1.1.1) - C_NONE (1.4.1) |
RC_NONE |
XO_NONE |
切換列表資料檔,重新載入 | NEWDIRECT |
- R_NEW /B_NEW /M_NEW (定義一致) (1.1.1) - C_INIT (1.4.1) |
RC_NEWDIR |
XO_INIT |
列表資料檔有更動,重新載入 | - (FULLUPDATE ) (Pirate BBS) - DIRCHANGED (etc.) |
- (R_NEW ) (1.1.1) - ( C_INIT ) (1.4.1) |
RC_CHDIR |
(XO_INIT ) |
重新載入資料並重繪全畫面 | FULLUPDATE |
- (R_NEW ) (1.1.1) - C_LOAD (1.4.1) |
RC_FULL |
XO_INIT |
重新載入資料並從列表頭重繪 | PARTUPDATE |
- (R_NEW ) (1.1.1) - ( C_LOAD ) (1.4.1) |
RC_BODY |
XO_LOAD |
重繪全畫面 | (FULLUPDATE ) |
- R_FULL /B_FULL /M_FULL (定義一致) (1.1.1) - C_FULL (1.4.1) |
(RC_FULL ) |
XO_HEAD |
從列表前說明處重繪 | (FULLUPDATE ) |
- (R_FULL ) (1.1.1) - ( C_FULL ) (1.4.1) |
(RC_FULL ) |
XO_NECK |
從列表頭重繪 | - (PARTUPDATE ) - PART_REDRAW (MapleBBS 2.36 & PttBBS) |
- R_PART /B_PART (定義一致) (1.1.1) - ( C_FULL ) (1.4.1) - CX_GET (限內部處理) (1.4.1) |
RC_DRAW |
XO_BODY |
重繪某項 | (直接呼叫函式) | - (R_LINE ) (1.1.1) - ( C_LINE ) (1.4.1) |
- RC_ITEM - (直接呼叫函式) (WD BBS) |
- (直接呼叫函式) - 有些分支有增加 XO_ITEM - XO_CUR + diff (DreamBBS v3) |
重繪某項及畫面底部 | (直接呼叫函式) | - R_LINE /B_LINE /M_LINE (定義一致) (1.1.1) - C_LINE (1.4.1) |
(直接呼叫函式) | - (直接呼叫函式) - XR_FOOT + XO_CUR + diff (DreamBBS v3) |
從列表後說明處重繪 | - (PARTUPDATE ) - ( PART_REDRAW ) (MapleBBS 2.36 & PttBBS) |
- (R_PART ) (1.1.1) - ( C_FULL ) (1.4.1) |
(RC_DRAW ) |
- (XO_BODY ) - 有些分支有增加 XO_KNEE
|
重繪畫面底部 | - (PARTUPDATE ) - READ_REDRAW (MapleBBS 2.36 & PttBBS) |
- (R_PART ) (1.1.1) - C_FOOT (1.4.1) |
RC_FOOT |
XO_FOOT - WindTop BBS 3.x: 只清除螢幕底部 (不會有 footer) - MapleBBS-itoc: 在螢幕底部畫出 XZ::feeter - DreamBBS v3: 呼叫 callback 列表對應 XO_FOOT 的函式 |
重繪畫面頂部 | - (FULLUPDATE ) - TITLE_REDRAW (PttBBS) |
- (R_FULL ) (1.1.1) - ( C_FULL ) (1.4.1) |
(RC_FULL ) |
- (XO_HEAD ) - XR_PART_HEAD + key (DreamBBS v3) |
重新載入資料但不重繪 | - (PARTUPDATE ) - HEADERS_RELOAD (PttBBS) |
(操作資料結構重新載入) | (操作資料結構重新載入) | - (操作資料結構重新載入) - XR_PART_LOAD + key (DreamBBS v3) |
使用場合 | Pirate BBS MapleBBS 2.36 PttBBS FireBird BBS 2.51 MapleBBS 2.39 WD BBS |
Formosa BBS | MapleBBS 3 |
---|---|---|---|
指定某功能需要動態載入 | (無) | (無) | cmd | XO_DL |
將游標放到最尾項 | (直接操作) | (直接操作) | - (直接操作: xo->pos = XO_TAIL ) - XO_MOVE + XO_TAIL (DreamBBS v3.0 起支援) |
移動游標 | - (直接操作) - GOTO_NEXT (FireBird BBS 2.51) |
- CAREYDOWN & CAREYUP (1.1.1) - C_DOWN & C_UP (1.4.1) |
- XO_MOVE + pos - XO_MOVE + XO_REL + diff (DreamBBS v3.0 起支援) |
移動游標 (頭尾循環) | (無) | (無) | - XO_MOVE + XO_WRAP + pos - XO_MOVE + XO_WRAP + XO_REL + diff (DreamBBS v3.0 起支援) |
翻頁 | (直接操作) | - (直接操作 + CAREYDOWN /CAREYUP ) (1.1.1) - (直接操作 + C_MOVE ) (1.4.1) |
- XO_MOVE + pos ± XO_TALL - XO_MOVE + XO_REL ± XO_TALL (DreamBBS v3.0 起支援) - 尾項上捲: XO_MOVE + XO_REL - ((xo->max-1 - xo->top) % XO_TALL + 1) (DreamBBS v3.0) |
翻頁 (頭尾循環) | (無) | (無) | - XO_MOVE + XO_WRAP + pos ± XO_TALL - 尾項下捲: xo->top = 0, XR_BODY + XO_MOVE + XO_WRAP + XO_REL + BMIN(xo->max, XO_TALL) (DreamBBS v3.0) - 首尾項上捲: XO_MOVE + XO_WRAP + XO_REL - ((xo->max-1 - xo->top) % XO_TALL + 1) (DreamBBS v3.0) |
捲動列表 | (無) | (無) | - XO_MOVE + XO_SCRL + pos (DreamBBS v3.0 新增) - XO_MOVE + XO_SCRL + XO_REL + diff (DreamBBS v3.0 新增) |
捲動列表 (頭尾循環) | (無) | (無) | - XO_MOVE + XO_WRAP + XO_SCRL + pos (DreamBBS v3.0 新增) - XO_MOVE + XO_WRAP + XO_SCRL + XO_REL + diff (DreamBBS v3.0 新增) |
切換列表 | (無) | (無) | - XZ_<ZONE> = XO_ZONE + zone - XO_ZONE + XO_WRAP + zone (DreamBBS v3.0 起支援) - XO_ZONE + XO_REL + diff (DreamBBS v3.0 起支援) - XO_ZONE + XO_WRAP + XO_REL + diff (DreamBBS v3.0 起支援) |
回到上層列表 | (無) | (無) | (無;有 XO_LAST ,但未實作) |
離開列表函式 | - DOQUIT - QUIT (MapleBBS 2.39 & WD BBS) |
- (直接操作) (1.1.1) - C_REDO (1.4.1) |
XO_QUIT - QUIT 重新定義為 XO_QUIT (DreamBBS v3.0) |
範圍或對應的 bit mask | 相關 macro | 功能 | 註解 |
---|---|---|---|
0x00000000 - 0x0000001f
|
CTRL() /Ctrl()
|
Ctrl + 一般按鍵 | - CTRL() 出自 Eagles BBS - Ctrl() 出自 Phoenix BBS |
0x00000020 - 0x000000ff
|
(無) | 一般按鍵 | |
0x00000100 - 0x00001fff
|
(無) | 傳統特殊按鍵 | 出自 Phoenix BBS DreamBBS v1.0 恢復使用 |
0x0000001f |
KEY_ESC |
- Esc/Alt + 一般按鍵 - 單獨的 Esc (DreamBBS v3) |
- 按下的一般按鍵需用 KEY_ESC_arg 取得 - 出自 Phoenix BBS - MapleBBS 3 不使用 - DreamBBS v3.0 新增按鍵延時判斷機制,恢復使用 |
0x00002000 - 0x000020ff
|
Meta() /Esc()
|
Esc/Alt + 一般按鍵 | - Meta() 出自 MapleBBS 3 - Esc() 出自 Maple-itoc - Maple-itoc 不使用 |
0x00002100 - 0x00003fff
|
Meta() |
Esc/Alt + 特殊按鍵 | DreamBBS v2.0 起支援 |
0x00000060 (mask) |
Shift() /Ctrl()
|
特殊按鍵的 Shift/Ctrl | DreamBBS v2.0 起支援 |
Ctrl(key) |
0x00 : Ctrl
|
Mask 後變 0x00
|
|
Shift(Ctrl(key)) |
0x20 : Shift + Ctrl
|
Mask 後變 0x20
|
|
key |
0x40 : 正常 |
Mask 後變 0x40
|
|
Shift(key) |
0x60 : Shift
|
Shift() 為 DreamBBS v2.0 新增 Mask 後變 0x60
|
|
0x00004000 - 0x7fffffff
|
KEY_NONE = 0x4000
|
(不使用) | 保留給 Xover 列表系統使用 - DreamBBS v1.0 新增 - DreamBBS v2.0 改為現值 - DreamBBS v3.0 改為現用法 |
0x80000000 - 0xffffffff
|
(無) | MapleBBS 3 特殊按鍵 (負數) | DreamBBS v1.0 起不使用,保留給 Xover 系統 |
範圍或對應的 bit mask | 相關 macro | 功能 | 註解 |
---|---|---|---|
0x00000000 - 0x00003fff
|
(無) | 按鍵輸入 | |
0x00004000 - 0x0fffffff
|
(未使用) | (未使用) | |
0x10000000 - 0x1fffffff-XO_TALL
|
XO_MODE |
畫面重繪、資料載入、離開列表 | 實際上只使用 9 到 11 個 (有些分支有 XO_ITEM 及 XO_KNEE ,有些沒有) |
0x20000000-XO_TALL - 0x1fffffff
|
XO_MOVE + pos (pos < 0 ) |
設定游標位置 (頭尾循環) | Maple-itoc 修正前 - 會導致在列表第一頁向上翻頁時直接跳到列表最後一項 (MapleBBS 3; WindTopBBS 使用循環閱讀 UFO2_CIRCLE 時) |
0x20000000 - 0x27ffffff-XO_TALL
|
XO_MOVE + pos (pos >= 0 ) |
設定游標位置 | Maple-itoc 修正前 - 會導致在列表第一項向上移動游標時,無視循環閱讀設定而跳到列表最後一項 (WindTopBBS 不使用循環閱讀 UFO2_CIRCLE 時) |
0x28000000 - 0x3fffffff
|
XO_MOVE + XO_WRAP + pos (pos >= 0 ) |
設定游標位置 (頭尾循環) | Maple-itoc 修正前 |
0x20000000-XO_TALL - 0x20800000
|
XO_MOVE + pos |
設定游標位置 | Maple-itoc 修正後 |
0x20800001 - 0x3fffffff
|
XO_MOVE + XO_WRAP + pos |
設定游標位置 (頭尾循環) | Maple-itoc 修正後 - 循環發生時跳到頭尾 - 循環發生時跳到循環後的對應項 (DreamBBS v3.0) |
0x40000000 - 0x7fffffff
|
XO_ZONE + zone (zone >= 0 ) |
列表切換 | Maple-itoc 只使用 14 個 |
0x80000000 - 0xffffffff
|
key | XO_DL |
特殊按鍵 (負數) 或動態載入功能 | 不能以特殊按鍵做為 callback 列表的 key - DreamBBS v1.0 將特殊按鍵值恢復為傳統的正數,可做為 callback 列表的 key |
範圍或對應的 bit mask | 相關 macro | 功能 | 註解 |
---|---|---|---|
0x00000000 - 0x00003fff
|
key |
按鍵輸入 | |
0x00004000 |
XO_NONE = KEY_NONE
|
什麼都不做 - 可視為不對應任何功能的按鍵 |
與 Ctrl(' ') / Ctrl('@') ('\0' ) 作區分 |
0x00ffffff (mask) |
XO_MOVE_MASK |
游標移動相關 | |
0x001fffff (mask) |
XO_POS_MASK |
取得游標目標位置 | 實際目標位置是 pos - XO_MOVE XO_MOVE 是游標位置的 bias,設定為 0x00100000
|
- XR_* + key - XZ_ZONE + XZ_* + key
|
- 執行按鍵功能後進行畫面重繪及資料載入 - 執行按鍵功能後進行列表相關操作 |
經過 XO_MOVE_MASK mask 後為 0x00000000 - 0x00004000
|
|
- XR_* + {XO_WRAP|XO_SCRL|XO_REL} + key - XZ_ZONE + XZ_* + {XO_WRAP|XO_SCRL|XO_REL} + key
|
- XO_CUR (XO_REL + XO_CUR_BIAS ) - (未使用) (其它) |
經過 XO_MOVE_MASK mask 後不為 0x00000000 - 0x00004000 ,而經過 XO_POS_MASK mask 後為 0x00000000 - 0x00004000 - 不需要操作游標的雜項功能放這一區 |
|
- XR_* + XO_CUR + diff - XZ_ZONE + XZ_* + XO_CUR + diff
|
重繪游標所在行,並移動游標到指定的相對位置 | 經過 XO_MOVE_MASK mask 後為 0x00200000 - 0x00204000 - 移動範圍為 -0x2000 (-8192 ) - 0x2000 (8192 ) |
|
- XR_* + XO_MOVE + move - XZ_ZONE + XZ_* + XO_MOVE + move
|
- 設定列表游標位置後進行畫面重繪及資料載入 - 設定 zone 游標位置後進行列表相關操作 |
經過 XO_POS_MASK mask 後為 0x00004001 - 0x001fffff - 這限制了游標的移動範圍為 -0x000fbfff (-1032191) - 0x000fffff (1048575) |
|
0x00200000 (mask) |
XO_REL |
將游標位置解釋為相對位置 | |
0x00400000 (mask) |
XO_SCRL |
- 將游標移動解讀為捲動列表 (無 XZ_ZONE ) - (未使用) (有 XZ_ZONE ) |
|
0x00800000 (mask) |
XO_WRAP |
讓游標位置頭尾循環 | 會跳到循環後的對應項而非頭尾 |
0x3f000000 (mask) |
XO_REDO_MASK |
畫面重繪及資料載入相關 | 把 XR_PART_* macros or 起來的值 |
0x01000000 (mask) |
XR_PART_LOAD |
重新載入列表資料 | - XR_INIT = XR_PART_LOAD | XR_HEAD - XR_LOAD = XR_PART_LOAD | XR_BODY - XO_INIT = XR_INIT + XO_NONE - XO_LOAD = XR_LOAD + XO_NONE
|
0x02000000 (mask) |
XR_PART_HEAD |
重繪畫面頂部 | - XR_HEAD = XR_PART_HEAD | XR_NECK - XO_HEAD = XR_HEAD + XO_NONE
|
0x04000000 (mask) |
XR_PART_NECK |
重繪列表前說明 | - XR_NECK = XR_PART_NECK | XR_BODY - XO_NECK = XR_NECK + XO_NONE
|
0x08000000 (mask) |
XR_PART_BODY |
重繪列表 | - XR_BODY = XR_PART_BODY | XR_KNEE - XO_BODY = XR_BODY + XO_NONE
|
0x10000000 (mask) |
XR_PART_KNEE |
重繪列表後說明處 | - XR_KNEE = XR_PART_KNEE | XR_FOOT - XO_KNEE = XR_KNEE + XO_NONE
|
0x20000000 (mask) |
XR_PART_FOOT |
重繪畫面底部 | - XR_FOOT = XR_PART_FOOT - XO_FOOT = XR_FOOT + XO_NONE
|
0x7f000000 (mask) |
XO_ZONE_MASK |
列表操作相關 | 把 XZ_* macros or 起來的值 |
0x40000000 (mask) |
XZ_ZONE |
將操作解讀為列表操作 |
XO_ZONE = XZ_ZONE + XO_MOVE
|
0x01000000 (mask) |
XZ_INIT |
- 進行某 zone 的初始化工作 (無 XZ_SKIN ) - (未使用) (有 XZ_SKIN ) |
未實作 |
0x02000000 (mask) |
XZ_FINI |
- 進行某 zone 的收拾工作 (無 XZ_SKIN ) - (未使用) (有 XZ_SKIN ) |
未實作 |
0x04000000 (mask) |
XZ_BACK |
- 回到上次所在的 zone (未實作) - (未使用) (有 XZ_SKIN ) |
XO_LAST = (XZ_ZONE | XZ_BACK) + XO_NONE
|
0x08000000 (mask) |
XZ_QUIT |
離開 xover() 函式 |
XO_QUIT = (XZ_ZONE | XZ_QUIT) + XO_NONE
|
0x10000000 (mask) |
XZ_SKIN |
將操作解讀為使用者介面 skin 切換 (未實作) |
XO_SKIN = ((XZ_ZONE | XZ_SKIN) + XO_MOVE)
|
0x20000000 (mask) |
XZ_UNUSED5 |
(未使用) | |
0x80100000 (mask) |
XO_FSPEC_MASK |
指定回呼函式類別相關 用在 KeyFunc 的按鍵值上 |
把相關的 macros or 起來的值 DreamBBS v3.0 新增 |
0x80000000 (mask) |
key | XO_DL |
指定回呼函式需動態載入 | |
0x00100000 (mask) |
key | XO_POSF (= XO_MOVE ) |
指定回呼函式具有 pos 參數 |
DreamBBS v3.0 新增 |
0x7fefffff (mask) |
XO_FUNC_MASK (= ~XO_FSPEC_MASK ) |
用以取得忽略函式類別指定 flags 後的實際對應按鍵值 | DreamBBS v3.0 新增 |
圖例:欄位名(所佔位元數)
、欄位名 = 此欄定值(所佔位元數)
、欄位名 (= 此欄通常值)(所佔位元數)
(--
表示未使用或須為定值的位元)
- Xover 命令與回呼函式指定:
-
- MapleBBS 3.10 後,若在 命令 中加了
XO_DL
(不應使用),會造成需動態載入的按鍵功能載入後仍有XO_DL
,再次嘗試載入時會造成程式崩潰。
- MapleBBS 3.10 後,若在 命令 中加了
- 一般按鍵:
32| XO_DL(1) | -- = 0(3) | -- (= 0)(20) | 按鍵值(8) |0
- 特殊按鍵(不應使用):
32| XO_DL = 1(1) | -- (= 0x7fffff)(23) | 按鍵值的絕對值的二補數(8) |0
- MapleBBS 3.10 後,若用來 指定回呼函式,會被解析成有
XO_DL
而強制使用動態載入的方式載入按鍵功能,會造成程式崩潰。
- MapleBBS 3.10 後,若用來 指定回呼函式,會被解析成有
- 畫面重繪:
32| XO_DL(1) | -- = 0(2) | XO_MODE = 1(1) | -- (= 0)(24) | 重繪索引值(4) |0
-
- 限 Xover 命令:
- 游標移動:
32| -- (= 0)(1) | -- = 0(1) | XO_MOVE = 1(1) | --(1) | XO_WRAP(1) | 游標位置(27) |0
- 正游標位置,有加
XO_WRAP
:30 | XO_MOVE = 1(1) | XO_MODE = 0(1) | XO_WRAP = 1(1) | 游標位置(27) |0
- 負游標位置,有加
XO_WRAP
:30 | XO_MOVE = 1(1) | XO_MODE = 0(1) | XO_WRAP = 0(1) | 游標位置的絕對值的二補數(27) |0
- 正游標位置,未加
XO_WRAP
:30 | XO_MOVE = 1(1) | XO_MODE - 0(1) | XO_WRAP = 0(1) | 游標位置(27) |0
- 負游標位置,未加
XO_WRAP
:30 | XO_MOVE = 0(1) | XO_MODE = 1(1) | XO_WRAP = 1(1) | 游標位置的絕對值的二補數(27) |0
- 正游標位置,有加
- Zone 切換:
32| -- (= 0)(1) | XO_ZONE = 1(1) | -- (= 0)(26) | Zone 索引值(4) |0
- 游標移動:
- Xover 命令:
32| -- (= 0)(1) | XZ_ZONE(1) | XR_PART_*/XZ_* flags(6) | XO_WRAP(1) | XO_SCRL(1) | XO_REL(1) | 游標位置值或按鍵(21) |0
- 若加上
XO_DL
(不建議),會找不到對應的回呼函式 (C),或僅嘗試呼叫需動態載入的版本 (C++)。 - 無法在 Xover 命令 直接加上
XO_POSF
(會被解釋為XO_MOVE
),不過可透過xover_exec_cb()
直接呼叫對應的回呼函式(行為見後述)。 - 其中
21| 游標位置值或按鍵(21) |0
的部份為:- 正游標位置:
21 | XO_MOVE = 1(1) | 游標位置(20) |0
- 負游標位置:
21 | XO_MOVE = 0(1) | 游標位置的絕對值的二補數(20) |0
(游標位置的絕對值的二補數 >XO_NONE
/0x4000
) - 僅重繪畫面或切換 zone:
21 | XO_MOVE = 0(1) | -- = 0(5) | -- = XO_NONE(15) |0
- 按鍵與雜項功能:
21 | XO_MOVE = 0(1) | -- = 0(6) | 按鍵值(14) |0
- 正游標位置:
- 若加上
- 回呼函式指定與呼叫:
-
- 呼叫時,若加上
XO_POSF
(不建議),會找不到對應的回呼函式 (C),或僅嘗試呼叫帶pos
參數的版本 (C++)。
- 呼叫時,若加上
- 按鍵與雜項功能:
32| XO_DL(1) | -- = 0(7) | XO_WRAP(1) | XO_SCRL(1) | XO_REL(1) | XO_POSF(1) | -- = 0(6) | 按鍵值(14) |0
- 重繪畫面或切換 zone:
32| XO_DL(1) | XZ_ZONE(1) | XR_PART_*/XZ_* flags(6) | -- = 0(3) | XO_POSF(1) | -- = 0(5) | -- = XO_NONE(15) |0
其中31| XZ_ZONE(1) | XR_PART_*/XZ_* flags(6) |24
的部份為:
-
- 無
XZ_ZONE
時:31| XZ_ZONE = 0(1) | XR_PART_FOOT(1) | XR_PART_KNEE(1) | XR_PART_BODY(1) | XR_PART_NECK(1) | XR_PART_HEAD(1) | XR_PART_LOAD(1) |24
- 有
XZ_ZONE
時:31| XZ_ZONE = 1(1) | XZ_UNUSED5(1) | XZ_SKIN(1) | XZ_QUIT(1) | XZ_BACK(1) | XZ_FINI(1) | XZ_INIT(1) |24
- 除了頭尾循環邏輯改變,舊的 macro 使用方法仍然有效
- 將
XO_MOVE
重新定義為游標位置的 bias,避免游標位置為負時 flag bits 的改變 - 重繪畫面的各個
XO_*
macros 之間的相對大小不變 - 允許畫面重繪/重新載入 (
XR_*
) 的各個部分自由組合 (尚未實作) - 允許將畫面重繪/重新載入 (
XR_*
) 或列表操作 (XZ_ZONE + XZ_*
),與按鍵輸入或移動游標的操作組合表示 - 使用游標移動表示 zone 的切換
此結構為 MapleBBS 3.02 時引入。MapleBBS 3.00 的 xover()
尚未將相關處理邏輯結構化。
Member 名稱 | 型別 | 出處 | 說明 |
---|---|---|---|
xo |
XO * |
MapleBBS 3.02 | 用以存放此區域的游標資料 |
cb - 移入 XO (DreamBBS v3) |
- KeyFunc * - KeyFuncListRef (後移入 XO ) (DreamBBS v3) |
MapleBBS 3.02 | 此區域的回呼函式清單 |
mode |
int |
MapleBBS 3.02 | 此區域對應的使用者狀態 |
feeter |
char * |
MapleBBS-itoc | 存放執行 XO_FOOT 命令時要畫出的 footer - DreamBBS 未引入此成員 (DreamBBS v3.0 執行 XO_FOOT 命令時會呼叫回呼函式清單中的對應函式) |
又名 struct OverView
。
Member 名稱 | 型別 | 出處 | 說明 |
---|---|---|---|
pos |
int |
MapleBBS 3.00 | 目前游標在列表中的絕對位置 |
top |
int |
MapleBBS 3.00 | 畫面中列表第一項在列表中的絕對位置 |
max |
int |
MapleBBS 3.00 | 列表項目數量 0 代表列表為空 |
key |
int |
MapleBBS 3.00 | 內部使用值 意義隨回呼函式而定 |
xyz |
- char * - void * (DreamBBS v3.0) |
MapleBBS 3.00 | 內部雜項資料 實際內容及意義隨回呼函式而定 |
nxt |
XO * |
MapleBBS 3.00 | 指向游標紀錄串列中的下一筆資料 游標資料紀錄用 |
cb |
KeyFuncListRef |
DreamBBS v3.0 | 回呼函式清單 原 XZ::cb
|
recsiz |
int |
DreamBBS v3.0 | 列表資料項目的資料位元組大小 0 代表未設定完成 |
dir |
- char [0] - char [FLEX_SIZE] (DreamBBS v2.0) |
MapleBBS 3.00 | 列表資料檔的系統路徑字串 |
Member 名稱 | 型別 | 出處 | 說明 |
---|---|---|---|
key - first (DreamBBS v3.0) |
- int - unsigned int (DreamBBS v2.1) |
MapleBBS 3.00 | 回呼函式對應按鍵的值 |
func - second (DreamBBS v3.0) |
- int (*)() (MapleBBS 3 / WindTop 3.02) - int (*)(XO *xo) (DreamBBS v0.96) - XoFunc (DreamBBS v3.0) |
MapleBBS 3.00 | 回呼函式 |
func
/second
為一 union 物件;在 MapleBBS 3 / WindTop 3.02 中原為 int (*)()
,實際使用時須依 key
/first
的值手動轉型。
DreamBBS v2.1 時將其改為匿名 union,以減少手動轉型錯誤的可能。
DreamBBS v3.0 時將此 union 分開定義為 XoFunc
。
DreamBBS v3.0 特別定義了 KeyFunc
相關型別以利支援使用 hash table 實作回呼函式清單。
名稱 | 等效 C 定義 | 等效 C++ 定義 | 說明 |
---|---|---|---|
KeyFunc |
含有上述成員的 struct
|
含有上述成員的 std::pair
|
KeyFuncList 的元素 |
KeyFuncList |
KeyFunc [] |
模板參數為上述成員型別的 std::unordered_map
|
含有多個 KeyFunc 的表 |
KeyFuncIter |
KeyFunc * |
KeyFuncList::iterator |
用以遍歷 KeyFuncList
|
KeyFuncListRef |
KeyFunc * |
自訂了建構式、operator =() 、與 operator ->() 的結構 |
用以參照整個 KeyFuncList
|
Member 名稱 | 型別 | 出處 |
key /first 指定方式 |
說明 |
---|---|---|---|---|
func |
int (*)(XO *xo) |
DreamBBS v2.1 | key |
普通 Xover 回呼函式 |
posf |
int (*)(XO *xo, int pos) |
DreamBBS v3.0 | key | XO_POSF |
帶 pos 參數的 Xover 回呼函式 |
dlfunc |
- const char * (使用動態載入) - int (*)(XO *xo) (不使用動態載入) |
DreamBBS v2.1 | key | XO_DL |
需動態載入的普通 Xover 回呼函式 |
dlposf |
- const char * (使用動態載入) - int (*)(XO *xo, int pos) (不使用動態載入) |
DreamBBS v3.0 | key | XO_POSF | XO_DL |
需動態載入的帶 pos 參數的 Xover 回呼函式 |
Macro | 值 | 功能 | 註解 |
---|---|---|---|
XO_MODE |
0x10000000 |
表示畫面重繪、資料載入、離開列表等操作 | DreamBBS v3.0 中已移除 |
XO_NONE |
- 0x10000000 - 0x00004000 (DreamBBS v3) |
- 什麼都不作 - 最小的被當作命令的 Xover key value |
|
XR_<redo> |
(多個) | 預先定義的畫面重繪及資料載入的組合動作 | DreamBBS v3.0 新增 |
XR_PART_<redo> |
(多個) | 畫面重繪及資料載入中的某部分 | DreamBBS v3.0 新增 |
XO_MOVE |
- 0x20000000 - 0x00100000 (DreamBBS v3) |
- 表示游標移動 - 游標移動的 bias (DreamBBS v3) |
|
XO_CUR |
(XO_REL + XO_CUR_BIAS) |
重繪游標所在行,並移動游標到指定的相對位置 | DreamBBS v3.0 新增 |
XO_CUR_BIAS |
0x2000 |
XO_CUR 內部處理相對位置時的 bias |
DreamBBS v3.0 新增 |
XO_CUR_MIN |
(XO_REL + 0 - XO_CUR) |
XO_CUR 可指定的相對位置的最小值 |
DreamBBS v3.0 新增 |
XO_CUR_MAX |
(XO_REL + KEY_NONE - XO_CUR) |
XO_CUR 可指定的相對位置的最大值 |
DreamBBS v3.0 新增 |
XO_RSIZ |
256 |
列表資料的資料結構大小限制 | DreamBBS v3.0 起不使用 |
XO_TALL |
(b_lines - 3) |
翻頁所跳行數 | 非常數 |
XO_MOVE_MAX |
(XO_POS_MASK - XO_MOVE) |
可加在 XO_MOVE 上的最大值 |
DreamBBS v3.0 新增 |
XO_MOVE_MIN |
(XO_NONE + 1 - XO_MOVE) |
可加在 XO_MOVE 上的最小值 |
DreamBBS v3.0 新增 |
XO_TAIL |
- (XO_MOVE - 999) - (XO_WRAP - 1) (DreamBBS v3) |
- 用來將游標 XO::pos 初始化到列表尾項 - 用在 XO_MOVE + XO_TAIL 中,將游標移到列表尾項 (DreamBBS v3.0 增加支援) |
注意是 TAIL ,與 XO_TALL 不同 |
XO_ZONE |
- 0x40000000 - (XZ_ZONE + XO_MOVE) (DreamBBS v3) |
切換到某個列表 | |
XZ_ZONE |
- 0x40000000
|
將操作解釋為列表相關操作 | DreamBBS v3.0 新增 |
XZ_BACK |
- 0x100 - 0x04000000 (DreamBBS v3) |
- (未使用) - 加在 XZ_ZONE 上,表示回到上次進入的 zone (DreamBBS v3) |
|
XZ_<zone> |
(XO_ZONE + <zone>) |
切換到某個 zone | |
XZ_INDEX_<zone> |
<zone> |
Zone 的 index 值 | DreamBBS v3.0 新增 |
XZ_INDEX_MAX |
XZ_INDEX_MYFAVORITE |
最後一個 zone 的 index 值 | DreamBBS v3.0 新增 |
XZ_COUNT |
(XZ_INDEX_MAX + 1) |
Xover zone 的數量 | DreamBBS v3.0 新增 |
XO_SKIN |
((XZ_ZONE | XZ_SKIN) + XO_MOVE) |
套用某個使用者介面 skin (未實作) | DreamBBS v3.0 新增 |
XZ_SKIN |
0x10000000 |
將操作解讀為使用者介面 skin 切換 (未實作) | DreamBBS v3.0 新增 |
i_read
與 Xover 列表系統的 callback 函式都可以透過回傳值,呼叫下一個 callback,本文稱之為「連鎖」。
例如 'i'
對應的 callback 回傳 'j'
,'j'
對應的 callback 回傳 'k'
,'k'
對應的 callback 回傳 XO_BODY
,XO_BODY
對應的 callback 回傳 XO_FOOT
,XO_FOOT
對應的 callback 回傳 XO_NONE
,稱為一個連鎖,可以記為 'i' -> 'j' -> 'k' -> XO_BODY -> XO_FOOT -> XO_NONE
。
連鎖的結尾 callback 可以回傳游標移動命令、XO_NONE
命令、或沒有對應 callback 的命令。
透過回傳按鍵值而呼叫下一個 callback 的連鎖,稱為「命令連鎖」。
例如連鎖 'i' -> 'j' -> 'k' -> XO_BODY -> XO_FOOT -> XO_NONE
中就包含了命令連鎖 'i' -> 'j' -> 'k'
。
從 DreamBBS v3.0 開始,可以將畫面重繪/重新載入或列表操作,與按鍵輸入或游標移動的操作組合表示,因此需要特別的規則來處理帶有這些組合的命令連鎖。
其中畫面重繪/重新載入 (XR_*
) 等操作,本文稱之為「redo-simple 操作」,與其組合的操作則稱為「redo 組合操作」;
列表操作 (XZ_ZONE + XZ_*
) 等操作,本文稱之為「zone-simple 操作」,與其組合的操作則稱為「zone 組合操作」。
「Redo 組合操作」與「zone 組合操作」,本文將其合稱為「組合操作」。
不是組合操作的操作,本文稱為「簡單操作」,因此,前文中的「redo-simple 操作」與「zone-simple 操作」都屬於「簡單操作」。
代表單純的按鍵輸入或游標移動的簡單操作,本文稱之為「pure 操作」。
之所以稱為「pure 操作」,是因為當按鍵連鎖中的各個 callback 的回傳值只有單純的按鍵輸入與游標移動操作時,回傳值之間不會互相影響。
Null 操作是 pure 操作的特例,是導致連鎖終止的單純操作,包含游標移動操作、XO_NONE
操作、以及沒有對應 callback 的值所代表的操作。
此外,DreamBBS v3 的切換列表操作 (XZ_<zone>
),是用游標移動達成的,本文將其歸類為 pure 操作中的 null 操作,而非 zone 組合操作;
MapleBBS 3 原本的 Xover 列表系統的切換列表操作,不是使用游標移動達到的,但本文也將其看作游標操作。
組合操作中的 redo-simple 部分及 zone-simple 部分,會累積起來,在命令連鎖結束時再執行。
其中,如果同時累積有 redo-simple 及 zone-simple 部分,則會先執行 zone-simple 部分,再執行 redo-simple 部分。
先後執行兩個操作的 pure 部分後,執行 redo-simple 操作。
先後執行兩個操作的 pure 部分後,執行 zone-simple 操作。
先後執行兩個操作的 pure 部分後,將與兩者組合的 redo-simple 操作一齊執行。
例如有 2 個 callback 函式:
-
'i'
對應的func_info()
會增加某項目的查詢次數,並且在列表後說明處畫東西,執行完後需要用XR_KNEE
重繪 -
Meta('i')
對應的func_info_full()
會在列表內容處畫東西,需要用XR_BODY
重繪,但需要呼叫func_info()
來畫出剩下的部分
而使用者按 i 執行 func_info()
後,要從畫面中列表後說明處向下重繪;按 Esc i 間接執行 func_info()
後,則要從畫面中列表內容處向下重繪。
可以這樣寫:
- 在
func_info()
中增加查詢次數,並return XR_KNEE + XO_NONE
(或return XO_KNEE
) -
func_info_full()
則有不同寫法:- 沒有連鎖規則時,要直接呼叫
func_info(xo)
再return XO_BODY
- DreamBBS v3 不使用 redo-redo 連鎖機制時,可以使用
return XR_BODY | func_info(xo)
,但要確定func_info()
不會回傳按鍵輸入值,否則需要連鎖規則才能處理
- DreamBBS v3 不使用 redo-redo 連鎖機制時,可以使用
- 有連鎖規則的話,則可以直接
return XR_BODY + 'i'
,這會間接呼叫func_info()
,並要求至少從畫面中列表內容處向下重繪
- 沒有連鎖規則時,要直接呼叫
return XR_BODY | func_info(xo)
寫法的優缺點:
- 適合用在按鍵的對應功能的函式已知的情況
- 限制是
func_info(xo)
不能回傳XZ_*
命令
return XR_BODY + 'i'
寫法的優缺點:
- 適合用在按鍵的對應功能的函式未知的情況,尤其是在按鍵本身的值未知時
- 可以正確處理按鍵的對應功能的函式回傳
XZ_*
命令的狀況 - 限制是按鍵本身不能是
XZ_*
命令
先後執行兩個操作的 pure 部分後,將與兩者組合的 zone-simple 操作一齊執行。
先後執行兩個操作的 pure 部分後,先執行 zone-simple 操作,再執行 redo-simple 操作。
在某些 zone-simple 操作後可以省略部分或全部的 redo-simple 操作。
- Home
- Install — 安裝說明
- Version
- Project Documentations — 專案說明文件
- Coding Style & Conventions — 程式碼撰寫風格與慣例
- Indentation
- Xover List System — Xover 列表系統
- Menu Systems — 選單系統
- Screen Coordinate System — 畫面座標系統
- BoardReadingHistory — BRH 看板閱讀紀錄系統
- Visio I/O Library — Visio 輸出入函式庫
- Permission System — 權限系統
- TANet BBS Family Genealogy Chart — TANet BBS 家族譜系圖
- 與 MapleBBS 3 的按鍵差異
- [WIP] 與 MapleBBS 3 的差異
- References — 參考資料
- Changelog & TODO
- Issue & TODO list — 問題與代辦事項清單
- MapleBBS-itoc Porting Project — MapleBBS-itoc 移植計畫
- BBS-Lua Changelog
- BBS-Ruby Changelog (external link — 外部鏈結)
- 新式密碼加密 (DLBBS v2.0+)
- [WIP] DreamBBS v3 發佈說明 Release Note
- Release Notes of Version 2.0.0 Artoria
- Version 2.0.0 Artoria 發行說明
- Release Notes of Version 1.0.0 Rimuru
- Version 1.0.0 Rimuru 發行說明
- NoCeM-innbbsd 原始說明文件
- WindTop 3.02 原始說明文件