一括表示

− 野ざらし言 −

[2013] ラインバッファにpsを一時置きすると

めざら 2007/06/04(Mon) 22:49
<mezala@nifty.com> http://homepage3.nifty.com/mezala/
 内容自体は Konno さんちの掲示板の流れなのですが, あちらではほぼ終息
したようなので,備忘録代わりに書いておきます。

 あるテキストの一部を取得してメニュー表示するという場合,よく使われる
のがラインバッファです。 通常は,ps の指すバッファに一時的に #G で取り
込んだものをラインバッファに転送するという手順を採りますが,ラインバッ
ファにじかに取り込んでしまうという方法を思い付きました。

wm+230     ←こっち方向   ↓起点(wm+530)                          終端
┌────┬───────┬───┬───┬───┬───┬──┬─┐
│        │メニューヘッダ│Title │Item1 │Item2 │Item3 │…  │  │
└────┴───────┴───┴───┴───┴───┴──┴─┘
                        ↑一時的にバッファサイズを埋め込む

 まずラインバッファの先頭から 300バイト目を文字列バッファの起点としま
す。何故 300バイト目かというと,メニューヘッダはメニューアイテムの個数
分だけサイズを必要とするからで,まぁこのくらい取っておけばというところ
です。 Emmett さんの疑似メニューでもメニューヘッダ分に 300バイト取って
いるので,この業界の標準というところでしょうか。

 wm+230 がラインバッファ先頭ですから,wm+530 ということになりますね。
ここを ps が指すように指定します。ヒストリーバッファとして使うためには
直前にサイズ情報が必要です。p..-1 に bl-300 の値を埋め込みます。

 さて,あとは表示部分をお尻から #G で取り込んでゆき,そのアイテム数に
相当するサイズのヘッダを付けてやれば OK。 起点から下位アドレスに向かっ
てヘッダを付けて,その先頭アドレスを再設定してメニューとしてコールすれ
ばよいということになります。

 ヒストリーバッファならアイテム文字列は取り込み順に先に送られ,転送ア
ドレスをいちいち指定してやる必要もありません。これはちょっと楽ですね。
どうして今まで気付かなかったんだろう。

----------^ MENUTEST.DEF ( date:2007-06-04 time:11:47 ) ----< cut here
= menutest = by H_ear
#if 0
カーソル位置から次の空行まで取得して参照型メニュー表示
#endif
* mad for vz!
1 ^\ "" ?.
        #< #] mb-,                      ;ラインバッファを解放
        (ct<2)?.                        ;空行では実行させない
        &s n=ln, mp[=2,                 ;n: 起動位置の行番号
        w16,                            ;w: メニュー幅 0 で76固定 他最小値
        ps[="\n\n", #c ps],             ;デリミタ(連続改行)を探す
        (r || ln-n>250)?>z              ;アイテム数制限
        #< i=ln-n,                      ;i: アイテム数+タイトル
        q=wm+230,                       ;q: バッファ先頭
        p=q+300,                        ;p: 文字列領域 as ps
        p..-1=bl-300,                   ;p size (ヒストリバッファ)
        ps[=p,
 :a     #s                              ;前行末へ(実行位置は必ず行頭)
        (lh*we+lx>74)?{ #< &x(75) }     ;メニュー幅に制限
        #b #< #G                        ;ヒストリバッファにお尻から入れる
        (w)?{ &Sn(ps) (r>w)?w=r+1, }    ;メニュー幅自動拡張サンプル
        r=ps,:d&SF(r,9)(r)?(r.0=' ',>d) ;TABなどの制御文字を変換するサンプル
        (ln>n)?>a                       ;起動した行に達するまで繰り返し
        ps],
        p=q=p-(i*2+20),                 ;バッファ先頭を再設定
        &02 &Sm(p,r,20)                 ;擬似マクロをセット
        p+=20,
        (i*2){ p.0-, p++, }             ;タイトル+アイテム数のパラメタコード
        (w)??w76, q.16=w,               ;メニューの表示幅
        q.17=i-1,                       ;アイテム数(タイトル分を引く)
        q.19=-1,                        ;カーソル位置(参照型-1)
        mp-, &d
        WL[-, rr[=q, &* rr], WL],
 :z     mp], &d #] .
2:      (3+$)."$(1,a,0,ff,ff,0)!01(r)$(0,e1,c0,0,4C,1)" ; 0,0
*
[Variables]
        n       ln
        i       items+title
        p,q     buf ptr
        w       width
[Buffers]
        lbuf    ps,menu
[History]
2007/06/04 0.10 初版
[Notes]
ラインバッファの途中にpsのサイズ情報を埋め込むのがキモ
----------$ MENUTEST.DEF ( lines:47 ) ----------------------< cut here

 何かに応用できるといいなあ…。

[2135] 逆は使えないかな?

としき 2007/07/17(Tue) 23:37
[2013]へのコメント http://www.hinocatv.ne.jp/~toshiki/
ふと思いついた、妄想レベルの話で申し訳ないのですが。

逆に、psでなくてもなんでもよいのですが、ラインバッファに何かを一時置
きするするということはできないのでしょうか。
いや、ラインバッファだと、割と簡単に復元というか古い状態に戻すことが
できたような気がしまして。既にいろんなマクロで使われていることを私が
知らないだけかもしれませんが。
 

[2136] Re: 逆は使えないかな?

めざら 2007/07/18(Wed) 09:39
[2135]へのコメント http://homepage3.nifty.com/mezala/
 別に逆の話ではなくて、psもそうなのですが一時置きの話なんです。この例は、メニューをラインバッファに一時置きする時に、アイテム転送の際のひと手間を省くというもの。

 カーソルがテキストバッファから出ていない状態、つまり cp の指すアドレスがラインバッファでないのであれば、ラインバッファは比較的自由に使用できます。

 ただ、一時置きするものが小さなものの場合、あるいはサイズが限定されていれば、ラインバッファに続くまさしく緩衝領域を使うのが普通だと思います。

 また、一時置きには、テキストスタックも使えますね。あるいは EMS を使うということもできるかもしれません。しかしこれらの(サイズの大きな)領域は、その大きさゆえにデータセグメントとは別のセグメントとなってしまうため、データを転送することが非常に厄介です。それで次の選択肢として比較的大きなラインバッファが狙われるということになります。

 上顎部麻酔中(^^;

↑ このページの先頭