/*
 * $Id: bg_bg.h,v 1.1 2003/02/07 18:15:44 wheeler Exp $
 *
 * $Log: bg_bg.h,v $
 * Revision 1.1  2003/02/07 18:15:44  wheeler
 * Fox's version of libultra and friends.
 *
 * Revision 1.12  1997/03/05  05:52:49  hayakawa
 * 四捨五入していたところを切り捨てにした
 *
 * Revision 1.11  1997/01/29  12:00:08  hayakawa
 * 小数スクロール用のインターフェイス追加
 *
 * Revision 1.10  1996/11/21  05:26:03  hayakawa
 * インクルードするべきファイルをインクルードしていなかった
 *
 * Revision 1.9  1996/11/07  02:24:29  hayakawa
 * 新レンダーモード対応
 *
 * Revision 1.8  1996/10/20  08:54:15  hayakawa
 * _LANGUAGE_C_PLUS_PLUS を __cplusplus に変更
 *
 */

#ifndef __BG_BG_H_
#define __BG_BG_H_

/*
 *
 * イメージバッファの構成図
 *  ←----------------------------- width ------------------------------→
 *  ←----------- xoff ------------→
 *  +----------------------------+--+------------------------------------+^^
 *  |        第4ブロック         :  |                                    |||
 *  +----------------------------+--+                                    |||
 *  |                            :  |                                    |||
 *  |                            :  |                                    | |
 *  |                            :  |                                    |y|
 *  |                            :空|     第2ブロック                    |o|
 *  |         第2ブロック        :  |                                    |f|
 *  |                            :  |                                    |f|
 *  |                            :  |                                    | 
 *  |                            :  |                                    ||h
 *  |                            :  |ll                                  ||e
 *  |                          lr:き+------------------------------------+|i
 *  +----------------------------+--+     空き領域                       ||g
 *  |        空き領域            :領+------------------------------------+Vh
 *  +----------------------------+--+ul                                  | t
 *  |                          ur:域|     第1ブロック                    | 
 *  |         第1ブロック        :  |                                    | |
 *  |                            :  |                                    | |
 *  |                            :  |                                    | |
 *  |                            :  |                                    | |
 *  |                            :  |                                    | |
 *  |                            :  |                                    | |
 *  |                            :  +------------------------------------+ |
 *  |                            :  |     第3ブロック                    | |
 *  +----------------------------+--+------------------------------------+ V
 *  |        １サイクルバイリニア処理のための一時ワーク領域              |
 *  +--------------------------------------------------------------------+
 *
 * フレームバッファへの割り当て図
 *  ←--------------------- width_draw ------------------------------→
 *  +-----------------------------------------------------------------+^
 *  |ul←(xpos,ypos)                                                ur||
 *  |                                                                 ||
 *  |                                                                 ||
 *  |                     第1ブロック                                 ||
 *  |                                                                 | 
 *  |                                                                 |h
 *  |                                                                 |e
 *  |                                                                 |i
 *  |                                                                 |g
 *  +------------------------------------+----------------------------+h
 *  |     第3ブロック                    |        第4ブロック         |t
 *  +------------------------------------+----------------------------+|
 *  |                                                                 |d
 *  |                                                                 |r
 *  |                                                                 |a
 *  |                                                                 |w 
 *  |                     第2ブロック                                 | 
 *  |                                                                 ||
 *  |                                                                 ||
 *  |                                                                 ||
 *  |                                                                 ||
 *  |ll                                                             lr||
 *  +-----------------------------------------------------------------+V
 *
 */

#include "ultra64.h"
#include "u64types.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum bg_bg_drawtype_e {
    BG_BG_DRAWTYPE_COPY_BLOCK,
    BG_BG_DRAWTYPE_COPY_TILE,
    BG_BG_DRAWTYPE_1CYCLE_BLOCK,
    BG_BG_DRAWTYPE_1CYCLE_TILE,
    BG_BG_DRAWTYPE_MAX
} bg_bg_drawtype_t;

