/*
 * $Id: bguty.h,v 1.1 2003/02/07 18:15:44 wheeler Exp $
 *
 * ユーティリティ
 *
 * $Log: bguty.h,v $
 * Revision 1.1  2003/02/07 18:15:44  wheeler
 * Fox's version of libultra and friends.
 *
 * Revision 1.29  1997/01/29  12:04:16  hayakawa
 * 細かい修正
 *
 * Revision 1.28  1996/12/02  05:34:04  hayakawa
 * HungUp_func、Reset関数の削除
 *
 * Revision 1.27  1996/11/21  06:20:35  hayakawa
 * メンバ関数の削除（移動）
 *
 * Revision 1.26  1996/10/29  12:44:19  hayakawa
 * BG_AUTO_DISABLE削除
 *
 * Revision 1.25  1996/10/20  09:09:28  hayakawa
 * いろいろ修正
 * 条件コンパイル化
 *
 * Revision 1.24  1996/10/01  05:19:58  hayakawa
 * HungUpのときにファイル名と行番号を出せるようにした
 * ライン用の init マクロを追加
 *
 */

#ifndef __BGUTY_H_
#define __BGUTY_H_

#include "stddef.h"
#include "bg.h"
#include "dynamic.h"		/* dynamicp */

#ifdef __cplusplus
extern "C" {
#endif

#if  G_IM_SIZ_8b == G_IM_SIZ_4b + 1 && G_IM_SIZ_16b == G_IM_SIZ_8b + 1 && G_IM_SIZ_32b == G_IM_SIZ_16b + 1
#define getbits(siz) (4 << ((siz) - G_IM_SIZ_4b))
#define getbytes(siz)       ((     1 << ((siz) - G_IM_SIZ_4b)     ) >> 1)
#define getbytes2(siz, dot) ((((dot) << ((siz) - G_IM_SIZ_4b)) + 1) >> 1)
#else
#define getbits(siz) f_getbits(siz, __LINE__)
int
f_getbits(
    const int siz,
    const int line
);
#endif

#define setColor4(rgba1, r1, g1, b1, a1) ((rgba1).r = (r1), (rgba1).g = (g1), (rgba1).b = (b1), (rgba1).a = (a1))
#define zen_setProjection(m1)		(BGzenPtr->Projection = (m1))
#define zen_setPerspNorm(n1)		(BGzenPtr->PerspNorm = (n1))
#define zen_setViewport(m1)		(BGzenPtr->Viewport = (m1))
#define zen_getFillColor()		(BGzenPtr->FillColor)
#define zen_setFillColor(rgba)		(BGzenPtr->FillColor = (rgba))
#define zen_setFillColor4(r1, g1, b1, a1) (setColor4(BGzenPtr->FillColor, r1, g1, b1, a1))
#define zen_setScissor(s1)		(BGzenPtr->Scissor = (s1))
#define zen_setScissor4(xl1, yl1, xh1, yh1) (BGzenPtr->Scissor.xl = (xl1), BGzenPtr->Scissor.yl = (yl1), BGzenPtr->Scissor.xh = (xh1), BGzenPtr->Scissor.yh = (yh1))

#define zen_setUcode(p1, p2) (BGzenPtr->ucode = (u64 *)(p1), BGzenPtr->ucode_data = (u64 *)(p2))
#define zen_getColorImage()		(BGzenPtr->Image.ColorImage)


#define BG_setZentai(p1)	(BGzenPtr = (p1))
#define BG_setZsort(p1, n1)	(BGzsPtr = (p1), BGzsMax = (n1))

#define bgptr_dalloc(p1, siz1) (xdalloc((Dynamic_t *)(p1), siz1))
#define bgptr_dalloc2(p1, type, num) (xdalloc2((Dynamic_t *)(p1), type, num))
#define bgptr_getGlistp(p1) ((Gfx *)((Dynamic_t *)(p1))->bg.BGglistp)
#define bgptr_setGlistp(p1, p2) (*((Gfx **)&(((Dynamic_t *)(p1))->bg.BGglistp)) = (p2))
#define bgptr_getCfb(p1) ((void *)bgptr_getImage(p1)->ColorImage)
#define bgptr_getImage(p1) (&(((Dynamic_t *)(p1))->bg.Image))
#define bgptr_getScissor(p1) (&(((Dynamic_t *)(p1))->bg.Scissor))

#define bgfuncx_isenable(p1) 	(!((p1)->attr & BG_FUNC_HIDDEN))
#define bgfuncx_enable(p1) 	((p1)->attr &= ~BG_FUNC_HIDDEN)
#define bgfuncx_disable(p1) 	((p1)->attr |= BG_FUNC_HIDDEN)
#define bgfuncx_setAttr(p1, n1) 	((p1)->attr = n1)
#define bgfuncx_setFunc(p1, f1) 	((p1)->func = (f1))
#define bgfuncx_getFunc(p1) 	((p1)->func)
#define bgfuncx_getPtr(p1) ((p1)->ptr)
#define bgfuncx_setPtr(p1, ptr1) ((p1)->ptr = (ptr1))
#define bgfuncx_setZpos(p1, z1) ((p1)->zPos = (z1))
#define bgfuncx_init(p1, func1, ptr1, attr1, zpos1) ( \
	bgfuncx_setFunc(p1, func1), \
	bgfuncx_setPtr(p1, ptr1), \
	bgfuncx_setAttr(p1, attr1), \
	bgfuncx_setZpos(p1, zpos1))
