#include <sys/bios.h>
#include "KSFont.h"

CKSFont KSFont[512];		/* フォントデータ */
CKSSprite KSSprite[128];	/* スプライトデータ */

/* スプライトステータス(0.未使用 1.使用中) */
unsigned short SpriteStatus[128];

unsigned int g_CurrentFontNo = FONT_START_NUMBER;
unsigned int g_CurrentSpriteNo = SPRITE_START_NUMBER;

/* クリップ範囲 */
int g_nClipLeft;	/* 0-31 */
int g_nClipTop;		/* 0-31 */
int g_nClipRight;	/* 0-31 */
int g_nClipBottom;	/* 0-31 */



/*=======================================================*/
/* KSFontライブラリ初期化 */
/*=======================================================*/
void KSFontInit( void )
{
	int n;

	for( n=0; n<128; n++ ){
		SpriteStatus[n] = 0;
	}

	g_CurrentFontNo = FONT_START_NUMBER;
	g_CurrentSpriteNo = SPRITE_START_NUMBER;

	g_nClipLeft = 0;
	g_nClipTop = 0;
	g_nClipRight = 31;
	g_nClipBottom = 31;
}



/*=======================================================*/
/* キャラクタフォント登録 */
/*=======================================================*/
int KSFontSet(
	unsigned num,				/* KSパターン登録番号 */
	unsigned short far *data,	/* キャラクタデータポインタ */
	int width,					/* キャラクタサイズ横[単位:キャラ] */
	int height,					/* キャラクタサイズ縦[単位:キャラ] */
	unsigned cpal )				/* キャラクタパレット番号 */
{
	/* フォントの登録範囲チェック */
	if( g_CurrentFontNo + width * height >= FONT_START_NUMBER + FONT_MAX_COUNT ) return 0;

	font_set_colordata( g_CurrentFontNo, width*height, data );

	KSFont[num].m_nStartNo = g_CurrentFontNo;
	KSFont[num].m_nWidth = width;
	KSFont[num].m_nHeight = height;
	KSFont[num].m_nPalette = cpal;

	g_CurrentFontNo += width * height;

	return 1;
}



/*=======================================================*/
/* 矩形領域キャラクタ表示設定 */
/*=======================================================*/
int KSScreenSet( unsigned num, int screen, int cx, int cy )
{
	static unsigned data[512];
	int lx, ly, dx, dy;
	int srcLeft, srcTop, srcRight, srcBottom;
	int dstLeft, dstTop, dstRight, dstBottom;
	int length, index;
	int x, y;

	index = 0;
	lx = KSFont[num].m_nWidth;
	ly = KSFont[num].m_nHeight;
	srcLeft = 0;
	srcTop = 0;
	srcRight = lx-1;
	srcBottom = ly-1;
	dstLeft = cx;
	dstTop = cy;
	dstRight = cx + lx - 1;
	dstBottom = cy + ly - 1;

	/* 描画がクリップ座標範囲外の場合抜ける */
	if( dstRight < g_nClipLeft  || dstBottom < g_nClipTop
	 || dstLeft > g_nClipRight || dstTop > g_nClipBottom ){
		return 1;
	}

	/* クリップ処理 */
	length = g_nClipLeft - dstLeft;
	if( length > 0 ){
		srcLeft += length;
		dstLeft += length;
	}
	length = g_nClipTop - dstTop;
	if( length > 0 ){
		srcTop += length;
		dstTop += length;
	}
	length = dstRight - g_nClipRight;
	if( length > 0 ){
		srcRight -= length;
		dstRight -= length;
	}
	length = dstBottom - g_nClipBottom;
	if( length > 0 ){
		srcBottom -= length;
		dstBottom -= length;
	}

	/* 最終表示範囲の算出 */
	dx = srcRight - srcLeft + 1;
	dy = srcBottom - srcTop + 1;

	/* 最終表示データ抽出 */
	for( y=0; y<dy; y++ ){
		for( x=0; x<dx; x++ ){
			data[index] = KSFont[num].m_nPalette << 9;
			data[index] += KSFont[num].m_nStartNo + srcLeft + x + (srcTop+y) * lx;
			index++;
		}
	}

	/* 表示 */
	screen_set_char( screen, dstLeft, dstTop, dx, dy, data );
	return 1;
}



