//×田■＃－凹己▲員♀門
//0 1 2 3 4 5 6 7 8 9 A
 var
	WIN = window,
	D=document,
	DGI = new Function("return WIN.document.getElementById(arguments[0]);"),
	DGT = new Function("return WIN.document.getElementsByTagName(arguments[0]);");
 var DA = null , DB = null,OP=false,WII = false;
 var VSCREEN_W = 640 , SCREEN_W = 640;
 var VSCREEN_H = 480 , SCREEN_H = 480;
 var STAGE_W = 640,STAGE_H = 480, FONT_SIZE = 32;
 var SPRITES_MAX = 256 , SOUNDS_MAX = 3;
 var SOUND_ENABLE = false;
 var IMAGEBASEDIR = "";
  if(location.toString().match(/(makimo\.to|jwm)/))
  		IMAGEBASEDIR = "http://www.janis.or.jp/users/segabito/ldm/";
 var mTimer = null,defInterval = 60,mTimerInterval = defInterval;
 var frameSkip = 1;
 var CGIPATH = "cgi";
 var SYSVER = 0x070425;

	D.onkeypress=function(){return false;};

 function initArea(area){
	 DB=area;
	 SCREEN_W = DB.clientWidth;
	 SCREEN_H = DB.clientHeight;
	 FONT_SIZE = Math.floor( SCREEN_H / 24 );
 } //

 function initSys(){
	init();
	mTimer = setTimeout("onMTimer()",mTimerInterval);
	D.onkeydown=onKeyDown;
	D.onkeyup  =onKeyUp;
	dummyFocus();
 } //
 
 function quitSys(){
	quit();
 } //
 
 var fcnt=0;
 function onMTimer(){
	action();
//	screen.updateInterval=5000;
	if( fcnt++ % frameSkip == 0 )draw();
//	screen.updateInterval=0;

	clearTimeout(mTimer);
	mTimer = setTimeout("onMTimer()",mTimerInterval);
 } //

 var DEBUGMODE=false;



 function WiiCode(v){
	WiiCode.isWii = navigator.userAgent.match(/nintendo wii/i);

	WiiCode.minus = 170;
	WiiCode.plus  = 174;
	WiiCode.bt1   = 172;
	WiiCode.bt2   = 173;
	WiiCode.btA   = 13;
	WiiCode.btB   = 171;

	if(v==1){
		WiiCode.up    = 175;
		WiiCode.rt    = 177;
		WiiCode.dn    = 176;
		WiiCode.lt    = 178;
	}else{
		WiiCode.up    = 177;
		WiiCode.rt    = 176;
		WiiCode.dn    = 178;
		WiiCode.lt    = 175;
	}
 }
 WiiCode(0);





 if(document.all && ( navigator["app"+"Name"] + "").toString().match(/Microsoft/i) ){
	if( !window.opera)DA = D.all;
	else{
		DG = D.getElementById;
		OP = true;
	}
 }else{
	DG = D.getElementById;
 }
	if(WiiCode.isWii)WII=true;
window.offscreenBuffering = true;

 function onKeyDown(e){
  var keyCode , srcElement , tagName;
  var shiftKey=false , altKey=false , ctrlKey=false;
 if(WII){
	keyCode = e.which;
//	var controllers = wii.controllers_;
 }else
 if(DA){
	keyCode=event.keyCode;
	srcElement=event.srcElement;
	tagName=event.srcElement.tagName;
	shiftKey= event.shiftKey;
	altKey  = event.altKey;
	ctrlKey = event.ctrlKey;
 }else{
	keyCode=e.keyCode;
	srcElement=e.target;
	tagName=srcElement.nodeName;
	shiftKey= e.shiftKey;
	altKey  = e.altKey;
	ctrlKey = e.ctrlKey;

 }
 if(tagName=="INPUT")return true;
 if(tagName=="TEXTAREA")return true;
 return keyDown(srcElement,keyCode,shiftKey,ctrlKey,altKey);
 } // end kDown

 function onKeyUp(e){
  var keyCode , srcElement , tagName;
  var shiftKey=false , altKey=false , ctrlKey=false;
 if(WII){
	keyCode = e.which;
//	var controllers = wii.controllers_;
 }else
 if(DA){
	keyCode=event.keyCode;
	srcElement=event.srcElement;
	tagName=event.srcElement.tagName;
	shiftKey= event.shiftKey;
	altKey  = event.altKey;
	ctrlKey = event.ctrlKey;
 }else{
	keyCode=e.keyCode;
	srcElement=e.target;
	tagName=srcElement.nodeName;
	shiftKey= e.shiftKey;
	altKey  = e.altKey;
	ctrlKey = e.ctrlKey;

 }
 if(tagName=="INPUT")return ture;
 if(tagName=="TEXTAREA")return true;
 return keyUp(srcElement,keyCode,shiftKey,ctrlKey,altKey);
 } // end kDown
function dummyFocus(){if(stageManager.replayMode)return;
	if(document.all){window.focus();}
	else
	if( DGI("dummyFocusArea") )
			DGI("dummyFocusArea").focus();
} //

//=========================================
//=========================================
//=========================================
 var gamePad1 = new GamePad() , gamePad2 = new GamePad() ;

function GamePad(){
	this.isGamePad = true;
	this.x=0;
	this.y=0;
	this.upFlag = false;
	this.dnFlag = false;
	this.rtFlag = false;
	this.ltFlag = false;
	this.buttons = Array(0,0,0,0,0);
	this.reset = function(){
		with(this){
			x=0;y=0;for(var i=0;i<buttons.length;i++)buttons[i]=0;
			upFlag = dnFlag = rtFlag = ltFlag = false;
		}
	}

	this.getPadState = function(){
		var tx=this.x+2,ty=this.y+2;
		var b1=(this.buttons[0]==0) ? 0 : 1;
		var b2=(this.buttons[1]==0) ? 0 : 1;
		var b3=(this.buttons[2]==0) ? 0 : 1;
		return	tx+
				ty*4+
				b1*16+
				b2*32 +
				b3*64 + 
				0;
	} //
	this.setPadState = function(s){
	 var t=parseInt(s);
		this.x=(t%4)-2;
		this.y=((parseInt(t/4)%4)-2);
		this.buttons[0]=parseInt(((t/16)%2));
		this.buttons[1]=parseInt(((t/32)%2));
		this.buttons[2]=parseInt(((t/64)%2));
	 return this.getPadState();
	} //

	this.getPadString = function (format){
		var t="";
		var tx=this.x+2;
		var ty=this.y+2;
		t=tx+""+ty;
		for(var i=0;i<this.buttons.length;i++)
			t+=(this.buttons[i]+2).toString();
	  return t;
	} //

	this.setPadString = function (s,format){
	 var str=s.toString();
		for(var i=2;i<str.length;i++)
			this.buttons[i-2]=parseInt(str.charAt(i))-2;
		this.x=parseInt(str.charAt(0))-2;
		this.y=parseInt(str.charAt(1))-2;
	 return this.getPadString(format);
	} //

	this.up = function(f){
		this.y = f ? -1 : (this.dnFlag ?  1 : 0);
		this.upFlag = f;
	}
	this.down = function(f){
		this.y = f ?  1 : (this.upFlag ? -1 : 0);
		this.dnFlag = f;
	}
	this.left = function(f){
		this.x = f ? -1 : (this.rtFlag ?  1 : 0);
		this.ltFlag = f;
	}
	this.right = function(f){
		this.x = f ?  1 : (this.ltFlag ? -1 : 0);
		this.rtFlag = f;
	}
} //

