/*	
 *	clipdmv.h
 *
 *	P/ECE DMG-Video Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2005 Naoyuki Sawa
 *
 *	* Fri Feb 18 20:18:00 JST 2005 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_DMV_H__
#define __CLIP_DMV_H__

/****************************************************************************
 *
 ****************************************************************************/

/* DMGVIDEO_ASMシンボル定義を読み込みます。
 * DMGVIDEO_ASMシンボルの未定義/定義によるC/アセンブラコードの切り替えは、
 * Cソースファイル(*.c)とアセンブラソースファイル(*.s)から参照するので、
 * 別のインクルードファイルに分けています。
 * (C言語特有の定義を含むインクルードファイルをそのままアセンブラソースに
 *  インクルードすると、アセンブルエラーになってしまうため。)
 */
#include "clipdmva.h"

/********** これ以降は書き換えないでください **********/

/* P/ECE以外ではアセンブラコードは使用できません。
 */
#ifndef PIECE
#undef DMGVIDEO_ASM
#endif /*PIECE*/

/****************************************************************************
 *
 ****************************************************************************/

/* ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ */
/* ★アセンブラルーチンから直接参照しているので、フォーマット固定です。★ */
/* ★フォーマットを変更したときは、framdmva.sの定義も追従してください。★ */
/* ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ */
typedef struct _DMGVIDEO {
	unsigned char* mem;			/* + 0, 4: メインメモリの先頭アドレス */
	unsigned char* vbuff/*[160*144]*/;	/* + 4, 4: 現在フレームの描画ターゲット (NULL:実描画無し) */
	unsigned char clut[4 * 3];		/* + 8,12:パレット ([0..3]=BGP,[4..7]=OBP0,[8..11]=OBP1) */
	unsigned char scan_start;		/* +20, 1: 走査区間の開始ライン */
	unsigned char scan_end;			/* +21, 1: 走査区間の終了ライン */
	//					/* +22, 2: (パディング) */
} DMGVIDEO;					/* =24 */

extern DMGVIDEO dmgvideo;

/****************************************************************************
 *
 ****************************************************************************/

void dmgvideo_partial_update();
void dmgvideo_draw_bg    ();
void dmgvideo_draw_window();
void dmgvideo_draw_sprite     (int priority);
void dmgvideo_draw_sprite_8x8 (int priority);
void dmgvideo_draw_sprite_8x16(int priority);
void dmgvideo_draw_chr       (int xpos, int ypos, int code, int palno);
void dmgvideo_draw_chr_opaque(int xpos, int ypos, int code, int palno);
void dmgvideo_draw_chr_revx  (int xpos, int ypos, int code, int palno);
void dmgvideo_draw_chr_revy  (int xpos, int ypos, int code, int palno);
void dmgvideo_draw_chr_revxy (int xpos, int ypos, int code, int palno);

/****************************************************************************
 *
 ****************************************************************************/

/* DMG-Videoコアをリセットします。
 * [in]
 *	mem		DMG-CPUと、メインメモリを共有します。
 *			メインメモリ空間の先頭アドレスを指定してください。
 */
void dmgvideo_reset(unsigned char* mem);

/* DMG-Videoから1バイト読み出します。
 * [in]
 *	addr		読み出すアドレス。($FF40..$FF4B)
 * [out]
 *	戻り値		読み出したデータ。
 * [note]
 *	- レジスタ領域からの読み出しは、必ずこの関数を経由してください。
 *	- VRAM($8000-$9FFF)、およびスプライトRAM($FE00..$FE9F)からの読み出しは、
 *	  直接メインメモリの内容を読み出してください。
 */
int dmgvideo_read(int addr);

/* DMG-Videoへ1バイト書き込みます。
 * [in]
 *	addr		書き込むアドレス。($FF40..$FF4B)
 *	data		書き込むデータ。
 * [note]
 *	- レジスタ領域への書き込みは、必ずこの関数を経由してください。
 *	- VRAM($8000-$9FFF)、およびスプライトRAM($FE00..$FE9F)への書き込みは、
 *	  直接メインメモリの内容を書き換えてください。
 */
void dmgvideo_write(int addr, int data);

/* 新しいフレームを開始します。
 * [in]
 *	vbuff		160x144画面バッファ。(NULL:内部処理のみ、実描画無し)
 * [out]
 *	戻り値		CPUへの割り込み要求。
 *			  bit0: V-Blank割り込みが発生したら1。
 *			  bit1: LCDC Status割り込みが発生したら1。
 * [note]
 *	- アプリケーションプログラムは、dmgvideo_new_frame()を呼び出した後、
 *	  dmgvideo_next_line()を154回(=画面内144+画面外10ライン分)実行してください。
 *	  <例>
 *		irq = dmgvideo_new_frame(draw);
 *		if(irq) {
 *			dmgmem[0xff0f] |= irq;
 *			dmgcpu_check_pending();
 *		}
 *		lines = 154;
 *		do {
 *			dmgcpu_run(dmgcpu.cycle + 456); // 1ライン=456サイクル分実行、前回の端数を考慮
 *			irq = dmgvideo_next_line();
 *			if(irq) {
 *				dmgmem[0xff0f] |= irq; // Vertical Blank & LCDC Status Interrupt
 *				dmgcpu_check_pending();
 *			}
 *		} while(--lines);
 */
int dmgvideo_new_frame(unsigned char vbuff[/*160*144]*/]);

/* 1ライン(4.19MHz×456サイクル)進めます。
 * [out]
 *	戻り値		CPUへの割り込み要求。
 *			  bit0: V-Blank割り込みが発生したら1。
 *			  bit1: LCDC Status割り込みが発生したら1。
 * [note]
 *	- 一回のdmgvideo_new_frame()に対して、必ず154回のdmgvideo_next_line()呼び出しが必要です。
 *	  154回を超えて呼び出すと、アサートします。
 *	  154回に満たないと、そのフレームの描画は不正な結果となります。
 *	- dmgvideo_new_frame()にNULL以外の画面バッファが指定されていた場合、
 *	  必要に応じて画面の部分更新、または全体更新を行います。
 */
int dmgvideo_next_line();

/* 160x144x4諧調グレイスケールを、128x88x4諧調グレイスケールへ縮小コピーします。
 * [in]
 *	src		160x144x4諧調グレイスケール画面バッファ。
 *	dst		128x 88x4諧調グレイスケール画面バッファ。
 *
 * [note]
 *	* srcとdstは同じアドレスを指していても構いません。
 *	  最終的に128x88の画面イメージだけが必要ならば、160x144と128x88の画面バッファを共通にして、
 *	  メモリを節約できます。
 */
void dmgvideo_reduce(unsigned char dst[/*128*88*/], const unsigned char src[/*160*144*/]);

#endif /*__CLIP_DMV_H__*/
