読者です 読者をやめる 読者になる 読者になる

八重タイちょこっと改造

YAE-typing - 八重タイピング - How To Become A Typer

八重タイでもAZIKの練習をしようと少しプレイしてみたんだけど、キー入れ替えソフトとキー入力による画面遷移の相性がよくないことに気づいた。というのも八重タイ(e-typing)は画面を切り替えるたびに次のような文字キーを要求してくるんだけど、キー入れ替え後の状態でsとかrを出させるのは少し手間だったりする。

  • スタート画面→レディ画面:sキー
  • レディ画面→プレイ画面:Spaceキー
  • 結果画面→スタート画面:rキー

例えば姫踊子草(繭姫)でローマ字入力タイピングソフト向けの出力をすると確かにローマ字入力をエミュレートしてくれるけど、「s」キーを出力するには「さ行」の文字を入力しないといけない。AZIKだと「s」「a」と二つ入力してようやく「sa」のキーが出力されるのだ。ちょっと気持ち悪いよね!

というわけで全部Enterキーで次の画面にいけるようにしてみた。初めはdat/screen.xmlで画面遷移のためのキーも定義してあるのかなと期待したけど、無かったのでソースを書き換えてコンパイルし直してみた。うん。便利便利。


あ、あとTODOのところで新しいものを発見。

vista でフォントのレンダリングおかしいという問題がまだ起きるのか調べる

確かSDLPythonポーティング版Pygameを使って書いたときもVistaでは英字フォントが変なことになっていた気がする。確か半角文字を描画してるのに全角サイズで描画されてレイアウトがおかしなことになったような。SDL_ttf.dllとかに問題があるとか無いとか。原因をちゃんと調べてなかったな・・・。


以下、ソース読み試行錯誤の痕跡。

YaetGui(yaet_gui.d)の中身を見てkeyDownEventHandlerを追っかけていけばいいだろうと思ったんだけど、_type関数と_optionKeyDown関数がYAET.TYPING、YAET.OPTIONの状態の時にしか呼ばれないことに気づいてさらに上を追っかけてみることに。ちなみにYaetGUI._typeはまさにタイピング画面でローマ字入力を処理している関数。

YaetGuiの親クラスはSDLXmlGui(xmlgui.d)クラス。この中のproc関数からkeyDownEventHandlerを呼び出している。(継承するならわざわざdelegate使わずに仮想関数にしてオーバーライドすればいいような・・・?)

SDLXmlGui.proc関数のSDL_KEYDOWNイベントを処理する一番深いところで、さきほどのkeyDownEventHandlerを呼び出していることがわかる。あれ?これだけ?と思ったらその少し前にs.shortcutTypeという関数を呼び出していて、これがfalseを返したときだけkeyDownEventHandlerを呼び出している。この関数にキー入力情報も渡しているのでそこで入力イベントを処理してるっぽい。怪しい。

で、このsが何かというとScreenContainer(screen.d)で、画面上のButtonとかImageをまとめて保持し、描画したりイベントを管理するクラスということがわかる。
ScreenContainer.shortcutTypeはさらにそのコンテナの中に入っている子アイテムに対してshortcutTypeを実行して一つでもうまくいったらtrueを返している。

あとはもう簡単で、ScreenContainerの中に入るであろうScreenButton(screen.d)を見てみると、shortcutKeysと_funcというdelegateが定義してあって、ScreenButton.shortcutTypeが呼び出されたときにshortcutKeysに定義してあるキーのどれかと一致したら_funcが呼び出されるという寸法だ。

そこでYaetGui(yaet_gui.d)の方に戻ると、確かにshortcutKeysに対していろいろキーを定義している箇所がたくさんある。それぞれ_loadTitle, _loadOption, _loadResult, _loadDetail, _typingReadyでその画面における「各ボタンをクリックしたとき」「キーを押したとき」に呼ばれる処理が書いてあるので、次の画面に遷移するキーにSDLK_RETURNを追加してやればOK。それぞれの関数は画面遷移するSDLXmlGui.go関数を呼び出すときに自動的に呼ばれる。


ちょっと気になったのはさっきの「delegateと継承」に関する部分とSceneを管理するのに"typing"といった文字列の名前を使っている部分とenumでYAET.TYPINGのように定義している二つが存在すること。あと、screen.xmlのButtonやImageには対応しているクラスがあるので、それをまとめるsceneにも対応するSceneクラスを作って画面遷移ごとに切り替えてやると描画や入力イベントの処理を抽象化できてすっきりするかも。

D言語も読みやすくて良いです。
C/C++爆発しろ!