サイクリック
いまは夜!
というわけで久しぶりの因数分解です。
覚えていますか、因数分解。愛・おぼえていますか?
あ、結局ブラウザはunDonutを使っています。こった機能はなんだか必要なくなってきました。RSSリーダーとか別にいいです、使わないし。ブログを大量に見る人には便利かもしれませんが…( 未だに手打ちHTML日記の人とかいますから余り使わなかったりします。手打ちも面白いけども )。
Sleipnirは環境依存の問題なのかマウスのホイールでフリーズします。マウスは普通のPS/2マウス。マウス関係の常駐はありません。avast!が原因かとも思いましたが、ウイルスソフトを切るわけにはいかないのでブラウザを切りました。ウイルス対策ソフトが無いってどういう了見だろう>x64。
で、お約束通りLunascape3に向かったわけですが、残念ながら操作性が悪すぎる。
これもなんだか環境依存な気がするんですが、お気に入りをクリックしても反応しない。
こんなことはあり得ないのでおそらくx64対応関係の問題だと思われます。
ちうわけでシンプルなブラウザであるところのunDonutに切り替え。
大満足です。お気に入りが変な独自形式じゃないし( プニルもルナもお気に入り移管に手間がかかりました。ユーザーの囲い込みかと疑わんばかりに( 穿ちすぎ ) )。
さて、CRCのお話。というか、今更ですが、CRCです。圧縮アーカイブ作りに必要なのです。
bzip2の仕様をみてみるとどうも900kbごとのブロックに分けて圧縮をしているみたいです。それはそうかという感じなので、こちらも1MB単位の圧縮をします。圧縮アーカイブの名前は未定ですが平凡な名前にしたいです。ABCでもいいかもしれません。内部呼称だし…。
CRCはひたすら因数分解なのです。
割り算したときのあまりがゼロと言うことはその他公式で割り切れると言うことなのですと言うことを高校でやると思いますが、人間は二つに分類される! すなわち、因数分解ができるやつとできないやつだ!
テンションが変ですが、寝てません、最近。4時とか5時に寝ることが多いです。目元がすごいことになってる…。仕事は終わったので今週末に打ち上げだそうです。正に「痴豚でもわかるIllustrator 10.0」という感じの忙しさ。
次のお仕事もう始まってるんですがね…。学生自治というものの面白さと大変さがわかり始めてきた今日この頃。
CRCはちゃんとできたらCurrentInterestingの方にまとめようかと思います。通信関連の本を見れば載っているはずですが…。
まだまだファイルシステム
Path名を処理するところはとりあえず終了。
たかだか数KB程度のコードですが、コンパイルが一発で…
…一発で通りませんでした。
temp :定義されていない識別子です
…tmpの間違いでした。これさえなければ夢の一発コンパイルだったのですが、残念。
内容的には大したことはなくて、お尻の\( 僕はルートと呼ぶのですが一般的にはDirectory Separatorとよぶのかな? 以下はルートと呼びます )をはずしてそこからさかのぼって最初のルートで切るとGetParentDirNameになりますし、さかのぼっていって二回連続で'.'が出たらそこでGetParentDirNameをすれば駆け上がりを処理することができます。
この手の処理は100人が100人とも…は言い過ぎか、50人ぐらいは同じことを書くはずなので、いい加減そういうAPIでも作ってくれればいいのに>Win。残りの50人はレクサとパーサのクラスを使い回したりするかもしれません。
僕は面倒なのでやりたくありませんが( そんな汎用のクラスを入れ込んでサイズでかくしたところでいいことなど一つもないので )。
さて、ここからAIOファイル読み込み処理になだれ込みたいところですが、ファイルをどのように扱えるかを見極めるために、先にアーカイバを作ります。
とりあえず手始めにハフマンやらLZ77やらで簡単な圧縮ルーチン( とそのアーカイブクラス )を書いてみることにします。
…誰でも思いつきそうなことですが、圧縮されるファイルをアーカイブするときに1MBずつに区切ってアーカイブにすればメモリに展開するファイルは常に1MB以下になるのでメモリを節約できるかもとか思いましたが、圧縮効率がかなり犠牲になるかもしれないところと処理が面倒なところ、そんなところを考えると素直に全部メモリ上に展開した方がいいかもしれません。
モダンなOSは馬鹿ではないので糞でかいヒープは仮想メモリに放り込んでくれるんじゃないかと思っているのですが間違いかな…。一時的に展開すればいいのかもしれませんが、それだとCD-ROMで動作するというのに反している気がするし、動作環境にどれだけHDDがあるかどうかもわからない状況でそんな博打みたいなことしたくないし。
もちろん今のところファイルシステムの方はどのドライブでも、ネットワークドライブすら対応できるようにはなっていますが。
CD-ROM駆動の最大の問題はどこにゲームのファイル( セーブデータ、コンフィグデータなど )を保存するか、でしょうか。
一番有力なのは
< マイドキュメント >\My Games\< ここ >
ですか。
マイクロソフトのゲームとか多くのゲームがデフォルトでここを使うので悪い選択肢ではないと思います。
次は「レジストリ」でしょうか。
レジストリに関しては本来は最も有効な選択肢だと思うのですが、世の中にはレジストリに書き出されるのをいやがるという何とも言えない人がいるようなので。
ちょっとしたユーティリティならそのソフトがあるフォルダにちょっとした環境設定ファイルでも書き出した方が簡単なのでそうするべきという主張はわかりますが、このゲームの場合はちょっと特殊なので…。
モダンなOSでシステム設定ファイルが数バイト大きくなった程度でパフォーマンスが何%も悪くなったらそれはOSの方が悪いんじゃないかと思うのですが、どうだろう。
こういうときぐらいレジストリを使わせてもらいたいものですが、ユーザに選択肢を与えるのがいい設計というものです。最終的には上記のどちらかを選択したもらう形になると思います。
つまり、マイドキュメント以下にMy Gamesなんていうセンスのないフォルダを作られるのがいやな人はレジストリを、レジストリに書き込まれるのが大嫌いでもう絶対にレジストリだけはいじらないでくれ毎日毎日毎日毎日全てのレジストリ更新のスナップショットを取ってるんだからもう勝手に変更するなという人はMy Gamesになりますね。
起動時に全ドライブを検索して設定ファイルを見つけるようにすればどこにどんな風に設定をおいても良いのですが。
つまり、
・まずはレジストリを走査する
・なければマイドキュメント以下を走査する
・なければ全ドライブを走査する( 数秒から数分程度 )
・全くなければ初回起動であるので「お風呂にする? ご飯にする? それともレ・ジ・ス・ト・リ?」
まあ、全ドライブ走査は冗談ですが( アホすぎ…とは一概に言えないかもしれない )。
インストール不要って言うのはかなり便利だと思うんだけどなあ…。PSのエミュレータで遊ぶみたいに使えるんだし。
文字列処理関数
卵入りカレーは絶品だと思います。今日の晩ご飯はカレーでしたがすごくまずかったです。ご飯が悪いのかそれともカレーが悪いのかわかりませんが、どっちもレトルトなのでそんなもんです。
さて、前にも書いたかもしれませんが、文字列処理を文字列処理関数を使ってやるな、ということはCプログラミング診断室の方でも繰り返されているとおり、全部sprintfでやれば、少し気をつけるだけでたいていのことはちゃんとできます。メモリ破壊とか怖いですよね…。
ぶっちゃけその手のバッファオーバーフローエラーがクラッカーに狙われるところになることは周知の事実ですから、最低限気をつけるべきことは気をつけろと。
本当はケツの方も確かめておくべきです。確保された以上のchar *に書き込んでませんか?
まあ、そんな糞ミスはゼロ除算ぐらい格好悪いミスですが。
というわけで、ファイルシステムのpath処理でちょこちょこ文字列処理をやってます。
boostのパーサ( レキサ? )も面白そうでしたがそこまでする必要はなさそうだったので、普通にforループで一文字ずつ調べてます。
ストリーミング再生をするにはどうしたらよいかを考えてます。無圧縮アーカイブというものも考えるべき、ということなんでしょうか。無圧縮アーカイブってターボールがそれだったっけ?
とか。
参考リンク:
strsafe.h : C 言語での安全な文字列処理
http://www.microsoft.com/japan/msdn/security/general/strsafe.asp
ファイルシステムその4
ようやく全体的なイメージがつかめました。
なんかやたらと時間がかかった。
ライブラリの難しいところは奇をてらったコーディングや、ひらめきみたいなコーディングではなくて、当たり前に使えるようにしなければいけないところかなと思います。
今もそれでずっと悩んでました。
つまり、普通、ファイルというのはどう開いてどう読み込んで・・・。
まあ結局いろんなソースを読んで参考にしていくしかないわけで、ぶっちゃけ現状のC標準関数の使い方を踏襲した形になるのが一番良いだろうと。
ファイルシステム自体にキャッシング機構をつけようかなどと考えています。
小さいものですが、画像ローダやサウンドローダとは別にファイルシステム自体にキャッシュ機構を持ちたい。
理由はメモリ上に展開したデータを片付けるのがもったいない、ということなのですが。
これについてはまだ未決定。思いつきにすぎないし、おそらく非効率でしょう。
そういえば知り合いにMixiに誘われてから登録がまだ済んでません。いい加減怒られてしまいそう。
というのも今登録できないのですよ。ええ、まあ、それは追々…。
それにしてもいい加減「他のシステムはどうなっているかを見る」という名目でゲームをやるのはいかがなものか。
さっきもうっかり久しぶりに「秋桜の空に」をインストールして遊んでしまったり。
途中で気づいて良かった。
普通のゲームもちゃんと参考にしているのですが。
// 個別のトピックをもうけるつもりはないのでここで。
前に取り上げたRaidersSphereというフライトシューティングゲームですが、なんか、次回作が面白いことになってしまいました。とはいえなんかそんな気は若干したのですが。
今回の舞台は宇宙だそうです。宇宙か…。あのゲーム面白いところがいっぱいあるので動向は興味深いですが、やってみようという気が起きないのが不思議。あれは戦闘機に乗ってるという感覚のゲームじゃないことを頭にたたき込んでおくべきだと思う。戦闘機だったら「ガン射程内!」なんて言われないもんなあ…。ええ、もちろんエースコンバットはその辺がおかしいという意味ですが。
( たぶんあのゲームに影響を与えてしまったなにがしかのいくつかを言い当てることができるとは思う。…つまり僕もあの作者の人と何かしら通じるチャンネルがあったりするのかもしれないですね。あまりのおもしろさにでもムービーで笑いまくったのは秘密。これは褒めてるんですよ! )
ゲーム自体は良くできてるのでそういうのが好きな人にはお勧め。
ただ、ベトナム戦争の時だってあれより当たるぞ、ミサイル、ファルコンミサイル。
非同期IOをあきらめる
いろいろ考えた結果、実装方法は何となくわかりました。
…が、そもそも非同期IOをサポートしなければならないのか。
検証。
DVD-ROMより遅いか同じぐらいのスピードで読み込むDVD-RAMに今のところのcHapter-5を乗せて走らせてみる。
でもって途中で長めの音楽(Ogg:4'34)を再生したりしてみる。
…結果。
画像切り替えの遅延は感じられず( フルスピードスキップをしてみた )。
音楽再生遅延も感じられず( フルスピードスキップをしてみた )。
結論。
別に非同期じゃなくてもキャッシングをしっかりやっておけば十分なパフォーマンスがでるんじゃないだろうか。
というかそもそも今使ってるOggの自前再生DLLであるところのFishLinkはストリーム再生にしてあるので最初からAIOなのです。
扱うデータはせいぜいスクリプト、画像、モデルデータ、音声、動画ぐらいのもので、このうち前半三つに関してはそれぞれがせいぜい200kb以下。
後半二つに関しては読み込むときにAIOな設計にしておけばいいわけで、非同期設計をやめましょう。面倒だし。バグるし。
パフォーマンス上の問題が生じた場合にのみ( 画像に関してはプリロード:シーン開始時に全ての背景、立ちキャラ画像をメモリ上に構築しておく予定なのでパフォーマンス上の問題は仕様上発生しない )AIO設計のファイル読み込みをサポートしましょう。
というわけでファイルシステムのコードを書いていきます。…。
圧縮はやっぱりzlibを使うのが楽かもしれないね。楽な方へ楽な方へ流れていく気もするが…。
もーっとファイルシステム( 続き )
調べてみるとlinuxではaio.hなる非同期IOをサポートした関数が用意されているらしい( 蛇足ですがAsynchronous IOの略でしょうね )。
さて、肝心のターゲットプラットフォームであるWindows NTではどうかというと…
………え? なんか今おかしいこと言った、僕?
だってターゲットプラットフォームはWindows NTじゃないですか。
…わかりました、わかりましたよ。本家の方でもばっちりWin98はサポートしているのです( MEを使うような酔狂な人はサポートしてあげたいけど無理かも )
参考リンクに詳しくありますが、今回用いるだろう非同期IO制御方法は参考リンク先の三つ目の例に挙がっている完了ポートを用いた非同期IOです。当初想定していた方法に近いです( 当初はファイルを開いて一行ずつ別スレッドで読み込んで完了したらコールバック関数に返すという非常にシビアな( =詳しい人が聞いたら苦笑どころか顔が引きつるような )ことをやろうとしていたのです。馬鹿馬鹿しいとは思いながら…。代替案が見つかって本当に良かった )。
ただ、どうもCreateIoCompletionPortのAPIはNT3.51以降でしか対応していないようで…。
ReadFileEx( 非同期を想定して作られたファイル読み込みAPI )は95から対応しているみたいなんですが。そこは切り替えて使うしかないかなあ…。
98のデバッグ環境を家から取り寄せるしかないみたいです。というか、デバッグ環境を一台作らないといけないのか。…サポートやめたくなってきた。
今時2000より前のOSなんて使ってる人いるんだろうか。…いや、問題はそこじゃないな。うむ。
参考リンク:
ソフトウェア情報館 : 非同期 I/O (1/4)
http://www.geocities.jp/i96815/windows/win03.html
今更だけど・ファイルシステム続き
なんだか知りたくもないのに急速にMicrosoftの掲げる新しいプログラミング環境であるところの.Netだか.NETだか.netだかについての情報が集まってきていやになります。
どうも.NETのFileStreamでは非同期IOがサポートされてるらしい。
わかりやすく言えば、Irminzulの目玉機能であるシームレス読み込み機能の半分ぐらいの仕事がすでにマイクロ何とかの社員の人の手によって終わらせられていると言うことです。
今からこの難問に立ち向かおうとしていたのに( ぶっちゃけきちんと管理したThreadでばんばん読み込んでいけばいいのですが、もちろんロック( 排他処理 )はきちんとして )なんだよ.NET環境とやらはさ!
あと今耳元で流れているのが「つまさきjump!」という曲なのですが( テンションの高いやつがちょうどいい )、 ムービーを裏で流しているのですよ。こういうことぐらいしか、今のところデュアルプロセッサの恩恵を受けていない気がする。全くよどまずに作業ができます。全く?! NTカーネルは設計をやり直してSMPたいおうをもっとしっかりやってくだちい!
それは置いておいて、閑話休題。
そのムービーの最後に
・動作環境( 抄 )
・本体…PC/AT100%互換機 : NEC PC-9821シリーズ
という記述があったのですよ。
いや、とってもわかりやすいけど、普通の人、普通にえろげーをやる人にはたぶん全く意味が通じてないと思う。少なくともユーザーの1割未満だろ、このメッセージの意味が通じてるのって。
いや、全く正しいと思う。
あと、今更9821対応にびっくりしたけど、普通の人は9821知らないのでは…ないか…な?
あとPC/ATの意味とか。
あ、いいんですいいんです、DOS/VのVはVGAのVですみたいな聞きかじったうんちくをひけらかすのはやめてください。
DOS/Vの最大の功利は漢字ROMとか言う数万円するふざけたチップをコンピュータの中から取り除いたことだと思いますです。
詳しくはWikipediaで調べてみてください。結構詳しく載ってます。DOS/Xなんて知りませんでした、絶対。
僕はきりのいいところまでPC-9821にしがみついていたので、DOS/Vっていうくされたマシンには造詣が深くありません。
もうね、VRAMみたいなでかいデータやりとりするボードを何であんな細いバスでつないで外に置いたのか、意味がわからないの、私。
もうね、VRAMへのアクセスは泣きたくなるほど遅いんです。それこそ下りは泣きそうになるほど遅いというのはゲームプログラマのよく知られた泣かせどころです。
PS2はPS2でメインメモリが少ないのが泣かせどころだそうなのでどっちもどっちです。
理想的なのは実はXBoxだったりするのですが、国内では誰も見向きもしないのが頭蓋に傷です。死んでるじゃん、それ( 字面で面白いことって言えないという形而上学的なジョーク )。
というわけで、内容がほどよく発散したところでFileSystemの実装に戻ります。
言いたかったのは一般向けって重要ってことです。
"VRAM"はパソコンゲームやろうとしてるんだから通じるよな…?
いや待てよ、ファイルの圧縮解凍の概念を知らない人が同人ソフトサークルの掲示板で「ダブルクリックしても開きません」みたいなことを言ってたぞ…?
あれはああいうコントだよな?
頼む、そうだといってくれ。
門戸を開きすぎるのも困りもの。
DirectXの問題で動かないことでクレームつけたりするのとか勘弁…ってゲーム作ってる人が言ってた。DirectXの問題は機種依存問題でも何でもなくってお前の環境が悪いだけなんだ!…ってそういう筋の人が言ってた。そういうことにしておくといいかな。
とりあえずこまったらdxdiagな。これ、お兄さんとの約束。
熱を出した話・ファイルシステム
熱出して寝込んでます。つらい…。何がつらいって今日はファイルシステムの実装をやろうと思っていたのです。それがこんなくだらないことで時間を取られるとは…。
疲れがたまっていたんでしょうか。それとも食生活の問題か。
ゴールデンウィーク付近で体調を崩すのは例年のことなので、もはや反射的に体調を崩しているのかも。実はこの体調不良が後々の大きな病気を防ぐ役割を果たしていたりとか。
ずっと寝てるか寝ながらウェブラジオ聞いてました。ワイヤレスヘッドホンはとても便利です。
久しぶりにお風呂。自堕落もいい加減にしたいものですね…( 汗が気持ち悪いのでお風呂でした。浴場が広いので気持ちが良かったです )。
ファイルシステムに関してはやねうらお氏が氏のブログ( 2006-03-13 )で書いているようなことを実装するだけです。
ある程度機能を限定すれば実装は難しいものではありません。必要なのは
・ディレクトリのAdd
・ディレクトリ走査
・ファイルを適切に処理する関数
ぐらいですか。画像形式は相も変わらずeri形式でいこうかと思ってます。デコーダ書いちゃったし楽だし。アルファチャンネルちゃんとサポートしてるし。
実験的に自分で書くのもありかもしれません。大したことはできないでしょうが。
音声はoggかな。
圧縮は適当なスライド辞書圧縮程度で問題ない気がします。もしくはzlibとか。
ライブラリ使うのが面倒なので自前で実装したいですが…。
とりあえず骨組みだけ組んでしまえばファイルを扱う関数もArchiverもあとからなんとでもなるのでそれでいいやと。
ファイルシステムはキャッシュシステムとも密接に関係してきます。
なぜならば、このIrminzulシステムの最大のセールスポイントがCDからシームレスにプレイできる、ということだからです。
prefetchみたいなこともやっていかないといけないとなると、ファイルシステムとキャッシュシステムの間でいろいろきちんとやらないといけない気がします。
アドベンチャースクリプトをコンパイルする段階でプリロードするファイルを分析して指定しておくというのも手かな…とか思ってます。
現状のアドベンチャーシステム、つまり「アドベンチャーゲームプログラミング(坂本 千尋 氏・著)」の使用からは大きく変わることになりますし、結構やることは山積みです。
今日は夢の中でBattleField2やってました。最近体験版にはまり、本編を買おうと計画中です。
すごいあつくて、走りながら汗がぼたぼた出て、建物の陰に隠れてはパンツァーファウストをどかん。
一発撃ったら弾を装填して走って次の物陰に入りパンツァーファウストをどかん。
敵の兵隊さんが集まってきたのでサブマシンガンに持ち替えて( パンツァーファウストは捨てました )敵の兵隊さんを殺しながら装甲戦闘車に走ってついて行きました。そんな夢。
起きたら汗びっしょり。いやな夢だったのかな…。とりあえずいえることはBattleField2好評発売中。
そういえば
宴会の席でC#はどうかという話が出たが、「コンパイラを持ってない」という理由で断った。
もちろんコンパイラは無料配布しているし、なんか技官室に行ってどうこうするとむにゃむにゃということだった。教育目的ライセンスが死ぬほど発行されてるんだろうというか、たぶん全員分のライセンスはすでにあるんだろう。計算機室全部の計算機にVCが入っていたのだし。
C#に行きたくない理由はひとえに「.Net意味不明」とか「Managedってなに?」みたいなところがまるでわかってないからだと思う。
「Mono」といってくれればわかるのだが、.Netといわれてもどこがどうネットワーク技術なのか小一時間問いつめたい。絶対に名前の付け方間違ってるんだってばさ!
…どう考えても性能のいいコンパイラに乗り換えない理由にはならないと思うけど…。使い慣れないIDEほどいやなものもないし。コンパイラだけ最後VC7.1にしてバイナリ吐き出して配布。
という風に考えてます。
しばらくはVC6.0でいくぞうっ!