One Note Jam

S60用スクリーンキャプチャツール「GetPixels」の開発 (2) (2005-11-27)

現在作成中のスクリーンキャプチャツールですが、開発は遅々として進んでいません。スクリーンキャプチャに必要な機能自体はすでに実装が済んでいるのですが、S60用のGUIの実装に時間がかかっています。ちなみに、アプリケーションの名前は「GetPixels」と命名しました(いかにもプログラマ的なセンスだ……)。

それはさておき、「GetPixels」開発において得たノウハウなどを、この場で書いていこうと思います。

スクリーン表示内容の取得

スクリーンキャプチャツールを作成するにあたり、まず何といっても「現在のスクリーンの表示内容を取得する」ことができないと話になりません。それを実現するためには、「スクリーンデバイス」の機能を使うことで、スクリーンの表示内容にアクセスすることができます。

CWsScreenDevice* device = CCoeEnv::Static()->ScreenDevice();

CWsScreenDeviceクラスには、「GetPixel」とか「GetScanLine」といったAPIが用意されているので、これらを使えば簡単にスクリーンの表示内容を取得できます。その後の料理はお好きなように。

スクリーンキャプチャツール内の実際の実装では、まさにスクリーンキャプチャのために用意されているかのような「CopyScreenToBitmap」というAPIを使っています。ビットマップオブジェクトを引数にして、指定されたビットマップにスクリーンの内容をコピーするというAPIです。使用例は以下のとおり。

CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
CleanupStack::PushL(bitmap);
User::LeaveIfError(bitmap->Create(device->SizeInPixels(), device->DisplayMode()));

device->CopyScreenToBitmap(bitmap);

// (bitmapを使って各種処理を行う)

CleanupStack::PopAndDestroy(bitmap);

ちなみに、このCopyScreenToBitmapというAPIですが、実行すると指定したビットマップの内容が変化するにもかかわらず、引数の型は「const CFbsBitmap*」とconst修飾されているので注意してください。CFbsBitmapクラス内には実データが含まれていない(実データへの「ポインタ」のみ含まれている)ので、こういう定義でも間違いではないのでしょうが、まぎらわしいものです。

なお、上記のスクリーンデバイス関連の記述は、S60とかUIQといったユーザーインターフェースに関係なく、Synbian OS全般で共通(のはず)です。

posted at 2005-11-27 | Permalink

S60用スクリーンキャプチャアプリケーションの開発 (2005-11-13)

久々に(プライベートで)Symbianプログラムを再開。作っているのはS60プラットフォーム向けのスクリーンキャプチャツールです。先日、702NKのスクリーンショットを取る必要が生じたのでその手のアプリケーションを物色してみたのですが、なぜか保存形式がJPEG形式だったり、非圧縮形式で保存できるものはシェアウェアだったりして、なんともままなりません。それがきっかけで、ちょっと自分で作ってみようかと思った次第です。

実は、最近私は業務でSymbianプログラムの開発をやっていて、表示系まわりについてはちょっとだけ知識があります。なので、スクリーンキャプチャを実現するために、Symbianのクラスライブラリのどのクラスを使えばいいのかについてもだいたい見当はついていました。というわけで、スクリーンの表示内容をCFbsBitmap形式にダンプするクラスをさくっと作成。そうなれば、CFbsBitmap::SaveL()メソッドを使って簡単にmbmファイルが出来上がり(mbm形式は、Symbian OS標準の画像形式です)。あとは、SDKのツール"bmconv"を使えばBMPファイルに変換できます。やっぱりスクリーンショットは非圧縮形式でないとねー。

せっかく作ったので、もうちょっとまともなものにして公開しようかと思います。まずは画像の保存形式を標準的なフォーマット(PNGとかBMPとか)に対応させたいところ。画像の各種フォーマットへのエンコードは、ICL(Image Conversion Library)を使えば簡単に実現できそうです。今後の業務でICLに係わる可能性もあるため、これを機に触れておこうかと考えています。

posted at 2005-11-13 | Permalink

ゲームボーイアドバンス用プログラム開発雑感 (2) (2005-11-05)

RAM: 288KBytes・ROM: (最大)32MBytes

ゲームボーイアドバンス(以下GBA)での開発をやってみて、最も厳しいと感じたことの一つは「RAMが少ない」という点です。CPU内部に32KBytes・CPU外部に256KBytesで、合わせて288KBytesというRAMの量は、最近のリッチな環境に慣れた者にとってはかなり手狭に感じます。

代わりに、ROM領域はかなり広大です。市販のGBAゲームでは、ROMカートリッジの容量が8MBytesとか16MBytesといったものもあります(最大で32MBytesまで)。また、GBAではROM領域に配置されたプログラムを直接(= RAM領域に展開せずに)実行できますし、CPUからROM領域のデータを直接アクセスすることもできます。なので、RAM領域は純粋に「読み書き可能なメモリ領域」として使うことになるので、容量が少なくてもさほど問題にはならないわけです(多いに越したことはないのですが)。

余談ですが、このあたりはDoJaなんかの携帯電話向けJavaアプリ開発などと比較すると見事に対称的です。携帯アプリでは「ROM容量(≒jarパッケージの容量)」は厳しく制限されていて、代わりに「RAM容量(≒ヒープとして確保できる領域)」は(端末にもよりますが)比較的多めに取れるようになっています。

RAM: 32KBytes・ROM: 256KBytes

ところが、ブートケーブルを使用して実機動作を行う環境の場合、話が変わってきます。以前の記事(2005-10-23)で触れましたが、「ブートケーブル」とは自作プログラムを実機へ送信して起動するためのハードウェアです。これを使用して「送信」したプログラムがどこに格納されるかというと、当然のごとくGBA内のRAM領域しかありません。具体的には「CPU外部RAM(256KBytes)」に格納されます。

すなわち、ブートケーブル環境で動かせるプログラムは最大でも256KBytesで、さらにRAMとして使用できる領域は内部RAMの32Kbytesということになります。これはさすがに狭い……。

実際のところ、私が作っているようなミニゲーム程度のものであれば、このスペックでもなんとかなります。とはいえ、「狭い」ことからくる心理的影響はなかなか大きく、開発中は何かと節約しがちなコーディングとなってしまいます。

こういった事情を知ると、市販GBAゲームで「1カートリッジプレイ」用のプログラムを作成するのは非常に大変であろうことが推測できます。市販GBAゲームの1カートリッジプレイでは、基本的には「通常版」のゲームをそのまま(あるいは「制限版」を)プレイできるようにする必要があります。256KBytes内にグラフィックやサウンドを収めることの厳しさもさることながら、使えるRAMが32KBytesに制限されるというのはさらに厳しいのではないかと思われます。仕事で開発している人は大変だな……。

posted at 2005-11-05 | Permalink

© 2004-2008 ENDO