module kyojintati4d.taskdemo;

private import SDL;

private import std.stream;

private import y4d;
private import y4d_aux.filesys;
private import y4d_aux.lineparser;
private import y4d_thread.gametask;
private import y4d_draw.transbltter;

private import kyojintati4d.val.kyojinconst;
private import kyojintati4d.val.y4dconst;
private import kyojintati4d.myapp;
private import kyojintati4d.gameinfo;

private import yamalib.hexpropagate;
private import yamalib.character;
private import yamalib.clock;
private import yamalib.headlinear;
private import yamalib.counter;
private import yamalib.log.log;
private import yamalib.draw.dropobject;
private import yamalib.draw.dizzytextdraw;
private import yamalib.draw.prmptcarsor;
private import yamalib.draw.flashintext;
private import yamalib.draw.scatteredtexture;
private import yamalib.draw.noisebltter;
private import yamalib.draw.screenframe;
private import yamalib.draw.texturelinenoise;
private import yamalib.draw.texturaltextdraw;
private import yamalib.draw.moveview;

/// デモシーン
/**
	D言語のテスト用につくったデモクラス
	yaneSDK4Dの使い方の練習
	デモは [Carnival!!(No Number：皐月)] disharmony ほかを参考
	BGMの一拍は 0.46..(21/45)sec で同期
*/
class TaskDemo : GameTaskBase, ProgressiveThread {
	
	/// タスク名を返却する
	/**
		このタスク名称を使って、コントローラ部でタスク判別を行う可能性があるので
		ユニークな名前で、実装しておくべきである
	*/	
	override char[] getTaskName() {
		with (kyojintati4d.val.kyojinconst) {
			return cast(char[]) KyojinConst.TASK_NAME[KyojinConst.Task.Task_Demo];
		}
	}
	
	/// 進捗率を返却する
	int getProgress() {
		return this.progress;
	}
	
	/// スレッドで処理したい動作を記述したデリゲードを返却
	int delegate() getDelegate() {
		return &onLoad;
	}
	
	/// 描画デリゲードを返却
	int delegate(Screen) getDrawDelegate() {
		return &taskLoading;
	}

	/// 移動の処理を行います
	override int onMove(Object o) {
		return 0;
	}

	/// 描画の処理を行います
	override int onDraw(Object o) {
		try {
			// オブジェクトをもらう
			info = cast(GameInfo)o;
			// クリア
			info.screen.setClearColor(0, 0, 0);
			info.screen.clear();
			
			switch( step ) {
	
			// 初期化
			case -2:
				// ↓でローダスレッド起動！
				onInit();
				return 0;
				
			case -1:
				// こいつはbreakしないでよい
				onInitAfter();
				nextStep();
	
			case 0:
				stepS01();
				break;
				
			// スタートタイトル
			case 1:
				step001();
				break;
	
			// 去人たちタイトルイン
			case 2:
				step002();
				break;
	
			// タイトルメモイン
			case 3:
				step003();
				break;
				
			// タイトルアウト
			case 4:
				step004();
				break;
			
			// 開閉	
			case 5:
				step005();
				break;
				
			// ロール
			case 6:
				step006();
				break;
			
			// 	キャラ紹介
			case 7:
				step108();
	//			step101();
				break;
			
			// ありすコード＆時計
			case 8:
				step107();
	//			step102();
				break;
				
			// 物語展開＋スロー
			case 9:
				step106();
	//			step103();
				break;
	
			// フラッシュ		
			case 10:
				step109();
	//			step104();
				break;
				
			// フラッシュインテキスト
			case 11:
				step105();
				break;
			
			// とみえたん立ち
			case 12:
				step104();
				break;
			
			// 翠子＋ありす
			case 13:
				step103();
				break;
			
			// 去人たちタイトル
			case 14:
				step110();
				break;
			
			// 開発スタッフ
			case 15:
				step111();
	//			step108();
				break;
			 
			case 16:
			 step112();
			 break;
				
	
			// ロール
			case 20:
				{
					// bg
					info.screen.blt(t_bg,-100,-250);
	
					// move view
					mv.onDraw(info.screen);
	
					// noise
					info.screen.setColor(255,255, 255, 255);
					info.screen.blendSrcAlpha();
					info.screen.blt(t_noise,-rand.get(370), -rand.get(250));
	
					// ring
					info.screen.setColor(255,255,255,128);
					info.screen.bltRotate(t_ring,40,120,timer.get()/10,0.6,4);
					info.screen.bltRotate(t_ring,65,350,-(timer.get()/10),0.7,4);
					info.screen.resetColor();
					info.screen.setColor(255,255,255,128);
					info.screen.blendAddColorAlpha();
					info.screen.blt(moji[0], 0, 0);
				}
				break;
	
			// 波紋
			case 30:
				{
					sizecounter += 0.03;
	
					float kosize = sizecounter;
					for(int i = 1; i <= 4; ++i) {
						kosize -= 0.05;
						info.screen.setColor(255,255,255,200/i);
						info.screen.blendAddColorAlpha();
						info.screen.bltRotate(t_ring2,340,240,0,kosize,4);
					}
					info.screen.bltRotate(t_ring2,340,240,0,sizecounter,4);
	
				}
				break;
			case 40:
				{
					step40();
				}
				break;
			case 50:
				{
					step50();
				}
				break;
	
			case 60:
				{
					static int phase = 0;
					static int add = 1;
			
					phase += add;
					if (phase > 255) {
						add = -1;
						phase = 255;
					} else if (phase < 0) {
						add = 1;
						phase = 0;
					}
				}
				break;
	
			case 70:
				{
					step70();
				}
				break;
	
			default:
			}
			
			static int count = 0;
			if (newstep && count++ > 0) {
				newstep = false;
				count = 0;
			} 
	
			movecounter += music_sync;
			step_counter += music_sync;
			timer.update();
			
			if (step >= 16 && !bgm.isPlay()) {
				info.gameSceneTransiter.exitScene();
				info.gameSceneTransiter.jumpScene(KyojinConst.Task.Task_Title);
				info.mouse.show();
				return 1;
			}	
	
			// 非0を返せば、このタスクは消される。
			return 0;

		} catch (Exception e) {
			Log.printFatal("RuntimeException %s#onMove : [%s] [%s]", 
				super.toString(), e.toString(), e.msg);
			throw e;
		}
	}

	override int task(Object o) {
		return 0;
	}

	/// オブジェクトを破棄して、ガベージコレクタを呼び出します
	override void destroy() {
		tl_bgStd = null;
		t_toplogo = null;
		t_title = null;
		t_titlememo = null;
		t_bg = null;
		t_k = null;
		t_2 = null;
		t_c = null;
		t_noise = null;
		t_ring = null;
		t_ring2 = null;
		t_flare = null;
		t_horizon = null;
		t_unLight = null;
		t_pole = null;
		t_fader = null;
		t_roleText = null;
		t_halftone = null;
		t_aliceEye = null;
		t_faice = null;
		t_ikiru = null;
		t_aliceUp = null;
		t_bg1 = null;
		t_tomiSt = null;
		t_tomiShade = null;
		t_bgEx = null;
		t_aliceSt = null;
		t_bgExZ = null;
		t_midoSt = null;
		t_Text = null;
		t_Code = null;
		t_CodeZ = null;
		t_aliceCode = null;
		t_kyo = null;
		tln = null;
		t_face = null;
		t_intro = null;
		ttdraw = null;
		tl_bg = null;
		t_bgFullNoise = null;
		t_shadows = null;
		t_endBg = null;
		t_endStaff = null;
		alphaCounter = null;
		mv = null;		// 背景ぶれ描画用クラス
		carsor = null;	// 点滅するプロンプトカーソル
		screenFrame = null;
		dTDraw = null;
		fl = null;
		sm = null;
		hp = null;
		ft = null;
		breakDrop = null;
		chara = null;
		clock = null;
		hexDrawer = null;
		headliner = null;
		t_Kyojintachi = null;
		headlineK2C = null;
		t_K2Cex = null;

		Log.print("%s#destroy : destroyed.", super.toString());
	}

