/*
tab 4
	なんかよくわからんが『ポリゴンぐるぐる』とでも名付けよう
	OpenSMのデモっすね。スプライト使ってないケド。
*/


#include <stdio.h>
#include <stdlib.h>
#include <OpenSM.h>
#define PAD_U		(0x01<<0)
#define PAD_D		(0x01<<1)
#define PAD_L		(0x01<<2)
#define PAD_R		(0x01<<3)
#define PAD_A		(0x01<<4)
#define PAD_B		(0x01<<5)
#define PAD_RUN		(0x01<<6)
#define PAD_SEL		(0x01<<7)


char	egb[1536];
short	tex[256*96];

static const unsigned char SwapFont[] = {
	0x00,0x39,0x13,0x96,0x78,0x41,0x50,0x59,
	0x84,0x79,0x53,0xd1,0x84,0x05,0x54,0x51,
	0x78,0x44,0xa4,0xd9,0x00,0x38,0xa3,0x56,
	0x00,0x00,0x00,0x10
};


main()
{
	int i;
	struct {
		short	x;
		short	y;
		short	n;
		char	s[80];
	}str;
	FILE	*fp;
	OBJ		*obj;
	COLTBL	*coltbl;
	
	SMfixed eye;
	
	
	/* テクスチャの読み込みっす */
	fp = fopen("../sys/open_sm", "rb");
	fseek(fp, 512, SEEK_SET);		/* 実際ただのTIFFなのよ､これが */
	fread(tex, 2, 256*96, fp);
	fclose(fp);
	
	
	/* ディスプレイの初期化(EGBの初期化もしてくれる)	*/
	smInitDisplay(egb, SM_ONLY_POLYGON | SM_MODE_3 | SM_WIDE);
	smInitTable();	/* テーブルも初期化しなくちゃ */
	
	
	
	/* おまけだっ 2画面合成(って初期化の時にモード3を使うと宣言したでしょ) */
	/* レイア0に文字を書きましょう…とりあえず操作方法でも書くとしますか */
	EGB_writePage(egb, 0);
	EGB_color(egb, 0, 15);
	
	strcpy(str.s, "パッドで操作します。　＜ＲＵＮボタンで終了＞");
	str.n = strlen(str.s);
	str.x = (512-str.n*8)/2;
	str.y = 20;
	EGB_sjisString(egb, &str);
	
	strcpy(str.s, "dosage:   U&D:pitch, L&R:head, BwithL&R:bank");
	str.n = strlen(str.s);
	str.x = (512-str.n*8)/2;
	str.y = 40;
	EGB_sjisString(egb, &str);
	
	strcpy(str.s, "AwithU&D:vertical, AwithL&R:horizontal");
	str.n = strlen(str.s);
	str.x += 8*10;
	str.y = 60;
	EGB_sjisString(egb, &str);
	
	strcpy(str.s, "OpenSM the Sprite manager for FM-TOWNS2");
	str.n = strlen(str.s);
	str.x = 511-8*str.n-4;
	str.y = 474;
	EGB_sjisString(egb, &str);
	
	EGB_putRectColor(egb, 0, SwapFont, 11, 466, 42, 472);
	EGB_writePage(egb, 1);
	EGB_color(egb, 0, 31<<10);
	
	strcpy(str.s, "wait a moment");
	str.n = strlen(str.s);
	str.x = (255-8*str.n)/2;
	str.y = 120;
	EGB_sjisString(egb, &str);
	
	
	
	
	
	
	
	
	/* オブジェクトの登録…ID(オブジェクトポインタ)をもらう */
	obj = smEntryObject();
	
	
	
	/*
		オブジェクトを作りませう
		面倒なんでファイル読み込みます…
	*/
	{
		SMfixed	x,y,z;
		int		p[4];
		short	t[3][2];
		int		i, j;
		int		loop;
		char	str[64];
		
		
		fp = fopen("demo.dat", "r");
		
		
		/* 頂点を設定する｡ 頂点番号は50番以降を使おうっと(きまぐれ) */
		fscanf(fp, "%s %ld", str, &loop);
		
		for(i=0; i<loop; i++){
			
			fscanf(fp, "%ld %ld %ld", &x.c, &y.c, &z.c);
			
			smDefineVertex(obj, 50+i, x, y, z);
		}
		
		
		
		/* ポリゴンを登録する(もちろん頂点とテクスチャも対応付ける) */
		fscanf(fp, "%s %ld", str, &loop);
		
		for(i=0; i<loop; i++){
			
			fscanf(fp, "%ld %ld %ld %s %ld %d %d %d %d %d %d",
				&p[1], &p[2], &p[3],  str,&j,
				&t[0][0],&t[0][1], &t[1][0],&t[1][1], &t[2][0],&t[2][1]);
			
			p[1] += 50;	/* 頂点番号50番以降を使うから(オフセット) */
			p[2] += 50;
			p[3] += 50;
			
			smDefinePolygon(obj, &p[1], t, tex);
		}
		
		fclose(fp);
		
		
		
		
		/*
			テクスチャデータを輝度別展開
			ライトインテンシティーは0.75…かなり陰影が鋭いスポットライト風
			深さは18にしよ (intensityが0.73だと計算上は22〜24が適当だけど)
		*/
		coltbl = smMakeShadingMap(tex, 256, 96, 18, 0.75);
		
		/* んで'tex'を使用している全ポリゴンをシェーディングONにする */
		smDefineShading(obj, tex, coltbl);
	}
	
	
	
	
	/* カメラ関係を適当に初期化しておきますか */
	smClipAreaPolygon(0, 0, 255, 239);		/* 表示される範囲(dot)*/
	
	eye.d.h = 600;				/* スクリーンから少し離れないとね */
	smViewpoint((SMfixed){0}, (SMfixed){0}, eye);		/* 視点	*/
	/* えーと､眼点が600ってぇいうと14インチディスプレイで40〜50cm */
	/* ぐらい離れた距離で見るとちょうどいいはず(計算が合ってれば) */
	
	
	
	
	/* ここからがループだ */
	{
		SMfixed rx,ry,rz;		/* 回転角度	*/
		SMfixed mx,my,mz;		/* 平行移動	*/
		int		null = 0;		/* ダミーだ	*/
		int		pad;			/* パッドよ	*/
		
		rx.c=ry.c=rz.c = 0;
		mx.c=my.c=mz.c = 0;
		
		while(1){
			
			/* パッドから情報を読むっす */
			SND_joy_in_2(0, &pad);
			if( ~pad&PAD_RUN )			/* RUNで終了	*/
				break;
			while( ~pad&PAD_SEL ){		/* SELECTでPAUSE	*/
				SND_joy_in_2(0, &pad);
				if( ~pad&PAD_A ){		/* PAUSE中A,Bで視点変更	*/
					smViewpoint(
						(SMfixed){0}, (SMfixed){0}, (SMfixed){600*65536});
					pad = PAD_SEL;
				} else if( ~pad&PAD_B ){
					smViewpoint(
						(SMfixed){0}, (SMfixed){0}, (SMfixed){200*65536});
					pad = PAD_SEL;
				}
			}
			if( ~pad&PAD_A ){			/* A押しながらで移動	*/
				if( ~pad&PAD_L )
					mx.d.h -= 2;		/* 2.0づつ移動する		*/
				if( ~pad&PAD_R )
					mx.d.h += 2;
				if( ~pad&PAD_U )
					my.d.h -= 2;
				if( ~pad&PAD_D )
					my.d.h += 2;
			} else if( ~pad&PAD_B ){	/* B押しながらでZ軸操作	*/
				if( ~pad&PAD_U )
					mz.d.h += 20;
				if( ~pad&PAD_D )
					mz.d.h -= 20;
				if( ~pad&PAD_L )
					rz.d.l += 655;
				if( ~pad&PAD_R )
					rz.d.l -= 655;
			} else {					/* ボタン放して回転		*/
				if( ~pad&PAD_L )
					ry.d.l += 655;		/* 10%づつ回転する	*/
				if( ~pad&PAD_R )
					ry.d.l -= 655;
				if( ~pad&PAD_U )
					rx.d.l += 655;
				if( ~pad&PAD_D )
					rx.d.l -= 655;
			}
			
			
			
			/* 自動的にある程度回転させる */
			rx.d.l -= 40;
			ry.d.l -= 40;
			rz.d.l += 200;
			
			
			/* 座標操作するっす (この場合は回転してから移動してる) */
			smBegin(obj);
			smRotate(obj, rx, ry, rz);
			smTranslate(obj, mx, my, mz);
			smEnd(obj);
			
			
			/* さて､描くとしますか */
			smClearPolygonBuffer(3<<5|6);	/* まず適当な色で消してから	*/
			smDrawObject(obj);				/* 描く						*/
			EGB_singlePset(egb, 6, 234);	/* 目印						*/
			EGB_singlePset(egb, 7, 234);	/* 目印						*/
			EGB_palette(egb, 1, &null);		/* 一応VSYNCを待ちますか	*/
			smSwapPolygonBuffer();			/* んで､表示すると			*/
		}
	}
	
	
	
	/* 使った領域を開放します…ってぇそんな必要ないんじゃない?? EXPだし */
	smUndefineShading(obj, NULL);	/* シェーディング解除(実は無意味) */
	smFreeShadingMap(coltbl);		/* これって結構メモリ使ってんのよ */
	smReturnObject(obj);			/* うっわ〜礼儀正しい	*/
	
	
	puts("ok!!!!!!!!!!!!!えぇぇぇぇぇぇぇ     うえ");
}