#define bgfuncx_init_gfxlist(p1, ptr1, zpos1) ( \
	bgfuncx_setFunc(p1, NULL), \
	bgfuncx_setPtr(p1, ptr1), \
	bgfuncx_setAttr(p1, BG_FUNC_GFXLIST), \
	bgfuncx_setZpos(p1, zpos1))
#define bgfuncx_init_linegfxlist(p1, ptr1, zpos1) ( \
	bgfuncx_setFunc(p1, NULL), \
	bgfuncx_setPtr(p1, ptr1), \
	bgfuncx_setAttr(p1, BG_FUNC_LINEGFXLIST), \
	bgfuncx_setZpos(p1, zpos1))

void
lut_init(
    const int num,		/* ルックアップテーブル番号 */
    unsigned short *const tlut	/* ルックアップテーブルへのポインタ */
);

/*
 * 指定座標がシザーボックス内かどうかを返す
 * ただし、s1 が NULL の時はシザーボックス内とする
 */
#define \
InScissorBox(\
	     /* bg_Scissor_t */ s1, /* シザーボックス構造体 */ \
	     /* int          */ x1, /* Ｘ位置               */ \
	     /* int          */ y1) /* Ｙ位置               */ \
((s1) == NULL || \
 ((s1)->yl <= (y1) && (y1) < (s1)->yh && \
  (s1)->xl <= (x1) && (x1) < (s1)->xh))

/* 注意：Fb_pset, Fb_pget のマクロ版は範囲チェックを行っていません */
#define Fb_pset(cfb, x1, y1, c1) (*((u16 *)(cfb) + (y1) * SCREEN_WD + (x1)) = (c1))
#define Fb_pget(cfb, x1, y1)     (*((u16 *)(cfb) + (y1) * SCREEN_WD + (x1)));

void fb_pset_new( bg_Image_t *img, bg_Scissor_t *sci, const int x, const int y, const unsigned short c );
void fb_pset( const int x, const int y, const unsigned short c );
int  fb_pget_new( bg_Image_t *img, bg_Scissor_t *sci, const int x, const int y );
int  fb_pget( const int x, const int y );
void fb_get_rectangle( const int xl, const int yl, const int xh, const int yh, void *const buf );
void fb_Mosaic(void *const ptr);
void *VtxMalloc( const size_t siz );

#define xdalloc(dp, siz) ((dp)->bg.BGglistrp = (Gfx *)((char *)(dp)->bg.BGglistrp - (siz)))
#define xdalloc2(dp, type, num)  ((type *)xdalloc(dp, sizeof(type) * (num)))
#define dalloc(siz) xdalloc(dynamicp, siz)
#define dalloc2(type, num)  xdalloc2(dynamicp, type, num)

#define getTexRect() dalloc2(Gtexrect, 1)
#define getVtx() dalloc2(Vtx, 4)
#define getMtx() dalloc2(Mtx, 1)
#define GetTMEMSize(fmt) (((fmt) == G_IM_FMT_CI) ? TMEM_SIZE_HALF : TMEM_SIZE_FULL)

Gfx *bgRegionInit(void *const regionp);
int bgRegionCheck(const int siz);


#ifdef __cplusplus
} /* extern "C" */
#endif

#endif