typedef struct bg_bg_s {
    int fmt;			/* ピクセルフォーマット */
    int siz;			/* ピクセルサイズ */
    int width;			/* 実際の横ドット数 */
    int height;			/* 実際の縦ライン数(バッファはこれより３ライン多く確保する) */
    void *timg;			/* バッファの先頭ポインタ */
    u16 *tlut;			/* !NULL:パレットのポインタ */
    int tt;			/* パレットのフォーマット(G_TT_xxxx) */
    int width_draw;		/* 表示横ドット数 */
    int height_draw;		/* 表示縦ライン数 */
    int xpos;			/* 左上の点の画面の表示座標 */
    int ypos;			/* 左上の点の画面の表示座標 */
    int xoff;			/* 仮想の左上の点へのオフセット */
    int yoff;			/* 仮想の左上の点へのオフセット */
    int delta_s;		/* スムーススクロール用オフセット */
    int delta_t;
    float xscale;		/* １サイクルモード用の横スケール */
    float yscale;		/* １サイクルモード用の縦スケール */
    Gfx *gfxlist;		/* １サイクル用の追加ディスプレイリスト */
    bg_bg_drawtype_t drawtype;	/* 表示タイプ */
    unsigned int rendmode:8;	/* 0:normal,1xlu_surf,2point */
    rgba8888_u_t primcolor;	/* プリミティブカラー */
    rgba8888_u_t envcolor;	/* 環境カラー */
} bg_bg_t;

/*
 * 初期化
 */
#define bg_bg_init(this1, fmt1, siz1, width1, height1, timg1, tlut1, tt1) \
( \
  (this1)->fmt = (fmt1), \
  (this1)->siz = (siz1), \
  (this1)->width = (width1), \
  (this1)->height = (height1), \
  (this1)->timg = (timg1), \
  (this1)->tlut = (tlut1), \
  (this1)->tt = (tt1), \
  bg_bg_setPosition(this1, 0, 0), \
  bg_bg_setDrawsize(this1, width1, height1), \
  bg_bg_setOffset(this1, 0, 0), \
  bg_bg_setDelta(this1, 0, 0), \
  bg_bg_setScale(this1, 1.0f, 1.0f), \
  bg_bg_setGfxlist(this1, NULL), \
  bg_bg_setDrawtype(this1, BG_BG_DRAWTYPE_COPY_BLOCK), \
  bg_bg_setRenderMode(this1, 0), \
  bg_bg_setPrimColor(this1, 255, 255, 255, 255), \
  bg_bg_setEnvColor(this1, 0, 0, 0, 0) \
)

/*
 * １サイクル用の追加ディスプレイリストの設定・取得
 */
#define bg_bg_getGfxlist(this1) ((this1)->gfxlist)
#define bg_bg_setGfxlist(this1, gfxlist1) \
( \
  (this1)->gfxlist = (gfxlist1) \
)

/*
 * 表示方法の設定・取得
 */
#define bg_bg_getDrawtype(this1) ((this1)->drawtype)
#define bg_bg_setDrawtype(this1, drawtype1) \
( \
  (this1)->drawtype = (drawtype1) \
)
    
/*
 * 表示位置の設定・取得
 */
#define bg_bg_getPositionX(this1) ((this1)->xpos)
#define bg_bg_getPositionY(this1) ((this1)->ypos)
#define bg_bg_setPosition(this1, xpos1, ypos1) \
( \
  (this1)->xpos = (xpos1), \
  (this1)->ypos = (ypos1) \
)

/*
 * 表示幅・高さの設定・取得
 */
#define bg_bg_getDrawsizeW(this1) ((this1)->width_draw)
#define bg_bg_getDrawsizeH(this1) ((this1)->height_draw)
#define bg_bg_setDrawsize(this1, width_draw1, height_draw1) \
( \
  (this1)->width_draw = (width_draw1), \
  (this1)->height_draw = (height_draw1) \
)

/*
 * 原点オフセットの設定・取得
 */
#define bg_bg_getOffsetX(this1) ((this1)->xoff)
#define bg_bg_getOffsetY(this1) ((this1)->yoff)
#define bg_bg_setOffset(this1, xoff1, yoff1) \
( \
  (this1)->xoff = (xoff1), \
  (this1)->yoff = (yoff1), \
  bg_bg_correct(this1, &(this1)->xoff, &(this1)->yoff) \
)
    
#define bg_bg_getOffsetXf(this1) ((float)bg_bg_getOffsetX(this1) + ((float)(this1)->delta_s / 32.0f))
#define bg_bg_getOffsetYf(this1) ((float)bg_bg_getOffsetY(this1) + ((float)(this1)->delta_t / 32.0f))
#define bg_bg_setOffsetf(this1, xoff1, yoff1) \
{ \
  (this1)->xoff = (int)Ffloor(xoff1); \
  (this1)->delta_s = (int)(((xoff1) - Ffloor(xoff1)) * 32.0f); \
  (this1)->yoff = (int)Ffloor(yoff1); \
  (this1)->delta_t = (int)(((yoff1) - Ffloor(yoff1)) * 32.0f); \
}
    