	/// コンストラクタ
	this() {
		{
			byte [] a = new byte[1024*1024*200];
			delete a;
		}

		music_sync = 15.0 / (1.0 / ABEAT);
		ft = new FlashInText();
		breakDrop = new ScatteredTexture();
		screenFrame = new ScreenFrame();
		
		step = -2;
	}

private:

	/// 次のステップへ
	void nextStep() {
		step_start = movecounter;
		step_counter = 0.0f;
		step_start_time = timer.get();

		switch( step ) {
		case -2:
			step = -1;
			break;
			
		case -1:
			timer.reset();
			step = 0;
			break;
						
		case 0:
			step = 1;
			break;

		case 1:	
			sizex = cast(int)t_bgEx.getWidth();
			sizey = cast(int)t_bgEx.getHeight();
			srcrect.setRect(0, 0, sizex, sizey);
			info.screen.setColor(128, 128, 128);
			step = 2;
			break;
			
		case 2:
			step = 3;
			sizex = cast(int)t_titlememo.getWidth();
			sizey = cast(int)t_titlememo.getHeight();
			srcrect.setRect(0,0,sizex,0);
			break;
			
		case 3: 
			sizex = cast(int)t_titlememo.getWidth();
			sizey = cast(int)t_titlememo.getHeight();
			srcrect.setRect(0, 0, sizex, sizey);
			step = 4; 
			break;
			
		case 4:
			step = 5;
			screenFrame.setOpenManual(true);
			// 開閉速度, 停止時間
			screenFrame.setColseOpneSpeed( 8 );
			break;
		case 5:
			step = 6;
			break;
			
		case 6:
			step = 7;
			break;
			
		case 7:
			for (int i = 0; i < 60; ++i) {
				clock.onMove(info.screen);
			}
			step = 8;
			break;
			
		case 8:
			sizex = cast(int)t_bgEx.getWidth();
			sizey = cast(int)t_bgEx.getHeight();
			srcrect.setRect(0, 0, sizex, sizey);
			step = 9;
			break;
		case 9:
			step = 10;
			break;
			
		case 10:
			step = 11;
			break;

		case 11:
			step = 12;
			break;

		case 12:
			step = 13;
			break;

		case 13:
			step = 14;
			break;

		case 14:
			step = 15;
			break;

		case 15:
			step = 16;
			break;

		case 16:
			step = 17;
			break;
		default:
			assert(false);
		}
		
		newstep = true;
		
		Log.print("Now step:%2s \n",step);
	}

	/// 初期化処理　スレッドローダー！
	void onInit() {
		// メモリー状況をプリント
		GameInfo.printMemoryState();

		onInitForLoadingDraw();
		int delegate() dg = &onLoad;
//		info.gameSceneController.callScene(KyojinConst.Task.Task_Loader, dg);
		info.gameSceneController.callScene(KyojinConst.Task.Task_Loader, this);
		Log.printLook("Loader Thread setting..");
	}
	
	/// ローディング後の初期化処理を記述する
	/**
		タイムクリティカルなものをここでするといい。
	*/
	void onInitAfter() {
		bgm.play();
		timer = new FixTimer();	// タイマの生成
	}
	
	/// ローディング中の表示処理
	int taskLoading(Screen screen) {
		try {
			screen.blt(m_loadbg,0,0);
			int prog = getProgress();
			for (int i = 0; i < m_loadCheck.length; ++i) {
				if ( m_checkPos[i][0] <= prog ) {
					screen.blt(m_loadCheck[i], m_checkPos[i][1], m_checkPos[i][2] );
				}
			}
			
			char[] num = cast(char[]) std.string.toString( prog );
			int[] index = null;
			foreach(char c; num) {
				char[] tmp;
				tmp ~= c;
				index ~= std.conv.toInt(tmp);
			}

			static int[][] pos = [
				[190,229],
				[148,230],
				[112,228],
			];
			
			info.screen.setColor(255,255,255);
			for (int j = 0, i = index.length-1; i >= 0; --i, ++j) {
				info.screen.blt(m_number[j][index[i]], pos[j][0], pos[j][1]);
			} 

		} catch (Exception e) {
			Log.printFatal("%s#taskLoading(Screen) : [%s]", this.toString(), e.toString());
			throw e;
		}
		return 0;
	}
	
	/// ローディング表示用リソースの初期化
	void onInitForLoadingDraw() {
		this.m_loadbg = new Texture();
		this.m_loadbg.load(cast(char[]) "img/load/loadbg.png");
		
		for (int i = 0; i < m_loadCheck.length; ++i) {
			m_loadCheck[i] = new Texture();
			m_loadCheck[i].load( cast(char[]) m_loadCheckFilename[i] );
		}
		
		initNumbers(cast(char[]) "img/load/num1/num.lst", this.m_numbers1);
		initNumbers(cast(char[]) "img/load/num2/num.lst", this.m_numbers2);
		initNumbers(cast(char[]) "img/load/num3/num.lst", this.m_numbers3);
	
		m_number ~= this.m_numbers1;
		m_number ~= this.m_numbers2;
		m_number ~= this.m_numbers3;
	}
	
