「PC」カテゴリーアーカイブ

タスクバーのアイコンがちょっと変だったのはビデオカードのドライバが原因だった件


 最近はあまり聞かなくなりましたが、パソコンのトラブルで「アイコンの表示がおかしくなる」というトラブルが昔はよくありました。そんなときに定番になっていた解決法「アイコンキャッシュを削除する」、しかし今回は一筋縄ではいきませんでした。

 先日の事なのですが、Google Chromeで適当にWebブラウジングをしている最中に妙な違和感に気づきました。
よく見てみるとタスクバーのChromeのアイコンに妙な黒い影が出ているではありませんか。

chrome_weird_icon.png

 「え~。Chromeのアイコンって元々こんな感じだったかな・・・」なんて不安に思っていましたが、よく調べてみるとChromeだけではなく他のアプリケーションのアイコンも黒い影が付いている物がありました。さらには自作のアプリケーションのアイコンまで・・・。

どうやらセーフモードでは正常に表示されるっぽい

 アイコンが化けてるのかな・・・とりあえずアイコンキャッシュを消せば直るか・・・」と軽い気持ちでアイコンキャッシュを削除→セーフモードで再起動→黒い影消失→「ほれみろ! やっぱりキャッシュ消せば直ったじゃないか」と思ったのがそもそも勘違い。

 なんと通常モードで再起動すると、例の黒い影が再び現れるのです。

 さらに、よくよく見てみるとどうやらこの黒い影はアイコンデータに含まれるアルファチャンネルのデータっぽい。
本来なら指定されたアルファチャンネル値に従って半透明で描画されなければいけないところが、問答無用で真っ黒になってしまっている事に気づきました。

 私は最近インストールしたアプリケーションがアイコン描画のAPIに悪さをしてるのではないかと疑い、ここ最近インストールしたアプリケーションをすべてアンインストールしてみましたがやはり症状は改善しません。

原因はビデオカードのドライバでした

 「それにしても・・・セーフモードではアイコンがちゃんと描画されるのに通常モードで起動するとアイコンがおかしくなるのは気味が悪い・・・。
 そもそも通常モードで読み込まれてセーフモードで読み込まれない物って・・・、ビデオカードのドライバとか、そういう重要な物だよな・・・。」

 なんて考えていると、実は最近nVidiaのドライバをアップグレードしたことを思い出しました。
該当のバージョンは「266.58」。ひょっとしたらビデオカードのドライバが悪さをしているのかもしれない。
そう思って、アップグレードしたドライバを削除し、ビデオカードの付属のCDからドライバを入れ直してみたところ、あっさりと直りやがりました!!!

chrome_normal_icon.png
 ビデオカードに付属のドライバのバージョンは「257.21」 どうやら新しいバージョンのビデオカードのドライバがアイコン描画関係に悪さをしていたようです。
 しかしながら、あのときセーフモードで再起動をしていなければおそらくは気づかなかったでしょう。

 ビデオカードのドライバが画面表示のアクセラレーションの肝を握っている事は前々から知っていましたが、まさかアイコン表示にまで影響を及ぼしているとは知りませんでした。なにしろ私はアイコンのビットマップをアルファチャンネルを考慮しつつそのまま転送していると思っていましたので。

 それにしても、ドライバのどこをどういじくればこのようにアイコン表示においてアルファチャンネルが無視されるようなバグが出来るんでしょうか・・・。こういう部分はすでに枯れていてほぼメンテナンスなんてしないと思っていました。

 というわけで、画面表示に妙な違和感を感じる場合にはビデオカードのドライバを古い物に戻してやると直る可能性もなきにしもあらずです。

Process.Start()で起動したプロセスのメインウィンドウのハンドルが取得できない場合の対処法


 現在C#にて、以下のような仕様でプロセス間通信を行うアプリケーションを作っているのですが、プロセスAから起動したプロセスBのメインウィンドウのハンドルが取得できないという問題に遭遇しました。

  • ユーザーの操作でプロセスAがプロセスBを起動。
  • プロセスAはプロセスBのメインウィンドウにWM_COPYDATAを用いてデータを送信。
  • プロセスBはプロセスAから受けた指示に従って各種動作を行う。

 一番最初に書いたコードは、次のコードです。
このコードを実行すると、プロセスは起動できるのですがWaitForInputIdle()で起動したプロセスのメッセージループ突入まで待機しているにも関わらず、メインウィンドウのハンドルが取得できずに0が返って来ることがあります。

            //プロセスを生成する。
            Process p = new Process();
            p.StartInfo.FileName = appPath;
            p.StartInfo.Arguments = args;
            p.StartInfo.UseShellExecute = false;
 
            p.Start();
 
            //念のため待つ。
            p.WaitForInputIdle();

            // ウィンドウのハンドルを取得するのだが、
