/*****************************************************************************
 * Bison/Flexプログラム部分をテストするための、Windowsアプリケーションの雛型 *
 * □ビルド・実行方法:                                                       *
 * ┃"C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"  *
 * ┃make -f winapp.mk run                                                   *
 *****************************************************************************/
#ifndef __WINAPP_H__
#define __WINAPP_H__
/*{{定型コード:winapp.h======================================================*/
#include <clip.h>
/* y.tab.y */
extern int yynerrs;
#if     (YYDEBUG!=0)
extern int yydebug;
#endif/*(YYDEBUG!=0)*/
int yyparse();
void yyerror(const char* fmt, ...);
/* lex.yy.l */
extern FILE* yyin;
extern FILE* yyout;
extern int yylineno;
int yylex();
void yylex_init(FILE* input_file);
/* winapp.c */
void push_location(const char* path);
void pop_location();
/*}}定型コード:winapp.h======================================================*/
//-----------------------------------------------------------------------------
//構造体定義
//-----------------------------------------------------------------------------
//スプライト
typedef struct _ST_Spr {
	char*		pSprLab;		//スプライト名。NULL不可。
	int		x, y;			//左上座標
	int		w, h;			//幅、高さ
	int		cx, cy;			//原点オフセット
	char*		Param;			//パラメータ
	//以下のフィールドは2パス目で格納する。
	int		iSprNo;			//このスプライトのスプライト番号。1ベース。
	char*		pTexLab;		//このスプライトが属するテクスチャのテクスチャ名。NULL不可。
} ST_Spr;
//テクスチャヘッダ
typedef struct _ST_TexHdr {
	char*		pTexLab;		//テクスチャ名。NULL不可。
	char*		pPath;			//ファイル名。一時的にはNULL可。1パス目完了時点でNULLのままならばエラー。
	int		bResource;		//リソースフラグ。リソースフラグはP/ECE用のテクスチャ定義ヘッダだけに影響する。汎用の列挙定義,及び,レジストリスクリプトでは無視される。
//{{2017/03/26変更:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
//	int		bLoop;			//ループフラグ。ループフラグはレジストリスクリプトだけに出力する。Windowsでムービーグラフィックを再生する時に参照する。
//↓2017/03/26変更:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
	struct _ST_AttrList*	pAttrList;	//属性リスト。属性リストはレジストリスクリプトだけに出力する。Windowsでムービーグラフィックのループ設定やグラフィックの描画モードを設定する時等に参照する。
//}}2017/03/26変更:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
} ST_TexHdr;
//テクスチャボディ
typedef struct _ST_TexBody {
	int		nSpr;			//スプライト数。0以上。0ならばテクスチャ定義だけでスプライト定義が無い事を意味する。
	ST_Spr*		aSpr[/*nSpr*/];		//スプライト配列
} ST_TexBody;
//テクスチャ
typedef struct _ST_Tex {
	ST_TexHdr*	pTexHdr;		//テクスチャヘッダ。NULL不可。
	ST_TexBody*	pTexBody;		//テクスチャボディ。NULL不可。
	//以下のフィールドは2パス目で格納する。
	int		iTexNo;			//このテクスチャのテクスチャ番号。1ベース。
} ST_Tex;
//{{2017/03/26追加:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
typedef struct _ST_Attr {
	char*		pAttrName;		//属性名
	int		iAttrType;		//属性の種類	0=数値,1=文字列
	union {
		int	iVal;			//数値		(iAttrType==0)の場合はこちらのフィールドが有効です。
		char*	pStr;			//文字列	(iAttrType==1)の場合はこちらのフィールドが有効です。
	};
} ST_Attr;
typedef struct _ST_AttrList {
	GTree*		pAttrValTree;		//数値属性のツリー	┬違う種類で同じ名前の属性は存在しても良い。
	GTree*		pAttrStrTree;		//文字列属性のツリー	┘
} ST_AttrList;
//}}2017/03/26追加:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
//-----------------------------------------------------------------------------
//グローバル変数宣言
//-----------------------------------------------------------------------------
extern int grid_w, grid_h;
//-----------------------------------------------------------------------------
//グローバル関数宣言
//-----------------------------------------------------------------------------
int cast_dbl_to_int(double d);
void addTex(ST_Tex* pTex);
ST_Tex* Tex_new(ST_TexHdr* pTexHdr, ST_TexBody* pTexBody);
//{{2017/03/26変更:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
//ST_TexHdr* TexHdr_new(char* pTexLab/*片方のみNULL可*/, char* pPath/*片方のみNULL可*/, int bResource, int bLoop);
//↓2017/03/26変更:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
ST_TexHdr* TexHdr_new(char* pTexLab/*片方のみNULL可*/, char* pPath/*片方のみNULL可*/, int bResource, ST_AttrList* pAttrList);
//}}2017/03/26変更:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
ST_TexBody* TexBody_new(int iGridW, int iGridH);
ST_TexBody* TexBody_addSpr(ST_TexBody* pTexBody, ST_Spr* pSpr);
ST_Spr* Spr_new( char* pSprLab, int x, int y, int w, int h, int cx, int cy, char* Param);
ST_Spr* Spr_newP(char* pSprLab, int x, int y, int w, int h, int px, int py, char* Param);
//{{2017/03/26追加:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
ST_AttrList* AttrList_NewBlank();
ST_AttrList* AttrList_New(ST_Attr* pAttr);
ST_AttrList* AttrList_AddAttr(ST_AttrList* pAttrList, ST_Attr* pAttr);
ST_Attr* Attr_New(char* pAttrName, int iAttrType, intptr_t iVal_pStr);
//}}2017/03/26追加:テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
//-----------------------------------------------------------------------------
//変更履歴
//-----------------------------------------------------------------------------
// * Sun Jan 10 21:20:52 JST 2016 Naoyuki Sawa
// - 1st リリース。
// * Thu Jan 14 21:10:13 JST 2016 Naoyuki Sawa
// - 列挙定義スクリプトを生成するオプション名を、'-m'⇒'-u'に変更しました。
//   オプション名をdFsmMapC.exeと統一するためです。
// * Tue Jan 26 21:39:05 JST 2016 Naoyuki Sawa
// - スプライトの中心位置を、サイズに対するパーセンテージでも指定出来るようにしました。
//   詳細は、y.tab.yのsprの処理,及び,winapp.cのSpr_newP()関数を参照して下さい。
//   この指定方法を追加した理由は、様々なサイズのスプライトに対して全て中央を中心にする場合、全て共通で'50%,50%'(又は'49%,49%',後述)の指定で済むからです。
// - 中央を指定する場合、50%ではなく、49%を指定する方が良い場合が有ります。
//   右(又は下)端を指定する場合、100%ではなく、99%を指定する方が良い場合が有ります。
//   特に、P/ECEのような解像度が低い環境で使用する場合、グリッド座標とピクセル座標の差が大きいので、49%や99%の方が適切かも知れません。
//   例えば右下を中心に回転する場合、'100%'指定では(右下+1)のドットが中心になって回転してしまいます。
//   '99%'指定ならば、右下のドットが中心になって回転するので、自然です。(ただし、スプライトのサイズが100以下の場合に限る)
//   ケースバイケースですので、環境によって調整して下さい。
//   より厳密に指定するには、パーセンテージ指定でなく、これまで通りピクセル単位で指定する方法で中心位置を指定して下さい。
// * Wed Jan 27 21:15:43 JST 2016 Naoyuki Sawa
// - レジストリスクリプトでも、マイナスのcx,cyを表現出来るようにしました。
//   アプリケーション側では、取得したcx,cyを(((int)(x<<8))>>8)のように符号拡張して使用して下さい。
// * Wed Jan 27 22:56:05 JST 2016 Naoyuki Sawa
// - ファイル名からラベルを自動生成する処理を変更しました。
// - 変更前は、単純に、Cシンボル以外の文字が出現した所で打ち切っていました。
//   しかしそれだと、'foo 001.bmp','foo 002.bmp','foo 003.bmp',…のような空白を含むファイル名に対して、個別のラベルが上手く生成出来ない問題が生じました。
//   「AVI2JPG」(http://www.gigafree.net/media/conv/avi2jpg.html)等のフリーソフトで連番画像を作成すると、上記のようにファイル名に空白が含まれるからです。
// - そこで、ファイル名からラベルを自動生成する処理を、以下のように変更しました。
//   ①'-'が出現するまでの間、Cシンボル以外の文字が出現したら、'_'に置き換えて継続する。
//   ②'-'が出現したら、そこで打ち切る。
//   (※②はdpbmpcnv.exeに準拠するための仕様です。Win32プロジェクトで使用する場合は必ずしも適切ではないのですが、P/ECEプロジェクトでの使い易さを優先する事にしました。)
// - 変更後の処理で、前述の例のファイル名は、以下のようなラベルに自動変換されます。
//   'foo 001.bmp'⇒FOO_001,'foo 002.bmp'⇒FOO_002,'foo 003.bmp'⇒FOO_003
//   別の例として、dpbmpcnv.exe用のフォーマット指定が付いているファイル名の場合、以下のようにラベルが自動変換されます。
//   'bar 001-2m.bmp'⇒BAR_001,'bar 002-2m.bmp'⇒BAR_002,'bar 003-2m.bmp'⇒BAR_003
// * Sun Feb 21 21:02:01 JST 2016 Naoyuki Sawa
// - libclipのライブラリ化の伴い、以下の変更を行いました。
//   ・extclip.hとextclip.cを削除しました。extclip.hとextclip.cはlibclipに含まれるようになったからです。
//   ・"CLiP Files"を削除しました。CLiPライブラリの各モジュールはlibclipに含まれるようになったからです。
//   当ツールの動作には変更有りません。
// * Wed Feb 24 21:12:31 JST 2016 Naoyuki Sawa
// - output_enm()において、テクスチャ名の一文字目がCシンボルの一文字目として無効な文字(多分数字)ならば、テクスチャ名の先頭に「`」を付与するようにしました。
// - output_enm()において、スプライト名の一文字目がCシンボルの一文字目として無効な文字(多分数字)ならば、スプライト名の先頭に「`」を付与するようにしました。
// * Tue Mar 01 21:34:55 JST 2016 Naoyuki Sawa
// - clipstd.hにてC4131の警告レベルを引き上げましたが、Bison/Flexの生成コードには旧スタイルの宣言が使われているので、Bison/Flexの生成コードのみ警告レベルを元に戻しました。
// * Wed Apr 06 21:53:01 JST 2016 Naoyuki Sawa
// - loopフラグを追加しました。
//   ループフラグはレジストリスクリプトだけに出力され、Windowsでムービーグラフィックを再生する時に参照します。
//   詳細は、Sample/Sample.txt を参照して下さい。
//   Windowsでムービーグラフィックを再生する時にループフラグを参照する処理は、近日中に/clip/DxlibHelper.cppに実装する予定です。
// * Sun Apr 24 21:05:43 JST 2016 Naoyuki Sawa
// - 2016/04/23に、/clip/clipstd.hにparsonとLibYAMLのインクルードを追加した事に伴い、当プロジェクトにもparsonとLibYAMLのインクルードパスとライブラリパスの設定を追加しました。
//   当プロジェクトはparsonもLibYAMLも使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
// - libclip.lib,gc.lib,pthreadVC2(d).lib,sqlite.lib,pdcurses.libのリンク指定を、/clip/libclip/extclip.hで指定するようにし、個別のアプリケーション設定からは削除しました。
//   parson.lib,yaml.libのリンク指定を、/clip/clipstd.hで指定するようにし、個別のアプリケーション設定からは削除しました。
// - 座標単位のダリミタを、「.」⇒「:」に変更しました。
//   【変更前】グリッド単位.ピクセル単位
//   【変更後】グリッド単位:ピクセル単位
//   変更した理由は、もし今後、数値に実数を使えるように変更した場合に、'グリッド単位.ピクセル単位'だと実数と区別できなくなるからです。
//   2016/04/24現時点は、まだ数値の実数対応は行っていませんが、今後実数対応する可能性が有るので、今のうちに変更しておく事にしました。	⇒{{2016/04/25追記:実数対応しました。}}
// * Mon Apr 25 22:45:55 JST 2016 Naoyuki Sawa
// - 実数の計算式に対応しました。
//   暗黙の型変換のルールは、C言語と同じです。
//   キャスト演算子は、'(int)'と'(double)'のみ対応しています。
// - あくまでも途中計算で実数の計算式が使えるだけであり、最終的には整数にキャストする必要が有る事に注意して下さい。	⇒{{2016/04/25追記:整数引数への暗黙の型変換を対応しました。}}
//   <例>
//   │TEX1
//   │  grid 1,1
//   │  SPR1       100.0/3 ,      50*1.23	//エラー
//   │  SPR2 (int)(100.0/3),(int)(50*1.23)	//正しい
//   │end
// * Tue Apr 26 22:39:26 JST 2016 Naoyuki Sawa
// - 実数の計算式から、整数引数への、暗黙の型変換を対応しました。
//   '-w'オプションを指定しなければ、C言語と同様に、警告無しで処理します。
//   '-w'オプション,又は,'-wcast'オプションを指定すると、暗黙の型変換によって誤差が発生した時のみ警告を表示し、最終的にエラー終了します。
//   C言語と違って、誤差が発生しなかった時は警告を表示しない事に注意して下さい。
// - 上記の変更のために、'-w'オプションを処理する仕組みとして、getsubopt()を導入しました。
//   今後、他の種類の警告を追加する時は、この仕組みを使って警告を追加出来ます。
// * Thu Jun 09 21:26:53 JST 2016 Naoyuki Sawa
// - lex.yy.lにて、数値(T_NUM)の解析を、既存の10進数と16進数に加えて、新しく8進数と2進数も解析出来るようにしました。
// * Sat Jul 02 21:34:21 JST 2016 Naoyuki Sawa
// - 2016/06/14に、/clip/clipstd.hに'#pragma comment(lib, "liblua.lib")'を追加した事に伴い、当プロジェクトにもlibluaのライブラリパスの設定を追加しました。
//   現在の所、当プロジェクトはlibluaを使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
//   尚、libluaのインクルードパスは以前から設定していたので、今回、追加したのはlibluaのライブラリパスのみです。
// - 2016/07/01に、/clip/libclip/extclip.hに'#include <sqlite3.h>'と'#pragma comment(lib, "sqlite3.lib")'を追加した事に伴い、当プロジェクトにもsqlite3のインクルードパスとライブラリパスの設定を追加しました。
//   現在の所、当プロジェクトはsqlite3を使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
// * Sun Jul 10 11:29:13 JST 2016 Naoyuki Sawa
// - y.tab.yのint_argの文法規則の最後に、「;」が抜けていたミスを修正しました。
//   bison.exeはこのような単純なミスを自動的に補ってくれるので、bison.exeのエラーにもならず、生成したプログラムの動作上も問題無く、これまで気付きませんでした。
//   しかし、間違った記述であった事には違い無いので、修正しておく事にしました。
// * Fri Sep 16 21:30:10 JST 2016 Naoyuki Sawa
// - '-q'オプションを追加しました。
//   /clip/test.win/を元にしたプロジェクトで、VC++6.0のカスタムビルドから呼び出された場合に、'\r'による同じ行の重ね書きが上手く認識されず、VC++6.0の出力ペインに進捗表示が多く出過ぎて、その他の重要なエラーが見づらくなってしまう問題を避けるためです。
//   基本的には、VC++6.0のカスタムビルドから呼び出す場合だけに'-q'オプションを使用し、コマンドラインから呼び出す場合はこれまで通り'-q'オプションは指定しなくて構いません。
// * Wed Sep 21 21:20:16 JST 2016 Naoyuki Sawa
// - die(～)で終了していた箇所を、error(EXIT_FAILURE,～)で終了するように変更しました。
//   変更した理由は、以下の通りです。
// - die()は、標準エラー出力がコンソールでなければ、エラーメッセージをメッセージボックスで表示します。
//   通常はそれが望ましい動作なのですが、VC++6.0やVS2015のカスタムビルドとして当ツールを呼び出した場合に、使い辛い問題が生じます。
//   VC++6.0やVS2015は、カスタムビルドとして呼び出すツールの標準エラー出力をリダイレクトして、アウトプットウインドウに表示します。
//   標準エラー出力がコンソールでないので、当ツールはエラー終了する場合に、メッセージボックスを表示します。
//   結果として、カスタムビルドとして呼び出したツールがエラーになると、いちいちメッセージボックスを表示して停止し、使い辛い問題が生じました。
//   元々、die()が標準エラー出力がコンソールでなければエラーメッセージをメッセージボックスで表示するようにした理由は、コマンドプロンプトを持たないウインドウアプリケーションのためであり、
//   当ツールのようなコンソールアプリケーションの標準エラー出力がリダイレクトされた場合にメッセージボックスを表示する必要はあまり有りません。
//   そこで、当ツールがエラー終了する時にdie()を呼び出すのをやめて、error()で終了するように変更する事にしました。
// * Sun Sep 25 21:05:26 JST 2016 Naoyuki Sawa
// - /clip/test.win/lex.yy.lの'popen'対応処理を、当ツールのlex.yy.lにマージしました。
//   当ツールの'popen'対応は必須ではないのですが、本日dFsmMapC.exeに上記の変更を行ったついでに当ツールも対応しておく事にしました。
// - エラーメッセージに、現在の行番号だけでなく、現在のファイル名も表示するようにしました。
//   エラーメッセージの形式は、VC++6.0に合わせて、「ファイル名(行番号) : エラーメッセージ」としました。
// * Wed Sep 28 21:26:44 JST 2016 Naoyuki Sawa
// - error()の文字列の最後に余計な改行が付いていたのを削除しました。
//   error()は指定された文字列の後に(もし有ればエラー名を挟んで)自動的に改行を出力するので、アプリケーション側で文字列の最後に改行を付けると、文字列とエラー名の間に余計な改行が出力されたり、二回改行してしまう問題が生じていました。
// * Sun Oct 02 21:48:17 JST 2016 Naoyuki Sawa
// - ";"によるマルチステートメントに対応しました。
//   変更箇所は、lex.yy.lの「\n { return T_EOL; }」の上の行に、「";" |」を追加しただけです。
// - マルチステートメント対応が必要になった理由は、主にdDirSeqC.exeのためです。
//   Cプリプロセッサで一つのマクロで複数のact命令を生成する時に、Cプリプロセッサの制限のために複数行に分けられないからです。
//   今回マルチステートメントを対応した事によって、「act ～; act ～; act ～」のように一行で複数のact命令が可能になりました。
//   dDirSeqC.exe以外のツールについては、今すぐにマルチステートメント対応が必要な訳ではないのですが、上述の通り変更箇所は少ないので、他のツールも一緒に変更しておく事にしました。
// * Thu Mar 16 23:39:55 JST 2017 Naoyuki Sawa
// - 複数の入力ファイルを指定した時に、最後以外のファイルでエラーが発生した場合、当ツールの終了ステータスが0になっていたバグを修正しました。
//   詳細は、/clip/tool/dEnmDefC/winapp.hの同日のコメントを参照して下さい。
// * Sun Mar 26 22:13:56 JST 2017 Naoyuki Sawa
// - テクスチャに汎用の属性リストを追加し、既存のループフラグも属性に含めました。
//   詳細は、以下の通りです。
// - これまで、テクスチャの属性には、'resource'と'loop'しか指定する事が出来ませんでした。
//   'resource'はP/ECE特有の指定なので置いておくとして、描画に関する属性は'loop'しか指定する事が出来ませんでした。
//   それ以外にも属性を指定したい場合、スプライトのparamとして指定して、スプライト描画経由でテクスチャ描画に伝播させるという方法しか使えず、やや無理が有りました。
//   今回、特定のムービーテクスチャを加算合成モードで描画したいという要件が生じました。(具体的には「CRIWARE Unity plugin」です。「CRIWARE Unity plugin」ではムービーテクスチャを再生開始する直前にadditiveModeで加算合成モードを設定する必要が有り、これをスプライトのparamとして指定するのは無理が有ります。)
//   今回の要件に限らず、テクスチャに色々な任意の属性を指定出来る方が便利だと思うので、思い切って大幅な変更を行う事にしました。
//   今回の変更により、例えば上述の加算合成モードを指定したい場合は、
//   │TEX_SAMPLE "sample.usm" loop additive
//   のように指定出来るようになりました。
// - 今回の変更に置いて工夫した点は、互換性維持のために、既存のloop指定を生かしたまま、任意の属性も指定出来るようにする事です。
//   そのために、属性の省略記法も使えるようにしました。
//   今回追加した任意の属性の指定方法は、「属性名 = 数値」又は「属性名 = "文字列"」です。
//   それに加えて、省略記法として「属性名」も使えるようにし、その場合暗黙に「属性名 = 1」と見なす事にしました。
//   これによって、「loop」と指定されたら、暗黙に「loop = 1」と見なされ、これまでのループ指定と同じレジストリスクリプトが出力出来ます。(厳密には少し非互換性が有ります。後述)
// - 複数の属性も指定出来ます。計算式も使えます。
//   │TEX_SAMPLE "sample.ogv" loop scale_x=1<<2 scale_y=1<<3 comment="コメント"
//   一つのテクスチャに対する定義を複数に分けて書いた場合、それぞれの属性がマージされる事についても、これまで通りです。
//   │TEX_SAMPLE "sample.bmp" loop resource
//   │TEX_SAMPLE              scale_x=2 scale_y=3
//   また、(実際にそうする事は無いと思いますが)属性の種類が違っていれば、同じ名前の属性を登録する事も出来ます。
//   │TEX_SAMPLE "sample.ogv" attrNameX=1 attrNameX="One"
//   具体的には、winapp.cのAttrList_AddAttr()の実装を参照して下さい。
// - 今回の変更による、変更前との非互換性について説明します。
//   変更前は、loopに対するレジストリ名は、「Loop」として出力していました。
//   変更後は、loopに対するレジストリ名は、「loop」として出力します。
//   なぜならば、変更後はloopは予約語ではなく、単なる属性名の一つでしかないので、そのままの名前でレジストリ名として出力されるからです。
//   上記の非互換性が発生したため、既存のアプリケーションで「RegKey_Loop」と指定している箇所は、「RegKey_loop」に変更して下さい。
//   尚、当ツール内で属性名の一文字目を大文字化する案も考えましたが、却って使い辛くなる問題の方が大きいと思ったので、その方法は取らない事にしました。
//   今回の非互換性によるアプリケーション側の修正は僅かなので、アプリケーション側で対応する事にしました。
// * Fri Mar 31 21:21:33 JST 2017 Naoyuki Sawa
// - 入力ファイル名のサフィックスによる属性の自動出力に対応しました。
//   今回は自動スケーリング属性のサフィックス('-1x'～'-9x')だけに対応しました。
//   今後必要に応じて増やして行く予定です。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20170331"
//-----------------------------------------------------------------------------
#endif/*__WINAPP_H__*/
