WindowsMobile」カテゴリーアーカイブ

WindowsMobile touchkeysip v1.11

いくつか複数の問い合わせが重なったので更新してみました。
使用期間が短いため問題ある場合は引き続き旧バージョンをお使いください。

touchkeysip v1.11 ソフトウエア入力パネル

●複数の sip 登録

オプション画面を拡張しました。オプション画面の開き方は次の通り。

  スタートメニューから
    設定 → 入力 → 入力方法: touchkeysip → オプション

右上のプルダウンメニューで「Sip 0」~「Sip 2」の切り替えが出来ます。
3 種類それぞれに対して個別に

 ・Script Path / 割り当てるスクリプトファイル名
 ・Enable / 有効・無効 切り替え

の設定が出来ます。有効にすると Sip 一覧に touchkeysip 1, 2 のエントリが表示
され、それぞれが独立した Sip のように振る舞います。

touchkeysip111_01.jpg
↑EM・ONE S01SH (WM6) の場合

touchkeysip111_02.jpg
↑Touch Diamond (S21HT) の場合

複数有効にしてもインスタンスは共有されるので、追加のメモリ消費はほとんど
無いはずです。現在選択している SIP 以外のりソースは解放されるので、
メモリに読み込まれているスクリプトも常に 1つだけです。

これで複数のキーボードデータを使い分けることが出来ると思います。
レジストリへ登録する CLSID を増やすだけなので、原理的にはいくらでも増やすことが出来ます。

●回転時の動作

T-01A で画面回転時に位置が不定になるとの報告をいただきました。
SIP を閉じた状態で画面を回転すると、センタリング位置が不定になる問題は修正
しました。

ただし、T-01A で発生している症状は他の機種では再現しないため、根本的に直って
いるかどうかはわかりません。現物がないと原因を特定できないかもしれません。
WindowsMobile 6.x ではタッチ用に UI が変更またはカスタマイズされており、
細かい動作が端末によって異なっている可能性があります。

●消費メモリの軽減

画像読み込み時のみ必要な dll はすぐに解放するようにしました。
bmp 指定時は dll を使わずに古いローダーを用いるように変更しました。

●パネル

スクリプトでパネルを切り替える方法について質問をいただきました。
以下その説明です。

画面(パネル)切り替えという概念は、script の機能を用いて仮想的に実現しています。
各パネルの機能を作るには下記のデータが必要となります。

・ディスプレイリスト
・イベントテーブル

スクリプトでは、この 2つデータを切り替えることでパネルを変更しています。

◎画像データ

パネルの絵は LoadBitmap コマンドで読み込み、必要なタイミングで描画しています。
描画は自分で行う場合と、ウィンドウシステムが必要なときに勝手に描画する場合が
あります。

例えば上に重なった別のウィンドウを閉じたとき、下のウィンドウの絵を復元しなければ
なりません。
このように再描画が必要になった場合に、どのデータを画面に描画するのかあらかじめ
登録しておくのが「ディスプレイリスト」です。

◎ディスプレイリストの登録

SetDisplayList 命令を使います。
画像の転送元や転送範囲、転送先の座標を登録するだけです。
複数登録しておくと順番に描画します。

SetWindowDisplayList 命令を使って、ウィンドウ毎にディスプレイリストを割り付ける
ことが出来ます。

◎直接描画

ディスプレイリストを登録してもすぐには画面が書き換わりません。
再描画が必要なタイミングにならないと呼び出されないからです。

アニメーションの表現や、パネル切り替えなどで即座に画面を書き換えたい場合は
直接描画する命令を使います。
DrawDisplayList は、指定したディスプレイリストをその場で直接描画する命令です。

◎描画のまとめ

ディスプレリストとは描画手順のこと。

SetDisplayList 命令で登録しておくことができます。

描画手順は二通り。この二つを状況に応じて使い分けることになります。

・ディスプレイリストをウィンドウに割り当てる SetWindowDisplayList
  再描画が必要になったら勝手に呼び出して描画してくれます。
  元の描画に戻す手順です。登録しておかないと再描画で元に戻らなくなります。

・その場で画面に書き込みたいなら DrawDisplayList
  すぐ描画します。一度限りなので、他のウィンドウで消されても戻りません。
  アニメーションや、パネル切り替えなどその場で更新したい場合に使います。

◎イベントテーブル

どの座標をタッチしたらどの関数を呼び出すのか、このようなアクションを登録して
おけるのがイベントテーブルです。

