ども。 新しいスレッドにします。 勢いにまかせて、Vz用の画像ファイル作成マクロをリクエストします。 使いやすいかどうかは別にして、私の考えている仕様は以下の通りです。 出力形式はxbm形式。 入力は、いにしえのTXT2BMPにならって、と言うわけでもありませんが、 半角1文字を1ドットに対応させたいです。 使い方としては、編集画面を行ブロック状態でこのマクロを起動すると、 ブロック範囲のキャラクタ状況を読み取って、画像ファイル形式で出力 する。いわば、banner.defのような感じでしょうか。 キャラクタとドットの対応付けとしては、半角空白が白、何かの文字が 黒を表す、としましょう。任意の文字、とすると難しいかもしれないの で、半角ピリオドとか半角#あたりの固定文字の方がいいかな。 でも、固定文字とすると、イレギュラーな文字があった場合の処理が必 要になって、かえって難しいかな。 黒と白の反転機能もあると嬉しいけど、必須ではないですね。 画像のサイズに関しては、ブロック範囲から読み取るのが基本。 画像名については、決め打ち(固定値)でもいいし、入力窓が開いて問 い合わせてくるのでもいいです。 あと、他に何か関係のありそうなものってなにかありましたっけ? とにかく、画像関係については、参考になりそうなものはbanner.defと TXT2BMP.EXEぐらいしか思いつかないので、他にもっといい方法があった としてもわからないのです。 ということで、ナイスな(死語?)マクロを作っていただけると幸いです。
なーんだ, てっきりフォント情報を読み取って XBM に変換するマクロかと 思ったら,いわゆる「お絵かき」するのですね。ちょっと易しすぎませんか? いや,易しいって言うと語弊がありますが,とんでもなく手が付けられないよ うなものを想像していたもので…。(^^; 誤解を招くといけないので,わたしの印象を一応言っておきます。 この仕様ならば,リクエストするというよりも,みんなで「競作」するのが 楽しいと思います。例えば,ビットのオン・オフをいかに高速に取得するかと か,取得した情報をいかに高速にCの書式で出力するか,みたいな。 あと,画像のサイズなのですが,8ビット記録だということは,縦横のサイ ズが8の倍数のドット数に限定すると作りやすそうですが,そういう制限はお 好みではないんでしょうね。 それから「お絵かき」の仕様に属するのですが,ドットは正方形か円でない と書いた絵と出来上がった画像の縦横比が変わってしまいますが,このへんは どうなのでしょう。
> 思ったら,いわゆる「お絵かき」するのですね。そです。何せ相手は画像ですから。 ま、発想が貧困なだけかもしれませんが。 例に挙げた他に、何かお絵描き系のマクロってありましたっけ。 Emmettさんあたりがfont関係のマクロを作っていたようも気がするけど、もう すっかり忘れています。> この仕様ならば,リクエストするというよりも,みんなで「競作」するのが> 楽しいと思います。例えば,ビットのオン・オフをいかに高速に取得するかと> か,取得した情報をいかに高速にCの書式で出力するか,みたいな。いや、楽しいというか、少し勉強すれば自分でも作れそうだな、と思ったもので しばらくネタを寝かせていたのですよ。でも、私の力では、いろいろとわからな い点が多くて、誰かそのうち創作意欲に燃えた人が現れないかな、と待っていた のですよ。 今回、例に挙げた仕様も、自分で作るとすればこんな感じにするかな、というこ とで出したまでで、他の人に作ってもらえれば、もっと無理難題を吹っかけたい ところ。ただ、肝心の無理難題を思い付きもしない、というのが何ともはや。> あと,画像のサイズなのですが,8ビット記録だということは,縦横のサイ> ズが8の倍数のドット数に限定すると作りやすそうですが,そういう制限はお> 好みではないんでしょうね。あれ、横は8ビットですが、縦も8ビットでしたっけ。 正確に把握していませんでした。 確かに制限は少ない方がいいです。 でも、8の倍数に限定したとして、条件に合わない入力ならチェックしてエラー を出すことになるかと思うのですが、それなら自動的に範囲を拡張することもそ れほど難しくはなさそう。もちろん、入力を一切チェックしないである条件であ ると仮定して動くというのもありだとは思いますが。> それから「お絵かき」の仕様に属するのですが,ドットは正方形か円でない> と書いた絵と出来上がった画像の縦横比が変わってしまいますが,このへんは> どうなのでしょう。私はこれ、純粋に1キャラを1ドットに変換、ということで割り切ってしまって よいと思っています。あとは、TXT2BMPには、縦横比を変換、というオプションが あったかと思いますが、せいぜいその程度でよいかと。 例えば、LXで使うことを仮定して、いろいろな縦横サイズが選べたかと思います ので、そういうのにいちいち対応していたらきりがないのではないでしょうか。 仮に、アスペクト比を調整するとして、どうするのがよいのか思い付きもしない、 というのもありますが。
> あれ、横は8ビットですが、縦も8ビットでしたっけ。あ,いえ,余計なニュアンスをつけてすみません。 左上から描画するということで,横幅は8ビットの倍数だけれども,高さは 特に規則はなかったですね。> 例えば、LXで使うことを仮定して、いろいろな縦横サイズが選べたかと思います> ので、そういうのにいちいち対応していたらきりがないのではないでしょうか。御意。 半角ならむしろプログラム的には楽ですね。全角だと1文字ずつカーソルを 移動して 0/1 の判断をするのが易しそうですが, 半角ならラインバッファか らメモリ上だけで取得できそうなので速度的に有利だと思います。メモリ上だ けでアレコレできるのなら,機械語でさらに速くなりそう。
> いや、楽しいというか、少し勉強すれば自分でも作れそうだな、と思ったもので> しばらくネタを寝かせていたのですよ。でも、私の力では、いろいろとわからな> い点が多くて、誰かそのうち創作意欲に燃えた人が現れないかな、と待っていたえ〜と、ちょうどいい機会というか、私のわからないことをいくつか教えて いただけますでしょうか。 まず、最初の仕様に示したように、ブロック範囲の情報を読み取ろうと思っ ています。行ブロックであるかどうかの判定方法はわかります。次に、ブロ ックされている行数を読み取る必要があると思うのですが、この方法がわか らない。先頭と末尾にカーソルを飛ばして、その論理行を取得する、という 形が単純そうですが、そうすると、65536をはさんだ時に誤動作しそうな気が します。何か他にいい方法があるのでしょうか。 まずはこんなところから。
別ファイルに切り出してしまうのが一番早いと思います。 例えば, mb=1, #k #R "nul" #m (s==4)?'y' ek[+, #i ek], …で,カーソルのある行は必ず EOF になるはずですから,行数は ln-1 です。 切り出すメリットは,一括置換ができること,いかようにも加工できること。 また,最終的にファイルにするわけですから範囲を再度指定する必要もないこ となど,色々ありますね。 一括置換できれば,全角で書いた絵をすべて半角にしてしまうことも可能で しょうから,変換処理が一本化できるのではないでしょうか。
なるほど、別ファイル化というのは考えてもみませんでした。 次は何を質問することになるかな。またぞろ例によって、配列関係だったりして。 ただ、年末年始はちょっと忙しいので、年明けになるかな。 何せ、30日は当番で日勤、元旦から2日にかけて宿直、という勤務なもので。 ただ、それまでには誰かが完成品をひょいとアップしてそうな気もしますが。
> ただ、年末年始はちょっと忙しいので、年明けになるかな。と書いておきながら、またすぐに質問してしまいます。 壁に突き当たったというわけでもないのですが、ちょいと教えてほしいこと がありまして。画像の横幅についてなのですが、どうやって取得するのがい いのかな、ということです。 案1:最初に1回、範囲を走査して幅を取得し、次にもう1度、 データ取得用に範囲を走査 案2:データの取得用に範囲を走査する時に横幅も同時に読み取る 問題となるのは、各行の長さが異なる時にどうするのか、という仕様の問題 とも絡むからです。こちらの方は、次のような感じでしょうか。 案A:一番大きい横幅にあわせる、短い行は空白で補完 案B:一番小さい横幅にあわせる、はみ出た部分は切り捨て 案C:最初の行の幅にあわせる、幅の異なる部分は空白補完または切り捨て 私としては案Aがよいのですが、そうなると案2とした時のデータのハンド リング方法が複雑になってしまうような気がしています。 ということで、他にいい案があるかもわかりませんので、お知恵をお貸しい ただけると幸いです。
仕様の問題が,そのまま使用可能な技術に直結するように思うので,ここは 一番重要なところですよね。 一番最初に考えた手法が,ブロック範囲をテキストスタックに送る前にテキ ストスタックの終端を取得しておいて,取得したスタックを直接読みに行って 画像情報だけを出力し,その後スタックの終端を取得前の位置に戻すというも のでした。これだと,どこも汚さず高速に処理できるはずです。ただ,全角/ 半角両方に対応しようとすると,少し難しいように思いました。これは当然,> 案2:データの取得用に範囲を走査する時に横幅も同時に読み取る…という仕様になりますね。最後に記憶されたスタックの大きさは分かりま すが,行の長さはすべて舐めて改行を探さなければなりません。面倒。(^^;> 案1:最初に1回、範囲を走査して幅を取得し、次にもう1度、> データ取得用に範囲を走査最大幅を取得するのは大して時間はかからないと思いますが,動作としては やや無駄がありますね。でも幅は最も重要な情報ですから,多少の無駄があっ てもいいのではないでしょうか。 わたしが思うに,黒(ビットがオン)になるところは当然何かキャラクタを 置きますが,ある位置から白(オフ)が行末まで連続するようなら,いちいち 空白を入れる必要はないのではないでしょうか。手を抜くのは人情ですから。 案D:一番大きい横幅を含む8の倍数を画像幅とし,足りない部分は空白補完 …で決まりではないでしょうか。空白補完と言っても,実際に空白を出力す るのではなく,空白として処理=数値を加算しない,ということで。 …となると…,おっ,仕様が固まってきた。 削除バッファを使おうかな。(^^)
> 案D:一番大きい横幅を含む8の倍数を画像幅とし,足りない部分は空白補完私の言葉が足りなかったのが悪いのですが、これって多分、私の考えたA案 とほとんど同じだと思います。 ・・・で、いいのかな。不安が出てきた。 「含む」という言葉の解釈が異なるかもしれない。 ここは「越える」と言い換えてもいいのでしょうか。 それとも「越えない」と言い換えるべきなのでしょうか。> …で決まりではないでしょうか。空白補完と言っても,実際に空白を出力す> るのではなく,空白として処理=数値を加算しない,ということで。ここは同意見です。 データ上において、空白ビットで補完する、ということですよね。
> これって多分、私の考えたA案とほとんど同じだと思います。8ドット単位という前提があるなら同じですね。って,そんなこと最初から 決まってますがね。(^^ゞ …と言うか, まだわたしは XBM の形式をきちんと理解しているとは言えな いようなので,ちょっと確認が必要かもしれません。幅を8の倍数でない数に して Irfanview で表示させてみたのですが, 4の倍数と7など奇数で振る舞 いが違いますね。Irfanview の解釈の可能性もあるのでよく解りません。 いずれにしても,行の長さは8の倍数固定ということで。> ここは「越える」と言い換えてもいいのでしょうか。いや,わたしも迷って「含む」としたのですが,「最長の行以上で最も小さ な8の倍数」としなければ意味が通じなかったですね。こういう場合って何か 言い方が有るのでしょうか。わたし,数IIBが赤点で。(^^;
ども、あけましておめでとうございます。 珍しく、居間のこたつからネットサーフィンしています。> いや,わたしも迷って「含む」としたのですが,「最長の行以上で最も小さ> な8の倍数」としなければ意味が通じなかったですね。こういう場合って何か> 言い方が有るのでしょうか。わたし,数IIBが赤点で。(^^;私も数学は赤点の1個上ぐらいだったので大差ありませんが。 でも、なんとなく日本語の問題のような気もします。 複数の言葉で言い換えて、曖昧さの一番少ない表現を使うのがよろしいのではない かと。とりあえず、「最長の行以上で最も小さな8の倍数」というのが一番いいと 思います。
としきさん,みなさん,あけましておめでとうございます。 (管理人の挨拶がこんなに遅れるなんて,なんたる掲示板でしょうか。(^^;) 夜勤明けのとしきさんは,そろそろ起き出してくる頃でしょうか。 昨日は普段呑まない酒を少し見栄張って手酌なんかしちゃったもので,一日 ダウンしていました。(-_*; ちまちまと,部品を作りはじめています。 (別ファイルに切り出す部品) (mb)??. mb=1, #k #R "nul" #m (s==4)?'y' ek[+, #i ek], (すべて半角に統一する部品) ; ---- 全→半 mb+, RX[+, ZH[-, #56 " " #m " " #m "ay" #56 "[、-瑤]" #m "@" #m "ay" ZH], RX], mb-, (画像サイズを測定する部品) ; ---- サイズ測定(カーソル位置がEOF) h=ln-1, w-, ;<h>高さ <w>幅 :a #s (r)?{ w=(w/8+(w%8>0))*8, >l } (w<lx)?w=lx, #< >a これらの部品を通過して,メインのループに至ります。 :l ; ---- loop ---- ;アレコレ >l さて,このループの内側でどういう風にやるかが楽しいですね。 いや全→半部品なしでもできるのですが,なにしろ楽なもので。(^_^;
二重ループでドツボにはまってしまって,ちょっと予想以上に難儀をしまし たが,泥縄くっつけてなんとかしました。ただ,ちょっと変になることがあっ て,見掛けは変数の初期化を怠ったときのような動作になることがたまにあり ます。原因不明。サイレントがらみかもしれません。ループの中の &s を取っ てしまうと正常になったりしていました。 このマクロで出力してみた画像が以下のものです。 → http://homepage3.nifty.com/mezala/vz/me.xbm = TXT2XBM = by H_ear #if 0 削除バッファを利用して行データを変換 次のような二値パターンで絵を描く(空白以外はビットが立つ) * * ** * 1 1 11 111 1 # # # # ## # ## # ## ### #### * * * * * * ** ******* *** * *** * * * *** * ** * ** ** * ** * * * * *** * * * ** * **** * *** * *** *** XBMに変換したい絵文字を行ブロックして実行 全半混在も可能(行内混在は非推奨(^^;) #endif * mad for vz! 1 ^\ "" ?. (mb)??. &s mb=1, #k mx+, #R "nul" #m (s==4)?'y' mx-, ek[+, #i ek], mi[-, ; ---- 全→半 mb+, RX[+, ZH[-, #56 " " #m " " #m "ay" #56 "[、-瑤]" #m "@" #m "ay" ZH], RX], mb-, ; ---- サイズ測定(カーソル位置がEOF) h=ln-1, w-, ;<h>高さ <w>幅 :a #s (r)?{ w=(w/8+(w%8>0))*8, >l } (lh+lx)??" " ;最低ひとつ空白が必要(ダサい(^^;) (w<lx)?w=lx, ;(「文字列」とするために) #< >a :l ; ---- main loop ---- &d &s q=p=mg..-3, ;削除バッファ終端<q>静/<p>動 #l ((mg..-3).-2=0, ;削除バッファに取得し終端をヌルに (j=w/8){ ;<j>内部ループ回数 i=r-, ;<i>カウンタ :m (p.i)??>n ;終端で確定 (p.i!=$20)?r+=1<<i, ;空白でなければビット加算 i++, (i<8)?>m :n pu.(j-mg..4)=r, ;mg..4:ループカウンタ p+=i, ;(p.i)?p+=8, ?p+=i, } i-, (j){ &?("0x%02x,",pu.i) i++, } ;1行分を出力 mg..-3=q, #d ;削除バッファの終端を元に戻す (ct)?>l ;EOFで終了 ; ---- et al. ---- #d #n "}" #^ #< #n "static char _bits[] = {" #< #n &?("#define _height %d",h) #< #n &?("#define _width %d",w) :z ; ---- exit ---- mi], #^ &d #< . * [Variables] w width h height i counter j loop counter p ptr(passing) q ptr(quiet) [Buffers] pu tmpbuf [History] 2006/01/03 0.10 初版 [Notes] 多重ループは嫌いじゃ(^^;
わ、やっぱり速いですねぇ。 今日はもうこんな時間なんで試すこともできませんが、近日中にはいろいろと 遊んでみたいと思います。
やっと使ってみる余裕ができました。 いやぁ、見事です。私の作っているものだと、こうはうまくいきそうにない です。完成するかどうかが疑問ですが、たとえ完成しなくても、私のバージ ョンは後日公開します。 私の作りかけのものと比較してみましたが、横幅の取得や8の倍数化につい ては大幅に異なっていました。私のものの方がローテクというか、自分で理 解している技術のみで作っているので、大いに笑ってしまうようなものにな っていると思われます。期待していてください。v(^_^) 画像のビット取得の部分も、かなり異なったアプローチをしています。 そもそも、その方法でうまく行くかどうかがわからないというか、現在、そ の部分で止まっています。ただ、一つ気がついたことがあります。 このツリーのルート、#569で提示した仕様の中で明確に書かなかったのが悪 いのですが、このなかで> 半角1文字を1ドットに対応させたいです。と書きました。これは、私の中では、全角文字は2ドットに対応させたい、 という意識があったのです。多分、一番最初の全角半角変換の部分をいじれ ばいいことだと思うのですが、どっちの方がいいのかな。とりあえず、私が 現在作成中のものでは、全角は2ドットという仕様で作っています。
> たとえ完成しなくても、私のバージョンは後日公開します。ぜひともお願いしますね。自分と異なる発想というのは,勉強になることが とても多いので。> 横幅の取得や8の倍数化については大幅に異なっていました。横幅の取得って,そんなに色々やりかたがあるのかなぁ。8の倍数化につい ては,今ごろようやく気付いたのですが,横幅の取得と同時にやらなくてもい いんですよね。ちょっと無駄な事をやってたように思います。そういうことを おっしゃってるのかな。> 画像のビット取得の部分も、かなり異なったアプローチをしています。これは,それこそ無数に手法があるのではないかと思いますし,このマクロ の核となるところですから,なかなか興味のあるところです。一番簡単なのは カーソルによる走査かと思いますので,8バイトごとに出力してしまうとか, まとめて出力するとか色々やり方はあるでしょうね。> 私の中では、全角文字は2ドットに対応させたい、という意識があったのです。なるほど。 でも,漢字の2バイト目が半角空白と同じ 20h となることはな いので,メモリ上での走査でも大して変更はないと思いますね。問題があると すれば,全角空白を2ドットの白背景とすべきところですが,これは最初に置 換してしまえばすむことですから,全→半変換と対になるカスタマイズ項目と する事で対処できると思います。仕様に影響しないインターフェースの部分で 好きな方を選択できるというわけですね。
なんとかできました。 1バイト文字だけで描いた絵をいくつか試してみましたが、めざらさんの作 られたマクロといずれも結果は一致しているので、それほど大ハズレではな いと思います。> 横幅の取得って,そんなに色々やりかたがあるのかなぁ。8の倍数化につい> ては,今ごろようやく気付いたのですが,横幅の取得と同時にやらなくてもい横幅って、Vzの編集画面をキャンバスに使うとすると、最大値はラインバ ッファの最大値ではなくweの最大値で決定されてしまうと考えました。なら ば・・・、というようなロジックになっています。 8の倍数化は、横幅の取得の直後に行っています。 最初は私も横幅の値から演算で求めようとしたのですが、もう頭が固くなっ ているんですかね、1分とたたずにめんどくさくなってしまい、力技に走っ てしまいました。でも、いくらなんでもちょっと、という気がしていますの で、そのうちに演算式一発の形に変更したいと思います。> これは,それこそ無数に手法があるのではないかと思いますし,このマクロ> の核となるところですから,なかなか興味のあるところです。一番簡単なのは> カーソルによる走査かと思いますので,8バイトごとに出力してしまうとか,> まとめて出力するとか色々やり方はあるでしょうね。結局、最初に思いついた方法は没にしました。 どんな方法かというと、メインのループは(i){....}の形式にして、i桁目の ビットが0/1を取得するローカルマクロをコールするという形にしようと していました。ただ、ローカルマクロがとんでもないロジックになっていま した。どんなものかというと、コールされるたびにカーソルを行頭に移動さ せ、それからi回 #d を行ってカーソルを指定の桁に移動させて情報を取得す るというもの。例えば、横幅250の絵を画いた場合の事を考えてみればわ かりますが、よくこんな非効率なアルゴリズムを思いつけたものだと、我な がら感心してしまいます。 ということで、できたのが以下のマクロです。 タブコードが入っていた場合は、編集画面の見栄えと結果が一致しないので すが、これはまぁ仕様という事で。 = XBM.DEF 変数一覧 w: width h: height a: temporary x: width counter y: height counter * M 1 ^\ "XBM.DEF" ?. (mb!=1)?. we[255, #k #N "nul.nul" #m ek[-, #i ek], w=0, h=0, ; ---- サイズ測定 :a h++, #> (w<lx)?w=lx, #d (r)??>a h--, :b (w%8!=0)?{w++, >b} ;8の倍数化 #^ #< #N "nul" #m #W ; ---- main loop x=1, y=1, a=0, :m &10 (ck==1)?{x++, &10} (cd!=13)?{#d} (x<w)?{x++, >m} (x==w)?{#> #d y++, x=1, #W #m #W} (y<=h)?{a=0, >m} ; ---- 後処理 we],#C 'y' #d #n "}" #^ #< #n "static char _bits[] = {" #< #n &?("#define _height %d",h) #< #n &?("#define _width %d",w) 10: (cd!=' ' && cd!=' ' && cd!=13)?{a=a|(1<<((x-1)%8)),} (x%8==0)?{#W &?("0x%02x,",a) a=0, #W} . * いまだにポインタがよくわかっていないので、ポインタは一切使っていない コードになっています。 あと、一番最後、XBMのヘッダを書き込む部分は、もう面倒になってしまった ので、めざらさんのコードをそのまま借用しました。例えば、私が自分で書 くなら、多分 #n は使わないでしょう。
> 横幅って、Vzの編集画面をキャンバスに使うとすると、最大値はラインバ> ッファの最大値ではなくweの最大値で決定されてしまうと考えました。なら> ば・・・、というようなロジックになっています。現実的な仕様としては,そういうことになりそうですね。折り返された表示 行で絵をイメージできる人は,まず居ませんから…。したがって,わたしのは we の値すらチェックせずに lx の最大値をそのまま画像幅に反映しています。 厳密にやれば lx+lh*we としなければならないところですが,明らかに非現 実的なので手を抜きました。> 最初は私も横幅の値から演算で求めようとしたのですが、> 力技に走ってしまいました。確かにゴリゴリですね。(笑) でも「演算式一発の形」でなくとも,例えば… (w%8!=0)?w=(w/8+1)*8, とか, (w%8!=0)?w+=8-w%8, …くらいでも十分なのではないでしょうか。 後者なら,評価を含めても w=(w/8+(w%8>0))*8, とバイト数は変わらないで すね。(w%8)?w+=8-w%8, にすればさらに短いじゃないですか。なーんだ。> した。どんなものかというと、コールされるたびにカーソルを行頭に移動さ> せ、それからi回 #d を行ってカーソルを指定の桁に移動させて情報を取得す#d だと全角半角が混在していると使えなくなってしまうので,&x(i)を使う 場面でしょうか。何れにしても速度面で問題が出るでしょうけれど。> タブコードが入っていた場合は、編集画面の見栄えと結果が一致しないので> すが、これはまぁ仕様という事で。そこまで考えてますか。(^_^; まぁ,タブ幅は環境によって異なりますし,あくまでも改行以外の1文字と いうことになるので,無視してよいのではないでしょうか。やりようがあると すれば別ファイルに切り出した段階でのタブ→空白変換ですが,もしかすると 別ファイルに貼り付けたときのタブ幅は保証されていませんから,意味がない かもしれませんね。 実行してみて驚いたのは,8ドット単位の切れ目に漢字がまたがっていても, きちんと出力することです。カーソルによる走査であれば,きっとそこに小骨 があるに違いないと予想して意地悪なデータを作って実行させてみたのですが, これはお見事と言うしかなかった。(^^; 1点だけ指摘させていただけば,新規ファイルを開けて #W で往復する場合 は,分割モードでの実行を抑止しなければなりません。(wt)?{&#Y(0)} で全画 面にしてから新規ファイルを開くか, #W ではなく &#T()によってテキストを 切り替えることが必要になります。> いまだにポインタがよくわかっていないので、ポインタは一切使っていない> コードになっています。使わずに済めば全く問題はないかと思います。特にカーソルによる走査とい うことで必然性もありませんよね。ただ,メモリ上でアレコレやろうとすると ポインタを使わざるをえませんから,速度を出すという目標があればポインタ を使うことになると思います。 あ,でもアレだ。わたしのはポインタを使っているなんてレベルじゃないで すよ。ポインタ演算子を使って順に相対アドレスのデータを取得しているだけ ですから。参照した値をアドレスとして使い,そのアドレスにあるデータを書 き換えたりするようなことをしていれば,結構高度なんでしょうけど。 ポインタもどきなんかよりも,a=a|(1<<((x-1)%8)), の方が余程難しいです。> 例えば、私が自分で書くなら、多分 #n は使わないでしょう。#m の場合は, 挿入モードとオートインデントモードを意識する必要がある ので,行を挿入するときは意識的に #n を使うことにしています。
> we の値すらチェックせずに lx の最大値をそのまま画像幅に反映しています。横幅というか論理行長が255を越える時の事を考えると、この手法の方が いいような気がしてきました。> …くらいでも十分なのではないでしょうか。かもしれません。 8の倍数化については、おいおい直したいと思います。> #d だと全角半角が混在していると使えなくなってしまうので,&x(i)を使うげ、&x()なんて、存在そのものを忘れていました。 これを聞いたことで、一旦没にしたロジックが甦るかもしれません。> まぁ,タブ幅は環境によって異なりますし,あくまでも改行以外の1文字と> いうことになるので,無視してよいのではないでしょうか。やりようがあると> すれば別ファイルに切り出した段階でのタブ→空白変換ですが,もしかすると> 別ファイルに貼り付けたときのタブ幅は保証されていませんから,意味がない> かもしれませんね。私ならそこまでするつもりはなくて。 タブコードを検知した時に、もし(Ta!=1)なら警告を表示するとか処理を中断 する、というくらいのところでまとめる事になるでしょう。> 1点だけ指摘させていただけば,新規ファイルを開けて #W で往復する場合> は,分割モードでの実行を抑止しなければなりません。(wt)?{&#Y(0)} で全画> 面にしてから新規ファイルを開くか, #W ではなく &#T()によってテキストを> 切り替えることが必要になります。この点は全く考えていませんでした。 全画面にしてから新規ファイルを開く方向で修正しようと思います。 いやぁ、ここでもやはり&#Y()っていうのを忘れていたので、もしこれを教え てもらえなかった場合には、wt!=0の間#Yを繰り返す、なんていうルーチンを 組み込んでいたことでしょう。> ポインタもどきなんかよりも,a=a|(1<<((x-1)%8)), の方が余程難しいです。括弧が多いから難しく感じているだけかもしれません。 要はビット演算なわけですから、そのあたりのことが得意な人にやらせれば、 もっとシンプルでわかりやすい方法が出てくると思います。> #m の場合は, 挿入モードとオートインデントモードを意識する必要がある> ので,行を挿入するときは意識的に #n を使うことにしています。なるほど、きちんと用途というか状況によって使い分けているわけですね。 この部分については、次回バージョンを公開することがあれば、そのときに は私のスタイルに書き直されていると思いますので、もし気がついた点があ ればまた指摘していただけると幸いです。
> 横幅というか論理行長が255を越える時の事を考えると、この手法の方が> いいような気がしてきました。…というところで,ごめんなさい。すっかり忘れていたのですが,わたしの 方は新規ファイルを開いたときに we255, を実行していませんでした。(^^;> げ、&x()なんて、存在そのものを忘れていました。> これを聞いたことで、一旦没にしたロジックが甦るかもしれません。1行が 255桁に納まって折り返しがないという前提であれば,その都度行頭 に移動する必然性はなくなりますので,ジャンプ距離は比較的短くなるのでは ないでしょうか。でも,速度を考えるとカーソルを移動させるのはかなり苦し いと思いますよ。#d の繰り返しに比べれば相当早いでしょうけど。> > ポインタもどきなんかよりも,a=a|(1<<((x-1)%8)), の方が余程難しいです。>> 括弧が多いから難しく感じているだけかもしれません。う〜ん,どうなんでしょう。わたしが「うわーっ」と思う根源は,x の初期 値が 1であるというところにあるのかもしれません。 0が初期値だったら lx がそのまま使えるのになぁ…という印象を引きずっているのかなぁ。 初期値が 0ならどうすると考えたときに,他の式の方が思い通りにならず, 簡単に思考が破綻したのです。なかなか悩ましいところですよね。
> 8の倍数化については、おいおい直したいと思います。ということで、これに関してはめざらさんに教えていただいた式を組み込ん でみました。それから、画面分割のチェックもめざらさんに教えてもらった ものをそのまま入れたし。 あと、全体的に自分の文体に書き直したものをアップします。 = XBM.DEF 変数一覧 w: width h: height a: temporary x: width counter y: height counter * M 1 ^\ "XBM.DEF" ?. (mb!=1)?. ;行ブロックモードでなければ終了 we[255, ;編集画面サイズを最大化 wt[, ;分割モード保存 (wt)?{&#Y(0)} ;全画面化 #k ;ブロック範囲をコピー #N "nul.nul" #m ;一時ファイルを開いて ek[-, #i ek], ;ペースト ; サイズ測定 w-, h-, :a #> (w<lx)?w=lx, #d ;行長の最大値を画像サイズとする (r)??{h++, >a} ;ファイル終端で終了 (w%8)?w+=8-w%8, ;8の倍数化 #^ #< ;カーソル位置を開始位置へ #N "nul" #m #W ;結果ファイルを開く ; main loop x1, y1, a0, :m &10 (ck==1)?{x++, &10} ;全角文字ならもう1ビットセット (cd!=13)?{#d} ;改行でなければカーソル移動 (x<w)?{x++, >m} ;横幅ループチェック (x==w)?{#> #d y++, x1, #W #m #W} ;横幅ループ終了処理 (y<=h)?{a0, >m} ;高さループチェック ; 後処理 #C 'y' ;一時ファイルクローズ "}" #m #^ &?("#define _width %d",w) #m &?("#define _height %d",h) #m "static char _bits[] = {" #m wt], we], ;設定戻し ; ローカルマクロ 10: (cd!=' ' && cd!=' ' && cd!=13)?{ ;現在の桁が空白でなければ a=a|(1<<((x-1)%8)), ;ビットに1をセット } (x%8==0)?{ ;8ビット分たまったら #W &?("0x%02x,",a) a=0, #W ;結果をファイルに出力 } * これ、そのまま起動すると、編集画面の切替が多発します。 ポケ3で使うと、いかにも一生懸命働いています、って感じになって、実行 時間もかなりかかるので、&sはつけたい気もします。でも、母艦で実行する と大したこともないので、とりあえずこのままという事で。 本当に速度が気になるのなら、めざらさんのマクロを使えばいいだけだし。 いや、ほんと、めざらさんのは速くていいですよ。 あと、おまけ。 banner.defって、DOS/Vバージョンは新しい版があって、縦2倍という か、フォントの1ドットを半角1文字に変換することもできるようです。で も、ポケ3やPC−98で動くバージョンにはそういう機能がなくて、縦が 圧縮された形でしか出力されません。つまり、半角1文字で縦2ドット分。 画面に表示する分にはこの方が美しくていいのですが、画像に変換すること を考えると、かなり使い勝手が悪いです。ということで、banner.defの出力 を単純に縦2倍にするマクロを作ってみました。本当ならbanner.defを改造 するのが筋なのかもしれませんが、そんな大がかりなことまでする必要はあ りませんから。 = X2.DEF * M 1 ^\ "X2.DEF" ?. (mb!=1)?. ;行ブロックモードでなければ終了 we[255, ;編集画面サイズを最大化 wt[, ;分割モード保存 ei[-, ;オートインデント抑止 (wt)?{&#Y(0)} ;全画面化 #k ;ブロック範囲をコピー #N "nul.nul" #m ;一時ファイルを開いて ek[-, #i ek], ;ペースト #^ #< ;カーソル位置を開始位置へ #N "nul" #m ;結果ファイルを開く #m #m #^ #W ;結果ファイル初期設定 :a (cd==' ')?{#W ' ' #x ' ' #e #W >b} (cd==',')?{#W ' ' #x '*' #e #W >b} (cd==';')?{#W '*' #x '*' #e #W >b} (cd==$27)?{#W '*' #x ' ' #e #W >b} (cd==13) ?{#W #x #m #m #e #W} :b #d (r)??>a #C 'y' #g #g ei], wt], we], ;設定戻し * 特に、ポケ3はもともとがワープロなので、機種依存文字のコードのところ に、いろいろと面白い記号が入っていたりします。そういうもののフォント 情報を取り出すと、ちょっとした絵を画くのに大いに役立ってくれそうです。
> 本当に速度が気になるのなら、めざらさんのマクロを使えばいいだけだし。いや,実は思ったほどでもなかったのです。 LX で実行すると速度差が歴然 とするはずと思ったのですが,サイレントにすると倍程度ですよ。意外でしょ。> ということで、banner.defの出力を単純に縦2倍にするマクロを作ってみました。あ,先を越された。(^_^; これ作らなくちゃなーって思ってたんですよね。でも折角だから,別のアプ ローチで作ってみます。
> これ作らなくちゃなーって思ってたんですよね。でも折角だから,別のアプ> ローチで作ってみます。私の方は、逆変換マクロというか、画像表示マクロを作ろうとしています。 えぇと、16進の読み込みは&hか。なんとかなりそうかな。
banner.def の出力を縦方向に伸長するマクロを作ってみました。 手法としては,ブロック内一括置換ですので,カーソル移動を伴う逐一変換 よりも早いと思います。…と言っても,このくらいのデータを扱うのではあま り変わりませんよね。 ----------^ BANANA.DEF ( date:2006-03-15 time:00:10 ) ------< cut here = banana.def v0.10 = by H_ear #if 0 banner出力されたAAの縦伸長 #endif * mad for vz! 1 ^\ "" ?. (mb!=1)?. ;行ブロック起動のみ &s RX[-, ZH[-, ek[-, a=id, #y mx+, #R "nul" #m (s)?'y' mx-, #i mb-, ek+, #56 ";" #m "\*" #m "ay" :l ; ---- main loop ---- #< #b #> #x (r)?>z ;safety #k ;blk push mb+, d-, &> mb-, #i ;blk pop mb+, d+, &> mb-, (ct)?>l :z ; ---- exit ---- #> mb+, #^ #< #y #C &#T(-a) ek-, #i ek], ZH], RX], ky-, &d #] . 0: ; ---- sub routine --- ; <-- d 0:upper, 1:lower ; --> void #56 "'" #m (d)?" " ?"\*" #m "y" #56 "," #m (d)?"\*" ?" " #m "y" * [Variables] a text-id(active) d dup. flag [Buffers] ps (11bytes) [History] 2006/03/15 0.10 初版 [Notes] カンマを忘れただけで,mb+&da+,がひとつの式として実行される。(笑) ----------$ BANANA.DEF ( lines:43 ) ------------------------< cut here 最初,おかしな動作をし,トレースしてみても分からなくて首をひねってい たのですが,20行目あたりの mb+, &d a+, の部分の mb+ の次のカンマを入れ 忘れていることに気付くまでかなり時間がかかりました。エラーにならないと ころが味噌で,mb+&da+ がひとつの式として解釈されていたわけです。&$daで はないのに不思議なものですね。 da って変数はない…いや,高橋版の DANNY さんの要望に応えた変数だ。あー,謎が解けた。
お、バナナ、いいですね。 やっと使ってみましたが、サクサクと変換してくれます。 ロジックとしては、1行づつ貼りつけて置換、ということでいいんですよね。 いえ、私、最近マクロの読解力が落ちているもので。> たのですが,20行目あたりの mb+, &d a+, の部分の mb+ の次のカンマを入れ> 忘れていることに気付くまでかなり時間がかかりました。エラーにならないとこの部分て、最終的にはなくなってしまったんですね。> はないのに不思議なものですね。 da って変数はない…いや,高橋版の DANNY> さんの要望に応えた変数だ。あー,謎が解けた。う、そんな変数あるんだ。 何をする変数だろう。
> ロジックとしては、1行づつ貼りつけて置換、ということでいいんですよね。最初に「;」は全部変換しておいて,あとは1行ずつ複写・「'」変換・貼り 付け・「,」変換しています。 極力カーソルを動かさないという観点で作りま した。カーソルを動かすのはブロック選択する時だけで,あとはブロック範囲 の再現やEk+による移動を活用しています。> この部分て、最終的にはなくなってしまったんですね。あ,作りかけの時点のコードだったのですが,貼り付けたバナナの中では, mb+, d+, &> mb-, というコードになっている部分です。 最終的に &d を取っ て,変数は a から d に変更したので全然別のものになってますね。(^^;> 何をする変数だろう。Da は表示スイッチで, 裏テキストになったときにステータスラインの属性 を変更するというものです。分割画面にしているときに,カーソルがどちらに あるか分かりやすいという利点があります。