SCRIPT_CLASS_FUNCTION(System, destroy)
{
    lua_getfield(state, 1, "destroyed");

    if(lua_isnil(state, -1))
    {
        lua_pop(state, 1);

        lua_getfield(state, 1, "_e");
        auto entity = reinterpret_cast<Entity*>(lua_touserdata(state, -1));
        lua_pop(state, 1);

        if(entity->isInserted())
        {
            entity->remove();
        }

        lua_pushboolean(state, true);
        lua_setfield(state, 1, "destroyed");

        getInstance().entitiesToRemove.add(entity);
        entity->finalize();
    }
    else
    {
        lua_pop(state, 1);
    }

    return 0;
}
bool startup(void) {
  if( !isInserted() )
    return false;
  //printf("test printf in dldi\n");
  //u8 * testMalloc = malloc(512);
  //memset( testMalloc, 0x5a, 512 );
  return sddInitSD();
}
Exemple #3
0
 /**
 * Set an empty definition Domain.
 **/
 void domainEmpty()
     {
     if (isDomainEmpty()) return;
     _LD->domainEmpty();
     if (isInserted())
         {
         enable(false); enable(true); resetDrawing(); // force update the range button on the object menu and then reset the drawing 
         }
     }
Exemple #4
0
 /**
 * Set the definition domain.
 *
 * @param   R   The new definition domain
 **/
 void domain(mtools::iBox2 R)
     {
     if (R == domain()) return;
     _LD->domain(R);
     if (isInserted())
         {
         enable(false); enable(true); resetDrawing(); // force update the range button on the object menu and then reset the drawing 
         }
     }
Exemple #5
0
 /**
 * Set how transparent color are handled when drawing pixel-type images.
 *
 * @param   type    The new type: one of REMOVE_NOTHING, REMOVE_WHITE, REMOVE_BLACK.
 **/
 void transparentColor(int type) 
     { 
     _LD->transparentColor(type);
     if (isInserted())
         {
         IndirectMemberProc<Plot2DLattice> proxy(*this, &Plot2DLattice::_updateImageTypeInFLTK); // update the status of the button in the fltk thread
         runInFLTKThread(proxy); // and also refresh the drawing if needed
         }
     }
Exemple #6
0
 /**
  * Sets image type (pixel or images). The drawer may discard this request and decide to draw in
  * pixel mode anyway if there is no getImage() method or if we are too far away
  *
  * @param   imageType   Type of the image.
  **/
 void setImageType(int imageType = TYPEPIXEL)
     {
     _LD->setImageType(imageType);
     if (isInserted())
         {
         IndirectMemberProc<Plot2DLattice> proxy(*this, &Plot2DLattice::_updateImageTypeInFLTK); // update the status of the button in the fltk thread
         runInFLTKThread(proxy); // and also refresh the drawing if needed
         }
     }
Exemple #7
0
 /**
  * Set the 'opacification factor' used when drawing pixel-type images.
  *
  * @param   o   The new value in [1.0,4.0] (1.0 to disable opacification).
  **/
 void opacify(float o)
     {
     if (o < 1.0f) { o = 1.0f; } else if (o > 4.0f) { o = 4.0f; }
     _LD->opacify(o);
     if (isInserted())
         {
         IndirectMemberProc<Plot2DLattice> proxy(*this, &Plot2DLattice::_updateImageTypeInFLTK); // update the status of the button in the fltk thread
         runInFLTKThread(proxy); // and also refresh the drawing if needed
         }
     }
Exemple #8
0
 void Plot2DAxes::scaling(float scaling)
     {
     if (!isFLTKThread()) // run the method in FLTK if not in it
         {
         IndirectMemberProc<Plot2DAxes, float> proxy(*this, &Plot2DAxes::scaling, scaling); // registers the call
         runInFLTKThread(proxy);
         return;
         }
     if (scaling < 0.1) { scaling = 0.1f; } else if (scaling >= 5.0f) scaling = 5.0f;
     _scaling = scaling;
     if (!isInserted()) return;
     _scaleSlider->value(scaling);
     refresh();
     }
Exemple #9
0
 void Plot2DAxes::graduations(bool show, RGBc color)
     {
     if (!isFLTKThread()) // run the method in FLTK if not in it
         {
         IndirectMemberProc<Plot2DAxes, bool, RGBc> proxy(*this, &Plot2DAxes::graduations, show, color); // registers the call
         runInFLTKThread(proxy);
         return;
         }
     _gradStatus = show;
     if (!_gradStatus) _numStatus = false;
     _gradColor = color;
     if (!isInserted()) return; // not inserted, we are done
     _gradButton->value(_gradStatus ? 1 : 0);
     _numButton->value(_numStatus ? 1 : 0);
     _gradColorButton->color(_gradColor);
     _gradColorButton->color2(_gradColor);
     _gradColorButton->redraw();
     refresh();
     yieldFocus();
     }
