/*****************************************************************************
 * 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_SprFnt {
	struct _ST_SprFntHdr*	pSprFntHdr;		//スプライトフォントヘッダ
	struct _ST_SprFntBody*	pSprFntBody;		//スプライトフォントボディ
} ST_SprFnt;
ST_SprFnt* SprFnt_New(struct _ST_SprFntHdr* pSprFntHdr, struct _ST_SprFntBody* pSprFntBody);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//スプライトフォントヘッダ
typedef struct _ST_SprFntHdr {
	char*			pSprFntLabel;		//スプライトフォントラベル								NULL不可
	int			iNextX;			//列ストライド。この文字を描いた後、この値の分、右へ進みます。				0〜0xFFFFFF(符号付き24ビット値を符号無し24ビット値にマスクした値)	パース処理においては、値が省略されたら(=Value_New()が-1)を返したら)0とする。出力処理においては、値が省略されたか又は明示的に0が指定された事によってこのフィールドが0ならば、当ツールはiNextXをレジストリテーブルに出力しない。実行時は、レジストリテーブルに値が格納されていなければ0と見なす(データ削減のためです)。レジストリテーブルに値が格納されていた場合は、取得した値のbit23を符号拡張して元の値に戻せ。
	int			iNextY;			//行ストライド。一行に描いた文字の、この値の内、最大の値の分、改行時に下へ進みます。	同上です。								同上です。
	int			iDrawX;			//描画オフセットX。スプライト原点Xを、この位置に描画します。				同上です。								同上です。
	int			iDrawY;			//描画オフセットY。スプライト原点Yを、この位置に描画します。				同上です。								同上です。
} ST_SprFntHdr;
ST_SprFntHdr* SprFntHdr_New(char* pSprFntLabel, int iNextX, int iNextY, int iDrawX, int iDrawY);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//スプライトフォントボディ
typedef struct _ST_SprFntBody {
	ght_hash_table_t*	ht_pSprFntRow;		//0(fallback),又は,文字コード(1〜0xFFFF)⇒(ST_SprFntRow*)
} ST_SprFntBody;
ST_SprFntBody* SprFntBody_New(struct _ST_SprFntRow* pSprFntRow);
ST_SprFntBody* SprFntBody_AddRow(ST_SprFntBody* pSprFntBody, struct _ST_SprFntRow* pSprFntRow);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//スプライトフォント行
typedef struct _ST_SprFntRow {
	int			iSprFntChar;		//0(fallback),又は,文字コード(1〜0xFFFF)
	int			iSprNo;			//0(blank),又は,スプライト番号(1〜0xFFFF)															iSprNoは常にレジストリテーブルに出力する。0(blank)でも出力する。出力を省略する事はしない。もし省略するとキーが空になる可能性が生じて、実行時にエラー判定が出来なくなるからです。
	int			iNextX;			//ST_SprFntHdrの説明を参照して下さい。							-1(省略),又は,0〜0xFFFFFF(省略無し)					値が省略された(-1)らレジストリテーブルに出力しない。値が省略されなかった(0〜0xFFFFFF)がST_SprFntHdrのデフォルト値(0〜0xFFFFFF)と同じならば、レジストリテーブルに出力しない。実行時は、この文字のキーから値を取得し、値が無ければスプライトフォントのキーの直下からデフォルト値を取得し、それも無ければ暗黙のデフォルト値である0と見なせ。
	int			iNextY;			//同上です。										同上です。
	int			iDrawX;			//同上です。										同上です。
	int			iDrawY;			//同上です。										同上です。
} ST_SprFntRow;
ST_SprFntRow* SprFntRow_New(int iSprFntChar, int iSprNo, int iNextX, int iNextY, int iDrawX, int iDrawY);
//-----------------------------------------------------------------------------
//定数定義
//-----------------------------------------------------------------------------
#undef  INT24_MIN		//┐
#undef  INT24_MAX		//├念のため確実に未定義としておく。(Microchipのヘッダファイル等では定義されているみたいです。)
#undef  UINT24_MAX		//┘
#define INT24_MIN		(INT32_MIN>>8)
#define INT24_MAX		(INT32_MAX>>8)
#define UINT24_MAX		((int)(UINT32_MAX>>8))	//(int)が必要です。忘れると、SprFntHdr_New()やSprFntRow_New()でのint変数との比較の際に、間違ってunsignedで比較してしまう。
//-----------------------------------------------------------------------------
//グローバル関数宣言
//-----------------------------------------------------------------------------
int cast_dbl_to_int(double d);
void addSprFnt(ST_SprFnt* pSprFnt);
//{{2017/04/12変更:文字コードを、文字列だけでなく、数値でも指定出来るようにしました。
//int SprFntChar_New(char* pSprFntChar);
//↓2017/04/12変更:文字コードを、文字列だけでなく、数値でも指定出来るようにしました。
int SprFntChar_NewStr(char* pSprFntChar);
int SprFntChar_NewVal(int iSprFntChar);
//}}2017/04/12変更:文字コードを、文字列だけでなく、数値でも指定出来るようにしました。
int SprNo_New(int iSprNo);
int Value_New(int iValue);
//-----------------------------------------------------------------------------
//変更履歴
//-----------------------------------------------------------------------------
// * Sat Mar 18 22:13:04 JST 2017 Naoyuki Sawa
// - 1st リリース。
//   dVslDefCをベースにして作成しました。
// - 当ツールが出力したデータを利用するには、clipsprf.cの関数を使用して下さい。
// * Mon Mar 20 22:44:17 JST 2017 Naoyuki Sawa
// - スプライトフォントラベルの一文字がCシンボル文字でなかった場合、先頭に「`」を付けてレジストリスクリプトに出力するように修正しました。
// * Wed Apr 12 22:29:29 JST 2017 Naoyuki Sawa
// - 文字コードを、文字列だけでなく、数値でも指定出来るようにしました。
//   既存の、文字列で指定する仕様では、「"」と「\」を指定出来なかったからです。
//   「"」は、当ツールのlex.yy.lの仕様上の制限で、文字列の中で「"」をエスケープ出来ないからです。
//   「\」は、当ツールのlex.yy.lの仕様上は問題無いのですが、MkSprFnt.batにてcpp.exeを通した時に、"\"に対してcpp.exeがunterminated stringエラーになってしまうからです。
//   文字コードを数値でも指定出来るようにすれば、上記のどちらも解決出来るので、そうする事にしました。
// - 別の案として、lex.yy.lが文字列をC言語文字列のように解釈してエスケープする案も考えたのですが、それではlex.yy.lの変更が大掛かりになり過ぎてエンバグが怖い事や、
//   既にこれまでに作成した他のツールのスクリプトが「\」はエスケープ文字ではないと想定して「C:\Foo\Bar.txt」のような文字列をたくさん使っており、
//   各ツールのlex.yy.lの共通化の観点から、lex.yy.lを大幅に変えるのは避けたいので、今回はlex.yy.lを変更せずに、上記のように文法の変更で対応する事にしました。
//   実際の所、文字列中に特殊な文字を使いたいツールは当ツールぐらいなので、この方法で問題無いと思います。
// - 今回の変更により、「"」の定義は、「0x22 = SprNo_DOUBLE_QUOTATION」と書けるようになりました。
//   また、「\」の定義は、「0x5C = SprNo_BACK_SLASH」と書けるようになりました。
//   「"」と「\」に限らず、その他の文字や、二バイト文字も、数値で指定出来ます。
//   例えば「表」などの、2バイト目が「\」でcpp.exeがエラーになる二バイト文字も、数値で定義する事でエラーを回避出来ます。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20170412"
//-----------------------------------------------------------------------------
#endif/*__WINAPP_H__*/
