FC2ブログ

三角端。

Δ-sphere管理人三角区也による絵日記/ゲーム開発日記。コメントは右側のweb拍手からどぞー。

バイナリファイルのお作法

今日はバイナリファイルのお話です。

以前作っていたフォント用ファイルが今見てみると大変扱いにくいファイルフォーマットだったので作り直していました。
あとテキストテーブルがなかったことに気付いたので新規に。

テキストテーブルというのは専用のIDと文字列が紐付けされたテーブルです。
たとえば
ID:text_000 text:オープニング・・・魔王が攻めてきてうんたらかんたら・・・
そんな感じ。
ツクールをやっている人からしたら直接イベントに書き込んでしまえばいいじゃん、って思うかもしれませんが、
テキストの変更をしたいときに変更箇所を探すのが大変になってしまいます。
それが複数箇所で使われていたりするともう何箇所変更すればよいのやら・・・
(あとは、まあ、翻訳することがあればすごく楽になるんじゃないかなあ・・・)


自分はバイナリフォーマットを作るときに、
[ヘッダ]
[データ1]
[データ2]
・・・
という形をとります。
ヘッダにはバージョンと各データ先頭までのオフセット値を入れてます。
そうするとバージョンアップしたときに対応しやすくなります。

今回のテキストテーブルは
[ヘッダ]
[データヘッダ列]
[テキスト列]
[ハッシュ列]
という形をとりました。

データヘッダは[テキストIDのオフセット][テキスト本文のオフセット]となっていて
それぞれがテキスト列のどの位置かを指し示すようにしました。
文字列はデータサイズが一定ではないのでちょっと面倒ですね・・・


これでデータを探すときは
1.ハッシュ列に対して大体どのあたりにデータがあるかを探す
2.1の値をもとにデータヘッダを探索
3.2で見つけたデータヘッダの指し示すテキスト本文を取得
という流れになりました。

それでこの解析器を独立したモジュールにしたのでもう安心です。
過去の自分は何を血迷ったか、データヘッダにデータの構造体しか書いていなくて
どういったファイル構造なのかまったくわからない状態になっていました。
まさか、過去の自分が書いたコードをリバースエンジニアリングする羽目になろうとは・・・

Lua導入

今週は風邪でうぼぁーしてました

まだ完治してないんですけどね。
鼻水ずるずるでござる。



◆trpr
Luaを導入して動作テストをしてました。
とりあえず初期化コードに
_RegistMap("hiroba")
といれるとマップ用のデータベースにhirobaを追加するようにしました。
その文字列とIDを紐付けておけば簡単にID探索もできますし、
IDからの文字列情報も手に入りますね。

他のモデルデータとかのファイル名はこの文字列を接頭辞にして、
hiroba_mainmodelとかにすると読み込みのときに、
hiroba_mainmodel,hiroba2_mainmodelとかたくさん書かずとも
登録文字列+_mainmodelでできるので楽でバグも少なそうです。

screen_252.jpg

screen_252.jpg

なぜか、最初間違えて上のファイルでアップロードして、下のファイルで上書きしたはずなのにずっと上のファイルが表示され続けるという・・・
FC2がバグっているんでしょうかねえ・・・

行列展開関数

世間はGWですってね

かくいう自分も10連休?なのでしっかりとこの隙に進めておきたいと思います。
まあ、実家に帰る予定があったり予定は埋まっていたりするんですけどね。


◆trpr
3Dモデルの変換ツールをずっと作っていたんですがずっとうまくいかないんです・・・
結果から言えばついさっき原因を見つけてうおおお! ってなったのですが、
まあその原因がひどいひどい。
でもバグってそんなもんだよね、ヒューマンエラーって怖いよね。


バグっていたのは変換行列を座標、拡大縮小、クオータニオンの各成分に分解する関数です。
DirectXにD3DXMatrixDecomposeっていう関数がありますが、まさにそれと同等の機能です。
あるんならそれを使っちゃえばいいじゃない?
まさにそれです、それなんです。
車輪の再発明はよくない。車輪転がりまくりです。

まあ、ただひとつだけ問題がありまして、
DirectXの関数を使うとDirectXの環境でしか使えないんですね。
仮にGLとか、DirectX以外の環境で作ることになったときに、
同じライブラリなのに一定の機能がDirectXに依存しているため使えない、といったことが起こります。

描画とかシェーダーとかDirectXの関数を使わないとどうにもならないような部分は仕方が無いですが、
数学関数とかは自分で実装してしまえという設計思想で作っています。


libpng

先週は北海道に行ってました。

昼間の気温は-5度とかだったんですが、なぜか寒く感じませんでした。
正直東京とかの方が寒いです。
日光が雪に反射するからでしょうかね?
スキーとかで日焼けするっていいますもんね。

でも帰りの空港が-12度で寒かったです。





libpngをライブラリに組み込んでいます。


もともとPNGの解析エンジンを自前で実装しようとしていました。
PNGのチャンクを取るところまでは簡単だったんですが、
IDATチャンク、画像のピクセルデータが入っているチャンクが
ZIP圧縮がかかっていてその展開ルーチンがよくわからず・・・

さらにzlibだけ入れようとしても詳しい仕様の日本語版のサイトがほとんどなくなっているようで、
結局libpngを導入することにしました。

libpngを入れるためにzlibと一緒にビルド。
できたlibpng.libをコピーしてゲーム側に持ってくるとなぜか
error LNK2019: 未解決の外部シンボル _crc32 が関数 _png_reset_crc で参照されました。
といったリンクエラーがずらずらと。
色々試していたらどうやらzlib.libも必要なようで。

libpng内部でzlibを使っているので当然といえば当然なんですが、
libpngに入っているプロジェクトをビルドしたら当然zlibがそのライブラリに入っているものだと思ってしまって、
この原因を見つけるのに無駄に時間がかかってしまいました(´・ω・`)

でも、まあ、無事にビルドして導入できたので一安心です。

XMLパーサー

作り直し作り直し。


以前Colladaパーサーを作ったのですが、
自分で書いたパーサーでメンテをしにくかったので作り直して、ついでにデータ形式を変更しようという魂胆です。
ColladaはXMLなのでMSXMLを使用することにしました。



COMを使ってるらしいので
アプリケーション開始時にCoInitialize、終了時にCoUninitializeを。
このあたりはお約束。


MSXMLを使うために以下のコードを追加

//includeのようなもの
#import "msxml6.dll" named_guids


こいつはdllから自動的にヘッダファイル(のようなもの)を生成してくれます。

//ドキュメントインスタンス作成
MSXML2::IXMLDOMDocument2Ptr pXMLDOMDocument;
pXMLDOMDocument.CreateInstance(CLSID_DOMDocument);




// XMLファイル読み込み
pXMLDOMDocument->put_async( VARIANT_FALSE ); // load関数がロードを完了するまで待つようにする。
hResult = pXMLDOMDocument->load( InFilename);



これでXMLインスタンスで解析できるようになりました。

あとはColladaの仕様に沿って解析していくのですが、
まあ・・・、自分の使って無い部分は作らなくてもよいので・・・ 必要な場所だけ・・・


Colladaは見た感じ

COLLADA
├asset
├library_cameras
├library_materials
・・・
├library_visual_scenes
└scene


となっているようです。

今回欲しかったのはモデルデータなのでlibrary_geometriesノードから探索して、頂点情報、マテリアルIDを取得。
そこから参照しているところを芋づる式にlibrary_materialsとかとかからデータを抽出しました。


・・・、というコードを書いたところで今日は終わり。
確認作業はこれからです(´ω`;)


前のページ 次のページ