‘プログラミング’のエントリ

WPFでボタンをデザイン。C++MFCだとオーナードローでこんなボタンを作ったらそれだけで数日はかかりそうだが,C#+WPF+Expression Blendなら慣れれば1時間くらいでできそう。今までめんどくさくてUIに凝ることもなかったが,これだけの開発環境を用意されるとUI作るのが楽しくなってくる。

2010042001


ちなみに作り方をメモっておく。Expression Blendで普通のボタンを作ってテンプレートの編集。ボタンの中身をごっそり削除して,Ellipseを配置してグラデーションをいい感じに設定。中身にcontaintPresenterをはりつけておく。ここまででデザインは完了。これだとボタンを押しても見た目が変わらないので,トリガータブの「+プロパティ」でIsPressedとかIsMouseOverとか必要なものを追加して,デザインを適当にいじるとイベントが起きたときに差分が適用されるようになる。ここまででスタイル作成完了。Mainのウィンドウに戻って今作ったスタイルをボタンのStyleとして設定。最後にボタンの中身にExpression Designとかで作った絵を貼り付けて完成。

2010042002


ついでにツールチップも付けてみた。色合いを変えて半透明にするためにStyleを変更してみたが,以下のようなコードを書くと,Expression Blendで編集する際に「’ToolTip’は,論理親またはビジュアル親を持つことができません。」というエラーになる。Expression Blendで編集できないだけでVisual Studio 2010ではビルドできて普通に動くのだが,これでいいのだろうか。

2010042003

<ResourceDictionary>
    <Style x:Key="Tip" TargetType="{x:Type ToolTip}">
        <Setter Property="Background" Value="#202020"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Opacity" Value="0.8"/>
    </Style>
</ResourceDictionary>
----
<Window>
    <Button Style="{DynamicResource PanelButton}">
        <Button.ToolTip><ToolTip Style="{DynamicResource Tip}">次のページ</ToolTip></Button.ToolTip>
            <Canvas Width="16" Height="16" Background="{DynamicResource NextButton}"/"
    </Button>
</Window>
		

Visual Studio 2010がリリースされたので会社を休んでインストールしてみた。これでようやく作ったものを配布できる。って言っても配布するものがないけど。

で最近はずっとC#でWPF開発をしているが,WPFの考えが面白くて,開発と言うより勉強しかしてない。

MIDIの楽譜化が少しずつできてきた。今こんな感じ。ホントはもっときれいな楽譜もあるのだが,著作権うんぬんがあるので,自作曲の手入力MIDIのサンプル。

20100318

今の自分のPCの解像度が1920×1200なのだが,それに合わせて作っているので,解像度が低いと見にくい。一応ベクタグラフィックなのでそれなりに縮小できるがやっぱり限界がある感じ。ぱじさんが「最近の画面解像度の統計あるよ」って言ってたので見せてもらったところ,1024×768が堂々の1位! ってマジですか。Windows 3.1の頃に一般的だった解像度なんですが・・・。

 


ぱじさんの「人喰い掲示板の噂」はなかなか進んでないっぽい。

発売したときから気になっていたC Magazine CompleteのDVD。199冊分の雑誌がDVD 1枚に入って定価55000円。一見高いように見えるが199冊分なので実はそうでもない。のか? 入手困難になる前にとりあえず買ってみた。BASIC マガジン Completeだったら倍の値段でも即買うんだけど・・・。

最初の方からコラム中心に読み直していってるけどNifty全盛時代って感じで懐かしい。

Visual Studio 2010 RC版公開。とりあえずダウンロードして明日いじってみよう。

楽譜表示。何度も作り替えているが,結局WPFで作ることに。ベクターグラフィックをそのまま使えるので拡大縮小しても綺麗なままというのがいい。2000だと動かない,XPだと汚くなるとかあるけど,もはやVista以降前提でもいいですよね,ってことで。

休み中ずっとWPFをいじっていた。C#のインテリセンス具合とかベクタグラフィックを直接扱えるのとかいい感じ。

