/*****************************************************************************
 * 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_Anm {
	//以下のフィールドはAnm_New()で格納する。
	char*			pAnmLab;		//アニメーション名			NULL不可
	struct _ST_KeyRows*	pKeyRows;		//キーフレームリスト
	int			tRep;			//ループ戻り時刻			(tRep≧tEnd)ならばループしない。
	int			tEnd;			//最終時刻+1				1〜UINT16_MAX
	//以下のフィールドは2パス目で格納する。
	int			iAnmNo;			//アニメーション番号			1〜UINT16_MAX
	int			iWordAddr;		//アドレス				(int)単位
	struct obstack		o;			//アニメーションデータ
} ST_Anm;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//キーフレームリスト
typedef struct _ST_KeyRows {
	int			nKeyRow;		//キーフレーム数			1〜(UINT16_MAX+1)	空のキーフレームリストが作成されない事は、y.tab.yのルールで保障されるので、winapp.c内の処理で検査する必要は無い。
	struct _ST_KeyRow*	aKeyRow[/*nKeyRow*/];	//キーフレーム配列			              ~~出力時に(-1)するので、上限は(UINT16_MAX+1)である。詳細は、pass2()内の「アニメーションデータを作成する」の処理を参照せよ。
} ST_KeyRows;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//キーフレーム
typedef struct _ST_KeyRow {
	//以下のフィールドはKeyRow_New()で格納する。
	int			iSprNo;			//スプライト番号			0〜UINT16_MAX
	int			nFrame;			//フレーム数				1〜UINT16_MAX
	//以下のフィールドはAnm_New()で格納する。
	int			tKey;			//このキーの時刻			0〜UINT16_MAX
} ST_KeyRow;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//{{2018/04/11追加:「repeat N」を追加しました。
//「repeat N」キーフレームリスト
typedef struct _ST_KeyRowsN {
	int			nRepeat;		//展開回数				1〜
	struct _ST_KeyRows*	pKeyRows;		//キーフレームリスト			NULL不可
} ST_KeyRowsN;
//}}2018/04/11追加:「repeat N」を追加しました。
//-----------------------------------------------------------------------------
//グローバル関数宣言
//-----------------------------------------------------------------------------
int cast_dbl_to_int(double d);
void addAnm(ST_Anm* pAnm);
ST_Anm* Anm_New(char* pAnmLab, ST_KeyRows* pKeyRowsI/*NULL可*/, ST_KeyRows* pKeyRowsL/*NULL可*/, int bStay);	//pKeyRowsIとpKeyRowsLは、両方とも非NULLか,又は,片方だけNULL可。両方ともNULLは不可。この制約は、y.tab.yのルールで保障されるので、当関数の処理で検査する必要は無い。
ST_KeyRows* KeyRows_Add(ST_KeyRows* pKeyRows/*NULL可*/, ST_KeyRow* pKeyRow);
ST_KeyRow* KeyRow_New(int iSprNo, int nFrame);
//{{2018/04/11追加:「repeat N」を追加しました。
ST_KeyRows* KeyRows_AddN(ST_KeyRows* pKeyRows/*NULL可*/, ST_KeyRowsN* pKeyRowsN);
ST_KeyRowsN* KeyRowsN_New(int nRepeat, ST_KeyRows* pKeyRows);
//}}2018/04/11追加:「repeat N」を追加しました。
//-----------------------------------------------------------------------------
//変更履歴
//-----------------------------------------------------------------------------
// * Sun Mar 06 21:12:57 JST 2016 Naoyuki Sawa
// - 1st リリース。
//   /clip/clipanms.c で使用するためのデータを出力するツールです。
// * Sun Mar 13 16:39:48 JST 2016 Naoyuki Sawa
// - 出力データに僅かな無駄が生じるケースが有った点を修正しました。
//   修正前は、repeatを挟んだ同一値のキーフレームをまとめず別々に出力していました。
//   修正後は、repeatを挟んだ同一値のキーフレームもまとめて出力するようになりました。
//   具体例は、Sample/Sample.txtのSample7を参照して下さい。
// * 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で指定するようにし、個別のアプリケーション設定からは削除しました。
// * Mon Apr 25 22:45:55 JST 2016 Naoyuki Sawa
// - 実数の計算式に対応しました。
//   暗黙の型変換のルールは、C言語と同じです。
//   キャスト演算子は、'(int)'と'(double)'のみ対応しています。
// - あくまでも途中計算で実数の計算式が使えるだけであり、最終的には整数にキャストする必要が有る事に注意して下さい。
//   例は、/clip/tool/dTexDefC/winapp.hの同日のコメントを参照して下さい。
// * 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の同日のコメントを参照して下さい。
// * Mon May 08 08:35:51 JST 2017 Naoyuki Sawa
// - ライブラリのバグ修正に伴う、ツールのリビルドを行いました。
//   詳細は、clipmisc.cの'Sun May 07 09:13:01 JST 2017 Naoyuki Sawa'のコメントを参照して下さい。
// * Wed Apr 11 23:59:59 JST 2018 Naoyuki Sawa
// - 「repeat N」を追加しました。
//   詳細は、以下の通りです。
// - これまでは、キーフレーム途中での同一パターンの繰り返しを手作業で書く必要があり、手間がかかる問題が有りました。
//   △変更前の例
//   │MyAnm1
//   │  SprNo_MySpr1, 30
//   │  SprNo_MySpr2, 10
//   │  SprNo_MySpr3, 20
//   │  SprNo_MySpr2, 10
//   │  SprNo_MySpr3, 20
//   │  SprNo_MySpr2, 10
//   │  SprNo_MySpr3, 20
//   │  SprNo_MySpr2, 10
//   │  SprNo_MySpr3, 20
//   │  SprNo_MySpr2, 10
//   │  SprNo_MySpr3, 20
//   │  SprNo_MySpr4
//   │  end
// - 今回「repeat N」を追加した事により、キーフレーム途中での同一パターンの繰り返しを簡単に書けるようになりました。
//   ○変更後の例
//   │MyAnm1
//   │  SprNo_MySpr1, 30
//   │  repeat 5
//   │    SprNo_MySpr2, 10
//   │    SprNo_MySpr3, 20
//   │  end
//   │  SprNo_MySpr4, 30
//   │  end
// - 「repeat N」のネストも可能です。stayタイプ，loopタイプ，repeat...endタイプと組み合わせて使用する事も可能です。
//   ○「repeat N」のネストの例
//   │MyAnm1
//   │  repeat 2
//   │    SprNo_MySpr1, 30
//   │    repeat 2
//   │      SprNo_MySpr2, 10
//   │      SprNo_MySpr3, 20
//   │    end
//   │    repeat 2
//   │      SprNo_MySpr4, 10
//   │      SprNo_MySpr5, 20
//   │      repeat 2
//   │        SprNo_MySpr6, 10
//   │        SprNo_MySpr7, 20
//   │      end
//   │    end
//   │    SprNo_MySpr8, 30
//   │  end
//   │  SprNo_MySpr9, 30
//   │  end
//   ○stayタイプと組み合わせて使用する例
//   │MyAnm1
//   │  SprNo_MySpr1, 30
//   │  repeat 5
//   │    SprNo_MySpr2, 10
//   │    SprNo_MySpr3, 20
//   │  end
//   │  SprNo_MySpr4
//   │  stay
//   ○loopタイプと組み合わせて使用する例
//   │MyAnm1
//   │  SprNo_MySpr1, 30
//   │  repeat 5
//   │    SprNo_MySpr2, 10
//   │    SprNo_MySpr3, 20
//   │  end
//   │  SprNo_MySpr4, 30
//   │  loop
//   ○repeat...endタイプと組み合わせて使用する例
//   │MyAnm1
//   │  SprNo_MySpr1, 30
//   │  repeat			#//┬「repeat」と「repeat N」は同じキーワードを使っていますが役割は全く別の機能である事に注意して下さい。
//   │    repeat 5		#//┘「repeat」は全体ループの制御であり実行時にも認識されます。「repeat N」はコンパイル時に展開されます。
//   │      SprNo_MySpr2, 10
//   │      SprNo_MySpr3, 20
//   │    end
//   │    SprNo_MySpr4, 30
//   │  end
// - 「repeat N」はあくまでも、コンパイル時に展開するだけのマクロ的な機能です。
//   「repeat N」を使用して繰り返しを表現しても、手作業で展開して書いても、出力されるデータに違いは有りません。
//   また「repeat N」にあまり大きな繰り返し回数を指定すると、大きなデータが作成されてしまうので注意して下さい。
// * Thu May 03 23:59:59 JST 2018 Naoyuki Sawa
// - Boehm GCを修正した事に伴い、当ツールもリビルドしました。
//   詳細は、/clip/tool/gc/README.TXTの'Wed May 02 23:59:59 JST 2018 Naoyuki Sawa'のコメントを参照して下さい。
// * Sat May 19 23:59:59 JST 2018 Naoyuki Sawa
// - '-u'オプションを追加しました。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20180519"
//-----------------------------------------------------------------------------
#endif/*__WINAPP_H__*/
