#ifndef WAIT_H_INCLUDED
#define WAIT_H_INCLUDED


/***********************************************************************
 * ウェイト調整処理 (システム依存)
 ************************************************************************/

/****************************************************************************
 * ウェイト調整処理の初期化／終了
 *
 * int  wait_vsync_init(void)
 *      システム依存のウェイト調整処理の初期化を行う。
 *      成功したら真、失敗したら偽を返す。
 *      この関数は、起動時に 1回だけ呼び出される。
 *
 * void wait_vsync_exit(void)
 *      システム依存のウェイト調整処理の後始末を行う。
 *      この関数は、終了時に 1回だけ呼び出される。
 *
 *****************************************************************************/
int  wait_vsync_init(void);
void wait_vsync_exit(void);


/****************************************************************************
 * ウェイト調整処理の設定
 *
 * void wait_vsync_setup(long vsync_cycle_us, int do_sleep)
 *      ウェイト調整処理の設定を行う。
 *
 *      long vsync_cycle_us … ウェイトの周期 (us)
 *      int  do_sleep       … 真なら、ウェイト中は CPU を Sleep させる。
 *                             (Sleep できない場合は、しなくてもよい)
 *
 *      この関数は、各モード (エミュ/メニュー/一時停止) の開始時や、設定の
 *      変更時に呼び出される。
 *      この関数が呼び出されたら、設定を変更してから、内部タイマーの初期化等を
 *      行い、ウェイトのタイミング合わせを開始する。
 *
 *****************************************************************************/
void wait_vsync_setup(long vsync_cycle_us, int do_sleep);


/****************************************************************************
 * ウェイト調整処理の実行
 *
 * int  wait_vsync_update(void)
 *      ウェイト調整を行う。
 *      前回この関数が呼ばれた時から、今回この関数が呼ばれた時までを計測し、
 *      wait_vsync_setup() で設定した時間 vsync_cycle_us [μsec] が経過したかを
 *      チェックする。
 *
 *      まだ経過していない場合は、時間が経過するまで待つ。(wait_vsync_setup()
 *      で設定した do_sleep に応じて、可能なら CPU を Sleep させて待つ)
 *      時間が経過したら、直ちに WAIT_JUST を返す。
 *
 *      すでに経過している場合は、直ちに WAIT_OVER を返す。
 *      (この時、ウェイト合わせのタイミングを再度調整してもよい。実装依存)
 *
 *      なお、 WAIT_YET を返してはいけない。
 *
 *****************************************************************************/
enum {
	WAIT_YET,			/* まだ時間経過してない */
	WAIT_JUST,			/* ちょうど時間になった */
	WAIT_OVER			/* 時間超過してる！ */
};
int wait_vsync_update(void);



/****************************************************************************
 * システム経過時間の取得
 *
 * void wait_get_current_time(union wait_time *time)
 *      経過時間を計測するために、起点の情報 (現在時刻) を *time に取得する。
 *      この内容はシステム依存で、呼び出し元は関知しない。
 *
 * int  wait_calc_elasped_time_ms(const union wait_time *got_time)
 *      *got_time (wait_get_current_time で取得した起点の情報) から、
 *      現在時刻までの経過時間を ms 単位で返す。
 *      1ms に満たない場合は、 0 を返す。
 *
 *****************************************************************************/
union wait_time {
	unsigned char  c[8];
	unsigned short s[4];
	unsigned int   i[2];
	unsigned long  l[1];
};
void wait_get_current_time(union wait_time *time);
int  wait_calc_elasped_time_ms(const union wait_time *got_time);


#endif /* WAIT_H_INCLUDED */