	/// 番号テクスチャのロード
	static void initNumbers(char[] filename, inout Texture[] numbers) {
		numbers = null;
		ubyte[] mem = cast(ubyte[]) FileSys.read(filename);
		std.stream.MemoryStream m = new std.stream.MemoryStream(mem);
		LineParser lp = new LineParser;
		while (!m.eof) {
			char[] linebuf = cast(char[]) m.readLine();
			lp.setLine(linebuf);
			char[] imgFileName = lp.getStr();
			if (!imgFileName) continue;
			
			Texture t = new Texture();
			t.load(imgFileName);
			numbers ~= t;
		}
		Log.print("load length : %s", numbers.length);
	}
	
	
	/// 初期化
	int onLoad() {
		with ( kyojintati4d.val.kyojinconst.PicNameConst.getInstance() ) {
			y4d_result res;
			
			this.progress = 0;
			
			++this.progress;
			
			// カーソル消すでー
			info.mouse.hide();
	
			rand = new Rand;	// ランダムの生成
			rand.randomize();
			st = SinTable.get();	// sinテーブルの取得
	
			font = new Font();	// フォントの生成
	
			dTDraw = new DizzyTextDraw();
			// ランダム文字画面のためのフォント
			fl = new FontLoader;
			++this.progress;
			fl.loadDefRW(cast(char[]) "fonts/FS-Gothic.ttf, 0, 21, 0\n");
			dTDraw.setFontLoader(fl,0);
			dTDraw.setSpeed(2);
			dTDraw.useHankana(false);
			++this.progress;
	
			// 点滅カーソル
			carsor = new PromptCarsor;
			++this.progress;
			Texture carsortexture = new Texture;
			carsortexture.load(cast(char[]) "img/scenario/carsor.png");
			carsor.setTexture(carsortexture);
			++this.progress;
	
			// 雪
			sm = new DropObjectManager;
			++this.progress;
			sm.presetSnow();
			sm.init(100);
			++this.progress;
	
			// HEX
			TextureLoader tl2 = new TextureLoader;
			tl2.loadDefRW(cast(char[]) "img/demo/hex_flame.png \n img/demo/hex.png \n img/demo/hex_flame2.png \n img/demo/hex_flame3.png");
			++this.progress;
			hp = new HexPropagate;
			hp.setHexSize(15,15);
			hp.setTextureLoader(tl2,3);
			++this.progress;
			
			tl_bgStd = new TextureLoader();
			tl_bgStd.loadDefRW( FileSys.read(cast(char[]) "img/demo/bg2/bg.lst") );
			++this.progress;

			Texture tex = new Texture;
	//		tex.load(DEMO__FLASH_TEXT_PNG);
			
			ft.getFontPepository().setLoader(info.fontloader,1);
			ft.getFontPepository().setMax(150);
			++this.progress;
			
			info.fontloader.get(1);
			++this.progress;

			// フラッシュインテキストクラスの設定
			// 白テクスチャの設定
			ft.setWhiteTextureBG( tl_bgStd.get(KyojinConst.BGDef.WHITE) );
			ft.setWhiteTexture(tex);
			ft.setShowSpeed( 14 );
			ft.addText(cast(wchar[]) "声明を荷電粒子にのせて加速を試行する");
			++this.progress;
			ft.addText(cast(wchar[]) "例えば、それが光速を超克するならば");
			++this.progress;
			ft.addText(cast(wchar[]) "声明は過去と未来にも伝播しえる");
			++this.progress;
			ft.addText(cast(wchar[]) "しかし荷電粒子は、光速近傍でその加速を取り止める");
			++this.progress;
			ft.addText(cast(wchar[]) "声明としての荷電粒子は過去と未来において意味を存続し得ない");
			++this.progress;
			ft.addText(cast(wchar[]) "今、此処にいる声明性の荷電粒子は");
			++this.progress;
			ft.addText(cast(wchar[]) "その意義を存続したまま、時空を超越することに懐疑的である");
			++this.progress;
			ft.addText(cast(wchar[]) "自身の疑念にとらわれた荷電粒子は物理的制縛と抗弁する");
			++this.progress;
			ft.addText(cast(wchar[]) "しかし、荷電粒子が本当にそう希求するならば光速度を");
			++this.progress;
			ft.addText(cast(wchar[]) "超えることは容易なのだ");
			ft.update();
			++this.progress;
	
			font.open(cast(char[]) "./fonts/LoveLetter.ttf",40);
			moji[] = new Texture[3];
			++this.progress;
			foreach(inout Texture t;moji) t = new Texture;
			++this.progress;
			
			// 装飾時計
			clock = new DecorativeColck();
			++this.progress;
	
			t_toplogo = new Texture();
			t_bg = new Texture();
			t_k = new Texture();
			t_2 = new Texture();
			t_c = new Texture();
			t_noise = new Texture();
			t_ring = new Texture();
			t_ring2 = new Texture();
			t_title = new Texture();
			t_titlememo = new Texture();
			t_flare = new Texture();
			t_horizon = new Texture();
			t_pole = new Texture();
			t_fader = new Texture();
			t_roleText = new Texture();
			t_faice = new Texture();
			t_ikiru = new Texture();
			t_bg1 = new Texture();
			t_bgEx = new Texture();
			t_aliceSt = new Texture();
			t_midoSt = new Texture();
			t_halftone = new Texture();
			
			t_aliceUp = new Texture();
			t_bgExZ = new Texture();
			t_tomiSt = new Texture();
			t_tomiShade = new Texture();
			t_aliceEye = new Texture();
			t_unLight = new Texture();
			++this.progress;
	
			t_toplogo.load( getFullName(cast(char[]) IMG__DEMO__LOGO1_PNG) );	// ロゴ "panicy style"
			++this.progress;
			t_bg.load( getFullName(cast(char[]) IMG__DEMO__BACK_JPG) );			// タイトル背景
			++this.progress;
			t_title.load( getFullName(cast(char[]) IMG__DEMO__TITLE_PNG) );		// タイトル
			++this.progress;
			t_titlememo.load( getFullName(cast(char[]) IMG__DEMO__TITLE_MEMO_PNG) );	// タイトルメモ
	
			t_noise.load( getFullName(cast(char[]) IMG__DEMO__NOISE_PNG) );	// ノイズテクスチャ
			++this.progress;
			t_ring.load( getFullName(cast(char[]) IMG__DEMO__RING_PNG) );	// 輪テクスチャ
			++this.progress;
			t_ring2.load( getFullName(cast(char[]) IMG__DEMO__WA_PNG) );
			
			t_flare.load( getFullName(cast(char[]) IMG__DEMO__FLERE_PNG) );	// フレア
			++this.progress;
			t_horizon.load( getFullName(cast(char[]) IMG__DEMO__HORIZON_PNG) );	// 水平線
			++this.progress;
			
			// ハーフトーンパターン
			t_halftone.load( getFullName(cast(char[]) IMG__DEMO__HALF_PNG) );
			++this.progress;
			// unlight
			t_unLight.load( getFullName(cast(char[]) IMG__DEMO__LIGHT_PNG) );
			++this.progress;
			
			// --- step6
			// 電柱
			t_pole.load( getFullName(cast(char[]) IMG__DEMO__POLE_PNG) );
			++this.progress;
			// テキスト
			t_roleText.load( getFullName(cast(char[]) IMG__DEMO__ROLE_TEXT_PNG) );
			++this.progress;
			// fader
			t_fader.load( getFullName(cast(char[]) IMG__DEMO__FADER_PNG) );
			++this.progress;
			
			// --stepXX
			++this.progress;
			t_faice.load( getFullName(cast(char[]) IMG__DEMO__ASA_F_PNG) );
			++this.progress;
			t_ikiru.load( getFullName(cast(char[]) IMG__DEMO__NANNO_PNG) );
			
			// --stepXX2
			++this.progress;
			t_aliceUp.load( getFullName(cast(char[]) IMG__DEMO__ALICE_UP_PNG) );
			++this.progress;
			t_bg1.load( getFullName(cast(char[]) IMG__DEMO__BG1_JPG) );
			
			// とみえたん
			++this.progress;
			t_aliceEye.load( getFullName(cast(char[]) IMG__DEMO__ALICE_EYE_PNG) );
			++this.progress;
			t_tomiSt.load( getFullName(cast(char[]) IMG__DEMO__TOMI_ST_PNG) );
			++this.progress;
			t_tomiShade.load( getFullName(cast(char[]) IMG__DEMO__TOMI_SHADE_PNG) );
		
			// --scene01
			++this.progress;
			t_bgEx.load( getFullName(cast(char[]) IMG__DEMO__SCENE01_JPG) );
			++this.progress;
			t_bgExZ.load( getFullName(cast(char[]) IMG__DEMO__SCENE01Z_JPG) );
			++this.progress;
			t_aliceSt.load( getFullName(cast(char[]) IMG__DEMO__ALICE_ST_PNG) );
			++this.progress;
			t_midoSt.load( getFullName(cast(char[]) IMG__DEMO__MIDO_ST_PNG) );
			
			// テキスト
			++this.progress;
			t_Text = new Texture[7];
			foreach(inout Texture t; t_Text) {
				t = new Texture();
			}
			++this.progress;
			t_Text[0].load( getFullName(cast(char[]) IMG__DEMO__TEXT1_PNG) );
			++this.progress;
			t_Text[1].load( getFullName(cast(char[]) IMG__DEMO__TEXT2_PNG) );
			++this.progress;
			t_Text[2].load( getFullName(cast(char[]) IMG__DEMO__TEXT3_PNG) );
			++this.progress;
			t_Text[3].load( getFullName(cast(char[]) IMG__DEMO__TEXT4_PNG) );
			++this.progress;
			t_Text[4].load( getFullName(cast(char[]) IMG__DEMO__TEXT5_PNG) );
			++this.progress;
			t_Text[5].load( getFullName(cast(char[]) IMG__DEMO__TEXT6_PNG) );
			++this.progress;
			t_Text[6].load( getFullName(cast(char[]) IMG__DEMO__TEXT7_PNG) );
			
			// -------------------------code
			++this.progress;
			t_Code = new Texture[5];
			foreach(inout Texture t; t_Code) {
				t = new Texture();
			}
			++this.progress;
			t_Code[0].load( getFullName(cast(char[]) IMG__DEMO__CODE1_PNG) );
			++this.progress;
			t_Code[1].load( getFullName(cast(char[]) IMG__DEMO__CODE2_PNG) );
			++this.progress;
			t_Code[2].load( getFullName(cast(char[]) IMG__DEMO__CODE3_PNG) );
			++this.progress;
			t_Code[3].load( getFullName(cast(char[]) IMG__DEMO__CODE4_PNG) );
			++this.progress;
			t_Code[4].load( getFullName(cast(char[]) IMG__DEMO__CODE5_PNG) );
	
			++this.progress;
			t_CodeZ = new Texture[5];
			foreach(inout Texture t; t_CodeZ) {
				t = new Texture();
			}
			++this.progress;
			t_CodeZ[0].load( getFullName(cast(char[]) IMG__DEMO__CODE_A_PNG) );
			++this.progress;
			t_CodeZ[1].load( getFullName(cast(char[]) IMG__DEMO__CODE_B_PNG) );
			++this.progress;
			t_CodeZ[2].load( getFullName(cast(char[]) IMG__DEMO__CODE_C_PNG) );
			++this.progress;
			t_CodeZ[3].load( getFullName(cast(char[]) IMG__DEMO__CODE_D_PNG) );
			++this.progress;
			t_CodeZ[4].load( getFullName(cast(char[]) IMG__DEMO__CODE_E_PNG) );
			
			++this.progress;
			t_aliceCode = new Texture();
			t_aliceCode.load( getFullName(cast(char[]) IMG__DEMO__ALICE_CODE_PNG) );
			
			++this.progress;
			t_kyo = new Texture();
			t_kyo.load( getFullName(cast(char[]) IMG__DEMO__KYO_PNG) );
			
			// ------------------char intoro
			++this.progress;
			t_face = new Texture[4];
			foreach(inout Texture t; t_face) {
				t = new Texture();
			}
	
			++this.progress;
			t_intro = new Texture[4];
			foreach(inout Texture t; t_intro) {
				t = new Texture();
			}
			
			++this.progress;
			t_face[0].load( getFullName(cast(char[]) IMG__DEMO__TATUWO_FACE_PNG) );		
			++this.progress;
			t_face[1].load( getFullName(cast(char[]) IMG__DEMO__TOMI_FACE_PNG) );		
			++this.progress;
			t_face[2].load( getFullName(cast(char[]) IMG__DEMO__ANZAI_FACE_PNG) );		
			++this.progress;
			t_face[3].load( getFullName(cast(char[]) IMG__DEMO__RUBI_FACE_PNG) );
			
			++this.progress;
			t_intro[0].load( getFullName(cast(char[]) IMG__DEMO__TATUWO_INTRO_PNG) );		
			++this.progress;
			t_intro[1].load( getFullName(cast(char[]) IMG__DEMO__TOMI_INTRO_PNG) );		
			++this.progress;
			t_intro[2].load( getFullName(cast(char[]) IMG__DEMO__ANZAI_INTRO_PNG) );		
			++this.progress;
			t_intro[3].load( getFullName(cast(char[]) IMG__DEMO__RUBI_INTRO_PNG) );
	
			++this.progress;
			ttdraw = new TexutralTextDraw();
			ttdraw.setTexture(t_intro[0]);
			ttdraw.setLineHeight(24);
			ttdraw.setStep(22);
			
			tl_bg = new TextureLoader();
			tl_bg.setCacheSize(-1);	// 無限キャッシュ
			tl_bg.loadDefRW( FileSys.read(cast(char[]) "img/demo/bg/list.lst") );
			++this.progress;
			// キャッシュに読み込んでおく
			for (int i = 0; i < tl_bg.getInfoList().size(); ++i) {
				Texture t = tl_bg.get(i);
			}
			
			++this.progress;
			// --------------------------flash
			t_bgFullNoise = new Texture();
			t_bgFullNoise.load(cast(char[]) "img/demo/bg_noise.png");
	
			++this.progress;
			t_shadows = new Texture[3];
			foreach(inout Texture t; t_shadows) {
				t = new Texture();
			}
			++this.progress;
			t_shadows[0].load( getFullName(cast(char[]) IMG__DEMO__MIDO_SHADOW_PNG) );
			++this.progress;
			t_shadows[1].load( getFullName(cast(char[]) IMG__DEMO__YUIRI_SHADOW_PNG) );
			++this.progress;
			t_shadows[2].load( getFullName(cast(char[]) IMG__DEMO__ALICE_SHADOW_PNG) );
			
			++this.progress;
			// キャッシュに喰っておく
			tl_bgStd.setCacheSize(-1);	// 無限キャッシュ
			for(int i = 0; i < tl_bgStd.getInfoList().size(); ++i) {
				Texture t = tl_bgStd.get(i);
			}
			++this.progress;
		
			// ---------------------------- KYOJINTACHI
			headliner = new SequentialDrawAlpha();
			headliner.setXY(320, 240);
			headliner.setMoveXY(30,50);
			headliner.setInterval(5);
			headliner.setStartRate(4.0f);
			headliner.setEffectingFrame(30);
			++this.progress;
			headliner.addTexture( FileSys.makeFullName(cast(char[]) "img/demo/kyojintachi.lst") );
			t_Kyojintachi = new Texture();
			++this.progress;
			t_Kyojintachi.load( getFullName(cast(char[]) IMG__DEMO__KYOJINTACHI_PNG) );
			
			++this.progress;
			// ---------------------------- K2C
			headlineK2C = new SlideInHeadlinear();
			headlineK2C.setXY(70, 150);
			headlineK2C.setMoveXY(0, 60);
			headlineK2C.setInterval(5);
			headlineK2C.setDisposeStep(25);
			headlineK2C.setFadeOut( true );
			++this.progress;
			headlineK2C.addTexture( FileSys.makeFullName(cast(char[]) "img/demo/logo/k2c.lst") );
			++this.progress;
			t_K2Cex = new Texture();
			t_K2Cex.load( getFullName(cast(char[]) IMG__DEMO__K2C_EX_PNG) );

			++this.progress;
			
			// ----------------------------- end staff
//			t_endBg = new Texture();
//			t_endBg.load("img/demo/end.jpg");
			t_endStaff = new Texture();
			t_endStaff.load( getFullName(cast(char[]) IMG__DEMO__ENDSTAFF_PNG) );
			alphaCounter = new InteriorCounter(0, 200, 120);

			++this.progress;
	
			// ラインノイズ
			tln = new TextureLineNoise;
			tln.setXY(300, -200);
			tln.setRandWidth(10);
			tln.setTexture(t_aliceCode);
			++this.progress;
			
			mv = new MoveView();	// 背景ぶれ描画クラス
			mv.setTextureLoader(tl_bgStd);
			
			++this.progress;
			// bgm
			bgm = new Sound;
			bgm.load(cast(char[]) "snd\\song\\bgm.ogg", -1);

			
			timer = new FixTimer();	// タイマの生成
			
			++this.progress;
			
			nextStep();
		}
		
		return 0;
	}
	
