2^16を日本語に翻訳するときに誤植しているのだが、2^16と216では全然話が違うではないか!正直、一瞬、何のことかと思ったですよ。CreateDIBSectionとか、一番有用な関数は日本語化されてません。Windows95のときから備わっている関数の翻訳をするのに、何年待たす気なんでしょうか。して、そういうところで技術の差別化を図っているんかな〜とか思わずにはいられないです。DIBは、特に問題はないのですが、DirectDrawSurfaceは曲者であることに最近気づきました。32bppモードのとき、最上位バイトは何が入るのでしょうか?これは、α値が入っていることもあるし、ゴミが入っていることもあります。通常のBlt転送によっては、この部分に対しては関与しない。3Dのゲームで遊んでゴミが入ったまま、ということも当然ありうるのです。GDIでのピクセル操作::SetPixel(GetDC(),x,y);というようにしたときも、この最上位バイトには関与しません。ところが、DirectDrawSurfaceをLockすると話は変わるのです。そのままDWORDでゴミまで取得できてしまうのです。ビデオメモリに対してアクセスするのは非常に遅いので、それを我慢しながらぐりぐりと画像をいじっていたのですが、獲得したDWORDのデータに対して、抜き色ありの転送を実現するためには、このゴミが載ってくることを考慮して、カラーキーと比較するために、PixelFormatからRGBMaskを割り出し、そいつでマスクしたのちに比較しなければならないのです。これには、流石に頭に来た。あと、場所を指定してそのカラーキーを獲得するサンプルがDirectXのSDKにあるのをその昔、見た覚えがあるのですが、そう考えるとあれは間違っているのです。試しにSetPixelで(0,0)に点を打ち、サーフェースをLockしてその値を取得し、nBppでマスクするようなコードでは、いかんのです。言うまでもなく、PixelFormatからRGBMaskを割り出して、そいつとマスクしなければならないのです。最近のビデオカードだと、特にこの最上位バイトにはゴミが入っている可能性が高いので、要注意。困るなぁ(笑)というか、先日アップした雑誌用の体験版、εLOGINの編集から抜き色のバグが指摘されて、原因調べてたら、そういうことだった。これって、俺が悪いんか?...まあ、悪いんだろうな...。何にしてもDirectDrawSurfaceは、矩形転送ぐらいしかアドバンテージが無いくせに、何かと手間が掛かる奴である。氏はホームページではPentium用の飽和加算ルーチンを説明されています。パワープログラマですね。フルスクリーン動作していて、Alt+Tabでウィンドゥモードに切り替えられて、そこからアプリに復帰した場合、その復帰コードを書くのは容易ではない。前回の画像に対してエフェクトを掛けるようなトランジションを行なっている場合は特にそうである。Alt+Tabからの復帰は、普通、WM_ACTIVATEAPPに対して復帰させるのだが、マルチスレッドにして、ワーカースレッドがDirectDrawオブジェクトを構築し、フルスクリーンモードにしていると、このイベントはWindowsNT系では来ないのである。おまけにCreateWindowしたスレッドと違うスレッドがSetCooprativeLevelするあたりで、どうも、バグるようだ(2日ぐらいかかって調べたが詳しい原因はよくわからない。標準コントロールでもこれに似た制限に出くわしたことがあるので、たぶん、シングルスレッド時代からの遺産だろう。ロギングしてみたところ、WM_MOVEとWM_SIZEが来るあたりで、別スレッドでDirectDrawオブジェクトでBlt等を行なうと、内部の何かを破壊してしまって、それ以降メッセージが正常に来ないようだ。シングルスレッドに書き直したら、なんなく動いた。俺の3日間を返せ〜って感じ。Alt+Tabを禁止する方法は、ここにある。http://www.microsoft.com/JAPAN/support/kb/articles/J048/2/77.htmただ、Alt+Tabの禁止は、ユーザーアンフレンドリーと言わなければならないだろう。某大手流通の社長が、これを禁止しているソフトに対してたいへんお怒りだった。して、某大手流通から商用ソフトを出そうと思うとAlt+Tabは有効でなければならないという裏事情もあるのだ^^余談ではあるが、Windowsのスレッディングはかなり特殊である。ハードウェアマウスカーソルを消す、::ShowCursorしようと思っても、::ShowCursorは、ウィンドゥに対して行なうくせにHWNDを引数として取らない。やっているかというと、どうも、内部的には自分のProcessIDから、それに属するHWNDを検索しているようだ。::CreateWindowしたスレッドが::ShowCursorしないと意味がないのである。ついでに言えば、二重起動を防止するために、Mutexを使って、もし既存であることがわかったら、既に起動しているほうのウィンドゥをアクティブにして終了したいとする。::FindWindowでウィンドゥキャプションで探すのは、簡単だが、キャプションが変わる場合は使えない。);して自分のモジュール名と比較すれば良いように思える。これでは全然ダメなのである。HINSTANCEは、uniqueな(一意に定まる)ハンドルではないのである。実際に調べてみればわかると思うが、ほとんどのアプリのHINSTANCEは、0x4000000であって、自分のプロセス空間のなかで生活している。uniqueなハンドルではないわけで、そんなものを引数にとって、::GetModuleFileNameでは何が得られるというのだろう?そう。自分のプロセス空間におけるhInstanceの意味しかない。0x4000000を指定したところで自分のモジュールのファイル名しか得られない。なんたるダサい設計だろうか。よって、::GetWindowLongでHINSTANCEを取得する方法では手詰まりで、HWNDからウィンドゥクラス名を取得して、それが自分が::RegisterClassしたものと同じかどうかを比較するしか無い。なると別フォルダで動いていても同じ実行ファイルだと、ウィンドゥクラス名は同じなので、そちらがアクティブになる。これでいい場合もあるが、ygs2kのように、別のフォルダで動いているものは同じアプリケーションとは限らない場合は、大いに困る。ついでに設計思想からすれば、ウィンドゥクラス名はライブラリのうち、WindowClassが担うべきものであって、それを2重起動防止するためのクラスが知らなくてはならないのはいくぶん理不尽という話もある。(まあこれは、許せる範囲だが)実は、::GetWindowModuleFileNameという隠しAPIがある。winable.hで定義されていたと思うが、こいつを使えばHWNDからモジュール名が取得できる......と思わせきや、この関数も嘘を返すようだ。?ひょっとして、このヘッダー、winableではなくて、W_INABLE(不能)の意味ですか?(笑)ついでに言えば、ShowCursorは、結局ワーカースレッドからウィンドゥメッセージを送って(::SendMessage)、メッセージポンプ側で処理してもらうようにしたのだが、メッセージポンプ側が、WM_CLOSEするから、ワーカースレッドの終了を待機していると、ワーカースレッドからマウス描画のためにShowCursorする必要が生じて、::SendMessageを呼び出すものだから、::SendMessageでフリーズする。::SendMessageは内部的に、CriticalSectionのようなもので排他処理を行なっているから、WM_CLOSEから抜けないと、::SendMessageは処理できないのである。ところが、WM_CLOSEのなかでワーカースレッドがシグナル状態になる(=終了)を待っているので、そのままフリーズするという憂き目に逢着する。WM_CLOSEのなかで、ワーカースレッドがシグナル状態になるのを待たなければいいと言う話もあるが、突然::DestroyWindowされて、不正なhWndになったりするとそこでワーカースレッドは落ちるのである。窓が消滅するまでにワーカースレッドに終了を通知し、ワーカースレッドがシグナル状態になるのを待機する必要がある。このへん、手抜きして、メッセージポンプ側ではワーカースレッドに停止信号を送って、一定時間待ってそれでダメならば強制終了、という処理にする手もなくは無いが、危険極まりないのでちょっとやりたくない。いうことで、安易にメッセージポンプ+ワーカースレッドで行こうとするやねうらおのマルチスレッディングな設計は破綻したのであった。Windowsの腐ったAPI仕様からすれば、本来は、ワーカースレッドの要求に応じて、コールバックで処理してくれるような設計にしなくてはならないのだろう。あと、リソースごとに対するCriticalSectionは、かなりやっかい。それでマルチスレッドの恩恵にあやかれるかというと、そうでもないような気がする。描画するのにトリプルバッファリングして、メッセージポンプ側にも描画の手伝いをさせたりするのならともかく、本来、メッセージポンプで処理されるのは、それほどCPU負荷の高くない処理なのだから...。00/08/11ところで、以前にも書いたとおり、やねうらおは、いまだに携帯を持ちません。勝手なことを言うんですが、4和音の着メロなんていけてないと思うんです。あれは、すぐにPCMになります。数年もすれば、ヴァーチャルアイドルに音声合成で好きなメッセージをしゃべらせることが出来るようになります。あと、i−modeもじきにJavaが動くようになるだろうし、Palm系のOSが走る携帯電話が出ます。あと、すぐに世界各国の辞書や事典がオンラインで照会できるようになるでしょうし、ストリーミング再生技術によって携帯で、テレビだって見れるようになります。あと主婦とかが携帯持つと、折込広告も電子配信になります。折込広告が配信されるかわりに基本料金がタダの携帯も発売されます。あと恋人サーチとかも出来るようになります。自分のプロフィールを登録しておけば、恋人募集中の人から条件に合った人を見つけてくれるのです。GPSシステムを搭載して道案内してくれる機種も出ます。あとGPS+恋人探しでは、恋人登録をしている者同士が近づくと、音が鳴って知らせてくれるのです。それがまた大ブレイクします。(すべて何の根拠もありません。フェード機能がはたらきませんって言うのは、何なんでしょうか?確かにNT系では、直接CDのボリュームコントロールを行なうのは不可能だったような記憶はありますが、どうせ普通、CDのラインはサウンドカードに接続されているのですから、オーディオコントロールのボリュームミキシングで解決すればいいような気もします。yaneSDK2ndのCAudioMixerがそれです。byteで右シフトする命令は無いのです。何て直交性の無い命令セットなんや..そんな話をさ〜さんと話していると、packusdwが無いという話になりました。サチュレートするようなpackより、むしろサチュレートしないpackのほうが必要な機会は多いです。して、この命令付けとかへんかな〜。おまけに、某MMX解説本は、この存在しない命令(packusdw)をpack命令のサンプルとして挙げている。著者も無いとは思わなかったのだろうな〜。サチュレートしながらのpackが出来るならば、サチュレート無しのpackぐらい出来るだろう..と。誰だってそう思うだろう。そんな命令は無いのだ。このMMX本の著者にも同情する余地があります。ところで、L1キャッシュのこと考えてたんです。L1キャッシュからパージ(追い出)されると、データのアクセスは著しく遅くなります。L1にあるうちは、1clockノンウェイトでアクセスできるのに、そうでなければ、その何十倍も遅いことさえありえます。L1に入るかどうかがとても重要なファクターなのです。この、L1キャッシュ、仮に8kあるとします。これは、プロセッサ1個につき、8kです。いうことは、2つのアプリケーションを同時に走らせて、このL1キャッシュを奪い合ったなら、両方のアプリはどちらも、L1の恩恵にあやかれないというケースもありうるわけです。アプリケーションを2つ走らせると10倍遅くなる(?)Windowsの特性は、案外、そういったプロセッサレベルにまで立ち帰れば説明出来るのかも知れません。ーか、プロセスディスクリプタを用意して、各プロセスごとにL1キャッシュ自体を切り替えするわけにはいかない(いかなかった)のでしょうか...。00/08/19最近、やねうらおは働きすぎである。あの仕事とか、この仕事とか引き受けなきゃよかったとか、いろいろ思わなくもないが、いろいろ付き合いもあるのでそうも言ってられない。知人に頼まれて、コミケ用のCGビュアーを作ることになった。たいしたものではないので、yaneSDK2ndをもってすれば6時間もあれば完成するのだが、先日ホームページにアップしたCDIB32のサンプルがWin95では動かないことが発覚した。何が悪いのか調べていたのだが、わかったことは、第BD回でちらっと出てきた、winable.hをincludeしてあると、それだけで落ちる(「システムに装着されているデバイスは動作していません」というエラーが出る/Win95にはGetWindowModuleFileNameが存在しないのが原因。そもそもその関数は呼び出してもいないのに、落ちるのである^^)ことがわかった。いうか、それを突き止めるのに2時間ぐらいかかった。こんな怪しげなヘッダー、もう使わない(笑)そんなわけで、yaneSDK2ndにあるCDIB32のサンプルは、こっそりコンパイルして差し替えておくことにした。(ここに書いたら、全然こっそりじゃないという話はある^^)お約束ではあるが、ついでに指定したCGを壁紙化する関数を作らなくてはならない。Dr.GUIの連載見て、::SystemParametersInfo(SPI_SETDESKWALLPAPER,0,lpfile,SPIF_UPDATEINIFILE);と書いたのだが、これではIEのほうの壁紙は変更できない。考えたが、どうしていいのかさっぱりわからないので、Webを検索してまわったがまともに解説しているサイトは見当たらない。Explorer/General/Wallpaper/レジストリを直接いじるしか無いのだろうか...こういうことを考えていると息が詰まって仕方がない。息抜きにソースで顔文字を浮かび上がらせて遊ぼう。