/*	
 *	framds21.c
 *
 *	高速RAM転送候補：スキャンライン描画関数（Ｚ比較なし・テクスチャなし）
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2008 Naoyuki Sawa
 *
 *	* Mon Aug  2 05:00:00 JST 2004 Naoyuki Sawa
 *	- clipren3.cから移動してきました。
 *	* Sat Aug 25 23:05:34 JST 2007 Naoyuki Sawa
 *	- アセンブラ化しました。
 *	* 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_woz_color(const RENDVERTEX* v0, const RENDVERTEX* v1, DSLPARAM* param)
{
	unsigned char* vptr;	/* カラーバッファポインタ     */
	int nx;			/* 現在のスキャンラインの長さ */
	int n;			/* 現在の辺の残りピクセル数   */
	const RENDVERTEX* tmp;
	int ofs;

	/* 確実に 左: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;

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

	/* DDAループ。 */
	n = nx;
	do {
//{{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:変更
		/* バッファポインタを進めます。 */
		vptr++;
	} while(--n); /* 右端ピクセルは描かないので、プリデクリメントです。 */
}
#else /*REND_NOASM*/
	asm("
	.code
	.align 1
	.global draw_scanline_woz_color
	;// IN:
	;// %r12     = v0
	;// %r13     = v1
	;// %r14     = param
draw_scanline_woz_color:
	;// USAGE:
	;// none

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

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

	xld.ub	%r12, [%r14+24]				;// param->fore_color
	;// %r12 = fore_color

	;// 主軸のDDAセットアップ。
	xld.uh	%r5, [%r13+0]				;// v1->x
	xjp.d	__draw_scanline_woz_color_next
	sub	%r5, %r6				; *delay*
	;// %r5     = n
	;// %psr(Z) = n==0

	;// DDAループ。
__draw_scanline_woz_color_loop:
	ld.b	[%r4]+, %r12				;// *vptr++
	;// 初回はここから始まります。
	;// ・n==0ならば、何も描かずに抜けます。
	;//   n=(n-1)になりますが、ダミー動作です。
	;// ・n!=0ならば、n=(n-1)、フラグに(n-1)==0を反映して、ループします。
	;// 2回目にここへ来たときも、フラグが維持されていることを利用します。
	;// ループカウンタとフラグは前のループの遅延スロットで先に変化させておき、
	;// 次のループでその結果を参照するわけです。
__draw_scanline_woz_color_next:
	xjrne.d	__draw_scanline_woz_color_loop
	sub	%r5, 1					; *delay*
	;// %r5     = (n-1)
	;// %psr(Z) = (n-1)==0

	ret
	");
#endif /*REND_NOASM*/
