/*	
 *	framds11.c
 *
 *	高速RAM転送候補：スキャンライン描画関数（Ｚ比較あり・テクスチャなし）
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2008 Naoyuki Sawa
 *
 *	* Tue Apr  2 05:53:00 JST 2003 Naoyuki Sawa
 *	- cliprend.cから移動してきました。
 *	* Tue Jan 01 21:51:54 JST 2008 Naoyuki Sawa
 *	- テクスチャ無しポリゴンの描画色を、背景色でなく、前景色に変更しました。
 *	  clipren3.cの2008/01/01の変更コメントを参照してください。
 *	- DSLPARAM構造体の、fore_colorとback_colorの順序の入れ替えに追従しました。
 *	  cliprend.hの2008/01/01の変更コメントを参照してください。
 *	- 下のアセンブラ版も、C言語版と同様に修正しました。(変更コメントは省略)
 *	  結局、上記二点の変更が相殺して、オフセットの変更は不要でした。
 *	  コメントをback_color→fore_colorに変更しただけで、コードはそのままです。
 */
#include "clip.h"

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

#ifdef REND_NOASM
void
draw_scanline_wz_color(const RENDVERTEX* v0, const RENDVERTEX* v1, DSLPARAM* param)
{
	unsigned char* vptr;	/* カラーバッファポインタ     */
	unsigned char* zptr;	/* Ｚバッファポインタ         */
	int nx;			/* 現在のスキャンラインの長さ */
	int n;			/* 現在の辺の残りピクセル数   */
	RENDVERTEX cur;		/* 現在値                     */
	DDA z;			/* Ｚ値DDA                    */
	const RENDVERTEX* tmp;
	int ofs;
	unsigned char zval;

	/* 確実に 左:v0 -> v1:右 とします。 */
	if(v0->x > v1->x) {
		tmp = v0;
		      v0 = v1;
		           v1 = tmp;
	}

	/* 始点アドレスを求めます。 */
	ofs = param->surface_w * v0->y + v0->x;
	vptr = param->surface_vbuff + ofs;
	zptr = param->surface_zbuff + ofs;

	/* 主軸のDDAセットアップ。 */
	nx = v1->x - v0->x;
	if(nx == 0) return; /* 点なら描きません。 */

	/* 副軸のDDAセットアップ。 */
	DRAW_SCANLINE_SETUP(z);

	/* DDAループ。 */
	n = nx;
	do {
		/* Ｚ比較。 */
		zval = (unsigned char)(cur.z >> 8);
		if(zval <= *zptr) {
//{{2008/01/01:変更
//			/* テクスチャ無しなら、フェイスの背景色で描きます。 */
//			*vptr = param->back_color;
//↓ * Tue Jan 01 21:51:54 JST 2008 Naoyuki Sawa
//↓ - テクスチャ無しポリゴンの描画色を、背景色でなく、前景色に変更しました。
//↓   clipren3.cの2008/01/01の変更コメントを参照してください。
//↓ - DSLPARAM構造体の、fore_colorとback_colorの順序の入れ替えに追従しました。
//↓   cliprend.hの2008/01/01の変更コメントを参照してください。
//↓ - 下のアセンブラ版も、C言語版と同様に修正しました。(変更コメントは省略)
//↓   結局、上記二点の変更が相殺して、オフセットの変更は不要でした。
//↓   コメントをback_color→fore_colorに変更しただけで、コードはそのままです。
			/* テクスチャ無しなら、フェイスの背景色で描きます。 */
			*vptr = param->fore_color;
//}}2008/01/01:変更
			*zptr = zval;
		}
		/* バッファポインタを進めます。 */
		vptr++;
		zptr++;
		/* DDAステップ実行。 */
		DRAW_SCANLINE_STEP(z);
	} while(--n); /* 右端ピクセルは描かないので、プリデクリメントです。 */
}
#else /*REND_NOASM*/
#if 0
//	asm("
//	.code
//	.align 1
//	.global draw_scanline_wz_color
//	;// IN:
//	;// %r12     = v0
//	;// %r13     = v1
//	;// %r14     = param
//draw_scanline_wz_color:
//	;// USAGE:
//	;// %r0      = cur.z
//	;// %r1      = cur.s (使わない)
//	;// %r2      = cur.t (使わない)
//	;// [%sp+ 0] = DDA.z
//	;// [%sp+16] = DDA.s (使わない)
//	;// [%sp+32] = DDA.t (使わない)
//	pushn %r2
//	xsub %sp, %sp, 48
//
//	;// 確実に 左:v0 -> v1:右 とします。
//	xld.uh %r4, [%r12+0]	;// v0->x
//	xld.uh %r5, [%r13+0]	;// v1->x
//	cmp %r4, %r5
//	xjrule __draw_scanline_wz_color_swap
//	xor %r12, %r13
//	xor %r13, %r12
//	xor %r12, %r13
//__draw_scanline_wz_color_swap:
//	;// %r12 = v0
//	;// %r13 = v1
//
//	;// 始点アドレスを求めます。
//	xld.uh %r4, [%r14+0]	;// param->surface_w
//	xld.uh %r5, [%r12+2]	;// v0->y
//	mltu.h %r4, %r5
//	ld.w %r4, %alr
//	xld.uh %r5, [%r12+0]	;// v0->x
//	add %r4, %r5
//	xld.w %r10, [%r14+4]	;// param->surface_vbuff
//	add %r10, %r4
//	xld.w %r11, [%r14+8]	;// param->surface_zbuff
//	add %r11, %r4
//	;// %r10 = vptr
//	;// %r11 = zptr
//	;// %r5  = v0->x
//
//	;// 主軸のDDAセットアップ。
//	xld.uh %r15, [%r13+0]	;// v1->x
//	sub %r15, %r5
//	xjreq __draw_scanline_wz_color_ret
//	;// %r15 = nx
//
//	;// 副軸のDDAセットアップ。
//	;// (DDA.z)
//	xld.uh %r0, [%r12+4]	;// v0->z => cur.z
//	xld.uh %r4, [%r13+4]	;// v1->z
//	sub %r4, %r0
//	xld.w %r5, 1
//	xjruge __draw_scanline_wz_color_setup_z
//	not %r4, %r4
//	xadd %r4, %r4, 1
//	xld.w %r5, -1
//__draw_scanline_wz_color_setup_z:
//	xsll %r4, 16
//	ld.w %alr, %r4
//	div0u %r15
//	div1 %r15		;//  1
//	div1 %r15		;//  2
//	div1 %r15		;//  3
//	div1 %r15		;//  4
//	div1 %r15		;//  5
//	div1 %r15		;//  6
//	div1 %r15		;//  7
//	div1 %r15		;//  8
//	div1 %r15		;//  9
//	div1 %r15		;// 10
//	div1 %r15		;// 11
//	div1 %r15		;// 12
//	div1 %r15		;// 13
//	div1 %r15		;// 14
//	div1 %r15		;// 15
//	div1 %r15		;// 16
//	ld.w %r4, %ahr
//	add %r4, %r4
//	xld.w [%sp+ 0], %r4	;// z.n * 2
//	not %r4, %r15
//	xadd %r4, %r4, 1
//	xld.w [%sp+ 4], %r4	;// z.d
//	ld.w %r4, %alr
//	mlt.h %r4, %r5
//	ld.w %r4, %alr
//	xld.w [%sp+ 8], %r4	;// z.u
//	xld.w [%sp+12], %r5	;// z.v
//	;// %r0      = cur.z
//	;// [%sp+ 0] = z.n * 2
//	;// [%sp+ 4] = z.d
//	;// [%sp+ 8] = z.u
//	;// [%sp+12] = z.v
//
//	;// DDAループ。
//	ld.w %r7, %r15
//	add %r15, %r15
//	xld.ub %r12, [%r14+24]	;// param->fore_color
//__draw_scanline_wz_color_loop:
//	;// %r7  = n
//	;// %r15 = nx * 2
//	;// %r12 = fore_color
//
//	;// Ｚ比較。
//	ld.uh %r4, %r0		;// zval
//	xsrl %r4, 8
//	xld.ub %r5, [%r11]	;// *zptr
//	cmp %r4, %r5
//	xjrugt __draw_scanline_wz_color_skip
//	;// %r4 = zval
//
//	;// テクスチャ無しなら、フェイスの背景色で描きます。
//	xld.b [%r10], %r12	;// *vptr
//	xld.b [%r11], %r4	;// *zptr
//__draw_scanline_wz_color_skip:
//
//	;// バッファポインタを進めます。
//	xadd %r10, %r10, 1
//	xadd %r11, %r11, 1
//
//	;// DDAステップ実行。
//	;// (DDA.z)
//	xld.w %r4, [%sp+ 8]	;// z.u
//	add %r0, %r4
//	xld.w %r4, [%sp+ 4]	;// z.d
//	xld.w %r5, [%sp+ 0]	;// z.n * 2
//	add %r4, %r5
//	xjruge __draw_scanline_wz_color_step_z ;// !C条件
//	xld.w %r5, [%sp+12]	;// z.v
//	add %r0, %r5
//	sub %r4, %r15
//__draw_scanline_wz_color_step_z:
//	xld.w [%sp+ 4], %r4	;// z.d
//
//	xsub %r7, %r7, 1
//	xjrne __draw_scanline_wz_color_loop
//
//__draw_scanline_wz_color_ret:
//	xadd	%sp, %sp, 48
//	popn	%r2
//	ret
//	");
#else	/* ↑draw_scanline_wz_2bitmaskと同じレジスタ割り当ての、標準的な実装 */
	/* ↓余ったレジスタにワークを割り当てた高速版。標準版より30%程度高速 */
	asm("
	.code
	.align 1
	.global draw_scanline_wz_color
	;// IN:
	;// %r12     = v0
	;// %r13     = v1
	;// %r14     = param
draw_scanline_wz_color:
	;// USAGE:
	;// %r0  = cur.z
	;// %r1  = DDA.z.n * 2
	;// %r2  = DDA.z.d
	;// %r6  = DDA.z.u
	;// %r13 = DDA.z.v
	pushn %r2

	;// 確実に 左:v0 -> v1:右 とします。
	xld.uh %r4, [%r12+0]	;// v0->x
	xld.uh %r5, [%r13+0]	;// v1->x
	cmp %r4, %r5
	xjrule __draw_scanline_wz_color_swap
	xor %r12, %r13
	xor %r13, %r12
	xor %r12, %r13
__draw_scanline_wz_color_swap:
	;// %r12 = v0
	;// %r13 = v1

	;// 始点アドレスを求めます。
	xld.uh %r4, [%r14+0]	;// param->surface_w
	xld.uh %r5, [%r12+2]	;// v0->y
	mltu.h %r4, %r5
	ld.w %r4, %alr
	xld.uh %r5, [%r12+0]	;// v0->x
	add %r4, %r5
	xld.w %r10, [%r14+4]	;// param->surface_vbuff
	add %r10, %r4
	xld.w %r11, [%r14+8]	;// param->surface_zbuff
	add %r11, %r4
	;// %r10 = vptr
	;// %r11 = zptr
	;// %r5  = v0->x

	;// 主軸のDDAセットアップ。
	xld.uh %r15, [%r13+0]	;// v1->x
	sub %r15, %r5
	xjreq __draw_scanline_wz_color_ret
	;// %r15 = nx

	;// 副軸のDDAセットアップ。
	;// (DDA.z)
	xld.uh %r0, [%r12+4]	;// v0->z => cur.z
	xld.uh %r4, [%r13+4]	;// v1->z
	sub %r4, %r0
	xld.w %r13, 1		;// z.v
	xjruge __draw_scanline_wz_color_setup_z
	not %r4, %r4
	xadd %r4, %r4, 1
	xld.w %r13, -1		;// z.v
__draw_scanline_wz_color_setup_z:
	xsll %r4, 16
	ld.w %alr, %r4
	div0u %r15
	div1 %r15		;//  1
	div1 %r15		;//  2
	div1 %r15		;//  3
	div1 %r15		;//  4
	div1 %r15		;//  5
	div1 %r15		;//  6
	div1 %r15		;//  7
	div1 %r15		;//  8
	div1 %r15		;//  9
	div1 %r15		;// 10
	div1 %r15		;// 11
	div1 %r15		;// 12
	div1 %r15		;// 13
	div1 %r15		;// 14
	div1 %r15		;// 15
	div1 %r15		;// 16
	ld.w %r1, %ahr		;// z.n * 2
	add %r1, %r1
	not %r2, %r15		;// z.d
	xadd %r2, %r2, 1
	ld.w %r6, %alr		;// z.u
	mlt.h %r6, %r13
	ld.w %r6, %alr
	;// %r0  = cur.z
	;// %r1  = DDA.z.n * 2
	;// %r2  = DDA.z.d
	;// %r6  = DDA.z.u
	;// %r13 = DDA.z.v

	;// DDAループ。
	ld.w %r7, %r15
	add %r15, %r15
	xld.ub %r12, [%r14+24]	;// param->fore_color
__draw_scanline_wz_color_loop:
	;// %r7  = n
	;// %r15 = nx * 2
	;// %r12 = fore_color

	;// Ｚ比較。
	ld.uh %r4, %r0		;// zval
	xsrl %r4, 8
	xld.ub %r5, [%r11]	;// *zptr
	cmp %r4, %r5
	xjrugt __draw_scanline_wz_color_skip
	;// %r4 = zval

	;// テクスチャ無しなら、フェイスの背景色で描きます。
	xld.b [%r10], %r12	;// *vptr
	xld.b [%r11], %r4	;// *zptr
__draw_scanline_wz_color_skip:

	;// バッファポインタを進めます。
	xadd %r10, %r10, 1
	xadd %r11, %r11, 1

	;// DDAステップ実行。
	;// (DDA.z)
	add %r0, %r6		;// cur.z += z.u
	add %r2, %r1		;// z.d += z.n * 2
	xjruge __draw_scanline_wz_color_step_z ;// !C条件
	add %r0, %r13		;// cur.z += z.v
	sub %r2, %r15		;// z.d -= nx * 2
__draw_scanline_wz_color_step_z:

	xsub %r7, %r7, 1
	xjrne __draw_scanline_wz_color_loop

__draw_scanline_wz_color_ret:
	popn	%r2
	ret
	");
#endif
#endif /*REND_NOASM*/
