/*
 * $Id: debug.h,v 1.1 2003/02/07 18:15:44 wheeler Exp $
 *
 * デバッグ用
 *
 * $Log: debug.h,v $
 * Revision 1.1  2003/02/07 18:15:44  wheeler
 * Fox's version of libultra and friends.
 *
 * Revision 1.20  1997/02/07  10:55:55  hayakawa
 * BATCH
 *
 * Revision 1.19  1996/12/18  01:00:51  hayakawa
 * 移植性のためにコントローラのヘッダ読み込みを廃止した
 *
 * Revision 1.18  1996/12/02  05:35:23  hayakawa
 * HungUp_func、Reset関数の追加
 *
 * Revision 1.17  1996/11/26  10:14:08  hayakawa
 * コントローラで、デバッグコントロールできるようにした
 * ハングアップ用の対応
 *
 * Revision 1.16  1996/11/21  06:21:32  hayakawa
 * XPRINTF、xdispの追加
 *
 * Revision 1.15  1996/10/29  12:45:35  hayakawa
 * DEBUG モードと NOUSE_PRINTF をわけた
 * ワーニング抑止
 *
 * Revision 1.14  1996/10/20  09:10:06  hayakawa
 * _LANGUAGE_C_PLUS_PLUS を __cplusplus に変更
 *
 * Revision 1.13  1996/10/01  05:26:47  hayakawa
 * ポインタがＫ０セグメント中に存在するかどうかのマクロを修正
 *
 */

#ifndef __DEBUG_H_
#define __DEBUG_H_

#include "u64types.h"		/* size_t */

#ifdef __cplusplus
extern "C" {
#endif

#if DEBUG
void dump(void *ptr, size_t siz);
#define HungUp() HungUp_func(__FILE__, __LINE__)
#else
#define dump(ptr, siz)		((void)0)
#define HungUp() {for (;;);}
#endif

#ifdef __cplusplus
} /* extern "C" */
#endif

#if DEBUG && !NOUSE_PRINTF

#define ZPRINTF(args)				\
{						\
    OSPri mythread_pri = osGetThreadPri(NULL);	\
    osSetThreadPri(NULL, OS_PRIORITY_APPMAX);	\
    PRINTF args;				\
    osSetThreadPri(NULL, mythread_pri);		\
}

#define PRINTF osSyncPrintf

#define DBG_NULL(var) { if ((var) == NULL) { \
PRINTF("%s %d:" #var " はヌルポインタです\n", __FILE__, __LINE__); }}

#define DBG_PTR(var) { \
if ((var) == NULL || !(0x80000000 <= (u32)(var) && (u32)(var) < 0x80400000)) { \
PRINTF("%s %d:ポインタ" #var " が異常です %08x\n", __FILE__, __LINE__, (var)); } \
}

#define DBG_RANGE(var, max) { if ((var) > (max)) { \
PRINTF("%s %d:" #var "(%d) > " #max "(%d)\n", \
       __FILE__, __LINE__, (int)(var), (int)(max)); }}

#ifdef __cplusplus
extern "C" {
#endif

float f_debug_range_f(
    char *file,
    int line,
    char *varstr,
    float var,
    char *minstr,
    float min,
    char *maxstr,
    float max
);

void HungUp_func( char *file, int line );		/* ハングアップ */
void Reset( void );		/* リセット */

#ifdef __cplusplus
} /* extern "C" */
#endif

