//--------------------------------------------------------------------------------------
//
// X-BASIC'
//	外部関数：iOS用 Graphic
//
//--------------------------------------------------------------------------------------
// 外部関数の構造を持っている

#import	"RunViewController.h"
#import "Console+animation.h"
#import "gConsole+bitmap.h"
#import "gConsole+bitmapEx.h"
#import "gConsole+picloader.h"
#import "libs.h"
#include "XBiOSg.h"
#include "fdef.h"
#include "support.h"
#import "rgbhsv.h"
#import "NSString+substringWithRange2.h"

//---------------------------------------------------------------------------------------------
// 共通ワーク

static RunViewController *runView;	// <- これはインターフェースから
static gConsole  *gconsole;		// これは内部で設定

#define MAX_POINTS	64
CGPoint points[MAX_POINTS];	// 面倒なので固定ワーク

//---------------------------------------------------------------------------------------------

static RET_FUNC _F_version(SWord numFAC,FAC fac[])
// この外部関数のバージョンを返す
{
	printFunc();
	fac[0].dl.cp[LL]=VERSION_XBIOSFUNCG;
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------
// 画面サイズ取得 v3.20
//---------------------------------------------------------------------------------------------

// 引数とリターン値はgetBitmapSize()に合わせてある
// gwy=getScreenWidth([gwx;int])
RET_FUNC _F_getScreenSize(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int gwx;
	int *ip=&gwx;
	if (fac[0].facType!=VOID_PARAM) { // 引数が省略されていない時
		ip=fac[0].dl.ip[LL];
	}
	*ip=gconsole.consoleWidth;
	int gwy=gconsole.consoleHeight;
	nslog(@"グラフィック画面幅=%d*%d",*ip,gwy);
	//
	fac[0].dl.l[LL]=gwy;
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------
// 画面表示
//---------------------------------------------------------------------------------------------

// pset(x,y)
// 直前のgcolor()色で描画
RET_FUNC _F_pset(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat x=fac[i++].dl.d;
	CGFloat y=fac[i++].dl.d;
	[gconsole pset:x y:y];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_line(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	CGFloat ex=fac[i++].dl.d;
	CGFloat ey=fac[i++].dl.d;
	int ffill=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		ffill=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;
	
	NSUInteger style=0xffff;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		style=fac[i].dl.l[LL];
	}
	[gconsole line:sx sy:sy ex:ex ey:ey fill:ffill style:style];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_box(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	CGFloat ex=fac[i++].dl.d;
	CGFloat ey=fac[i++].dl.d;
	NSUInteger style=0xffff;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		style=fac[i].dl.l[LL];
	}
	[gconsole box:sx sy:sy ex:ex ey:ey style:style];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_fill(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	CGFloat ex=fac[i++].dl.d;
	CGFloat ey=fac[i++].dl.d;
	[gconsole fill:sx sy:sy ex:ex ey:ey];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_circle(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat cx=fac[i++].dl.d;
	CGFloat cy=fac[i++].dl.d;
	CGFloat r =fac[i++].dl.d;
	//
	CGFloat startAngle=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		startAngle=fac[i].dl.d;
		nslog(@"startAngle=%f/%f度",startAngle,radian2degree(startAngle));
		// 累積演算誤差で2.0*M_PIを超えることがあるようなので削除
//		if (startAngle<-2.0*M_PI||startAngle>2.0*M_PI) {
//			setExternalFuncErrmes("開始角度が範囲外です","Start angle is illegal.");
//			return (RET_FUNC_ERR);
//		}
	}
	i++;
	
	CGFloat endAngle=2.0*M_PI;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		endAngle=fac[i].dl.d;
		nslog(@"endAngle=%f/%f度",endAngle,radian2degree(endAngle));
		// 累積演算誤差で2.0*M_PIを超えることがあるようなので削除
//		if (endAngle<-2.0*M_PI||endAngle>2.0*M_PI) {
//			setExternalFuncErrmes("終了角度が範囲外です","End angle is illegal.");
//			return (RET_FUNC_ERR);
//		}
	}
	i++;
	
	int	clockwise=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		clockwise=(int)fac[i].dl.l[LL];
	}
	i++;
	
	int ffill=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		ffill=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;
	
	NSUInteger style=0xffff;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		style=fac[i].dl.l[LL];
	}
	
	nslog(@"circle:(%f,%f)r=%f,Angle:%f〜%f,clockwise=%d,style=$%04x,ffill=%d",cx,cy,r,startAngle,endAngle,clockwise,(int)style,ffill);
	[gconsole circle:cx cy:cy r:r startAngle:startAngle endAngle:endAngle clockwise:clockwise fill:ffill style:style];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}


RET_FUNC _F_ellipse(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat cx=fac[i++].dl.d;
	CGFloat cy=fac[i++].dl.d;
	CGFloat r =fac[i++].dl.d;
	
	CGFloat hv=1.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		hv=fac[i].dl.d;
	}
	i++;
	
	int ffill=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		ffill=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;
	
	NSUInteger style=0xffff;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		style=fac[i].dl.l[LL];
	}
	
	nslog(@"ellipse:(%f,%f)r=%f,hv=%f,style=$%04x,ffill=%d",cx,cy,r,hv,(int)style,ffill);
	[gconsole ellipse:cx cy:cy r:r hv:hv fill:ffill style:style];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}


void _F_gBackgroundAlphaSub(double alpha)
{
	[gconsole alpha:alpha];
}

