Exemplo n.º 1
0
/********************************************************************
 *	PIC24プログラムモード
 ********************************************************************
 */
void pic_bitbang(void)
{
	uchar cnt =PacketFromPC.raw[1];
	uchar wait=PacketFromPC.raw[2];
	uchar *p =&PacketFromPC.raw[3];
	uchar *t =&PacketToPC.raw[0];
	uchar c;
	while(cnt) {
		c = *p++;
//	ポート出力データ.
		set_bit(MCLR,c & 0x08);
		set_bit(PGM ,c & 0x04);
		set_bit(PGD ,c & 0x02);
		set_bit(PGC ,c & 0x01);
//	方向レジスタ (0=出力)
		set_dir(dirMCLR,c & 0x80);
		set_dir(dirPGM ,c & 0x40);
		set_dir(dirPGD ,c & 0x20);
		set_dir(dirPGC ,c & 0x10);
		if(Cmd0==PICSPX_BITREAD) {
			c = 0;
			if(digitalRead(inMCLR)) c|=0x08;
			if(digitalRead(inPGM))  c|=0x04;
			if(digitalRead(inPGD))  c|=0x02;
			if(digitalRead(inPGC))  c|=0x01;
			*t++ = c;
		}
		wait_ums(wait);
		wait_us(1);
		cnt--;
	}
}
Exemplo n.º 2
0
void Actor::swap_move_dir()
{
    switch(m_dir) {
        case Right:
            set_dir(Left);
            break;

        case Left:
            set_dir(Right);
            break;

        default:
            break;
    }
}
Exemplo n.º 3
0
static int
gpio_proc_write(struct file *file, const char *buffer, unsigned long count,
                void *data)
{
    u32 reg = 0;

    /* get buffer size */
    procfs_buffer_size = count;
    if (procfs_buffer_size > PROCFS_MAX_SIZE) {
        procfs_buffer_size = PROCFS_MAX_SIZE;
    }
    /* write data to the buffer */
    if (copy_from_user(procfs_buffer, buffer, procfs_buffer_size)) {
        return -EFAULT;
    }

    procfs_buffer[procfs_buffer_size] = 0;

    if (procfs_buffer[0] == '0' || procfs_buffer[0] == 'i')
        reg = 0;
    if (procfs_buffer[0] == '1' || procfs_buffer[0] == 'o')
        reg = 1;

    if ((unsigned int)data & GPIO_IN) {
        set_gpio_in(((unsigned int)data) & PIN_MASK, reg);
    }
    if ((unsigned int)data & GPIO_OUT) {
        set_gpio_out(((unsigned int)data) & PIN_MASK, reg);
    }
    if ((unsigned int)data & GPIO_DIR) {
        set_dir(((unsigned int)data) & PIN_MASK, reg);
    }

    return procfs_buffer_size;
}
Exemplo n.º 4
0
int ReadSource::set_file(const QString & filename)
{
	PENTER;
	
	Q_ASSERT(m_clip);

	m_error = 0;
	
	int splitpoint = filename.lastIndexOf("/") + 1;
	int length = filename.length();
	
	QString dir = filename.left(splitpoint - 1) + "/";
	QString name = filename.right(length - splitpoint);
		
	set_dir(dir);
	set_name(name);
	
	if (init() < 0) {
		return -1;
	}
	
	set_audio_clip(m_clip);
	
	emit stateChanged();
	
	return 1;
}
Exemplo n.º 5
0
int ReadSource::set_state( const QDomNode & node )
{
	PENTER;
	
	QDomElement e = node.toElement();
	m_channelCount = e.attribute("channelcount", "0").toInt();
	m_origSheetId = e.attribute("origsheetid", "0").toLongLong();
	set_dir( e.attribute("dir", "" ));
	m_id = e.attribute("id", "").toLongLong();
	m_rate = m_outputRate = e.attribute("rate", "0").toUInt();
	bool ok;
	m_length = TimeRef(e.attribute("length", "0").toLongLong(&ok));
	m_origBitDepth = e.attribute("origbitdepth", "0").toInt();
	m_wasRecording = e.attribute("wasrecording", "0").toInt();
	m_decodertype = e.attribute("decoder", "");
	
	// For older project files, this should properly detect if the 
	// audio source was a recording or not., in fact this should suffice
	// and the flag wasrecording would be unneeded, but oh well....
	if (m_origSheetId != 0) {
		m_wasRecording = true;
	}
	
	set_name( e.attribute("name", "No name supplied?" ));
	
	return 1;
}
Exemplo n.º 6
0
//--------- Begin of function Bullet::init ---------//
//
// <char> parentType		- the type of object emits the bullet
// <short> parentRecno	- the recno of the object
// <short> targetXLoc	- the x loc of the target
// <short> targetYLoc	- the y loc of the target
//	<char> targetMobileType - target mobile type
//
void Bullet::init(char parentType, short parentRecno, short targetXLoc, short targetYLoc, char targetMobileType)
{
	parent_type = parentType;
	parent_recno = parentRecno;
	target_mobile_type = targetMobileType;

	//**** BUGHERE, using parentType and parentRecno to allow bullet by firm, town, etc.
	//**** BUGHERE, only allow bullet by unit for this version
	err_when(parent_type!=BULLET_BY_UNIT);
	Unit *parentUnit = unit_array[parentRecno];

	//---------- copy attack info from the parent unit --------//

	AttackInfo* attackInfo = parentUnit->attack_info_array+parentUnit->cur_attack;

	attack_damage  = parentUnit->actual_damage();
	damage_radius  = attackInfo->bullet_radius;
	nation_recno   = parentUnit->nation_recno;
	// ###### begin Gilbert 26/6 ########## //
	fire_radius    = attackInfo->fire_radius;
	// ###### end Gilbert 26/6 ########## //

	//----- clone vars from sprite_res for fast access -----//

	sprite_id 	= attackInfo->bullet_sprite_id;
	sprite_info = sprite_res[sprite_id];

	sprite_info->load_bitmap_res();		// the sprite bitmap will be freed by ~Sprite(), so we don't have to add ~Bullet() to free it. 

	//--------- set the starting position of the bullet -------//

	cur_action = SPRITE_MOVE;
	cur_frame  = 1;
	set_dir(parentUnit->attack_dir);

	SpriteFrame* spriteFrame = cur_sprite_frame();

	origin_x = cur_x = parentUnit->cur_x;
	origin_y = cur_y = parentUnit->cur_y;

	//------ set the target position and bullet mobile_type -------//

	target_x_loc = targetXLoc;
	target_y_loc = targetYLoc;

	go_x = target_x_loc * ZOOM_LOC_WIDTH  + ZOOM_LOC_WIDTH/2  - spriteFrame->offset_x - spriteFrame->width/2;			// -spriteFrame->offset_x to make abs_x1 & abs_y1 = original x1 & y1. So the bullet will be centered on the target
	go_y = target_y_loc * ZOOM_LOC_HEIGHT + ZOOM_LOC_HEIGHT/2 - spriteFrame->offset_y - spriteFrame->height/2;

	mobile_type = parentUnit->mobile_type;

	//---------- set bullet movement steps -----------//

	int xStep 	= (go_x - cur_x)/attackInfo->bullet_speed;
	int yStep 	= (go_y - cur_y)/attackInfo->bullet_speed;

	total_step  = MAX(1, MAX(abs(xStep), abs(yStep)));
	cur_step    = 0;

	err_when( total_step < 0 );		// number overflow
}
Exemplo n.º 7
0
intptr_t WINAPI SetDirectoryW(const SetDirectoryInfo* info) {
  PluginInstance* plugin = (PluginInstance*) info->hPanel;
  bool show_error = (info->OpMode & (OPM_SILENT | OPM_FIND | OPM_QUICKVIEW)) == 0;
  try {
    return set_dir(plugin, info->Dir, show_error);
  }
  HANDLE_ERROR(FALSE, TRUE);
}
Exemplo n.º 8
0
void Actor::set_action(Action action)
{
    if (m_action != action) {
        m_anim_dir = AnimUp;
        m_action = action;
        set_dir();
    }
}
Exemplo n.º 9
0
void Crawler::check_ground(Map *map)
{
    if (get_hit_ground()) {
        if (m_dir == Right) {
            if (!check_collision(m_x + get_attribute("right"),
                                 m_y + get_attribute("bottom") + 1, map)) {
                set_dir(Left);
            }
        }
        else if (m_dir == Left) {
            if (!check_collision(m_x + get_attribute("left"),
                                 m_y + get_attribute("bottom") + 1, map)) {
                set_dir(Right);
            }
        }
    }
}
Exemplo n.º 10
0
void Climber::move_climb(Map *map, int input)
{
    const Tmx::Tileset *tileset = map->get_tileset(0);
    const Tmx::PropertySet prop = tileset->GetProperties();
    int block_id = prop.GetNumericProperty("climb");

    if (!m_leave_ready && m_leave_timer.expired(c_leave_time)) {
        m_leave_ready = true;
    }

    switch (m_climb_dir) {
        case ClimbRight:
        case ClimbLeft:
            if (input & PRESS_JUMP) {
                if (m_leave_ready) {
                    leave_climb(map);
                }
            }
            else if (input & PRESS_DOWN) {
                animate_climb();
                set_action(Move);
                set_dir(Right);
                set_vy(check_ahead(map, get_attribute("move_speed"),
                                   block_id, block_id));
            }
            else if (input & PRESS_UP) {
                animate_climb();
                set_action(Move);
                set_dir(Left);
                set_vy(-check_ahead(map, get_attribute("move_speed"),
                                    block_id, block_id));
            }
            else {
                set_dir();
                set_action(Still);
                set_vy(0);
            }
            break;

        default:
            break;
    }

    Body::move(map);
}
Exemplo n.º 11
0
/*!
  Copies the point and dir pointers from \a p.  Also copies the values
  of empty and gdType .
*/
sphericalGraspDirection::sphericalGraspDirection(GraspDirection* p) : GraspDirection()
{
    point = new spherical_coordinates();
    set_point(p->get_point());
    dir = new spherical_coordinates();
    set_dir(p->get_dir());
    empty = p->get_empty();
    set_gdType(p->get_gdType());
}
Exemplo n.º 12
0
void set_gpio(int pin, int val)
{
    if (pin >= 200) {
        ltq_stp_set(NULL, pin - 200, val);
        return;
    }
    set_dir(pin, 1);
    set_gpio_out(pin, val);
}
Exemplo n.º 13
0
/*********************************************************************
 *	16bitデータの受信
 *********************************************************************
 */
