/*
 ******************************************************************************
 *              
 *      メイン処理ヘッダー
 *      $Id: main.h,v 1.1 2003/05/30 21:25:28 tong Exp $
 ******************************************************************************
 */
#if      !defined(__MAINH)
#define  __MAINH
#include "system.h"
#include "main_h.h"
#include "controllerx.h"
#include "envManager.h"
#include "viewManager.h"
#include "frameManager.h"
#include "worldManager.h"
#include "castManager.h"
#include "actorEManager.h"
#include "nxgotoManager.h"
#include "clipbdManager.h"
#include "saveManager.h"
#include "warpManager.h"

/* ゲームステータスの構造 */
typedef char    t_gsns;
typedef char    t_gsrt;
typedef char    t_gppm;
typedef char    t_gsps;
typedef char    t_gfrz;
typedef char    t_spfz;
typedef struct game_status {
        t_gsns  newScene;	/* 新しいシーンが生成されているとき TRUE */
        t_gsrt  reset;   	/* リセットのときON */
        t_gfrz  freeze;		/* 停止のときON(特定アクターを除き停止のとき)*/
        t_gppm  pousePermi;	/* ポーズ許可フラグ */
        t_gsps  pouse;	        /* ポーズのときON */
#if USE_SUPER_FREEZE
        t_spfz  spFreeze;	/* スーパーフリーズ
				   (いつでも"停止"することができる) */
#endif
} GMSTAT;
#define GMSTATUS_()              GAME_().status
/* シーン生成ステータス */
enum scene_status {
     MAKING_COMPLETE_NEWSCENE,
     MAKING_NOW_NEWSCENE,
     CHANGE_NEWSCENE
};
#define is_newScene()            (GMSTATUS_().newScene == MAKING_NOW_NEWSCENE)
#define is_changeScene()         (GMSTATUS_().newScene == CHANGE_NEWSCENE)
#define newScene(s)              (GMSTATUS_().newScene = (s))
/* リセットフラグを設定 */
#define set_reset()              (GMSTATUS_().reset = TRUE)
#define clr_reset()              (GMSTATUS_().reset = FALSE)
#define is_reset()               (GMSTATUS_().reset)
/* ポーズフラグを設定 */
#define is_pousePermi()          (GMSTATUS_().pousePermi)
#define pousePermi_OFF()         (GMSTATUS_().pousePermi = FALSE)
#define pousePermi_ON()          (GMSTATUS_().pousePermi = TRUE)
#define set_pouseFg(v)           (GMSTATUS_().pouse = (v))
#define get_pouseFg()            (GMSTATUS_().pouse)
#define is_pouse()               (get_pouseFg() && is_pousePermi())
int set_pouse(t_gsps);
/* 停止設定 */
#define get_freezLv()		(GMSTATUS_().freeze)

#define is_pause()              (GMSTATUS_().freeze == PAUSE)
#define set_pause()             (GMSTATUS_().freeze = PAUSE)
/* ポーズが上位に立つ */
#define is_freeze()              (GMSTATUS_().freeze != MELT)
#define set_freeze()             (GMSTATUS_().freeze = FREEZE)
#define is_melt()                (GMSTATUS_().freeze == MELT)
#define set_melt()               (GMSTATUS_().freeze = MELT)
#if USE_SUPER_FREEZE
/* スーパーフリーズ */
#define is_spFreeze()            (GMSTATUS_().spFreeze != MELT)
#define spFreeze_ON()            (GMSTATUS_().spFreeze = FREEZE)
#define spFreeze_OFF()           (GMSTATUS_().spFreeze = MELT)
#endif
/**** 時限情報 ****/
typedef struct limit_time {
    unint switchCnt;	/* スイッチのカウンター */
    unint switchFlag;   /* ON or OFF */
} LIMTIME;
#define get_limitTime()          (GAME_().limitTime)
#define get_switchCnt()          (get_limitTime().switchCnt)
#define set_switchCnt(n)         (get_switchCnt() = (n))
#define is_switchCnt_ON()        (get_switchCnt() > 0)

#define get_switchFlag()         (get_limitTime().switchFlag)
#define set_switchFlag(dt)       (get_switchFlag() = (dt))


/* 表示後処理の情報 */
typedef void (*DSAFPC)(void *);
typedef struct display_after_process_entry {
        void    *prm;
        DSAFPC  process;
} DAPETY;