	/// イントロ部分
	void stepS01() {
		static const uint LC_STEP_TIME = 10000;
		static const uint LC_IN_TIME = 6000;
		static float alpha = 0.0f;
		
		info.screen.setClearColor(128,128,128); 
		
		// noise
		info.screen.setColor(128, 128, 255, 255);
		info.screen.blendSrcAlpha();
		info.screen.blt(t_noise,-rand.get(370), -rand.get(250));
		
		if ( timer.get() > LC_IN_TIME ) {
			if (alpha < 255) {
				alpha += 0.5;
			}
			// タイトル
			info.screen.setColor(255,255,255, cast(int) alpha);
			info.screen.blt(t_toplogo,0,0);
		}
		
		if( timer.get() > LC_STEP_TIME ) {
			nextStep();
		}
		
	}

	/// タイトル "panicky style"
	void step001() {
		// move view
		mv.onDraw(info.screen);
		mv.setRandX(30);
		mv.setAngleSpeed(30);
		mv.setAmplitude(30);

		// noise
		info.screen.setColor(128, 128, 255, 255);
		info.screen.blendSrcAlpha();
		info.screen.blt(t_noise,-rand.get(370), -rand.get(250));

		// タイトル
		info.screen.setColor(255,255,255,addfade);
		info.screen.blt(t_toplogo,0,0);

		if( addfade < 255 &&  stepFlameToSec() < 3.0 ) {
			addfade += 10;
			if( addfade > 200 && !replay ) {
				addfade = 80;
				replay = true;
			}
			if( addfade > 255 ) {
				addfade = 255;
			}
		}
		
		// スクリーンフレームの描画
		screenFrame.onDraw(info.screen);
		
		if( stepFlameToSec() > 3.0 ) {
			addfade -= 5;
			if( addfade <= 0 ) {
				addfade = 0;
				movecounter = 0;
				nextStep();
			}
		}
	}