int	recvData16(void)
{
	int rc;
	add_data4(b_0001);	// send SIX command '0000'
	add_data8(0x00  );	// send 1 byte '0000_0000'

//	PGC=0;
	set_bit(PGC ,0);

//	dirPGD=1;			// INPUT
	set_dir(dirPGD ,1);

	wait_us(1);
	rc = pic24_getData16();

//	dirPGD=0;			// OUTPUT
	set_dir(dirPGD ,0);
	wait_us(1);
	send_nop1();
	return rc;
}
Exemplo n.º 14
0
void Shooter::update(const game::GameContext & c) {
	switch (c.u.input().key_down()) {
		case SDLK_LEFT:left_key_down_ = true;break;
		case SDLK_RIGHT:right_key_down_ = true;break;
		case SDLK_UP:up_key_down_ = true;break;
		case SDLK_DOWN: down_key_down_ = true;break;
		default:break;
	}
	switch (c.u.input().key_up()) {
		case SDLK_LEFT:left_key_down_ = false;break;
		case SDLK_RIGHT:right_key_down_ = false;break;
		case SDLK_UP:up_key_down_ = false;break;
		case SDLK_DOWN: down_key_down_ = false;break;
		default:break;
	}
	if (left_key_down_ && !right_key_down_)
		set_dir(HorizontalDir::Left);
	else if (right_key_down_ && !left_key_down_)
		set_dir(HorizontalDir::Right);
	else
		set_dir(HorizontalDir::None);
	if (up_key_down_ && !down_key_down_)
		set_dir(VerticalDir::Up);
	else if (down_key_down_ && !up_key_down_)
		set_dir(VerticalDir::Down);
	else
		set_dir(VerticalDir::None);
	move(c.u.seconds_per_update());
}
Exemplo n.º 15
0
//--------- Begin of function Tornado::init ---------//
//
// <short> startX, startY       starting location of the tornado
// <short> lifeTime             time (no. of frames) the tornado survive
//
void Tornado::init(short startX, short startY, short lifeTime)
{
	Sprite::init(TORNADO_SPRITE_ID, startX, startY);
	err_when( strcmp("TORNADO", sprite_info->sprite_code ) );

	attack_damage  = (float) 2.0 / ATTACK_SLOW_DOWN;
	life_time = lifeTime;

	set_dir(DIR_N);
	cur_action = SPRITE_MOVE;		// always moving
	dmg_offset_x = 0;
	dmg_offset_y = 0;
}
Exemplo n.º 16
0
void Actor::face_reference(int width)
{
    const Sprite *spr = get_sprite();
    int check_width;

    if (!width) {
        check_width = spr->get_width();
    }
    else {
        check_width = width;
    }

    if (abs(m_xref - get_front()) < check_width) {
        set_dir();
    }
    else if (m_xref > get_front()) {
        set_dir(Right);
    }
    else if (m_xref < get_front()) {
        set_dir(Left);
    }
}
Exemplo n.º 17
0
void main(int argc, char * argv[]) 
{
	//Set up gpio to be pointer to chunk of memory that includes I/O.
	//gets around virtual memory issues too.
	gpio=init_memmap();
	
	set_dir(38,OUT);
	while(1)
	{
		set_pin(38);
		clear_pin(38);
	}
}
Exemplo n.º 18
0
int				key_hook(t_all *all)
{
	int		ch;
	t_pos	dir;

	ch = getch();
	if (ch)
	{
		if (ch == ECHAP)
			return (-1);
		if (ch == K_LEFT)
			set_dir(&dir, -1, 0);
		else if (ch == K_RIGHT)
			set_dir(&dir, 1, 0);
		else if (ch == K_UP)
			set_dir(&dir, 0, -1);
		else if (ch == K_DOWN)
			set_dir(&dir, 0, 1);
		all->env.played = 1;
		if (ch == K_LEFT || ch == K_RIGHT || ch == K_UP
		|| ch == K_DOWN)
			ft_move(all, dir);
	}
}
Exemplo n.º 19
0
//--------- Begin of function Unit::ship_leave_beach ---------//
void Unit::ship_leave_beach(int shipOldXLoc, int shipOldYLoc)
{
	err_when(cur_x!=next_x || cur_y!=next_y);

	UnitMarine *shipPtr = (UnitMarine*) this;
	err_when(!shipPtr->in_beach && shipPtr->extra_move_in_beach==EXTRA_MOVE_FINISH);

	//--------------------------------------------------------------------------------//
	// scan for location to leave the beach
	//--------------------------------------------------------------------------------//
	int curXLoc = next_x_loc();
	int curYLoc = next_y_loc();
	int xShift, yShift, checkXLoc, checkYLoc, found=0;
	Location *locPtr;

	//------------- find a location to leave the beach ------------//
	for(int i=2; i<=9; i++)
	{
		misc.cal_move_around_a_point(i, 3, 3, xShift, yShift);
		checkXLoc = curXLoc + xShift;
		checkYLoc = curYLoc + yShift;

		if(checkXLoc<0 || checkXLoc>=MAX_WORLD_X_LOC || checkYLoc<0 || checkYLoc>=MAX_WORLD_Y_LOC)
			continue;
		
		if(checkXLoc%2 || checkYLoc%2)
			continue;

		locPtr = world.get_loc(checkXLoc, checkYLoc);
		if(terrain_res[locPtr->terrain_id]->average_type==TERRAIN_OCEAN &&
			locPtr->can_move(mobile_type))
		{
			found++;
			break;
		}
	}

	if(!found)
		return; // no suitable location, wait until finding suitable location

	//---------------- leave now --------------------//
	set_dir(shipOldXLoc, shipOldYLoc, checkXLoc, checkYLoc);
	set_ship_extra_move();
	go_x = checkXLoc*ZOOM_LOC_WIDTH;
	go_y = checkYLoc*ZOOM_LOC_HEIGHT;
	err_when(cur_x==go_x && cur_y==go_y);
}
int copy(const char *in_object) {
    
    char object[PATH_SIZE];
    
    strcpy(object, in_object);
    struct stat buf;
   // log_add(DEBUGGING, "In copy %s\n", object);
    if (stat(object, &buf) != 0) {
        log_add(FATAL, "stat failed\n");
        return errno;
    }
    if(S_ISDIR(buf.st_mode)) {
        DIR *dir;
        struct dirent *entry;
        
        if ((dir = opendir(object)) == 0) {
            log_add(FATAL, "Can't open directory\n");
            return errno;
        }

        set_dir(get_filename(object), buf.st_mode);
        
        while ((entry = readdir(dir)) != NULL) {
          //  log_add(DEBUGGING, "In while\n");
           // log_add(DEBUGGING, "object is %s\n", object);
            //log_add(DEBUGGING, "file %s\n", entry->d_name);
            if (is_good_file(entry->d_name)) {
                
                strcat(object, "/");
                strcat(object, entry->d_name);
                
                copy(object);
                object[strlen(object)-strlen(entry->d_name)-1] = '\0';
            }
            
        }
        closedir(dir);
        prev_dir();
    }
    else {
      //  log_add(DEBUGGING, "It's file: %s\n", object);
        copy_file(object, curr_out_dir());
    }
    
    return 0;
}
Exemplo n.º 21
0
/* Makes sure hardware single-stepping is (globally) enabled.
   Returns true if successful.  */