MSDN更新案内がくる。「今ならITバリューアップキャンペーンでお徳! 今すぐここにアクセス!」とかいう怪しいDMが入っていたので騙されて申し込んでみた。今までProfessionalだったのが,Premiumに変わって年間換算で+2万くらい。これでOfficeもExpressionもServer類も手に入るってことで。Visual Studio 2010が出ればTeam Foundation Serverも付いてくるらしいのでお徳,なのか? 今まで個人でPremium入ってた人はあんまりいないような気がするがこのキャンペーンで結構増えるような気がしないでもない。

Visual Studio 2010で遊んでいるのだが,C++0xに一部対応ってことでいろいろ面白いことができるようになっている。個人的にはクロージャのサポートとか正規表現の標準ライブラリ化とかメルセンヌツイスターの乱数発生とかが嬉しいところ。

なんかC++もC#もJavaもお互いに機能を取り入れまくっていて,よく似た言語が3つできあがっているだけのような気が・・・。それでいてヌルポはnullじゃなくてnullptrになってたりして意味が分からない。

# と思ったらregexなんかはVS2008 SP1からあるんですね。SPで機能が追加されるとは・・・。

しばらくどのソフトも公式リリースはなさそうなのでVisual Studio 2010β2に移行してみた。WPFベースでデザイン一新に見えて色変わっただけ? みたいな。C++のインテリセンスとか編集中に波線が付くとかC#のインテリセンスに少しだけ近づいた感じか。ところでF#って何ですか?

楽譜描画。今までウェザタイ同様,DirectDrawで音符の画像を作って描画していたのだが,それだと連符や連桁の斜め線を描画するのが難しい。角度とか…。で,試しにGetDCしてGDIで描画してみたのだが,やっぱり線がギザギザして格好悪い。何かいい方法ないかなあ,ってことでいろいろ探した結果,DirectGraphics 9のID3DXLineを使うことにした。ID3DXLineにはアンチエイリアシング機能があるので良い感じの線を描ける。

で,これを使うにはDirectDrawベースじゃなくてDirect3Dベースにする必要があり大改造なのだが,こんなこともあろうかと描画ロジックを分離して作っていたおかげで2D→3Dへの移行は案外すんなり完了。結局DirectDrawのBltFastを使う描画ロジックとDirect3DのID3DXSpriteを使う描画ロジックを切り替えられるようになった。

これをウェザタイに逆輸入すればウェザタイ3D版ができていろいろなエフェクトが使えるわけだが,今更やろうとは思わないだろうなあ。

「テトリスを1時間強で作ってみた」動画が面白かった。「弾いてみた」とか「描いてみた」とかを見てるとそればっかりやってる人はやっぱりすごいんですね的なことがよく分かるので,誰かプログラマバージョン作らないかなあ,とか思ってたので興味深い。この,ちょっと作って動かして,を繰り返して段々形ができていく面白さがちゃんと伝わるようになっているのがいいですね。

現在メインマシンはWindows 7英語版なのだが,ウェザタイのオプション画面を開くと明らかに日本語版とデザインが違う。何でか不思議だったが,とりあえず原因判明。プロパティシートは,外側(フレームとタブ)と内側(ラベルとかがあるところ)で分かれているが,外側はWindowsが持ってるダイアログテンプレートをベースにしているのでシステムフォントになり,内側はリソースエディタで設定したフォントになり,食い違っている。例えば外側は英語版ではMS Shell Dlg,日本語版ではMS UI Gothicになったりするわけで,当然DLUが変わり,フレームの大きさが中身に比べて小さすぎたり大きすぎたりすることになる。

プロパティシートのコールバックでPSCB_PRECREATEを受け取ったときにダイアログテンプレートのフォント名をメモリ上で無理矢理書き換えればフォントを変えられそうだが,フォント名が同じ長さじゃないとダメだったりするし,今のところ解決策なし。

