#include "defines.h"
#include "aigtext.h"
#include "doslibm.h"

// セット関数
void (*tset)(int,int,int,int,int)=_tpset3;

void txline3_set(void (*set)(int,int,int,int,int))
// セット関数設定
{
	tset=set;
}

void txline3(int planes,int sx,int sy,int ex,int ey,int sz,int fset)
// tpset3（変更可能）を使ったtxline
// planes : BIT0=plane0,BIT1=plane1,BIT2=plane2,BIT3=plane3
//	   同時に複数のプレーン指定可能
// sz	 : 1dotの大きさ:1,2,4,8,16のみ
// fset	 : 0=reset , 1=set
// x,y	 : 表示座標:0〜(1024/sz)-1
{
#define	BAI	1024	// 整数化のための倍数
// x68のintは32bitなので65536*65536までは大丈夫
// 従って、*1024はオーバーフローしない(x,y<1024だから)
int k,dx=1,dy=1,z=0,x,y;
int ssp;
	ssp=SUPER(0);
	if (sx==ex && sy==ey) { // 点になるとき
		tset(planes,sx,sy,sz,fset);
	} else { // 線になるとき
	    x=ex-sx; if (x<0) {dx=-1; x=-x;}
	    y=ey-sy; if (y<0) {dy=-1; y=-y;}
	    x++; y++; // 幅だから+1
	    if (y>x) { // 傾きが４５°より大きい線
		k=(x*BAI)/y; // 傾き（整数化）
		do {
			tset(planes,sx,sy,sz,fset);
			sy+=dy;
			z+=k;
			if (z>=BAI) {sx+=dx; z-=BAI;}
		} while (sy!=ey+dy);
	    } else { // 傾きが４５°以下の線
		k=(y*BAI)/x; // 傾き（整数化）
		do {
			tset(planes,sx,sy,sz,fset);
			sx+=dx;
			z+=k;
			if (z>=BAI) {sy+=dy; z-=BAI;}
		} while (sx!=ex+dx);
	    }
	}
	if (ssp>=0) SUPER(ssp);
}

/* オリジナルlineアルゴリズム
	(sx,sy)-(ex,ey)に線分を引く場合

前提(1)
	ex>=sx,ey>=sy
	（逆の時は入れ換えればよいだけ）

	その線分の傾きは
	k=(ex-sx+1)/(ey-sy+1)

前提２(2)
	この傾きが０°〜４５°を考える
		(ex-sx+1)>(ey-sy+1)
	この時、xは常に+1され、yは数回に１回+1される
	（それ以上の時は逆にyを基準にして考えればよいだけ）

このままでは傾きkは実数になるので、1024倍して整数化する。
1024倍するのはＸ６８の画面幅が1024*1024までだから
（(0,0)-(1023,1)の線分も引けるようにするため）＋シフトで計算出来る倍率だから。
Ｘ６８では最大座標が1023だから1023*1023は３２ビットで収まるので計算しやすい。

(sx,sy)から描画を始め、xは常に+1,yは傾きkの累積が1024を以上になる時に+1する。
yを+1したときはk-=1024しておく。

このアルゴリズムは最初に整数割り算があるが、それ以後は単純な加算だけでいけるので
簡単だし速いと思われる。

*/


#if 0
#include <conio.h>

void txline3s(int planes,int sx,int sy,int ex,int ey,int sz,int fset)
{
// ex>sx,ey>sy
//	txline3(planes,sx,sy,ex,ey,2,1); // ＋傾き
//	txline3(planes,sx,ey,ex,sy,2,1); // −傾き
// sx>ex,sy>ey
	txline3(planes,ex,ey,sx,sy,2,1); // ＋傾き
	txline3(planes,ex,sy,sx,ey,2,1); // −傾き
	getch();
}

void main()
{
	txline3(BIT0,30,30,30,30,8,1);	// １点

	txline3s(BIT0,10,10,100,100,2,1);	// =45°
	txline3s(BIT1,10,10,100, 50,2,1);	// <45
	txline3s(BIT1,10,10, 50,100,2,1);	// >45
	txline3(BIT1|BIT0,10,10,100,10,2,1);	// 水平
	txline3(BIT1|BIT0,10,10,10,100,2,1);	// 垂直
	getch();

	cls();
	txline3_set(_tpset2);	// 描画関数変更
	txline3s(BIT0,10,10,100,100,2,1);	// =45°
	txline3s(BIT1,10,10,100, 50,2,1);	// <45
	txline3s(BIT1,10,10, 50,100,2,1);	// >45
	txline3(BIT1|BIT0,10,10,100,10,2,1);	// 水平
	txline3(BIT1|BIT0,10,10,10,100,2,1);	// 垂直
}
#endif