static inline int enable_single_stepping (void)
{
	static int enabled = 1;	/* Remember whether we already did it.  */
	return enabled;
	if (! enabled) {
		/* Turn on the SE (`single-step enable') bit, 0x100, in the
		   DIR (`debug information register').  This may fail if a
		   processor doesn't support it or something.  We also try
		   to clear bit 0x40 (`INI'), which is necessary to use the
		   debug stuff on the microblazee2; on the microblazee, clearing 0x40
		   shouldn't cause any problem.  */
		microblaze_reg_t dir = set_dir (0x100, 0x40);
		/* Make sure it really got set.  */
		if (dir & 0x100)
			enabled = 1;
	}
	return enabled;
}
void CL_FileDialog_Generic::read_dir()
{
	std::string cwd = CL_Directory::get_current();
	path = cwd;

	int find_last1 = cwd.rfind('/');
	int find_last2 = cwd.rfind('\\');

	int index = 0;
	if(find_last1 != -1)
		index = find_last1 + 1;
	else if(find_last2 != -1)
		index = find_last2 + 1;

	cwd = cwd.substr(cwd.length() - (cwd.length() - index));

	set_dir(cwd);
}
Exemplo n.º 23
0
//--------- Begin of function Tornado::init ---------//
//
// <short> startX, startY       starting location of the tornado
// <short> lifeTime             time (no. of frames) the tornado survive
//
void Tornado::init(short startX, short startY, short lifeTime)
{
	static int spriteId = sprite_res.search_sprite( TORNADO_SPRITE_NAME );
	err_when( !spriteId );

	Sprite::init(spriteId, startX, startY);
	// err_when( strcmp("TORNADO", sprite_info->sprite_code ) );

	attack_damage  = (float) 2.0 / ATTACK_SLOW_DOWN;
	life_time = lifeTime;

	set_dir(DIR_N);
	cur_action = SPRITE_MOVE;		// always moving
	dmg_offset_x = 0;
	dmg_offset_y = 0;

	damage_player_flag = 0;
}
Exemplo n.º 24
0
//this is my custom movement fucntion unique to the ascii man class
void ascii_man::move(void)
{
	//dont move if i already moved it somewhere else
  	if (did_move()==false && did_collide()==false)
	{
		//temp move i think is now not used
		if (get_temp_mv_p()==NULL)
		{set_pt(get_pt()+get_mv());}
		else
		{
			set_pt(get_pt()+get_temp_mv());
			set_temp_mv(NULL);
		}
		did_move(true);
	}

	//this is where i set the direction the dude is moving
	if (get_mv().get_x() != 0)
	{set_dir((int)(get_mv().get_x()/abs(get_mv().get_x())));}
}
Exemplo n.º 25
0
// This constructor is called for existing (recorded/imported) audio sources
ReadSource::ReadSource(const QDomNode node)
	: AudioSource()
{
	
	set_state(node);
	
	private_init();
	
	Project* project = pm().get_project();
	
	// FIXME The check below no longer makes sense!!!!!
	// Check if the audiofile exists in our project audiosources dir
	// and give it priority over the dir as given by the project.tpf file
	// This makes it possible to move project directories without Traverso being
	// unable to find it's audiosources!
	if ( QFile::exists(project->get_root_dir() + "/audiosources/" + m_name) || 
	     QFile::exists(project->get_root_dir() + "/audiosources/" + m_name + "-ch0.wav") ) {
		set_dir(project->get_root_dir() + "/audiosources/");
	}
	
	m_silent = (m_channelCount == 0);
}	
Exemplo n.º 26
0
//--------- Begin of function Sprite::sprite_move --------//
//
// <int> desX, desY   - the destination coordination
//
void Sprite::sprite_move(int desX, int desY)
{
	if( cur_action != SPRITE_MOVE )
	{
		cur_action = SPRITE_MOVE;
		cur_frame  = 1;
	}

	err_when(desX<0 || desY<0 || desX>=MAX_WORLD_X_LOC*LOCATE_WIDTH || desY>=MAX_WORLD_Y_LOC*LOCATE_HEIGHT);

#ifdef DEBUG	
	short vectorX=desX-next_x;
	short vectorY=desY-next_y;
	
	if(vectorX && vectorY)	// both are non-zero
	{
		err_if(abs(vectorX) != abs(vectorY))
			err_here();
	}
#endif

	go_x = desX;
	go_y = desY;

	//----------- determine the movement direction ---------//

	set_dir(cur_x, cur_y, go_x, go_y);

	//------ set the next tile to move towards -------//
/*
	next_x = cur_x;
	next_y = cur_y;
*/
	int stepMagn = move_step_magn();
	set_next(cur_x+stepMagn*move_x_pixel_array[final_dir], cur_y+stepMagn*move_y_pixel_array[final_dir], -stepMagn);

	err_when(cur_action==SPRITE_MOVE && (cur_x!=next_x || cur_y!=next_y) &&
				final_dir!=(check_dir1=get_dir(cur_x, cur_y, next_x, next_y)));
}
Exemplo n.º 27
0
WORD
count( char *s )
{
	char	*tmp;
	int	ret;

	tmp = s;
	while ( *tmp++ );

	if (*(tmp-2) == '*')		/* a dir 		*/
	{
	  if ( set_dir( s ) )		/* set the path		*/
	  {
	    ret = countrec();
	    Dsetpath( "\\" );
	    return( ret );		/* recursive count	*/	
	  }
	  else
	    return( FALSE );	
	}
	numfiles++;
	return(TRUE);
}
Exemplo n.º 28
0
                         int shell (int argc, char *argv[]) {
                         char *s=NULL; //= malloc(INPUT_STRING_SIZE+1);			/* user input string */

                         tok_t *t;			/* tokens parsed from input */
                         int lineNum = 0;
                         int fundex = -1;
                         pid_t pid = getpid();		/* get current processes PID */
                         pid_t ppid = getppid();	/* get parents PID */
                         pid_t cpid, tcpid, cpgid;

                         init_shell();

                         printf("%s running as PID %d under %d\n",argv[0],pid,ppid);

                         lineNum=0;

                         set_dir();

                         fprintf(stdout, "%d:%s $ ", lineNum,cdir);
                         while ((s = freadln(stdin))) {

                         t = getToks(s); /* break the line into tokens */
                         //printf("args s: %s\n",s);
                         fundex = lookup(t[0]); /* Is first token a shell literal */
                         if(fundex >= 0) cmd_table[fundex].fun(&t[1]);
                         else {
                         if(t[0]) {
                         terminal_cmd(t);
                     }
                         //fprintf(stdout, "This shell only supports built-ins. Replace this to run programs as commands.\n");
                     }
                         free(s);
                         freeToks(t);
                         fprintf(stdout, "%d:%s $ ", lineNum,cdir);
                     }
                         return 0;
                     }
