/*****************************************************************************
 * 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用のテクスチャ定義ヘッダだけに影響する。汎用の列挙定義,及び,レジストリスクリプトでは無視される。
	int		bLoop;			//ループフラグ。ループフラグはレジストリスクリプトだけに出力する。Windowsでムービーグラフィックを再生する時に参照する。
} 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;
//-----------------------------------------------------------------------------
//グローバル変数宣言
//-----------------------------------------------------------------------------
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);
ST_TexHdr* TexHdr_new(char* pTexLab/*片方のみNULL可*/, char* pPath/*片方のみNULL可*/, int bResource, int bLoop);
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);
//-----------------------------------------------------------------------------
//変更履歴
//-----------------------------------------------------------------------------
// * 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以外のツールについては、今すぐにマルチステートメント対応が必要な訳ではないのですが、上述の通り変更箇所は少ないので、他のツールも一緒に変更しておく事にしました。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20161002"
//-----------------------------------------------------------------------------
#endif/*__WINAPP_H__*/
