2019/06/05(水) [n年前の日記]
#1 [python][mz] pygameを使って実験中
Python 2.7.16 + pygame 1.9.6 を使って、MZ-700っぽい画面の表示ができないか実験中。
やってることは、VRAM相当の配列を作成して、0xD000 - 0xD3E7 にディスプレイコードが、0xD800 - 0xDBE7 にアトリビュートが記憶されているものと仮定。VRAM相当の配列の中身に従って、読み込んだフォント一覧画像から 8x8ドット単位で選んで描画、みたいな感じ。
MZ-700の表示関係の仕様は、以下が参考になる。ありがたや。
_Programming MZ-700: Display
普段から「pygameは遅い」と言っておきながら何故使うのか、と言われそうだけど。Python を使って画像の類をサクサクサ表示して実験したい、てな場面では、やはり pygame は便利なわけで。
やってることは、VRAM相当の配列を作成して、0xD000 - 0xD3E7 にディスプレイコードが、0xD800 - 0xDBE7 にアトリビュートが記憶されているものと仮定。VRAM相当の配列の中身に従って、読み込んだフォント一覧画像から 8x8ドット単位で選んで描画、みたいな感じ。
MZ-700の表示関係の仕様は、以下が参考になる。ありがたや。
_Programming MZ-700: Display
普段から「pygameは遅い」と言っておきながら何故使うのか、と言われそうだけど。Python を使って画像の類をサクサクサ表示して実験したい、てな場面では、やはり pygame は便利なわけで。
◎ 問題。 :
MZ-80K/1200 のように、色が使えなくて、文字のみを表示する画面なら、2Dゲームのタイルマップを描画するのと同じようなものだから、これといった問題は出ないだろうけど…。
MZ-700 は、文字色と背景色が文字単位 ―― 8x8ドット単位で指定できる。そのあたりをどうすればいいのかで悩んだり。
読み込んだフォント一覧画像は、文字色が白、背景色が黒といった具合に、既に色が指定されているから、そのまま描画しても白黒の文字しか表示できない。それらを、文字色と背景色を別々に、8色で ―― 黒、青、赤、紫、緑、水色、黄色、白に変化させつつ描画したいわけだけど。上手い案が浮かばず。
ソフトウェア的に、ビット単位でアレコレして、毎回 Surface の中身を生成するのはどうかと思ったけれど、たぶんソレだと遅いよなと。C言語等で書くならアリかもだけど、Pythonではな…。Python は遅いし…。
結局、文字部分については、スクリプトの初期化時に、元画像から8色分の画像を生成して、ずっと持ち続けることにした。なんだか富豪的プログラミング。背景部分も、8x8ドットで、8色分のベタ画像を事前に持っておく。
画面の描画時は、まずは文字の背景に相当する8x8ドットのベタ画像を描画して、その上に文字相当をαチャンネルを有効にした状態で描画、みたいな。これを 40 x 25 文字分繰り返す。
こんな方法ではめちゃくちゃ遅いんじゃないのかと予想もしたけど。実際に書いて動かしてみたら、意外とそうでもない。今時のPCスペックならそれほど負荷は高くないようで。
しかし、もっと上手い方法がありそうな気もする。
MZ-700 は、文字色と背景色が文字単位 ―― 8x8ドット単位で指定できる。そのあたりをどうすればいいのかで悩んだり。
読み込んだフォント一覧画像は、文字色が白、背景色が黒といった具合に、既に色が指定されているから、そのまま描画しても白黒の文字しか表示できない。それらを、文字色と背景色を別々に、8色で ―― 黒、青、赤、紫、緑、水色、黄色、白に変化させつつ描画したいわけだけど。上手い案が浮かばず。
ソフトウェア的に、ビット単位でアレコレして、毎回 Surface の中身を生成するのはどうかと思ったけれど、たぶんソレだと遅いよなと。C言語等で書くならアリかもだけど、Pythonではな…。Python は遅いし…。
結局、文字部分については、スクリプトの初期化時に、元画像から8色分の画像を生成して、ずっと持ち続けることにした。なんだか富豪的プログラミング。背景部分も、8x8ドットで、8色分のベタ画像を事前に持っておく。
画面の描画時は、まずは文字の背景に相当する8x8ドットのベタ画像を描画して、その上に文字相当をαチャンネルを有効にした状態で描画、みたいな。これを 40 x 25 文字分繰り返す。
こんな方法ではめちゃくちゃ遅いんじゃないのかと予想もしたけど。実際に書いて動かしてみたら、意外とそうでもない。今時のPCスペックならそれほど負荷は高くないようで。
しかし、もっと上手い方法がありそうな気もする。
◎ ASCIIコードとディスプレイコードの変換で悩む。 :
MZ-700のVRAMは、ディスプレイコードと呼ばれる番号で、どの文字を表示するかを指定できる。このディスプレイコードは、ASCIIコードとは全く並びが違う。
_mz-80K Display - Enri's Home PAGE (mz-80K)
_MZ-700 japanese ASCII code tables
故に、ASCIIコードで列挙された文字列を描画したい時は、1文字ずつ、ASCIIからディスプレイコードに変換しないといけない。で、その変換処理をどう書くかで、またちょっと悩んだり。
ところどころ、位置は違うけど並びは似ている個所があるので、if文で値を返すのはどうかと思って書き始めたけれど。英数字はともかく、カタカナを変換するあたりでギブアップ。これはどう考えてもテーブルが必要だろう。しかし目視でそんなもの作ってられない。せいぜい256個だから、目視と手作業でやれなくもないかもしれんけど、カタカナに加えて、図形文字の判別が厳しい。1ドットだけ位置が違う線、等々があるし…。
結局、Python + Pillow (PIL) で画像を読み込んで、テーブルを出力するスクリプトを書いた。両方の画像を1文字単位で比較して、同じものが見つかったら、それが目的の変換後の番号、みたいな。
ただ、元画像として、ディスプレイコード、及び、ASCIIコードの並びを、全く同じ文字データで列挙した画像が必要で。そのあたりは、EDGE2 を使って、目視と手作業で画像内を並び替えする羽目に。これで本当に作業が楽になったのだろうか…。どうなんだ…。
それにしても、どうしてMZシリーズは、こんな仕様で作ってしまったのだろう…。メモリの節約を試みたのかなあ。
_mz-80K Display - Enri's Home PAGE (mz-80K)
_MZ-700 japanese ASCII code tables
故に、ASCIIコードで列挙された文字列を描画したい時は、1文字ずつ、ASCIIからディスプレイコードに変換しないといけない。で、その変換処理をどう書くかで、またちょっと悩んだり。
ところどころ、位置は違うけど並びは似ている個所があるので、if文で値を返すのはどうかと思って書き始めたけれど。英数字はともかく、カタカナを変換するあたりでギブアップ。これはどう考えてもテーブルが必要だろう。しかし目視でそんなもの作ってられない。せいぜい256個だから、目視と手作業でやれなくもないかもしれんけど、カタカナに加えて、図形文字の判別が厳しい。1ドットだけ位置が違う線、等々があるし…。
結局、Python + Pillow (PIL) で画像を読み込んで、テーブルを出力するスクリプトを書いた。両方の画像を1文字単位で比較して、同じものが見つかったら、それが目的の変換後の番号、みたいな。
ただ、元画像として、ディスプレイコード、及び、ASCIIコードの並びを、全く同じ文字データで列挙した画像が必要で。そのあたりは、EDGE2 を使って、目視と手作業で画像内を並び替えする羽目に。これで本当に作業が楽になったのだろうか…。どうなんだ…。
それにしても、どうしてMZシリーズは、こんな仕様で作ってしまったのだろう…。メモリの節約を試みたのかなあ。
[ ツッコむ ]
以上、1 日分です。