talbe <名前>
dataw <ボタンの個数>
dataw EVENT_DOWN  0 16  32  32  FuncPushA  0  0
~
endtable

テーブルは座標範囲と呼び出す関数名、関数に渡す引数で構成されています。
これをボタンの数だけ並べておけば、タッチしたときに任意のスクリプトが走ります。

実際の動作は関数依存なので、任意の文字を送信してもいいし、パネル切り替えなどの
機能を作ることも出来ます。

イベントテーブルは複数作っておくことが出来るので、パネル毎に設定し直すだけで
動作を好きなように変えられるわけです。

テーブルはウィンドウ毎に指定可能で SetEventTable 命令を使います。
SetEventTable には一度に複数のテーブルを与えることが出来ます。
複数のパネルで同じように使うボタンがあれば、イベントテーブルを共通化しておくことが出来ます。

◎ウィンドウ

CommandManual.txt にも説明がありますが、ウィンドウという概念を持っています。
メインパネルはウィンドウの 0 番 (= WIN_MAIN) に相当します。

サブウィンドウを開くことが出来るので、例えばポップアップ小さい画面を重ねて
情報を出すような表現を作ることが出来ます。

WindowsMobile に最初から入っている SIP はメインパネルだけで出来ています。
touchkeysip も複雑なことをしなければ WIN_MAIN だけで sip として機能します。

◎パネルを切り替える方法

ほぼ下記の命令をセットで用いています。
サンプルスクリプトなどで探してみてください。

SetDisplayList ~       # 描画手順の変更、再登録や書き換えなど
SetWindowDisplayList ~ # ウィンドウに DisplayList を割り当て(変更無ければ不要)
DrawDisplayList ~      # その場で画面を書き換えて表示を更新
SetEventTable ~        # ボタンを押したときの動作を変更する

現在選択しているパネルの状態は、適当なグローバル変数を使って管理しています。

関連エントリ
WindowsMobile touchkeysip v1.10 加速センサーで文字入力

Direct3D Mobile と T-01A の Snapdragon

Toshiba T-01A の d3dmcaps を調べてもらいました。
wm_gamer さん協力ありがとうございました。

Direct3D Mobile DeviceCaps 一覧

Driver="YAMATO_D3DM", Description="AMD Yamato D3D Mobile Driver"
   yes D3DMDEVCAPS_HWTRANSFORMANDLIGHT
   yes D3DMDEVCAPS_HWRASTERIZATION

上記の通り 3D アクセラレータが有効となっています。AMD (ATI) core です。
ドライバはこれまで見たことがない YAMATO_D3DM というもの。

T-01A は Qualcomm の Snapdragon を搭載しています。
Snapdragon は Cortex-A8 同様、新しい ARMv7 世代の ARM core を採用しており、
さらに 1GHz で動作するのが特徴です。

Impress Qualcommの携帯電話向けプロセッサ「Scorpion」~独自実装で1GHz駆動を実現

上の記事によると、かつての StrongARM のように独自の実装であることがわかります。
Cortex-A8 と同じくアウトオブオーダーのスーパースカラで、レジスタリネーミングなど
より積極的な改良が行われているようです。
嬉しいのは VFP 対応なこと。WindowsMobile も、iPhone のように当たり前に
浮動小数演算を使えるようになって欲しいところです。

3D 性能も強化されており、上の d3dmcaps を見ても機能の対応度がこれまでの
MSM7201A (Touch Diamond 他) とは全然違います。

OpenGLES2.0 対応とのことなので、ハードウエア的にはシェーダー世代のはず。
Direct3D8 相当で固定パイプしかない Direct3D Mobile (D3DM) は手狭なのでしょう。
現状で性能を出し切るにはおそらく OpenGLES 2.0 が必要です。

Mobile の世界では Direct3D , OpenGL の立場が逆転しており、Direct3D Mobile の
仕様はかなり遅れているといわざるを得ません。

d3dmcpas のリストを見て特筆すべき点は、出力対応フレームバッファとして 32bit
D3DMFMT_A8R8G8B8 が列挙されていることです。
WindowsMobile は 16bit カラーしか対応しておらず、これまでも最大発色数は 65536色 の
ままでした。当たり前のようにフルカラー対応機種が出ている携帯電話と比べると、だいぶ見劣り
していたことになります。

T-01A / Snapdragon がフルスクリーン時のフルカラー出力に対応しているのだとしたら
私が知る限りでは初だと思います。