// IEや.NETアプリを立ち上げるとゼロになってしまう場合がある。
            IntPtr hMainWindow = p.MainWindowHandle;

 notepad.exeなどのシンプルなアプリケーションの場合には正しくウィンドウハンドルを取得できるのですが、Internet Explorerや自作の.NETアプリケーションの場合には0が返ってきます。

 どうやら挙動を詳しく調べてみると、一部のアプリケーションを起動した場合にはWaitForInputIdle()がきちんとWaitしてくれていないようで、メインウィンドウが生成される前にMainWindowHandleを取得してしまいゼロが取得されるようでした。

 おそらく一部のアプリケーションでは、ウィンドウ生成後メッセージループ突入という組み方がされていないためこのような現象が起こるのでは、と推測します。

 そこで、以下のようなコードを作成し再びテストを行ったところ、InternetExplorerや.NETアプリケーションを起動してもウィンドウハンドルを取得することができるようになりました。

            //プロセスを生成する。
            Process p = new Process();
            p.StartInfo.FileName = appPath;
            p.StartInfo.Arguments = args;
            p.StartInfo.UseShellExecute = false;
 
            p.Start();
 
            //念のため待つ。
            p.WaitForInputIdle();
 
            //ウィンドウハンドルが取得できるか、
//生成したプロセスが終了するまで待ってみる。
            while (p.MainWindowHandle == IntPtr.Zero && 
p.HasExited == false)
            {
                System.Threading.Thread.Sleep(1);
                p.Refresh();
            }
 
            // hMainWindow != IntPtr.Zeroの場合にはウィンドウハンドルを
//取得できたと思われる。
            IntPtr hMainWindow = p.MainWindowHandle;

 このコードでは、WaitForInputIdle();で念のためメッセージループの開始を待った後に、さらに、本当にウィンドウハンドルが取得できたかどうかをチェックし、取得できるまでループを回す、という事を行っています。

 その際に、起動したプロセスが異常終了した時の事も考慮し、プロセスが終了してしまった場合にはループを抜けるようにしています。

 今のところはこのやり方で、メインウィンドウのハンドルは取得できています。

 ただしこのコードにはタイムアウト処理が入っていません。もし起動したプロセスがなんらかの原因でウィンドウの生成に失敗した場合、起動元のプロセスがフリーズしてしまいますので、実際にはタイムアウト処理も入れた方が良いでしょう。

 さらに.NET Frameworkのドキュメントによりますと、Windows Formで生成したフォームのウィンドウハンドルはフォームの有効期間中に不変であるという保証はないそうです。(ShowInTaskbarプロパティを操作すると変わったりするようです) 従って、ウィンドウハンドルを取得しそこへウィンドウメッセージを送るという方式でプロセス間通信を実現する場合には、取得したメインウィンドウのハンドルを保持しておくのではなく、メッセージ送信前に取得しなおしておいたほうが確実かもしれません。

Windows Live Messenger 2009をWindows Server 2003にインストールする方法


今朝起きたところ「Windows Live Messengerの新しいバージョンを入れろゴルァ!」という警告が出ていて、どうやら断るとサインイン出来ない事がわかったので、なんとか私の開発マシン(Windows Server 2003)にインストールべく試行錯誤しました。

そしたらあっさりと完了。

用意する物

手順

1.Resource HackerでWindows Live 2009のインストーラ(wlsetup_all.exe)を開きます。
2.左のペインからCONFIG → CONFIG0 → 0を順に辿ります。
3.次のような画面が表示されるはず。

resourcehack1.png

4.右側のデータ部分に以下のXMLをコピペで上書きし、「スクリプトをコンパイル」ボタンをクリックした後、上書き保存。

5.大威張りでwlsetup_all.exeを開き、インストールを行います。

注意:開発元のマイクロソフトはWindows Server 2003での動作を保証していません。この方法を試して何らかの損害を被ったとしても当方では責任を負いかねますので、自己責任でお願いします。

「新世紀エヴァンゲリオン~約束の時~」のオンラインシミュレータを公開しました。