Weather Typing,World TesterをWindows 7で評価。評価結果は問題なかったのでそれぞれのページの対象OSにWindows 7を追加した。が,評価していてWeather Typingのバグを発見し,結局Ver. 2.2.2にリビジョンアップ。修正したのは以下の3つ。3つ目は以前掲示板でzaqさんから報告があった件。

  • リプレイファイルを拡張子に関連づけて起動すると,WeatherTypingの設定が初期化される問題を修正
  • ロビー,2回目に起動すると初回起動時のチャットログファイルが「_old」にリネームされてしまう問題を修正
  • ロビー,ファイル選択ダイアログを開いていると,チャットログがダイアログで開いているパスからの相対パスに出力される問題を修正

今回,検証にVMWareを使ってみた。World Testerの検証にはDirect3Dが必要なのでVirtualPCではダメ。てことでDirect3DをサポートしたVMWare6.5を使ったわけだが,それなりに動いた。WDDMではないのでAeroは動かないが検証には十分使える感じ。Aeroサポートという噂のVMWare7からは本格的に使ってみようかな。

で,今後旧OSの環境を作ったときにWindows Updateが終了してたら困るので,Windows Server 2008 R2にWSUS 3.0 SP2を入れてみた。2000/XP/2003/Vista/2008/7の全てのセキュリティアップデートと重要な更新をダウンロードしたらだいたい9GB程度。このくらいなら持っておいてもいいか,って感じ。

最近MIDIファイルの読み込みと再生を実装していたのだが,ウェザタイと同じように,60fpsごとにそれまでに出さなければならなかった音を出すという形にするとかなり重い。これに描画とMIDI inの処理を入れると相当なスペックを要求するソフトになってしまう。普通のMIDIプレイヤーってどうやってるんだろう。

で,MIDIファイル読み込みはだいたいできたので,とりあえずいろんなMIDIファイルを入力してみたが,どうしても解析に失敗するMIDIファイルがある。調べてみるとどうもメタイベントのあと,メタイベントの前のランニングステータスを引き継ぐ前提で作られているらしい。つまり1.MIDIイベント-2.メタイベント-3.MIDIイベントで,3の部分で1のランニングステータスを引き継いでいる。MIDIファイルの規格書を見てみても「メタイベントはランニングステータスをキャンセルするしランニングステータスは適用されない」としか書いてないのでどっちだかいまいち分からない。まあそういうシーケンサがあるんだから対応しろってことだろうけど。

物理の時もそうだったけど,勉強しながら開発するから進みが遅い。もう少し形ができてきたら,音楽に詳しいはっぱさんやまっちーさんに協力を依頼するかな。

一応流し読みしているタイピングスレで出ていたのだが,Weather TypingでJISかなを選んでいると「ヵヶヮ」が打てないという話。全然気付かなかった・・・。でもかな入力の仕様的に直すのは無理なんじゃないのか。とりあえず他にないか探してみよう。

地道にARToolkit。ARToolkitでドミノ倒しを動かすために,描画エンジンをOpenGLからDirectXに変える作業を行っていた。これでxファイルを自由に読み込んだり既存のソースを使い回しできる。この辺は既にいろんな人がやっているので今更感はあるけど,ARToolkitの元論文を読んでみたり座標系の違いに苦労しながらもこんな感じのところまではいった。

2008112401

# とりあえずウェザタイの静止画をはめこんでいるだけでゲームができる訳じゃない。やろうと思えばウェザタイ自身も空中で動かせるのかな。

ここまでくればリアル指で仮想ドミノ倒しをいじるってのもすぐできそう。

今更だがARToolkitを試してみる。これはWebカメラで撮影した画像に3次元CGをリアルタイム合成する技術。下のカメラはWebカメラ2台で撮影した画像に,立方体を重ねた画像。交差法で見ると立体に見えるはず。2台同時だとさすがに重いけどリアルタイムな動画で動いていて,紙を動かせばちゃんと立方体も動く。こんな感じでカメラ2台とヘッドマウントディスプレイを使えば,外部を撮影した画像にいろんな物体を合成して見ることができるわけで。あとは擬似的に触ることができて人工知能ができてブレインマシンインターフェースができてヒゲができれば,電脳コイルになりますね。とりあえずこれとWorld Testerを使って面白いことができないか考えているところ。