関連エントリ
HTC Touch Diamond で Direct3DMobile その(10) d3dmclock v1.10 3Dクロック 更新
HTC S11HT の 3dmcaps

WindowsMobile CABファイルの作成

WindowsMobile 用のフリーソフトウエアは CAB 形式で配布しています。
CAB ファイルは explorer から実行するだけでインストールできるので扱いも簡単です。

今なら別の方法があるのかもしれませんが、昔から VisualStudio に付属している
cabwiz を使用しています。というか WindowsCE / PocketPC の頃に作った設定
ファイルをほとんどテンプレートとして、ずっとそのまま使ってきました。

d3dmclock の場合 (d3dmclock.inf)

[Version]
Signature	= "$Windows NT$"
Provider	= "HYP"
CESignature	= "$Windows CE$"

[CEStrings]
AppName		= d3dmclock
InstallDir	= %CE1%\%AppName%

[CEDevice.ARMWM6]
VersionMin	= 5.0
VersionMax	= 32767.0
ProcessorType	= 2577

[DestinationDirs]
Shortcuts.All = 0,%CE11%
Files.Common = 0,%InstallDir%
DefaultDestDir = 0,%InstallDir%

[Shortcuts.All]
d3dmclock,0,d3dmclock.exe,%CE11%

[SourceDisksNames]
1 = , "Common files",,C:\usr\ce\gclock

[SourceDisksNames.ARMWM6]
2 = , "ARMfiles",,C:\usr\ce\gclock\ARMV4I\Release

[SourceDisksFiles]
d3dmclock.txt = 1
font.dds = 1
bgimage0.bmp = 1
bgimage1.bmp = 1
bgimage2.bmp = 1
textimage0.dds = 1
textimage1.dds = 1
textimage2.dds = 1
textimage3.dds = 1
textimage4.dds = 1
textimage5.dds = 1
textimage6.dds = 1
textimage7.dds = 1

[SourceDisksFiles.ARMWM6]
d3dmclock.exe = 2

[DefaultInstall]
CEShortcuts	= Shortcuts.All

[DefaultInstall.ARMWM6]
CopyFiles	= Files.Common, Files.ARMWM6

[Files.Common]
d3dmclock.txt,,,0
font.dds,,,0
bgimage0.bmp,,,0
bgimage1.bmp,,,0
bgimage2.bmp,,,0
textimage0.dds,,,0
textimage1.dds,,,0
textimage2.dds,,,0
textimage3.dds,,,0
textimage4.dds,,,0
textimage5.dds,,,0
textimage6.dds,,,0
textimage7.dds,,,0

[Files.ARMWM6]
d3dmclock.exe,,,0x80000000

CEString は他で参照する定数の定義です。%~% で参照しています。
Install 先フォルダをここに記述しています。%CE1% は \Program Files

SourceDisksNames はインストールするファイルが置かれている実在のパスを指定します。

SourceDisksFiles はアーカイブするファイルがどこにあるか指定します。
後ろの番号は SourceDisksNames の番号に対応しています。

Files が実際にインストールコピーされるファイルリスト。

“.ARMWM6” がついた定義名は、もともと WindowsCE が複数の CPU に対応しており
対象 CPU 毎に CAB を用意していた頃の名残です。CPU 毎に別ファイルを指定する
場合と、共通に含めるファイルを分けて記述できるようになっています。

(1) DestinationDirs でインストール先フォルダを指定。
  %InstallDir% の定義は CEStrings にあります。
(2) SourceDisksNames.* にアーカイブするファイルの場所を記述
(3) SourceDisksFiles.* に必要なファイルを記述
  (数値は SourceDisksNames の番号に対応している)
(4) Files.* にアーカイブするファイルを記述

詳しくはこちら
MSDN スマート デバイスの .inf ファイルの概要

touchkeysip の場合 (touchkeysip.inf)

[Version]
Signature	= "$Windows NT$"
Provider	= "HYP"
CESignature	= "$Windows CE$"

[CEStrings]
AppName		= touchkeysip
InstallDir	= %CE1%\%AppName%

[CEDevice.ARM]
VersionMin	= 5.0
VersionMax	= 1000.0
ProcessorType	= 2577

[CEDevice.ARMGS]
VersionMin	= 5.0
VersionMax	= 1000.0
ProcessorType	= 2577

[DestinationDirs]
Files.Common = 0,%InstallDir%
DefaultDestDir = 0,%CE2%