Eva3OnlineSimulator.png

 前回のデスクトップアプリケーション版のリリースに引き続き、Webアプリケーション版のシミュレータも公開しました。これで、ちょっとしたシミュレーションならわざわざデスクトップアプリケーション版をダウンロードしなくともWebブラウザから試してみることができます。

 サーバー負荷の関係から、成立役履歴の詳細表示が無い、シミュレート可能なゲーム数は10,000ゲームまで、という制限はありますが、その他の機能はデスクトップアプリケーション版と全く同じです。

 しかしながらシミュレーションの実行はサーバーに負荷がかかりますので、繰り返し何度もシミュレーションを行いたい方や、大量のシミュレーションを行いたい方はデスクトップアプリケーション版をダウンロードしてください。よろしくお願いします。

デスクトップアプリケーション版のダウンロードはこちら

エヴァンゲリオン~約束の時~のシミュレータをリリースしました。


Eva3Simulator_Screenshot.png

 以前のエントリでも少しだけお知らせしていた新作のシミュレータですが、この度ようやくリリースすることができました。

 以前のエントリに書いた「機械割が割と高く、判別要素もあり、なおかつバケを引くとガッカリする某人気機種」とは「新世紀エヴァンゲリオン~約束の時~」の事でした。

 主な特徴といたしましては、Slotware製のソフトウェアではお馴染みのデータ表示機能やスランプグラフ機能は勿論のこと、以下の機能を搭載しています。

実機を忠実に再現した42種類の抽選テーブル

flagview.png 実機を忠実に再現した7種類の抽選テーブル(通常、黄7 or 青7成立中、赤7 or REG成立中、天井、暴走、覚醒、ボーナス中)を各設定毎に6セット、合計42種類搭載しています。

 これによって、スイカやチェリーの後のリプレイの連続による「もしや入った!?」という状態もきちんとシミュレート。

 当然ボーナス中の小役確率も設定毎に異なります。
さらにグラフィカルで見やすくなったシミュレーション結果の表示

SimResult.png
 シミュレーション結果にはボーナス回数の他に、設定推測には必須である小役出現率も同時に表示します。さらにスイカとチェリーの合算、およびスイカとチェリー、ベルの3役の合算も表示します。

100ゲーム毎のレア小役およびベルのカウントおよび集計機能

koyakucounter_all.png

 さらにそれだけではありません。Eva3
Simulatorは100ゲーム毎に小役が何回出現したか、さらに累計出現回数と出現確率も表示します。実際にこの台を打つ方はこまめに小役を数えてい
ると思いますが(私も100G毎の小役回数をメモしながら打っています)、その機能もシミュレータに搭載しました。

 実際にこの機能を使って頂くとわかりますが、3000ゲーム程度でもまだ小役の出現率に大きなブレがあるということがわかると思います。

 このソフトウェアが皆様のパチスロの立ち回りに役立てる事を願っています。
ダウンロードはEva3 Simulatorのページから可能ですので、ぜひお試し下さい。

Visual Studio 2005の「最近使ったプロジェクト」一覧から不要な項目を削除するツールを公開しました。


 ご存じの通り、Visual Studio 2005のスタートページには「最近使ったプロジェクト」という一覧が表示されていまして、読んで字の如く最近使ったプロジェクトを素早く開くことが出来るのですが、時としてもう使わないような古いプロジェクトや既にディスクから消えてしまったり別の場所に移動してしまったプロジェクトなども延々と居座り続けて不愉快極まりない事があります。

 存在しないプロジェクトに関しては、一覧からそのプロジェクトをクリックすることにより削除しても良いかどうかの確認が表示され、消すことができるのですが、これが大量にあると実に面倒くさい。

 わたしもこの問題に常日頃悩まされ続けていまして、そういう不便を一発で解消するツールは無いものかと探していたのですが、無かったので作っちゃいました。

 さらに、海外でも同様の問題にアタマを抱えている人がたくさんいることを知りましたので、同時に英語版ページもこしらえました。

VS2005 MRU Cleaner

VS2005 MRU Cleaner (English Page)

というか・・・・このエントリを書いてて気づきました。
「無かったので作っちゃいました。」なんて書きましたが、既にもっと出来の良い物を作って公開していらっしゃる方を発見!

あーあ。
車輪の再発明しちゃった・・・。

ネオジオのスプライトデータを覗いたり編集したりするツールを開発中


お久しぶりです。

ここ数日はプログラミングに勤しんでおりました。
といっても、パチスロのシミュレーションツールではなく、別なツールです。

その名も

「ネオジオのスプライトデータを覗いたり編集したりするツール」(仮名)

NeoSpriteDecoder.png