/*
 * １サイクルモード用のＳＴデルタ値の設定・取得
 */
#define bg_bg_getDeltaS(this1) ((this1)->delta_s)
#define bg_bg_getDeltaT(this1) ((this1)->delta_t)
#define bg_bg_setDelta(this1, ds1, dt1) \
( \
  (this1)->delta_s = (ds1), \
  (this1)->delta_t = (dt1) \
)
    
/*
 * １サイクルモード用のＸＹスケール値の設定・取得
 */
#define bg_bg_getScaleX(this1) ((this1)->xscale)
#define bg_bg_getScaleY(this1) ((this1)->yscale)
#define bg_bg_setScale(this1, xscale1, yscale1) \
( \
  (this1)->xscale = (xscale1), \
  (this1)->yscale = (yscale1) \
)

#define bg_bg_setRenderMode(p1, r1) 	((p1)->rendmode = (r1))
#define bg_bg_getRenderMode(p1) 	((p1)->rendmode)
#define bg_bg_setPrimColor(p1, r1, g1, b1, a1) \
    ((p1)->primcolor.c.r = (r1), \
     (p1)->primcolor.c.g = (g1), \
     (p1)->primcolor.c.b = (b1), \
     (p1)->primcolor.c.a = (a1))
#define bg_bg_setPrimColor_rgba8888(p1, rgba8888) \
    ((p1)->primcolor.rgba8888.c = (rgba8888))
#define bg_bg_setEnvColor(p1, r1, g1, b1, a1) \
    ((p1)->envcolor.c.r = (r1), \
     (p1)->envcolor.c.g = (g1), \
     (p1)->envcolor.c.b = (b1), \
     (p1)->envcolor.c.a = (a1))
#define bg_bg_setEnvColor_rgba8888(p1, rgba8888) \
    ((p1)->envcolor.rgba8888.c = (rgba8888))

/*
 * 座標の補正
 * 0 <= xpos < this1->width
 * 0 <= ypos < this1->height
 * になるように補正される
 */
void
bg_bg_correct(
    bg_bg_t *this1,
    int *xpos,
    int *ypos
);
    
/*
 * 原点オフセットの移動
 */
void
bg_bg_moveOffset(
    bg_bg_t *this1,
    int xoff,
    int yoff
);

void
bg_bg_moveOffsetf(
    bg_bg_t *this1,
    float xoff,
    float yoff
);

/*
 * 原点オフセットの移動
 */
void
bg_bg_moveOffsetDelta(
    bg_bg_t *this1,
    int xoff,
    int yoff,
    int ds1,
    int dt1
);

/*
 * イメージバッファになにかを書く初期処理
 *  4b イメージバッファは内部で、16b にしている
 */
void
bg_bg_rectangle_init(
    bg_bg_t *this1,
    Gfx **glistpp
);

/*
 * イメージバッファにテクスチャレクタングルを書く初期処理
 * 16b コピーモード
 *  8b １サイクルモード
 *  4b コピーモード(4dot単位)
 */
void
bg_bg_texture_rectangle_init(
    bg_bg_t *this1,
    Gfx **glistpp,
    int g_ac			/* G_AC_NONE:16bモード以外では不定 */
);

/*
 * イメージバッファにフィルレクタングルを書く初期処理
 * 16b フィルモード
 *  8b １サイクルモード
 *  4b フィルモード(横4dot単位)
 */
void
bg_bg_fill_rectangle_init(
    bg_bg_t *this1,
    Gfx **glistpp,
    u32 fillcolor
);

/*
 * イメージバッファにレクタングルを書く終了処理
 * フレームバッファのアドレスとシザーボックスを元に戻す
 */
void
bg_bg_rectangle_finish(
    bg_bg_t *this1,
    Gfx **glistpp
);

/*
 * イメージバッファにテクスチャレクタングルを書く
 * 自動分割はサポートしていない(8ビットモードで、64x64以内)
 * 特殊表示はサポートしない（拡大縮小/半透明/バイリニアなど）
 */
void
bg_bg_texture_rectangle(
    bg_bg_t *this1,
    Gfx **glistpp,
    void *timg,
    int xpos,
    int ypos,
    int xsize,
    int ysize
);

/*
 * イメージバッファにフィルレクタングルを書く
 */
void
bg_bg_fill_rectangle(
    bg_bg_t *this1,
    Gfx **glistpp,
    int xpos,
    int ypos,
    int xsize,
    int ysize
);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __BG_BG_H_ */