[SourceDisksNames]
1 = , "Common files",,C:\usr\ce\minisip2

[SourceDisksNames.ARM]
2 = , "ARMfiles",,C:\usr\ce\minisip2

[SourceDisksNames.ARMGS]
3 = , "ARMfiles",,C:\usr\ce\minisip2\gs

[SourceDisksFiles]
touchkeysip.txt = 1
defaultscript.txt = 1
defaultkeyboard.bmp = 1

[SourceDisksFiles.ARM]
touchkeysip.dll = 2

[SourceDisksFiles.ARMGS]
touchkeysip.dll = 3

[DefaultInstall]

[DefaultInstall.ARM]
CopyFiles	= Files.Common, Files.ARM
CESelfRegister	= touchkeysip.dll

[DefaultInstall.ARMGS]
CopyFiles	= Files.Common, Files.ARMGS
CESelfRegister	= touchkeysip.dll

[Files.Common]
touchkeysip.txt,,,0
defaultscript.txt,,,0
defaultkeyboard.bmp,,,0

[Files.ARM]
touchkeysip.dll,,,0x80000000

[Files.ARMGS]
touchkeysip.dll,,,0x80000000

コマンドの実行手順は Makefile に記述しています。(install.mak)

ZIPFILEARM	= touchkeysip***.zip
CABFILEARM	= touchkeysip.ARM.CAB
EXEARM		= touchkeysip.dll

all: \
	$(EXEARM) \
	$(CABFILEARM) \
	$(ZIPFILEARM) \


zip: $(ZIPFILEARM)


_MANUALFILE	= touchkeysip.txt	\
		CommandManual.txt	\


_CABSRCFILE	= touchkeysip.txt	\
		defaultscript.txt	\
		defaultkeyboard.bmp	\


_SRCFILEARM	= $(EXEARM) \
		$(_CABSRCFILE) \


ZIPSRCFILEARM	= $(CABFILEARM)   $(_MANUALFILE)


$(ZIPFILEARM):	$(ZIPSRCFILEARM)
	7z a -tzip $(ZIPFILEARM) $(ZIPSRCFILEARM)


CABWIZE	= C:\Program Files (x86)\Microsoft Visual Studio 9.0\SmartDevices\SDK\SDKTools\Cabwiz.exe

$(CABFILEARM): touchkeysip.inf $(_SRCFILEARM)
	"$(CABWIZE)" touchkeysip.inf  /cpu ARM

VisualStudio で作成&動作確認が終わったら、nmake の実行だけで CAB の生成と
zip の作成もいっぺんに行われます。上のファイルは install.mak という名前で
各プロジェクトのフォルダに置いてあります。実行はコマンドラインから

nmake -f install.mak

プログラムの数も非常に多いし、開発中はそれぞれが頻繁に更新されるので
公開までの手順は自動化されています。
ドキュメントを修正した場合も nmake だけでアーカイブが作られます。

普段使っているスクリプトファイルを入れて

touchkeysip.dll + スクリプト

といった自分専用の CAB を作っておけば、デバイスの再インストール時に
ちょっとだけ手間が減るかもしれません。

WindowsMobile Touch Pro E30HT と 3D

HTC E30HT の 3D caps 情報を提供していただきました。
nekomantle さんありがとうございました。

Direct3D Mobile DeviceCaps 一覧

E30HT は 3D アクセラレータに対応していないようです。
スペックを調べてみると、同じ Touch Pro でも HT-01A/X05HT とは相違点が目立ちます。

HTC Touch Pro E30HT
HTC Touch Pro HT-01A
HTC Touch Pro X05HT

通信方式の違いから使用しているチップが異なっており、
搭載されている 3D 機能も互換性がないのかもしれません。

モバイルライフ応援日記 伊藤浩一 au初のスマートフォン「E30HT」開封レビュー(第104回)
 >図12 起動画面。ユーザーインタフェースには「Touch FLO 3D」ではなく
 >「Touch FLO」が搭載されています

上の記事によると Touch FLO 3D ではなく Touch FLO に変更されているとのこと。
この辺も関係がありそうです。

なお Qualcomm MSM7500 自体は 3D アクセラレータを持っています。

西川善司の3Dゲームファンのための「東京ゲームショウ2007」グラフィックス講座

問題なのは、同じ Touch Diamond や Touch Pro 系、また同じ機種名でも互換性が
ないということです。
以前作成した d3dmclock も Touch Diamond / Touch Pro 系で動作すると書きましたが、
このデータを見る限り一概には言えなくなりました。
きちんと 3D を扱えるデバイスが少ないとか バグ とか、
WindowsMobile で 3D は何かとたいへんです。