function InputRecorder(pad){
	var T = this;
	T.isInputRecorder = true;

	T.lastInput = 0;
	T.lastClock = 0;
	T.replayCnt = 0;
	T.hasNext = false;
	T.data = new Array();
	T.extMode = false;
	T.cr = 50;
	T.record = function(pad , tm){
	 with(this){
		var str = pad.getPadState();
		var s = Number(str);
		if(str >= 0x40)extMode = true;
		data[replayCnt++]=str;
		lastInput=s;
		lastClock=tm;
		return str;
	 }
	} //
	T.play = function(pad , tm){
	 with(this){
	  if(!hasNext)return pad.getPadState();
	  var t=data[replayCnt++];
		hasNext = (data[replayCnt]) ? true : false;
	 return (t).toString();
	 }
	} //

	T.getRecordData = function(){
	 with(this){
		data.unshift(0);
	    var tmp = new Array() , i = 0 , chk1 = data[1], chk2 = 0, cnt = 0;
		for(; i < replayCnt ; i++){
			chk2 = data[ i + 1 ];
			if(chk1 != chk2 || cnt >= 255){
				if(cnt > 1)
					tmp[i] = String.fromCharCode(chk1 + 0x3b) + cnt;
				else
					tmp[i] = String.fromCharCode(chk1 + 0x3b);
				cnt=1;
				chk1 = chk2;
			}else
				cnt++;
		}
		tmp[i] = String.fromCharCode(chk1 + 0x3b) + cnt;
		data.shift();
		var tmp2 = tmp.join(""),ret="";
		for(i = 0; i < tmp2.length ; i += cr ) ret += tmp2.substr(i,cr) + "\n";
		return ret;
	 }
	} //

	T.setRecordData = function(code){
	 with(this){
		data = new Array();
		var dat = code.replace(/[\t\r\n ]/g,'');
		var tmp = decompress(dat);
		for(var i = 0 ; i < tmp.length ; i++ )data[i]=tmp.charCodeAt(i) - 0x3b;
		hasNext = true;
	 }
	} //

	T.decompress = function(txt){
	 with(this){
		var tmp = new Array(256).join("#"),ch = new Array();
		for( var i = 0x40 ; i< (0x100 + 0x40) ; i++ )ch[i]=tmp.replace(/#/g,String.fromCharCode(i));
		txt = txt.replace(/([\x40-\xff\x0100-0140])([0-9]+)/g,
					function(a,b,c){return ch[b.charCodeAt(0)].substring(0,c)} );
		return txt;
	 }
	} //

} //



//=========================================
//=========================================
//=========================================
 var B_Blank   = 0x0000; // 0
 var B_Brick   = 0x0001; // 1
 var B_Rock    = 0x0002; // 2
 var B_Ladder  = 0x0004; // 3
 var B_Rope    = 0x0008; // 4
 var B_HHole   = 0x0010; // 5
 var B_HLadder = 0x0020; // 6
 var B_Gold    = 0x0040; // 7
 var B_Enemy   = 0x0080; // 8
 var B_Player  = 0x0100; // 9
 var B_Gate    = 0x0200; //10
 var B_MBlock  = 0x0400; //11
 var B_HEnemy  = 0x0800; //12
 var B_Net     = 0x1000; //13
 var B_Bomber  = 0x2000; //14
 var B_Explode = 0x4000; //15
 var B_Digger  = 0x8000; //16
 var B_Bonus   =0x10000; //17
 var B_Ghost   =0x20000; //18
  var B_Block  = B_Brick | B_Rock | B_Net |B_MBlock;
 


 function ISize(ww,hh){
	this.width  = 32;
	this.height = 32;
 }
 function IPosition(T){
	T.isIPosition = true;
	T.x = 0;
	T.y = 0;
	T.z = 0;
	T.width  = 32;
	T.height = 32;
	T.getX = _getX;
	T.getY = _getY;
	T.getWidth  = _getWidth;
	T.getHeight = _getHeight;
	T.setX = _setX;
	T.setY = _setY;

	function _getX(){return this.x;}
	function _getY(){return this.y;}
	function _getCX(){return this.x + this.width  / 2;}
	function _getCY(){return this.y + this.height / 2;}
	function _getWidth(){return this.width;}
	function _getHeight(){return this.height;}
	function _setX(xx){this.x = xx;}
	function _setY(yy){this.y = yy;}

	T._func = function(){return false;}
 } //
 function ICharacter(T,stg){
	IPosition(T);
	T.isICharacter = true;
	T.life = 1;
	T.score = 0;
	T.goldCnt = 0;
	T.walkSpeed = 4;
	T.fallSpeed = 4;
	T.xMove = 0;
	T.yMove = 0;
	T.action = T._func;
	T.draw   = T._func;
	T.moveTo = T._func;
	T.moveBy = T._func;
	T.kill   = T._func;
	T.mind   = 0;
	T.image = "img/undefined.gif";

	T.master = "";
	T.setMaster = function(m){this.master=m;}
	T.group = "";
	T.setGroup  = function(g){this.group=g;}

	T.collision  = function(obj){
		//if(!obj.isICharacter)return false;
		with(this){
//			if( Math.abs( x - obj.x ) > width  ) return false;
//			if( Math.abs( y - obj.y ) > height ) return false;
			if(	( x + width  < obj.x )     ||
				( x > obj.x  + obj.width ) ||
				( y + height < obj.y )     ||
				( y > obj.y  + obj.height ) 
			) return false;
			return true;
		}
	}
	T._collision = T.collision;

	T.pointCollision  = function(xx,yy){//if(!obj.isICharacter)return false;
		with(this){
			if( Math.abs( x - xx ) > width  ) return false;
			if( Math.abs( y - yy ) > height ) return false;
			return true;
		}
	}
	T._pointCollision = T.pointCollision;

	T.onCollided = T._func;

	T.stage = stg;
	T.setStage = function(stg){this.stage = stg;}
	
	T.getBX = function(){
		return Math.floor((this.x + 16 ) / 32);
//		return Math.floor((this.x + 16 ) / this.stage.blockSize);
	}
	T.getBY = function(){
		return Math.floor((this.y + 16 ) / 32);
	}

	function _setGroup(obj){this.myGroup = obj;}

 } //
 
 function ISpriteControl(T){
	T.isISpriteControl = true;
	T.sprite = new Sprite();
	T.sprite.setVisibility(true);

	T.moveTo = _moveTo;
	T.moveBy = _moveBy;
	T.setZ = _setZ;

	T.flipV = false;
	T.flipH = false;
	T.opacity = 100;

	T.setFlipV = _setFlipV;
	T.setFlipH = _setFlipH;
	T.setOpacity = _setOpacity;

	T.draw = _draw;
	T.kill = _kill;
	T.updateSprite = _updateSprite;

	function _moveTo(xx,yy){
		this.x = xx;this.y = yy;
		this.sprite.moveTo(xx,yy);
	}
	function _moveBy(xx,yy){
		this.moveTo(this.x + xx,this.y + yy);
	}
	function _setZ(zz){
		this.z = zz;
		this.sprite.setZ(zz);
	}
	function _setFlipV(f){
		this.flipV = f;
		this.sprite.setFlipV(f);
	}
	function _setFlipH(f){
		this.flipH = f;
		this.sprite.setFlipH(f);
	}
	function _setOpacity(o){
		this.opacity = o;
		this.sprite.setOpacity(o);
	}

	function _draw(){
		this.sprite.draw();
	}
	function _updateSprite(){
		if(this.sprite.alive >0)this.sprite.update(true);
	}
	function _kill(){
		this.life=-1;
		return this.sprite.kill();
	}
 } //

 
 function ICharacterGroup(){
	var T = this;
	T.isICharacterGroup = true;
	T.members = new Array();
	T.getMembers = function(){return this.members;}
	T.action = function(){
		with(this){
			for(var i = members.length -1 ; i >= 0 ; i-- ){
				if(members[i].life > 0)
						members[i].action();
				else
					members.splice(i,1);
			}
		}
	}
	T.draw = function(){
		with(this){
			for(var i = members.length -1 ; i >= 0 ; i-- ){
				if(members[i].life > 0)
						members[i].draw();
			}
		}
	}
	T.updateSprite = function(){
		with(this){
			for(var i = members.length -1 ; i >= 0 ; i-- ){
				if(members[i].life > 0)members[i].updateSprite();
			}
		}
	}
	T.add = function(obj){
	 	with(this){
			if(!obj.isICharacter)return false;
			for(var i = members.length -1 ; i >= 0 ; i-- ){
				if(members[i] == obj)return false;
			}
			members.unshift(obj);
			obj.setGroup(this);
			return true;
		}
	}
	T.remove = function(obj){
	 	with(this){
			if(!obj.isICharacter)return false;
			for(var i = members.length -1 ; i >= 0 ; i-- ){
				if(members[i] == obj){
					members[i].splice(i,1);
					obj.setGroup(null);
					return true;
				}
			}
			return false;
		}
	}
	T.clear = function(){this.members = new Array();}
	T.collision = function(obj){
	 with(this){
		if(obj.isICharacter){
			for(var i = members.length - 1 ; i >= 0 ; i-- ){
					if(members[i] == obj)continue;
						if(members[i].collision(obj)){
							//members[i].onCollided(obj);
							obj.onCollided(members[i]);
						}
						
			}
		}else
		if(obj.isICharacterGroup){
			var mm = obj.getMembers();
			for(var i = mm.length - 1 ; i >= 0 ; i-- )collision(mm[i]);
		}
	 }
	}
	T.pointCollision = function(xx,yy){
	 with(this){
		for(var i = members.length - 1 ; i >= 0 ; i-- ){
					if(members[i].pointCollision(xx,yy))return true;
		}
		return false;
	 }
	}
 } //

//=========================================
//=========================================
//=========================================
 function StageImages(){
	StageImages.B_Blank = "";
	StageImages.B_Brick = "img/block1.gif";
	StageImages.B_Rock  = "img/block2.gif";
	StageImages.B_Ladder = "img/ladder.gif";
	StageImages.B_Rope  = "img/rope.gif";
	StageImages.B_HHole = "img/block1.gif";
	StageImages.B_HHole2 = "img/hhole.gif";
	StageImages.B_HLadder = "";
	StageImages.B_Gold  = "img/gold.gif";
	StageImages.B_Player = "";//"img/plStart.gif";
	StageImages.B_Enemy  = "";//"img/rbStart.gif";
	StageImages.B_Digger = "";//"img/block1.gif";
	StageImages.B_Gate  = "img/gate.gif";
	StageImages.B_MBlock = "img/mblock.gif";
	StageImages.B_Bonus = "img/bonus.gif";
 } //
 StageImages();
 function PlayerImages(){
	PlayerImages.standL		= "img/plStandL.gif";
	PlayerImages.standR		= "img/plStandR.gif";
	PlayerImages.standMoveL	= "img/plStandMoveL.gif";
		PlayerImages.standMoveL0	= "img/plStandMoveL0.gif";
		PlayerImages.standMoveL1	= "img/plStandMoveL1.gif";
		PlayerImages.standMoveL2	= "img/plStandMoveL2.gif";
		PlayerImages.standMoveL3	= "img/plStandMoveL1.gif";
	PlayerImages.standMoveR	= "img/plStandMoveR.gif";
		PlayerImages.standMoveR0	= "img/plStandMoveR0.gif";
		PlayerImages.standMoveR1	= "img/plStandMoveR1.gif";
		PlayerImages.standMoveR2	= "img/plStandMoveR2.gif";
		PlayerImages.standMoveR3	= "img/plStandMoveR1.gif";
	PlayerImages.standDigL	= "img/plStandDigL.gif";
	PlayerImages.standDigR	= "img/plStandDigR.gif";
	PlayerImages.ropeL		= "img/plRopeL.gif";
	PlayerImages.ropeR		= "img/plRopeR.gif";
	PlayerImages.ropeMoveL	= "img/plRopeMoveL.gif";
		PlayerImages.ropeMoveL0	= "img/plRopeMoveL0.gif";
		PlayerImages.ropeMoveL1	= "img/plRopeMoveL1.gif";
		PlayerImages.ropeMoveL2	= "img/plRopeMoveL2.gif";
		PlayerImages.ropeMoveL3	= "img/plRopeMoveL1.gif";
	PlayerImages.ropeMoveR	= "img/plRopeMoveR.gif";
		PlayerImages.ropeMoveR0	= "img/plRopeMoveR0.gif";
		PlayerImages.ropeMoveR1	= "img/plRopeMoveR1.gif";
		PlayerImages.ropeMoveR2	= "img/plRopeMoveR2.gif";
		PlayerImages.ropeMoveR3	= "img/plRopeMoveR1.gif";
	PlayerImages.ropeDigL	= "img/plRopeDigL.gif";
	PlayerImages.ropeDigR	= "img/plRopeDigR.gif";
	PlayerImages.ladder	= "img/plLadder.gif";
	PlayerImages.ladderMove	= "img/plLadderMove.gif";
		PlayerImages.ladderMove0	= "img/plLadderMove0.gif";
		PlayerImages.ladderMove1	= "img/plLadderMove1.gif";
		PlayerImages.ladderMove2	= "img/plLadderMove2.gif";
		PlayerImages.ladderMove3	= "img/plLadderMove1.gif";
	PlayerImages.ladderDigL	= "img/plLadderDigL.gif";
	PlayerImages.ladderDigR	= "img/plLadderDigR.gif";
	PlayerImages.fallL		= "img/plFallL.gif";
		PlayerImages.fallL0		= "img/plFallL.gif";
		PlayerImages.fallL1		= "img/plFallL.gif";
		PlayerImages.fallL2		= "img/plFallL.gif";
		PlayerImages.fallL3		= "img/plFallL.gif";
	PlayerImages.fallR		= "img/plFallR.gif";
		PlayerImages.fallR0		= "img/plFallR.gif";
		PlayerImages.fallR1		= "img/plFallR.gif";
		PlayerImages.fallR2		= "img/plFallR.gif";
		PlayerImages.fallR3		= "img/plFallR.gif";
	PlayerImages.dieL		= "img/plDie.gif";
	PlayerImages.dieR		= "img/plDie.gif";
	PlayerImages.DiggerEffect = "img/fireball.gif";
	PlayerImages.gate	= "img/plLadder.gif";
	
	PlayerImages.plStandKickL = "img/plKickL.gif";
	PlayerImages.plStandKickR = "img/plKickR.gif";
	PlayerImages.bomber  = "img/bomberA.gif";
	PlayerImages.bomberB = "img/bomberB.gif";
	PlayerImages.explosion = "img/explosion.gif";
 } //
 PlayerImages();
 function RobotImages(){
	RobotImages.standL		= "img/rbStandL.gif";
	RobotImages.standR		= "img/rbStandR.gif";
	RobotImages.standMoveL	= "img/rbStandMoveL.gif";
		RobotImages.standMoveL0	= "img/rbStandMoveL0.gif";
		RobotImages.standMoveL1	= "img/rbStandMoveL1.gif";
		RobotImages.standMoveL2	= "img/rbStandMoveL2.gif";
		RobotImages.standMoveL3	= "img/rbStandMoveL1.gif";
	RobotImages.standMoveR	= "img/rbStandMoveR.gif";
		RobotImages.standMoveR0	= "img/rbStandMoveR0.gif";
		RobotImages.standMoveR1	= "img/rbStandMoveR1.gif";
		RobotImages.standMoveR2	= "img/rbStandMoveR2.gif";
		RobotImages.standMoveR3	= "img/rbStandMoveR1.gif";
	RobotImages.ropeL		= "img/rbRopeL.gif";
	RobotImages.ropeR		= "img/rbRopeR.gif";
	RobotImages.ropeMoveL	= "img/rbRopeMoveL.gif";
		RobotImages.ropeMoveL0	= "img/rbRopeMoveL0.gif";
		RobotImages.ropeMoveL1	= "img/rbRopeMoveL1.gif";
		RobotImages.ropeMoveL2	= "img/rbRopeMoveL0.gif";
		RobotImages.ropeMoveL3	= "img/rbRopeMoveL1.gif";
	RobotImages.ropeMoveR	= "img/rbRopeMoveR.gif";
		RobotImages.ropeMoveR0	= "img/rbRopeMoveR0.gif";
		RobotImages.ropeMoveR1	= "img/rbRopeMoveR1.gif";
		RobotImages.ropeMoveR2	= "img/rbRopeMoveR0.gif";
		RobotImages.ropeMoveR3	= "img/rbRopeMoveR1.gif";
	RobotImages.ladder		= "img/rbLadder.gif";
	RobotImages.ladderMove	= "img/rbLadderMove.gif";
		RobotImages.ladderMove0	= "img/rbLadderMove0.gif";
		RobotImages.ladderMove1	= "img/rbLadderMove1.gif";
		RobotImages.ladderMove2	= "img/rbLadderMove2.gif";
		RobotImages.ladderMove3	= "img/rbLadderMove1.gif";
	RobotImages.fallL   = "img/rbFallL.gif";
		RobotImages.fallL0   = "img/rbFallL.gif";
		RobotImages.fallL1   = "img/rbFallL2.gif";
		RobotImages.fallL2   = "img/rbFallL.gif";
		RobotImages.fallL3   = "img/rbFallL2.gif";
	RobotImages.fallR   = "img/rbFallR.gif";
		RobotImages.fallR0   = "img/rbFallR.gif";
		RobotImages.fallR1   = "img/rbFallR2.gif";
		RobotImages.fallR2   = "img/rbFallR.gif";
		RobotImages.fallR3   = "img/rbFallR2.gif";
	RobotImages.dieL   = "img/rbDieL.gif";
	RobotImages.dieR   = "img/rbDieR.gif";
 } //
 RobotImages();
 function EventWord(){
	EventWord.otosiana="!?";
	EventWord.goal="脱出！";
	EventWord.last1="あと１個！";
	EventWord.gotoGoal="脱出するモナ！";
	EventWord.input="セリフを入力 (HTMLタグも使用可能)";
	EventWord.num1="オマエモナー";
	EventWord.num2="∧＿∧<br>(　´∀｀)";
	EventWord.num3="○|￣|＿　";
	EventWord.num4="(　´Д｀) <span style=\"font-family:戦国TURB,へた字\">もうだめぽ</span> ";
	EventWord.num5="逝ってよし！( ﾟДﾟ)";
	EventWord.num6="m9(^Д^)";
	EventWord.num7="(;´∀｀)あぶなかった";
	EventWord.num8="箱は(・∀・)ｶｴﾚ！";
	EventWord.num9="(・ｘ・)";
	EventWord.num0="＼(^o^)／";
	EventWord.damepo1="<span style=\"font-family:'戦国TURB'\">もうだめぽ</span>";
	EventWord.damepo2="・・・。";
	EventWord.damepo3="∧＿∧<br>(－_－)<br>(∩ ∩)";
	EventWord.damepo4="∧＿∧<br>(－_－) ｵﾜﾀ…。<br>(∩ ∩)";
	EventWord.damepo5="[DEL]キーでギブアップします";
	EventWord.pinch1="[　ﾟДﾟ])´A｀)[ﾟДﾟ　]";
	EventWord.pinch2="(；´∀｀)";
	EventWord.atamakin="♪～";
	EventWord.kumaBonus="クマ～♪";
	EventWord.mugyu="むぎゅっ＞＜";
	EventWord.mugyu2="[ﾟД｡]";
	EventWord.jama="(＞＜)";
	EventWord.kakure="！";
	EventWord.ngWord="ぬるぽ";
	EventWord.tukkomi="ガッ！";
	
	EventWord.kick999="x999";
	EventWord.kick5="x5";
	EventWord.kick1="x1";
	EventWord.startWord="スタート";
	EventWord.replayWord="リプレイ：";
	EventWord.pauseWord="* P A U S E *";
 }
 EventWord();

 function onCacheRead(){
	imageCacheManager.onCacheRead();
 }//
 function onCacheError(){
	imageCacheManager.onCacheError();
 }//
 function ImageCacheManager(){
	var T= this;
	T.complete = false;
	T.chk = "";
	T.img = [];
	T.imgCnt = 0;
	T.completeHandler = new Array();
	
	T.set = function(obj){
		var t="";
		var baseDir = IMAGEBASEDIR;
		 if(!baseDir)baseDir = "";
		for(var v in obj){
			var s = obj[v].toString();
			if(s.match(/\.(jp?g|gif|bmp|tif|png|mng)$/)){
				s = baseDir + s;
				if( !this.img[s] ){
					var im = new Image(32,32);
					im.onload = onCacheRead;//function(){ImageCacheManager.instance.onCacheRead();this.onload=null;}
					im.onerror= onCacheError;//function(){ImageCacheManager.instance.onCacheError();this.onerror=null;}
					im.src = s;
					this.img[s] = im;
					im.loop=1;
					this.chk += s + "\t";
					this.imgCnt++;
				}
			}
		}
	}

	T.onCacheRead = function(){
		with(this){
			imgCnt--;
			if(imgCnt <= 0)onCacheComplete();
		}
	} //
	T.onCacheError = function(){
		with(this){
			imgCnt--;
			if(imgCnt <= 0)onCacheComplete();
		}
	} //

	T.onCacheComplete = function(){
		with(this){
			if(complete == true)return;
			complete = true;
			for(var i = 0; i < completeHandler.length ; i++ )
						completeHandler[i].onCacheComplete(this);
			for(var v in img){
				img[v].onload=null;
				img[v].onerror=null;
				//img[v].src=UNDEF_GIF;
			}
		}
	}
	T.addHandler = function(obj){
		if(obj.onCacheComplete){
			this.completeHandler.push(obj);
		}
	}
	T.getCache = function(src){
		if(this.img[src]){
			return this.img[src];
		}
	}
	if(!imageCacheManager)imageCacheManager = this;
 } //
 
 function Player(stg,xx,yy){
	var T=this;
	T.isPlayer = true;
	ICharacter(T,stg);
	ISpriteControl(T);
	
	
	T.startX = T.x = xx;
	T.startY = T.y = yy;
	T.walkSpeed = 8;
	T.fallSpeed = 8;
	T.xMove = 0;
	T.yMove = 0;
	T.gamePad = null;
	T.height = 32;
	T.image = PlayerImages.fallR;
	T.sprite.setImage(T.image,32,48);
	T.sprite.setVisibility(true);
	T.moveTo(xx,yy);
	T.setZ(120);
	T.dead = false;
	
	T.mind = B_Player;
	
	T.setGamePad   = function(pad){this.gamePad   = pad;}
	
	T.digger = null;
	T.bomber = "";
	T.btnCnt = 0;

	T.ropeFlag = false;
	T.ladderFlag = false;
	T.fallFlag = false;
	T.stepFlag = true;
	T.goalGateFlag = false;
	T.ladderBugFlag=false;
	T.hFace = 1;
	T.vFace = 0;
	T.mugyu=false;

	T.fukidashi = new Fukidashi(stg,xx,yy);
	T.fukidashi.setMaster(this);
	T.damepoCnt=0;
	T.hoverCnt=0;
	T.animCnt=0;

	T.init = function(){
		with(this){
			life = 1;
			dead = false;
		}
	}

	T.actionCnt=0;
	T.action = function(){
	 with(this){
		actionCnt++;
		if(actionCnt == 1)speak(stage.startWord);
		if(digger)	diggerAction();
		else		walkAction();
		checkDamepo();
		fukidashi.action();
	 }
	}

	var lastxm=0,lastym=0;
	T.walkAction = function(){ //plwalk
	 with(this){
		var xm = gamePad.x , ym = gamePad.y , dm = 0 ,gmode=stage.gameMode;

		var bSize = stage.blockSize,xs = x % bSize , ys = y % bSize;
		var centerX = x + width / 2 , centerY = y + height / 2,bottomY = y + height - 1;
		var cb = stage.getXYPointBlock(centerX , centerY );
		var fb = stage.getXYPointBlock(centerX , y + height + ( ym - 1) );
		var kickFlag= false;

		hoverCnt--;
		if(xm != 0)hFace = xm;// 顔の向き
		else hoverCnt=-1;
		fallFlag = ropeFlag = false;

		if(gmode == GameMode.PC){ //走りっぱなし
			if(xm==0)xm = lastxm;if(ym==0)ym = lastym;
			if(gamePad.x!=0)lastym=ym=0;if(gamePad.y!=0)lastxm=xm=0;
			lastxm=xm;lastym=ym;
			if(gamePad.buttons[2]!=0)xm=ym=lastxm=lastym=0;
		}

		if(xm != 0){ //横移動判定
			var xp = x + ((xm > 0) ? width : -1);
			var b = stage.getXYPointBlock( xp , centerY );
			if( stage.isWallB(b) ){
				xm = 0;
				if(xs==0 && gmode!= GameMode.BBR && (b & B_Bomber) !=0)kickFlag = true;
			 if( ys == 16 || ys == 24){ // ブロックの境目にいる
				var hb = stage.getXYPointBlock( xp , y - walkSpeed*2 ) & ~B_Bomber;
				if( !stage.isWallB(hb) && ym < 1)ym = -1;
			 }
			}
		}
		if(!stage.isLadder(cb | fb) && (fb & B_Enemy)==0)ladderFlag = false;
		if(ym!=0){ //縦移動判定
			if(stage.isLadder(cb | fb))ladderFlag = true;
			else
			if(stage.isEnemy(fb) && ym > 0)ladderFlag = true;
			if(xs == 16 && !ladderFlag){//梯子補正
				var lhb = stage.getXYPointBlock(centerX-walkSpeed,y-walkSpeed);
				var lb = stage.getXYPointBlock(centerX-walkSpeed,centerY);
				if(stage.isLadder(lb) && xm < 1){
					//ladderFlag = true;
					xm = -1;ym=0;
				}
			}
			if(!ladderFlag && ym < 0 )ym = 0;

			var yp = y + ((ym > 0) ? height : -1);
			var b = stage.getXYPointBlock(centerX , yp);
			if( ym > 0 ) b = b & ~(B_HHole | B_Enemy);
			if( stage.isWallB(b) ){
//				if(xs == 16){ //動き補正
//				 var flb=stage.getXYPointBlock( x-walkSpeed , yp );
//				 if( !stage.isWallB(flb) && xm < 1 ){}//xm = -1;
//				 else	ym = 0;
//				}else
					ym = 0;
			}
			if(ym!=0)xm=0;
		}
		if(!ladderFlag && hoverCnt<0){ //落下判定
			var ffb = stage.getXYPointBlock(centerX, y + height);
			if(stage.magicHand == 1 || gmode == GameMode.IMode || gmode==GameMode.GBA){
				var ee =stage.getXYPointBlock(x,y+height) |
						stage.getXYPointBlock(x+width-1,y+height);
				ee = ee & (B_Enemy|B_MBlock|B_Bomber);
				ffb = ffb | ee;
			}

			if( stage.isLadder(cb))ladderFlag = true;
			else
			if( stage.isFloor(ffb) && stage.isRope(cb) && ym>0){//&& gmode==GameMode.GBA){
				ropeFlag=false;
			}else
			if( ym<=0 && stage.isRope(cb) && ys==0){
				ropeFlag = true;
				y = Math.floor(y / bSize)*bSize;
			}else
			if(stage.isFloor(ffb)){
				//if(ys<16)y = Math.floor(y / bSize) * bSize;
				//if(xs == 16 && xm < 1){var fflb = stage.getXYPointBlock(centerX-1, y + height);}
			}else{
				ym=xm=0;
				dm=1;
				fallFlag=true;
			}
		}

		// 穴掘る？
		if( (gamePad.buttons[0] != 0 || gamePad.buttons[1] != 0) && dm == 0	){
			var mx = Math.floor( centerX / bSize ),by = getBY();
			var fx = centerX + ((gamePad.buttons[0] != 0) ? -width : +width );
			var fy = centerY + height;
			 var ffb = stage.getXYPointBlock(fx,fy);
//			hoverCnt=-1;
			 if( stage.isBrick(ffb) ){
				var tb = stage.getXYPointBlock(fx,centerY);
				if(gmode == GameMode.IMode){// 携帯版では埋まった敵の下を掘れる
					if( (tb & B_Digger) != 0)tb = tb & ~B_Enemy;
				}
				if(gmode == GameMode.BBR)tb = tb & ~B_Bomber;
				if( stage.isBlank(tb) ){
					hFace = (gamePad.buttons[0] != 0) ? -1 : 1;
					x = mx * bSize;
					digger = stage.createDigger(this,Math.floor(fx / bSize),Math.floor(fy / bSize));
						y = getBY() * bSize;
						lastxm=lastym=xm = ym = 0;
						ladderBugFlag=false;
				}
			}
		}

		//ボンバー＆キック
		 if( gamePad.buttons[2] != 0 )btnCnt++;
		 if((gamePad.buttons[2] == 0 && btnCnt>1 && btnCnt<8)|| btnCnt==8 ||kickFlag){
			var bx = getBX() , by = getBY();
			var hb = stage.getXYBlock(bx + hFace , by);
			if( (hb & (B_Block | B_Bomber)) == 0 ){
			 x = bx * bSize;
			 ladderBugFlag=false;
			if((!bomber || !bomber.busy) && !kickFlag)
				bomber = stage.createBomber(this , bx + hFace, by , btnCnt > 4);
			}else{
				if(gmode== GameMode.BBR)
					stage.kickBlock(this,bx + hFace , by , btnCnt);
				else
				if(!fallFlag && !ropeFlag && ym==0 && ys==0)
					stage.kickBlock(this,bx + hFace , by , 1);
			}
		 }
		 if(gamePad.buttons[2] == 0)btnCnt = 0;

		xMove = xm * walkSpeed;
		yMove = ym * walkSpeed+ dm * fallSpeed;
		x += xMove;y += yMove;
//*
		// 位置補正
		if(xMove != 0 && y % bSize != 0){
			var xp = x + ((xMove>0) ? width :-1);
			var hp = stage.getXYPointBlock(xp,y);
			var fp = stage.getXYPointBlock(xp,y+height-1);
			if(((hp|fp)&(B_Block|B_Bomber|B_HHole|B_Ladder|B_Rope) )!=0 || gmode!=GameMode.GBA)
							y += walkSpeed*((y % bSize < 16 ) ? -1 : 1);
		}else
		if(yMove != 0 && x % bSize != 0)x += walkSpeed*(( x % bSize < 16 ) ? -1 : 1);
//*/
		if( x % bSize == 0 && y % bSize == 0 ){
			if( stage.isGold(cb) )getGold();
			if( stage.isBonus(cb))getBonus();
			if( stage.isGate(cb) )goalGateFlag = true;
		}



		var lr = (hFace == 1) ? "R" : "L";
		var mv = (xMove == 0 && yMove == 0) ? '' : 'Move';
		var cm='';
		if(mv!=''){
			animCnt = (animCnt + 10) % 40;
			cm = Math.floor(animCnt / 10);
		}

		if( xMove==0 && yMove<0 && y%bSize==8)ladderBugFlag=true;
		else if(mv!="")ladderBugFlag=false;

		if( xMove != 0 && yMove==0){ ladderFlag = false;fallFlag=false; }
		if(dead)image = PlayerImages["die" + lr];
		else	if(goalGateFlag)image = PlayerImages["gate"];
		else	if(fallFlag)	image = PlayerImages["fall" + lr + cm];
		else	if(ropeFlag)	image = PlayerImages["rope" + mv + lr + cm];
		else	if(ladderFlag)	image = PlayerImages["ladder" + mv +cm];
		else					image = PlayerImages["stand" + mv + lr + cm];
	 }
	} //


	T.diggerAction = function(){
		with(this){
			if(!digger.busy){
				digger = null;
				walkAction();
				return;
			}

			var lr = (hFace == 1) ? "R" : "L";
			var bx = getBX(),by=getBY();

			if(dead)image = PlayerImages["die" + lr];
			else	if(ropeFlag)	image = PlayerImages["ropeDig" + lr];
			else	if(ladderFlag)	image = PlayerImages["ladderDig" + lr];
			else	image = PlayerImages["standDig" + lr];
		}
	} //
	T.checkDamepo = function(){
		with(this){
		 var bx = getBX(), by = getBY(),bs=stage.blockSize;
		 var cb = stage.getXYBlock(bx,by);
		 var lb = stage.getXYBlock(bx-1,by);
		 var rb = stage.getXYBlock(bx+1,by);
		 var fb = stage.getXYBlock(bx,by+1);
		 if( !ladderFlag && x%bs===0 && y%bs==0 &&
			((lb&(B_Block|B_HHole))!=0) &&	((rb&(B_Block|B_HHole))!=0) &&
			 (fb &  B_Block ) != 0
		 ){
			damepoCnt++;
		  if(damepoCnt >= 10 && stage.gameMode!=GameMode.BBR){
			var dp = damepoCnt % 100;
			if(dp == 10 )
				speak(EventWord.damepo1);
			else
			if(dp == 20 )
				speak(EventWord.damepo2);
			else
			if(dp == 40 )
				speak(EventWord.damepo3);
			else
			if(dp == 70 )
				speak(EventWord.damepo4);
			else
			if(dp == 80 )
				speak(EventWord.damepo5);
		  }
		 }
		 if(cb == B_HHole && fallFlag && y % 16 == 0){
				speak("!?");
				stage.updateHHole(getBX(),getBY());
		 }
		 
		 if( ((cb & B_Enemy) != 0) && (((lb|rb) & B_Enemy) != 0) )
				speak(EventWord.pinch1,0);
		 if(!fallFlag && (lb&B_Enemy) != 0 &&  (rb&B_Enemy) != 0)
				speak(EventWord.pinch2,0);
		}
	} //

	T.getGold = function(){
		with(this){
			 var bx = getBX(), by = getBY();
			 var fb = stage.getXYBlock(bx,by+1);
			 goldCnt++;
			if( (fb & ( B_Enemy)) != 0)speak(EventWord.atamakin);
			stage.getGold(this);
		}
	}
	T.getBonus = function(){
		with(this){
			speak(EventWord.kumaBonus);
			goldCnt+=stage.getBonus(this);
		}
	}

	T.onCollided = function(obj){ // plcoll
		with(this){
		var pbx = getBX() , pby = getBY();
		var bx = obj.getBX() , by = obj.getBY();
		 if(obj.mind == B_Enemy ){
			if(stage.ladderBugEnable>0&&ladderBugFlag){
				return;
			}
			if(
				(obj.resurrectCnt <= 1 ) ||
				((stage.gameMode== GameMode.FC || stage.gameMode== GameMode.DS))
				){
				var cb = stage.getXYBlock( pbx , pby );
				var ox = obj.getX(),oy=obj.getY();
				if(pbx == bx && pby < by && stage.magicHand==1){
					if( stage.isGold(cb))getGold();
				}
				 if(Math.abs(x - ox) <= width/2){
//					if(gamePad.x<0 && x%stage.blockSize>=16)hoverCnt=3;
					if(gamePad.x<0 && oy>y && obj.xMove!=0)hoverCnt=2;
						
					if(oy - y > height / 2 && !ladderFlag){
						if(fallFlag && gamePad.x!=0)y = obj.getY()-height;//y = pby*stage.blockSize;
//						if(fallFlag)y = obj.getY()-height;//pby*stage.blockSize;
						return;//頭上にいる
					}
					if(oy - y >= height / 2 && fallFlag)return;
					if(by == pby)giveup();
				 }
			}
		 }else
		 if( obj.mind == B_Digger ){
			if(bx==pbx && by == pby){
				if(stage.ladderBugEnable>1&&ladderBugFlag){
					stage.setXYBlock(pbx,pby,B_Blank,1);
					return;
				}
				giveup();
			}else
			if(pby<by)y = pby*stage.blockSize;
		 }else
		 if( obj.mind == B_MBlock ){
			if(bx == pbx){
				var xd = obj.getY() - y;
				 if(xd==-height){speak(EventWord.mugyu);mugyu=true;sprite.setSize(32,32);}
				if(by == pby){
				 if(xd >-height/2){
					sprite.setSize(width,12);
					giveup();
				 }
				}
			}else{
			}
		 }
		}
	}


	T.giveup = function(){
		with(this){
			dead = true;
			var lr = (hFace == 1) ? "R" : "L";
			image = PlayerImages["die" + lr];
		}
	}

	T.speak = function(w){
		this.fukidashi.setWord(w);
	}

	T.draw = function(){
		with(this){
			if(mugyu){
				sprite.setImage(image,width,32);
				if(ropeFlag)sprite.moveTo(x,y-8);
				else	sprite.moveTo(x,y);
			}else{
				sprite.setImage(image,width,height + 16);
				sprite.moveTo(x,y-16);
			}
			sprite.draw();
			fukidashi.draw();
		}
	} //
	
 } //



//=========================================
//=========================================
//=========================================
function Digger(stg,xx,yy,flag){
	var T=this;
	T.isDigger = true;
	ICharacter(T,stg);
	ISpriteControl(T);
	T.busy = true;
	T.counterStart = 100;
	T.counterStart = 162;

	T.digSpd = 6;

	if(T.stage.diggerTime >0)T.counterStart = T.stage.diggerTime;
	if(T.stage.diggerSpeed>0)T.digSpd = T.stage.diggerSpeed;
	T.counter = T.counterStart;

	T.walkSpeed = 8;
	T.height = T.width = T.stage.blockSize;
	T.spriteWidth  = T.width;
	T.spriteHeight = T.height;
	T.baseX = Math.floor(xx / T.width  ) * T.width;
	T.baseY = Math.floor(yy / T.height ) * T.height;
	T.defaultBlock = T.stage.getXYPointBlock(T.baseX,T.baseY);
	T.sprite.setImage(T.stage.imgTable[T.defaultBlock],T.width,T.height);
	T.sprite.setVisibility(true);
	T.moveTo( T.baseX , T.baseY );
	T.setZ(108);

	if(!flag){
		T.mode = 0;
		T.effect = new Sprite();
		T.effect.setImage( PlayerImages.DiggerEffect , T.width + 8 , T.height);
		T.effect.setOpacity(60);
		T.effect.setVisibility(true);
		T.effect.moveTo( T.baseX - 4 , T.baseY - 16 );
		T.effect.setZ(116);
	}else{
		T.mode = 1;
		T.effect = DummySprite.instance;
		T.stage.setXYPointBlock(T.baseX,T.baseY,0,-1);
		T.counter = T.counterStart - T.digSpd;
	}
	

	T.mind = B_Digger;
	T.action = function(){
		with(this){
		  if( counter > counterStart - digSpd ){
			  if( counter == counterStart ){
				busy = true;
				stage.setXYPointBlock(baseX,baseY,0,-1);
				effect.setVisibility(true);
			  }
			var yp = (counterStart - counter) * (height / digSpd);
			sprite.moveTo( baseX  , baseY + yp );
			effect.moveTo( baseX -4 , baseY + yp - 16 );
			sprite.setSize(spriteWidth , spriteHeight - yp);
			stage.updateBlock(this);
			var ob = stage.getXYPointBlock(baseX,baseY-stage.blockSize/2);
			if(stage.isEnemy(ob)){
				 master.speak(EventWord.jama);
				 kill();
			}
		  }else
		  if( counter >  16 ){
			if( counter == counterStart - digSpd ){
				defaultBlock = stage.setDiggerMask(this);
				sprite.setVisibility(false);
				effect.setVisibility(false);
				busy = false;
			}
		  }else{
			if( counter ==  16 )sprite.setVisibility(true);

			var yp = counter * (spriteHeight / 16);
			sprite.moveTo( baseX +1, baseY + yp );
			sprite.setSize(spriteWidth , spriteHeight - yp);
			stage.updateBlock(this);
		  }
		  if( counter <= 1 ){
			stage.resetDiggerMask(this);
		  	if( counter == 0 )kill();
		  }
		  counter--;
		}
	}
	T.getBX = function(){return Math.floor( (this.baseX + this.width / 2) / this.width); }
	T.getBY = function(){return Math.floor( (this.baseY + this.width / 2) / this.width); }
	T.draw = function(){
		this.sprite.draw();
		this.effect.draw();
	}
	T.kill = function(){
		this.busy = false;
		this.life = -1;
		this.stage.resetDiggerMask(this);
		this.sprite.kill();
		this.effect.kill();
	} //
	
	T.getBX = function(){return Math.floor(this.baseX / 32);}
	T.getBY = function(){return Math.floor(this.baseY / 32);}
	
	T.collision = function(obj){
		with(this){
			if(mode==1){mode=0;return _collision(obj);}
			 if(counter == 0)return _collision(obj);
			 else return false;
		}
	}
	T.onCollided = function(obj){}
} //

function Explosion(stg,xx,yy){
	var T=this;
	T.isDigger = true;
	ICharacter(T,stg);

	T.mind = B_Digger;
	T.height = T.width = T.stage.blockSize;
	T.x = Math.floor(xx / T.width  ) * T.width;
	T.y = Math.floor(yy / T.height ) * T.height;

	T.action = function(){this.life = -1;}
} //

//=========================================
//=========================================
//=========================================

function Robot(stg,xx,yy){
	var T=this;
	T.isRobot = true;
	ICharacter(T,stg);
	ISpriteControl(T);

	T.walkSpeed = 8;
	T.fallSpeed = 8;

	T.goldRelease = 20;
	T.goldRelease = 28;
	T.goldReleaseCnt = T.stage.random.get() % T.goldRelease;

	T.image = RobotImages.standR;
	T.sprite.setImage(T.image,32,32+16);
	T.sprite.setVisibility(false);
//	T.sprite.setVisibility(true);
	T.moveTo(xx,yy);
	T.setZ(110);
	T.startX = xx;
	T.startY = yy;
	
	T.hFace = 1;
	T.fallFlag = false;
	T.ropeFlag = false;
	T.ladderFlag = false;
	T.hideFlag = false;
	T.hiddenEnemy = false;

	T.mind = B_Enemy;

	T.number = Robot.number++;
	T.actionCnt = 0;
	T.sleepCnt = -0xff;
	T.sleepCntStart = getRobotSleepTime(stg);
	
	T.resurrectCnt = Robot.number * 2;//←出現タイミングを一瞬ずらす
	if(stg.fastStart == 1)T.resurrectCnt = 1;

	T.kickedCnt=0;
	T.moveCnt=0;
	T.animCnt=0;

	T.target = null;
	 T.setTarget = function(obj){this.target = obj;}

	T.action = function(){
		with(this){
			stage.resetEnemyMask(this);
			if(number==0)updateActionTable();
			 var sp = checkActionTable();

			if(hideFlag)hideAction();
			else	if(resurrectCnt-->0)resurrectAction();
			else	if(kickedCnt-->0)kickedAction();
			else{
			 if(sp==0)	sprite.moveTo(x,y-16);
			 else{
				var xx=x,yy=y;
				actionCnt++;
				for(var i=0;i<sp;i++){
					if(sleepCnt-- > 0)sleepAction();
					else	walkAction();
				}
				sprite.moveTo((xx+x)/2,(yy+y)/2-16);
				var ac = actionCnt % 20,sbs=sprite.body.style;
				if(goldCnt>0 &&ac==19)sbs.background="#999966";
				else	if(hiddenEnemy && ac==9)sbs.background="#996666";
				else	if(ac%10==1)sbs.background="";
			 }
			}
			if(!hideFlag)stage.setEnemyMask(this);
		}
	}



	T.walkAction = function(){ //robowalk
		with(this){
			var T=this;
			var bSize = stage.blockSize,gmode=stage.gameMode;
			var bx = getBX() , by = getBY();
			var cb = stage.getXYBlock( bx , by );
			var hw = width/2, hh =height/2;
			var fb = stage.getXYPointBlock(x + hw, y + height);
			var fbb = stage.getXYPointBlock(x + hw, y + height-1);
			var ctx = x + hw;
			var xs = x % bSize , ys = y % bSize;
			ropeFlag = false;
			if( stage.isLadder(cb|fbb) )fallFlag = false;
			else if(stage.isRope(cb)){
				if(ys<=8)fallFlag=false;
				else if(stage.isLadder(fb))fallFlag=false;
				else fallFlag=true;
			}


			if( ys == 0 && cb&B_Rope==0)fallFlag=false;
			if(fallFlag && ys!=0){
			}else{ // 行動範囲検索
				var xsMove = 0 , ysMove=0;
				var pbx = target.getBX() , pby = target.getBY();
				if(gmode == GameMode.GBA || gmode == GameMode.IMode){
					if(target.getY() % bSize == walkSpeed)pby++; // GBA版の半キャラずらし
				}
				checkPointA.reset(bx , by , pbx , pby);
				checkPointB.reset(bx , by , pbx , pby);

				if(stage.ladderBugEnable>0&& target.ladderBugFlag)pbx=-1;
				// プレイヤーと同じ高さにいて地続きなら、直進する
				if( checkFloorLine( bx , by , pbx , pby ) )
					xsMove = ( target.getX() > x ) ? 1 : -1 ;
				else{
					checkHorizontal( bx , by , pbx , pby );	// 行ける範囲を探索
				}


				if(checkPointA.found) // 同じ高さに行けそう
					{xsMove = checkPointA.xMove; ysMove = checkPointA.yMove;}
				else
				if(checkPointB.found) // 同じ高さに行けない
					{xsMove = checkPointB.xMove; ysMove = checkPointB.yMove;}

				if(gmode == GameMode.GBA){
						if(bx == pbx && by==pby)ysMove=xsMove=0;
				}
					xMove = xsMove * walkSpeed;
					yMove = ysMove * walkSpeed;
			}

				// 落下判定
				fallFlag = false;
				var fbb = stage.getXYPointBlock(ctx , y + height);
					// 横視界バグの再現
				if(stage.fcBugEnable >0 && ( fbb & B_Player ) != 0)fbb =  B_Blank;
				if( (fbb & ( B_Block | B_Ladder | B_Enemy | B_Bomber )) == 0 ){
					var	cbb = stage.getXYPointBlock(x+hw , y + hh);
				  if( ( (cbb & (B_Ladder | B_Rope )) == 0) && 
					 sleepCnt < 0 ){ // ←同じ穴に落ちないようにするため
						yMove = walkSpeed;
						fallFlag = true;
				  }
				}
//			 }else
//			 if(gmode == GameMode.IMode)
//					{xsMove = hFace;}

	// 壁衝突判定
			var xv = 1 ,yv = 1;
				if(xMove != 0){ //横衝突
					var xb = stage.getXYPointBlock(x + ((xMove>0)?width:-1) , y + hh);
					if( ( xb & (B_Block | B_Enemy | B_HHole | B_Bomber)) != 0 )xv = 0;
				}
				if(yMove != 0){ //縦衝突
					var yb = stage.getXYPointBlock(x + hw , y + ((yMove>0)?height:-1));
					if( yMove > 0 || stage.gameMode == GameMode.GBA) yb = yb & ~B_HHole;
					if( ( yb & (B_Block | B_Enemy | B_HHole | B_Bomber)) != 0 ){
						yv = 0;
						if(fallFlag)y = Math.floor(y / bSize) * bSize;
						fallFlag = false;
					}
					xv = 0;
				}
			xMove *= xv;
			yMove *= yv;






	// 顔の向き・移動フラグ
			if(xMove!=0)hFace = (xMove > 0) ? 1 : -1;
			var lr = ( hFace > 0 ) ? "R" : "L";
			var mv = ( xMove == 0 && yMove == 0 ) ? "" : "Move";

	//金塊取得
			if( xs == 0 && ys == 0 && !hiddenEnemy){
				if(goldCnt<1 && stage.isGold(cb)){
					goldCnt++;
					stage.getGold(this);
						goldReleaseCnt = stage.random.get() % goldRelease;
						if(goldReleaseCnt<1)goldReleaseCnt=1;
					moveCnt=0;
				}
			}

	//位置補正&移動
			var xsv=0,ysv=0;
			x+=xMove;y+=yMove;
			 if(yMove *yv != 0 && xs != 0)xsv = walkSpeed * (( xs >= hw ) ? 1 : -1);
			 if(xMove *xv != 0 && ys != 0)ysv = walkSpeed * (( ys >= hh ) ? 1 : -1);
			x+=xsv;y+=ysv;

			if(!fallFlag && cb==B_Blank && !hiddenEnemy){
			 var mbx=getBX(),mby=getBY();
			 if( goldCnt>0 && (bx!=mbx || by != mby)){
				moveCnt++;
				if(moveCnt > goldReleaseCnt && stage.gameMode != GameMode.IMode){
					if((cb&~B_Ghost)==B_Blank&&(fb&(B_Block|B_Ladder|B_Bomber)) != 0 ){
						stage.setGoldXY(bx,by);
						goldCnt--;
						goldReleaseCnt= goldReleaseCnt % goldRelease;
					}
				 }
			 }
			}

			if(fallFlag){
			  if(stage.isDigger(stage.getXYBlock(getBX(),getBY()))){
				var ys = y % bSize;
				if(ys == 16){
					if(sleepCntStart < 0 && stage.fcBugEnable > 0)goldCnt=1;
					if(stage.gameMode != GameMode.BBR)releaseGold();
				}
				if(ys == 0){sleep();return;}
			  }
			}


	// グラフィック変更
			var cm='';
			if(mv!=''){
				animCnt = (animCnt + 8) % 40;
				cm = Math.floor(animCnt / 10);
			if( stage.isRope(cb) && xv != 0) ropeFlag = true;
			if( y % bSize != 0 && stage.isRope(cb))
				{ropeFlag = false;fallFlag = true;}
			if( stage.isLadder(cb | fb) ){ ladderFlag = true;fallFlag=false;}
			if( xMove * xv != 0){ladderFlag = false;}
			if(!ladderFlag && yMove * yv > 0){fallFlag = true;}

			if(fallFlag)		image = RobotImages["fall" + lr +cm];
			else if(ropeFlag)	image = RobotImages["rope" + mv + lr +cm];
			else if(ladderFlag)	image = RobotImages["ladder" + mv +cm];
			else				image = RobotImages["stand" + mv + lr +cm];
			}//else	if(!checkPointA.found && !checkPointB.found){
//				image = RobotImages["stand" + lr];
//			}
		}
	}






	T.sleep = function(){
		with(this){
			var lr = (hFace > 0) ? "R" : "L";
			image = RobotImages["die" + lr];
			sleepCnt = sleepCntStart;
			fallFlag = false;
			var bSize = stage.blockSize;
			moveTo(getBX() * bSize , getBY() * bSize);
			releaseGold();
		}
	}
	T.releaseGold = function(){
		with(this){
			if(goldCnt < 1 )return;
			var ub = stage.getXYPointBlock(x , y - height / 2);
			var ge = B_Gold;

			 if((ub & (B_Digger | B_Block | B_Gold)) != 0){
				if(!hiddenEnemy)stage.lostGold(this);
				goldCnt--;
			 }else
			 if((ub & ge) == 0){
				if(hiddenEnemy)stage.setBonus(this);
				else		 stage.setGold(this);
				goldCnt--;
			 }
		}
	}
	T.hideAction = function(){
		with(this){
			var bx = getBX(),by=getBY();
			var cb = stage.getXYBlock(bx,by);
			if(stage.isDigger(cb)){
				hideFlag = false;
				sprite.setVisibility(true);
				resurrectCnt=0;
				target.speak(EventWord.kakure);
				sleep();
				goldCnt=1;
			}
		}
	}
	T.hide = function(){
		with(this){
			hiddenEnemy=hideFlag = true;startX=x;startY=y;
			sprite.setVisibility(false);
		}
	}

	T.kickedAction = function(){
		with(this){
			var dx=x-sprite.x;
			if(sleepCnt>4)sleepCnt=sleepCntStart;
			if(dx!=0)sprite.moveTo(sprite.x+((dx>0)?8:-8),sprite.y);
			else	kickedCnt==0;
			if(kickedCnt==0)sprite.moveTo(x,y-16);
		}
	}
	T.onKicked = function(obj,pow){
		with(this){
			var hf = obj.hFace,bx = getBX(),by=getBY();
			var lrb = stage.getXYBlock(bx+hf,by);
//			alert(hf+" " + lrb);
//			if(kickedCnt>0)return false;
			if(fallFlag)return false;
			if((lrb & (B_Block|B_Bomber|B_HHole))!=0)return false;
			if((lrb & B_Enemy)!=0){
				if(!stage.kickBlock(obj,bx+hf,by,pow))return false;
			}
			if(resurrectCnt>0)return true;
			stage.resetEnemyMask(this);
			x=(bx+hf)*stage.blockSize;
			stage.setEnemyMask(this);
			kickedCnt=4;
			return true;
		}
	}

	T.sleepAction = function(){ //robosleep
		with(this){
			var bx = getBX(),by=getBY();
			if(sleepCnt<=4){
				 var hb = stage.getXYPointBlock(x+width/2,y-walkSpeed);
				 var cb = stage.getXYBlock(bx,by),be=B_Block|B_Enemy;
				 image = RobotImages["ladderMove"];
				 if(stage.gameMode == GameMode.GBA){
					be|=B_Bomber;
					if(target.collision(this)&&target.y<=y-16&&Math.abs(target.x-x)<=24&&sleepCnt>2)sleepCnt++;
					else{
					 if(sleepCnt<2){
						walkAction();
						if(x % stage.blockSize==16)sleepCnt++;
					 }else{
						var hlb=stage.getXYBlock(bx-1,by-1),hrb=stage.getXYBlock(bx+1,by-1);
						if((hb & be)!=0){sleepCnt++;}
						else	if((hlb & be)!=0 && (hrb & be)!=0)sleepCnt++;
						else	 y -= walkSpeed ;
					 }
					}
				 }else
				 if(stage.gameMode == GameMode.BBR){}
				 else{
					if((cb & B_Digger)!=0 && sleepCnt>0){
					 if((hb & be)!=0){sleepCnt++;}
					 else	 y -= walkSpeed ;
					}else{
						walkAction();
						if(x % stage.blockSize==16)sleepCnt++;
					}
				 }
			}else
			if(sleepCnt <  10){
				var lr=(sleepCnt % 2 > 0)?"R":"L";image=RobotImages["die"+lr];
			}
		}
	}



	T.resurrect = function(){
		with(this){
			var lr = (hFace > 0) ? "R" : "L";
			image = RobotImages["die" + lr];
			stage.resetEnemyMask(this);
			sprite.setVisibility(false);
//			sprite.setOpacity(50);
			sleepCnt = 0;
			resurrectCnt = 32;
			Robot.lastActPtr=number;
			if(stage.gameMode == GameMode.GBA){
				 if( goldCnt > 0 ){
					if(!hiddenEnemy)stage.lostGold(this);
					goldCnt--;
				 }
				 if(hiddenEnemy){moveTo(0,0);hideFlag=true;}
				 else{	stage.resurrectEnemy(this);stage.setEnemyMask(this);}
			}else{
				 if(hiddenEnemy){moveTo(0,0);hideFlag=true;}
				 else{	stage.resurrectEnemy(this);stage.setEnemyMask(this);}
				 if( goldCnt > 0 ){
					if(!hiddenEnemy)stage.lostGold(this);
					goldCnt--;
				 }
			}
		}
	}
	T.resurrectAction = function(){
		with(this){xMove=yMove=0;
			var bx=getBX(),by=getBY(),cb=stage.getXYBlock(bx,by);
			if(stage.gameMode==GameMode.IMode && (cb & B_Bomber)!=0)resurrectCnt=32;
			if(resurrectCnt == 5 || resurrectCnt == 0){
//									sprite.setOpacity(100);
									sprite.setVisibility(true);
			}else
									sprite.setVisibility(resurrectCnt % 4<2);

			if( stage.fcBugEnable>0 && (cb&B_Ladder) != 0){
				sprite.setVisibility(true);
				resurrectCnt=1;
			}
			var lr=(hFace > 0)?"R":"L";
			image=(resurrectCnt > 5 ) ? RobotImages["die"+lr] : RobotImages["fall"+lr];
			
		}
	}
	T.checkFloorLine = function(x1,y1,x2,y2){ // 相手と地続きかどうかをチェック
		var T= this;
		with(this){
			if(y1!=y2 || x2<0)return false;
			var xx1,xx2,yf=y1+1;
			var b34 = B_Ladder|B_Rope;
			var b12347abd=B_Block|B_Ladder|B_Rope|B_Gold|B_Gate|B_MBlock|B_Digger|B_Bonus;
				b12347abd |= B_Bomber;
				if(T.stage.gameMode==GameMode.GBA)b12347abd |= B_Ghost;
			if(x1<=x2){xx1=x1 + 1;xx2=x2;}else{xx1 = x2 ; xx2 = x1 -1;}
			for(var i = xx1 ; i <= xx2 ; i++){
				var fb = T.stage.getXYBlock(i , yf);
				if( (fb & b12347abd ) == 0 ){
					 var cb = T.stage.getXYBlock(i,y1);
					if((cb & b34) == 0 )return false;
				}
			}
			return true;
		}
	}



	if( T.stage.gameMode == GameMode.PC)
			T.checkPointA = new CheckPointA2(this);
	else	T.checkPointA = new CheckPointA(this);
	T.checkPointB = new CheckPointB(this);
	T.checkHorizontal = function (x1,y1,x2,y2){ // 横視界のチェック
		var T=this;
			T.checkH(x1,y1,x2,y2,0); //垂直
			if(T.checkPointA.found==true)return;
			T.checkH(x1-1,y1,x2,y2,-1);//左
			T.checkH(x1+1,y1,x2,y2, 1);//右
	}




	T.checkH = function(x1,y1,x2,y2,lr){
		var T=this;
//	 with(this){
		var j = x1,max = (lr > 0) ? T.stage.cols : 0;
		var cb,fb,cbb,fbb;
		var ff = (y1 >= T.stage.rows-2) ? B_Block : 0;
		var wall = B_Block | B_Bomber;
		var floor= B_Block | B_Digger | B_Bomber;
		var pe = B_Enemy | B_Player ;
		if(T.stage.gameMode==GameMode.GBA)wall|=B_HHole;
			for( ; ; j+=lr ){ if( j == max )break;
			if(T.checkPointA.found){if(Math.abs(j-x1) > T.checkPointA.xDistance)return j;}

				cbb = cb = T.stage.getXYBlockR( j , y1 );
				if( (cb & wall) != 0 )break;
				fbb = fb = T.stage.getXYBlockR( j , y1 + 1 ) | ff;
				if(T.stage.fcBugEnable==1){//横視界バグの再現
				 if( (cb & B_Digger ) == 0)
					{if( (cb & pe) != 0 )cb = B_Blank;}
				 if( (fb & B_Digger ) == 0)
					{if( (fb & pe) != 0 )fb = B_Blank;}
				}
					if( ((cbb|fbb)& B_Ladder) !=0 ) // 縦視界チェック
						T.checkVertical( j , y1 , x2 , y2 );
					else
					if( ( fb & floor ) == 0 ){ // 足下がブロック以外
						T.checkVertical( j , y1 , x2 , y2 );
						if( ( cb & ( B_Ladder | B_Rope ) ) == 0 )break;
					}
				if(lr==0)break;
			}
			return j;
//	 }
	}


//=================================-

	T.checkVertical = function( x1 , y1 , x2 , y2 ){ // 縦視界のチェック
	 with(this){
		var T=this;
		var i , cb = T.stage.getXYBlockR( x1 , y1 );
		var l = x1-1 , r = x1+1;

		if( y1<= T.stage.lineZeroBlock){
			 /*最上段にいるときは上視界サーチしない*/
		}
		else
		if( (cb & B_Ladder) != 0 ){
			var fb = T.stage.getXYBlockR( l , y1 ) | T.stage.getXYBlockR( r , y1 );
			var e = (T.checkPointA.found) ? y2 : 0,b123= B_Block|B_Ladder|B_Bomber|B_Digger;
			 for( i = y1-1 ; i >= e ; i-- ){ //上視界

				cb = T.stage.getXYBlockR( x1 , i );
					// 現在のブロックがはしご以外(≒はしごの最上段)なら「行ける場所」
					if( (cb & B_Ladder) == 0 || i==0){
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						break;
					}
				if(T.checkPointA.found){
					if(i != y2)continue;
					fb=T.stage.getXYBlockR(l,i+1)|T.stage.getXYBlockR(r,i+1);
				}
				var lrb = T.stage.getXYBlockR(l,i) | T.stage.getXYBlockR(r,i);
					// 横にバーがあるなら「行ける場所」
					if( (lrb & B_Rope) != 0 ){
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						fb=lrb;
						continue;
					}
					// 斜め下に床(ブロック・はしご)があるなら「行ける場所」
					if( (fb & b123) != 0)
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
				fb = lrb;
			 }
		} //end if( T.stage.isLadder(cb) )
/*
条件１）ランナーの高さ以下にある
条件２）以下のどれかの位置にあるハシゴ、バー、落とし穴、金塊、掘ったレンガ
・ブロックの左上・右上
・はしごの左上・右上
・バーの左上・右(右上ではない)
*/

	if( (T.stage.getXYBlockR( x1 , y1 + 1 ) & (B_Block|B_Digger|B_Bomber)) != 0 )return;

	var rp = (x1 == 1 && T.stage.fcBugEnable==1) ? B_Rope : 0;
	var rw = (T.checkPointA.found) ? (y2+1) : T.stage.rows+2;

	var b12d  = B_Block | B_Digger|B_Bomber;

	var b3457d= B_Ladder| B_Rope | B_HHole | B_Gold | B_Digger;
	var b1234d= B_Block | B_Ladder | B_Rope | B_Digger|B_Bomber;
	var b123d = B_Block | B_Ladder | B_Digger|B_Bomber;
			for( i = y1 ; i < rw ; i ++ ){ //下視界
					// 足下が床(ブロック・掘ったブロック)なら「行ける場所」
					var fb = T.stage.getXYBlockR( x1 , i + 1 );
					if( (fb & b12d) != 0 ){
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						break;
					}else
					if(i >= y2){// プレイヤーと同じか下
	//			 if(T.checkPointA.found){if(i != y2)continue;}
						cb = T.stage.getXYBlockR( x1 , i );

						 if( ( cb & b3457d ) != 0 ){

							//ブロック・はしご・バー・掘ったブロックの左上
							var frb = T.stage.getXYBlockR( r , i + 1 ) & ~rp;
							 if( (frb & b1234d) != 0 ){
								((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
								continue;
							 }
							//ブロック・はしご・掘ったブロックの右上
							var flb = T.stage.getXYBlockR( l , i + 1 );
							 if( (flb & b123d) != 0 ){
								((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
								continue;
							 }
							// バーの右(右上ではない)・左から2列目にあるバーの左
							var lb = T.stage.getXYBlockR( l , i );
							var rb = (rp==0)?0: T.stage.getXYBlockR( r , i );
							if( ( (lb|rb) & B_Rope ) != 0 ){
								((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
								continue;
							}
						 }
					}

		} // end for

	 } // end with(this)
	} // end checkVertical
if(T.stage.gameMode==GameMode.GBA){
	T.checkVertical = function( x1 , y1 , x2 , y2 ){ // 縦視界のチェック
	 with(this){
		var T=this;
		var i , cb = T.stage.getXYBlockR( x1 , y1 );
		var l = x1-1 , r = x1+1;
/*
・はしごの頂上
・横にバーがあり、ランナーより高い位置にある地点
・斜め下にはしごかレンガかコンクリか掘ったレンガがあり、ランナーより高い位置にある地点
*/
		if( y1<= T.stage.lineZeroBlock){
			 /*最上段にいるときは上視界サーチしない*/
		}
		else
		if( (cb & B_Ladder) != 0 ){
			var e = (T.checkPointA.found) ? y2 : 0,b123= B_Block|B_Ladder|B_Bomber|B_Digger;
			 for( i = y1-1 ; i >= e ; i-- ){ //上視界

				cb = T.stage.getXYBlockR( x1 , i );
					// 現在のブロックがはしご以外(≒はしごの最上段)なら「行ける場所」
					if( (cb & B_Ladder) == 0 || i==0 ){
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						break;
					}
				if(T.checkPointA.found){if(i != y2)continue;}
				if(i < y2){
					var lrb = T.stage.getXYBlockR(l,i) | T.stage.getXYBlockR(r,i);
					// 横にバーがあるなら「行ける場所」
					if( (lrb & B_Rope) != 0 ){
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						continue;
					}
					// 斜め下に床(ブロック・はしご)があるなら「行ける場所」
					var fb=T.stage.getXYBlockR(l,i+1)|T.stage.getXYBlockR(r,i+1);
					if( (fb & b123) != 0)
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
				}
			 }
		} //

//	if( (stage.getXYBlockR( x1 , y1 + 1 ) & (B_Block|B_Digger)) != 0 )return;
	if( (T.stage.getXYBlockR( x1 , y1 + 1 ) & (B_Block|B_Digger|B_Bomber)) != 0 )return;

	var rw = (T.checkPointA.found) ? (y2+1) : T.stage.rows+2;

	var b12d = B_Block | B_Digger| B_Bomber;
	var b345d= B_Ladder| B_Rope  | B_Digger;
	var b123d= B_Block | B_Ladder| B_Digger |B_Bomber;
			for( i = y1 ; i < rw ; i ++ ){ //下視界
					// 足下が床(ブロック・掘ったブロック)なら「行ける場所」
					var fb = T.stage.getXYBlockR( x1 , i + 1 );
					if( (fb & b12d) != 0 ){
						 ((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						break;
					}else
					if(i >= y2){// プレイヤーと同じか下
//				 	if(T.checkPointA.found){if(i != y2)continue;}
						cb = T.stage.getXYBlockR( x1 , i );
						 if( ( cb & b345d ) != 0 ){// 梯子・バー・穴
							//ブロック・はしご・掘ったブロックの斜め上
							var fb = T.stage.getXYBlockR(l,i+1)|T.stage.getXYBlockR(r,i+1);
							 if( (fb & b123d) != 0 ){
								((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
								continue;
							 }
							// バーの左右
							var lrb =T.stage.getXYBlockR(l,i)|T.stage.getXYBlockR(r,i);
							if( ( lrb & B_Rope ) != 0 )
								((i==y2)?T.checkPointA:T.checkPointB).compare( x1 , i );
						 }
					}

		} // end for

	 } // end with(this)
	} // end checkVertical

}

	T.moveTo = function(xx,yy){
			var T=this;
			T.x=xx;T.y=yy;
			T.sprite.moveTo(xx,yy-16);
	}
	T.moveTo(T.x,T.y);
	
	T.draw = function(){
		var T=this;
			T.sprite.setImage(T.image,T.width,48);
			T.sprite.draw();
	}
	
	T.onCollided = function(obj){//robocoll
	 with(this){
		var obx = obj.getBX(),oby = obj.getBY(),bx = getBX()	 , by = getBY();
		if(resurrectCnt>0)return;
		if(obj.mind == B_Digger ){
				if(bx != obx)return;
				if(by >  oby)return;
				if(by <  oby)return;
			resurrect();
			if(stage.gameMode!=GameMode.BBR)stage.resetDiggerMask(obj);
		}else
		 if( obj.mind == B_MBlock ){
				var ox = obj.getX(),oy=obj.getY();
				var xd = ox - y;
			if(kickedCnt>0)return;
			if(ox == x && oy==y)resurrect();
			else
			if(bx == obx && obj.yMove>0 ){
				 if(fallFlag && xd>height-8){}//y=obj.getY()+height;
				 else
				 if(xd >-height/2 && obj.getBY()==getBY() && oy<=y){
					obj.getScore(1);
					resurrect();
				 }
			}else{
				var ox = obj.getX(),xm=obj.xMove;
				var xb = stage.getXYPointBlock(x+(xm>0?width:-1),y+height/2);
				if(xm==0 || fallFlag)return;
				if( by == oby){
				 if(!stage.isWall(xb)){
					stage.resetEnemyMask(this);
					if(xm < 0)	x = ox-width;
					else		x = ox+width;
					stage.setEnemyMask(this);
				 }
				}
			}
		 }
	 }
	}


	T.initActionTable= function(){
	 with(this){
		var cnt = Robot.number;
		var tA=new Array(),tB=new Array(),tC=new Array();
		var a,b,c,n = cnt+stage.lap*1+1,i;
		if(n>8+cnt){n=8+cnt;}
//		if(stage.gameMode==GameMode.GBA)n=(cnt>6)?36:(12*cnt-cnt*cnt);
		if(stage.gameMode==GameMode.IMode)n=2*cnt;
		a=b=c= Math.floor(n/3);
		if(n%3>=2){b++;c++;}else if(n%3>=1)c++;
		if(stage.gameMode==GameMode.FC){
			if(n==4){b=2;c=1;}
			if((stage.lap*1 + cnt)%256==0)n=a=b=c=0;
		}
		var bt = new Array(a,b,c),at=new Array();
		for(i=0;i<cnt;i++)at[i]=0;
		Robot.baseTable = bt;
		Robot.actionTable=at;
		Robot.basePtr= 0;
		Robot.lastActPtr=-1;
	 }
	}

	T.updateActionTable = function(){
		with(this){
			var at=Robot.actionTable,bt = Robot.baseTable;
			var mv=bt[Robot.basePtr % bt.length];
			var lp=0;
			Robot.lastActPtr++;
			for(var i=0;i<mv;i++){
				lp = (Robot.lastActPtr + i) % at.length;
				at[ lp ]++;
			}
			if(at.length==1)at[0]=mv;
			Robot.actionTable = at;
			Robot.lastActPtr=lp;
			Robot.basePtr++;
		}
	}
	T.checkActionTable = function(){
		with(this){
			var ret = Robot.actionTable[number];
			Robot.actionTable[number]=0;
			return ret;
		}
	}
	T.initActionTable();

	function getRobotSleepTime(stg,ver){
	 with(this){
	  var gm = stg.gameMode,ret=22,lp=stg.lap*1;
	  if(gm==GameMode.FC||gm==GameMode.GBA||gm==GameMode.DS||lp>0){
		var tmp="26,26,2E,44,47,49,4A,4B,4C,4D,4E,4F,50,51,52,53,54,55,56,57,58,00,00,00,00,01,01,01,01,01,01,03,01,01,03,03,03,03,03,03,03,07,03,07,07,07,07,07,07,07,0F,07,0F,0F,0F,0F,0F,0F,0F,1F,0F,1F,1F,1F,1F,1F,1F,1F,3F,1F,3F,3F,3F,3F,3F,3F,3F,7F,3F,7F,7F,7F,7F,7F,A5,A6,85,C1,A9,00,85,95,A9,78,85,B0,A9,EA,85,B1,A9,00,85,86,A9,00,85,85,A5,86,20,1C".split(","),c;
		if(lp<0)return;
		c = parseInt(((tmp[lp]) ? tmp[lp] : tmp.pop()) ,16);
		 // (FC版-4)/2が目安
		if(c>127)c=-10;
		if(c>10)c-=5;
		ret=Math.round(c/2);
	  }
		if(gm==GameMode.BBR)ret=0;
	  return ret;
	 }
	}
} //

Robot.number=0;

/*
ロボットの目的地
・ロボがいる場所と、その行きたい先が同じの場合、下に降りる動作をする。
*/
function ICheckPoint(T,obj){
	T.x=0;
	T.y=0;
	T.xMove=0;
	T.yMove=0;
	T.xDistance=0xffff;
	T.yDistance=0xffff;
	T.found = false;
	T.master = obj;
	T.bx = obj.getBX() ;
	T.by = obj.getBY();
	T.pbx = 0;
	T.pby = 0;

	T.reset = function(bxx,byy,pbxx,pbyy){
	 with(this){
		x = 0xffff; y = 0xffff;
		xMove = 0;yMove = 0;
		xDistance = 0xffff;yDistance = 0xffff;
		found = false;
		bx = bxx;
		by = byy;
		pbx = pbxx;
		pby = pbyy;
	 }
	}

	T.overwrite = function(xx , yy , xd , yd ){
		with(this){
			x = xx ; y = yy;
			xDistance = xd ; yDistance = yd;
			if( xd == 0 ){
				xMove = 0;
				yMove = ( by > yy ) ? -1 : 1;
			}else{
				xMove = ( bx > xx ) ? -1 : 1;
				yMove = 0;
			}
			found = true;
			return true;
		}
	}
} //

/*
ランナーの高さに行ける場合、
・それが1か所だけならばそこへ向かって歩く。
・それが2か所以上の場合、その、近いほうへ行く。
・距離が同じな2か所が候補の時、左側を選ぶ。
*/
function CheckPointA(obj){ // ロボットが行きたい場所(FC)
	var T=this;
	ICheckPoint(T,obj);
	T.compare = function( xx , yy ){
		var T= this;
	 with(this){
		var xd = Math.abs( xx - T.bx ), yd = Math.abs( yy - T.by );
		if( yy != T.pby )return;
		if(T.xDistance >= xd ){ //今の場所よりも同じか近い
			if(T.xDistance != xd )
					return overwrite( xx , yy , xd , yd );
			else{ // 同じ距離
				if(xx < bx) // 今のポイントより左にある
					return overwrite( xx , yy , xd , yd );
			}
		}
		return false;
	 }
	}
} //
function CheckPointA2(obj){ // ロボットが行きたい場所(PC版)
	var T=this;
	ICheckPoint(T,obj);
	T.compare = function( xx , yy ){
		var T=this;
	 with(this){//真下以外では常に左優先？
		var xd = Math.abs( xx - T.bx ), yd = Math.abs( yy - T.by );
		if( yy != T.pby )return;
		if(T.xDistance == 0)return;
		if( xd == 0 )return overwrite( xx , yy , xd , yd );
		if( xx < T.x ) return overwrite( xx , yy , xd , yd );
		return false;
	}
	}
} //


/*
ランナーの高さに行けない場合、
・ランナーより高い位置に行きたがる。
・ランナーより低い位置にしか行けない場合、そのいちばん高いところへ行きたがる。
・行きたい高さに行ける場所が複数ある場合、ロボの真下が優先。
・真下以外の複数の場合、左側に行ける場所があればそっちへ。なければ右へ。
*/
function CheckPointB(obj){ // ロボットが行きたい場所に行けない場合に行く場所
	var T=this;
	ICheckPoint(T,obj);
	T.compare = function( xx , yy ){
		var T=this;
	 with(this){
		var xd = Math.abs( xx - T.bx ), yd = Math.abs( yy - T.by );
//		if(yy> T.y && xd==0 && SYSVER >= 0x070503)return overwrite( xx , yy , xd , yd ); // 真下が最優先
			if( yy > T.pby ){ // プレイヤーよりも低い
				if( T.y < T.pby)return;
				if(yy <= T.y){ //今と同じか上
					if(yy < T.y)return overwrite( xx , yy , xd , yd );// 今より上
					if(xd == 0)	return overwrite( xx , yy , xd , yd );
					if(xx < T.x && T.xDistance != 0) // 同じ高さ・今より左・真下が見つかってない
								return overwrite( xx , yy , xd , yd );
					return false;
				}
					return false;
			}
			else{ // プレイヤーよりも高い位置
				if( y > T.pby )return	overwrite( xx , yy , xd , yd );
				if(yy >= T.y){ //今と同じか下
					if(yy > T.y)return overwrite( xx , yy , xd , yd );// 今より下
					if(xd == 0)	return overwrite( xx , yy , xd , yd );
					if(xx < T.x && T.xDistance != 0)// 同じ高さ・今より左・真下が見つかってない
							 	return overwrite( xx , yy , xd , yd );
					return false;
				}
			}
		return false;
	 }
	}

} //



//=========================================
//=========================================
function Bomber(stg,xx,yy,mFlag){
	var T=this;
	T.isBomber = true;
	ICharacter(T,stg);
	ISpriteControl(T);

	T.walkSpeed = 8;
	T.fallSpeed = 8;

	T.mode = (mFlag) ? 1 : 0;
	T.image = (mFlag) ? PlayerImages.bomberB : PlayerImages.bomber;
	T.sprite.setImage(T.image,32,32);
	T.sprite.setVisibility(true);
	T.moveTo(xx,yy);
	T.setZ(130);
	T.startX = xx;
	T.startY = yy;
	T.width=32;
	T.height=32;
	T.hFace = 1;
	T.explodeFlag = false;
	T.explodeStartCnt = 10;


	T.mind = B_Bomber;
	T.xMoveCnt = 0;

	T.timer =48;
	T.busy = true;
	T.busyCnt = 4;

	T.target = null;
	 T.setTarget = function(obj){this.target = obj;}
	
	T.action = function(){
		with(this){
			if(busyCnt -- <= 0 )busy = false;
			if(mode == 0)timer --;
			if(timer > explodeStartCnt){
				stage.resetBomberMask(this);
				normalAction();
				stage.setBomberMask(this);
			}else
			if(timer > 0){
				explodeAction();
				stage.resetBomberMask(this);
			}
			else kill();
		}
	}
	
	T.normalAction = function(){
		with(this){
			var bSize = stage.blockSize;
			var xs = x % bSize , ys = y % bSize;
			if(xs ==0 && ys == 0 ){
			 var bx = getBX() , by = getBY();
			 var cb = stage.getXYBlock( bx , by );
			 var fb = stage.getXYBlock( bx , by + 1 );
			 if( xMoveCnt > 0 ){
				var xx = ((hFace > 0) ? 1 : -1);
				var lrb = stage.getXYBlock( bx + xx ,by);
				if( (lrb & (B_Block | B_Bomber)) != 0 ){
					xMoveCnt = 0;
					xMove = 0;
				}else{
					xMoveCnt --;
					xMove = xx * walkSpeed;
				}
			 }else{
				xMove = 0;
			 }
			 if( (fb & (B_Block | B_Bomber)) == 0){
				xMove = 0;
				yMove = walkSpeed;
			 }else{
				yMove = 0;
			 }
			}
				moveBy(xMove,yMove);
		}
	}
	
	T.explodeAction = function(){
		with(this){
			if(!explodeFlag){
			 explodeFlag=true;
			 mode = 0;
			 image = PlayerImages.explosion;
			 stage.explode(this,x,y);
			}
		}
	}

	T.draw = function(){
		with(this){
			var bSize = stage.blockSize;
			if(explodeFlag){
			 sprite.setOpacity(50);
			 sprite.setImage(image,bSize * 4 , bSize * 4);
			 sprite.setSize(bSize*4, bSize*4);
			 sprite.moveTo(x - bSize * 1.5,y - bSize * 1.5);
			}else{
				var yp = ( (x + bSize/2) % bSize) % (bSize / 2);
				 sprite.setImage(image,width,height);
				 sprite.moveTo(x,y - yp);
			}
			sprite.draw();
		}
	} //

	T.onCollided = function(obj){
		with(this){
			if(explodeFlag)return;
			if(obj.mind == B_Digger){
				timer = explodeStartCnt + 2 ;
				mode=0;
			}
		}
	}

	T.onKicked = function(obj,pow){
		with(this){
			var hf = obj.hFace;
			hFace = hf;
			if(pow >= 8){xMoveCnt = 999;obj.speak(EventWord.kick999)}
			else
			if(pow >  4){xMoveCnt = 5;obj.speak(EventWord.kick5)}
			else		{xMoveCnt = 1;obj.speak(EventWord.kick1)}
		}
	}
} //
Bomber.number=0;


//=========================================
//=========================================
function MBlock(stg,xx,yy){
	var T=this;
	T.isMBlock = true;
	ICharacter(T,stg);
	ISpriteControl(T);

	T.walkSpeed = 8;

	T.mode = 0;
	T.image = StageImages.B_MBlock;
	T.sprite.setImage(T.image,32,32);
	T.sprite.setVisibility(true);
	T.moveTo(xx,yy);
	T.setZ(120);
	T.width=32;
	T.height=32;
	T.hFace = 1;
	T.actionCnt=0;
	T.fallFlag=false;

	T.mind = B_MBlock;
	T.xMoveCnt = 0;

	T.fukidashi=null;
	T.words=new Array("あべし","ひでぶっ","たわば","うわらばっ","ばよえ～ん");
	T.busy = true;
	T.busyCnt = 4;
	T.action = function(){
		with(this){
			actionCnt++;
			//012345678
			//xoxoxoxox
			//0123456789ABCD
			//oxoooxoxoooxox
			var sk = ((actionCnt%9) %2 ==0);

			stage.resetBomberMask(this);
			if(sk)sprite.moveTo(x,y-16);
			else{
				var xx = x,yy=y;
				walkAction();
				sprite.moveTo((xx+x)/2,(yy+y)/2-16);
			}
			stage.setBomberMask(this);

			if(fukidashi)fukidashi.action();
		}
	}

	T.walkAction = function(){
		with(this){
			var bSize = stage.blockSize;
			var xs = x % bSize , ys = y % bSize;
			var bx = getBX() , by = getBY();
			var fb = stage.getXYBlock( bx , by + 1 );
			if(xs ==0 && ys == 0 ){
			 var cb = stage.getXYBlock( bx , by );
			 if( xMoveCnt > 0 ){
				xMoveCnt--;
				var xx = ((hFace > 0) ? 1 : -1);
				var lrb = stage.getXYBlock( bx + xx ,by);
//				status=xx;
				 xMove = xx * walkSpeed;
				if( (lrb & (B_Block|B_HHole)) !=0){
						xMoveCnt = xMove = 0;
				}
				else
				if( (lrb & (B_Enemy|B_Bomber)) !=0 && !fallFlag && stage.isFloor(fb)){
					if(!stage.kickBlock(this,bx+xx,by,xMoveCnt)){
						xMoveCnt = xMove = 0;
					}
				}
			 }else
				xMove = 0;
			 if( (fb & (B_Block | B_Bomber )) == 0)	fallFlag=true;
			 else	fallFlag=false;
			}
			if(fallFlag){
			 var fbb = stage.getXYPointBlock( x + width/2 , y+height+walkSpeed );
			 if( (fbb & (B_Block | B_Bomber )) == 0){
				xMove = 0;
				yMove = walkSpeed;
			 }else{
				yMove = 0;
				y=by*bSize;
				fallFlag=false;
			 }
			}
			moveBy(xMove,yMove);
		}
	}
	

	T.onCollided = function(obj){
		with(this){
			if(obj.mind == B_Digger){
				var obx = obj.getBX(),oby=obj.getBY();
				var bx = getBX(),by=getBY();
				if(obx==bx && oby==by){
				 soundSpriteManager.setImage(WaveTable.digger,1,0).moveTo( x , y );
				//if(stage.gameMode!=GameMode.BBR)
				stage.resetDiggerMask(obj);
				 stage.resetBomberMask(this);
				 kill();
				}
			}
		}
	}
	T.draw = function(){
		with(this){
			sprite.moveTo(x,y);
			sprite.draw();
			if(fukidashi)fukidashi.draw();
		}
	} //

	T.getScore = function(){
		with(this){
			if(!fukidashi){fukidashi = new Fukidashi(stage,x,y);fukidashi.setMaster(this);}
			score++;
			fukidashi.setWord(EventWord.mugyu2);
		}
	}
	T.speak = function(){}
	T.onKicked = function(obj,pow){
		with(this){
			var hf = obj.hFace;
			var bx = getBX(),by=getBY();
			var hb = stage.getXYBlock(bx,by-1),fb = stage.getXYBlock(bx,by+1);
			var lrb = stage.getXYBlock(bx+hf,by);
			if(xMoveCnt>0 && stage.gameMode==GameMode.BBR)return true;
			if(x% stage.blockSize!=0)return false;
			if((lrb & (B_Block|B_HHole))!=0)return false;
			if(!stage.isFloor(fb))return false;
			if(fallFlag)return false;
			if((hb & (B_MBlock|B_Bomber)) !=0 && stage.gameMode!=GameMode.BBR)return false;
			if((lrb & B_Bomber)!=0 && stage.gameMode!=GameMode.BBR)return false;
			if((lrb & (B_Enemy|B_Bomber))!=0 && stage.gameMode==GameMode.BBR){
				if(!stage.kickBlock(obj,bx+hf,by,pow))return false;
			}else
			if((lrb & (B_Enemy))!=0){
				if(!stage.kickBlock(obj,bx+hf,by,pow))return false;
			}
			hFace = hf;
			xMoveCnt=1;
			if(pow >= 8){xMoveCnt = 999;obj.speak(EventWord.kick999)}
			else
			if(pow >  4){xMoveCnt = 4;obj.speak(EventWord.kick5)}
			else		xMoveCnt = 1;
			return true;
		}
	}
	T.kill = function(){
		with(this){
			life=-1;
			if(fukidashi)fukidashi.kill();
			sprite.kill();
		}
	}
} //


function Fukidashi(stg,xx,yy){
	var T=this;
	ICharacter(T,stg);
	ISpriteControl(T);
	
	T.master="";
	T.wordArea="";
	T.counter = 0;
	T.counterStart = 30;
	
	T.sprite.setZ(103);
	T.currentWord="";
	
	T.maru1 = new Sprite();
	 T.maru1.setZ(102);
	 T.maru1.setImage("img/maru.gif",32,32);
	 T.maru1.moveTo(-10000,-10000);
	 T.maru1.setVisibility(true);
	T.maru2 = new Sprite();
	T.maru2.setVisibility(true);
	 T.maru2.setZ(102);
	 T.maru2.setImage("img/maru.gif",16,16);
	 T.maru2.moveTo(-10000,-10000);
	 T.maru2.setVisibility(true);
	
	T.oWidth= -1;
	T.oHeight=-1;
	
	T.setMaster = function(o){
		this.master = o;
	}
	
	T.setWord = function(w){
		with(this){
			if(w=="")return;
			counter = counterStart;
			if(w.length < 5)counter = w.length * 4;
			if(w != currentWord){
				var htmlSrc1 = '<table cellspacing=0 cellpadding=0 height=10><tr><td width=16><img src="'+IMAGEBASEDIR+'img/maruL.gif" style="width:16px;height:100%;"><td style="text-align:left;background:white;font-size:'+ FONT_SIZE +'px;padding:1%;font-weight:bolder;font-family:\'ＭＳ Ｐゴシック\'" nowrap>';
				var htmlSrc2 = '<td width=16><img src="'+IMAGEBASEDIR+'img/maruR.gif" style="width:16px;height:100%;"></table>';
			sprite.setHTML( htmlSrc1 + w + htmlSrc2 );
			sprite.update();
			}
			setPosition();
			setVisibility(true);
		}
	}
	
	T.action = function(){
		with(this){
			counter--;
			if(counter < 0 )return;
			else
			if(counter == 0 )
				setVisibility(false);
			else
				setPosition();
			
				return;
		}
	}
	T.setPosition = function(){
		with(this){
			 oWidth  = sprite.body.offsetWidth  / ( SCREEN_W / VSCREEN_W );
			 oHeight = sprite.body.offsetHeight / ( SCREEN_H / VSCREEN_H );
			var xx = master.x + master.width /2;
			var yy = master.y + master.height/2;
			x = xx - oWidth / 2 + 48;
			y = yy - oHeight    - 48;//;
			if(x < stage.scrollLeft ) x = stage.scrollLeft;
			if(y < stage.scrollTop )  y = yy + 60;
			if(y < 0 )  y = yy + 60;
			if(x + oWidth  > VSCREEN_W + stage.scrollLeft)
				x = stage.scrollLeft + VSCREEN_W - oWidth;
			sprite.moveTo(x,y);

			var cx = (xx - ( x + oWidth  /2 )) / 10;
			var cy = (yy - ( y + oHeight /2 )) / 10;
			maru1.moveTo(xx - cx * 8 -16 ,yy - cy * 8 -16);
			maru2.moveTo(xx - cx * 5 - 8 ,yy - cy * 5 - 8);
		}
	}
	
	T.draw = function(){
		with(this){
			sprite.draw();
			maru1.draw();
			maru2.draw();
		}
	}
	T.setVisibility = function(f){
		with(this){
			sprite.setVisibility(f);
			maru1.setVisibility(f);
			maru2.setVisibility(f);
		}
	}
	T.kill = function(){
		with(this){
			sprite.kill();
			maru1.kill();
			maru2.kill();
		}
	}
} //

function ScreenMessage(stg,xx,yy){
	var T=this;
	ICharacter(T,stg);
	ISpriteControl(T);
	
	T.master="";
	T.wordArea="";
	
	T.sprite.setZ(120);
	T.currentWord="";
	T.counter = 30;
	T.counterStart = 300;
	
	T.oWidth= -1;
	T.oHeight=-1;
	T.xMove=0;
	T.yMove=0;
	T.xAccel=0;
	T.yAccel=0;
	T.fontColor = "red";
	T.bgColor = "black";
	
	T.setWord = function(w){
		with(this){
			counter = counterStart;
			if(w != currentWord){
				var fsize = FONT_SIZE * 2;
				var htmlSrc1 = '<table cellspacing=0 cellpadding=0 border=3><tr><td style="text-align:center;font-size:'+ fsize +'px;font-weight:bolder;color:'+fontColor+';background:'+bgColor+';" nowrap>';
				var htmlSrc2 = '</table>';
			sprite.setHTML( htmlSrc1 + w + htmlSrc2 );
			sprite.update();
			}
			sprite.setOpacity(70);
			setPosition();
			setVisibility(true);
			return this;
		}
	}
	T.setVisibility = function(f){
		this.sprite.setVisibility(f);
	}
	T.setMotion = function(xm,ym,xa,ya){
		with(this){
			xMove = xm;
			yMove = ym;
			xAccel = xa;
			yAccel = ya;
			return this;
		}
	}

	
	T.action = function(){
		with(this){
			counter--;
			return true;
		}
	}
	T.moveTo = function(xx, yy){
		with(this){
			x = xx;y = yy;
			setPosition();
		}
	}
	T.setPosition = function(){
		with(this){
			 oWidth  = sprite.body.offsetWidth  / ( SCREEN_W / VSCREEN_W );
			 oHeight = sprite.body.offsetHeight / ( SCREEN_H / VSCREEN_H );
			var lx = x - oWidth  / 2;
			var ty = y - oHeight / 2;
			sprite.moveTo(lx,ty);
		}
	}
	
} //



//=========================================
//=========================================
//=========================================

function ScoreBoard(sc , fd){
	var T = this;
	T.isScoreBoard = true;
	T.time = 0;
	 T.timeF = null;
	T.plGold = 0;
	 T.plGoldF = null;
	T.stGold = 0;
	T.killCnt = 0;
	 T.killCntF = null;
	T.diggerCnt = 0;
	 T.diggerCntF = null;
	T.stageNumberF = null;
	T.scoreF = null;
	T.lifeF = null;

	T.vScreen = sc;
	T.field = fd;
	T.stage = null;
	T.player = null;
	T.initFlag = false;
	
	T.width=0;
	T.height=0;
	T.top = 0;
	T.left = 0;

	T.initHTML = function(html,stg){
	   with(this){
		stage = stg;
		field.innerHTML = html;
		var inp = field.getElementsByTagName("input");
		var img = field.getElementsByTagName("img");
		player = stage.getPlayer(0);
		timeF   = inp["time"];
		plGoldF = inp["playerGold"];
		diggerCntF = inp["diggerCnt"];
		killCntF = inp["killedEnemy"];
		stageNumberF = inp["stageNumber"];
		scoreF = inp["score"];
		lifeF = inp["life"];
		var ic = ImageCacheManager.instance;
		if(img["goldImg"])
				img["goldImg"].src  = IMAGEBASEDIR + StageImages.B_Gold;
		if(img["enemyImg"])
				img["enemyImg"].src = IMAGEBASEDIR + RobotImages.StandR;
		width = field.offsetWidth;
		height = field.offsetHeight;
		initFlag = true;
		action();
		draw();
	   }
	}

	T.action = function(){
		with(this){
			if(!initFlag)return;
			left = ( vScreen.clientWidth  - width  ) / 2 ;
			top  = ( vScreen.clientHeight - height );
		}
	}

	T.draw = function(){
		with(this){
			if(!initFlag)return;
			if(stage.frameCnt != time)
				timeF.value = time = stage.frameCnt;
			if(player.goldCnt != plGold || stage.goldCnt != stGold){
				plGold = player.goldCnt;
				stGold = stage.goldCnt;
				var g = stGold - plGold;
				plGoldF.value = g;
				if( g == 0 ){
					var fc =field.firstChild,s="style";
					plGoldF[s].color="red";
					if(fc[s]){
					 fc[s].color= "#ffff00";
					 fc[s].background="#000088";
					}
				}
			}
			if(stage.diggerCnt != diggerCnt)
				diggerCntF.value = diggerCnt = stage.diggerCnt;
			if(stage.killCnt != killCnt)
				killCntF.value = killCnt = stage.killCnt;

			if(left != field.style.left) field.style.left = left;
			if(top  != field.style.top ) field.style.top  = top;
		}
	}
	T.setChallengeModeParam = function(stg,score,life){
		with(this){
			if(stageNumberF){
			 stageNumberF.value = stg;
			 scoreF.value = score;
			 lifeF.value = life;
			 if(life == 1)lifeF.style.color="red";
			}
		}
	}
	
} //

function InputViewer(sc , fd){
	var T = this;
	T.isInputViewer = true;
	T.lastX = 0;
	T.x = 0;
	 T.lF = null;
	 T.rF = null;
	T.lastY = 0;
	T.y = 0;
	 T.uF = null;
	 T.dF = null;
	T.btA = 0;
	 T.btAF = null;
	 T.lastA=0;
	T.btB = 0;
	 T.btBF = null;
	 T.lastB=0;
	T.btC = 0;
	 T.btCF = null;
	 T.lastC=0;

	T.vScreen = sc;
	T.field = fd;
	T.initFlag = false;
	T.gamePad = null;
	T.width=0;
	T.height=0;
	T.top = 0;
	T.left = 0;
	T.s = "style";
	T.v = "background";

	T.V="red";T.H="#000000";

	T.initHTML = function(html,stg){
	   with(this){
		stage = stg;
		gamePad = stg.vGamePad;
		field.innerHTML = html;
		var inp = field.getElementsByTagName("img");
		uF   = inp["upKey"];
		dF   = inp["downKey"];
		lF   = inp["leftKey"];
		rF   = inp["rightKey"];
		btAF = inp["btA"];
		btBF = inp["btB"];
		btCF = inp["btC"];

		width = field.offsetWidth;
		height = field.offsetHeight;
		initFlag = true;
		action();
		draw();
	   }
	}

	T.action = function(){
		with(this){
			if(!initFlag)return;
			left=(vScreen.clientWidth-width);
		}
	}

	T.draw = function(){
		with(this){
			if(!initFlag)return;
			x=gamePad.x;y=gamePad.y;
			btA=gamePad.buttons[1];btB = gamePad.buttons[0]; btC = gamePad.buttons[2]; 
			if(x!=lastX){lastX=x;lF[s][v]=(x<0)?V:H;rF[s][v]=(x>0)?V:H;}
			if(y!=lastY){lastY=y;uF[s][v]=(y<0)?V:H;dF[s][v]=(y>0)?V:H;}
			if(btA!=lastA){btAF[s][v]=(btA>0)?V:H;lastA=btA;}
			if(btB!=lastB){btBF[s][v]=(btB>0)?V:H;lastB=btB;}
			if(btC!=lastC){btCF[s][v]=(btC>0)?V:H;lastC=btC;}
			if(left!=field[s].left)field[s].left=left;
			if(top!=field[s].top)field[s].top=top;
		}
	}
	
} //


//=========================================
//=========================================
//=========================================

function IStateManager(T){
	T.isIStateManager = true;
	T.call = function(){return this;}
	T.init = function(){return this;}
	T.action = function(){return this;}
	T.draw = function(){return this;}
	
} //

function TitleManager(sc,fd){
	var T = this;
	IStateManager(T);
	var flag = 0;
	T.vScreen = sc;
	T.field  = fd;
	T.cnt = 30;
	T.plY=0;

	T.init = function(){
		with(this){
			return this;
		}
	}
	T.initHTML = function(src){
		var s = src.replace(/!BASEDIR!/g,IMAGEBASEDIR);
		this.field.innerHTML = s;
	}

	T.call = function(){
		this.field.style.visibility="visible";
		this.field.style.clip = "rect(0%,100%,100%,0%)";
		this.flag = 0;
		this.cnt = 30;
		this.plY=player.getY();
		var yy =this.plY + ((this.plY < VSCREEN_H /2) ? VSCREEN_H : -VSCREEN_H);
		player.moveTo(player.getX(),yy);
		return this;
	}

	T.setStartFlag = function(){
		with(this){
			flag = 1;
			gamePad1.reset();

			if(vScreen.filters && false){
			 try{
				cnt = 15;
				vScreen.style.filter = "progid:DXImageTransform.Microsoft.Pixelate(duration=1);";
				vScreen.filters[0].enabled = true;
				vScreen.filters[0].Apply();
				field.style.visibility="hidden";
				vScreen.filters[0].Play();
			 }catch(e){}
			}else{
				cnt = 10;
			}
		}
	}

	T.action = function(){
	  with(this){
		if( flag == 0 && (gamePad1.buttons[0] != 0 || gamePad1.buttons[1] != 0 || gamePad1.x !=0 || gamePad1.y!=0)){
			setStartFlag();
		}
		if( flag == 1 ){
			cnt--;
			if(vScreen.filters && false){
			}else{
				var w = field.clientWidth , h = field.clientHeight;
				var p = ( (10 - cnt) * 10 ) / 2;
				var wp = w * p / 100,wwp = w - wp, hp = h * p / 100,hhp = h - hp;
				field.style.clip = "rect(" + 
						hp + "px," + wwp + "px," + hhp + "px," + wp + "px)";
			}
			var py = player.getY(); 
			if(py + 0 == py)
			player.moveBy(0,(plY - py) / 10);
		}
		
		if(cnt == 0){
			player.moveTo(player.getX(),plY);
			if(vScreen.filters && false)vScreen.style.filter="";
				return stageManager.call();
		}
		else
				return this;
	  }
	}
	
	T.draw = function(){
		player.draw();
		return this;
	}
	T.hide = function(){
			this.field.style.visibility="hidden";
	}
//	T.init();
} //


function StageMenuManager(sc,fd){
	var T = this;
	IStateManager(T);
	var flag = 0;
	T.vScreen = sc;
	T.field  = fd;
	T.cnt = 30;
	T.enabled=true;

	T.init = function(){return this;}
	T.initHTML = function(src){this.field.innerHTML = src;}

	T.call = function(){
		this.showWindow(0);
		this.flag = 0;
		this.cnt = 0;
		this.setStartFlag();
		var src = (stageManager.stageClear)	? 
					DGI("goalHTML").value : src = DGI("missedHTML").value;

		var gameOver = false;
		var stm = stageManager;
		var bonusInfo="";
		var continueEnable = false;
		if(challengeMode){
			parent.stageEnd(player , stageManager);
			bonusInfo = parent.playerParam.bonusInfo;
			gameOver = parent.gameOver;
			if(gameOver){stm = parent.playerParam;
			  if(!stageManager.replayMode && DGI("continueButton"))continueEnable=true;
			}
			else{
			 src = src.replace(/<form[^<]+<\/form>/gi,"");
			 src = src.replace(/<input[^>]+>/gi,"");
			 src = src.replace(/<textarea[^<]+<\/textarea>/gi,"");
			}
		}

		if(stageManager.replayMode && frameMode){
			src = src.replace(/<form[^<]+<\/form>/gi,"");
			src = src.replace(/<input[^>]+>/gi,"");
			src = src.replace(/<textarea[^<]+<\/textarea>/gi,"");
			if(!challengeMode){showBBS();
				this.field.style.display="none";
			}
			else{
				if(gameOver){showBBS();
				this.field.style.display="none";
				}
				else	this.flag=1;//this.setStartFlag();
			}
		}else{
			src = src.replace(/!CGIPATH!/g		,CGIPATH);
		}
		var msg=(stageManager.stageClear)?"＊ＳＴＡＧＥ　ＣＬＥＡＲ＊":"＊ＭＩＳＳ＊";
			src = src.replace(/!SYSVER!/g	,SYSVER);
			src = src.replace(/!GAMEMODE!/g	,stageManager.gameMode);
			src = src.replace(/!REPLAY!/g	,stm.getReplayCode());
			src = src.replace(/!FRAMECNT!/g	,stm.frameCnt);
			src = src.replace(/!DIGGERCNT!/g,stm.diggerCnt);
			src = src.replace(/!KILLCNT!/g	,stm.killCnt);
			src = src.replace(/!KEY!/g		,stm.key);
			if(challengeMode){
			 src = src.replace(/!GOLDCNT!/g	, stm.goldCnt);
			 if(gameOver && stageManager.stageClear){
			  src = src.replace(/!STAGENUMBER!/g,stm.startStage+"-END");
			 }else{
			  src = src.replace(/!STAGENUMBER!/g,stm.startStage+"-"+stm.stageNumber);
			 }
			 src = src.replace(/!LIFE!/g,stm.life);
			 src = src.replace(/!SCORE!/g,stm.score);
			 src = src.replace(/!CHALLENGEMODE!/g,1);
			 src = src.replace(/!BONUSINFO!/g,bonusInfo);
			 if(gameOver){
				src = src.replace(/!CONTINUE!/g,"-->");
				this.enabled = false;
				this.cnt=25;
				this.showWindow(100);
				msg = (stageManager.stageClear) ?
						"＊ＣＯＮＧＲＡＴＵＬＡＴＩＯＮ＊":"＊ＧＡＭＥ　ＯＶＥＲ＊";

			 }
			}
			else{
			 src = src.replace(/!STAGENUMBER!/g,0);
			 src = src.replace(/!LIFE!/g,0);
			 src = src.replace(/!SCORE!/g,0);
			 src = src.replace(/!CHALLENGEMODE!/g,0);
			 src = src.replace(/!BONUSINFO!/g,"");
			 src = src.replace(/!GOLDCNT!/g	, player.goldCnt+"/"+stm.goldCnt);
			}

			 src = src.replace(/!MSG!/g	, msg);

		this.initHTML(src);
		return this;
	}

	T.setStartFlag = function(){
		with(this){
			flag = 0;
			gamePad1.reset();
				cnt = 0;

		}
	}
	T.action = function(){
	  with(this){
		if(flag ==-1)return this;
		if( gamePad1.buttons[0] != 0 || gamePad1.buttons[1] != 0){
			flag = 1;
		}
		if( cnt <= 25 ){
			cnt++;
			if(vScreen.filters && false){
			}else{
				showWindow(cnt * 4);
			}
		}else{
			if(vScreen.filters)	vScreen.style.filter="";
		}
		
		if(flag == 1){
			flag=-1;
			showWindow(100);
			if(vScreen.filters)	vScreen.style.filter="";
			if(frameMode){
				if(enabled)		parent.stageStart();
				return this;
			}else{
				location.replace(location);
				return this;
			}
		}
		else
				return this;
	  }
	}
	
	T.showWindow = function(per){
		with(this){
			var p = 100- per;
			var w = field.clientWidth , h = field.clientHeight;
			var wp = w * p / 100 , wwp = w - wp , hp = h * p / 100 , hhp = h - hp;
			field.style.clip = "rect(" + 
					hp + "px," + wwp + "px," + hhp + "px," + wp + "px)";
			field.style.visibility="visible";
		}
	}
	
	T.hide = function(){
			this.field.style.visibility="hidden";
	}
} //


function DyingEventManager(sc,fd){
	var T = this;
	IStateManager(T);
	T.cnt=30;
	T.ymv=-8;
	T.yacc=2;
	T.call = function(){
		var px = player.getX() , py = player.getY();
		this.cnt=30;
		this.y = py;
		this.ymv=-10;
		soundSpriteManager.setImage(WaveTable.dead,1,0).moveTo( px , py );
		return this;
	}
	T.action = function(){
		with(this){
			ymv += yacc;
			player.moveBy(0,ymv);
			cnt--;
			if(cnt == 0)return stageMenuManager.call();
		 return this;
		}
	}
	T.draw = function(){
		with(this){
			player.draw();
			stageManager.draw();
			scoreBoard.draw();
			return this;
		}
	}
} //

function GoalEventManager(sc,fd){
	var T = this;
	IStateManager(T);
	T.field = fd;
	T.vScreen = sc;
	T.cnt=12;
	T.ymv=-0;
	T.mode = 0;
	T.scrollLeft=16;
	T.scrollTop=16;
	T.stageWidth = 0;
	T.stageHeight = 0;
	T.vScreenWidth=0;
	T.vScreenHeight=0;
	T.call = function(){
		with(this){
		 var px = player.getX() , py = player.getY();
		  scrollLeft = stageManager.scrollLeft;
		  scrollTop  = stageManager.scrollTop;
		  stageWidth = stageManager.getStageWidth();
		  stageHeight= stageManager.getStageHeight();
		  vScreenWidth = stageManager.vScreenWidth;
		  vScreenHeight= stageManager.vScreenHeight;
		 if( py <= 0 ){
		  mode = 0;
		  cnt=12;
		 }else{
		  mode = 1;
		  player.speak(EventWord.goal);
		  player.image = PlayerImages["gate"];
		  cnt = 300;
		 }
		
		soundSpriteManager.setImage(WaveTable.goal,1,0).moveTo( px,py );

		return this;
		}
	}
	T.action = function(){
		with(this){
			if(mode == 0){
			var xx = (player.x % 32);
			if(xx != 0)xx = (xx > 16) ? -8 : 8; //横方向位置補正
				player.moveBy(0,-4);
			}else
			if(mode == 1){
			  var py = player.y;
			  if(cnt < 290){
			   ymv-= 1;
			   player.moveBy(0,ymv);
			   player.fukidashi.action();
			   setScrollPoint();
			  }
			 if(py <= -32)cnt = 0;
			}

			cnt--;
			if(cnt <= 0)return stageMenuManager.call();
		 return this;
		}
	}
	T.setScrollPoint = function(){
		with(this){
			var px = player.getX() +16, py = player.getY() + 16;
			var sw = stageWidth , sh = stageHeight;
			var sl = px - vScreenWidth  / 2 ;
			var st = py - vScreenHeight / 2 ;
			if( sl < 16 ) sl = 16;
			if( sl > sw - vScreenWidth  -16 ) sl = sw - vScreenWidth -16;
			if( st < 16 ) st = 16;
			if( st > sh - vScreenHeight -16 ) st = sh - vScreenHeight-16;
			scrollLeft = sl;
			scrollTop  = st;
		}
	}
	T.scrollApply = function(){
		with(this){
			vScreen.scrollLeft = scrollLeft * (vScreen.clientWidth  / vScreenWidth);
			vScreen.scrollTop  = scrollTop  * (vScreen.clientHeight / vScreenHeight);
		}
	}
	T.draw = function(){
		with(this){
			player.draw();
			scrollApply();
			scoreBoard.draw();
			return this;
		}
	}
} //

function GameMode(){ // 敵出現アルゴリズムなどを切り替えたい
	GameMode.Other	= 0;
	GameMode.FC		= 1;
	GameMode.GBA	= 2;
	GameMode.DS		= 3;
	GameMode.IMode	= 4;
	GameMode.PC		= 5;
	GameMode.BBR	= 6;
	GameMode.Irem	= 7;
	GameMode.names = new Array("Normal","FC","GBA","DS","IMode","PC","BBR","Irem");
} //
GameMode();

function Point(xx,yy){
	this.x = xx;this.y = yy;
} //

function StageManager(sc,fd){
	var T = this;
	IStateManager(T);
	T.blockSize = 32;
	T.cols = VSCREEN_W / T.blockSize;
	T.rows = VSCREEN_H / T.blockSize;
	T.dat = new Array(0);
	T.stageData = new Array();
	T.underground= "";
	 T.ugEnable = 0;
	T.imageBaseDir = "";
	T.field = fd;
	T.vScreen = sc;
	T.mirrorMode = 0;
	T.wideMode=0;
	T.pixelRatio=1;
	T.table = "";
	T.cells = "";
	T.imgTable = new Array();
	T.gameMode = GameMode.Other;
	T.fcBugEnable = 1;
	T.editBugEnable=0;
	T.ladderBugEnable=0;
	T.robotTable="";
	T.lap=0;
	T.word = new Array();

//	 for(var i = 0; i <= B_Digger ; i++ )T.imgTable[i] = "";
	 T.imgTable[B_Blank]   = StageImages.B_Blank;	// 空白
	 T.imgTable[B_Brick]   = StageImages.B_Brick;	// ブロック
	 T.imgTable[B_Rock]    = StageImages.B_Rock;	// コンクリート
	 T.imgTable[B_Ladder]  = StageImages.B_Ladder;	// はしご
	 T.imgTable[B_Rope]    = StageImages.B_Rope;	// バー
	 T.imgTable[B_HHole]   = StageImages.B_HHole;	// 落とし穴
	 T.imgTable[B_HLadder] = StageImages.B_HLadder;	// 脱出はしご
	 T.imgTable[B_Gold]    = StageImages.B_Gold;	// 金塊
	 T.imgTable[B_Enemy]   = StageImages.B_Enemy;	// 敵
	 T.imgTable[B_Digger]  = StageImages.B_Digger;	// プレイヤー
	 T.imgTable[B_Gate]  = StageImages.B_Gate;	// 門
	 T.imgTable[B_Digger + B_Brick]  = StageImages.B_Digger;
	 T.imgTable[B_Digger + B_Enemy]  = StageImages.B_Digger;
	 T.imgTable[B_Digger + B_Player] = StageImages.B_Digger;
	 T.imgTable[B_HHole + B_Player] = StageImages.B_HHole2;
	 T.imgTable[B_Digger + B_Gold]   = StageImages.B_Gold;
	 T.imgTable[B_HLadder+ B_Gold]  = StageImages.B_Gold;
	 T.imgTable[B_Ghost  + B_Gold]   = StageImages.B_Gold;
	 T.imgTable[B_Enemy  + B_Gold]   = StageImages.B_Gold;
	 T.imgTable[B_Player  + B_Gold]   = StageImages.B_Gold;
	 T.imgTable[B_Ghost]  = "";
	 T.imgTable[B_Bomber]  = "";
	 T.imgTable[B_Bonus]   = StageImages.B_Bonus;
	 T.imgTable[B_Ghost  + B_Bonus]  = StageImages.B_Bonus;
	 T.imgTable[B_Enemy  + B_Bonus]  = StageImages.B_Bonus;
	 T.imgTable[B_HLadder+ B_Bonus]  = StageImages.B_Bonus;
	 T.imgTable[B_Player+ B_Bonus]  = StageImages.B_Bonus;

	T.creator = "Nanashi";
	T.startWord = EventWord.startWord;
	T.bgStyle="";
	T.bgColor="#000033";
	T.sysVersion = -1; // リプレイの互換性確保のために用意
	T.sysVersionF = -1;
	 T.sysVersionX = -1;
	
	T.frameCnt=0;
	T.inputRecorder = new InputRecorder();
	T.replayMode = false;
	T.pauseFlag = false;
	
	T.diggerSpeed = -1;
	T.diggerTime = -1;
	T.sleepTime = -1;
	T.goldReleaseTime = -1;
	T.fastStart = 0;
	T.magicHand = 0;
	T.lineZeroBlock = 1;
	
	T.giveupFlag = -1;
	 T.setGiveupFlag = function(){
		if((currentState == this && !this.replayMode) || this.autoReplay==1)
			this.giveupFlag = this.frameCnt + 1;
	}
	T.killCnt = 0;
	T.diggerCnt = 0;
	T.bomberCnt = 0;
	T.bomberACnt = 0;
	T.stageClear = false;
	T.key = 0;
	T.password="";
	
	T.goalGates = new Array();
	T.player = null;
	T.vGamePad = new GamePad();
	T.startX = 0;
	T.startY = 0;
	T.stageData = new Array();
	T.getStartX = function(){return this.startX * this.blockSize;}
	T.getStartY = function(){return this.startY * this.blockSize;}

	 T.vScreenWidth  = 0;
	 T.vScreenHeight = 0;
	 T.getVScreenWidth  = function(){return this.vScreenWidth;}
	 T.getVScreenHeight = function(){return this.vScreenHeight;}
	 T.scrollTop = 0;
	 T.scrollLeft = 0;

	T.robotEye = false;
	 T.setRobotEye = function(v){this.robotEye=v;}

	T.stageNumber = 0;
	T.scoreBoard = null;
	 T.addScoreBoard = function(bd,html){
			this.scoreBoard=bd;bd.initHTML(html,this);
	 }
	T.inputViewer = null;
	 T.addInputViewer = function(bd,html){
			this.inputViewer=bd;bd.initHTML(html,this);
	 }

	 T.getStageWidth  = function(){return this.cols * this.blockSize;}
	 T.getStageHeight = function(){return this.rows * this.blockSize;}

	 T.params = [];
	T.diggers = new ICharacterGroup();
	T.enemies = new ICharacterGroup();
	T.effects = new ICharacterGroup();
	T.bombers = new ICharacterGroup();

	T.randomizeValue = Math.floor(Math.random() * 1000);
	T.random = new Randomizer(T.randomizeValue);

	T.autoReplay=0;

	T.loadCnt = 0;
	T.loadStage = function(text){
	 with(this){
		if(loadCnt > 0 ){return;}
		loadCnt++;
		var tmp = text.split("\n");
		var dat = new Array();
		var rpFlag = false,rpCode="";;
		for(var i=0 ; i < tmp.length; i++){
			var line = tmp[i].replace(/[\t\n]/g,"").replace(/^[\t\s]+/,"").replace(/[\t\s]+$/,"");
			if(line.match(/^[\s\t]*#/))continue;
			line  =line.replace(/[\r\n]/g,"");
			if(!rpFlag && line.match(/^[0-9０-９ 　×ｘＸx田B■H井＃#♯ーｰ－￣\-弓己乙\|▲金\$凹M員買囚O♀PＡａ門扉Ｂｂ□Ｃｃ囚]+$/)){
				line = '"' + line + '"';
			}
			if(line.match(/^[\s\t]*["”│\|]([ 0-9a-f]+)["”│\|]/i)){
				dat.push(RegExp.$1);
				continue;
			}
			if(line.match(/^[\s\t]*["”│\|]([０-９ 　×ｘＸx田B■H井＃♯#ーｰ－￣\-弓己乙\|▲金\$凹M員買囚O♀PＡａ門扉Ｂｂ□Ｃｃ囚]+)["”│\|]/i)){
				var tl=RegExp.$1;
				 tl = tl.replace(/[０ 　×ｘＸx]/g,"0");
				 tl = tl.replace(/[１田B]/g,"1");
				 tl = tl.replace(/[２■H]/g,"2");
				 tl = tl.replace(/[３井＃♯#]/g,"3");
				 tl = tl.replace(/[４ー－-￣ｰ]/g,"4");
				 tl = tl.replace(/[５凹M]/g,"5");
				 tl = tl.replace(/[６弓己乙\|]/g,"6");
				 tl = tl.replace(/[７▲金\$]/g,"7");
				 tl = tl.replace(/[８員買O]/g,"8");
				 tl = tl.replace(/[９♀P]/g,"9");
				 tl = tl.replace(/[Ａａ門扉]/g,"a");
				 tl = tl.replace(/[Ｂｂ□]/g,"b");
				 tl = tl.replace(/[Ｃｃ囚]/g,"c");
				 dat.push(tl);
				continue;
			}
			if(line.match(/((\[|<)replay(\]|>))/)){
				rpFlag = true;
				line = line.replace(/(\[|<)replay(\]|>)/i,"");
			}
			if(rpFlag){
				rpCode += line.replace(/[\r\n]/,"");
			}
			if(line.match(/\[\/replay\]/)){
				rpFlag = false;
			}
			if( line.match(/^[\s\t]*word([0-9]+)[\s\t]*=(.+)/i) ){
				this.word[RegExp.$1] = unescape(RegExp.$2);
				continue;
			}
			if(line.match(/^[\s\t]*startWord=(.+)/i) ){
				this.startWord = RegExp.$1;
				continue;
			}
			if(line.match(/^[\s\t]*([a-z0-9_\/\\]+)[\s\t]*=[\s\t]*([#;\(\)%\-a-z0-9_\/\\\:\.=]+)/i)){
				this[RegExp.$1] = RegExp.$2;
				params[RegExp.$1] = RegExp.$2;
				continue;
			}
		}


		if(sysVersionX >= 0){
			sysVersion = parseInt(sysVersionX,16);
			params["sysVersion"] = sysVersion;
			SYSVER = parseInt(sysVersionX,16);
		}
		if(sysVersionF >= 0)
			SYSVER = parseInt(sysVersionF);
		if( rpCode != "" ){
			replayMode = true;
			startWord = EventWord.replayWord + startWord;
			inputRecorder.setRecordData(rpCode);
				SYSVER = parseInt(sysVersion);
		}
		if( imageBaseDir != "" && imageBaseDir != IMAGEBASEDIR ){
			IMAGEBASEDIR = imageBaseDir;
		}
		
		cols = 0;
		rows = dat.length;

		stageData = new Array(dat.length);
		for(var i = 0 ; i < dat.length ; i++){
			var line = dat[i];
			 line = line.replace(/[ ]/g,"0").replace(/[^0-9^a-f]/gi,"");
			if(cols < line.length) cols = line.length;
			var tmpArray = line.split("");
			stageData[i] = new Array();
			for(var j = 0 ; j < cols ; j++ )
					stageData[i][j] = ( 1 << ( parseInt(tmpArray[j],16) -1 ) ) & 0x7fff;
			stageData[i].push(B_Rock);
			stageData[i].unshift(B_Rock);
		}
		cols+=2;
		for(var i = 0 ; i < stageData.length ; i++ ){
			while( stageData[i].length < cols )stageData[i].push( B_Rock );
			if(mirrorMode == 1)stageData[i].reverse();
		}
		 var bLine = new Array(),tLine = new Array();//最上段と最下段を追加
		  while(bLine.length < cols ){ bLine.push(B_Rock);tLine.push(B_Rock);}
		  stageData.push(tLine);stageData.unshift(bLine);
		  for(var i=1;i<cols-1;i++)stageData[0][i] = B_Blank;
		rows+=2;
		underground = new Underground(this);

		if( !params["gameMode"]){
			if(cols== 16 && rows == 15)gameMode = GameMode.FC;
			if(cols== 30 && rows == 15)gameMode = GameMode.FC;
			if(cols== 17 && rows == 16)gameMode = GameMode.DS;
			if(cols== 30 && rows == 16)gameMode = GameMode.DS;
			if(cols== 28 && rows == 18)gameMode = GameMode.PC;
		}

		if(gameMode == GameMode.FC){
			ugEnable = true;
			lineZeroBlock=0;
			fcBugEnable=1;
			ladderBugEnable=1;
			if(cols==16)editBugEnable=1;
			if(diggerTime <= 0){
				diggerTime = 99;
			}
		}
		if(gameMode == GameMode.IMode){
			diggerTime = 70;
			fcBugEnable = 0;
		}
		if(gameMode == GameMode.PC)fcBugEnable=0;
		if(gameMode == GameMode.GBA){
				fcBugEnable=0;
				diggerTime=99;
		}
		if(gameMode == GameMode.DS){
			fcBugEnable=1;
			diggerTime = 99;
			ugEnable = 1;
			if(cols==17)editBugEnable=1;
			underground.setDsMode();
		}


		if(params["fcBugEnable"])fcBugEnable=params["fcBugEnable"];
		else fcBugEnable = (gameMode==GameMode.FC ||gameMode==GameMode.DS) ? 1 : 0;
		if(params["ladderBugEnable"])ladderBugEnable=params["ladderBugEnable"];

		if(params["magicHand"])magicHand=params["magicHand"];
		fastStart = 1;
		if(params["fastStart"])fastStart=params["fastStart"];
		if(params["diggerTime"])diggerTime=params["diggerTime"];

		if( lineZeroBlock==1 ){ //天井をオープンにするか埋めるか
			for(var i=1;i<cols-1;i++)stageData[0][i] = B_Rock;
		}else lineZeroBlock=0;

		if(vScreenWidth  <= 0)vScreenWidth  = getStageWidth() -32;	else pixelRatio=0;
		if(vScreenHeight <= 0)vScreenHeight = getStageHeight()-32;	else pixelRatio=0;
		if(OP){vScreenWidth+=32;vScreenHeight+=16;}//Opera

		if(pixelRatio != 0 && wideMode==0){
			var xr = vScreen.clientWidth*pixelRatio/vScreenWidth;
			var yr = vScreen.clientHeight/vScreenHeight;
			if(xr > yr)	vScreenWidth = vScreen.clientWidth / yr;
			else		vScreenHeight = vScreen.clientHeight / xr;
		}
		if(wideMode == 1){
			if(vScreenWidth == vScreenHeight){
				vScreenWidth = vScreenHeight = vScreenHeight /2;
			}else{
			 if(vScreenWidth > vScreenHeight)vScreenWidth = vScreenHeight;
			 if(vScreenHeight > vScreenWidth)vScreenHeight = vScreenWidth;
			}
		}

		VSCREEN_W = getVScreenWidth();
		VSCREEN_H = getVScreenHeight();
		STAGE_W = getStageWidth();
		STAGE_H = getStageHeight();

		frameCnt = 0;
		random.set(randomizeValue);
		createStage();
		createCharacters();
		if(	ImageCacheManager.complete )firstDraw();

		setScrollPoint();
		scrollApply();

		return true;
	 }
	}

	T.imgTmpFlag = 0;
	T.createStage = function(){
	 with(this){
		if(imgTmpFlag==1)return;
		 imgTmpFlag = 1;
		 var tbl = new String(),tr="",trr = new Array();
		 var tw = field.clientWidth  / vScreenWidth * blockSize;
		 var th = field.clientHeight / vScreenHeight * blockSize;
		 var twi = Math.floor(tw) , twf=tw-twi , thi = Math.floor(th) , thf=th-thi;
		 var colcnt=0 , colcntMax=0 , colMax=0 , colPix=0 , rowmax=0 , thftmp=0 ;

		  for(var i = 0;i < stageData.length ; i++){

			 thitmp =thi;
			 thftmp+=thf;
			  if(thftmp >= 1){thitmp+=1;thftmp-=1;}// 小数点以下誤差補正
			colcnt=0;
			
			 var twftmp=0;
			 colPix=0;

			tr = "<tr>";
			var trh = ';height:'+thitmp ;
			for(var j = 0 ; j < stageData[i].length ; j++ ){
			 colcnt++;
			 var twitmp=twi;
			 twftmp+=twf;
			  if(twftmp>=1){ twitmp+=1;twftmp-=1;}// 小数点以下誤差補正

			  var wh = 'style=width:' + twitmp + trh;
				tr = tr.concat('<td '+wh+'><img '+wh+';visibility:hidden;>');
			  colPix+=twitmp;
			}
			tbl = tbl.concat(tr);


			rowmax+=thitmp;
			if(colMax<colPix){colMax=colPix;colcntMax=colcnt;}
		  }
  tbl=
	'<table style="position:absolute;table-layout:fixed;width:'+colMax+';top:0px;left:0px;margin:0;padding:0;background:'+ bgColor +';'+ bgStyle +';" cellspacing="0" cellpadding="0" onclick="if(DA)dummyFocus()" unselectable="true">'
	+tbl+
	'</table>';

		field.innerHTML = tbl;
		table = field.firstChild;
		var imgs = field.getElementsByTagName('IMG');
		var k = 0;
		cells = new Array();
		for(var i = 0 ; i < rows ; i ++ ){
			cells[i] = new Array();
			for(var j = 0 ; j < cols ; j++ ) cells[i][j] = imgs[k++];

		}
		
		var par = vScreen.parentNode;
		if( table.offsetWidth - field.clientWidth  < -32 ){
			vScreen.style.width = table.offsetWidth;
			vScreen.style.left = (par.clientWidth - vScreen.offsetWidth) / 2;
		}
		if(table.offsetHeight - field.clientHeight < -32 ){
			vScreen.style.height = table.offsetHeight;
			vScreen.style.top = (par.clientHeight - vScreen.offsetHeight) / 2;
		}
		
		 return tbl;
	 }
	}
	T.onCacheComplete = function(obj){this.firstDraw(obj);}

	T.getPlayer = function(){return this.player;}
	T.createCharacters = function(){
		with(this){
			var y,x;
			var sx=13,sy=7;
			var rndRobo,rndCnt=2;
			sx = Math.floor(cols / 2);
			if(cols == 16 && gameMode == GameMode.FC)sx=13;
			sy = Math.floor(rows / 2);
			player = new Player( this , 32*sx , 32*sy );
			startX = sx;startY=sy;
			player.setGamePad(vGamePad);

			for(y = stageData.length - 1 ; y >= 0 ; y-- ){
				for(x = stageData[y].length -1 ; x >= 0 ; x-- ){
//			for(y = 0; y<stageData.length ; y++ ){
//				for(x = 0; x<stageData[y].length ; x++ ){
					var b = stageData[y][x],xb=x*blockSize,yb=y*blockSize;
					switch(b){
						case B_Player:
							startX = x;	startY = y;
							player.moveTo(getStartX(),getStartY());
							player.init();
							stageData[y][x] = B_Ghost;
						break;
						case B_Enemy:
						case B_HEnemy:
						 if(gameMode!= GameMode.GBA || !rndRobo || b!=B_HEnemy){
							var rbt = new Robot( this , xb , yb );
							rbt.setTarget(player);
							if(sleepTime >= 0)rbt.sleepCntStart = sleepTime;
							if(goldReleaseTime >= 0)rbt.goldRelease = goldReleaseTime;
							
							enemies.add(rbt);
							if(b==B_Enemy)stageData[y][x] = B_Ghost | B_Enemy;
							else{
							 stageData[y][x] = B_Brick;
							 rndRobo=rbt;
							 rbt.hide();
							}
						 }else{//簡易シャッフル
							if(random.get() % rndCnt++==0){
								rndRobo.moveTo(xb,yb);
								rndRobo.hide();
							}
							stageData[y][x] = B_Brick;
						 }
						break;
						case B_Gold:
							goldCnt++;
						break;
						case B_Gate:
							goalGates.push(new Point(x,y));
							stageData[y][x] = B_Blank;
						break;
						case B_MBlock:
							var mb = new MBlock(this,x*blockSize,y*blockSize);
							bombers.add(mb);
							stageData[y][x] = B_Bomber;
						break;
					}
				}
			}
		}
	} 


	T.onResize = function(){
		with(this){
			vScreen.style.width = "100%";
			vScreen.style.height= "100%";
			vScreen.style.top = vScreen.style.left = 0;
			SCREEN_W = vScreen.clientWidth;
			SCREEN_H = vScreen.clientHeight;
		 var tw = SCREEN_W / vScreenWidth  * blockSize,
			 th = SCREEN_H / vScreenHeight * blockSize,
			 twi = Math.floor(tw) , twf=tw-twi, thi = Math.floor(th) , thf=th-thi,thftmp=0;
		field.style.display="none";
		table.style.width =tw * cols;table.style.height=th * rows;
		  for(var i = 0;i < cells.length ; i++){
			 thitmp =thi;
			 thftmp+=thf;
			  if(thftmp >= 1){thitmp+=1;thftmp-=1;}// 小数点以下誤差補正
			 var twftmp=0;
			for(var j=0 ; j < cells[i].length ; j++ ){
			 var twitmp=twi;
			 twftmp+=twf;
			  if(twftmp>=1){ twitmp+=1;twftmp-=1;}// 小数点以下誤差補正

			  var cell = cells[i][j] , td = cell.parentNode;
				  cell.style.width=twitmp;
				  td.style.width=twitmp;
				  cell.style.height=thitmp;
				  td.style.height=thitmp;
			}
		  }
		var par = vScreen.parentNode;

		if( table.offsetWidth - field.clientWidth  < -32 ){
			vScreen.style.width = tw * cols;
			vScreen.style.left = (par.clientWidth - tw * cols) / 2;
		}
		if(table.offsetHeight - field.clientHeight < -32 ){
			vScreen.style.height = th * rows;
			vScreen.style.top = (par.clientHeight - th * rows) / 2;
		}

			player.updateSprite();
			diggers.updateSprite();
			enemies.updateSprite();
			bombers.updateSprite();
		scrollApply();
		field.style.display="";
		}
	}


	T.getXYBlockR = function(xp,yp){// ロボ視点でのgetXYBlock
		if(xp==0 || yp < 0)return B_Blank;
			if(this.ugEnable==1)return this.underground.getXYBlock(xp,yp);
			if( xp == this.cols -1){
				if(yp < this.rows-1 )return (this.editBugEnable ==1) ? B_Rock : B_Blank;
				else return B_Blank;
			}
		if( xp < 0 || xp >= this.cols || yp >= this.rows ) return B_Rock;
		 	return this.stageData[yp][xp];
	}

	T.getXYBlock= function(xp,yp){
		if(yp < 0)return B_Blank;
		if( xp < 0 || xp >= this.cols || yp < 0 || yp >= this.rows ) return B_Rock;
			return this.stageData[yp][xp];
	}


	T.getXYPointBlock = function(xx,yy){
		 return this.getXYBlock(
							Math.floor( xx / this.blockSize ) , 
							Math.floor( yy / this.blockSize ) );
	}
	T.getCurrentBlock = function(ch){
		if(!ch.isIPosition)return 0;
		return this.getXYBlock( ch.getBX() , ch.getBY() );
	}

	T.getXYBlockSize = function(xp,yp){
	 with(this){
		if( xp < 0 || xp >= cols || yp < 0 || yp >= rows ) return blockSize;
		 return new ISize(cells[yp][xp].style.width,cells[yp][xp].style.height);
	 }
	}
	T.getXYPointBlockSize = function(xx,yy){
		return this.getXYBlockSize(	
							Math.floor( xx / this.blockSize ) , 
		 					Math.floor( yy / this.blockSize ) );
	}

	
	T.setXYBlock = function(xp,yp,block,flag){
	 with(this){
		if( xp < 0 || xp >= cols || yp < 0 || yp >= rows ) return 2;
		 if(yp > stageData.length )return 0;
		 if(xp > stageData[yp].length )return 0;
		 if(block < 0)return 0;
		 // 厳密には、セルの書き換えはdraw内で行うべき
		 if(flag != 1 ){
			var bb = block & ~(B_Enemy|B_Bomber|B_Ghost);
			if(imgTable[bb] != ""){
				 cells[yp][xp].src = IMAGEBASEDIR + imgTable[bb];
		 	 	 cells[yp][xp].style.visibility= "visible";
		 	}else{
		 	 	 cells[yp][xp].style.visibility= "hidden";
		 	}
		 }
		 if(flag != -1){
			 stageData[yp][xp] = block;
			 var bf = stageData[yp][xp];
			 underground.setSwitch(xp,yp,bf,block);
		 }
		 return stageData[yp][xp];
	 }
	}
	T.updateBlock = function(obj){this.underground.updateSwitch();}
	T.updateHHole = function(xx,yy){this.setXYBlock(xx,yy,B_HHole+B_Player,-1);}
	T.setXYPointBlock = function(xx,yy,block,flag){
		 return this.setXYBlock(
							Math.floor( xx / this.blockSize ),
							Math.floor( yy / this.blockSize ),block,flag);
	}
	T.setCurrentBlock = function(ch,block,flag){
		if(!ch.isIPosition)return 0;
		var cx = ch.getX() + ch.getWidth()  / 2 , cy = ch.getY() + ch.getHeight() / 2;
		return this.setXYPointBlock(cx,cy,block,flag);
	}
	
	T.action = function(){ // stageAction
		with(this){
		frameCnt++;
		 var padState;
		 if(replayMode)	padState = inputRecorder.play(gamePad1,frameCnt);
		 else			padState = inputRecorder.record(gamePad1,frameCnt);
		 vGamePad.setPadState(padState);
		 if( frameCnt == 1 && goldCnt == 0 ) createLadder();// 金塊が無い面
			//ランナー
			//レンガ再生 
			//埋まったら死亡 
			//敵の移動
			//敵にさわられたら死亡 
			 resetPlayerMask(player);
			player.action();
			 setPlayerMask(player);
			diggers.action();
			 diggers.collision(enemies);
			 diggers.collision(bombers);
			 diggers.collision(player);
			bombers.action();
			enemies.action();
			underground.action();
			enemies.collision(player);
			bombers.collision(player);
			bombers.collision(enemies);


			effects.action();
			scoreBoard.action();
			inputViewer.action();

		  resetPlayerMask(player);



			if(word[frameCnt])
				player.speak(word[frameCnt].replace(/^#C-/,""));
			if(frameCnt == giveupFlag){
				table.style.background="#880000";
				player.giveup();
			}

			setScrollPoint();

			if(pauseFlag){
				pauseFlag = false;
				return pauseScrollManager.call(this);
			}
			if(
				(player.y <= 0 && player.ladderFlag && goalGates.length < 1 &&  goldCnt <= player.goldCnt) || 
				(gameMode == GameMode.DS && player.y <= 32 && goldCnt <= player.goldCnt && goalGates.length < 1) ||
				player.goalGateFlag
			){
				stageClear = true;
				return goalEventManager.call();
			}
			if(player.dead)return dyingEventManager.call();
			if(replayMode && !challengeMode && !inputRecorder.hasNext){
				if(autoReplay==1)return dyingEventManager.call();
				replayMode = false;
				return pauseScrollManager.call(this);
			}
				return this;
		}
	}

	T.setSpeaking = function(w,pl,f){
		with(this){
		var fs=(f)?f:1;
		if(currentState == this && !this.replayMode)word[ frameCnt+fs ] = w;
			return w;
		}
	}
	
	T.setPauseFlag = function(){this.pauseFlag = true;}

	T.setScrollPoint = function(){
		with(this){
			var w = 16 , px = player.getX() +w, py = player.getY() + w;
			var sw = getStageWidth() , sh = getStageHeight();
			var sl = px - vScreenWidth  / 2 , st = py - vScreenHeight / 2 ;
			if( sl < w ) sl = w;
			if( sl > sw - vScreenWidth  -w ) sl = sw - vScreenWidth -w;
			if( st < w ) st = w;
			if( st > sh - vScreenHeight -w ) st = sh - vScreenHeight-w;
			scrollLeft = sl;scrollTop  = st;
		}
	}

	T.draw = function(){
		with(this){
			diggers.draw();
			effects.draw();
			bombers.draw();
			enemies.draw();
			player.draw();
			scrollApply();
			underground.draw();

			scoreBoard.draw();
			inputViewer.draw();
		}
	}
	T.scrollApply = function(){
		with(this){
			vScreen.scrollLeft = scrollLeft * (vScreen.clientWidth  / vScreenWidth);
			vScreen.scrollTop  = scrollTop  * (vScreen.clientHeight / vScreenHeight);
		}
	}

	T.call = function(){
	 with(this){
		if(scoreBoard && challengeMode){
			var pp = parent.playerParam;
			scoreBoard.setChallengeModeParam(pp.stageNumber,pp.score,pp.life);
		}
		firstDraw();
		return this;
	 }
	}

	T.firstDraw = function(){
	 with(this){
		if(imgTmpFlag == 1){
			imgTmpFlag = 0;
			for(var y = 0 ; y < cells.length ; y ++ ){
				for(var x = 0 ; x < cells[y].length ; x ++ ){
					var sd = stageData[y][x] & ~(B_Enemy|B_Bomber|B_Ghost);
					if(x==startX && y==startY){ 
						//モナーを置かなかった場合の出現位置にあるブロック
						if(sd == B_Brick) stageData[y][x] = B_Blank;
						if(imgTable[sd] != ""){
						 cells[y][x].src = IMAGEBASEDIR + imgTable[sd];
						 cells[y][x].style.visibility = "visible";
						}
					}else
					if(imgTable[sd] != ""){
						cells[y][x].src = IMAGEBASEDIR + imgTable[sd];
						cells[y][x].style.visibility = "visible";
					}
				}
			}
		}
	 }
	}

	T.isBlank = function(b){ // レンガの上に余計な物がないか
		switch(b){
			case B_Blank:	case B_HLadder:	case B_Ghost:
			case B_Digger://	case B_Bomber:
			return true;
		}
		return false;
	}

	T.isBlankB = function(b){ // レンガの上に余計な物がないか(隠れハシゴ含む)
		return ( b == B_Blank );
		return false;
	}
	
	T.isWall = function(b){ // ブロック
		return ( ((  b & ( B_Block | B_Bomber ))) != 0 );
	}
	T.isWallB = function(b){ // ブロック
		return ( ((  b & ( B_Block | B_HHole | B_Bomber ))) != 0 );
	}

	T.isWallOrRobot = function(b){ // ブロックまたは敵
		return ( (  b & ( B_Block | B_Enemy )) != 0 );
	}

	 T.floor = ( B_Brick | B_Rock | B_Ladder | B_Enemy | B_Bomber | B_MBlock);
	T.isFloor = function(b){ // ブロック・はしご・埋まった敵
		return ( (  b & this.floor ) != 0 );
	}
	 T.floorRA = ( B_Block | B_Ladder | B_Rope | B_Gold | B_Digger | B_Bomber | B_MBlock);
	T.isFloorRA = function(b){ // ブロック・はしご・ロープ・金塊・掘ったブロック
		return ( (  b & this.floorRA ) != 0 );
	}

	T.isFloorR = function(b){ // ブロック・はしご・掘ったブロック
		return ( (  b & ( B_Block | B_Ladder | B_Digger )) != 0 );
	}

	T.isFloorRB = function(b){ // ブロック・掘ったブロック
		return ( (  b & ( B_Block | B_Digger )) != 0 );
	}
	T.isFloorRC = function(b){ // ハシゴ、バー、落とし穴、金塊、掘ったレンガ
		return ( (  b & ( B_Ladder | B_Rope | B_HHole | B_Gold | B_Digger )) != 0 );
	}

	T.isBrick	= function(b){return b == B_Brick;}
	T.isLadder	= function(b){return (b & B_Ladder) != 0;}
	T.isRope	= function(b){return (b & B_Rope) != 0;}
	T.isGold	= function(b){return (b & B_Gold) != 0;}
	T.isGate	= function(b){return (b & B_Gate) != 0;}
	T.isEnemy	= function(b){return (b & B_Enemy) != 0;}
	T.isDigger	= function(b){return (b & B_Digger) != 0;}
	T.isBonus	= function(b){return (b & B_Bonus) != 0;}
	
	T.goldCnt = 0;
	T.getGold = function(obj){ //金塊ゲット
	 with(this){
		resetGoldMask(obj);
		if( goldCnt - player.goldCnt == 1)player.speak(EventWord.last1);
		if( goldCnt == player.goldCnt ) createLadder();
		if( obj.isPlayer ){
			var wav = WaveTable.gold;
			soundSpriteManager.setImage(wav,1,0).moveTo( obj.getX() , obj.getY() );
			
		}
		return 1;
	 }
	}
	T.getBonus = function(obj){
	 with(this){
		resetBonusMask(obj);
		goldCnt+=10;
		if( obj.isPlayer ){
			var wav = WaveTable.gold,xx=obj.getX(),yy=obj.getY();;
			soundSpriteManager.setImage(wav,1,0).moveTo( xx,yy );
			soundSpriteManager.setImage(wav,1,0).moveTo( xx,yy );
			soundSpriteManager.setImage(wav,1,0).moveTo( xx,yy );
		}
		return 10;
	 }
	}
	T.lostGold = function(obj){
	 with(this){
		goldCnt--;
		var wav = WaveTable.gold;
		soundSpriteManager.setImage(wav,1,0).moveTo( obj.getX() , obj.getY() );
		if( goldCnt <= player.goldCnt ) createLadder();
	 }
	}
	
	T.setGold = function(obj,ct){ //金塊セット
	 with(this){
		var bx = obj.getBX(),by = obj.getBY();
		if(!ct)by -=1;//一個上に落とす
			this.setXYBlock(bx , by , this.stageData[by][bx] |=  B_Gold);
	 }
	}
	T.setGoldXY = function(xx,yy){ //金塊セット
	 with(this){
		if(xx<0||yy<0||xx>=cols||yy>=rows)return;
			this.setXYBlock(xx , yy , this.stageData[yy][xx] |=  B_Gold);
	 }
	}
	T.setBonus = function(obj,ct){
	 with(this){
		var bx = obj.getBX(),by = obj.getBY();
		if(!ct)by -=1;//一個上に落とす
			this.setXYBlock(bx , by , this.stageData[by][bx] |=  B_Bonus);
	 }
	}
	
	
	
	T.createDigger = function(pl,bx,by){ //穴を掘る
		with(this){
			var xx = bx * blockSize,yy=by * blockSize;
			var dg = new Digger(this,xx,yy);
			diggerCnt++;
			soundSpriteManager.setImage(WaveTable.digger,1,0).moveTo( xx , yy );
			dg.setMaster(pl);
			diggers.add(dg);
			return dg;
		}
	}
	T.createBreaker = function(pl,bx,by){ //壁を壊す
		with(this){
			if( bx < 1 || by < 1)return;
			var xx = bx * blockSize,yy=by * blockSize;
			var b = getXYBlock(bx,by) & ~(B_Bomber|B_Digger);
			var dg;
			if( b == B_Brick || b == B_Net ){
				dg = new Digger(this,xx,yy,true);
				diggerCnt++;
			}else
				dg = new Explosion(this,xx,yy);
			dg.setMaster(pl);
			diggers.add(dg);
			soundSpriteManager.setImage(WaveTable.digger,1,0).moveTo( xx , yy );
			return dg;
		}
	}
	T.createBomber = function(pl,bx,by,flag){ //爆弾を出す
		with(this){
			if(bomberACnt > 4)return null;
			var xx = bx * blockSize,yy=by * blockSize;
			var bm = new Bomber(this,xx,yy,flag);
			bomberCnt++;bomberACnt++;
			bm.setMaster(pl);
			bombers.add(bm);
			return bm;
		}
	}
	T.explode = function(obj){
		with(this){
			var p = obj.master ,bs = blockSize;;
			var bx = obj.getBX(),by = obj.getBY();
			bomberACnt--;
			if(gameMode != GameMode.BBR)return;
			createBreaker(p,bx,by-2);
				createBreaker(p,bx-1,by-1);
				createBreaker(p,bx  ,by-1);
				createBreaker(p,bx+1,by-1);
					createBreaker(p,bx-2,by);
					createBreaker(p,bx-1,by);
					createBreaker(p,bx  ,by);
					createBreaker(p,bx+1,by);
					createBreaker(p,bx+2,by);
				createBreaker(p,bx-1,by+1);
				createBreaker(p,bx  ,by+1);
				createBreaker(p,bx+1,by+1);
			createBreaker(p,bx,by+2);
		}
	}
	T.kickBlock = function(obj,xx,yy,pow){
		with(this){
			var b = stageData[yy][xx],ret=true,bm,i;
			if( gameMode == GameMode.BBR &&(b & (B_Net | B_Brick)) != 0 )
				return createDigger(obj,xx,yy);
			if( (b & B_Bomber) != 0){
				bm = bombers.getMembers();
				for(i = 0 ; i < bm.length ;i++){
					if(bm[i].getBX() == xx && bm[i].getBY() == yy)
						ret&=bm[i].onKicked(obj,pow);
				}
			}
			if( (b & B_Enemy) != 0){
				bm = enemies.getMembers();
				for(i = 0 ; i < bm.length ;i++){
					if(bm[i].getBX() == xx && bm[i].getBY() == yy)
						ret&=bm[i].onKicked(obj,pow);
				}
			}
			return ret;
		}
	}


	T.createLadder = function(){
		with(this){
			if(goalGates.length > 0){
			 for(i = 0 ; i < goalGates.length ; i++ ){
					var g = goalGates[i];
					setXYBlock( g.x , g.y , B_Gate );
			 }
			 for(y = 0 ; y < stageData.length ; y++ ){
				for(x = 0 ; x < stageData[y].length ; x++ ){
					if( (stageData[y][x] & ( B_HLadder | B_Ladder ) ) != 0 )
							setXYBlock( x , y , B_Ladder );
				}
			 }
			}else{
			 var t="";
			 var lx = -1 , ly = -1;
			 for(y = 0 ; y < stageData.length ; y++ ){
				for(x = 0 ; x < stageData[y].length ; x++ ){
					if(gameMode == GameMode.FC || gameMode == GameMode.DS){}
					else{
					 if( y == 1 ){
						if(	(stageData[1][x] & ~(B_Enemy|B_Ghost|B_Bomber)) == B_Blank &&
							(stageData[2][x] &( B_HLadder|B_Ladder) ) != 0)
								setXYBlock( x , y , B_Ladder);
					 }
					}
					
					if( (stageData[y][x] & ( B_HLadder | B_Ladder ) ) != 0 ){
						lx = x ; ly = y;
							setXYBlock( x , y , B_Ladder );
						if(y == 1)
							setXYBlock( x , 0 , B_Ladder );
					}
				}
			 }
			 if(lx >= 0 && ly >= 0)underground.setSwitch(lx,ly,B_HLadder,B_Ladder);
			 if(gameMode == GameMode.DS){
				for( var i = 1 ; i < cols - 1 ; i++)setXYBlock(i,0,B_Blank);
			 }
			}
			player.speak(EventWord.gotoGoal);
		}
	}
	
	T.resurrectEnemy = function(obj){
		with(this){
			killCnt++;
		if(gameMode==GameMode.IMode){obj.moveTo(obj.startX,obj.startY);return;}
		if(gameMode==GameMode.GBA){
			var bx = obj.getBX();
			for(var i=0;i<4;i++){
				var ix = bx + (i % 2),iy=1 + (i>>1);
				var k =stageData[iy][ix] & ~(B_Ghost);
				if(k == B_Blank || k==B_HLadder){
					obj.moveTo(ix*blockSize,iy*blockSize);
					return;
				}
			}
			var s = getXYPointBlock(obj.startX,obj.startY);
			if((s & (B_Player | B_Bomber | B_Enemy)) == 0){obj.moveTo(obj.startX,obj.startY);return;}
		}

			 var r = (random.get() % (cols-2)) + 1;
			 var bm = B_Enemy | B_Ghost;
			 var sline = (lineZeroBlock == 1) ? 2 : 1;
			 if(gameMode==GameMode.GBA){sline=0;bm=B_Ghost;}

			 //FC・DSのバグを再現
				if( editBugEnable > 0 && cols < 30 ){
					r = (random.get()% 28) +1;
					if(r>= cols-1){r=0;sline++;}
				}

			 var bt = ~bm;
			 var rb = stageData[sline][r] & bt;
			 if(gameMode==GameMode.GBA)rb=B_Brick;

			 if( rb == B_Blank || rb == B_HLadder)
				obj.moveTo(r * blockSize , sline*blockSize);
			 else{
				if(gameMode!= GameMode.GBA){
					for(var x = r+1 ; x < cols - 1; x++){
						var lx = stageData[sline][x] &bt;
						if(lx == B_Blank || lx == B_HLadder ){
							obj.moveTo(x * blockSize , sline * blockSize);
							return;
						}
					}
				}
				for(var y = sline+1; y < rows -1 ; y++){
					var line = stageData[y];
					for(var x = 1 ; x < cols - 1; x++){
						var lx = line[x] & bt;
						if(lx == B_Blank || lx == B_HLadder ){
							obj.moveTo(x * blockSize , y * blockSize);
							return;
						}
					}
				}
				if(gameMode==GameMode.GBA)obj.moveTo(obj.startX,obj.startY);
				else	obj.moveTo(3 * blockSize , (rows -1) * blockSize);
			 }
	 }
	}

	T.getMapText = function(format){
	 with(this){
		var t = '';
		for(var i = 0 ; i < dat.length ; i++ ){
			t += '"'+dat[i] + '"\n';
		}
		var fm="";
		if( !format )format="";
		if( format == "JP" )
			fm="×田■＃－凹己▲員♀門□囚".split();
		else
		if(format.length >= 10) fm = format;

		if(fm != ""){
			for(var i = 0 ; i < fm.length ; i++ ) t = t.replace( i , fm[i] );
		}

		for(p in params){
			if(p=="key")continue;
			if(p=="giveupFlag")continue;
			t += p+" = "+params[p]+"\n";
		}
		return t;
	 }
	}

	T.getReplayCode = function(){
		with(this){
			var ret = getMapText()+"\n";
			ret += "randomizeValue=" + randomizeValue + "\n";
			ret += "sysVersion=" + SYSVER + "\n";
			if(key != 0)ret += "key=" + key +"\n";
			if(giveupFlag > 0)ret += "giveupFlag =" + giveupFlag + "\n";
			
			for(var v in word){
				if(!word[v].match(/^#C-/))
					ret += 'word'+ v +'=' + escape(word[v]) + '\n';
			}

			ret += "[replay]\n" + inputRecorder.getRecordData();
			return ret;
		}
	}
	
	T.cancelReplay = function(){this.replayMode = false;}
	
	T.setPlayerMask = function(obj){
		if(this.ladderBugEnable>0 && obj.ladderBugFlag)return;
		if(obj.y<0)return;
		var bx = obj.getBX(),by = obj.getBY();
				this.stageData[by][bx] |=  B_Player;
	}
	T.resetPlayerMask = function(obj){
		if(obj.y<0)return;
		var bx = obj.getBX(),by = obj.getBY();
			this.stageData[by][bx] &= ~B_Player;
	}
	T.setDiggerMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
		var rt = this.stageData[by][bx];
			this.stageData[by][bx] = B_Digger;
			this.underground.setSwitch(bx,by-1,B_Blank,B_Blank);
		return rt;
	}
	T.resetDiggerMask = function(obj){
		var rest = B_Brick; if(obj.isDigger)rest= obj.defaultBlock;
		var bx = obj.getBX(),by = obj.getBY();
			this.setXYBlock(bx,by,rest);
	}
	T.setBomberMask = function(obj){
		if(this.gameMode != GameMode.BBR && !obj.isMBlock)return;
		var bx = obj.getBX(),by = obj.getBY();
			this.stageData[by][bx] |=  B_Bomber;
	}
	T.resetBomberMask = function(obj){
		if(this.gameMode != GameMode.BBR && !obj.isMBlock)return;
		var bx = obj.getBX(),by = obj.getBY();
			this.stageData[by][bx] &= ~B_Bomber;
	}
	T.clearBomberMask = function(){
		with(this){
			if(this.gameMode != GameMode.BBR)return;
			var m = ~B_Bomber;
			for(var i=stageData.length-1;i >= 0; i--){
				var ln = stageData[i];
				for(var j=ln.lengh-2;j >= 1;j--)ln[i] &= m;
			}
		}
	}
	T.setEnemyMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
			this.stageData[by%(this.rows-1)][bx] |=  B_Enemy;
	}
	T.resetEnemyMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
			this.stageData[by%(this.rows-1)][bx] &=  ~B_Enemy;
	}
	T.setGoldMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
			this.setXYBlock(bx , by , this.stageData[by][bx] |=  B_Gold);
	}
	T.resetGoldMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
			this.setXYBlock(bx , by , this.stageData[by][bx] &=  ~B_Gold);
	}
	T.setBonusMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
			this.setXYBlock(bx , by , this.stageData[by][bx] |=  B_Bonus);
	}
	T.resetBonusMask = function(obj){
		var bx = obj.getBX(),by = obj.getBY();
			this.setXYBlock(bx , by , this.stageData[by][bx] &=  ~B_Bonus);
	}
} //

function PauseScrollManager(sc,fd){
	var T = this;
	IStateManager(T);

	T.vScreen = sc;
	T.field = fd;
	T.scrollLeft = 16;
	T.scrollTop = 16;
	T.defScrollLeft=16;
	T.defScrollTop=16;
	T.stageWidth = 640;
	T.stageHeight = 480;
	T.vScreenWidth = 640;
	T.vScreenHeight = 480;
	T.returnState = null;
	T.returnFlag = false;
	T.msg = null;
	T.frameCnt=0;

	T.call = function(stm){
		with(this){
			scrollLeft = defScrollLeft = stm.scrollLeft;
			scrollTop  = defScrollTop  = stm.scrollTop;
			stageWidth = stm.getStageWidth();
			stageHeight = stm.getStageHeight();
			vScreenWidth  = stm.vScreenWidth;
			vScreenHeight = stm.vScreenHeight;
			returnState = stm;
			returnFlag = false;
			frameCnt=0;
			if(msg == null){
				msg = new ScreenMessage(stm,0,0);
				msg.setWord(EventWord.pauseWord);
			}
			return this;
		}
	}
	T.setReturnFlag = function(){this.returnFlag = true;}

	T.action = function(){
		with(this){
			frameCnt++;
			if(returnFlag){
			 msg.setVisibility( false );
			 scrollTop = Math.round(scrollTop + (defScrollTop - scrollTop) / 4);
			 scrollLeft= Math.round(scrollLeft+ (defScrollLeft- scrollLeft)/ 4);
			 if(Math.abs(scrollLeft - defScrollLeft) <= 8 && 
			 	Math.abs(scrollTop -defScrollTop) <= 8 ){
				msg.draw();
				return returnState;
			 }
			}else
			if(gamePad1.buttons[0] != 0 || gamePad1.buttons[1] != 0){
			 scrollTop = Math.round(scrollTop + (defScrollTop - scrollTop) / 8);
			 scrollLeft= Math.round(scrollLeft+ (defScrollLeft- scrollLeft)/ 8);
			}else
			if(gamePad1.buttons[2] != 0 ){
				gamePad1.buttons[2] = 0;
				showReplayCode();
			}else{
				var sl = 0 , st = 0;
				var sr = stageWidth - vScreenWidth ,sb = stageHeight- vScreenHeight;
				scrollLeft += 16 * gamePad1.x;
				scrollTop  += 16 * gamePad1.y;
				msg.setVisibility( (frameCnt % 30) < 15 );
				if(scrollLeft < sl)scrollLeft = sl;
				else if(scrollLeft > sr)scrollLeft = sr;
				if(scrollTop  < st)scrollTop  = st;
				else if(scrollTop  > sb)scrollTop  = sb;
				var	ctx = scrollLeft + vScreenWidth / 2,
					cty = scrollTop + vScreenHeight / 2;
				if(stageWidth < vScreenWidth )ctx = stageWidth / 2;
				if(stageHeight< vScreenHeight)cty = stageHeight/ 2;
				msg.moveTo(	ctx,cty );
			}
			return this;
		}
	}
	T.draw = function(){
			this.msg.draw();
			this.scrollApply();
	}
	T.scrollApply = function(){
		with(this){
			var sl = scrollLeft * (vScreen.clientWidth  / vScreenWidth),
				sr = scrollTop  * (vScreen.clientHeight / vScreenHeight);
			if(vScreen.scrollTo)vScreen.scrollTo(sl,sr);
			else{
				vScreen.scrollLeft = sl;
				vScreen.scrollTop  = sr;
			}
		}
	}
	
	T.showReplayCode = function(){
		with(this){
			showBBS(parent.codeViewHtml);
		}
	}

} //


function Underground(stg){ // 地下帝国
	var T=this;
	T.stage = stg;
	T.map = stg.stageData;
	T.dat = new Array(3);
	T.cols = stg.cols;
	T.rows = stg.rows + 2;
	T.pad = stg.vGamePad;
	T.kSwitch = 0;
	T.rSwitch = B_Rope; // 右スイッチ
	T.cSwitch = B_Rock; // センタースイッチ
	T.oSwitch = B_Blank; // 外部スイッチ
	 T.oCnt=0;
	T.showDebug = false;
	T.bn=[];
	 T.bn[B_Blank]   = "×";
	 T.bn[B_Brick]   = "田";
	 T.bn[B_Rock]    = "■";
	 T.bn[B_Ladder]  = "＃";
	 T.bn[B_Rope]    = "－";
	 T.bn[B_HLadder] = "己";
	 T.bn[B_HHole]   = "凹";
	T.dsMode=false;
	T.init = function(){
	 with(this){
		var i;
		for(i=0; i < 3;i++){
			T.dat[i] = new Array(stage.cols + 20);
			for(var j=0;j<dat[i].length;j++){
				dat[i][j] = (i==2) ? B_Brick : B_Blank;
			}
		}
		dat[0][1] = dat[0][2] = B_HHole;
		for(i=0; i < 9 ;i++)dat[1][i] = 0;
		for(; i < dat[1].length ;i++)dat[1][i] = B_Brick;

		dat[0][8]  = cSwitch;
		dat[0][14] = rSwitch;
		dat[0][15] = oSwitch;
	 }
	}
	T.init();
	T.getXYBlock = function(xp,yp){
	 with(this){
		if(cols==16){ // ファミコンサイズ
			if(xp ==15 && yp < rows - 3 )return B_Rock;
		}
		if(xp < 0 || yp < 0 || xp >= cols || yp >= rows) return B_Rock;
		if(xp == 0 || xp == cols -1 )return B_Blank;
		if(yp < stage.rows -1)return map[yp][xp];
		 	return dat[ yp - stage.rows +1 ][xp];
	 }
	}
	T.action = function(){
		with(this){
			if(dsMode)return;
			oSwitch = (oCnt-->=0) ? B_Rock : B_Blank;
//　キー単独の場合…右or左＝コンクリ　下＝バー　上orAorB＝落とし穴
//　複数の場合…ナナメ入力や、A,Bを押しながらのキー操作はすべて落とし穴
			var vt = pad.getPadState();
			var dbg="";
			switch(vt){
				case 2 + 2*4: //ニュートラル
					kSwitch = B_Blank;break;
				case 1 + 2*4:	case 3+ 2*4: // 左・右
					kSwitch = B_Rock;break;
				case 2 + 3*4: // 下
					kSwitch = B_Rope;break;
				default:kSwitch = B_HHole;break;
			}
			dat[0][5] = kSwitch;
			if(stage.rows > 9 ){
				var yy = 9,nb = ~B_Digger;
				for(var i = 7 ; i < map[yy].length; i++){
						dat[1][i-6] =	map[yy][i] & nb;
						if((dat[1][i-6] & (B_Enemy|B_Player)) != 0)dat[1][i-6]=0;
				}
			}

			dat[0][8]  = cSwitch;
			dat[0][14] = rSwitch;
			dat[0][15] = oSwitch;
		
		}
	}
	T.draw = function(){
	 with(this){
		if(showDebug){
			var rw = stage.rows -1;
		 if(!dsMode){
			status = 
				"debug:キーSW=" + kSwitch + 
				" 中SW=" + bn[cSwitch] + 
				" 右SW=" + bn[rSwitch] + 
				" 外SW=" + bn[oSwitch];
			stage.setXYBlock(5 ,rw,kSwitch,-1);
			stage.setXYBlock(15,rw,oSwitch,-1);
			var rw = stage.rows -1;
			stage.setXYBlock(8 ,rw,cSwitch,-1);
			stage.setXYBlock(14,rw,rSwitch,-1);
			for(var i = 1 ; i < dat[1].length ; i++)
						stage.setXYBlock(i,0,dat[1][i],-1);
		 }
		 }
	 }
	}

	T.abc = new Array("A","B","C");
	T.cTable = new Array(B_Rock,B_Rope,B_HHole);
	T.rTable = new Array();
	 T.rTable[0] = new Array(B_Rope ,B_HHole,B_HHole);
	 T.rTable[1] = new Array(B_Rock ,B_Rock ,B_Rope);
	 T.rTable[2] = new Array(B_HHole,B_HHole,B_HHole);
	T.setSwitch = function(xx,yy,before,after){ // 
	 with(this){
		if(dsMode)return;
			var A=0,B=1,C=2;
			var c = (xx > 2 ) ? C : ( (yy % 4 != 0) ? C : ( (xx == 1) ? A : B ) );
			var r = (yy % 2 == 1) ? C : ( (xx % 2 == 1) ? A : B );
			cSwitch = cTable[c];
			oCnt = 1;
		var grp=0,bgh = B_Gold + B_HLadder;
		 switch(after){
			case B_Brick:case B_Blank:// レンガ掘る、埋まる、金塊消える
				grp=0;
			break;
			case B_Ladder: //脱出はしご出る
				grp=1;
			break;
			case B_Gold:case bgh://金塊現れる
				grp=2;
			break;
		 }
			rSwitch = rTable[r][grp];
		if(yy == 9 && xx >= 7){
				var nb = ~B_Digger;
		}
		if(showDebug){}
	 }
	}
	
	T.updateSwitch = function(){this.oCnt = 1;}
	
	T.show = function(){
	 with(this){
		showDebug = true;
		stage.imgTable[B_HHole] = StageImages.B_HHole2;
		var rw = stage.rows -1;
		for(var i = 1 ; i < dat[1].length ; i++){
					stage.setXYBlock(i,rw,dat[0][i],-1);
					stage.setXYBlock(i, 0,dat[1][i],-1);
		}
	 }
	}
	T.hide = function(){
	 with(this){
		showDebug = false;
		stage.imgTable[B_HHole] = StageImages.B_HHole;
		var rw = stage.rows -1;
		for(var i = 1 ; i < dat[1].length ; i++){
					stage.setXYBlock(i, 0,map[ 0][i],-1);
					stage.setXYBlock(i,rw,map[rw][i],-1);
		}
	 }
	}
	T.setDsMode = function(){
		with(this){
			dsMode=true;
				for(var i = 1 ; i < dat.length ; i++){
					for(var j = 1 ; j < dat[i].length ; j++){
						dat[i][j]=0;
					}
				}
			dat[0][25]=dat[0][26]=dat[1][13]=dat[1][14]=B_Brick;
		}

	}
} //



function Randomizer(seed){
	var T=this;
	T.rnd = seed;
	T.rndA=8*5+5;
	T.rndC=1213;
	T.rndM=0x10000;
	T.get = function(){
	 with(this){
		rnd = ( rndA * rnd + rndC ) % rndM;
		return  rnd ;
	 }
	}
	T.set = function(seed){this.rnd = seed;}
} //
//=========================================
//=========================================
//=========================================

function WaveTable(){
	WaveTable.gold = "wav/gold.wav";
	WaveTable.goal = "wav/goal.wav";
	WaveTable.digger = "wav/digger.wav";
	WaveTable.dead = "wav/dead.wav";
} //
WaveTable();

function SoundSprite(){ // 音響空間に描画するスプライト
	var T=this;
	T.isSoundManager = true;
	T.src="";
	T.loop="";
	T.volume=0;
	T.changed = false;
	T.moved = false;
	T.busy = false;

	T.x = 0 ; T.y = 0;
	T.id = SoundSprite.id++;
	T.body = DGI("soundBody" + T.id);

	T.action = function(){}
	T.setImage = function(s,lp,vol){
		with(this){
			src=s;
			if(lp)loop=lp;
			if(vol)volume=vol;
			changed = true;
		}
	}
	T.moveTo = function(xx,yy){
			if(!SOUND_ENABLE)return;
		with(this){
			x = xx;
			y = yy;
			moved = true;
		}
	}
	
	T.stop = function(){
		with(this){
			body.src = "";
			body.balance = 0;
			body.volume = -10000;
			x=0;
		 try{
			if(body.stop)body.stop();
			else
			if(body.Stop)body.Stop();
		 }catch(e){
			if(DEBUGMODE)alert(e);
		 }
		}
	}

	T.draw = function(){
			if(!SOUND_ENABLE)return;
		with(this){
			try{
				if(moved){
					var xx = ( x / STAGE_W ) * 20000 - 10000;
					if(xx < -10000 )xx = -10000;
					if(xx >  10000 )xx =  10000;
					body.balance = xx;
					moved = false;
				}
				if(changed){
					body[(DA)?"loop" : "repeat"] = loop;
					body.volume = volume;
					body.src = IMAGEBASEDIR + src;
					if(body.SetURL){
						var baseDir=""
						src = IMAGEBASEDIR + src;
						var ul = body.GetURL();
						if( ul != "" && !src.match(/^(file|http)/))
							baseDir = location.toString().replace(/\/[^\/]+$/,"/");
						src = baseDir + src;
						if( ul == src )	body.Play();
						else			body.SetURL(src);
					}else
					if(body.play)body.play();
					changed = false;
				}
			}catch(e){
				if(DEBUGMODE)		alert(e);
			}
		}
	}
	T.play = T.draw;
} //
SoundSprite.id = 0;


function SoundSpriteManager(){
	if(SoundSpriteManager.instance)return SoundSpriteManager.instance;
	var T = this;

	T.sounds = new Array();
	T.ptr = 0;
	T.enabled = false;

	for(var cnt = 0 ; cnt < SOUNDS_MAX ; cnt++ ){
		var s = DGI("soundBody" + cnt);
		if(!s)break;
		 T.sounds[cnt] = new SoundSprite();
	}
	T.bgm = DGI("bgmPlayer");

	T.setImage = function(s,lp,vol){
		with(this){
			var ret = sounds[ptr];
			ret.setImage(s,lp,vol);
			ptr = ( ptr + 1 ) % sounds.length;
			return ret;
		}
	} 

	T.setBgm = function(src){
		with(this){
		 try{
			bgm.src = src;
			if(bgm.play){
				bgm.Play();
			}else
			if(bgm.SetURL){ // QuickTime
				var baseDir=""
				src = IMAGEBASEDIR + src;
				if(bgm.GetURL() != ""  && !src.match(/^(file|http)/)){
					baseDir = location.toString().replace(/\/[^\/]+$/,"/");
				}
				if(bgm.SetIsLooping) bgm.SetIsLooping(true);
				bgm.SetURL(baseDir + src);
			}
		 }catch(e){
			if(DEBUGMODE)alert(e);
		 }
		}
	}

	T.action = function(){
		with(this){
			if(enabled != SOUND_ENABLE){
				if(enabled)stop();
				enabled = SOUND_ENABLE;
			}
		}
	}

	T.draw = function(){
		with(this){
			for(var i = 0 ; i < sounds.length ; i++ ) sounds[i].draw();
			
		}
	}

	T.stop = function(){
		with(this){
			for(var i = 0 ; i < sounds.length ; i++ ) sounds[i].stop();
			if( bgm.stop ){
				bgm.stop();
			}else 
			if( bgm.Stop ){
				bgm.Stop();
			}
			bgm.src = "";
		}
	}
	T.play = T.draw;
	SoundSpriteManager.instance = this;
} //

function createSoundSpriteBody(){
	for(var i = 0 ; i < SOUNDS_MAX ; i ++ ){
	 if(DA)
		document.write('<bgSound id="soundBody' + i + '" loop="1" />');
	 else
		document.write('<embed id="soundBody' + i + '" type="audio/wav" autostart="true" repeat="1" style="position:absolute;top:'+ i * 40 +';left:-150;width:100;height:40;z-index:1;" enablejavascript="true" />');
	}
	document.write('<embed id="bgmPlayer" autostart="false" style="position:absolute;top:0;left:-100;width:100;height:40;z-index:1;" enablejavascript="true" loop="true" />');
} //


//=========================================
//=========================================
//=========================================

var frameMode = false;
var challengeMode = false;
var player ;
var scoreBoard,inputViewer;
var stageManager;
var titleManager;
var dyingEventManager;
var goalEventManager;
var stageMenuManager;
var imageCacheManager;
var soundSpriteManager;
var pause = false;
var pauseScrollManager;
var currentState = null;
function init(){
	if(window.name=="gameScreen")frameMode=true;
	var stg = "" , autoStart=false;
	if(frameMode){
		stg = parent.stageSrc;
		autoStart = parent.autoStart;
		challengeMode = parent.challengeMode;
		if(challengeMode && !DEBUGMODE)DGI("restartButton").style.display="none";
		SOUND_ENABLE = parent.soundEnable;
		mTimerInterval = parent.mTimerInterval;
		frameSkip = parent.frameSkip;
	}else{
		DGI("menuBar").style.diplay="none";
		stg = DGI("sampleStage").value;
	}
	resized();

	stageManager.loadStage(stg);

	DGI("loadingMsg").style.display="none";

	player = stageManager.getPlayer();
	titleManager.initHTML(DGI("titleHTML").value);
	currentState = titleManager.call();
	 imageCacheManager.set( StageImages );
	 imageCacheManager.set( PlayerImages );
	 imageCacheManager.set( RobotImages );
	stageManager.addScoreBoard( scoreBoard , DGI("scoreBoardHTML").value );
	stageManager.addInputViewer( inputViewer , DGI("inputViewerHTML").value );

	var btn = DGI("soundEnableButton");
	btn.style.display="";
	setSoundEnable(btn,SOUND_ENABLE);
	setSpeedView();
	DGI("sysVerInfo").innerHTML = "sysver:" + (SYSVER + 0x1000000).toString(16).substring(1) + " mode:" + GameMode.names[stageManager.gameMode];

	if(autoStart || stageManager.replayMode){
		titleManager.setStartFlag()
	}

} //
 
function quit(){
	if(frameMode){
	 if(mTimerInterval < 150){
		parent.frameSkip = frameSkip;
		parent.mTimerInterval = mTimerInterval;
	 }
	}
} //

var resizeFlag = false;
function resized(){
	var menuBar = DGI("menuBar");
	var scrn = DGI("screen1");
	menuBar.style.diplay = ( frameMode ) ? "" : "none" ;
	if(SCREEN_W != DB.clientWidth || SCREEN_H != DB.clientHeight){
	 SCREEN_W = DB.clientWidth;
	 SCREEN_H = DB.clientHeight;
	 resizeFlag = true;
	}
	//if(!onresize)onresize = resized;
} //

var actionCnt=0;
function action(){
	if(pause)return;
	actionCnt++;
	if(!imageCacheManager.complete)return;
	currentState = currentState.action();
	soundSpriteManager.action();
	return true;
} //

var drawCnt=0;
function draw(){
	if(pause)return;
	drawCnt++;
	currentState.draw();
	soundSpriteManager.draw();

	if(resizeFlag && drawCnt % 5==0){
		resizeFlag = false;
		 stageManager.onResize();
	}
	return true;
} //
 
 var lastWord = EventWord.num1;
function keyDown(srcElement,keyCode,shiftKey,ctrlKey,altKey){
//	var si =DGI("speedInfo");	si.innerHTML  = keyCode;
//	stageManager.
	switch(keyCode){
		case 49: //1
		
			pause = true;
			 var s = prompt(EventWord.input,lastWord);
			 if(s){lastWord = stageManager.setSpeaking(s,0);
			  if(s.match(EventWord.ngWord)){
				alert(EventWord.tukkomi);
				stageManager.setGiveupFlag();
			  }
			 }
			pause = false;
			break;
//∩彡⊂
		case 50:stageManager.setSpeaking(EventWord.num2,0);	break;
		case 51:stageManager.setSpeaking(EventWord.num3,0);	break;
		case 52:stageManager.setSpeaking(EventWord.num4,0);	break;
		case 53:stageManager.setSpeaking(EventWord.num5,0);	break;
		case 54:stageManager.setSpeaking(EventWord.num6,0);	break;
		case 55:stageManager.setSpeaking(EventWord.num7,0);	break;
		case 56:stageManager.setSpeaking(EventWord.num8,0);	break;
		case 57: //
		if(!shiftKey)stageManager.setSpeaking(EventWord.num9,0);
		else{
			var u = stageManager.ugEnable;
			if(u==1){
				stageManager.ugEnable = 0;
				stageManager.setSpeaking("ug:off",0);
			}else{
				stageManager.ugEnable = 1;
				stageManager.setSpeaking("ug:on",0);
			}
		}
			break;
		case 48: // 0
		if(!shiftKey)stageManager.setSpeaking(EventWord.num0,0);
		else{
			var v = stageManager.underground.showDebug;
			if(v){ 
				scoreBoard.field.style.visibility = "visible";
				stageManager.underground.hide();
			}else{ 
				scoreBoard.field.style.visibility = "hidden";
				stageManager.underground.show();
			}
			break;
		}
		case 74: // J
		case 90: // Z
//		case 17: // CTRL
		case WiiCode.bt1:
			gamePad1.buttons[0]=1;
			break;
		case 75: // K
		case 88: // X
//		case 16: // SHIFT
		case WiiCode.bt2:
			gamePad1.buttons[1]=1;
			break;

		case 65: // A
		case 73: // I
		case 101:// num5
//		case 13: // num5
			gamePad1.buttons[2]=1;
			break;

		case 83: //S
		case 37: //←
		case 100:
		case WiiCode.lt:
			gamePad1.left(true);
			break;
		case 69: //E
		case 38: //↑
		case 104:
		case WiiCode.up:
			gamePad1.up(true);
			break;
		case 70: //F
		case 39: //→
		case 102:
		case WiiCode.rt:
			gamePad1.right(true);
			break;
		case 68: //D
		case 40: //↓
		case 98:
		case WiiCode.dn:
			gamePad1.down(true);
			break;
		case 32: // SPACE
//		case 80: // P
		case WiiCode.btB:
		case 101:// num5
			if(currentState == stageManager)stageManager.setPauseFlag();
			else
			if(currentState == pauseScrollManager)pauseScrollManager.setReturnFlag();
			break;
		case 46: // del
		case WiiCode.btA:
		case 13:
			stageManager.setGiveupFlag();
			break;
		case 36: // home
			if(mTimerInterval < 1000){
				frameSkip = 1;
				mTimerInterval = defInterval;
				setSpeedView();
			}
			break;
		case 35: // end
			if(mTimerInterval < 1000){
				frameSkip = 1;
				mTimerInterval = 10;
				setSpeedView();
			}
			break;
		case 33: // pageUp
		case WiiCode.plus:
			speedUp(shiftKey);
			break;
		case 34: // pageDn
		case WiiCode.minus:
			speedDown(shiftKey);
			break;
	}
	return true;
} //
function speedUp(shiftKey){
	if(mTimerInterval < 1000){
	 if(shiftKey){
		if(frameSkip < 5) frameSkip++;
	 }
	 else{
		if(mTimerInterval > 10)mTimerInterval-=10;
		setSpeedView();
	 }
	}
} //
function speedDown(shiftKey){
	if(mTimerInterval < 150){
	 if(shiftKey){
		if(frameSkip > 1) frameSkip--;
	 }
	 else{
		mTimerInterval=mTimerInterval*1+10;
		setSpeedView();
	 }
	}
} //
function setSpeedView(){
	var si =DGI("speedInfo");
	var sp =DGI("speedSelect");
	if(!si)return;
	var p = 6 - Math.round( mTimerInterval / 10);
	si.innerHTML = "SPEED(" + p + ","+ (frameSkip-1) +")";
	if(sp)sp.value=mTimerInterval;
} //

function keyUp(srcElement,keyCode,shiftKey,ctrlKey,altKey){
	switch(keyCode){
		case 74: // J
		case 90: // Z
//		case 17: // CTRL
		case WiiCode.bt1:
			gamePad1.buttons[0]=0;
			break;
		case 75: // K
		case 88: // X
//		case 16: // SHIFT
//		case 32: // SPACE
		case WiiCode.bt2:
			gamePad1.buttons[1]=0;
		break;
		case 65: // A
		case 73: // I
		case 101:// num5
//		case 13: // num5
			gamePad1.buttons[2]=0;
			break;
		case 83: //S
		case 37: //←
		case 100:
		case WiiCode.lt:
			gamePad1.left(false);
			break;
		case 69: //E
		case 38: //↑
		case 104:
		case WiiCode.up:
			gamePad1.up(false);
			break;
		case 70: //F
		case 39: //→
		case 102:
		case WiiCode.rt:
			gamePad1.right(false);
			break;
		case 68: //D
		case 40: //↓
		case 98:
		case WiiCode.dn:
			gamePad1.down(false);
			break;
	}
	return true;
} //
 
function showHelp(){
	var sf = DGI("helpWindow");
	var sd = sf.style.display;
	if(sd == "")	sf.style.display = "none";
	else{
		sf.style.display="";
		focusWin(sf);
	}
	return false;
} //

function showBBS(u){
	if(!frameMode)return;
	var sf = DGI("bbsWindow");
	var sd = sf.style.display;
	var bl = bbsWindow.location.toString().replace(/#.*?$/,"").replace(/.+\//,"");
	var bbs = CGIPATH + "/bbs.cgi?act=showIndex";
		if(parent.returnBBS != ""){
			bbs = parent.returnBBS;
		}
	var url = ( (u) ? u : bbs );
	var ul = url.replace(/#.*?$/,"").replace(/.+\//,"");
	
	if(sd == ""){
		if(bl == ul){
			bbsWindow.location.replace(parent.blankHtml);
			sf.style.display = "none";
			pause=false;
		}else{
			pause=true;
			bbsWindow.location.replace( url );
			focusWin(sf);
		}
	}else{
		sf.style.display="";
//		titleManager.hide();
//		stageMenuManager.hide();
		pause=true;
		if(bl != ul)
			bbsWindow.location.replace(parent.blankHtml);
			bbsWindow.location.replace( url );
			focusWin(sf);
	}
} //

function hideBBS(){
	if(!frameMode)return;
	var sf = DGI("bbsWindow");
	bbsWindow.location.replace(parent.blankHtml);
	sf.style.display = "none";
	pause=false;
} //

function showThread(key){
	if(!frameMode)return;
	showBBS(CGIPATH + "/bbs.cgi?key="+key);
} //

function showEditor(){
	if(!frameMode)return;
	showBBS(parent.editHtml);
} //

function showReplayForm(){
	if(!frameMode)return;
	showBBS();
	bbsWindow.location.replace(parent.replayHtml);
} //

function focusWin(win){
	if(!frameMode)return;
	var bw = DGI("bbsWindow"),hw = DGI("helpWindow");
	if(win == bw){	bw.style.zIndex=301;	hw.style.zIndex=300;}
	else{	bw.style.zIndex=300;	hw.style.zIndex=301;}
} //

function setSoundEnable(btn,flg){
	if(flg == true){
//		btn.value = "SOUND";
		btn.style.color="blue";
		btn.style.border="inset";
	}
	else{
//		btn.value = "SOUND:OFF";
		btn.style.color="black";
		btn.style.border="outset";
	}
	SOUND_ENABLE = flg;
	 var se = document.getElementById("soundEnable");
	 if(se)se.checked=SOUND_ENABLE;
	if(frameMode)parent.soundEnable = flg;
} //

onhelp = showHelp;