	/// タイトルイン（フェード＋スライドイン）
	void step002() {
		static const float LC_SWING_TIME = 700.0f;
		static const uint LC_STEP_TIME = 1200;
		static float move = 0.0f;
		
		if (newstep) {
			move = move.init;
		}

		uint baseTime = timer.get() - step_start_time;
		if (baseTime > LC_SWING_TIME) {
			baseTime = cast(int) LC_SWING_TIME;
			move += 0.1f;
		}
		tx = 200 + st.sin(cast(int)(baseTime / LC_SWING_TIME * 128),110);

		// bg
		info.screen.blt(t_bg,-100,-250);

		// move view
		mv.onDraw(info.screen);
		
		info.screen.setColor(255,255,255,cast(int)( (baseTime / LC_SWING_TIME) * 255) );
		info.screen.blendSrcAlpha();
		info.screen.blt(t_title, cast(int)move + tx, 250);

		// noise
		info.screen.setColor(128,128,255,255);
		info.screen.blendSrcAlpha();
		info.screen.blt( t_noise,-rand.get(370), -rand.get(250) );

		// スクリーンフレームの描画
		screenFrame.onDraw(info.screen);

		if( timer.get()-step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}

	/// タイトルメモイン（カットイン）
	void step003() {
		static const int LC_MEMO_POSY = 300;
		static const uint LC_STEP_TIME = 2800;		
		
		// bg
		info.screen.blt(t_bg,-100,-250);

		// move view
		mv.onDraw(info.screen);

		// noise
		info.screen.setColor(128,128,255,255);
		info.screen.blendSrcAlpha();
		info.screen.blt(t_noise,-rand.get(370), -rand.get(250));

		info.screen.setColor(255,255,255,255);
		info.screen.blendSrcAlpha();
		info.screen.blt(t_title, cast(int)move + tx, 250);
		move += 0.1;

		srcrect.bottom = sizey * (timer.get() - step_start_time) / 1248;
		info.screen.blt(t_titlememo, 310, LC_MEMO_POSY, &srcrect);

		// スクリーンフレームの描画
		screenFrame.onDraw(info.screen);

		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}

	/// タイトルアウト
	void step004() {
		static const int LC_MEMO_POSY = 300;
		static const uint LC_STEP_TIME = 1200;
		static const uint LC_CUTIN_TIME = 500;
		uint baseTime = timer.get() - step_start_time;
		
		// bg
		info.screen.blt(t_bg,-100,-250);

		// move view
		mv.onDraw(info.screen);

		// noise
		info.screen.setColor(128,128,255,255);
		info.screen.blendSrcAlpha();
		info.screen.blt(t_noise,-rand.get(370), -rand.get(250));

		// タイトルのフェード
		if (baseTime < LC_CUTIN_TIME) {
			info.screen.setColor(255, 255, 255, (255 - (255 * baseTime / LC_CUTIN_TIME)) );
			info.screen.blendSrcAlpha();
			info.screen.blt(t_title, cast(int)move + tx, 250);
		}

		// メモのカットアウト
		if (baseTime < LC_CUTIN_TIME) {
			info.screen.setColor(255, 255, 255, 255);
			srcrect.bottom = sizey - (sizey * baseTime / LC_CUTIN_TIME);
			info.screen.blt(t_titlememo, 310, LC_MEMO_POSY, &srcrect);
		}

		// スクリーンフレームの描画
		screenFrame.onDraw(info.screen);

		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}

	// -> プロローグ：開閉
	void step005() {
		static const int LC_MEMO_POSY = 300;
		static const uint LC_STEP_TIME = 1500;
		static const uint LC_CUTIN_TIME = 500;

		static int waitTime = 0;
		static float rate = 3.0f;
		static bool open = false;
		
		uint baseTime = timer.get() - step_start_time;

		if (newstep) {
			waitTime = waitTime.init;
			rate = rate.init;
			open = open.init;
		}
		
		if ( !screenFrame.isWait() ) {
			if ( !open ) {
				// bg
				info.screen.blt(t_bg, -100, -250);
		
				// move view
				mv.onDraw(info.screen);
		
				// noise
				info.screen.setColor(128, 128, 255, 255);
				info.screen.blendSrcAlpha();
				info.screen.blt(t_noise,-rand.get(370), -rand.get(250));
				
				screenFrame.drawCloseOpen(info.screen);
				if ( screenFrame.isWait() ) {
					waitTime = baseTime;
				}
			}
		} else {
			int sx = info.screen.getWidth();
			int sy = info.screen.getHeight();
			int ty = cast(int) t_horizon.getHeight();
			screenFrame.drawCloseOpen(info.screen);
			
			info.screen.enableBlend();
			info.screen.blendSrcAlpha();
			info.screen.setColor(255, 255, 255, 255);
			
			info.screen.blt(t_horizon, 0, (sy / 2) - (ty / 2));
			info.screen.bltRotate(t_flare, sx/2, sy/2, 0, rate, 4);
			rate -= 0.12f;
			
			if (rate < 0.0f) {
				screenFrame.screenOpen();
				nextStep();
			}
		}
	}
	
	/// プロローグ：ロール
	void step006() {
		static int rad1 = 0;
		static int rad2 = Y4dConst.C_RAD_MAX;
		static float top = 0.0f;
		static const uint LC_STEP_TIME = 13250;

		if (newstep) {
			rad1 = rad1.init;
			rad2 = rad2.init;
			top = top.init;
		}
		
		Rect srcRc;
		int w = cast(int) t_pole.getWidth();
		int h = cast(int) t_pole.getHeight();
		
		// 回転リング描画
		info.screen.setColor(255, 255, 255, 128);
		info.screen.bltRotate( t_ring, 60, 100, rad1, 0.5f, 4);
		info.screen.bltRotate( t_ring, 85, 320, rad2, 0.8f, 4);
		
		rad1++;
		rad2--;
		if (rad1> Y4dConst.C_RAD_MAX) {
			rad1 = 0;
		}
		if (rad2 < 0) {
			rad2 = Y4dConst.C_RAD_MAX;
		}
		
		srcRc.left = 0;
		srcRc.right = w;
		srcRc.top = cast(int) top;
		srcRc.bottom = srcRc.top + 480;
		top += 0.2f;
		
		// ダークレイヤー描画
		info.screen.setColor( 0, 0, 0, 162 );
		info.screen.blendSrcAlpha();		
		info.screen.drawPolygon(
			0,0,
			300,0,
			300,480,
			0,480);
		info.screen.setColor( 0, 0, 0, 255 );
		info.screen.blendSrcAlpha();
		info.screen.drawPolygon(
			600,0,
			640,0,
			640,480,
			600,480);

		// 電柱描画		
		info.screen.setColor(255, 255, 255, 100);
		info.screen.blt(t_pole, 300, 0, &srcRc);
		
		// テキスト
		info.screen.setColor(255, 255, 255, 196);
		info.screen.blt(t_roleText, 20, 0, &srcRc);
		
		// noise
		info.screen.setColor(255, 255, 255, 128);
		info.screen.blt(t_noise,-rand.get(370), -rand.get(250));
		
		// プログラム処理するのマンドクセ
		// フェーダー
		info.screen.setColor(255, 255, 255, 255);
		info.screen.blt(t_fader, 0, 0);
		
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}		
	}
	
// -------------
	// 何のために生きるの？	
	void step101() {
		static float x1 = 0.0f;
		static float x2 = 0.0f;
		static int alpha = 0;
		static int waitCounter = 0;
		static int add = 3;
		
		if (newstep) {
			x1 = x1.init;
			x2 = x2.init;
			alpha = alpha.init;
			waitCounter = waitCounter.init;
			add = add.init;
		}
		
		info.screen.setColor(255, 255, 255, alpha);
		
		info.screen.blt(t_faice, 200 + cast(int)x1, 50);
		info.screen.blt(t_ikiru, 150 - cast(int)x2, 200);

		alpha += add;
		if (alpha == 255) {
			add = 0;
		}
		// フェードアウトウェイト
		if (add == 0) {
			++waitCounter;
			if (waitCounter == 128) {
				add = -3;
			}
		}
		
		x1 += 0.3f;
		x2 += 0.3f;
		
		if (alpha == 0) {
			nextStep();
		}
	}
	