#define MAX_DSAFPROC             20
typedef short  t_dafp;
typedef struct display_after_process_information {
        t_dafp  dspAftPc_id;
        DAPETY  dspAfterProcS[MAX_DSAFPROC];
} DAPINF;
#define DAPINFp_(g)              ((g)->dspAftPrcInfo)
#define getP_dspAfterProcS(g)    (DAPINFp_(g).dspAfterProcS)
#define get_dspAftPc_id(g)       (DAPINFp_(g).dspAftPc_id)
#define reset_dspAftPc_id(g)     (DAPINFp_(g).dspAftPc_id = 0)
#define inc_dspAftPc_id(g)       (++DAPINFp_(g).dspAftPc_id)
int regist_displayAfterProc(DSAFPC, void *);
/* ゲーム情報の構造
   (すべての処理の中心となる) */
typedef char   t_os;
typedef char   t_bkot;
typedef int    t_gmpg;
typedef void   (*MEPROC)(ACTORIF *);
struct game_born {
       t_os    orgScene;	 /* 電源投入時, ハードリセットから最初の
				    シーンが表示されるまで ON になる */

       t_gmmd  next_gameMode;	 /* 次のシーンのゲーム処理のモード */
       t_gmmd  gameMode;	 /* 現在のゲーム処理のモード */

       GMSTAT  status;		 /* "ゲーム"の状態情報 */
       CONTIF  controllerInfo;	 /* コントローラの入力情報 */
       INPROC  inputProc;	 /* 入力変換処理へのポインター */
       GMPROC  process;		 /* [メイン処理] へのポインター */
       t_bkot  useBlackout;	 /* 画面のブラックアウト使用/未使用 */
       DSPROC  display;		 /* 表示処理へのポインター */
       DAPINF  dspAftPrcInfo;	 /* 表示後処理の情報へのポインター */

       GMPROC  deconstProc;      /* [後始末処理]へのポインター */
       GMPROC  const1Proc;       /* [画面の出力]直前の初期化へのポインター */
       GMPROC  const2Proc;       /* [画面の出力]直後の初期化2へのポインター */

       t_cnt   frameCnt;	 /* フレームカウンター */
       BG_Zentai SpriteInfo;	 /* スプライトライブラリーの中核情報 */
       void    *zBuffer;	 /* (Z)バッファへのポインター */
       DMAINF  dmaInfo;	         /* DMA関連情報 */

       t_sig   prgWait;          /* プログラマブルウェイト */
       t_sig   actorSignal;	 /* アクターシグナル */
       t_sig   BgDrawSignal;	 /* BGの描画シグナル */

       t_gmpg  page;
       t_gmpg  newPage;
    
       VIEWIF  viewInfo;	 /* 視点情報 */
       FRMINF  frameInfo;	 /* フレーム情報 */
       WRLDIF  worldInfo;	 /* ワールド情報 */
       WARPIF  warpInfo;	 /* ワープ情報 */
       CTLTIF  castLstInfo;	 /* キャスティングリスト情報 */
       NXGTIF  nxgotoInfo;	 /* "Next-Goto"情報 */
       ACTORIF actorInfo;	 /* アクター情報 */
       PIPEIF  pipeInfo;	 /* パイプ情報 */

       unchar  oam_buffNum;	   /* 現在のOAMバッファ番号 */
       void    *oamInfo[DRAW_TYPE];/* OAM情報へのポインター */

       CLPBDIF clipboardInfo;    /* クリップボード */
       SAVEIF  saveInfo;	 /* セーブ情報 */

       ENVRIF  enviroInfo;	 /* 環境情報 */
       LIMTIME limitTime;        /* 時限情報 */
};
#define GAME_()              (__Game)
#define GAME_P()             (&__Game)
#define get_game()           (GAME_())
#define getP_game()          (GAME_P())
#define getP_SpriteInfo()    (&GAME_().SpriteInfo)
/* 初期シーンの確認 */
#define start_orgScene()     (GAME_().orgScene = TRUE)
#define end_orgScene()       (GAME_().orgScene = FALSE)
#define is_orgScene()        (GAME_().orgScene == TRUE)
/* ゲーム処理モードを設定 */
#define set_gameMode(m)      (GAME_().gameMode = (m))
#define get_gameMode()       (GAME_().gameMode)
#define set_nextGameMode(m)  (GAME_().next_gameMode = (m))
#define get_nextGameMode()   (GAME_().next_gameMode)
#define renew_gameMode()     set_gameMode(get_nextGameMode())