関連エントリ
HTC Touch Diamond で Direct3DMobile その(10) d3dmclock v1.10 3Dクロック 更新
HTC Touch Diamond で Direct3DMobile その(9) d3dmclock v1.00 3D クロック

WindowsMobile のメモリ

WindowsMobile6.x がもう一世代継続されるようです。

米マイクロソフト、スペインで「Windows Mobile 6.5」発表

今でもプラグインが多いと SIP が読み込めなかったり切り替わらなかったり、
ブラウザのようなメモリを多く消費するアプリが不安定になったりしています。
WindowsMobile6.x のカーネルは WindowsCE5.2 で、WindowsMobile5.0 とそれほど
大きく変わっていません。
下記のページで詳しく解説されています。

Windows CE .NET の高度なメモリ管理

これを見ると CE4~5 のメモリ管理は下記の構造になっていることがわかります。

(1プロセス 32MB × 32プロセス) + 32MB の XIP DLL 空間 (ROM DLL)
  + ラージメモリ空間(992MB) + カーネル空間(2GB)

CE の限界は、上記の通り 1プロセスあたりのメモリ空間が 32MB に制限されていること。
最近の端末では 128MB~256MB の RAM を搭載していますが、1つのアプリケーションが
メモリ空間的に限界に達しているときは、いくら物理メモリを増やしても効果がない
ことがわかります。(desktop Windows でも 32bit OS だと 2GB まで、という制限に似ています)

32MB の XIP DLL 空間は、ROM にあらかじめ組み込まれている DLL を配置するための
領域だそうです。system の共有 DLL が XIP 空間に配置されている場合は 32MB の
プロセス領域を消費しません。

ROM に含まれていない (XIP でない) DLL は XIP 空間に配置できません。
こちらはプロセスのメモリを消費します。さらに DLL はプロセス間で共有されるために
ロードしたアドレスが固定されてしまうようです。
よって SIP プラグインなど、後から追加した dll が多数読み込まれている場合は、
各アプリケーションで使用可能なメモリ空間を食いつぶしてしまう可能性があります。

たとえば XIP でない DLL の合計が 16MB あって、かつ最もよく使われる dll が
一番下位のメモリにロードされてしまった場合。またはアプリケーションが複数の
dll をロードする構造の場合、最悪アプリケーションが使用可能なメモリ空間も
16MB になってしまうということです。

これらのこの問題に拍車をかけているのがもう 1つの制限、プロセス数の上限が
32個ということ。常駐するアプリケーションはプロセスを消費しないようサービス
として dll 化することが推奨されていているため、dll 空間を余計圧迫している
可能性があります。また単一のプロセス空間を取り合うため、dll を配置する
サービス用の空間自体も限界に達してしまう可能性もあります。

常駐する dll が多い場合、追加で dll 自体をロードできなくなる場合があること、
またブラウザなどの大きなアプリが不安定になる可能性があることがわかります。
メモリが大量にある場合、dll の共有はかえって逆効果なのかもしれません。

ただ実際に touchkeysip が読み込まれなくなる場合、どの段階で限界が来ており
どこのメモリ確保でエラーが出ているのかきちんと調べたわけではないので、
上の説明もいろいろと憶測が含まれています。あらかじめご了承ください。
単に touchkeysip が悪いだけの可能性もあります。

データ領域に限っていえば、ラージメモリ領域を使用することが出来るためまだ余裕は
ありそうです。上の MSDN のページに書いてある方法で大きなメモリブロックを
まとめて VirtualAlloc で予約すると、ラージメモリ領域に配置されるとのこと。

・常駐する dll を減らす。
・常駐する dll は一番先に読み込ませておく。
・アプリが消費するヒープメモリは自分でラージメモリから確保する。
・アプリを使い終わったらすぐ終了させる。特に独自の dll を使うもの。

等が有効かもしれません。

WindowsCE6.0 (WindowsMobile7) 以降は一般的な 32bit OS と同じ 2GB に拡張され、
プロセス数の制限もなくなるはずです。逆に普通の Windows に近づくので
CE である必要性が徐々に薄れていくような気もします。
先があることがわかっている中に出る 6.5 は Me を思い出してしまいます。

関連エントリ
emobile EM・ONE 使い切れないメインメモリ