Inside.
概要
ボトルクライアントには、各種ゴーストのサーフィスをプレビューする機能が搭載されていますが、ボトルクライアント自体にはサーフィスの画像データが含まれていませんし、特定のファイル形式から画像データを取得してくるような機構も実装されていません。
画像データは、プラグインを通して取得します。
プラグインは、ボトルクライアントと同じ場所にある SPP フォルダに配置します。ここに配置することで、起動時にプラグインが自動的に読み込まれます。
現在の仕様では、プラグインは見つかった順に読み込まれ、サーフィスの検索は読み込まれた順に優先されて行われます。
実装仕様とAPI
概要
プラグインの実体は、単純なDLLです。
プラグインの基本的な機能は、「ゴースト名とサーフィス番号を受け取って、ビットマップ画像を返す」という、いたってシンプルな動作の繰り返しです。
画像をどこからどのように取得してくるのか(或いは自前で描画するのかもしれませんが)について、ボトルクライアントは関知しませんが、すべての呼び出しはボトルクライアントの動作をブロックするので、出来るだけ素早く画像を返すことが望まれます(オンデマンドでリモートからダウンロード、とかは無理です)。
残念ながらselfnameとkeronameの組み合わせではなくて、単純にselfnameのみで識別することになります。
プラグインは、Load, Unload, GetVersion, GetImage, GetImageSize,
Configureの6つの関数をエキスポートしてください。
いずれかが欠けるとエラーとなります。将来のバージョンではGetVersion以外の関数はエキスポートされなくなる・プロトタイプが変わる可能性があります。
以下の関数のプロトタイプがPascal限定なのは、単純に自分がC言語でどう書くのか自信を持って言えないからですが、Visual
C++やVBでDLLを作成することも可能です。
とりあえず、呼び出し規約は cdecl で、 PChar = LPSTR, integer = int, boolean = BOOL
のはずなので、後は自分でなんとかしてください。
Load
procedure Load(Path: PChar); cdecl;
DLLの読み込み時に呼び出されます。Pathには、DLLの存在する場所が渡ります。
DLL固有の設定ファイルなどを保存する場合はPathで指定されるディレクトリを利用してください。
Unload
procedure Unload; cdecl;
DLLの解放直前に呼び出されます。呼び出す側が特にやって欲しい動作はありませんので、DLLが独自に取得したリソースの解放などを行ってください。
GetVersion
function GetVersion(Name: PChar; NameLen: integer;
var Version: integer; var CanConfigure: boolean): integer; cdecl;
プラグインのバージョンやプラグイン名を報告します。
NameLenバイト以内で、Nameにプラグインの名前を返してください。この文字列の中に、できればプラグイン自体のバージョン番号などを含めるとよいです。
Versionは対応しているAPIのバージョン番号です。1を返してください。
CanConvigureは、Configureができるかどうかを返します。ただしここでfalseを返す場合でも、Configure関数は何もしない関数としてエキスポートはしてください。
GetImageSize
function GetImageSize(Ghost: PChar; Surface: integer; var w, h:
integer): integer; cdecl;
実際のイメージを返すのに先立って、イメージのサイズを取得します。
関数は、イメージサイズの取得に失敗した場合に1を、成功した場合に0を返してください。
Ghost, Surfaceはそれぞれ、必要なゴースト名とサーフィス番号です。wとhに、画像の幅と高さを入れて関数を終了してください。
この関数は、実際に画像を読み込んで正確なサイズを取得する必要は必ずしもありません。また、GetImageSizeが成功した場合でも、実際のGetImageの段階で関数が失敗(画像が見つからない)することに問題はありません。DLLが固定されたサイズの画像しか返さない仕様なら、この関数は問答無用で定数を返すだけの実装にして大丈夫です。
実際に画像を読み込んで正確なサイズを返す場合は、直後にGetImageが呼ばれることを考えて、読み込んだ画像を保持しておく必要があるかもしれません。
GetImage
function GetImage(Ghost: PChar; Surface: integer; H: HBITMAP): integer;
cdecl;
実際にイメージを取得します。Hはビットマップハンドルで、関数の呼び出し元で既に作成され、サイズが指定されています。
このビットマップに、求める画像を描画してください。
関数が失敗した場合(指定画像が見つからない場合)は1を、成功した場合は0を返します。
Configure
procedure Configure; cdecl;
DLLの設定を行います。ボトルクライアントが設定画面でプラグイン項目をダブルクリックした場合に呼び出されます。
自前で準備した設定ダイアログを開いて、その設定結果をファイルに保存するなどしてください。
DLL実装上の注意
- 一度取得された画像本体と、一度取得を要求して失敗した、という結果はボトルクライアント側でキャッシュを行います。したがって、全く同じゴースト名・サーフィス番号での要求が何度も繰り返し渡るようなことはありません。つまり、DLL側で特に画像自体をキャッシュするような機構は、必要はありません。
ただし、サーフィスプレビューの性質上、同じゴーストで違うサーフィス番号の画像の要求は、連続してたくさん来るのが通常ですので、そのような呼び出しに高速に対応できるような実装をすることが望まれます。
これは画像が見つからない場合も同様で、DLLの知らないゴーストの画像が要求される場合、知らないゴーストのいろいろなサーフィス番号の要求が連続してたくさん来ることになりますので、そのたびにファイルを検索する、といった実装をすると、速度低下の原因となります。