/*=======================================================*/
/* 矩形領域パターン表示設定 */
/*=======================================================*/
int KSScreenSetPattern( unsigned num, unsigned ptnum, int screen, int cx, int cy )
{
	static unsigned data[512];
	int lx, ly, dx, dy;
	int srcLeft, srcTop, srcRight, srcBottom;
	int dstLeft, dstTop, dstRight, dstBottom;
	int length, index;
	int x, y;

	index = 0;
	lx = KSFont[num].m_nWidth;
	ly = KSFont[num].m_nHeight;
	srcLeft = 0;
	srcTop = 0;
	srcRight = lx-1;
	srcBottom = ly-1;
	dstLeft = cx;
	dstTop = cy;
	dstRight = cx + lx - 1;
	dstBottom = cy + ly - 1;

	/* 描画がクリップ座標範囲外の場合抜ける */
	if( dstRight < g_nClipLeft  || dstBottom < g_nClipTop
	 || dstLeft > g_nClipRight || dstTop > g_nClipBottom ){
		return 1;
	}

	/* クリップ処理 */
	length = g_nClipLeft - dstLeft;
	if( length > 0 ){
		srcLeft += length;
		dstLeft += length;
	}
	length = g_nClipTop - dstTop;
	if( length > 0 ){
		srcTop += length;
		dstTop += length;
	}
	length = dstRight - g_nClipRight;
	if( length > 0 ){
		srcRight -= length;
		dstRight -= length;
	}
	length = dstBottom - g_nClipBottom;
	if( length > 0 ){
		srcBottom -= length;
		dstBottom -= length;
	}

	/* 最終表示範囲の算出 */
	dx = srcRight - srcLeft + 1;
	dy = srcBottom - srcTop + 1;

	/* 最終表示データ抽出 */
	for( y=0; y<dy; y++ ){
		for( x=0; x<dx; x++ ){
			data[index] = KSFont[num].m_nPalette << 9;
			data[index] += KSFont[ptnum].m_nStartNo;
			index++;
		}
	}

	/* 表示 */
	screen_set_char( screen, dstLeft, dstTop, dx, dy, data );

	/* 正常終了 */
	return 1;
}



/*=======================================================*/
/* 矩形領域キャラクタ塗り潰し表示設定 */
/*=======================================================*/
int KSScreenFill( unsigned num, int screen, int cx, int cy, int dx, int dy )
{
	unsigned data;

	data = KSFont[num].m_nPalette << 9;
	data += KSFont[num].m_nStartNo;

	screen_fill_char( screen, cx, cy, dx, dy, data );
}




/*=======================================================*/
/* スプライト登録 */
/*=======================================================*/
int KSSpriteSet(
	int spno,
	int ftno,
	int zx,
	int zy,
	int priority )
{
	unsigned attr = 0;
	unsigned palette = 0;
	unsigned font;
	int x, y, cx, cy;

	KSSprite[spno].m_nSpriteNo = g_CurrentSpriteNo;
	KSSprite[spno].m_nX = zx;
	KSSprite[spno].m_nY = zy;
	KSSprite[spno].m_nFontNo = KSFont[ftno].m_nStartNo;
	KSSprite[spno].m_nWidth = KSFont[ftno].m_nWidth;
	KSSprite[spno].m_nHeight = KSFont[ftno].m_nHeight;
	KSSprite[spno].m_nPalette = KSFont[ftno].m_nPalette - 8;

	cx = KSSprite[spno].m_nWidth;
	cy = KSSprite[spno].m_nHeight;
	palette = KSSprite[spno].m_nPalette;
	font = KSSprite[spno].m_nFontNo;

	for( y=0; y<cy; y++ ){
		for( x=0; x<cx; x++ ){
			attr = priority << 13;
			attr |= palette << 9;
			attr |= font;
			sprite_set_char_location( g_CurrentSpriteNo, attr, zx+8*x, zy+8*y );
			g_CurrentSpriteNo++;
			font++;
		}
	}

	sprite_set_range( SPRITE_START_NUMBER, g_CurrentSpriteNo-SPRITE_START_NUMBER );

	return 1;
}



/*=======================================================*/
/* スプライト移動 */
/*=======================================================*/
void KSSpriteMove( int spno, int mx, int my )
{
	int x, y, cx, cy, sp;

	KSSprite[spno].m_nX = mx;
	KSSprite[spno].m_nY = my;

	cx = KSSprite[spno].m_nWidth;
	cy = KSSprite[spno].m_nHeight;
	sp = KSSprite[spno].m_nSpriteNo;

	for( y=0; y<cy; y++ ){
		for( x=0; x<cx; x++ ){
			sprite_set_location( sp, mx+8*x, my+8*y );
			sp++;
		}
	}


}



/* スプライトキャラクタ変更 */
void KSSpriteChange( int snum, int fnum )
{
	unsigned attr = 0;
	unsigned palette = 0;
	unsigned sprite;
	unsigned font;
	int x, y, cx, cy, zx, zy;


	KSSprite[snum].m_nFontNo = KSFont[fnum].m_nStartNo;
	KSSprite[snum].m_nPalette = KSFont[fnum].m_nPalette - 8;

	zx = KSSprite[snum].m_nX;
	zy = KSSprite[snum].m_nY;
	cx = KSSprite[snum].m_nWidth;
	cy = KSSprite[snum].m_nHeight;
	palette = KSSprite[snum].m_nPalette;
	sprite = KSSprite[snum].m_nSpriteNo;
	font = KSSprite[snum].m_nFontNo;

	for( y=0; y<cy; y++ ){
		for( x=0; x<cx; x++ ){
			attr = palette << 9;
			attr |= font;
			sprite_set_char_location( sprite, attr, zx+8*x, zy+8*y );
			sprite++;
			font++;
		}
	}
}