Exemple #10
0
// 中間ポートを利用する場合のルーティング(中間からシンクまで)
bool routingIToSink(int trgt_line_id){

	Line* trgt_line = board->line(trgt_line_id);
	
	vector<vector<IntraBox*> > my_board(board->getSizeY(), vector<IntraBox*>(board->getSizeX()));
	IntraBox init = {
		INT_MAX,INT_MAX,INT_MAX,INT_MAX,
		{false,false,false,false},
		{false,false,false,false},
		{false,false,false,false},
		{false,false,false,false}};
	
	for(int y=0;y<board->getSizeY();y++){
		for(int x=0;x<board->getSizeX();x++){
			my_board[y][x] = new IntraBox;
			*(my_board[y][x]) = init;
		}
	}
	
	// 通れないマスを規定
	vector<Point>* trgt_track = trgt_line->getTrack();
	map<int,map<int,bool> > can_pass;
	for(int y=-1;y<=board->getSizeY();y++){
		for(int x=-1;x<=board->getSizeX();x++){
			can_pass[y][x] = true;
		}
	}
	for(int i=0;i<(int)(trgt_track->size());i++){
		int tmp_x = (*trgt_track)[i].x;
		int tmp_y = (*trgt_track)[i].y;
		can_pass[tmp_y][tmp_x] = false;
		can_pass[tmp_y][tmp_x-1] = false;
		can_pass[tmp_y][tmp_x+1] = false;
		can_pass[tmp_y-1][tmp_x] = false;
		can_pass[tmp_y+1][tmp_x] = false;
	}
	
	// ソースから中間までの経路を一時保存
	vector<Point> before_track;
	for(int i=0;i<(int)(trgt_track->size());i++){
		before_track.push_back((*trgt_track)[i]);
	}
	trgt_track->clear();
	
	
	int start_x = trgt_line->getInterX();
	int start_y = trgt_line->getInterY();
	
	IntraBox* start = my_board[start_y][start_x];
	start->ne = 0; start->nw = 0;
	start->se = 0; start->sw = 0;
	
	queue<Search> qu;
	// 北方向
	if(can_pass[start_y-1][start_x] && isInserted(start_x,start_y-1,SOUTH) && isFixed(start_x,start_y,NORTH,-1,trgt_line_id)){
		Search trgt = {start_x,start_y-1,SOUTH,-1};
		qu.push(trgt);
	}
	// 東方向
	if(can_pass[start_y][start_x+1] && isInserted(start_x+1,start_y,WEST) && isFixed(start_x,start_y,EAST,-1,trgt_line_id)){
		Search trgt = {start_x+1,start_y,WEST,-1};
		qu.push(trgt);
	}
	// 南方向
	if(can_pass[start_y+1][start_x] && isInserted(start_x,start_y+1,NORTH) && isFixed(start_x,start_y,SOUTH,-1,trgt_line_id)){
		Search trgt = {start_x,start_y+1,NORTH,-1};
		qu.push(trgt);
	}
	// 西方向
	if(can_pass[start_y][start_x-1] && isInserted(start_x-1,start_y,EAST) && isFixed(start_x,start_y,WEST,-1,trgt_line_id)){
		Search trgt = {start_x-1,start_y,EAST,-1};
		qu.push(trgt);
	}
	
	while(!qu.empty()){
		
		Search trgt = qu.front();
		qu.pop();
		
		//cout << "(" << trgt.x << "," << trgt.y << ")" << endl;
		
		Box* trgt_box = board->box(trgt.x,trgt.y);
		IntraBox* trgt_ibox = my_board[trgt.y][trgt.x];
		bool update = false;
		
		int turn_count = 0;
		if(trgt.c != trgt.d) turn_count++;
	
		// コスト計算
		if(trgt.d == SOUTH){ // 南から来た
			IntraBox* find_ibox = my_board[trgt.y+1][trgt.x];
			// タッチ数
			int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getSouthNum();
			if(touch_count < 0){ cout << "error! (error: 24)" << endl; exit(24); }
			// コスト
			int cost_se = (find_ibox->ne) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C + turn_count * BT;
			int cost_sw = (find_ibox->nw) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C + turn_count * BT;
			// 南東マス
			if(cost_se < trgt_ibox->se){
				update = true;
				trgt_ibox->se = cost_se;
				(trgt_ibox->d_se).n = false;
				(trgt_ibox->d_se).e = false;
				(trgt_ibox->d_se).s = true;
				(trgt_ibox->d_se).w = false;
			}
			else if(cost_se == trgt_ibox->se){
				(trgt_ibox->d_se).s = true;
			}
			// 北東マス
			if(cost_ne < trgt_ibox->ne){
				update = true;
				trgt_ibox->ne = cost_ne;
				(trgt_ibox->d_ne).n = false;
				(trgt_ibox->d_ne).e = false;
				(trgt_ibox->d_ne).s = true;
				(trgt_ibox->d_ne).w = false;
			}
			else if(cost_ne == trgt_ibox->ne){
				(trgt_ibox->d_ne).s = true;
			}
			// 南西マス
			if(cost_sw < trgt_ibox->sw){
				update = true;
				trgt_ibox->sw = cost_sw;
				(trgt_ibox->d_sw).n = false;
				(trgt_ibox->d_sw).e = false;
				(trgt_ibox->d_sw).s = true;
				(trgt_ibox->d_sw).w = false;
			}
			else if(cost_sw == trgt_ibox->sw){
				(trgt_ibox->d_sw).s = true;
			}
			// 北西マス
			if(cost_nw < trgt_ibox->nw){
				update = true;
				trgt_ibox->nw = cost_nw;
				(trgt_ibox->d_nw).n = false;
				(trgt_ibox->d_nw).e = false;
				(trgt_ibox->d_nw).s = true;
				(trgt_ibox->d_nw).w = false;
			}
			else if(cost_nw == trgt_ibox->nw){
				(trgt_ibox->d_nw).s = true;
			}
		}
		if(trgt.d == WEST){ // 西から来た
			IntraBox* find_ibox = my_board[trgt.y][trgt.x-1];
			// タッチ数
			int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getWestNum();
			if(touch_count < 0){ cout << "error! (error: 25)" << endl; exit(25); }
			// コスト
			int cost_nw = (find_ibox->ne) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C + turn_count * BT;
			int cost_sw = (find_ibox->se) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C + turn_count * BT;
			// 北西マス
			if(cost_nw < trgt_ibox->nw){
				update = true;
				trgt_ibox->nw = cost_nw;
				(trgt_ibox->d_nw).n = false;
				(trgt_ibox->d_nw).e = false;
				(trgt_ibox->d_nw).s = false;
				(trgt_ibox->d_nw).w = true;
			}
			else if(cost_nw == trgt_ibox->nw){
				(trgt_ibox->d_nw).w = true;
			}
			// 北東マス
			if(cost_ne < trgt_ibox->ne){
				update = true;
				trgt_ibox->ne = cost_ne;
				(trgt_ibox->d_ne).n = false;
				(trgt_ibox->d_ne).e = false;
				(trgt_ibox->d_ne).s = false;
				(trgt_ibox->d_ne).w = true;
			}
			else if(cost_ne == trgt_ibox->ne){
				(trgt_ibox->d_ne).w = true;
			}
			// 南西マス
			if(cost_sw < trgt_ibox->sw){
				update = true;
				trgt_ibox->sw = cost_sw;
				(trgt_ibox->d_sw).n = false;
				(trgt_ibox->d_sw).e = false;
				(trgt_ibox->d_sw).s = false;
				(trgt_ibox->d_sw).w = true;
			}
			else if(cost_sw == trgt_ibox->sw){
				(trgt_ibox->d_sw).w = true;
			}
			// 南東マス
			if(cost_se < trgt_ibox->se){
				update = true;
				trgt_ibox->se = cost_se;
				(trgt_ibox->d_se).n = false;
				(trgt_ibox->d_se).e = false;
				(trgt_ibox->d_se).s = false;
				(trgt_ibox->d_se).w = true;
			}
			else if(cost_se == trgt_ibox->se){
				(trgt_ibox->d_se).w = true;
			}
		}
		if(trgt.d == NORTH){ // 北から来た
			IntraBox* find_ibox = my_board[trgt.y-1][trgt.x];
			// タッチ数
			int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getNorthNum();
			if(touch_count < 0){ cout << "error! (error: 26)" << endl; exit(26); }
			// コスト
			int cost_ne = (find_ibox->se) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C + turn_count * BT;
			int cost_nw = (find_ibox->sw) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C + turn_count * BT;
			// 北東マス
			if(cost_ne < trgt_ibox->ne){
				update = true;
				trgt_ibox->ne = cost_ne;
				(trgt_ibox->d_ne).n = true;
				(trgt_ibox->d_ne).e = false;
				(trgt_ibox->d_ne).s = false;
				(trgt_ibox->d_ne).w = false;
			}
			else if(cost_ne == trgt_ibox->ne){
				(trgt_ibox->d_ne).n = true;
			}
			// 南東マス
			if(cost_se < trgt_ibox->se){
				update = true;
				trgt_ibox->se = cost_se;
				(trgt_ibox->d_se).n = true;
				(trgt_ibox->d_se).e = false;
				(trgt_ibox->d_se).s = false;
				(trgt_ibox->d_se).w = false;
			}
			else if(cost_se == trgt_ibox->se){
				(trgt_ibox->d_se).n = true;
			}
			// 北西マス
			if(cost_nw < trgt_ibox->nw){
				update = true;
				trgt_ibox->nw = cost_nw;
				(trgt_ibox->d_nw).n = true;
				(trgt_ibox->d_nw).e = false;
				(trgt_ibox->d_nw).s = false;
				(trgt_ibox->d_nw).w = false;
			}
			else if(cost_nw == trgt_ibox->nw){
				(trgt_ibox->d_nw).n = true;
			}
			// 南西マス
			if(cost_sw < trgt_ibox->sw){
				update = true;
				trgt_ibox->sw = cost_sw;
				(trgt_ibox->d_sw).n = true;
				(trgt_ibox->d_sw).e = false;
				(trgt_ibox->d_sw).s = false;
				(trgt_ibox->d_sw).w = false;
			}
			else if(cost_sw == trgt_ibox->sw){
				(trgt_ibox->d_sw).n = true;
			}
		}
		if(trgt.d == EAST){ // 東から来た
			IntraBox* find_ibox = my_board[trgt.y][trgt.x+1];
			// タッチ数
			int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getEastNum();
			if(touch_count < 0){ cout << "error! (error: 27)" << endl; exit(27); }
			// コスト
			int cost_ne = (find_ibox->nw) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C + turn_count * BT;
			int cost_se = (find_ibox->sw) + ML + touch_count * penalty_T + turn_count * BT;
			int cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C + turn_count * BT;
			// 北東マス
			if(cost_ne < trgt_ibox->ne){
				update = true;
				trgt_ibox->ne = cost_ne;
				(trgt_ibox->d_ne).n = false;
				(trgt_ibox->d_ne).e = true;
				(trgt_ibox->d_ne).s = false;
				(trgt_ibox->d_ne).w = false;
			}
			else if(cost_ne == trgt_ibox->ne){
				(trgt_ibox->d_ne).e = true;
			}
			// 北西マス
			if(cost_nw < trgt_ibox->nw){
				update = true;
				trgt_ibox->nw = cost_nw;
				(trgt_ibox->d_nw).n = false;
				(trgt_ibox->d_nw).e = true;
				(trgt_ibox->d_nw).s = false;
				(trgt_ibox->d_nw).w = false;
			}
			else if(cost_nw == trgt_ibox->nw){
				(trgt_ibox->d_nw).e = true;
			}
			// 南東マス
			if(cost_se < trgt_ibox->se){
				update = true;
				trgt_ibox->se = cost_se;
				(trgt_ibox->d_se).n = false;
				(trgt_ibox->d_se).e = true;
				(trgt_ibox->d_se).s = false;
				(trgt_ibox->d_se).w = false;
			}
			else if(cost_se == trgt_ibox->se){
				(trgt_ibox->d_se).e = true;
			}
			// 南西マス
			if(cost_sw < trgt_ibox->sw){
				update = true;
				trgt_ibox->sw = cost_sw;
				(trgt_ibox->d_sw).n = false;
				(trgt_ibox->d_sw).e = true;
				(trgt_ibox->d_sw).s = false;
				(trgt_ibox->d_sw).w = false;
			}
			else if(cost_sw == trgt_ibox->sw){
				(trgt_ibox->d_sw).e = true;
			}
		}
		
		if(!update) continue;
		
		// 北方向
		if(trgt.d!=NORTH && can_pass[trgt.y-1][trgt.x] && isInserted(trgt.x,trgt.y-1,SOUTH) && isFixed(trgt.x,trgt.y,NORTH,trgt.d,trgt_line_id)){
			Search next = {trgt.x,trgt.y-1,SOUTH,trgt.d};
			qu.push(next);
		}
		// 東方向
		if(trgt.d!=EAST && can_pass[trgt.y][trgt.x+1] && isInserted(trgt.x+1,trgt.y,WEST) && isFixed(trgt.x,trgt.y,EAST,trgt.d,trgt_line_id)){
			Search next = {trgt.x+1,trgt.y,WEST,trgt.d};
			qu.push(next);
		}
		// 南方向
		if(trgt.d!=SOUTH && can_pass[trgt.y+1][trgt.x] && isInserted(trgt.x,trgt.y+1,NORTH) && isFixed(trgt.x,trgt.y,SOUTH,trgt.d,trgt_line_id)){
			Search next = {trgt.x,trgt.y+1,NORTH,trgt.d};
			qu.push(next);
		}
		// 西方向
		if(trgt.d!=WEST && can_pass[trgt.y][trgt.x-1] && isInserted(trgt.x-1,trgt.y,EAST) && isFixed(trgt.x,trgt.y,WEST,trgt.d,trgt_line_id)){
			Search next = {trgt.x-1,trgt.y,EAST,trgt.d};
			qu.push(next);
		}
		
	}
	
	// cout << endl;
	// for(int y=0;y<board->getSizeY();y++){
		// for(int x=0;x<board->getSizeX();x++){
			// IntraBox* trgt_box = my_board[y][x];
			// if(trgt_box->nw > 10000){
				// cout << " +";
			// }
			// else{
				// cout << setw(2) << trgt_box->nw;
			// }
			// if(trgt_box->ne > 10000){
				// cout << " +";
			// }
			// else{
				// cout << setw(2) << trgt_box->ne;
			// }
			// cout << " ";
		// }
		// cout << endl;
		// for(int x=0;x<board->getSizeX();x++){
			// IntraBox* trgt_box = my_board[y][x];
			// if(trgt_box->sw > 10000){
				// cout << " +";
			// }
			// else{
				// cout << setw(2) << trgt_box->sw;
			// }
			// if(trgt_box->se > 10000){
				// cout << " +";
			// }
			// else{
				// cout << setw(2) << trgt_box->se;
			// }
			// cout << " ";
		// }
		// cout << endl;
	// }
	
	
	// バックトレース
	int now_x = trgt_line->getSinkX();
	int now_y = trgt_line->getSinkY();
	int intra_box = -1;
	
	vector<int> adj_cost(8);
	if(now_y!=0){
		adj_cost[0] = my_board[now_y-1][now_x]->sw; // 北,南西
		adj_cost[1] = my_board[now_y-1][now_x]->se; // 北,南東
	}
	else{
		adj_cost[0] = INT_MAX;
		adj_cost[1] = INT_MAX;
	}
	if(now_x!=(board->getSizeX()-1)){
		adj_cost[2] = my_board[now_y][now_x+1]->nw; // 東,北西
		adj_cost[3] = my_board[now_y][now_x+1]->sw; // 東,南西
	}
	else{
		adj_cost[2] = INT_MAX;
		adj_cost[3] = INT_MAX;
	}
	if(now_y!=(board->getSizeY()-1)){
		adj_cost[4] = my_board[now_y+1][now_x]->ne; // 南,北東
		adj_cost[5] = my_board[now_y+1][now_x]->nw; // 南,北西
	}
	else{
		adj_cost[4] = INT_MAX;
		adj_cost[5] = INT_MAX;
	}
	if(now_x!=0){
		adj_cost[6] = my_board[now_y][now_x-1]->se; // 西,南東
		adj_cost[7] = my_board[now_y][now_x-1]->ne; // 西,北東
	}
	else{
		adj_cost[6] = INT_MAX;
		adj_cost[7] = INT_MAX;
	}
	vector<int> min_direction_array;
	int min_cost = INT_MAX, threshold_cost = 10000, min_direction_array_size;
	for (int trying = 0; trying < 5; trying++) {
		for (int a = 0; a < 8; a++) {
			if (adj_cost[a] > threshold_cost) {
				continue;
			}
			if (adj_cost[a] < min_cost) {
				min_direction_array.clear();
				min_direction_array.push_back(a);
				min_cost = adj_cost[a];
			} else if(adj_cost[a] == min_cost){
				min_direction_array.push_back(a);
			}
		}
		min_direction_array_size = (int)(min_direction_array.size());
		if (min_direction_array_size != 0) {
			break;
		}
		threshold_cost *= 10;
	}
	if (min_direction_array_size == 0) {
		for (int i = 0; i < (int)(before_track.size()); i++) {
			trgt_track->push_back(before_track[i]);
		}
		return false;
	}
	int adj_count = (int)mt_genrand_int32(0, min_direction_array_size - 1);
	int adj_id = min_direction_array[adj_count];
	//cout << min_cost << endl;
	
	
	//bool p_n = false;
	//bool p_e = false;
	//bool p_s = false;
	//bool p_w = false;
	switch(adj_id){
		case 0: // 北,南西
		now_y = now_y - 1; intra_box = SW;
		//p_n = true;
		break;
		case 1: // 北,南東
		now_y = now_y - 1; intra_box = SE;
		//p_n = true;
		break;
		case 2: // 東,北西
		now_x = now_x + 1; intra_box = NW;
		//p_e = true;
		break;
		case 3: // 東,南西
		now_x = now_x + 1; intra_box = SW;
		//p_e = true;
		break;
		case 4: // 南,北東
		now_y = now_y + 1; intra_box = NE;
		//p_s = true;
		break;
		case 5: // 南,北西
		now_y = now_y + 1; intra_box = NW;
		//p_s = true;
		break;
		case 6: // 西,南東
		now_x = now_x - 1; intra_box = SE;
		//p_w = true;
		break;
		case 7: // 西,北東
		now_x = now_x - 1; intra_box = NE;
		//p_w = true;
		break;
	}
	
	while(now_x!=start_x || now_y!=start_y){
		
		//cout << now_x << "," << now_y << endl;
		Point p = {now_x, now_y};
		trgt_line->pushPointToTrack(p);
		
		Direction trgt_d;
		switch(intra_box){
			case NE:
			trgt_d = my_board[now_y][now_x]->d_ne;
			break;
			case NW:
			trgt_d = my_board[now_y][now_x]->d_nw;
			break;
			case SE:
			trgt_d = my_board[now_y][now_x]->d_se;
			break;
			case SW:
			trgt_d = my_board[now_y][now_x]->d_sw;
			break;
			default:
			assert(!"Undefined Intra-Box");
			break;
		}
		
		vector<int> next_direction_array;
		if(trgt_d.n) next_direction_array.push_back(NORTH);
		if(trgt_d.e) next_direction_array.push_back(EAST);
		if(trgt_d.s) next_direction_array.push_back(SOUTH);
		if(trgt_d.w) next_direction_array.push_back(WEST);
		//cout << (int)(next_direction_array.size()) << endl;
		
		int next_count = (int)mt_genrand_int32(0, (int)(next_direction_array.size()) - 1);
		int next_id = next_direction_array[next_count];
		
		switch(next_id){
			case NORTH:
			now_y = now_y - 1; // 北へ
			if(intra_box == NE || intra_box == SE) intra_box = SE;
			if(intra_box == NW || intra_box == SW) intra_box = SW;
			//p_n = true; p_e = false; p_s = false; p_w = false;
			break;
			case EAST:
			now_x = now_x + 1; // 東へ
			if(intra_box == NE || intra_box == NW) intra_box = NW;
			if(intra_box == SE || intra_box == SW) intra_box = SW;
			//p_n = false; p_e = true; p_s = false; p_w = false;
			break;
			case SOUTH:
			now_y = now_y + 1; // 南へ
			if(intra_box == NE || intra_box == SE) intra_box = NE;
			if(intra_box == NW || intra_box == SW) intra_box = NW;
			//p_n = false; p_e = false; p_s = true; p_w = false;
			break;
			case WEST:
			now_x = now_x - 1; // 西へ
			if(intra_box == NE || intra_box == NW) intra_box = NE;
			if(intra_box == SE || intra_box == SW) intra_box = SE;
			//p_n = false; p_e = false; p_s = false; p_w = true;
			break;
		}
	}

	// ターゲットラインのトラックを整理する
	bool retry = true;
	while (retry) {
		retry = false;

		// トラックを一時退避 (コピー) する
		vector<Point> tmp_track;
		for (int i = 0; i < (int)(trgt_track->size()); i++) {
			tmp_track.push_back((*trgt_track)[i]);
		}

		// 冗長部分を排除してトラックを整理
		trgt_track->clear();
		for (int i = 0; i < (int)(tmp_track.size()); i++) {
			if ((int)(tmp_track.size()) - 2 <= i) {
				trgt_track->push_back(tmp_track[i]);
				continue;
			}
			if (tmp_track[i].x == tmp_track[i + 2].x && tmp_track[i].y == tmp_track[i + 2].y) {
				retry = true;
				i++;
				continue;
			}
			trgt_track->push_back(tmp_track[i]);
		}
	}
	
	// 中間ポートと中間からソースまでの経路を追加
	Point trgt_point = {trgt_line->getInterX(), trgt_line->getInterY()};
	trgt_track->push_back(trgt_point);
	for(int i=0;i<(int)(before_track.size());i++){
		trgt_track->push_back(before_track[i]);
	}
	
	// 表示
	// map<int,map<int,int> > for_print;
	// for(int y=0;y<board->getSizeY();y++){
		// for(int x=0;x<board->getSizeX();x++){
			// Box* trgt_box = board->box(x,y);
			// if(trgt_box->isTypeBlank()){
				// for_print[y][x] = -1;
			// }
			// else{
				// for_print[y][x] = trgt_box->getNumber();
			// }
		// }
	// }
	// for(int i=0;i<(int)(trgt_track->size());i++){
		// int point = (*trgt_track)[i];
		// int point_x = point % board->getSizeX();
		// int point_y = point / board->getSizeX();
		// for_print[point_y][point_x] = -2;
	// }
	// for(int y=0;y<board->getSizeY();y++){
		// for(int x=0;x<board->getSizeX();x++){
			// if(for_print[y][x] == -2) cout << "@";
			// else if(for_print[y][x] == -1) cout << "+";
			// else{
				// if(for_print[y][x] < 10){
					// cout << for_print[y][x];
				// }
				// else{
					// cout << changeIntToChar(for_print[y][x]);
				// }
			// }
		// }
		// cout << endl;
	// }
	
	for(int y=0;y<board->getSizeY();y++){
		for(int x=0;x<board->getSizeX();x++){
			delete my_board[y][x];
		}
	}
	
	return true;
}
/****************************************************************************
 * MenuLanguageSelect
 ***************************************************************************/