	// dis
	void step102() {
		static float mx1 = 0.0f;
		static int mx2 = 0;
		static uint counter = 0;
		static int add = 20;
		static int rad = 0;
		static const uint LC_STEP_TIME = 20000;
		
		if (newstep) {
			mx1 = mx1.init;
			mx2 = mx2.init;
			counter = counter.init;
			add = add.init;
			rad = rad.init;
		}
		
		info.screen.setColor(255, 255, 255, 255);
		info.screen.bltRotate(t_bg1, 320,240, rad, 1.0f, 4);
		info.screen.blt(t_aliceUp, (640 - mx2 - cast(int)mx1), 0);

		rad += 4;
		if (rad >= Y4dConst.C_RAD_MAX) {
			rad = 0;
		}
		
		mx2 += add;
		mx1 += 1;
		
		if (counter++ == 40) {
			add = 0;
		}
	
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}		
	}
	
	// test
	void step103() {
		static const int LC_STEP_TIME = 3100;
		static float rate  = 0.5f;
		static uint count = 0;
		static int innerStep = 0;
		static int mx = 0;
		static int mxSt = -80;
		static int mySt = 0;
		static int mxSt2 = 0;
		static int mySt2= 0;
		static float rateSt = 0.4f;
		static int mxBg = 0;
		static float mxCount = 0.0f;
		static int alpha = 0;
		
		if (newstep) {
			rate = rate.init;
			count = count.init;
			innerStep = innerStep.init;
			mx = mx.init;
			mxSt = mxSt.init;
			mySt = mySt.init;
			mxSt2 = mxSt2.init;
			mySt2 = mySt2.init;
			rateSt = rateSt.init;
			mxBg = mxBg.init;
			mxCount = mxCount.init;
			alpha = alpha.init;
		}
		
		// 固定
		switch(innerStep) {
			case 0:
				if (mxSt < 0) {
					mxSt += 10;
				} else {
					mxCount += 0.5f;
					if (mxCount >= 1.0f) {
						mxSt +=1;
						mxCount -= 1.0f;
					}
				}
				info.screen.setColor(255, 255, 255, 255);
				info.screen.bltRotate(t_bgEx, 360, 240, 0, rate, 4);
				info.screen.bltRotate(t_midoSt, 320, 200, 0, 0.4f, 0);
				// ありす中央入場
				info.screen.blt(t_aliceSt, 150-mxSt, 0);
				break;

			case 1:
				// 左スライド
				mx += 5;
				mxSt += 15;
				mxSt2 += 5;
				info.screen.bltRotate(t_bgEx, 360-mx, 240, 0, rate, 4);
				info.screen.bltRotate(t_midoSt, 320-mxSt2, 200, 0, 0.4f, 0);
				info.screen.blt(t_aliceSt, 150-mxSt, 0);
				break;

			case 2:
				info.screen.bltRotate(t_bgEx, 360-mx, 240, 0, rate, 4);
				info.screen.bltRotate(t_midoSt, 320-mxSt2, 200, 0, 0.4f, 0);
				info.screen.blt(t_aliceSt, 150-mxSt, 0);
				break;

			case 3:
				// 拡大フェーズ
				rate += 0.07;
				if (rate >= 1.3f) {
					innerStep++;
				} else {
					rateSt += 0.1;
					mxBg += 15;
					mySt2 += 15;
					mxSt2 += 15;
					mySt += 50;
				}
				mxSt += 100;
				info.screen.setColor(255, 255, 255, 255);
				info.screen.bltRotate(t_bgExZ, 360, 240 - mxBg, 0, rate, 4);
				info.screen.bltRotate(t_midoSt, 320-mxSt2, 200-mySt2, 0, rateSt, 0);
				// ありす中央退場
				info.screen.bltRotate(t_aliceSt, 150-mxSt, 0-mySt, 0, 1.0f + rateSt, 0);
				break;
				
			case 4:
				// 拡大中
				info.screen.setColor(255, 255, 255, 255);
				info.screen.bltRotate(t_bgEx, 360, 240 - mxBg, 0, rate, 4);
				info.screen.bltRotate(t_midoSt, 320-mxSt2, 200-mySt2, 0, rateSt, 0);
				break;
			default:
				assert(false);
		}
		
		info.screen.blt(t_halftone, 0 , 0);
		
		if (innerStep == 4) {
			// ダークレイヤー描画
			info.screen.setColor( 255, 255, 255, alpha);
			info.screen.blendSrcAlpha();		
			info.screen.drawPolygon(
				0, 0,
				640, 0,
				640, 480,
				0, 480);
			if (alpha < 255) {				
				alpha += 18;
				if (alpha > 255) {
					alpha = 255;
				}
			}
		}
		
		count++;
/*		if (count == 120) {
			innerStep++;
		} else if (count == 130) {
			innerStep++;
		} else if (count == 220) {
			innerStep++;
		}
*/		if (count == 50) {
			innerStep++;
		} else if (count == 60) {
			innerStep++;
		} else if (count == 150) {
			innerStep++;
		}
				
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
		
	}
	
	// とみえたん立ち
	void step104() {
		static float alpha = 0.0f;
		static float myBg = 0.0f;
		static int count = 0;
		static float mxSt = 0.0f;
		static const int LC_STEP_TIME = 3100;
		
		if (newstep) {
			alpha = alpha.init;
			myBg = myBg.init;
			count = count.init;
			mxSt = mxSt.init;
		}
			
		info.screen.setColor(255, 255, 255, 255);
		info.screen.blt(t_aliceEye, 0, -250 + cast(int) myBg);
		info.screen.setColor(255, 255, 255, 128);
		info.screen.blt(t_halftone, 0, 0);
		info.screen.setColor(255, 255, 255, 128 + cast(int) alpha);
		info.screen.blt(t_tomiShade, 195- cast(int) mxSt, 10);
		info.screen.setColor(255, 255, 255, 255);
		info.screen.blt(t_tomiSt, 200, -30);
		
		count++;
		
		mxSt += 0.15f;
		
		alpha += 0.5f;
		if (count <= 5) {
			myBg += 15.0f;
		} else {
			myBg += 0.2f;
		}
		
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}
	
	// FlashInText
	void step105() {
		static const int LC_STEP_TIME = 6700;
		static const int LC_BG_COUNT = 7;
		static int counter = 0;
		static int bgIndex = 0;
		
		if (newstep) {
			counter = counter.init;
			bgIndex = bgIndex.init;
		}
		
		info.screen.blt(tl_bgStd.get( bgIndex ), 0, 0);
		
		// 白塗りつぶし
		info.screen.setColor(0, 0, 0, 255);
		
		// 上部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 0,
			640, 0,
			640, 120,
			0, 120 ); 
		
		// 下部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 360,
			640, 360,
			640, 480,
			0, 480 );				

		// ダークレイヤー描画
		info.screen.setColor( 0, 0, 0, 80 );
		info.screen.blendSrcAlpha();		
		info.screen.drawPolygon(
			0, 0,
			640, 0,
			640, 480,
			0, 480);
		
		ft.onMove(info.screen);
		ft.onDraw(info.screen);
		
		counter++;

		if ( !(counter % LC_BG_COUNT) ) {
			bgIndex = rand.get( tl_bgStd.getInfoList().size() );
		}
		
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
		