#define is_seisan()          is_SEISAN(get_gameMode())
#define is_option()          is_OPTION(get_gameMode())
#define is_priclub()         is_PRICLUB(get_gameMode())
#define is_turesariDemo()    is_TURESARIDEMO(get_gameMode())
#define is_title()           is_TITLE(get_gameMode())
#define is_fruitSelMode()    is_FRUITSELECT(get_gameMode())
#define is_clearDemo()       is_CLEARDEMO(get_gameMode())
#define is_shopDemo()        is_SHOPDEMO(get_gameMode())
#define is_scenarioMode()    is_SCENARIOMODE(get_gameMode())
#define is_exerciseMode()    is_EXERCISE(get_gameMode())
#define is_trialMode()       is_TRIALMODE(get_gameMode())
#define is_playerSelMode()   is_PLAYERSELECT(get_gameMode())
#define is_playGame()        (is_scenarioMode() || is_trialMode() \
                              || is_exerciseMode())
#define is_nextPlayGame()    (is_SCENARIOMODE(get_nextGameMode()) \
                              || is_TRIALMODE(get_nextGameMode()) \
                              || is_EXERCISE(get_nextGameMode()))
#define is_nextShopDemo()    is_SHOPDEMO(get_nextGameMode())
#define is_retryGame()       (get_gameMode() == RETRY)
#define is_gameOver()        is_GAMEOVER(get_gameMode())
#define is_gameMiss()        (get_gameMode() == GAMEMISS)
/* ゲームの処理ページ */
#define set_gamePage(v)      (GAME_().page = (v))
#define get_gamePage()       (GAME_().page)
#define set_newGamePage(v)   (GAME_().newPage = (v))
#define get_newGamePage()    (GAME_().newPage)
int change_gamePage(void);
/* ゲームの入力処理 */
#define chg_inputProc(p)     (GAME_().inputProc = (p))
#define ROCK_ON_INPUT        ((INPROC)NOPFUNC)
/* フレームカウンターの処理 */
#define get_frameCnt()       (GAME_().frameCnt)
#define set_frameCnt(v)      (GAME_().frameCnt = (t_cnt)(v))
#define reset_frameCnt()     (GAME_().frameCnt = (t_cnt)0)
#define frameCount()         (GAME_().frameCnt += 1)
/* Zバッファ設定 */
#define setP_ZBuffer(p)      (GAME_().zBuffer = (p))
#define getP_ZBuffer()       (GAME_().zBuffer)
#define is_availableZBuffer() (GAME_().zBuffer)
#define regist_zBuffer(p)    bg_SetZBuffer(&get_game().SpriteInfo, (p))
/* 処理フレーム数の設定 */
#if 0
#define set_keepFrame(n)     zen_setKeepFrame(n)
#endif
extern  u8 bg_zentai_keep_frame;
#define set_keepFrame(n)     (bg_zentai_keep_frame = (u8)(n))
#define get_keepFrame()      zen_getKeepFrame()
/* シグナル処理 */
enum dispaly_blackout_mode {USE_BLACKOUT, UNUSE_BLACKOUT};
#define is_useBlackout()     (GAME_().useBlackout == USE_BLACKOUT)
#define unuse_blackout()     (GAME_().useBlackout = UNUSE_BLACKOUT)
#define use_blackout()       (GAME_().useBlackout = USE_BLACKOUT)
/* シグナル処理 */
enum programabule_normal_wait {NOWAIT_ALLACTOR, WAIT_ALLACTOR};
#define set_prgWait(m)       (GAME_().prgWait = (m))
#define get_prgWait()        (GAME_().prgWait)

#define get_signal()         (GAME_().actorSignal)
#define set_signal(s)        (GAME_().actorSignal = (s))
#define clear_signal()       (GAME_().actorSignal = CLEAR_SIGNAL)
#define is_freeSignal()      (get_signal() == FREE_SIGNAL)
enum actor_signal {CLEAR_SIGNAL, FREE_SIGNAL, ACTOR_SIGNAL};
#define get_BgDrawSignal()   (GAME_().BgDrawSignal)
#define set_BgDrawSignal(s)  (GAME_().BgDrawSignal = (s))
#define clr_BgDrawSignal()   (GAME_().BgDrawSignal = FALSE)
void const_sceneInfo(GAME *);
void deconst_sceneInfo(GAME *);
#if USE_SLEEP_WAKEUP
void sleep_sceneInfo(GAME *);
void wakeup_sceneInfo(GAME *);
#endif
void set_restart(GMPROC, GMPROC, GMPROC);
void setAll_restart(GMPROC, GMPROC, GMPROC);
void inputProcess(GAME *);
void available_zBuff(void);
void unavailable_zBuff(void);

void subresetGame(void);
#endif
