/*
 * $Id: bg_debug.h,v 1.1 2003/02/07 18:15:44 wheeler Exp $
 * デバッグモード
 * $Log: bg_debug.h,v $
 * Revision 1.1  2003/02/07 18:15:44  wheeler
 * Fox's version of libultra and friends.
 *
 * Revision 1.4  1997/02/07  10:33:56  hayakawa
 * 違う型も使えるようにした
 *
 * Revision 1.3  1997/02/07  10:19:17  hayakawa
 * いろいろ変更
 * 使い方説明モード
 *
 * Revision 1.2  1997/01/29  12:01:16  hayakawa
 * 大幅な変更
 *
 * Revision 1.1  1996/11/21  05:31:52  hayakawa
 * Initial revision
 *
 */

#ifndef __BG_DEBUG_H_
#define __BG_DEBUG_H_

#ifndef EXTERN_C
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C extern
#endif /* __cplusplus */
#endif /* EXTERN_C */


#if !USE_DEBUGMODE

#define debugmode_initReg(debugmode, no, defval, help) ((void)(debugmode, no, defval, help))
#define debugmode_initRegF(debugmode, no, defval, flags, help) ((void)(debugmode, no, defval, flags, help))
#define debugmode_reg(debugmode, no) ((void)(debugmode, no), 0)
#define	_REG(no) ((void)(no), (int)0)
#define	_SETREG(no, val) ((void)(no), (int)(val))
#define	REG(name) _REG(0)
#define	SETREG(name, val) _SETREG(0, val)
#define _REGINIT(no, defval, help) ((void)(no, defval, help))
#define REGINITH(name, defval, help) _REGINIT(0, defval, help)
#define REGINIT(name, defval) REGINITH(name, defval, #name)

#else  /* !USE_DEBUGMODE */

#include "controller.h"		/* pad_t */

typedef union debugmode_regvalue_u {
    int i;
    float f;
} debugmode_regvalue_t;

typedef struct debugmode_reg_s {
    int flags;			/* 制御用フラグ */
    debugmode_regvalue_t value;	/* レジスタ値 */
    debugmode_regvalue_t defval; /* デフォルト値 */
    char *help;			/* レジスタ値の説明 */
} debugmode_reg_t;
typedef debugmode_reg_t DebugMode_Reg;

typedef struct debugmode_s {
    int enable;			/* 表示変更するかどうか(記憶は残る) */
    int mode;			/* 制御用フラグ */
    int reg_max;		/* レジスタ数 */
    DebugMode_Reg *regs;	/* レジスタ構造体 */
    int cur_no;			/* 現在のカーソル番号 */
//    int cur_page;		/* 現在のページ番号 */
} debugmode_t;
typedef debugmode_t DebugMode;

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

void debugmode_init(DebugMode *debugmode, int reg_max);
void debugmode_cleanup(DebugMode *debugmode);
void debugmode_move(DebugMode *debugmode, pad_t *pad);
void debugmode_draw(DebugMode *debugmode, Gfx **glistp);
void debugmode_initIReg(DebugMode *debugmode, int no, int defval, char *help);
void debugmode_initIRegF(DebugMode *debugmode, int no, int defval, int flags, char *help);
void debugmode_initFReg(DebugMode *debugmode, int no, float defval, char *help);
void debugmode_initFRegF(DebugMode *debugmode, int no, float defval, int flags, char *help);

#ifdef __cplusplus
} /* extern "C" */
#endif 

#define debugmode_initReg debugmode_initIReg
#define debugmode_initRegF debugmode_initIRegF

#define debugmode_reg(debugmode, n) ((debugmode)->regs[n].value)
#define debugmode_ireg(debugmode, n) (debugmode_reg(debugmode, n).i)
#define debugmode_freg(debugmode, n) (debugmode_reg(debugmode, n).f)

#define DMF_DISPBCD	(1 << 0) /* １０進表示 */
#define DMF_DISPOCT 	(1 << 1) /* ８進表示 */
#define DMF_DISPHEX 	(1 << 2) /* １６進表示 */
#define DMF_DISPBIN 	(1 << 3) /* ２進表示 */
#define DMF_DISPFLT 	(1 << 4) /* float進表示 */
#define DMF_DISPDBL 	(1 << 5) /* double進表示 */
#define DMF_READONLY 	(1 << 6) /* 値変更不可 */
#define DMF_POINTER 	(1 << 7) /* ポインタ型 */

/* グローバル用 */
extern DebugMode debugmode;		/* デバッグモード */
#define	_IREG(no) debugmode_ireg(&debugmode, no)
#define	_SETIREG(no, val) (debugmode_ireg(&debugmode, no) = (val))
#define	_FREG(no) debugmode_freg(&debugmode, no)
#define	_SETFREG(no, val) (debugmode_freg(&debugmode, no) = (val))
#define	_REG(no) _IREG(no) 
#define	_SETREG(no, val) _SETIREG(no, val) 
#define	REG(name) _REG(REG_##name)
#define	SETREG(name, val) _SETREG(REG_##name, val)
#define	IREG(name) _IREG(REG_##name)
#define	SETIREG(name, val) _SETIREG(REG_##name, val)
#define	FREG(name) _FREG(REG_##name)
#define	SETFREG(name, val) _SETFREG(REG_##name, val)
#define _IREGINIT(no, defval, help) debugmode_initIReg(&debugmode, no, defval, help)
#define _FREGINIT(no, defval, help) debugmode_initFRegF(&debugmode, no, defval, DMF_DISPFLT, help)
#define _REGINIT(no, defval, help) _IREGINIT(no, defval, help)
#define IREGINIT(name, defval) _IREGINIT(REG_##name, defval, #name)
#define IREGINITH(name, defval, help) _IREGINIT(REG_##name, defval, help)
#define FREGINIT(name, defval) _FREGINIT(REG_##name, defval, #name)
#define FREGINITH(name, defval, help) _FREGINIT(REG_##name, defval, help)
#define REGINIT(name, defval) _REGINIT(REG_##name, defval, #name)
#define REGINITH(name, defval, help) _REGINIT(REG_##name, defval, help)

enum REG_e {
    REG_0 = 0,
    REG_ZERO = REG_0,
    REG_ZBufferPointer,
    REG_DispFuncParam,
    REG_VERBOSE,
    REG_EXT_GFXLIST,
    REG_BG_BEGIN,
    REG_BG_END = REG_BG_BEGIN + 10,
    REG_NEWRENDER_BEGIN,
    REG_NEWRENDER_END = REG_NEWRENDER_BEGIN + 10,
    REG_BG_BG_DRAW_BEGIN,
    REG_BG_BG_DRAW_END = REG_BG_BG_DRAW_BEGIN,
    REG_BG_POLYGON_BEGIN,
    REG_BG_POLYGON_END = REG_BG_POLYGON_BEGIN,
    REG_BG_RECT_BEGIN,
    REG_BG_RECT_END = REG_BG_RECT_BEGIN,
    REG_BG_TASK_BEGIN,
    REG_BG_TASK_END = REG_BG_TASK_BEGIN,
    REG_FBMGR_BEGIN,
    REG_FBMGR_END = REG_FBMGR_BEGIN,
    REG_RASTER_BEGIN,
    REG_RASTER_END = REG_RASTER_BEGIN + 1,
    REG_BGTEST_BEGIN = 50,
    REG_BGTEST_END = REG_BGTEST_BEGIN + 30,
    REG_PadNowButton = 90,
    REG_PadOnButton,
    REG_PadOffButton,
    REG_MAX
};

#endif /* !USE_DEBUGMODE */

#endif /* __BG_DEBUG_H_ */