#っていってもGPLらしいからその辺をどうしようってのも考えないと。

2008110301


ARToolkitをVisual Studio 2008 SP1 + Windows SDK for Windows Server 2008 and .NET Framework 3.5でビルドする方法。多分ちゃんとした方法じゃないしちゃんとまとめてないけど自分用メモってことで。

  • ARToolkit,DSVL,GLUTをダウンロード
  • GLUTをビルド。glut32.libをライブラリパスに入れる。特に困ることはなかったけど,/MT /MTdを/MD /MDdに変更したような気もする。DSVLの方だったかな。
  • Program FilesMicrosoft SDKsWindowsv6.1SamplesMultimediaDirectShowBaseClassesをビルド。インクルードパスに同フォルダを追加し,strmbase.libをライブラリパスに入れる。インクルードパスについてはPlatform SDKより優先させること。
  • DSVLextlibtinyxmlをビルド。/MT /MTdを/MD /MDdに変更しておく。tinyxml_STL.libをライブラリパスに入れる。
  • DSVLのインポートライブラリにcomsuppw.libを追加。さらにDbgOutStringがないといわれるのでコメントアウト。デバッグ用だし1行しかないしめんどいのでコメントにしてしまった。DSVLをビルドし,DSVL.libをライブラリパスに入れる。
  • ARToolkitをビルド。
  • DSVL.dll,glut32.dllをパスの通ったところにおいてサンプルsimpleTest.exeをおもむろに実行。
  • とりあえず「DSVL_GraphManager::SampleCB」で落ちるのでちょっと修正しておく。
    iter = iter2;
    // 追加開始
    if(iter == mb.end())
    {
        break;
    }
    // 追加終了
    

今週末はお引っ越し。今の場所から歩いて5分くらいのところ。てことで今まで持ってなかった電化製品とか家具を買っている。あとはベッドだけなのだが,玄関のところがちょっと狭いので入るのかなあ,と心配に。で,シミュレーションしてみた。

2008092401

白いのがマットレス。木目なのがドアとか廊下の仕切りですね。ちなみにベッドは通常組み立て式なのでマットレスさえ入れば搬入OK。実験結果は「余裕で入る」ってことに。いや,まあ「ドアの幅+廊下の幅」が「マットレスの長さ」以内なら入るのは分かってるんだけど,World Testerを使えばこんなシミュレーションも簡単にできるよ,みたいな。

ぱじさんと進めているプロジェクトが大詰め。塗り絵をしたり掲示板をメンテしたり。内容に関してはまだ公開できないので日記に書くことがない。結局8月はほとんど何も書いてないや。

掲示板に挙がっているが,第1ロビーサーバが1時くらい,第2ロビーサーバが6時くらいに止まったようだ。第1ロビーサーバはプログラムがフリーズしていたっぽい。今まで見たことないケース。第2サーバは,管理人にメールを出してみたが,しばらくは止まってるかも。

ロビーサーバが12時くらいから24時くらいまで落ちていた。原因はPC電源断。ロビーは諸事情で自動起動にはなっていないので,PCは起動してもロビーは起動されない。

とりあえず第2ロビーサーバを使用できるので大丈夫かとは思う。って第2ロビーサーバって知られているのだろうか。ロビー起動時に,コンボボックスを開くとサーバが2つ出てくるので,1つ目が落ちていて入れない場合,2つ目のを使用してみて下さい。

WeatherTyping2.2.1を公開。プレイヤー名などで「[]」を使うと設定が壊れる件の修正のみ。特に困っていなければダウンロードの必要はありません。

