/*	
 *	clipemu.h
 *
 *	エミュレータ用サブルーチン集。
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2003 Naoyuki Sawa
 *
 *	* Thu Dec 25 06:00:00 JST 2003 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_EMU_H__
#define __CLIP_EMU_H__

/****************************************************************************
 *	汎用定数
 ****************************************************************************/

#define	NTSC_COLOR_SUBCARRIER	3579545	/* NTSCカラーサブキャリア周波数[Hz] */
#define PAL_COLOR_SUBCARRIER	4433619	/* PAL カラーサブキャリア周波数[Hz] (正しくは、4433618.75[Hz]) */
					/* PALの方はまず使うことはないと思いますが、一応定義しました。 */

/****************************************************************************
 *	キャラクタ描画
 ****************************************************************************/

/* * 描画先のピクセル形式は次の通りです。
 *
 *	planes=1の場合:
 *			pppppppb
 *			|||||||+-プレーン#0|カラー番号
 *			+++++++-------------パレット番号
 *	planes=2の場合:
 *			ppppppgb
 *			|||||||+-プレーン#0|カラー番号
 *			||||||+--プレーン#1|
 *			++++++--------------パレット番号
 *	planes=3の場合:
 *			ppppprgb
 *			|||||||+-プレーン#0|カラー番号
 *			||||||+--プレーン#1|
 *			|||||+---プレーン#2|
 *			+++++---------------パレット番号
 *	planes=4の場合:
 *			ppppargb
 *			|||||||+-プレーン#0|カラー番号
 *			||||||+--プレーン#1|
 *			|||||+---プレーン#2|
 *			||||+----プレーン#3|
 *			++++----------------パレット番号
 */
#define GFX_MAX_PLANES		4		/* 最大プレーン数(調整可) */

/* キャラクタROMを表す構造体 */
typedef struct _GFX {
	unsigned char bits;				/* + 0, 1: 1プレーン1ピクセル当りのビット数 */
	unsigned char planes;				/* + 1, 1: プレーン数 */
	unsigned char width;				/* + 2, 1: キャラクタ幅  [ピクセル] */
	unsigned char height;				/* + 3, 1: キャラクタ高さ[ピクセル] */
	int count;					/* + 4, 4: キャラクタ数 */
	const void* plane_address[GFX_MAX_PLANES];	/* + 8,16: プレーンアドレス */
} GFX;							/* =24 */

/* キャラクタを描きます。
 * [in]
 *	render		描画先のRENDER構造体。
 *	gfx		描画するキャラクタのGFX構造体。
 *	dx		描画先の基点X座標。
 *	dy		描画先の基点Y座標。
 *	code		キャラクタ番号。
 *	palette		パレット番号。
 *	param		透過および反転フラグ。
 */
void render_gfx(RENDER* render, const GFX* gfx, int dx, int dy, int code, int palette, int param);

/* render_gfx()のparam引数用フラグ。0個以上の組み合わせで指定してください。 */
#define GFX_TRANSPARENT		(1 << 0)	/* カラー#0が透過色 */
#define GFX_REVX		(1 << 1)	/* 左右反転 */
#define GFX_REVY		(1 << 2)	/* 上下反転 */

/* 以下のフラグは内部使用です。アプリケーションからは指定しないでください。 */
#define GFX_CLIPX		(1 << 3)	/* 水平クリッピング */
#define GFX_CLIPY		(1 << 4)	/* 垂直クリッピング */

/****************************************************************************
 *	カラールックアップ
 ****************************************************************************/

/* * カラールックアップテーブルは次のように定義してください。
 *
 *	unsigned 変数名[パレット数×パレット当りのカラー数];
 *
 * <例> 16パレット4カラーで「g_clut」という名前のカラールックアップテーブルを定義：
 *
 *	unsigned g_clut[16 * 4];
 */

/* カラールックアップテーブルを初期化します。
 * [in]
 *	clut		カラールックアップテーブル。
 *	count		エントリ数。
 */
void clut_init(unsigned clut[/*count*/], int count);

/* カラールックアップテーブルエントリの{RorGorB}レベルを変更します。
 * [in]
 *	clut		カラールックアップテーブル。
 *	i		カラー番号。(全パレット通算)
 *	v		{RorGorb}レベル。(暗:0x00〜0xff:明)
 */
void clut_set_b(unsigned clut[], int i, unsigned char v);
void clut_set_g(unsigned clut[], int i, unsigned char v);
void clut_set_r(unsigned clut[], int i, unsigned char v);

/* カラールックアップテーブルエントリのRGBレベルを変更します。
 * [in]
 *	clut		カラールックアップテーブル。
 *	i		カラー番号。(全パレット通算)
 *	v		RGBレベル。(00000000_rrrrrrrr_gggggggg_bbbbbbbb)
 */
void clut_set_rgb(unsigned clut[], int i, int v);

/* カラールックアップテーブルを更新します。
 * [in]
 *	clut		カラールックアップテーブル。
 *	count		エントリ数。
 * [out]
 *	戻り値		更新したエントリ数。
 */
int clut_update(unsigned clut[/*count*/], int count);

/* 指定領域のカラールックアップを行います。
 * [in]
 *	render		描画先のRENDER構造体。
 *	clut		カラールックアップテーブル。
 *	x		領域の基点X座標。
 *	y		領域の基点Y座標。
 *	w		領域の幅。
 *	h		領域の高さ。
 */
void render_clut(RENDER* render, const unsigned clut[], int x, int y, int w, int h);

/****************************************************************************
 *	ROMセットファイル
 ****************************************************************************/

typedef struct _ROM {
	const char* name;	/* ROM名(ZIP内のファイル名) */
	unsigned base;		/* ベースアドレス */
	unsigned size;		/* サイズ */
	unsigned crc;		/* CRC */
} ROM;

/* ROMセットファイルを読み込みます。
 * [in]
 *	fname		ZIPファイル名。
 *	rom		ROM配列。
 *	count		ROMの数。
 *	mem		読み込み先メモリの先頭アドレス。
 * [out]
 *	戻り値		全て正しく読み込めたら0を返します。
 *			失敗なら0以外の値を返します。
 */
int rom_load(const char* fname, const ROM* rom, int count, unsigned char* mem);

#endif /*__CLIP_EMU_H__*/