int MenuLanguageSelect() {
    int cnt = 0;
    int ret = 0, choice = 0;
    int scrollon;
    int returnhere = 0;

    GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume);
	// because destroy GuiSound must wait while sound playing is finished, we use a global sound
	if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);
	//	GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume);

    char imgPath[100];

    snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
    GuiImageData btnOutline(imgPath, button_dialogue_box_png);
    snprintf(imgPath, sizeof(imgPath), "%ssettings_background.png", CFG.theme_path);
    GuiImageData settingsbg(imgPath, settings_background_png);

    GuiTrigger trigA;
    trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
    GuiTrigger trigB;
    trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);

    char fullpath[100];
    int countfiles = GetAllDirFiles(Settings.languagefiles_path);

    if (!strcmp("", Settings.languagefiles_path)) {
        sprintf(fullpath, "%s", tr("Standard"));
    } else {
        sprintf(fullpath, "%s", Settings.languagefiles_path);
    }

    GuiText titleTxt(fullpath, 24, (GXColor) {0, 0, 0, 255});
    titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
    titleTxt.SetPosition(0,0);
    GuiButton pathBtn(300, 50);
    pathBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
    pathBtn.SetPosition(0,28);
    pathBtn.SetLabel(&titleTxt);
    pathBtn.SetSoundOver(&btnSoundOver);
    pathBtn.SetSoundClick(btnClick2);
    pathBtn.SetTrigger(&trigA);
    pathBtn.SetEffectGrow();

    GuiImage oggmenubackground(&settingsbg);
    oggmenubackground.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
    oggmenubackground.SetPosition(0, 0);

    GuiText backBtnTxt(tr("Back") , 22, THEME.prompttext);
    backBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
    GuiImage backBtnImg(&btnOutline);
    if (Settings.wsprompt == yes) {
        backBtnTxt.SetWidescreen(CFG.widescreen);
        backBtnImg.SetWidescreen(CFG.widescreen);
    }
    GuiButton backBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
    backBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
    backBtn.SetPosition(-190, 400);
    backBtn.SetLabel(&backBtnTxt);
    backBtn.SetImage(&backBtnImg);
    backBtn.SetSoundOver(&btnSoundOver);
    backBtn.SetSoundClick(btnClick2);
    backBtn.SetTrigger(&trigA);
    backBtn.SetTrigger(&trigB);
    backBtn.SetEffectGrow();

    GuiText defaultBtnTxt(tr("Default") , 22, THEME.prompttext);
    defaultBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
    GuiImage defaultBtnImg(&btnOutline);
    if (Settings.wsprompt == yes) {
        defaultBtnTxt.SetWidescreen(CFG.widescreen);
        defaultBtnImg.SetWidescreen(CFG.widescreen);
    }
    GuiButton defaultBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
    defaultBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
    defaultBtn.SetPosition(190, 400);
    defaultBtn.SetLabel(&defaultBtnTxt);
    defaultBtn.SetImage(&defaultBtnImg);
    defaultBtn.SetSoundOver(&btnSoundOver);
    defaultBtn.SetSoundClick(btnClick2);
    defaultBtn.SetTrigger(&trigA);
    defaultBtn.SetEffectGrow();

    GuiText updateBtnTxt(tr("Update Files") , 22, THEME.prompttext);
    updateBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
    GuiImage updateBtnImg(&btnOutline);
    if (Settings.wsprompt == yes) {
        updateBtnTxt.SetWidescreen(CFG.widescreen);
        updateBtnImg.SetWidescreen(CFG.widescreen);
    }
    GuiButton updateBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
    updateBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
    updateBtn.SetPosition(0, 400);
    updateBtn.SetLabel(&updateBtnTxt);
    updateBtn.SetImage(&updateBtnImg);
    updateBtn.SetSoundOver(&btnSoundOver);
    updateBtn.SetSoundClick(btnClick2);
    updateBtn.SetTrigger(&trigA);
    updateBtn.SetEffectGrow();

    customOptionList options2(countfiles);

    for (cnt = 0; cnt < countfiles; cnt++) {
        char filename[64];
        strlcpy(filename, GetFileName(cnt), sizeof(filename));
        char *dot = strchr(filename, '.');
        if (dot) *dot='\0';
        options2.SetName(cnt, "%s", filename);
        options2.SetValue(cnt, NULL);

    }

    if (cnt < 9) {
        scrollon = 0;
    } else {
        scrollon = 1;
    }

    GuiCustomOptionBrowser optionBrowser4(396, 280, &options2, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, scrollon, 10);
    optionBrowser4.SetPosition(0, 90);
    optionBrowser4.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);

    HaltGui();
    GuiWindow w(screenwidth, screenheight);
    w.Append(&oggmenubackground);
    w.Append(&pathBtn);
    w.Append(&backBtn);
    w.Append(&defaultBtn);
    w.Append(&updateBtn);
    w.Append(&optionBrowser4);
    mainWindow->Append(&w);

    w.SetEffect(EFFECT_FADE, 20);
    ResumeGui();

    while (w.GetEffect()>0) usleep(50);

    while (!returnhere) {

        if (shutdown == 1)
            Sys_Shutdown();
        else if (reset == 1)
            Sys_Reboot();

        else if (backBtn.GetState() == STATE_CLICKED) {

            backBtn.ResetState();
            break;
        }

        else if (defaultBtn.GetState() == STATE_CLICKED) {
            choice = WindowPrompt(tr("Loading standard language."),0,tr("OK"), tr("Cancel"));
            if (choice == 1) {
                sprintf(Settings.language_path, "notset");
                cfg_save_global();
                gettextCleanUp();
				HaltGui();
                CFG_Load();
				ResumeGui();
                returnhere = 2;
            }
            defaultBtn.ResetState();
			//optionBrowser4.SetFocus(1); // commented out to prevent crash
        }

        else if (updateBtn.GetState() == STATE_CLICKED) {
            choice = WindowPrompt(tr("Update all Language Files"),tr("Do you wish to update/download all language files?"),tr("OK"), tr("Cancel"));
            if (choice == 1) {

                bool network = true;
                if (!IsNetworkInit()) {
                    network = NetworkInitPrompt();
                }

                if (network) {
                    const char URL[60] = "http://usbloader-gui.googlecode.com/svn/trunk/Languages/";
                    char fullURL[300];
                    FILE *pfile;

                    URL_List LinkList(URL);
                    int listsize = LinkList.GetURLCount();

                    subfoldercreate(Settings.languagefiles_path);

                    for (int i = 0; i < listsize; i++) {

                        ShowProgress(tr("Updating Language Files:"), 0, LinkList.GetURL(i), i, listsize-1);

                        if (strcasecmp(".lang", strrchr(LinkList.GetURL(i), '.')) == 0) {

                            snprintf(fullURL, sizeof(fullURL), "%s%s", URL, LinkList.GetURL(i));

                            struct block file = downloadfile(fullURL);

                            if (file.data && file.size) {
                                char filepath[300];

                                snprintf(filepath, sizeof(filepath), "%s%s", Settings.languagefiles_path, LinkList.GetURL(i));
                                pfile = fopen(filepath, "wb");
                                fwrite(file.data, 1, file.size, pfile);
                                fclose(pfile);

                            }

                            free(file.data);
                        }
                    }
                    ProgressStop();
                    returnhere = 1;
                    break;
                }
            }
			updateBtn.ResetState();
			//optionBrowser4.SetFocus(1); // commented out to prevent crash
        }

        else if (pathBtn.GetState() == STATE_CLICKED) {
            w.Remove(&optionBrowser4);
            w.Remove(&backBtn);
            w.Remove(&pathBtn);
            w.Remove(&defaultBtn);
            char entered[43] = "";
            strlcpy(entered, Settings.languagefiles_path, sizeof(entered));
            int result = OnScreenKeyboard(entered,43,0);
            w.Append(&optionBrowser4);
            w.Append(&pathBtn);
            w.Append(&backBtn);
            w.Append(&defaultBtn);
            if ( result == 1 ) {
                int len = (strlen(entered)-1);
                if (entered[len] !='/')
                    strncat (entered, "/", 1);
                strlcpy(Settings.languagefiles_path, entered, sizeof(Settings.languagefiles_path));
                WindowPrompt(tr("Languagepath changed."),0,tr("OK"));
                if (isInserted(bootDevice)) {
                    cfg_save_global();
                    returnhere = 1;
                    break;
                } else {
                    WindowPrompt(tr("No SD-Card inserted!"), tr("Insert an SD-Card to save."), tr("OK"));
                }
            }
            if (countfiles > 0) {
                optionBrowser4.SetFocus(1);
            }
            pathBtn.ResetState();
        }

        ret = optionBrowser4.GetClickedOption();

        if (ret>=0) {
            choice = WindowPrompt(tr("Do you want to change language?"), 0, tr("Yes"), tr("Cancel"));
            if (choice == 1) {
                if (isInserted(bootDevice)) {
                    snprintf(Settings.language_path, sizeof(Settings.language_path), "%s%s", Settings.languagefiles_path, GetFileName(ret));
                    cfg_save_global();
                    if (!checkfile(Settings.language_path)) {
                        sprintf(Settings.language_path, tr("not set"));
                        WindowPrompt(tr("File not found."),tr("Loading standard language."),tr("OK"));
                    }
                    gettextCleanUp();
					HaltGui();
					CFG_Load();
					ResumeGui();
                    returnhere = 2;
                    break;
                } else {
                    WindowPrompt(tr("No SD-Card inserted!"), tr("Insert an SD-Card to save."), tr("OK"), 0,0,0,-1);
                }
            }
            optionBrowser4.SetFocus(1);
        }

    }

    w.SetEffect(EFFECT_FADE, -20);
    while (w.GetEffect()>0) usleep(50);

    HaltGui();
    mainWindow->Remove(&w);
    ResumeGui();

    return returnhere;
}