掲示板に出ているバグ。iniファイル読み込みクラスがバグっていて,値の中に「[」「]」が存在するとセクション名だと思っておかしくなってしまう。なんて基本的な。ていっても10年くらい前から使ってるソースだし他にもいろいろなところで使われている気がする。今更こんなバグが見つかるのかぁ,という感じ。さくらの人(誰)まだ使ってたら直しておいて下さい。

ネットで,走っているトラックの荷台に,ほぼ同じ速度で車が乗り込んだらどうなるか,という議論が載っていたので考えてみる。つまり高速道路で走行中,車をトラックに格納するようなシチュエーションである。一見,荷台に載った瞬間急加速して前の壁にぶつかりそうに思ってしまう。でもよく考えると,乗り込んだ瞬間,乗り込んだ車のスピードメータがほぼ0になって,あとは(乗り込んだ車の速度 – トラックの速度)分だけ減速すればOK,って感じになりそう。でいいのかな。乗り込んだ瞬間にタイヤの回転がピタっと止まるわけで,前輪駆動とか後輪駆動とか考えると難しい話になるけど。

いろいろ想像してみると,動く歩道に乗った時が思い浮かんだので実験してみた。動く歩道に乗り込む場合,動く歩道と同じスピードで乗り込むと,乗り込んだ瞬間速度が0になって,(動く歩道に対して)元の速度まで戻そうとするとそれなりに力がいる。

てなわけで,World Testerでビー玉を転がして,動いている板に乗せる実験をしてみた。結局,板に乗る前は普通に回転しているが,板に乗った瞬間回転がほぼ止まって,板を追い越すと再び回転が始まる。物理シミュレーションならこんな実験を手軽に試せる,ていう例。というかこんな実験ならリアル世界で試せよ,っていう例でもある。

# 実際は,World Testerだと板と地面の摩擦があるのでうまくいかない。上記はプログラム的に板と地面の摩擦を0にして動く歩道をシミュレーションした。

Weather Typing 2.2公開。追加機能はほとんどなくて,現在分かっているバグをたくさん直したバージョンという感じ。

Weather Typing 2.2のプログラムテストが完了。あとはトータルテストが終われば公開可能。今公開している開発版でいろいろバグが見つかった。特に大きいのはWindows 2000とWindows XP SP2なしで動作しないことか。今回,IPv6対応のためにGetAddrInfoW関数を使ったのだが,Windows XP SP2以降とWindows Vistaでしか使えない。いっそWindows2000をサポート外にするかとも考えたが,さすがに厳しいので直しておいた。

掲示板に来ている,設定が読み込めないというのが気になるが…。

Silverlightで通信ができないというメールが来た。どうやらSilverlight 2 Beta 1からBeta 2になったときに仕様が変わったとのこと。ローカルPCにSilverlightのコンテンツを置いておいてローカルPC上のサーバにアクセスする際にも,クロスドメインポリシーを考慮しなければならなくなったらしい。どこがクロスだよ,って気もするけど。

早速実験してみる。Silverlight Tools Beta 2を入れる場合,Beta 1のアンインストールが必要なのだが,普通にアンインストールしただけではだめで,更新プログラムの一覧からKB949325を直接消さないといけないというのにはまりつつ,インストール完了。微妙にWatermarkedTextBoxが消えてたりするのに困りつつ実験開始。

確かに以前と同じコードでSocket通信すると,AccessDeniedになってしまう。ということでクロスドメインポリシーサーバをたててみる。FlashのSocket通信のときに同じようなことをやってたのでほぼ流用。ポート943で,「<policy-file-request/>」という文字列を受信したら以下のような文字列を送信するサーバをたてればOK。許可ドメインはちゃんと絞り込まないといけないけど。

<?xml version="1.0" encoding ="utf-8"?>
<access-policy>
 <cross-domain-access>
  <policy>
   <allow-from>
    <domain uri="*" />
   </allow-from>
   <grant-to>
    <socket-resource port="4502" protocol="tcp" />
   </grant-to>
  </policy>
 </cross-domain-access>
</access-policy>