static RET_FUNC _F_gBackgroundAlpha(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	_F_gBackgroundAlphaSub(fac[0].dl.d);
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_gBackgroundColor(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int r,g,b,alpha;
	getRGBColorFromFac(fac,0,&r,&g,&b,&alpha); // v2.2
	[gconsole backgroundColor:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_lineWidth(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	[gconsole lineWidth:fac[0].dl.d];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_lineCap(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	[gconsole lineCap:(int)fac[0].dl.l[LL]];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_lineJoin(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	[gconsole lineJoin:(int)fac[0].dl.l[LL]];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_blend(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	[gconsole blend:(int)fac[0].dl.l[LL]];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_splitRGB(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int rgba  =(int)fac[i++].dl.l[LL];
	int *r	  =fac[i++].dl.ip[LL];
	int *g	  =fac[i++].dl.ip[LL];
	int *b	  =fac[i++].dl.ip[LL];
	int *alpha=fac[i++].dl.ip[LL];
	splitRGB(rgba,r,g,b,alpha);
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_rgb(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	// ここはr,g,bすべて必要なのでgetRGBColorFromFac()は使えない
	int r,g,b,alpha;
	r=(int)fac[i++].dl.l[LL];
	g=(int)fac[i++].dl.l[LL];
	b=(int)fac[i++].dl.l[LL];
	alpha=255; // 省略時
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		alpha=(int)fac[i].dl.l[LL];
	}
	
	fac[0].dl.l[LL]=rgb(r,g,b,alpha);
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_hsv(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int h,s,v,alpha;
	h=(int)fac[i++].dl.l[LL];
	s=(int)fac[i++].dl.l[LL];
	v=(int)fac[i++].dl.l[LL];
	alpha=255; // 省略時
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		alpha=(int)fac[i].dl.l[LL];
	}
	fac[0].dl.l[LL]=hsv(h,s,v,alpha);
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}


RET_FUNC _F_gColor(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int r,g,b,alpha;
	getRGBColorFromFac(fac,0,&r,&g,&b,&alpha); // v2.2
	[gconsole color:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_gborder(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat width=fac[i++].dl.d;
	if (width>0) {
		int r,g,b,alpha;
		getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
		[gconsole border:width r:r g:g b:b alpha:alpha];
	} // width<=0の時は何もしない
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_wipe(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	[gconsole wipe];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

RET_FUNC _F_symbol(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	nslog(@"%f,%f",sx,sy);
	UByte  *bp=fac[i++].dl.bp[LL];
	if (*bp!=0) {
		UByte *str=strWithUTF8no(bp,0); // UTF8化
		nslog(@"str=%@",@((char*)str));
		UByte *fontName	=strWithUTF8no(fac[i++].dl.bp[LL],1); // UTF8化
		CGFloat pointSize=fac[i++].dl.d;
		nslog(@"fontName=%@/size=%f",@((char*)fontName),pointSize);
		@autoreleasepool {
			CGSize size=[gconsole symbol:sx sy:sy str:uCstringToNSString(str) fontName:uCstringToNSString(fontName) pointSize:pointSize];
			//
			if (fac[i].facType!=VOID_PARAM) {
				double *dp=fac[i].dl.dp[LL];
#if AARM>=2
				storeDoubleToDoublePointer(dp,size.height);
#else
				*dp=size.height;
#endif
				nslog(@"size.height=%f(%p)",*dp,dp);
			}
			fac[0].dl.d=size.width;
		}
	} else {
		// 文字列=""のときは実行されない
		fac[0].dl.d=0;
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// 縦書symbol
static RET_FUNC _F_symbolt(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	UByte  *bp=fac[i++].dl.bp[LL];
	if (*bp!=0) {
		UByte *str=strWithUTF8no(bp,0); // UTF8化
		UByte *fontName	=strWithUTF8no(fac[i++].dl.bp[LL],1); // UTF8化
		CGFloat pointSize=fac[i++].dl.d;
		@autoreleasepool {
		//
			NSString *ufontName=uCstringToNSString(fontName);
			NSString *ustr=uCstringToNSString(str);
			nslog(@"sx=%f,sy=%f,fontName=%@,str=%@",sx,sy,ufontName,ustr);
			
			for (int i=0;i<[ustr length];i++) {
				nslog(@"i=%d",i);
				NSRange range=NSMakeRange(i, 1);
				NSString *c=[ustr substringWithRange2:range];
				nslog(@"c=%@",c);
				CGSize size=[gconsole symbol:sx sy:sy str:c fontName:ufontName pointSize:pointSize];
				sy+=size.height;
			}
		//
		}
	} // str=""の時は何もしない
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//　配列にはx1,y1,x2,y2・・・の順で格納しておくこと
static RET_FUNC _F_lines(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	SWord size1;
	uwYouso youso;
	
	DOUBLE_LONG *xys=(DOUBLE_LONG *)getDim1FromFAC(fac,0,&size1,&youso); // fac[0]から
	// float配列は直接float*で読みだしてはいけない
	if (xys==NULL) { // 1次元でない
		return (RET_FUNC_ERR);
	}
	// x,yの組みからCGPointに変更する
	int max=(youso<=MAX_POINTS*2? youso:MAX_POINTS)/2; // x,yの2つで1組だから
	nslog(@"1要素サイズ=%d,要素数=%d,座標組数=%d",size1,youso,max);
	int i;
	for (i=0;i<max;i++) {
#if AARM>=1
		points[i].x=readDoubleFromDOUBE_LONGPointer(xys++);
		points[i].y=readDoubleFromDOUBE_LONGPointer(xys++);
#else
		points[i].x=xys->d; xys++;
		points[i].y=xys->d; xys++;
#endif
		nslog(@"[%d]=%f,%f",i,points[i].x,points[i].y);
	}

	i=1; // fac[1]から
	int ffill=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		ffill=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;
	
	NSUInteger style=0xffff;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		style=fac[i].dl.l[LL];
	}
	[gconsole lines:points count:max fill:ffill style:style];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}
//-----------------------------------------

static RET_FUNC _F_gfileStatus(SWord numFAC,FAC fac[])
{
	printFuncs(@":fret=%d",gconsole.fret);
	fac[0].dl.l[LL]=gconsole.fret; // マルチタスクしているので、直後では正しくない可能性もあるので、後からも読めるようにした
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_pngSave(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	UByte *bp=fac[0].dl.bp[LL];
	if (*bp==0) {
		nslog(@"ファイル名がNULLである");
		fac[0].dl.l[LL]=NO; // ファイルが見つかるはずがない
	} else {
		@autoreleasepool {
			[gconsole imageSave:@(bstrWithUTF8(bp)) quality:1.0 fjpeg:NO]; // qualityはダミー // UTF8化
		}
		//
		fac[0].dl.l[LL]=gconsole.fret; // マルチタスクしているので、直後では正しくない可能性もある;-1/YES/NOだが、BASICでは-1/1/0になる(YES/NOはBASIC型に変換しない)
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_jpegSave(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	UByte *bp=fac[0].dl.bp[LL];
	if (*bp==0) {
		nslog(@"ファイル名がNULLである");
		fac[0].dl.l[LL]=NO; // ファイルが見つかるはずがない
	} else {
		@autoreleasepool {
			[gconsole imageSave:@(bstrWithUTF8(bp)) quality:fac[1].dl.d fjpeg:YES]; // UTF8化
		}
		//
		fac[0].dl.l[LL]=gconsole.fret; // マルチタスクしているので、直後では正しくない可能性もある;-1/YES/NOだが、BASICでは-1/1/0になる(YES/NOはBASIC型に変換しない)
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_imageCopyToAlbum(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	UByte *bp=fac[0].dl.bp[LL];
	if (*bp==0) {
		nslog(@"ファイル名がNULLである");
		fac[0].dl.l[LL]=NO; // ファイルが見つかるはずがない
	} else {
		@autoreleasepool {
			[gconsole imageCopyToAlbum:makeFullPathForSaveData(@(bstrWithUTF8(bp)))]; // UTF8化
		}
		//
		fac[0].dl.l[LL]=gconsole.fret; // マルチタスクするので、直後では正しくない;-1/YES/NOだが、BASICでは-1/1/0になる(YES/NOはBASIC型に変換しない)
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_imgLoad(SWord numFAC,FAC fac[])
{
	printFunc();
	// sx,sy,wx,wyをv3.00で省略可能化
	int i=0;
	CGFloat sx=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sx=fac[i].dl.d;
	}
	i++;
	CGFloat sy=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sy=fac[i].dl.d;
	}
	i++;
	CGFloat wx=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wx=fac[i].dl.d;
	}
	i++;
	CGFloat wy=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wy=fac[i].dl.d;
	}
	i++;
	UByte *fname=fac[i++].dl.bp[LL];
	if (*fname==0) {
		nslog(@"ファイル名がNULLである");
		// 何も実行しない
		fac[0].dl.l[LL]=NO; // ファイルが見つかるはずがない
	} else {
		@autoreleasepool {
			[gconsole imgLoad:sx sy:sy wx:wx wy:wy fname:@(bstrWithUTF8(fname)) ftile:NO]; // UTF8化
		}
		//
		fac[0].dl.l[LL]=gconsole.fret; // マルチタスクしているので、直後では正しくない可能性もある;-1/YES/NOだが、BASICでは-1/1/0になる(YES/NOはBASIC型に変換しない)
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_tileImgLoad(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sx=fac[i].dl.d;
	}
	i++;
	CGFloat sy=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sy=fac[i].dl.d;
	}
	i++;
	CGFloat wx=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wx=fac[i].dl.d;
	}
	i++;
	CGFloat wy=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wy=fac[i].dl.d;
	}
	i++;
	
	UByte *fname=fac[i++].dl.bp[LL];
	if (*fname==0) {
		nslog(@"ファイル名がNULLである");
		fac[0].dl.l[LL]=NO; // ファイルが見つかるはずがない
	} else {
		@autoreleasepool {
			[gconsole imgLoad:sx sy:sy wx:wx wy:wy fname:@(bstrWithUTF8(fname)) ftile:YES]; // UTF8化
		}
		//
		fac[0].dl.l[LL]=gconsole.fret; // マルチタスクしているので、直後では正しくない可能性もある;-1/YES/NOだが、BASICでは-1/1/0になる(YES/NOはBASIC型に変換しない)
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------

// グラフィックの描画対象ページ
RET_FUNC _F_apage(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int page=(int)fac[0].dl.l[LL];
	nslog(@"GCONSOLE0=%d〜GCONSOLE3=%d:page=%d",GCONSOLE0,GCONSOLE3,page);
	if (page>=GCONSOLE0 && page<=GCONSOLE3) {
		gconsole=[runView getConsole:page];
		nslog(@"apage=%d:%@",page,gconsole);
		runView.nowApage=page;
	} else {
		nslog(@"apage;ページ番号が範囲外:page=%d",page);
		// 何もしない
	}
	fac[0].dl.l[LL]=runView.nowApage; // 現在の設定を返す
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// 表示ページ設定
// vpage(page)
// bit対応 : bit(?CONSOLE)=1 表示
RET_FUNC _F_vpage(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int pageBits=(int)fac[0].dl.l[LL];
	// 第2引数は現在未使用；仕様確定時に消し忘れていた
	// 旧仕様:vpage(1ページ,onoff)
	// 現仕様:vpage(ビット単位ページ指定) 指定ページをON,他をOFF
	nslog(@"pageBits=$%08x",pageBits);
	if (pageBits>=0) {
		for (int i=SCONSOLE;i<=GCONSOLE3;i++) {
			BOOL onoff=NO;
			if (pageBits&bit(i)) {
				onoff=YES;
			}
			nslog(@"bit%d=%d",i,onoff);
			// こちらはページ単位で設定
			[runView vpage:i onoff:onoff];
		}
		runView.nowVpage=pageBits;
	} // <0なら現在の設定を返すのみ
	fac[0].dl.l[LL]=runView.nowVpage; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// テキストとグラフィックのページ表示優先順位
static RET_FUNC _F_vpriority(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	int p0=(int)fac[i++].dl.l[LL]; // pn=?CONSOLE(1~)
	int p1=(int)fac[i++].dl.l[LL];
	int p2=(int)fac[i++].dl.l[LL];
	int p3=(int)fac[i++].dl.l[LL];
	int p4=(int)fac[i++].dl.l[LL];
	int p5=SCONSOLE; // スプライトがないときはp4までが有効
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		p5=(int)fac[i].dl.l[LL];
	}
	i++;
	fac[0].dl.l[LL]=c2basicYESNO([runView vpriority:p0 p1:p1 p2:p2 p3:p3 p4:p4 p5:p5]);
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// ON/OFFのみ
static RET_FUNC _F_screenRotate(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	BOOL onoff=(fac[0].dl.l[LL]==BASIC_YES? NO:YES);
	[runView disableRotate:onoff]; // YESでdisable
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_getOrientation(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	fac[0].dl.l[LL]=getOrientation();
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_gAntiAlias(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	[gconsole antiAliasing:basic2cYESNO(fac[0].dl.l[LL])];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------
// bitmap関数(v1.6)
//---------------------------------------------------------------------------------------------

// int bitmapOpen([wx;int,wy;int][fdirect;int])
// サイズ省略時はView幅と同じ
static RET_FUNC _F_bitmapOpen(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	int width=0,height=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		width=(int)fac[i].dl.l[LL];
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		height=(int)fac[i].dl.l[LL];
	}
	i++;
	//
	BOOL fdirect=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fdirect=basic2cYESNO(fac[i].dl.l[LL]);
	}
	//
	fac[0].dl.l[LL]=c2basicYESNO([gconsole bitmapOpen:width height:height fdirect:fdirect]);
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// void bitmapClose()
static RET_FUNC _F_bitmapClose(SWord numFAC,FAC fac[])
{
	printFunc();
	[gconsole bitmapClose];
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// void bitmapWipe()
static RET_FUNC _F_bitmapWipe(SWord numFAC,FAC fac[])
{
	printFunc();
	[gconsole bitmapWipe];
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// void bitmapPset(x;int,y;int,r;int[,g;int,b;int[,alpha;int]])
// bitmap内は座標がint
static RET_FUNC _F_bitmapPset(SWord numFAC,FAC fac[])
{
//	printFunc();
	//
	int i=0;
	int x=(int)fac[i++].dl.l[LL];
	int y=(int)fac[i++].dl.l[LL];
	int r,g,b,alpha;
	getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
	[gconsole bitmapPset:x y:y r:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// int bitmapPoint(x;int,y;int[,r;int,g;int;b;int,alpha;int])
static RET_FUNC _F_bitmapPoint(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int x=(int)fac[i++].dl.l[LL];
	int y=(int)fac[i++].dl.l[LL];
	if (fac[i].facType!=VOID_PARAM) {
		int *r	  =fac[i++].dl.ip[LL];
		int *g	  =fac[i++].dl.ip[LL];
		int *b	  =fac[i++].dl.ip[LL];
		int *alpha=fac[i++].dl.ip[LL];
		fac[0].dl.l[LL]=[gconsole bitmapPoint:x y:y r:r g:g b:b alpha:alpha];
	} else { // r/g/b/alpha省略時は合成RGB値のみを返すため、各変数はダミーを与える
		int r,g,b,alpha;
		fac[0].dl.l[LL]=[gconsole bitmapPoint:x y:y r:&r g:&g b:&b alpha:&alpha];
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

enum {
	BITMAP_LINE=0,
	BITMAP_BOX,
	BITMAP_FILL,
};

// void bitmap*(sx;int,sy;int,ex;int,ey;int,r;int[,g;int,b;int[,alpha;int]])共通処理
static RET_FUNC bitmapLineBoxFill(SWord numFAC,FAC fac[],int mode)
{
	printFuncs(@"%d",mode);
	//
	int i=0;
	int sx=(int)fac[i++].dl.l[LL];
	int sy=(int)fac[i++].dl.l[LL];
	int ex=(int)fac[i++].dl.l[LL];
	int ey=(int)fac[i++].dl.l[LL];
	int r,g,b,alpha;
	getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
	switch (mode) {
		case BITMAP_LINE:
			[gconsole bitmapLine:sx sy:sy ex:ex ey:ey r:r g:g b:b alpha:alpha];
			break;
		case BITMAP_BOX:
			[gconsole bitmapBox :sx sy:sy ex:ex ey:ey r:r g:g b:b alpha:alpha];
			break;
		case BITMAP_FILL:
			[gconsole bitmapFill:sx sy:sy ex:ex ey:ey r:r g:g b:b alpha:alpha];
			break;
	}
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// void bitmapLine(sx;int,sy;int,ex;int,ey;int,r;int[,g;int,b;int[,alpha;int]])
static RET_FUNC _F_bitmapLine(SWord numFAC,FAC fac[])
{
	printFunc();
	return (bitmapLineBoxFill(numFAC,fac,BITMAP_LINE));
}

static RET_FUNC _F_bitmapBox(SWord numFAC,FAC fac[])
// void bitmapBox(sx;int,sy;int,ex;int,ey;int,r;int[,g;int,b;int[,alpha;int]])
{
	printFunc();
	return (bitmapLineBoxFill(numFAC,fac,BITMAP_BOX));
}

// void bitmapFill(sx;int,sy;int,ex;int,ey;int,r;int[,g;int,b;int[,alpha;int]])
static RET_FUNC _F_bitmapFill(SWord numFAC,FAC fac[])
{
	printFunc();
	return (bitmapLineBoxFill(numFAC,fac,BITMAP_FILL));
}

// void bitmapCircle(x;int,y;int,rr;int;int,r;int[,g;int,b;int[,alpha;int]])
RET_FUNC _F_bitmapCircle(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	int x =(int)fac[i++].dl.l[LL];
	int y =(int)fac[i++].dl.l[LL];
	int rr=(int)fac[i++].dl.l[LL];
	int r,g,b,alpha;
	getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
	[gconsole bitmapCircle:x y:y rr:rr r:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// void bitmapPaint(x;int,y;int,r;int[,g;int,b;int[,alpha;int]])
RET_FUNC _F_bitmapPaint(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	int x =(int)fac[i++].dl.l[LL];
	int y =(int)fac[i++].dl.l[LL];
	int r,g,b,alpha;
	getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
	[gconsole bitmapPaint:x y:y r:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_bitmapGetSize(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int sx=(int)fac[i++].dl.l[LL];
	int sy=(int)fac[i++].dl.l[LL];
	int ex=(int)fac[i++].dl.l[LL];
	int ey=(int)fac[i++].dl.l[LL];
	//
	fac[0].dl.l[LL]=calcBitmapBoxArea(sx,sy,ex,ey)/SZ_INT; // BASICレベルではint配列しか認めてないので、バイト数ではなく要素数で返す
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_bitmapGet(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int sx=(int)fac[i++].dl.l[LL];
	int sy=(int)fac[i++].dl.l[LL];
	int ex=(int)fac[i++].dl.l[LL];
	int ey=(int)fac[i++].dl.l[LL];
	//
	SWord size1;
	uwYouso youso;
	UByte *bp=(UByte *)getDim1FromFAC(fac,i,&size1,&youso);
	if (bp==NULL) { // 1次元でない
		return (RET_FUNC_ERR);
	}
	// 必要バッファーサイズを計算する
	SLong cnt=calcBitmapBoxArea(sx,sy,ex,ey);
//	printf("sx,sy=%d,%d/ex,ey=%d,%d:",sx,sy,ex,ey);
	printf("必要バイト数=%d\n",(int)cnt);
	printf("要素数=%d,1要素サイズ=%d,要素バイト数=%d\n",youso,size1,youso*size1);
	if (youso*size1<cnt) {
		setExternalFuncErrmes("配列の要素数が足りません","Array's elements are not enough.");
		return (RET_FUNC_ERR);
	}
	//
	[gconsole bitmapGet:sx sy:sy ex:ex ey:ey buff:bp];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_bitmapPut(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int sx=(int)fac[i++].dl.l[LL];
	int sy=(int)fac[i++].dl.l[LL];
	int ex=(int)fac[i++].dl.l[LL];
	int ey=(int)fac[i++].dl.l[LL];
	//
	SWord size1;
	uwYouso youso;
	UByte *bp=(UByte *)getDim1FromFAC(fac,i,&size1,&youso);
	if (bp==NULL) { // 1次元でない
		return (RET_FUNC_ERR);
	}
	// 必要バッファーサイズを計算する
	SLong cnt=calcBitmapBoxArea(sx,sy,ex,ey);
//	printf("sx,sy=%d,%d/ex,ey=%d,%d:",sx,sy,ex,ey);
	printf("必要バイト数=%d\n",(int)cnt);
	printf("要素数=%d,1要素サイズ=%d,要素バイト数=%d\n",youso,size1,youso*size1);
	if (youso*size1<cnt) {
		setExternalFuncErrmes("配列の要素数が足りません","Array's elements are not enough.");
		return (RET_FUNC_ERR);
	}
	//
	[gconsole bitmapPut:sx sy:sy ex:ex ey:ey buff:bp];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

void _F_bitmapImgLoadSub(int sx,int sy,int wx,int wy)
{
	@autoreleasepool {
		[gconsole bitmapImgLoad:sx sy:sy wx:wx wy:wy ftile:NO];
	}
}

static RET_FUNC _F_bitmapImgLoad(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sx=fac[i].dl.d;
	}
	i++;
	CGFloat sy=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sy=fac[i].dl.d;
	}
	i++;
	CGFloat wx=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wx=fac[i].dl.d;
	}
	i++;
	CGFloat wy=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wy=fac[i].dl.d;
	}
	i++;
	//
	_F_bitmapImgLoadSub(sx,sy,wx,wy);

	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_bitmapTileImgLoad(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sx=fac[i].dl.d;
	}
	i++;
	CGFloat sy=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		sy=fac[i].dl.d;
	}
	i++;
	CGFloat wx=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wx=fac[i].dl.d;
	}
	i++;
	CGFloat wy=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		wy=fac[i].dl.d;
	}
	i++;
	//
	@autoreleasepool {
		[gconsole bitmapImgLoad:sx sy:sy wx:wx wy:wy ftile:YES];
	}
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//-----------------------------------------------------------------------------
// v2.5

static RET_FUNC _F_bitmapEllipse(SWord numFAC,FAC fac[])
// void bitmapEllipse(x;int,y;int,rr;int;int,hv;int,r;int[,g;int,b;int[,alpha;int]])
{
	printFunc();
	//
	int i=0;
	int x =(int)fac[i++].dl.l[LL];
	int y =(int)fac[i++].dl.l[LL];
	int rr=(int)fac[i++].dl.l[LL];
	int hv=(int)fac[i++].dl.l[LL];
	int r,g,b,alpha;
	getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
	[gconsole bitmapEllipse:x y:y rr:rr hv:hv r:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_bitmapEllipse2(SWord numFAC,FAC fac[])
// void bitmapEllipse2(x;int,y;int,aa;int;int,bb;int,r;int[,g;int,b;int[,alpha;int]])
{
	printFunc();
	//
	int i=0;
	int x =(int)fac[i++].dl.l[LL];
	int y =(int)fac[i++].dl.l[LL];
	int aa=(int)fac[i++].dl.l[LL];
	int bb=(int)fac[i++].dl.l[LL];
	int r,g,b,alpha;
	getRGBColorFromFac(fac,i,&r,&g,&b,&alpha); // v2.2
	[gconsole bitmapEllipse:x y:y aa:aa bb:bb r:r g:g b:b alpha:alpha];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//-----------------------------------------------------------------------------

static RET_FUNC _F_picLoader(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	UByte *fname=fac[i++].dl.bp[LL];
	BOOL fdirect=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fdirect=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;

	BOOL fNoBitmapClose=NO; // YES=bitmapCloseを実行しない , NO=実行する
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fNoBitmapClose=basic2cYESNO(fac[i].dl.l[LL]);
	}
	//
	@autoreleasepool {
		fac[0].dl.l[LL]=[gconsole picLoader:@(bstrWithUTF8(fname)) sx:sx sy:sy fbitmapOpen:YES fdirect:fdirect fNoBitmapClose:fNoBitmapClose]; // UTF8化
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_picHeader(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	BOOL fsquare;
	int	mode,bitLength,wx,wy;
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	//
	UByte *comment=NULL;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		comment=fac[i].dl.bp[LL];
	}
	i++;
	//
	@autoreleasepool {
		fac[0].dl.l[LL]=[gconsole getPicHeader:@(bstrWithUTF8(fname))	// UTF8化
										 fsquare:&fsquare mode:&mode bitLength:&bitLength wx:&wx wy:&wy
										 comment:comment maxCommentLength:operationStatus.sz_str];
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=c2basicYESNO(fsquare);
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=mode;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=bitLength;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wy;
		}
		i++;
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_cutLoader(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	UByte *fname=fac[i++].dl.bp[LL];
	BOOL fdirect=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fdirect=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;

	BOOL fNoBitmapClose=NO; // YES=bitmapCloseを実行しない , NO=実行する
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fNoBitmapClose=basic2cYESNO(fac[i].dl.l[LL]);
	}
	//
	@autoreleasepool {
		fac[0].dl.l[LL]=[gconsole cutLoader:@(bstrWithUTF8(fname)) sx:sx sy:sy fbitmapOpen:YES fdirect:fdirect fNoBitmapClose:fNoBitmapClose]; // UTF8化
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_cutHeader(SWord numFAC,FAC fac[])
{
	printFunc();
	
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	//
	int wx,wy;
	
	@autoreleasepool {
		fac[0].dl.l[LL]=getCutHeader(@(bstrWithUTF8(fname)),&wx,&wy);	 // UTF8化
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wy;
		}
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}


static RET_FUNC _F_magLoader(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat sx=fac[i++].dl.d;
	CGFloat sy=fac[i++].dl.d;
	UByte *fname=fac[i++].dl.bp[LL];
	BOOL fdirect=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fdirect=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;
	BOOL fNoBitmapClose=NO; // YES=bitmapCloseを実行しない , NO=実行する
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		fNoBitmapClose=basic2cYESNO(fac[i].dl.l[LL]);
	}
	//
	@autoreleasepool {
		fac[0].dl.l[LL]=[gconsole magLoader:@(bstrWithUTF8(fname)) sx:sx sy:sy fbitmapOpen:YES fdirect:fdirect fNoBitmapClose:fNoBitmapClose]; // UTF8化
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_magHeader(SWord numFAC,FAC fac[])
{
	printFunc();
	
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	nslog(@"fname=%s",fname);
	//
	UByte *comment=NULL;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		comment=fac[i].dl.bp[LL];
	}
	i++;
	//
	int wx,wy,mode;
	UByte machine[MAG_LEN_MACHINE+1];
	UByte username[MAG_LEN_USERNAME+1];
	
	@autoreleasepool {
		fac[0].dl.l[LL]=getMagHeader(@(bstrWithUTF8(fname))		 // UTF8化
										,&wx,&wy,&mode
									   	,machine,username
									   	,comment,operationStatus.sz_str);
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wy;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=mode;
		}
		i++;
		UByte *bp;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			bp=fac[i].dl.bp[LL];
			strcpy((char*)bp,(char*)machine);
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			bp=fac[i].dl.bp[LL];
			strcpy((char*)bp,(char*)username);
		}
		i++;
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_jpegHeader(SWord numFAC,FAC fac[])
{
	printFunc();
	
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	nslog(@"fname=%s",fname);
	//
	@autoreleasepool {
		int wx,wy;
		fac[0].dl.l[LL]=getJpegHeader(@(bstrWithUTF8(fname)),&wx,&wy);	 // UTF8化
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wy;
		}
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_pngHeader(SWord numFAC,FAC fac[])
{
	printFunc();
	
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	nslog(@"fname=%s",fname);
	//
	@autoreleasepool {
		SLong wx,wy;
		int bitLength;
		fac[0].dl.l[LL]=getPngHeader(@(bstrWithUTF8(fname)),&wx,&wy,&bitLength);	 // UTF8化
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=(int)wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=(int)wy;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=(int)bitLength;
		}
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_gifHeader(SWord numFAC,FAC fac[])
{
	printFunc();
	
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	nslog(@"fname=%s",fname);
	//
	@autoreleasepool {
		int wx,wy;
		fac[0].dl.l[LL]=getGifHeader(@(bstrWithUTF8(fname)),&wx,&wy);	 // UTF8化
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=wy;
		}
		i++;
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_bmpHeader(SWord numFAC,FAC fac[])
// v2.2
{
	printFunc();
	
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	nslog(@"fname=%s",fname);
	//
	@autoreleasepool {
		SLong wx,wy;
		int bitLength;
		fac[0].dl.l[LL]=getBmpHeader(@(bstrWithUTF8(fname)),&wx,&wy,&bitLength);	 // UTF8化
		//
		int *ip;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=(int)wx;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=(int)wy;
		}
		i++;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ip=fac[i].dl.ip[LL];
			*ip=bitLength;
		}
	}
	//
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------
// bitmap関数
//---------------------------------------------------------------------------------------------

static RET_FUNC _F_bitmapImageFile(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	UByte *fname=fac[i++].dl.bp[LL];
	if (*fname==0) {
		nslog(@"ファイル名がNULLである");
		fac[0].dl.l[LL]=PIC_FILENOTFOUND; // ファイルが見つかるはずがない
	} else {
		CGFloat sx=0;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			sx=fac[i].dl.d;
		}
		i++;
		//
		CGFloat sy=0;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			sy=fac[i].dl.d;
		}
		i++;
		//
		CGFloat ex=-1;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ex=fac[i].dl.d;
		}
		i++;
		//
		CGFloat ey=-1;
		if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
			ey=fac[i].dl.d;
		}
		i++;
		//
		@autoreleasepool {
			fac[0].dl.l[LL]=[gconsole bitmapImageFile:@(bstrWithUTF8(fname)) sx:sx sy:sy ex:ex ey:ey]; // UTF8化
		}
	}
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}


void _F_bitmapPatternSub(int sx,int sy,int wx,int wy,UByte *bp)
{
	[gconsole bitmapPattern:sx sy:sy wx:wx wy:wy ptrn:bp];
}

static RET_FUNC _F_bitmapPattern(SWord numFAC,FAC fac[])
{
	printFunc();
	int i=0;
	int sx=(int)fac[i++].dl.l[LL];
	int sy=(int)fac[i++].dl.l[LL];
	int wx=(int)fac[i++].dl.l[LL];
	int wy=(int)fac[i++].dl.l[LL];
	//
	SWord size1;
	uwYouso youso;
	UByte *bp=(UByte *)getDim1FromFAC(fac,i,&size1,&youso);
	if (bp==NULL) { // 1次元でない
		return (RET_FUNC_ERR);
	}
	// 必要バッファーサイズを計算する
	SLong cnt=calcBitmapBoxArea(sx,sy,sx+wx-1,sy+wy-1);
	//	printf("sx,sy=%d,%d/wx,wy=%d,%d:",sx,sy,wx,wy);
	printf("必要バイト数=%d\n",(int)cnt);
	printf("要素数=%d,1要素サイズ=%d,要素バイト数=%d\n",youso,size1,youso*size1);
	if (youso*size1<cnt) {
		setExternalFuncErrmes("配列の要素数が足りません","Array's elements are not enough.");
		return (RET_FUNC_ERR);
	}
	//
	_F_bitmapPatternSub(sx,sy,wx,wy,bp);
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

static RET_FUNC _F_getBitmapSize(SWord numFAC,FAC fac[])
{
	printFunc();

	int wx;
	int *ip=&wx; // 省略時の時のため
	if (fac[0].facType!=VOID_PARAM) { // 引数が省略されていない時
		ip=fac[0].dl.ip[LL];
	}
	*ip=gconsole.bitmapWidth;
	//
	fac[0].dl.l[LL]=gconsole.bitmapHeight;
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------
// v2.1
//---------------------------------------------------------------------------------------------

static RET_FUNC _F_gScroll(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	int mode=(int)fac[i++].dl.l[LL];
	int cnt=1;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		cnt=(int)fac[i].dl.l[LL];
		if (cnt<0) cnt=1;
	}

	for (i=0;i<cnt;i++) {
		[gconsole grScroll:mode fContext:YES];
	}
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------

// アニメーションパラメーター設定(簡易)
static RET_FUNC _F_gAnimationParameter(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat tx=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		tx=fac[i].dl.d;
	}
	i++;
	CGFloat ty=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		ty=fac[i].dl.d;
	}
	i++;
	CGFloat scaleX=1.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		scaleX	=fac[i].dl.d;
	}
	i++;
	CGFloat scaleY=1.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		scaleY	=fac[i].dl.d;
	}
	i++;
	CGFloat angle=0;
	BOOL fangle=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		angle	=fac[i].dl.d;
		fangle	=YES;
	}
	i++;
	int axis=(fangle? AXIS_X:AXIS_NONE);
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		axis=(int)fac[i].dl.l[LL];
	}
	i++;
	// 水平移動		tx,ty,1.0,1.0,0,AXIS_NONE
	// 拡大縮小		0,0,scaleX,scaleY,0,AXIS_NONE
	// 回転			0,0,1.0,1.0,angle,axis
	[gconsole setAnimeParameter2:tx ty:ty scaleX:scaleX scaleY:scaleY angle:angle axis:axis];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// アニメーションパラメーター設定(詳細)
static RET_FUNC _F_gAnimationMatrix(SWord numFAC,FAC fac[])
{
	printFunc();
	// こう設定される。鏡像変換は自動的に行われるので考えなくていい
	// m11,m12,m13,0
	// m21,m22,m23,0
	// m31,m32,m33,0
	//  tx, ty,  0,1
	CATransform3D matrix=CATransform3DIdentity; // まずはデフォルト設定
	int i=0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m11=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m12=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m13=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m21=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m22=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m23=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m31=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m32=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m33=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m41=fac[i].dl.d;
	}
	i++;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		matrix.m42=fac[i].dl.d;
	}
	i++;
	[gconsole setAnimeParameter3:matrix];
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

// layerへのアニメーション設定とUIViewアニメーションは掛け合わせることができる

// アニメーション実行
static RET_FUNC _F_gAnimation(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	int anime=(int)fac[i++].dl.l[LL];	// アニメーションモード
	
	CFTimeInterval 	duration=0; // 省略はANIMATION_STOP時のみ
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		duration=fac[i].dl.d;
	}
	if (duration<0) duration=-duration;
	if (duration==0) anime=ANIMATION_STOP;
	i++;
	
	float repeatCount=1;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		repeatCount=(float)fac[i].dl.d;
	}
	if (repeatCount<1) repeatCount=1;
	i++;
	
	BOOL autoreverses=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		autoreverses=basic2cYESNO(fac[i].dl.l[LL]);
	}
	i++;
	
	int animationCurve=UIViewAnimationCurveEaseInOut;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		animationCurve=(int)fac[i].dl.l[LL];
	}
	if (animationCurve<UIViewAnimationCurveEaseInOut) animationCurve=UIViewAnimationCurveEaseInOut;
	if (animationCurve>UIViewAnimationCurveLinear) 	  animationCurve=UIViewAnimationCurveLinear;
	//
	[gconsole setAnimeParameter1:duration repeatCount:repeatCount autoreverses:autoreverses animationCurve:animationCurve];
	gconsole.fanime=anime; // KVO発生
	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------

// 変形設定
RET_FUNC _F_gTransform(SWord numFAC,FAC fac[])
{
	printFunc();
	//
	int i=0;
	CGFloat tx=0;
	BOOL ftx=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		 tx=fac[i].dl.d;
		ftx=YES;
	}
	i++;
	CGFloat ty=0;
	BOOL fty=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		 ty=fac[i].dl.d;
		fty=YES;
	}
	i++;
	CGFloat scaleX=1.0;
	BOOL fscaleX=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		scaleX	=fac[i].dl.d;
		fscaleX	=YES;
	}
	i++;
	CGFloat scaleY=1.0;
	BOOL fscaleY=NO;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		scaleY	=fac[i].dl.d;
		fscaleY	=YES;
	}
	i++;
	
	int activePage=-1;
	int nowAPage;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		activePage=fac[i].dl.l[LL];

		// 以下は_F_apage()の処理参照のこと
		// 現在のページ番号を保存
		nowAPage=runView.nowApage;
		// アクティブページを設定
		gconsole=[runView getConsole:activePage];
	}
	i++;
	
	BOOL fangle=NO;
	CGFloat angle=0.0;
	if (fac[i].facType!=VOID_PARAM) { // 引数が省略されていない時
		angle	=fac[i].dl.d;
		fangle	=YES;
		nslog(@"angle=%f",angle);
	}
	i++;
	
	if (!ftx && !fty && !fscaleX && !fscaleY && !fangle) {
		// apage以外全パラメーター省略時はキャンセル
		[gconsole transformCancel];
	} else {
		// 回転はxy平面のみ
		[gconsole transform:tx ty:ty scaleX:scaleX scaleY:scaleY angle:angle];
	}
	
	if (activePage!=-1) {
		// ページを復帰
		gconsole=[runView getConsole:nowAPage];
		runView.nowApage=nowAPage;
	}

	//
	fac[0].dl.l[LL]=0; // 念のため
	fac[0].facType=FACTYPE_RETURN;
	return (RET_FUNC_OK); // OK
}

//---------------------------------------------------------------------------------------------
// インフォメーションテーブル (5.2.1章)
//---------------------------------------------------------------------------------------------

// 関数名テーブル(トークンテーブル)
static const char *iOSGTokens[]={
	"getScreenSize",		// v3.20
	"pset",
	"line",
	"box",
	"fill",
	"circle",
	"ellipse",			// v3.00
	"gBackgroundAlpha",
	"gBackgroundColor",	// v2.2
	"lineWidth",
	"lineCap",
	"lineJoin",
	"blend",
	"gBlend",	// v2.1
	"splitRGB",
	"rgb",
	"hsv",
	"gcolor",
	"gColor",		// v2.1
	"wipe",
	"gfileStatus",
	"gFileStatus",	// v2.2
	"pngSave",
	"jpegSave",
	"imageCopyToAlbum",
	"imgLoad",
	"tileImgLoad",
	"symbol",
	"symbolt",	// v2.1
	"lines",
	"gborder",
	"gBorder",	// v2.1
	//
	"apage",
	"vpage",
	"vpriority",
	"screenRotate",
	"getOrientation",
	"gAntiAlias",
	// bitmap
	"bitmapOpen",
	"bitmapClose",
	"bitmapWipe",
	"bitmapPset",
	"bitmapPoint",
	"bitmapLine",
	"bitmapBox",
	"bitmapFill",
	"bitmapCircle",
	"bitmapPaint",
	"bitmapImgLoad",
	"bitmapTileImgLoad",
	"bitmapGetSize",
	"bitmapGet",
	"bitmapPut",
	"bitmapPattern",// v2.2
	"getBitmapSize",// v2.2
	"picLoader",
	"cutLoader",
	//
	"pic_load",
	"picHeader",	// v2.2
	"cut_load",
	"cutHeader",	// v2.2
	"magLoader",	// v2.2
	"magHeader",	// v2.2
	"jpegHeader",	// v2.2
	"pngHeader",	// v2.2
	"gifHeader",	// v2.2
	"bmpHeader",	// v2.2
	"bitmapImageFile",
	// v2.1
	"gScroll",
	"gAnimationParameter",
	"gAnimationMatrix",
	"gAnimation",
	"gTransform",
	// v2.5
	"bitmapEllipse",
	"bitmapEllipse2",
	// バージョン
	"versionXBiOSGraphic$",
	// end of table
	NULL,
};

// 実行アドレステーブル
static FUNC_EXEC iOSGFuncExec[]={
	// Cの標準関数名と重複させないよう_F_を付ける
	{_F_getScreenSize},	// 3.20
	{_F_pset	},
	{_F_line	},
	{_F_box		},
	{_F_fill	},
	{_F_circle	},
	{_F_ellipse	},
	{_F_gBackgroundAlpha	},
	{_F_gBackgroundColor	},	// v2.2
	{_F_lineWidth	},
	{_F_lineCap		},
	{_F_lineJoin	},
	{_F_blend	},
	{_F_blend	},
	{_F_splitRGB},
	{_F_rgb		},
	{_F_hsv		},
	{_F_gColor	},
	{_F_gColor	},
	{_F_wipe	},
	{_F_gfileStatus},
	{_F_gfileStatus},	// v2.2
	{_F_pngSave	},
	{_F_jpegSave},
	{_F_imageCopyToAlbum},
	{_F_imgLoad	},
	{_F_tileImgLoad	},
	{_F_symbol	},
	{_F_symbolt	}, // v2.1
	{_F_lines	},
	{_F_gborder	},
	{_F_gborder	},
	//
	{_F_apage},
	{_F_vpage},
	{_F_vpriority},
	{_F_screenRotate},
	{_F_getOrientation},
	{_F_gAntiAlias},
	// bitmap
	{_F_bitmapOpen},
	{_F_bitmapClose},
	{_F_bitmapWipe},
	{_F_bitmapPset},
	{_F_bitmapPoint},
	{_F_bitmapLine},
	{_F_bitmapBox},
	{_F_bitmapFill},
	{_F_bitmapCircle},
	{_F_bitmapPaint},
	{_F_bitmapImgLoad},
	{_F_bitmapTileImgLoad},
	{_F_bitmapGetSize},
	{_F_bitmapGet},
	{_F_bitmapPut},
	{_F_bitmapPattern},	// v2.2
	{_F_getBitmapSize},	// v2.2
	{_F_picLoader},
	{_F_cutLoader},
	//
	{_F_picLoader},
	{_F_picHeader},	// v2.2
	{_F_cutLoader},
	{_F_cutHeader},	// v2.2
	{_F_magLoader},	// v2.2
	{_F_magHeader}, // v2.2
	{_F_jpegHeader},// v2.2
	{_F_pngHeader},	// v2.2
	{_F_gifHeader},	// v2.2
	{_F_bmpHeader},	// v2.2
	{_F_bitmapImageFile},
	// v2.1
	{_F_gScroll},
	{_F_gAnimationParameter},
	{_F_gAnimationMatrix},
	{_F_gAnimation},
	{_F_gTransform},
	// v2.5
	{_F_bitmapEllipse},
	{_F_bitmapEllipse2},
	// バージョン
	{_F_version},
	// end of table
	{NULL},
};

//------------------------------
// パラメーターテーブル
// (1)種類別定義
// 1関数の引数は最大MAX_PARAM個

static const uwPARAMTYPE p_pset[]={
	FLOAT_VAL,
	FLOAT_VAL,
	VOID_RET,
};

static const uwPARAMTYPE p_line[]={
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_box[]={
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_fill[]={
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	VOID_RET,
};

static const uwPARAMTYPE p_circle[]={
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_OMT,
	FLOAT_OMT,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_ellipse[]={	// v3.00
	FLOAT_VAL,	// cx
	FLOAT_VAL,	// cy
	FLOAT_VAL,	// r
	FLOAT_OMT,	// hv
	INT_OMT,	// ffill
	INT_OMT,	// style
	VOID_RET,
};

static const uwPARAMTYPE p_gBackgroundAlpha[]={
	FLOAT_VAL,
	VOID_RET,
};
#define	p_lineWidth	p_gBackgroundAlpha

static const uwPARAMTYPE p_gBackgroundColor[]={ // v2.2
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_lineCap[]={
	INT_VAL,
	VOID_RET,
};
#define p_lineJoin	p_lineCap
#define p_blend		p_lineCap

static const uwPARAMTYPE p_gcolor[]={
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_rgb[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_OMT,
	INT_RET,
};
#define p_hsv	p_rgb

static const uwPARAMTYPE p_splitRGB[]={
	INT_VAL,
	INT_VP,
	INT_VP,
	INT_VP,
	INT_VP,
	VOID_RET,
};

static const uwPARAMTYPE p_wipe[]={
	VOID_RET,
};

static const uwPARAMTYPE p_gfileStatus[]={
	INT_RET,
};

static const uwPARAMTYPE p_pngSave[]={
	STR_VAL,
	INT_RET,
};
#define p_imageCopyToAlbum	p_pngSave

static const uwPARAMTYPE p_jpegSave[]={
	STR_VAL,
	FLOAT_VAL,
	INT_RET,
};

static const uwPARAMTYPE p_imgLoad[]={
	FLOAT_OMT,	// v3.00で省略可能化
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	STR_VAL,
	INT_RET,
};

static const uwPARAMTYPE p_tileImgLoad[]={
	FLOAT_OMT,	// v3.00で省略可能化
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	STR_VAL,
	INT_RET,
};

static const uwPARAMTYPE p_symbol[]={
	FLOAT_VAL,
	FLOAT_VAL,
	STR_VAL,
	STR_VAL,
	FLOAT_VAL,
	FLOAT_VP|PARAM_OMIT, // v2.1
	FLOAT_RET, // v2.1
};

static const uwPARAMTYPE p_symbolt[]={ // v2.1
	FLOAT_VAL,
	FLOAT_VAL,
	STR_VAL,
	STR_VAL,
	FLOAT_VAL,
	VOID_RET,
};

static const uwPARAMTYPE p_lines[]={
	ARRAY1_FLOAT,
	INT_VAL,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_apage[]={
	INT_VAL,
	INT_RET,
};

static const uwPARAMTYPE p_vpage[]={
	INT_VAL,	// page
	INT_OMT,	// onoff;現在未使用
	INT_RET,
};

static const uwPARAMTYPE p_screenRotate[]={
	INT_VAL,
	VOID_RET,
};

static const uwPARAMTYPE p_vpriority[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_OMT,
	INT_RET,
};

static const uwPARAMTYPE p_getOrientation[]={
	INT_RET,
};

static const uwPARAMTYPE p_gborder[]={
	FLOAT_VAL,
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_bitmapOpen[]={
	INT_OMT,
	INT_OMT,
	INT_OMT,
	INT_RET,
};

static const uwPARAMTYPE p_bitmapClose[]={
	VOID_RET,
};
#define p_bitmapWipe	p_bitmapClose

static const uwPARAMTYPE p_bitmapPset[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_bitmapPoint[]={
	INT_VAL,
	INT_VAL,
	INT_VP|PARAM_OMIT,	// v2.5
	INT_VP|PARAM_OMIT,	// v2.5
	INT_VP|PARAM_OMIT,	// v2.5
	INT_VP|PARAM_OMIT,	// v2.5
	INT_RET,
};

static const uwPARAMTYPE p_bitmapLine[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};
#define p_bitmapBox		p_bitmapLine
#define p_bitmapFill	p_bitmapLine

static const uwPARAMTYPE p_bitmapCircle[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_bitmapEllipse[]={
	INT_VAL,	// x
	INT_VAL,	// y
	INT_VAL,	// rr/aa
	INT_VAL,	// hv/bb
	INT_VAL,	// r
	INT_OMT,	// g
	INT_OMT,	// b
	INT_OMT,	// alpha
	VOID_RET,
};
#define p_bitmapEllipse2	p_bitmapEllipse

static const uwPARAMTYPE p_bitmapPaint[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_bitmapGetSize[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_RET,
};

static const uwPARAMTYPE p_bitmapGet[]={
	INT_VAL,
	INT_VAL,
	INT_VAL,
	INT_VAL,
	ARRAY1_INT,
	VOID_RET,
};
#define p_bitmapPut		p_bitmapGet
#define p_bitmapPattern	p_bitmapGet	// v2.2

static const uwPARAMTYPE p_getBitmapSize[]={
	INT_VP|PARAM_OMIT,	// v3.20
	INT_RET,
};
#define p_getScreenSize	p_getBitmapSize	// v3.20

static const uwPARAMTYPE p_bitmapImgLoad[]={
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_bitmapTileImgLoad[]={
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	FLOAT_VAL,
	VOID_RET,
};

static const uwPARAMTYPE p_picLoader[]={
	FLOAT_VAL,
	FLOAT_VAL,
	STR_VAL,
	INT_OMT,
	INT_OMT,
	INT_RET,
};
#define p_cutLoader	p_picLoader
#define p_magLoader	p_picLoader

static const uwPARAMTYPE p_picHeader[]={	// v2.2
	STR_VAL,			// fname
	STR_VP|PARAM_OMIT,	// comment	STR_VALでも同じ
	INT_VP|PARAM_OMIT,	// fsquare
	INT_VP|PARAM_OMIT,	// mode
	INT_VP|PARAM_OMIT,	// bitLength
	INT_VP|PARAM_OMIT,	// wx
	INT_VP|PARAM_OMIT,	// wy
	INT_RET,
};

static const uwPARAMTYPE p_cutHeader[]={	// v2.2
	STR_VAL,			// fname
	INT_VP|PARAM_OMIT,	// wx
	INT_VP|PARAM_OMIT,	// wy
	INT_RET,
};

static const uwPARAMTYPE p_magHeader[]={	// v2.2
	STR_VAL,			// fname
	STR_VP|PARAM_OMIT,	// comment	STR_VALでも同じ
	INT_VP|PARAM_OMIT,	// wx
	INT_VP|PARAM_OMIT,	// wy
	INT_VP|PARAM_OMIT,	// mode
	STR_VP|PARAM_OMIT,	// machine	STR_VALでも同じ
	STR_VP|PARAM_OMIT,	// username	STR_VALでも同じ
	INT_RET,
};

static const uwPARAMTYPE p_jpegHeader[]={	// v2.2
	STR_VAL,			// fname
	INT_VP|PARAM_OMIT,	// wx
	INT_VP|PARAM_OMIT,	// wy
	INT_RET,
};

static const uwPARAMTYPE p_pngHeader[]={	// v2.2
	STR_VAL,			// fname
	INT_VP|PARAM_OMIT,	// wx
	INT_VP|PARAM_OMIT,	// wy
	INT_VP|PARAM_OMIT,	// bitLength
	INT_RET,
};
#define p_bmpHeader	p_pngHeader

static const uwPARAMTYPE p_gifHeader[]={	// v2.2
	STR_VAL,			// fname
	INT_VP|PARAM_OMIT,	// wx
	INT_VP|PARAM_OMIT,	// wy
	INT_RET,
};

static const uwPARAMTYPE p_bitmapImageFile[]={
	STR_VAL,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	INT_RET,
};

static const uwPARAMTYPE p_gScroll[]={
	INT_VAL,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_gAnimationParameter[]={
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_gAnimationMatrix[]={
	FLOAT_OMT,	FLOAT_OMT,	FLOAT_OMT,
	FLOAT_OMT,	FLOAT_OMT,	FLOAT_OMT,
	FLOAT_OMT,	FLOAT_OMT,	FLOAT_OMT,
	FLOAT_OMT,	FLOAT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_gAnimation[]={
	INT_VAL,
	FLOAT_OMT,
	FLOAT_OMT,
	INT_OMT,
	INT_OMT,
	VOID_RET,
};

static const uwPARAMTYPE p_gTransform[]={
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,
	FLOAT_OMT,	// ページ指定
	FLOAT_OMT,	// 回転
	VOID_RET,
};

static const uwPARAMTYPE p_gAntiAlias[]={
	INT_VAL,
	VOID_RET,
};

static const uwPARAMTYPE p_version[]={
	STR_RET,
};

//------------------------------
// パラメーターテーブル
// (2)関数別定義

static
const
uwPARAMTYPE *iOSGParams[]={
	p_getScreenSize,	// v3.20
	p_pset,
	p_line,
	p_box,
	p_fill,
	p_circle,
	p_ellipse,		// v3.00
	p_gBackgroundAlpha,
	p_gBackgroundColor,
	p_lineWidth,
	p_lineCap,
	p_lineJoin,
	p_blend,
	p_blend,
	p_splitRGB,
	p_rgb,
	p_hsv,
	p_gcolor,
	p_gcolor,
	p_wipe,
	p_gfileStatus,
	p_gfileStatus,	// v2.2
	p_pngSave,
	p_jpegSave,
	p_imageCopyToAlbum,
	p_imgLoad,
	p_tileImgLoad,
	p_symbol,
	p_symbolt,	// v2.1
	p_lines,
	p_gborder,
	p_gborder,
	//
	p_apage,
	p_vpage,
	p_vpriority,
	p_screenRotate,
	p_getOrientation,
	p_gAntiAlias,
	// bitmap
	p_bitmapOpen,
	p_bitmapClose,
	p_bitmapWipe,
	p_bitmapPset,
	p_bitmapPoint,
	p_bitmapLine,
	p_bitmapBox,
	p_bitmapFill,
	p_bitmapCircle,
	p_bitmapPaint,
	p_bitmapImgLoad,
	p_bitmapTileImgLoad,
	p_bitmapGetSize,
	p_bitmapGet,
	p_bitmapPut,
	p_bitmapPattern,	// v2.2
	p_getBitmapSize,	// v2.2
	p_picLoader,
	p_cutLoader,
	//
	p_picLoader,	// pic_load()
	p_picHeader,	// v2.2
	p_cutLoader,	// cut_load()
	p_cutHeader,	// v2.2
	p_magLoader,	// v2.2
	p_magHeader,	// v2.2
	p_jpegHeader,	// v2.2
	p_pngHeader,	// v2.2
	p_gifHeader,	// v2.2
	p_bmpHeader,	// v2.2
	p_bitmapImageFile,
	// v2.1
	p_gScroll,
	p_gAnimationParameter,
	p_gAnimationMatrix,
	p_gAnimation,
	p_gTransform,
	// v2.5
	p_bitmapEllipse,
	p_bitmapEllipse2,
	// バージョン
	p_version	,
	// end of table
	NULL,
};

//-------------

// この中の関数の初期化処理
static void _Frun(void)
{
	printFunc();
	runView=xb_getRunView();
	//
#if 0	// iOSt側に移動
	[runView disableRotate:YES]; // RUN直後は画面回転禁止(RUN方向の画面で固定)
	[runView vpriority:SCONSOLE p1:TCONSOLE p2:GCONSOLE0 p3:GCONSOLE1 p4:GCONSOLE2 p5:GCONSOLE3];
	[runView vpage:SCONSOLE onoff:NO];
	[runView vpage:TCONSOLE onoff:YES];
#endif
	for (int i=GCONSOLE0;i<=GCONSOLE3;i++) {
		[runView vpage:i onoff:NO]; // グラフィックはとりあえず全ページOFF
		gconsole=[runView getConsole:i];
		[gconsole start]; // RUN時画面はここに来る直前に固定されるので、ここで呼び出す必要がある
		[gconsole wipe];
		[gconsole color:-THWHITE g:0 b:0 alpha:255];
		[gconsole lineCap:kCGLineCapSquare];
		[gconsole lineJoin:kCGLineJoinBevel];
		[gconsole lineWidth:1.0];
		[gconsole blend:kCGBlendModeNormal];
#if 0	// console側に移動
		[gconsole alpha:1.0];
		[gconsole border:0 r:0 g:0 b:0 alpha:0]; // ボーダーなし
#endif
	}
	// 初期のapageはGPAGE0にしておく
	gconsole=[runView getConsole:GCONSOLE0];
	runView.nowApage=GCONSOLE0;
}

// この中の関数の終了処理
static void _Fend(void)
{
	printFunc();
	[runView disableRotate:NO]; // 画面回転許可
	for (int i=GCONSOLE0;i<=GCONSOLE3;i++) {
		gconsole=[runView getConsole:i];
		[gconsole end];
	}
}

// インフォメーションテーブル
const
INFORMATION_TABLE	InfoIosGFuncs={
	#ifdef FUNC_DEBUG
	"iOS Graphics functions",
	#endif
	returnOnly,	// Finit〜Fexitが対
	_Frun,		// Frun〜Fendが対
	_Fend,		// Fend
	returnOnly,	// Fexit
	returnOnly,	// Fbreak
	NULL,		// FctrlD;未使用
	NULL,		// 予約1
	NULL,		// 予約2
	//
	iOSGTokens,
	iOSGParams,
	iOSGFuncExec
};

//---------------------------------------------------------------------------------------------