//		if ( ft.isFinish() || counter == 360) {
//			ft.reset();
//			bgIndex = 0;
//			counter = 0;
//			nextStep();
//		}
	}
	
	// キャラ紹介
	void step106() {
		static uint counter = 0;
		static float rate = 2.0f;
		static int dlayerCount = 0;
		static int stopCoounter = 15;
		static int bgNo = 10;
		static int index = 0;
		static int alpha = 255;
		static int count = 0;
		Rect rc;
		
		if (newstep) {
			counter = counter.init;
			rate = rate.init;
			dlayerCount = dlayerCount.init;
			stopCoounter = stopCoounter.init;
			bgNo = bgNo.init;
			index = index.init;
			alpha = alpha.init;
			count = count.init;
		}
		
		// 有効描画領域(大きくとってマージン確保)
		int tx = 650 - cast(int) (640 * rate);
		int ty = 490 - cast(int) (480 * rate);
		
		if (rate <= 0.0f) {
			stopCoounter--;
			if (stopCoounter <= 0) {
				rate = 2.0f;
				stopCoounter = 15;
				++bgNo;
				++index;
				index %= t_Text.length;
				alpha = 255;
				count++;
				
				if (count >= 7) {
//					nextStep();
				}
			}
		} else {
			int px = ( 640 - cast(int)t_Text[index].getWidth() ) / 2;
			int py = ( 480 - cast(int)t_Text[index].getHeight() ) / 2;
			rc.setRect(tx/2, ty/2, 640-tx/2, 480-ty/2);
			
			info.screen.setColor(255, 255, 255, 255);
			if (rate < 1.0f) {
				info.screen.blt(tl_bgStd.get(bgNo), tx/2, ty/2, &rc);
			} else if (tx/2 < 320){
				info.screen.blt(tl_bgStd.get(bgNo), 0, 0);
			}
			info.screen.bltRotate(t_unLight, 320, 240, 0, rate, 4);
			
			info.screen.setColor(255, 255, 255, alpha);
			info.screen.blt(t_Text[index], px, py);
	
			// 適当なタイミングでダークレイヤー描画し明滅させる		
			if (dlayerCount > 0) {
				// ダークレイヤー描画
				info.screen.setColor( 0, 0, 0, 80 );
				info.screen.blendSrcAlpha();		
				info.screen.drawPolygon(
					0, 0,
					640, 0,
					640, 480,
					0, 480);
				dlayerCount--;
			} else {
				if (rand.get(10) == 0) {
					dlayerCount = 5;
				}
			}
			rate -= 0.023f;
			alpha -= 2;
		}

		info.screen.setColor(255, 255, 255, 160);
		info.screen.blt(t_halftone, 0, 5 - rand.get(10) );

		if (timer.get() - step_start_time > (11500)) {
			nextStep();
		}
		
	}
	
	// code
	void step107() {
		static const int LC_STEP_TIME = 13200;
		static int myBg = 0;
		static int index = 0;
		static int myBgZ = 0;
		static int indexZ = 0;
		static float mySt = -200.0f;
		
		if (newstep) {
			myBg = myBg.init;
			index = index.init;
			myBgZ = myBgZ.init;
			indexZ = indexZ.init;
			mySt = mySt.init;
			
		}
		
		int px = (640 - cast(int)t_kyo.getWidth()) / 2;
		int py = (480 - cast(int)t_kyo.getHeight()) / 2;
		
		// 時計描画
		clock.onMove(info.screen);
		clock.onDraw(info.screen);
		
		info.screen.setColor(255, 255, 255, 96);
		info.screen.blt(t_CodeZ[indexZ], 0, myBgZ);
		info.screen.blt(t_CodeZ[indexZ + 1], 0, 480 + myBgZ);
		
		// ありす
		info.screen.setColor(255, 255, 255, 128);
		tln.setXY(300, cast(int) mySt);
		tln.onDraw(info.screen);
		
		info.screen.blt(t_kyo, px, py);

		info.screen.setColor(255, 255, 255, 128);
		info.screen.blt(t_Code[index], 0, myBg);
		info.screen.blt(t_Code[index + 1], 0, 480 + myBg);
		
		mySt += 0.3f;
		
		myBg -= 2;
		if (myBg <= -480) {
			myBg = 0;
			index++;
			index %= t_Code.length;
		}
		
		myBgZ -= 1;
		if (myBgZ <= -480) {
			myBgZ = 0;
			indexZ++;
			index %= t_CodeZ.length;
		}
		
		// 終了タイミングの時間判定
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}
	
	/// キャラクターイントロダクション
	void step108() {
		static const int frameSize = 4;
		static const int steps[4] = [31, 29, 35, 34];
		static const int LC_COLOR_D = 20;
		static const Rect rcTop = {0, 0, 640, 120}; 
		static const Rect rcBottom = {0, 360, 640, 480}; 

		static int resetCounter = 0;
		static int bgCount = 0;
		static Color4ub color = {255, 255, 255, 255};
		static float stX = 250.0f;
		static int iIndex = 0;

		if (newstep) {
			resetCounter = resetCounter.init;
			bgCount = bgCount.init;
			stX = stX.init;
			iIndex = 0;
		}

		Color4ub colorOld = info.screen.getColor4ub();
		int r,g,b;
		r = rand.get(LC_COLOR_D) - (LC_COLOR_D)/2;
		g = rand.get(LC_COLOR_D) - (LC_COLOR_D)/2;
		b = rand.get(LC_COLOR_D) - (LC_COLOR_D)/2;
		
		if ( color.r + r > 255 ) {
			color.r = 255;
		} else if (color.r + r < 0) {
			color.r = 0;
		} else {
			color.r += r;
		}

		if ( color.g + g > 255 ) {
			color.g = 255;
		} else if (color.g + g < 0) {
			color.g = 0;
		} else {
			color.g += g;
		}

		if ( color.b + b > 255 ) {
			color.b = 255;
		} else if (color.b + b < 0) {
			color.b = 0;
		} else {
			color.b += b;
		}
		
		info.screen.setColor(255, 255, 255, 200);
		
		// キャラクター描画
		stX += 0.2f;
		info.screen.blt(t_face[iIndex], cast(int) stX, 120);

		// テキスト描画

		// 描画終了したフレームアウトさせる
		if ( ttdraw.isEnd() ) {
			int x,y;
			ttdraw.getXY(x,y);
			ttdraw.setXY(x, y-10);
			
			if (y < -100) {
				++iIndex;
				if (iIndex < 4) {
					ttdraw.reset();
					ttdraw.setTexture(t_intro[iIndex]);
					ttdraw.setStep(steps[iIndex]);
					stX = stX.init;
				} else {
					nextStep();
				}
			}
		} else {
			ttdraw.setXY(10, 130);
		}
		
		ttdraw.onMove(info.screen);
		ttdraw.onDraw(info.screen);
		
		// hex 描画
		info.screen.setColor( color );
		hp.onDraw(info.screen);

		info.screen.setColor(255, 255, 255, 255);
		
		// スクリーンフレームの描画
		Texture t = tl_bg.get(bgCount);
		info.screen.blt(t, cast(int) rcTop.left, cast(int) rcTop.top, cast(Rect*) &rcTop);
		info.screen.blt(t, cast(int) rcBottom.left, cast(int) rcBottom.top, cast(Rect*) &rcBottom);
		// 白塗りつぶし
		info.screen.setColor(255, 255, 255, 255);
		
		// 上部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 120 - frameSize,
			640, 120  - frameSize,
			640, 120,
			0, 120 ); 
		
		// 下部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 360,
			640, 360,
			640, 360 + frameSize,
			0, 360 + frameSize );		