Exemplo n.º 29
0
int cmd_cd(tok_t arg[]) {
    char temp[MAX_DIR_STRING_SIZE];
    if(arg[0]) {
        strcpy(temp,arg[0]);
        char *spacer="\ ";
                     int i;
                     for(i=1; arg[i]; i++) {
                     strcat(temp,spacer);
                     strcat(temp,arg[i]);

                 }
                 }
             //printf("TEST: %s\n",temp);

                     if(chdir(temp)==0) {
                     set_dir();
                     return 1;
                 } else {
             fprintf(stdout,"no such file or directory :\\\n");
                     return 0;
                 }


                 }
Exemplo n.º 30
0
int TFileSel::mychdir(int n) {
    char *old = NULL;
  if (n == 0) { // ..
    char *s = strrchr(path,SLASH[0]);
    if (s) {
      *s = 0;
      old = strdup(s+1);
#ifdef RAINE_WIN32
      if (s[-1] == SLASH[0]) { s[-1] = 0; // double \ in windows
	printf("double replace for %s\n",path);
      }
#endif
    }
#ifdef RAINE_WIN32
    if (strlen(path)==2) // only the drive letter is left
      strcat(path,SLASH);
#else
    if (!*path)
      strcpy(path,SLASH);
#endif
  } else
    sprintf(&path[strlen(path)],"%s%s",SLASH,menu[n].label);
  set_dir(path);
  if (old) {
      for (n=0; n<nb_items; n++)
	  if (!strcmp(menu[n].label,old)) {
	      sel = n;
	      break;
	  }
      free(old);
  }
  top = 0;
  if (top + rows - 1 < sel) top = sel-rows+1;

  return 0;
}