2010/08/24
fastmake
以前は VisualStudio の nmake を使っていました。
最近は fastmake を使っています。
・fastmake
●特徴
・高速動作させるための様々な記述が可能。
・豊富な組み込みコマンド。
・Windows native で exe ファイル一つのみ。
・基本的に gmake 互換。
・-j の並列化可能。ただし .PARALLEL 宣言したルールのみ
・コマンド行は TAB じゃなくても良い。
●高速な理由
一番効果的だと感じたのがサブシェル呼出を徹底的に廃したこと。
例えば普通の make だとコマンド実行でシェルを経由するので余計に時間がかかります。
echo や del などのよく使う命令もシェルコマンドなのでシェルが走っています。
この場合 shell が 3回起動するので非常に低速です。
(UNIX shell だと (~;~) 等で呼び出しをまとめたりできる。)
fastmake は echo, rm, mkdir, cd 等よく使う機能が組み込まれており、
サブシェル呼出を必要としません。
コンパイラなどのコマンド実行もシェルを経由せずに直接 exec 可能です。
$(echo~) は組み込み関数です。リダイレクトの代わりに $(echo ~,outpufile)
で直接出力ファイル名を指定することも可能です。
.NOSHELL 指定はシェルを経由せずに直接コマンドを exec しています。
Makefile 中さらに別の Makefile を呼び出すことがよくあります。
やはり通常は make の呼出のためにシェルを経由します。
fastmake は自分自身を呼び出す組み込み関数があります。
この場合同一プロセス内で実行可能で、シェル呼び出しも外部コマンドの呼出も
スキップします。プロセス起動が無いため高速です。
フォルダまるごと削除も簡単に。
↓
●便利な機能など
ドキュメントにも書いてありますが .COMBINE 指定があります。
等のパターンマッチは、生成するファイルごとに個別にコマンドを実行します。
.COMBINE 指定すると 1回のコマンド呼び出しにまとめて実行されます。
↓
フォルダごとに make -f Win32.mak clean を実行する場合次のように書けます。
ドキュメントには下記の方法も紹介されていますが単純に foreach した方が速いようです。
内部コマンドは副作用として実行される関数扱いなので、マクロ置換できる場所なら
どこにでも書けます。下記の make もマクロ展開時に実行されます。
結果が不要な内部コマンドは空文字になるようです。
●気がついたことなど
環境変数はデフォルトでは取り込まれません。
個別に .IMPORT 指定が必要です。
変数 include への代入が出来ません。
コンパイラへ渡す環境変数として "include" が用いられることがありますが、
上のように書くと include 命令と勘違いしてしまうようです。
export 宣言することで回避できます。
Makefile 中に C言語のブロックコメント /*~*/ が使えるように拡張されています。
最近これが問題になることが分かってきました。
こんな感じの記述があると、system"/*".dds の "/*" 以降がコメント扱いになり
無視されてしまいます。エラーが出ないので厄介です。
.FOREACH が意外に汎用性がありません。
パターン定義以外ではあまりうまく機能しないようです。
$(make ~) の make 呼び出しでは -j 指定を変更できません。
下の例の (1) では job 数が変わりません。
job 数を変更する場合は (2) のように自分自身を実行しなおす必要があります。
nmake だとファイルの存在確認が簡単にできますが fastmake ではすっきり
書けません。要研究。
最近は fastmake を使っています。
・fastmake
●特徴
・高速動作させるための様々な記述が可能。
・豊富な組み込みコマンド。
・Windows native で exe ファイル一つのみ。
・基本的に gmake 互換。
・-j の並列化可能。ただし .PARALLEL 宣言したルールのみ
・コマンド行は TAB じゃなくても良い。
●高速な理由
一番効果的だと感じたのがサブシェル呼出を徹底的に廃したこと。
例えば普通の make だとコマンド実行でシェルを経由するので余計に時間がかかります。
echo や del などのよく使う命令もシェルコマンドなのでシェルが走っています。
# nmake
echo_abc:
@echo A
@echo B
@echo C
この場合 shell が 3回起動するので非常に低速です。
(UNIX shell だと (~;~) 等で呼び出しをまとめたりできる。)
fastmake は echo, rm, mkdir, cd 等よく使う機能が組み込まれており、
サブシェル呼出を必要としません。
コンパイラなどのコマンド実行もシェルを経由せずに直接 exec 可能です。
# fastmake
echo_abc:
$(echo A)
$(echo B)
$(echo C)
%.obj .NOSHELL .PARALLEL : %.cpp
$(CC) $(CFLAGS) -c -o $@ $<
$(echo~) は組み込み関数です。リダイレクトの代わりに $(echo ~,outpufile)
で直接出力ファイル名を指定することも可能です。
.NOSHELL 指定はシェルを経由せずに直接コマンドを exec しています。
Makefile 中さらに別の Makefile を呼び出すことがよくあります。
やはり通常は make の呼出のためにシェルを経由します。
# nmake
android:
$(MAKE) -f Android.mak all
fastmake は自分自身を呼び出す組み込み関数があります。
# fastmake
android .PHONY :
$(make -f Android.mak all)
この場合同一プロセス内で実行可能で、シェル呼び出しも外部コマンドの呼出も
スキップします。プロセス起動が無いため高速です。
フォルダまるごと削除も簡単に。
# nmake で rm -fr $(OBJDIR) 相当
OBJDIR = obj
clean:
if exist $(OBJDIR) rmdir /Q /S $(OBJDIR)
↓
# fastmake
OBJDIR = obj
clean:
$(rm $(OBJDIR))
●便利な機能など
ドキュメントにも書いてありますが .COMBINE 指定があります。
%.obj: %.cpp
cl $@ $<
等のパターンマッチは、生成するファイルごとに個別にコマンドを実行します。
cl a.cpp cl b.cpp cl c.cpp ~
.COMBINE 指定すると 1回のコマンド呼び出しにまとめて実行されます。
%.obj .COMBINE : %.cpp
cl $@ $<
↓
cl a.cpp b.cpp c.cpp ~
フォルダごとに make -f Win32.mak clean を実行する場合次のように書けます。
# fastmake
WIN32_DIRS = math file d3d11 gl3 gles2 network script
clean_win32 .PHONY :
$(foreach dir,$(WIN32_DIRS),$(make -C $(dir) -f Win32.mak clean))
ドキュメントには下記の方法も紹介されていますが単純に foreach した方が速いようです。
# fastmake
WIN32_DIRS = math file d3d11 gl3 gles2 network script
clean_win32 .PHONY : $(WIN32_DIRS:+.win32clean) ;
%.win32clean .PHONY :
$(make -C $* -f Win32.mak clean)
内部コマンドは副作用として実行される関数扱いなので、マクロ置換できる場所なら
どこにでも書けます。下記の make もマクロ展開時に実行されます。
DIRS = a b c A:=$(foreach dir,$(DIRS),$(make -f sub.mak))
結果が不要な内部コマンドは空文字になるようです。
$(echo $(echo B)A$(echo C)) ↓ B C A
●気がついたことなど
環境変数はデフォルトでは取り込まれません。
個別に .IMPORT 指定が必要です。
.IMPORT .IGNORE : PATH DXSDK_DIR
変数 include への代入が出来ません。
include = $(DXSDK_DIR)\\include
コンパイラへ渡す環境変数として "include" が用いられることがありますが、
上のように書くと include 命令と勘違いしてしまうようです。
export 宣言することで回避できます。
export include=$(DXSDK_DIR)\\include
Makefile 中に C言語のブロックコメント /*~*/ が使えるように拡張されています。
最近これが問題になることが分かってきました。
COPYFILE_SRC = system/*.dds
こんな感じの記述があると、system"/*".dds の "/*" 以降がコメント扱いになり
無視されてしまいます。エラーが出ないので厄介です。
.FOREACH が意外に汎用性がありません。
パターン定義以外ではあまりうまく機能しないようです。
$(make ~) の make 呼び出しでは -j 指定を変更できません。
下の例の (1) では job 数が変わりません。
job 数を変更する場合は (2) のように自分自身を実行しなおす必要があります。
# (1)
android .PHONY :
$(make -j 10 -f Android.mak all)
# (2)
FMAKE = fastmake.exe
android .PHONY .NOSHELL :
$(FMAKE) -j 10 -f Android.mak all
nmake だとファイルの存在確認が簡単にできますが fastmake ではすっきり
書けません。要研究。
# nmake MAYAPATH = C:\Program Files\Autodesk\Maya2011 !if EXIST( "$(MAYAPATH)" ) ~ !endif
# fastmake PROGFILES = C:\\Program Files PROGFILES_AUTO = $(PROGFILES)\\Autodesk .IF $(ls $(PROGFILES),d,Autodesk) != "" .IF $(ls $(PROGFILES_AUTO),d,Maya2011) != "" ~ .END .END
2010/07/31
OpenGL 4.1 GeForce GTX 460
買ってきました。
早速 OpenGL 4.1 対応ドライバ 259.09 入れています。
D3D11 の caps は RADEON HD 5870 とほとんど同じで、RADEON + D3D11 用に
作ったプログラムもそのまま動作しました。
Feature で Driver Command Lists のみ No になっている点も RADEON と同じです。
OpenGL 4.1 はとりあえず初期化だけ。
まだヘッダがありませんが Shader のバイナリフォーマットも
こんな感じで取れました。
関連エントリ
・OpenGL 4.1 と OpenGL ES 2.0
早速 OpenGL 4.1 対応ドライバ 259.09 入れています。
D3D11 の caps は RADEON HD 5870 とほとんど同じで、RADEON + D3D11 用に
作ったプログラムもそのまま動作しました。
Feature で Driver Command Lists のみ No になっている点も RADEON と同じです。
OpenGL 4.1 はとりあえず初期化だけ。
まだヘッダがありませんが Shader のバイナリフォーマットも
const int GL_NUM_PROGRAM_BINARY_FORMATS= 0x87fe;
const int GL_PROGRAM_BINARY_FORMATS= 0x87ff;
GLint bin_nums= 0;
glGetIntegerv( GL_NUM_PROGRAM_BINARY_FORMATS, &bin_nums );
GLint param[max_formats];
glGetIntegerv( GL_PROGRAM_BINARY_FORMATS, param );
for( int i= 0 ; i< bin_nums ; i++ ){
GLint bin_format= param[i];
..
}
こんな感じで取れました。
GL_VERSION: 4.1.0 GL_RENDERER: GeForce GTX 460/PCI/SSE2 GL_VENDOR: NVIDIA Corporation GL_SHADING_LANGUAGE_VERSION: 4.10 NVIDIA via Cg compiler NUM_PROGRAM_BINARY_FORMATS = 1 PROGRAM_BINARY_FORMAT = 8e21 NUM_COMPRESSED_TEXTURE_FORMATS = 3 COMPRESSED_TEXTURE_FORMAT = 83f0 COMPRESSED_TEXTURE_FORMAT = 83f2 COMPRESSED_TEXTURE_FORMAT = 83f3 [GL_ARB_ES2_compatibility] [GL_ARB_get_program_binary] [GL_ARB_robustness] [GL_ARB_separate_shader_objects] [GL_ARB_shader_precision] [GL_ARB_vertex_attrib_64bit] [GL_ARB_viewport_array]
関連エントリ
・OpenGL 4.1 と OpenGL ES 2.0
2010/07/30
OpenGL 4.1 と OpenGL ES 2.0
OpenGL の動きが活発です。
OpenGL 4.0/3.3 のリリースが今年の 3月。
早くも OpenGL 4.1 が出ました。
・OpenGL Registry
NVIDIA のサイトにはすでに GeForce (Fermi) 系向けのドライバもあります。
・NVIDIA OpenGL 4.1 driver
OpenGL は 3.x で徐々に新しい機能セットに移行し、従来との互換性は Profile
指定による互換モードで保っています。
互換性の枷がなくなったことで新機能への追従が容易になったのでしょう。
DirectX に比べて遅れていた機能面の取り込み速度が格段に早くなっています。
4.0 以降、Direct3D 11 との機能差はほぼなくなっているようです。
DirectX も細かな改良は定期的な DirectX SDK のリリースで続けられていますが、
世代の変化は OS の更新と同調する必要もあり、ここしばらく core には目立った
動きもありませんでした。
むしろ Game Console が D3D9 世代ということもあり、さらに XP の制限も
あったため、API が完全刷新された Direct3D 10 への移行すらあまり積極的に
進んでいない状況です。
その点 OpenGL の方が世代間を移行しやすいので、D3D10/D3D11 相当の機能は
OpenGL の方がより広く使われることになるかもしれません。
もう一つ OpenGL の勢いを決定づけた点がモバイル向け API OpenGL ES の存在です。
すでにモバイル向け 3D API の標準は OpenGL ES 2.0 だと断言して構わないでしょう。
DirectX Mobile は固定機能の D3D8 ベースから更新されておらず、
WindowsPhone 7 でも XNA を通したサブセットで、シェーダーどころかさらに機能
制限される形になりそうです。モバイル向け GPU も進化し続けていますが、
その可能性を引き出せる API にはならないようです。
モバイル開発との相互移植性の高さは OpenGL の魅力の一つです。
この点は十分認知されているようで OpenGL 4.1 ではさらに OpenGL ES 2.0 との
互換 Profile が追加されました。考えられるメリットは下記の通り。
・HW 機能の再現が不要なら Emulator 無しに GL core だけで動作確認できる
・相互移植のしやすさ、desktop 向け OpenGL ES 2.0 アプリの開発
これまでもデスクトップで動作する OpenGL ES 2.0 Emulator が各 GPU メーカー
から公開されています。それぞれ完成度が高く、アプリがすんなり動いていたので
このままリリースしてもいいのではないかと疑問をいだいていたのも事実。
● OpenGL の問題点や Direct3D との違い
すっかり OpenGL / OpenGL ES 2.0 を使う機会が多くなりました。
とはいえ D3D11 にも良い点がかなりあります。
今後それぞれ改良されていくものと思われます。
以下いくつか問題と感じていた点。
・コンパイラ互換性
DirectX は OS 間の互換性を保つことが出来ませんが、そのかわり GPU の違いは
かなり吸収してくれます。
特にシェーダーコンパイラは共通バイトコードが定義されており、どの GPU でも
MS 製の同じコンパイラでバイナリ化出来ます。
OpenGL の GLSL コンパイラは GPU ドライバ依存なので、言語仕様の小さな差異が
問題になることがあります。
同じ C++ 言語でも VC と gcc で違いがあるように、GPU メーカー毎に異なる
コンパイラが存在しているからです。
・エラーコード
Direct3D 10 以降のエラーメッセージに慣れていると OpenGL API のエラーコードに
戸惑います。GL_INVALID_ENUM 等の数種類のコードの使い回しなので、すぐに問題を
特定することが出来ません。慣れかもしれませんが、この点は Direct3D の方が
ずっと分かりやすいし親切だといえます。
・シェーダーコンパイル時間
GLSL はアプリケーション起動のたびに毎回コンパイルが必要でした。
OpenGL 4.1 ではシェーダーを独立してバイナリ化するための専用 API が追加
されているので、今後解決していくものと思われます。
・テクスチャ圧縮フォーマット
Direct3D で当たり前に使える DXT/BC のありがたみがよく分かります。
・スレッド対応
OpenGL の場合自分で工夫する必要あり。
Direct3D 11 が便利すぎたので。
関連エントリ
・OpenGL 4.0 / OpenGL 3.3
OpenGL 4.0/3.3 のリリースが今年の 3月。
早くも OpenGL 4.1 が出ました。
・OpenGL Registry
NVIDIA のサイトにはすでに GeForce (Fermi) 系向けのドライバもあります。
・NVIDIA OpenGL 4.1 driver
OpenGL は 3.x で徐々に新しい機能セットに移行し、従来との互換性は Profile
指定による互換モードで保っています。
互換性の枷がなくなったことで新機能への追従が容易になったのでしょう。
DirectX に比べて遅れていた機能面の取り込み速度が格段に早くなっています。
4.0 以降、Direct3D 11 との機能差はほぼなくなっているようです。
DirectX も細かな改良は定期的な DirectX SDK のリリースで続けられていますが、
世代の変化は OS の更新と同調する必要もあり、ここしばらく core には目立った
動きもありませんでした。
むしろ Game Console が D3D9 世代ということもあり、さらに XP の制限も
あったため、API が完全刷新された Direct3D 10 への移行すらあまり積極的に
進んでいない状況です。
その点 OpenGL の方が世代間を移行しやすいので、D3D10/D3D11 相当の機能は
OpenGL の方がより広く使われることになるかもしれません。
もう一つ OpenGL の勢いを決定づけた点がモバイル向け API OpenGL ES の存在です。
すでにモバイル向け 3D API の標準は OpenGL ES 2.0 だと断言して構わないでしょう。
DirectX Mobile は固定機能の D3D8 ベースから更新されておらず、
WindowsPhone 7 でも XNA を通したサブセットで、シェーダーどころかさらに機能
制限される形になりそうです。モバイル向け GPU も進化し続けていますが、
その可能性を引き出せる API にはならないようです。
モバイル開発との相互移植性の高さは OpenGL の魅力の一つです。
この点は十分認知されているようで OpenGL 4.1 ではさらに OpenGL ES 2.0 との
互換 Profile が追加されました。考えられるメリットは下記の通り。
・HW 機能の再現が不要なら Emulator 無しに GL core だけで動作確認できる
・相互移植のしやすさ、desktop 向け OpenGL ES 2.0 アプリの開発
これまでもデスクトップで動作する OpenGL ES 2.0 Emulator が各 GPU メーカー
から公開されています。それぞれ完成度が高く、アプリがすんなり動いていたので
このままリリースしてもいいのではないかと疑問をいだいていたのも事実。
● OpenGL の問題点や Direct3D との違い
すっかり OpenGL / OpenGL ES 2.0 を使う機会が多くなりました。
とはいえ D3D11 にも良い点がかなりあります。
今後それぞれ改良されていくものと思われます。
以下いくつか問題と感じていた点。
・コンパイラ互換性
DirectX は OS 間の互換性を保つことが出来ませんが、そのかわり GPU の違いは
かなり吸収してくれます。
特にシェーダーコンパイラは共通バイトコードが定義されており、どの GPU でも
MS 製の同じコンパイラでバイナリ化出来ます。
OpenGL の GLSL コンパイラは GPU ドライバ依存なので、言語仕様の小さな差異が
問題になることがあります。
同じ C++ 言語でも VC と gcc で違いがあるように、GPU メーカー毎に異なる
コンパイラが存在しているからです。
・エラーコード
Direct3D 10 以降のエラーメッセージに慣れていると OpenGL API のエラーコードに
戸惑います。GL_INVALID_ENUM 等の数種類のコードの使い回しなので、すぐに問題を
特定することが出来ません。慣れかもしれませんが、この点は Direct3D の方が
ずっと分かりやすいし親切だといえます。
・シェーダーコンパイル時間
GLSL はアプリケーション起動のたびに毎回コンパイルが必要でした。
OpenGL 4.1 ではシェーダーを独立してバイナリ化するための専用 API が追加
されているので、今後解決していくものと思われます。
・テクスチャ圧縮フォーマット
Direct3D で当たり前に使える DXT/BC のありがたみがよく分かります。
・スレッド対応
OpenGL の場合自分で工夫する必要あり。
Direct3D 11 が便利すぎたので。
関連エントリ
・OpenGL 4.0 / OpenGL 3.3
2010/07/08
マルチタッチイベントの構造と違い
● Windows 7
●Android 2.x 以降
●iOS (iPhoneOS)
たまに更新しています。
・Multitouch 関連情報
PRIMARY
WM_TOUCH: id3 (x,y) DOWN
WM_TOUCH: id3 (x,y) MOVE
WM_TOUCH: id3 (x,y) MOVE id4 (x,y) DOWN
WM_TOUCH: id3 (x,y) MOVE id4 (x,y) MOVE
WM_TOUCH: id3 (x,y) MOVE id4 (x,y) MOVE id5 (x,y) DOWN
WM_TOUCH: id3 (x,y) UP id4 (x,y) MOVE id5 (x,y) MOVE
WM_TOUCH: id4 (x,y) MOVE id5 (x,y) MOVE
WM_TOUCH: id4 (x,y) MOVE id5 (x,y) UP
WM_TOUCH: id4 (x,y) UP
●Android 2.x 以降
pointerIndex/pointerId (x,y)
ACTION_DOWN: 0/id0 (x,y)
ACTION_MOVE: 0/id0 (x,y)
ACTION_MOVE: 0/id0 (x,y)
ACTION_DOWN: 0/id0 (x,y) 1/id1 (x,y) actionPointerId=1
ACTION_MOVE: 0/id0 (x,y) 1/id1 (x,y)
ACTION_DOWN: 0/id0 (x,y) 1/id1 (x,y) 2/id2 (x,y) actionPointerId=2
ACTION_MOVE: 0/id0 (x,y) 1/id1 (x,y) 2/id2 (x,y)
ACTION_UP: 0/id0 (x,y) 1/id1 (x,y) 2/id2 (x,y) actionPointerId=0
ACTION_MOVE: 0/id1 (x,y) 1/id2 (x,y)
ACTION_MOVE: 0/id1 (x,y) 1/id2 (x,y)
ACTION_UP: 0/id1 (x,y) 1/id2 (x,y) actionPointerId=1
ACTION_UP: 0/id1 (x,y) actionPointerId=0
●iOS (iPhoneOS)
touchesBegan: (x,y) touchesMoved: (x,y) touchesMoved: (x,y) touchesBegan: (x,y) touchesMoved: (x,y) touchesMoved: (x,y) (x,y) touchesBegan: (x,y) touchesMoved: (x,y) (x,y) (x,y) touchesMoved: (x,y) (x,y) (x,y) touchesEnded: (x,y) touchesMoved: (x,y) (x,y) touchesMoved: (x,y) touchesEnded: (x,y) (x,y)
たまに更新しています。
・Multitouch 関連情報
2010/07/04
iPad タッチキーボード
iPad のタッチパネルは紙を数枚重ねても反応します。
指が直に触れる必要はないようです。
薄い紙を1枚敷いて適当に下書きして、上に切り取った厚めのボール紙を貼りつけてみました。
キーの形にカットして中央に穴をあけています。
うまくいくかわからなかったので、かなり適当な試作です。

厚紙でも 2枚くらいなら反応するので、キーの上に指を置いて休めることはできません。
ただタッチしたときにボタンの位置がわかるので、ホームポジションからタッチ
しながら位置の補正ができるようにはなりました。
見た目は悪いけど意外に打てるかも。
キータイプしてて違和感あるのは次の3つ
(1) 爪があたっても反応しない。
(2) ソフトキーボードのキー間隔が微妙に一定じゃない。
(3) 長押し判定があり、キーを離したときに入力される。
(2) はタイプするまで気が付きませんでしたが、一見等間隔に並んでいるようで違います。
例えば左端の [Q] と [A] はキー幅の半分ずれてますが、右端の [O] と [L] は
キー幅の半分以上重なっています。[O] と [L] の方が本来のキーに近い配置です。
同じように [A] と [Z] のずれ位置は正しいですが、右端の [L] に対して [.] は若干
左に寄っています。
ちょっとくらい貼り付ける位置をずらしても大丈夫なので、本来のキーボードに合わせて
作れば打ちやすくなるかもしれません。
(1) はタイピング方法を変えて慣れるしかなさそうです。中指の中下段など、キーに
よっては少々厳しいところがあります。
意外に良かった点は Nキーロールオーバー。押しっぱなしでも 7キーくらい順番通りに
入力されました。多点マルチタッチ可能な iPad ならでは。
ただ (3) の挙動があるので、複数のキーを押したままだとどれか 1つのキーを離すまで
文字が入力されません。
その他のテスト
裏返しで使ってみたら、触れただけでは反応せず押し込んで打てるようになった。
もっと手抜きして、キーの中央に小さく紙を貼りつけるだけでも打てます。
位置が分かりづらいので最初のと比べていまいちでした。

入力よりも連文節の変換で詰まることも多いです。
iPhone は iOS 4 で改善されているので iPad 版を待つことにしましょう。
指が直に触れる必要はないようです。
薄い紙を1枚敷いて適当に下書きして、上に切り取った厚めのボール紙を貼りつけてみました。
キーの形にカットして中央に穴をあけています。
うまくいくかわからなかったので、かなり適当な試作です。

厚紙でも 2枚くらいなら反応するので、キーの上に指を置いて休めることはできません。
ただタッチしたときにボタンの位置がわかるので、ホームポジションからタッチ
しながら位置の補正ができるようにはなりました。
見た目は悪いけど意外に打てるかも。
キータイプしてて違和感あるのは次の3つ
(1) 爪があたっても反応しない。
(2) ソフトキーボードのキー間隔が微妙に一定じゃない。
(3) 長押し判定があり、キーを離したときに入力される。
(2) はタイプするまで気が付きませんでしたが、一見等間隔に並んでいるようで違います。
例えば左端の [Q] と [A] はキー幅の半分ずれてますが、右端の [O] と [L] は
キー幅の半分以上重なっています。[O] と [L] の方が本来のキーに近い配置です。
同じように [A] と [Z] のずれ位置は正しいですが、右端の [L] に対して [.] は若干
左に寄っています。
ちょっとくらい貼り付ける位置をずらしても大丈夫なので、本来のキーボードに合わせて
作れば打ちやすくなるかもしれません。
(1) はタイピング方法を変えて慣れるしかなさそうです。中指の中下段など、キーに
よっては少々厳しいところがあります。
意外に良かった点は Nキーロールオーバー。押しっぱなしでも 7キーくらい順番通りに
入力されました。多点マルチタッチ可能な iPad ならでは。
ただ (3) の挙動があるので、複数のキーを押したままだとどれか 1つのキーを離すまで
文字が入力されません。
その他のテスト
裏返しで使ってみたら、触れただけでは反応せず押し込んで打てるようになった。
もっと手抜きして、キーの中央に小さく紙を貼りつけるだけでも打てます。
位置が分かりづらいので最初のと比べていまいちでした。

入力よりも連文節の変換で詰まることも多いです。
iPhone は iOS 4 で改善されているので iPad 版を待つことにしましょう。
| 次のページ(日付が古い方向)>>