2018/12/03
■ [変愚蛮怒/開発]変愚蛮怒用インターフェース拡張の可能性
これはRoguelike Advent Calendar 2018 3日目の記事です。
はじめに
今年もAdvent Calenderの季節がやってまいりました。 一昨年とか去年とかの進行に関する記事を見直しながらやはり溜息つくのが現状であります。
冒頭から私事の愚痴で恐縮なのですが、ここ数年は実の所リアルの事情が停滞でじり貧でした。逆に今年からは逆に良い方にも悪い方にも振れ幅が大きすぎて頭抱えることが多く、中々に続けるものを続けることが困難な日々が続いております。
どうにか他の人々のご厚意受けて立て直したいとまだ考えてはいるのでどうぞよろしく。
過去の関連記事
本ブログの記事を見直すに4年以上前には現状のWindowsAPIを拡張する形で、あれこれやろうとして(実際BGM機能は既存先人のものを改良できたりしましたが)頓挫しっぱなしになっていたりします。
また、マルチプラットホームに関する件については過去のAdvent Calenderの記事にもした
などがあります。
現状のインターフェースについて
しばしば某所で言われますし、それで当然とは思われますが、現状変愚が直接はZangbandから引き継いできた旧WindowsAPIによるCursesの延長上を意識したテキストインターフェースも昔から色々限界になっております。 何分往年の主力であったDirectXすら使わない、恐らくはWindows98時代基準のAPI採用です。
テキストだけで完結できるシステムというのが、恐らく今ですら全くメリットがないとは言えないとは思います。現に本家Angbandは現行でもGNU系Cursesやでのビルドも可能なようですし、ANSI準拠のCが走る環境をサポートする態勢も確保しているようです。
とは言え平成も終わろうとしているこのご時世にいい加減にテキストのままも虚しいですよね。その点も含み本家は64ドットタイルにも対応していますがZangbandなどを挟み、フォークとして遠く離れてしまった変愚はここから恩恵を受けることなく、独自路線で行くしかありません。
そのZangから受け取ったインターフェースの構造はどんなもんでしょうか。一重にz-form.hの構造体にまとまっています。
/*! * @brief term実装構造体 / An actual "term" structure */ typedef struct term term; struct term { vptr user; //!< Extra "user" info (used by application) vptr data; //!< Extra "data" info (used by implementation) bool user_flag; //!< Flag "user_flag" An extra "user" flag (used by application) bool data_flag; //!< Flag "data_flag" An extra "data" flag (used by implementation) bool active_flag; //!< Flag "active_flag" This "term" is "active" bool mapped_flag; //!< Flag "mapped_flag" This "term" is "mapped" bool total_erase; //!< Flag "total_erase" This "term" should be fully erased bool fixed_shape; //!< Flag "fixed_shape" This "term" is not allowed to resize bool icky_corner; //!< Flag "icky_corner" This "term" has an "icky" corner grid bool soft_cursor; //!< Flag "soft_cursor" This "term" uses a "software" cursor bool always_pict; //!< Flag "always_pict" Use the "Term_pict()" routine for all text bool higher_pict; //!< Flag "higher_pict" Use the "Term_pict()" routine for special text bool always_text; //!< Flag "always_text" Use the "Term_text()" routine for invisible text bool unused_flag; //!< Flag "unused_flag" Reserved for future use bool never_bored; //!< Flag "never_bored" Never call the "TERM_XTRA_BORED" action bool never_frosh; //!< Flag "never_frosh" Never call the "TERM_XTRA_FROSH" action byte attr_blank; //!< Value "attr_blank" Use this "attr" value for "blank" grids char char_blank; //!< Value "char_blank" Use this "char" value for "blank" grids char *key_queue; //!< Keypress Queue -- various data / Keypress Queue -- pending keys u16b key_head; u16b key_tail; u16b key_xtra; u16b key_size; TERM_LEN wid; //!< Window Width(max 255) TERM_LEN hgt; //!< Window Height(max 255) TERM_LEN y1; //!< Minimum modified row TERM_LEN y2; //!< Maximum modified row TERM_LEN *x1; //!< Minimum modified column(per row) TERM_LEN *x2; //!< Maximum modified column(per row) term_win *old; //!< Displayed screen image term_win *scr; //!< Requested screen image term_win *tmp; //!< Temporary screen image term_win *mem; //!< Memorized screen image void (*init_hook)(term *t); //!< Hook for init - ing the term void (*nuke_hook)(term *t); //!< Hook for nuke - ing the term errr (*user_hook)(int n); //!< ユーザ設定項目実装部 / Hook for user actions errr (*xtra_hook)(int n, int v); //!< 拡張機能実装部 / Hook for extra actions errr (*curs_hook)(TERM_LEN x, TERM_LEN y); //!< カーソル描画実装部 / Hook for placing the cursor errr (*bigcurs_hook)(TERM_LEN x, TERM_LEN y); //!< 大型タイル時カーソル描画実装部 / Hook for placing the cursor on bigtile mode errr (*wipe_hook)(TERM_LEN x, TERM_LEN y, int n); //!< 指定座標テキスト消去実装部 / Hook for drawing some blank spaces errr (*text_hook)(TERM_LEN x, TERM_LEN y, int n, TERM_COLOR a, cptr s); //!< テキスト描画実装部 / Hook for drawing a string of chars using an attr void (*resize_hook)(void); //!< 画面リサイズ実装部 errr (*pict_hook)(TERM_LEN x, TERM_LEN y, int n, TERM_COLOR *ap, const char *cp, const TERM_COLOR *tap, const char *tcp); //!< タイル描画実装部 / Hook for drawing a sequence of special attr / char pairs };
一応インターフェースの抽象化と言う奴はこれで一通りできてはいるんですね。ここの後半を占める関数ポインタでTerm(テキスト画面)の描画や消去を行い、前半で各インターフェースの性質に応じた処理の行い分けも実現は出来ている。
これを前の記事で述べたmain-???.c各自が実装することでWindows版、UNIX/Linuxのcurses版やx11版、古いMac版などが成り立っている次第です。
逆に言えば、この構造体の中身を新規にmain-???.cで埋め尽くせば、ひとまずは新しいインターフェースが作成できることになります。今回それの候補を考えるとどうなるかなのですが。
SDL(特に2.0系)
今やSteamでも鳴らして久しいToME先輩やAngband大先輩もどうも対応しているらしい選択肢です。 私自身馴染みがある、といいますかそもそもD'angbandだなんて、残骸になりかけている方でらしいインターフェースは作ったりしています。
こちらも大概変愚ソース改変から始まっていたり、かと思ったらフルスクラッチでやったり迷走している有様なのですが、じゃあここで作ったリソースを少しでも変愚の方に還元するのもありかなと。
いっそUnity使えや
もうSDLもレガシーにも程がある遺産な訳で今から手を付けるのならいっそ一足飛びに最近のスタンダードになりつつあるUnityに飛び込むのもありなのかもしれません。
個人的に、こちとら技術の進歩と流行りに取り残されて悶絶している最中ですが、将来の本業としてあるいはここでその一足飛びをかますのもありでしょう。さしあたってネイティブプラグインという選択肢はあるようですし。
最後に
どれでもいいからいい加減計画は立てるだけでなく軌道修正しながら実現しましょう。
カレンダー4日目はp31xxx氏のCAVES OF QUDの紹介となります。
■ [変愚蛮怒/開発]変愚蛮怒開発日誌part96…リファクタリング
ノーコメント。
- Mon Dec 3 23:57:22 2018 +0900: [Refactor] #37353 コメント整理 / Refactor comments.
- Mon Dec 3 23:52:59 2018 +0900: [Refactor] #37353 コメント整理 / Refactor comments.
- Mon Dec 3 23:47:46 2018 +0900: [Refactor] #37353 メッセージ整理。 / Refactor messages.
- Mon Dec 3 23:39:49 2018 +0900: [Refactor] #37353 コメント整理 / Refactor comments.
- Mon Dec 3 23:31:06 2018 +0900: [Refactor] #37353 mon_take_hit() のコメントアウト済落馬処理を削除。 / Delete comment outed process in mon_take_hit().
- Sun Dec 2 23:56:57 2018 +0900: [Refactor] #37353 コメント整理 / Refactor comments.