//		screenFrame.setFrameSize(3);
//		screenFrame.onDraw(info.screen);
		
		resetCounter++;
		
		if (resetCounter == 30) {
			hp.clear(true);
			resetCounter = 0;
		}
		
		bgCount++;
		if (bgCount >= tl_bg.getInfoList().size() ) {
			bgCount = 0;
		}
	}
	
	
	/// 一瞬の変遷
	void step109() {
		static const int frameSize = 3;
		static int step = 0;
		static int counter = 0;
		static int charaIndex = 0;
		static int flashCounter = 0;
		
		if (newstep) {
			step = step.init;
			counter = counter.init;
			charaIndex = charaIndex.init;
			flashCounter = flashCounter.init;
		}
		
		info.screen.setColor(255, 255, 255);
		info.screen.blt(t_bgFullNoise, 0, 0);
		
		info.screen.blt(t_shadows[charaIndex], 100, 0);
		
		// 白塗りつぶし
		info.screen.setColor(0, 0, 0);
		
		// 上部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 80 - frameSize,
			640, 80  - frameSize,
			640, 80,
			0, 80 ); 
		
		// 下部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 400,
			640, 400,
			640, 400 + frameSize,
			0, 400 + frameSize );				
		// ホワイトフラッシュ
		if (counter == 0  || counter == 1 || counter == 14 || counter == 15) {
			info.screen.setColor(255, 255, 255);
			
			// 上部非描画領域の区切り線描画
			info.screen.drawPolygon(
				0, 0,
				640, 0,
				640, 480,
				0, 480 ); 
		}
		
		if ( counter == 60 || 
			(counter > 60 && ( ( (counter-60) % 7) == 0 ) ) ) {
			info.screen.setColor(255, 255, 255);
			
			// 上部非描画領域の区切り線描画
			info.screen.drawPolygon(
				0, 0,
				640, 0,
				640, 480,
				0, 480 );
			
			if (++flashCounter  == 8) {
				nextStep();
			} 
				 
		}
		
	    if (counter == 8) {
	    	charaIndex++;
		} else if (counter == 60) {
	    	charaIndex++;
		}
		counter++;
	}
	
	/// タイトル去人たち
	void step110() {
		static const int LC_STEP_TIME = 6900;
		static const int alphaCount = 4;
		static float rate = 1.0f;
		static int alpha = 255;
		static int counter = 0;
		
		if (newstep) {
			counter = counter.init;
			rate = rate.init;
			alpha = alpha.init;
		}

		headliner.onDraw(info.screen);

		/* K2C */
		if ( timer.get() - step_start_time > (LC_STEP_TIME / 2) ) {
			if (alpha > 0 && rate > 0.0f) {
				int x = ( info.screen.getWidth() - cast(int) (t_Kyojintachi.getWidth() * rate) ) / 2;
				int y = ( info.screen.getHeight() - cast(int) (t_Kyojintachi.getHeight() * rate) ) / 2;
				
				info.screen.setColor(255, 255, 255, alpha);
				info.screen.bltRotate(t_Kyojintachi, x, y, 0, rate, 0);	// 描画	
				
				alpha -= alphaCount;
				rate -= 0.003f;		
			}
		}

		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}

	/// K2Cタイトル	
	void step111() {
		static const int LC_STEP_TIME = 6900;
		static const int alphaCount = 4;
		static int counter = 0;
		static float rate = 1.0f;
		static int alpha = 255;
		
		if (newstep) {
			counter = counter.init;
			rate = rate.init;
			alpha = alpha.init;
		}

		headlineK2C.onDraw(info.screen);
		
		if ( timer.get() - step_start_time > (LC_STEP_TIME / 2) ) {
			if (alpha > 0 && rate > 0.0f) {

				int x = ( info.screen.getWidth() - cast(int) (t_K2Cex.getWidth() * rate) ) / 2;
				int y = ( info.screen.getHeight() - cast(int) (t_K2Cex.getHeight() * rate) ) / 2;
				
				info.screen.setColor(255, 255, 255, alpha);
				info.screen.bltRotate(t_K2Cex, x, y, 0, rate, 0);	// 描画	
				
				alpha -= alphaCount;
				rate -= 0.003f;		
			}
		}
		
		if( timer.get() - step_start_time > LC_STEP_TIME ) {
			nextStep();
		}
	}
	
	/// 開発スタッフ
	void step112() {
		static int counter = 0;
		if (newstep) {
			counter = counter.init;
		}
		
		// 背景描画
//		info.screen.blt(t_endBg, 0, 0);
		
		clock.setXY(-250, 300);
		
		// 時計描画
		clock.onMove(info.screen);
		clock.onDraw(info.screen);
		
		// 暗幕フィルタ
		
		info.screen.setColor( 0, 0, 0, 255 - alphaCounter.get() );
		
		// 上部非描画領域の区切り線描画
		info.screen.drawPolygon(
			0, 0,
			640, 0,
			640, 480,
			0, 480 );

		info.screen.setColor(255, 255, 255, alphaCounter.get() );
		// スタッフ描画
		info.screen.blt(t_endStaff, 0, 0);
		
		alphaCounter++;
		
		// フェードアウト
		if (counter == 200) {
			alphaCounter.set(200, 0, 120);
		} 

		++counter;
		
//		if ( alphaCounter.get() == 0 ) {
//			destroy();
//			info.gameSceneController.jumpScene(KyojinConst.Task.Task_Title);
//			info.mouse.show();
//		}		
		
	}

	void step40() {
		dTDraw.onDraw(info.screen);
		carsor.onDraw(info.screen);
	}

	void step50() {
		breakDrop.onMove(info.screen);
		breakDrop.onDraw(info.screen);

		if (breakDrop.isFinish()) {
			Log.print("finished!");
		}
	}
	
	void step60() {
		static int phase = 0;
		static int add = 1;
		
		phase += add;
		if (phase > 255) {
			add = -1;
			phase = 255;
		} else if (phase < 0) {
			add = 1;
			phase = 0;
		}
		
		TransBltter.blt(19,info.screen,t_bg,0,0,phase);
	}
	
	void step70() {
		NoiseBltter.bltUnVerticalSync(info.screen,t_bg,0,0);
	}

	/// ステップ経過フレーム数から経過時間
	float stepFlameToSec() {
		return step_counter / 60.0f;
	}
	

private:
	GameInfo info;

	static const float ABEAT = 21.0f/45.0f;	//!< 一拍の秒数
	static float music_sync; 			//!< 60fps時、四分音符で何フレーム進行するか

	int step = 0;	//!< 状態
	Rand rand;
	SinTable st;
	FixTimer timer;
	Font font;

	Texture moji[3];	// テキスト表示テクスチャ

	Sound	bgm;		// BGM

	float movecounter = 0.0f;	//!< 開始時からのフレーム
	float step_start = 0.0f;	//!< 現在のステップの開始フレーム
	float step_counter = 0.0f;	//!< ステップ開始からのフレーム
	uint step_start_time;		//!< ステップの開始時の時間
	bool newstep;	//!< 新しいステップに入ったかのフラグ

	float sizecounter = 0.3;
	int lastpoint;

	int curtime;	// 現在の時間
	int sizex;
	int	sizey;
	Rect srcrect;
	
	int tx;
	float move = 0.0f;

	int faderate;
	int addfade;	// fade率
	bool replay;

	TextureLoader tl_bgStd;
	
	Texture t_toplogo;
	Texture t_title;
	Texture t_titlememo;
	Texture t_bg;
	Texture t_k;
	Texture t_2;
	Texture t_c;
	Texture t_noise;
	Texture t_ring;
	Texture t_ring2;
	Texture t_flare;
	Texture t_horizon;
	Texture t_unLight;
	
	Texture t_pole;
	Texture t_fader;
	Texture t_roleText;
	Texture t_halftone;
	Texture t_aliceEye;
	
	// 何のために生きるの？
	Texture t_faice;
	Texture t_ikiru;
	
	// --CUTIN
	Texture t_aliceUp;
	Texture t_bg1;
	
	// とみえたん
	Texture t_tomiSt;
	Texture t_tomiShade;
	
	// scene01 -- powered by [REVERSE](TUKIHIME)
	Texture t_bgEx;
	Texture t_aliceSt;
	Texture t_bgExZ;
	Texture t_midoSt;
	
	// テキスト
	Texture[] t_Text;
	
	// code
	Texture[] t_Code;
	Texture[] t_CodeZ;
	Texture t_aliceCode;
	Texture t_kyo;
	TextureLineNoise tln;
	
	// chara intro
	Texture[] t_face;
	Texture[] t_intro;
	TexutralTextDraw ttdraw;
	TextureLoader tl_bg;
	
	// flash
	Texture t_bgFullNoise;
	Texture[] t_shadows;
	
	// end-staff
	Texture t_endBg;
	Texture t_endStaff;
	InteriorCounter alphaCounter;
	
	MoveView mv;		// 背景ぶれ描画用クラス
	PromptCarsor carsor;	// 点滅するプロンプトカーソル
	ScreenFrame screenFrame;

	DizzyTextDraw dTDraw;	// 文字ランダム表示
	FontLoader 	fl;

	DropObjectManager sm;
	HexPropagate hp;
	FlashInText ft;
	ScatteredTexture breakDrop;
	CharaSprite chara;
	
	DecorativeColck clock;	//!< 時計
	// 背景描画用
	HexPropagate hexDrawer;
	// 去人たちタイトル
	SequentialDrawAlpha headliner;
	Texture t_Kyojintachi;
	// 団体名タイトル
	SlideInHeadlinear headlineK2C;
	Texture t_K2Cex;
	
	int progress = 0;

	// ----------------- LOADING IMG -------------------
	Texture m_loadbg;
	Texture[5] m_loadCheck;
	static int[][] m_checkPos = [
		[1,256,236],
		[78,259,269],
		[92,259,299],
		[95,260,328],
		[99,262,354]
	];
	const char[][] m_loadCheckFilename = [
		"img/load/c1.png",
		"img/load/c2.png",
		"img/load/c3.png",
		"img/load/c4.png",
		"img/load/c5.png"
	];
	
	Texture[][] m_number;
	Texture[] m_numbers1;
	Texture[] m_numbers2;
	Texture[] m_numbers3;

}