最近は”NeoDev”というツールキットがあるようで、(https://arcadedev.emuvibes.com/参照)、C言語を使ってネオジオのソフトを自作できるらしいのです。これには私もものすごく興味があるのですが、残念ながらグラフィックツールやサウンドツールが無い。コンバーターの類は発見できたのですが、直接編集できるツールがまだ無いっぽいのです。

そこで、自作することを決意しました。

ネオジオのROMカセットには、用途別にP-ROM、C-ROM、V-ROM、S-ROM、M-ROMが搭載されています。このうちP-ROMには68000CPUで実行されるゲームのプログラム、C-ROMにはゲームで利用されるスプライトデータが格納されています。

このツールはC-ROMに格納されているスプライトデータをのぞき見ることができます。
編集機能はまだ搭載していませんが、データの仕様はわかったのでいずれは編集機能もつけたいところであります。

しかしながら、スプライトデータの解析に丸一日かかってしまいました。
というのも、そのへんに転がっている資料を探せば見つかるだろう、と甘く見ていたのですが、どこにもC-ROMに関する資料がない! 
しょうがなく、わかっている情報から手探りで解析することに……。

ネオジオのスプライトは、スプライト一つにつき16色が使えますので、4BPPであります。つまり、1バイトに2ピクセル分の情報が格納されていることになります。
そして、ネオジオのスプライトひとつの基本サイズは16×16ピクセル。
すなわち、スプライト一つにつき128バイト、ということになります。

チャン・コーハンやアースクェイクのような巨大なキャラクターも、複数のスプライトを組み合わせて表現されています。それどころか、ゲームの背景画もスプライトです。

つまり、ゲーム中は大量のスプライトが画面で動き回っていることになります。
それでも、たくさんのスプライトを管理するとなるとプログラムが複雑になったり、処理落ちが発生するかもしれません。

しかしながらここがネオジオのすごいところで、ネオジオのVDPには「複数のスプライトを合体させてあたかも一つの巨大なスプライトとして扱う」機能が付いています。このおかげで格闘ゲームなどの開発がやりやすかったのでしょう。

さて、話をスプライトデータにもどしましょう。スプライトは4bppで表現されていることから、データはMSXのSCREEN 5みたいな形式で格納されているのだろう、と読んでいたのですが、甘かった。 

解析してみてわかったのですが、ネオジオのスプライトはものすごくひねくれた形式で格納されています。4bppなのは間違いないのですが、本当にヒネクレてます。MSXのSCREEN 5、というよりは、SCREEN 2が4層重なったような形式になっています。

そして、基本的に一つのスプライトは二つのROMにまたがって格納されています。

なぜこんな仕様なのかはわかりませんが、おそらく当時のVDPで巨大なスプライトを大量に動かすにはメモリインターリーブのようなことをせざるを得なかったのでは? と予想しています。

この辺で得たノウハウは、後々資料として公開しようかと。

それで、この数日間でとりあえずなんとか中身を覗くところまでできました。
しかもC#で書いたのにもかかわらずとても軽快に動作します。

あとはやっぱり編集機能を付けたいですね。

しっかし・・・プログラミングはそれほどではなかったけれども、解析はものすごく疲れた(汗

C#からWebBrowserコントロールを使ってみる


さて今日はプログラミングな話です。C#でIEコントロールをいじくってみます。

詳細はまだ明かせないのですが、現在C#で簡単なチャットプログラムを作成しておりまして、会話のログ表示部分にIEコンポーネント(WebBrowserコントロール)を使ってみようということにしました。私の確認する限りでは米国版のYahooメッセンジャーもこの方式が使われていて、会話ログの中にYouTubeの動画を埋め込むことができたりと、かなり強力です。

そこで今日はチャットプログラムでIEコンポーネントを効率よく使う方法についていろいろと自習をしていました。

続きを読む C#からWebBrowserコントロールを使ってみる

Visual Studio 2005で作成したはずのユーザーコントロールがツールボックスから消失した際の対処法


Visual Studio 2005で、ユーザーコントロールを作成しビルドするとツールボックス内に自動的に追加されますが、何かの拍子にツールボックスから消えてしまうことがあります。
私も開発中に何度か経験して非常に困りましたのでメモ的に書き残しておきます。

  1. ソリューションエクスプローラから消えてしまったユーザーコントロールを含むプロジェクトを一度削除します。
  2. 再びソリューションエクスプローラから該当プロジェクトを追加します。(この時点でツールボックスにユーザーコントロールが復活するはずです)
  3. ソリューションからプロジェクトを削除すると、他のプロジェクトの参照設定から削除したプロジェクトが自動的に外されるので、それらを手動で設定しなおします。(プロジェクトが多数あるとこれがめんどくさい)