結局,Socket通信は以下のような感じになる。

  1. Silverlightクライアントからサーバの943ポートへ,フレームワークが勝手に「<policy-file-request/>」を送信する
  2. サーバの943ポートからSilverlightクライアントへ,クロスドメインポリシーを返信する
  3. Silverlightクライアントからサーバの4502-4532ポートへ通信

ロビーでSJIS以外の文字を使えるようにしていろんな文字が使われていたが,どうも変な文字が入るとGulimフォントなど(Vistaの場合)になってしまう。いろいろ実験してみると,VistaのWordPad(RichEdit 5.0)では,デフォルトのフォントをメイリオにしているとちゃんと変な文字もメイリオになるが,RichEdit 2.0だとGulimフォントなどになってしまってメイリオに変更してもフォントが変わらない。とりあえず致命的なわけでもないのでしばらくはこのままか。


ウェザタイのIPv6実験は成功。今のままでも,例えばVista-Vistaで対戦をするとIPv6アドレスで対戦ができる。これで通信部分を作り直す必要はなくなった。


ロビーに入り浸っていると,どうも対戦中に落ちる現象があるらしい。ちょっと調べてみて怪しい部分を修正。文字コードを変換するとき,変換前にいちいちsetlocaleして変換後にsetlocaleを戻していたのだが,そのあたりで落ちる。前のノートの時は起きてなかった気がするのでマルチコアで起きやすいのかも知れない。とりあえずsetlocaleはデフォルトでは全スレッドに効くので,プロセス起動時に行うようにしたら落ちなくなった。

Weather Typingの開発版をこっそり公開。経緯としては,掲示板に報告があがっている問題の対応が発端。掲示板に挙がっている問題は,NICOLAで高速打鍵が誤入力になってしまうというもので,右親指キーを使った入力から左親指キーを使った入力を高速に行うと,ミスになってしまう。これのせいでNICOLAでの入力が遅くなってしまう方も多いだろうということで急遽開発版を公開することにした。

注意点は以下の通り。

  • 公式版とは違いちゃんとしたテストはしていません。最悪の場合,スコア等が消えてしまう可能性があるので,必ず旧バージョンのWeatherTypingフォルダごとバックアップをとっておいてください。
  • 旧バージョンからバージョンアップする場合,旧バージョンのフォルダに新バージョンのファイルを上書きすることで,旧バージョンの設定を引き継ぎます。
  • 旧バージョンからバージョンアップする場合,既にその日のロビーチャットログがあれば,リネームしておいて下さい。(例:2008/6/8ならchat20080608.logをリネーム)リネームしない場合,バージョンアップした日のチャットログだけ文字化けします。

修正点は以下の通り。

  • ファイルオープンダイアログをXP/Vista標準のものに変更
  • アイコンを変更
  • 対戦開始時のプレイヤー情報表示画面で,IPアドレス表示部分にIPv6のアドレスも表示する
  • 右親指キーを使った入力から左親指キーを使った入力を高速に行うと,ミスになってしまうのを修正
  • スコアファイル名を変更した場合,スコアアップロードとロビーのレベル表示で正しいスコアファイルが使われないのを修正
  • CPU入力方式とPlayerの入力方式が同期しなくなる場合があるのを修正
  • 対戦の接続待ちの際,途中でエラーが発生しても待機し続けていたのをエラーメッセージを表示するように変更
  • ロビー。SJIS以外の文字を使えるようにする。但し旧バージョンのロビークライアントからは見えないので注意
  • ロビー。チャットのログファイルをUnicodeに変更

DirectPlayのヘルプを見ていると,どうもDirectPlayは9からIPv6をサポートしていることが判明。Weather Typingでも今のままでIpv6に対応できている。ような気がする。検証中。

ぱじさんのプロジェクトに対応して,ロビーサーバをほぼ作り直した。ユーザ関連をデータベースを使用するようにしたのと,永久部屋とかもろもろ。大分コードもすっきりした感じ。しばらくテストしたらウェザタイのロビーサーバを更新してみよう。