#define DBG_RANGE_F(var, min, max) \
f_debug_range_f(__FILE__, __LINE__, #var, var, #min, min, #max, max)

#define disp(fmt, var) \
PRINTF("%d %s %d:%s = %" # fmt "\n", osGetThreadId(NULL), __FILE__, __LINE__, # var, (var))

#define zdisp(fmt, var) \
ZPRINTF(("%d %s %d:%s = %" #fmt "\n", osGetThreadId(NULL), __FILE__, __LINE__, #var, (var)))

    /*
     * ViewPort内容表示
     */
#define DispViewport(vv) \
    PRINTF("%s %d: [%s] = {\n%d %d %d %d\n%d %d %d %d\n}\n", \
	   __FILE__, __LINE__, #vv, \
	   (vv)->vp.vscale[0], (vv)->vp.vscale[1], \
	   (vv)->vp.vscale[2], (vv)->vp.vscale[3], \
	   (vv)->vp.vtrans[0], (vv)->vp.vtrans[1], \
	   (vv)->vp.vtrans[2], (vv)->vp.vtrans[3])
/*
 * 行列の内容表示(long)
 */
#define DispMatrix(m) \
{ \
    Mtx2u_t *u = &((Mtx2 *)(m))->m2u; \
    PRINTF( "%s %d: [%s] =\n" \
	    "/ %04x.%04x %04x.%04x %04x.%04x %.04x.%04x \\\n" \
	    "| %04x.%04x %04x.%04x %04x.%04x %.04x.%04x |\n" \
	    "| %04x.%04x %04x.%04x %04x.%04x %.04x.%04x |\n" \
	    "\\ %04x.%04x %04x.%04x %04x.%04x %.04x.%04x /\n", \
	    __FILE__, __LINE__, #m, \
	    u->i[0][0], u->f[0][0], u->i[1][0], u->f[1][0], u->i[2][0], u->f[2][0], u->i[3][0], u->f[3][0], \
	    u->i[0][1], u->f[0][1], u->i[1][1], u->f[1][1], u->i[2][1], u->f[2][1], u->i[3][1], u->f[3][1], \
	    u->i[0][2], u->f[0][2], u->i[1][2], u->f[1][2], u->i[2][2], u->f[2][2], u->i[3][2], u->f[3][2], \
	    u->i[0][3], u->f[0][3], u->i[1][3], u->f[1][3], u->i[2][3], u->f[2][3], u->i[3][3], u->f[3][3]); \
}

/*
 * 行列の内容表示(float)
 */
#define DispMatrixf(m) \
PRINTF( "%s %d: [%s] =\n"\
	"/ %12.6f %12.6f %12.6f %12.6f \\\n" \
	"| %12.6f %12.6f %12.6f %12.6f |\n" \
	"| %12.6f %12.6f %12.6f %12.6f |\n" \
	"\\ %12.6f %12.6f %12.6f %12.6f /\n", \
	__FILE__, __LINE__, #m, \
	(m)->mf[0][0], (m)->mf[1][0], (m)->mf[2][0], (m)->mf[3][0], \
	(m)->mf[0][1], (m)->mf[1][1], (m)->mf[2][1], (m)->mf[3][1], \
	(m)->mf[0][2], (m)->mf[1][2], (m)->mf[2][2], (m)->mf[3][2], \
	(m)->mf[0][3], (m)->mf[1][3], (m)->mf[2][3], (m)->mf[3][3])
    

#else  /* DEBUG && !NOUSE_PRINTF */
    
#ifdef __cplusplus
    
inline void _cppprtintf(char *)
{
    return;
}
inline void _cppprtintf(...)
{
    return;
}
#define PRINTF _cppprtintf

#else

#define PRINTF (void)

#endif

#define ZPRINTF PRINTF
#define DBG_NULL(var) ((void)(var))
#define DBG_PTR(ptr) ((void)(ptr))
#define DBG_RANGE(var, max) ((void)(var), (void)(max))
#define DBG_RANGE_F(var, min, max) ((void)(var), (void)(min), (void)(max))
#define disp(fmt, var)		((void)(var))
#define zdisp(fmt, var)		((void)(var))
#define T()			((void)0)
#define DispMatrix(m)		((void)(m))
#define DispMatrixf(m)		((void)(m))
#define DispViewport(vv) 	((void)(vv))

#endif /* DEBUG && !NOUSE_PRINTF */

#define xdisp(fmt, var)		((void)(var))
#define XPRINTF (void)

#define C_BELL 			7
#define BEEP() 			PRINTF("%c", C_BELL) /* ピーと鳴る */

#endif /* __DEBUG_H_ */
