Пример #1
0
short SaveLangFileAs( char *filename )
{
	char fileWithPath[1024];
	// Check the exe directory first - as this is where users should have their lang directory
	GetLangV41File( fileWithPath, gPath, PATHSEPSTR, 0 ); 
	if ( ValidatePath( fileWithPath ) )
	{
		// Now check for a lang directory which is located back a directory - this where we have our lang directory
		GetLangV41File( fileWithPath, gPath, PATHBACKDIR, 0 ); 
	}
	if ( ValidatePath( fileWithPath ) )
	{
		// Try the current directory - basically, a last resort...
		GetLangV41File( fileWithPath, 0, 0, 0 ); 
	}
	if ( GetLangSaveFolderName( fileWithPath, filename ) )
	{
		ReadNewLangStringsFromLangList();
		char *pos;
		pos = strstri( fileWithPath, LANG_EXT );
		if ( !pos )
			mystrcat( fileWithPath, LANG_EXT );
		if ( SaveNewLangStringsToLangFile( fileWithPath ) )
		{
			FileFromPath( fileWithPath, MyPrefStruct.language );
			strcpyuntil( MyPrefStruct.language, MyPrefStruct.language, '.' );
			return 1;
		}
	}
	return 0;
}
Пример #2
0
Файл: config.c Проект: VCCE/VCC
unsigned char WriteIniFile(void)
{
	vccPakGetCurrentModule(CurrentConfig.ModulePath);
	ValidatePath(CurrentConfig.ModulePath);
	ValidatePath(CurrentConfig.ExternalBasicImage);
	WritePrivateProfileString("Version","Release",AppName,IniFilePath);

	WritePrivateProfileInt("CPU","DoubleSpeedClock",CurrentConfig.CPUMultiplyer,IniFilePath);
	WritePrivateProfileInt("CPU","FrameSkip",CurrentConfig.FrameSkip,IniFilePath);
	WritePrivateProfileInt("CPU","Throttle",CurrentConfig.SpeedThrottle,IniFilePath);
	WritePrivateProfileInt("CPU","CpuType",CurrentConfig.CpuType,IniFilePath);
	WritePrivateProfileInt("CPU", "MaxOverClock", CurrentConfig.MaxOverclock, IniFilePath);

	WritePrivateProfileString("Audio","SndCard",CurrentConfig.SoundCardName,IniFilePath);
	WritePrivateProfileInt("Audio","Rate",CurrentConfig.AudioRate,IniFilePath);

	WritePrivateProfileInt("Video","MonitorType",CurrentConfig.MonitorType,IniFilePath);
	WritePrivateProfileInt("Video","ScanLines",CurrentConfig.ScanLines,IniFilePath);
	WritePrivateProfileInt("Video","AllowResize",CurrentConfig.Resize,IniFilePath);
	WritePrivateProfileInt("Video","ForceAspect",CurrentConfig.Aspect,IniFilePath);

	Cassette::writeConfig(IniFilePath);

	WritePrivateProfileInt("Memory","RamSize",CurrentConfig.RamSize,IniFilePath);
	WritePrivateProfileString("Memory", "ExternalBasicImage", CurrentConfig.ExternalBasicImage, IniFilePath);

	WritePrivateProfileInt("Misc","AutoStart",CurrentConfig.AutoStart,IniFilePath);
	WritePrivateProfileInt("Misc","CartAutoStart",CurrentConfig.CartAutoStart,IniFilePath);
	WritePrivateProfileInt("Misc","KeyMapIndex",CurrentConfig.KeyMap,IniFilePath);
	WritePrivateProfileString("Misc", "LastPakPath", vccPakGetLastPath(), IniFilePath);
	WritePrivateProfileString("Misc", "LastPrnPath", LastPrnPath, IniFilePath);

	WritePrivateProfileString("Module", "OnBoot", CurrentConfig.ModulePath, IniFilePath);

	WritePrivateProfileInt("LeftJoyStick","UseMouse",Left.UseMouse,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","Left",Left.Left,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","Right",Left.Right,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","Up",Left.Up,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","Down",Left.Down,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","Fire1",Left.Fire1,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","Fire2",Left.Fire2,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick","DiDevice",Left.DiDevice,IniFilePath);
	WritePrivateProfileInt("LeftJoyStick", "HiResDevice", Left.HiRes, IniFilePath);
	WritePrivateProfileInt("RightJoyStick","UseMouse",Right.UseMouse,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","Left",Right.Left,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","Right",Right.Right,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","Up",Right.Up,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","Down",Right.Down,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","Fire1",Right.Fire1,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","Fire2",Right.Fire2,IniFilePath);
	WritePrivateProfileInt("RightJoyStick","DiDevice",Right.DiDevice,IniFilePath);
	WritePrivateProfileInt("RightJoyStick", "HiResDevice", Right.HiRes, IniFilePath);

	return(0);
}
Пример #3
0
CStdString SystemFolderInfo::GetCommonAppDataPath()
{
	CStdString sPath;

	switch (GetWindowsVersion())
	{
	case WINDOWS_95:
	case WINDOWS_ME:
	case WINDOWS_98:
		sPath = GetWindowsPath() + _T("\\All Users\\Application Data");
		break;

	case WINDOWS_NT:
		sPath = GetFolderPath(CSIDL_COMMON_APPDATA, NULL);

		// For some reason - if the user has restricted access to the folder
		// this will return an empty string - but we know we can
		// access it and it should exist!
		if (sPath.IsEmpty())
			sPath = GetProfilesRoot() + _T("\\All Users\\Application Data");
		break;

	case WINDOWS_2K:
	case WINDOWS_XP:
	case WINDOWS_2003SERVER:
	default:
		sPath = GetFolderPath(CSIDL_COMMON_APPDATA, NULL);
		break;

	}

	ValidatePath(sPath, CSIDL_COMMON_APPDATA);
	return sPath;
}
Пример #4
0
CStdString SystemFolderInfo::GetDefaultUserAppDataPath()
{
	CStdString sPath;

	switch (GetWindowsVersion())
	{
	case WINDOWS_95:
	case WINDOWS_ME:
	case WINDOWS_98:
		sPath = GetWindowsPath() + _T("\\Application Data");
		break;

	case WINDOWS_NT:
		{
			sPath = GetLocalUserAppDataPath();

			int nPos = sPath.Find(_T("\\"), GetProfilesRoot().size()+1);

			sPath = GetProfilesRoot() + _T("\\Default User\\") + sPath.Right(sPath.size() - nPos - 1);
		}
		break;

	case WINDOWS_2K:
	case WINDOWS_XP:
	case WINDOWS_2003SERVER:
	default:
		sPath = GetFolderPath(CSIDL_APPDATA, (HANDLE)-1);
		break;

	}

	ValidatePath(sPath, CSIDL_APPDATA);
	return sPath;
}
Пример #5
0
CStdString SystemFolderInfo::GetLocalUserAppDataPath()
{
	CStdString sPath;

	switch (GetWindowsVersion())
	{
	case WINDOWS_95:
	case WINDOWS_ME:
	case WINDOWS_98:
		{
			if (HasWin98UserGotProfile())
				sPath = GetProfilePath() + _T("\\Application Data");
			else
				sPath = GetWindowsPath() + _T("\\Local Settings\\Application Data");
		}

		break;

	case WINDOWS_NT:
	case WINDOWS_2K:
	case WINDOWS_XP:
	case WINDOWS_2003SERVER:
	default:
		sPath = GetFolderPath(CSIDL_APPDATA, NULL);
		break;

	}

	ValidatePath(sPath, CSIDL_APPDATA);
	return sPath;
}
Пример #6
0
CStdString SystemFolderInfo::GetCommonStartMenu()
{
	CStdString sPath;

	switch (GetWindowsVersion())
	{
	case WINDOWS_95:
	case WINDOWS_ME:
	case WINDOWS_98:
		{
			if (HasWin98UserGotProfile())
				sPath = GetProfilePath();
			else
				sPath = GetWindowsPath();

			sPath += _T("\\Local Settings\\Start Menu");
		}

		break;

	case WINDOWS_NT:
	case WINDOWS_2K:
	case WINDOWS_XP:
	case WINDOWS_2003SERVER:
	default:
		sPath = GetFolderPath(CSIDL_COMMON_STARTMENU, NULL);
		break;

	}

	ValidatePath(sPath, CSIDL_COMMON_STARTMENU);
	return sPath;
}
Пример #7
0
void show_prefixes6(int count,struct prefix *prefix,BGPDATA BGP,BGPDUMP_ENTRY *entry,std::ofstream &outFile)
{
        int i;
        char buf[128];
	return;
        for (i=0;i<count;i++) {
		char cidr[128];
		int arv = 0;
		int srv = 0;
	        sprintf(cidr,"%s/%d",inet_ntop(AF_INET6,&prefix[i].address.v6_addr,buf,128),prefix[i].len);
		if (entry->attr->aspath != NULL && !BGP.asnfile.empty()) {
			arv = ValidatePath(entry->attr->aspath->str,BGP);
		}
		else if (entry->attr->aspath != NULL) {
			arv = 1;
		}
		if (!BGP.setfile.empty()) {
			srv = ValidateSet(cidr,BGP);
		}
		else {
			srv = 1;
		}
		if (BGP.or_flag) {
			if (arv != 0 || srv != 0) 
				print_entry(cidr,entry,outFile);
		}
		else if (srv != 0 && arv != 0) {
			print_entry(cidr,entry,outFile);
		}
	}
}
Пример #8
0
/* TODO */
int BfastAlignValidateInputs(struct arguments *args) {

	char *FnName="BfastAlignValidateInputs";

	/* Check if we are piping */
	if(NULL == args->readsFileName) {
		VERBOSE = -1;
	}

	if(0<=VERBOSE) {
		fprintf(stderr, BREAK_LINE);
		fprintf(stderr, "Checking input parameters supplied by the user ...\n");
	}

	if(args->fastaFileName!=0) {
		if(0<=VERBOSE) {
			fprintf(stderr, "Validating fastaFileName %s. \n",
					args->fastaFileName);
		}
		if(ValidateFileName(args->fastaFileName)==0)
			PrintError(FnName, "fastaFileName", "Command line argument", Exit, IllegalFileName);	
	}	
	else {		
		PrintError(FnName, "fastaFileName", "Required command line argument", Exit, IllegalFileName);	
	}

	if(args->readsFileName!=0) {
		if(0<=VERBOSE) {
			fprintf(stderr, "Validating readsFileName %s. \n",
					args->readsFileName);
		}
		if(ValidateFileName(args->readsFileName)==0)
			PrintError(FnName, "readsFileName", "Command line argument", Exit, IllegalFileName);	
	}	

	if(args->space != NTSpace && args->space != ColorSpace) {
		PrintError(FnName, "space", "Command line argument", Exit, OutOfRange);	
	}	
	
	if(args->numThreads<=0) {		
		PrintError(FnName, "numThreads", "Command line argument", Exit, OutOfRange);
	} 

	if(args->tmpDir!=0) {		
		if(0 <= VERBOSE) {
			fprintf(stderr, "Validating tmpDir path %s. \n", 
					args->tmpDir);
		}
		if(ValidatePath(args->tmpDir)==0)
			PrintError(FnName, "tmpDir", "Command line argument", Exit, IllegalPath);	
	}	
	/* If this does not hold, we have done something wrong internally */	
	assert(args->timing == 0 || args->timing == 1);

	return 1;
}
Пример #9
0
void ValidateAllPaths (void)
{
	//int				i;
	CObject			*objP;
	tAIStaticInfo	*aiP;

FORALL_ROBOT_OBJS (objP, i) {
	aiP = &objP->cType.aiInfo;
	if ((objP->info.controlType == CT_AI) &&
		 (aiP->nHideIndex != -1) && (aiP->nPathLength > 0) &&
		 !ValidatePath (4, &gameData.ai.routeSegs [aiP->nHideIndex], aiP->nPathLength))
		aiP->nPathLength = 0;	//	This allows people to resume without harm...
	}
Пример #10
0
/*---------------------------------------------------------------------*/
H_ARCHIVE ArchiveOpenForWrite(CHAR * path)
{
    H_ARCHIVE harchive;
    ARCHIVE *archive;

    ArchiveLog(ARC_LOG_VERBOSE, "Open archive for write: %s", path);

    _archive_error = ARC_NO_ERROR;

    /* Get next available handle */
    if ((harchive = GetNextHandle()) == VOID_H_ARCHIVE)
        return (VOID_H_ARCHIVE);

    _archive[harchive].last_error = ARC_NO_ERROR;

    /* Check out the path */
    if (!ValidatePath(path, harchive))
        return (VOID_H_ARCHIVE);

    /* Create stream list */
    if (!CreateList(&_archive[harchive].streams)) {
        _archive_error = ARC_NO_MEMORY;
        return (VOID_H_ARCHIVE);
    }

    /* Get state and lock for write access */
    if (!OpenStateForWrite(harchive)) {
        _archive_error = _archive[harchive].last_error;
        return (VOID_H_ARCHIVE);
    }

    _n_archives++;

    /* Start the purge thread... */
    archive = &_archive[harchive];
    if (archive->state.thres_bytes != VOID_UINT64) {
        MUTEX_LOCK(&archive->purge.mutex);
        if(!archive->purge.active ) {
            ArchiveLog(ARC_LOG_VERBOSE, "Starting purge thread");
            if(!THREAD_CREATE(&archive->purge.thread_id, PurgeThread, &archive->purge)) {
                MUTEX_UNLOCK(&archive->purge.mutex);
                _archive_error = ARC_PURGE_THREAD;
                return (VOID_H_ARCHIVE);
            }
        }
        MUTEX_UNLOCK(&archive->purge.mutex);
    }

    return (harchive);
}
Пример #11
0
NTSTATUS
CheckED(
    IN PED EDRecord,
    IN IED ied
    )
{
    int i;

    i = ValidatePath( ied, EDRecord, EDRecord->pthEd );
    if (i != -1) {
#if DBG
        SrvPrint1( "CheckED( %d ): ", ied );
        SrvPrint4( "%s %s (User Path invalid in %d char (%02x))\n",
                  EDRecord->nmOwner,
                  EDRecord->pthEd,
                  i,
                  EDRecord->pthEd[ i ]
                );
#endif
        return( (NTSTATUS)((ULONG)STATUS_UNSUCCESSFUL + 0x6000 + ied) );
        }

    i = ValidateName( ied,
                      EDRecord->nmOwner,
                      cchUserMax,
                      FALSE
                    );
    if (i != -1) {
#if DBG
        SrvPrint1( "CheckED( %d ): ", ied );
        SrvPrint4( "%s %s (Owner invalid in %d char (%02x))\n",
                  EDRecord->nmOwner,
                  EDRecord->pthEd,
                  i,
                  EDRecord->nmOwner[ i ]
                );
#endif
        return( (NTSTATUS)((ULONG)STATUS_UNSUCCESSFUL + 0x7000 + ied) );
        }

    return( STATUS_SUCCESS );
}
Пример #12
0
/*---------------------------------------------------------------------*/
H_ARCHIVE ArchiveOpenForRead(CHAR * path)
{
    H_ARCHIVE harchive;

    ArchiveLog(ARC_LOG_VERBOSE, "Open archive for read: %s", path);

    _archive_error = ARC_NO_ERROR;

    /* Get next available handle */
    if ((harchive = GetNextHandle()) == VOID_H_ARCHIVE) {
        ArchiveLog(ARC_LOG_ERRORS, "ArchiveOpenForRead: No available handle");
        return (VOID_H_ARCHIVE);
    }

    _archive[harchive].last_error = ARC_NO_ERROR;

    /* Check out the path */
    if (!ValidatePath(path, harchive)) {
        ArchiveLog(ARC_LOG_ERRORS, "ArchiveOpenForRead: Invalid path: %s", path);
        return (VOID_H_ARCHIVE);
    }

    /* Create stream list */
    if (!CreateList(&_archive[harchive].streams)) {
        _archive_error = ARC_NO_MEMORY;
        ArchiveLog(ARC_LOG_ERRORS, "ArchiveOpenForRead: out of memory");
        return (VOID_H_ARCHIVE);
    }

    /* Get state and open for read access */
    if (!OpenStateForRead(harchive)) {
        _archive_error = _archive[harchive].last_error;
        ArchiveLog(ARC_LOG_ERRORS, "ArchiveOpenForRead: cannot get archive state");
        return (VOID_H_ARCHIVE);
    }

    _n_archives++;

    return (harchive);
}
Пример #13
0
CStdString SystemFolderInfo::GetProfilePath()
{
	CStdString sPath;

	switch (GetWindowsVersion())
	{
	case WINDOWS_95:
	case WINDOWS_ME:
	case WINDOWS_98:
		{
			if (HasWin98UserGotProfile())
			{
				sPath = GetProfilesRoot() + _T("\\") + GetLoggedOnUser();
			}
			else
			{
				sPath = GetProfilesRoot() + _T("\\All Users");
			}
		}
		break;

	case WINDOWS_NT:
		sPath = GetProfilesRoot() + _T("\\") + GetLoggedOnUser();
		break;

	case WINDOWS_2K:
	case WINDOWS_XP:
	case WINDOWS_2003SERVER:
	default:
		sPath = GetFolderPath(CSIDL_PROFILE, NULL);
		break;

	}

	ValidatePath(sPath, CSIDL_PROFILE);
	return sPath;
}
Пример #14
0
//	-----------------------------------------------------------------------------------------------------------
//	Create a path from objP->info.position.vPos to the center of nEndSeg.
//	Return a list of (segment_num, point_locations) at pointSegP
//	Return number of points in *numPoints.
//	if nMaxDepth == -1, then there is no maximum depth.
//	If unable to create path, return -1, else return 0.
//	If randomFlag !0, then introduce randomness into path by looking at sides in random order.  This means
//	that a path between two segments won't always be the same, unless it is unique.p.
//	If bSafeMode is set, then additional points are added to "make sure" that points are reachable.p.  I would
//	like to say that it ensures that the CObject can move between the points, but that would require knowing what
//	the CObject is (which isn't passed, right?) and making fvi calls (slow, right?).  So, consider it the more_or_less_safeFlag.
//	If nEndSeg == -2, then end seg will never be found and this routine will drop out due to depth (xProbably called by CreateNSegmentPath).
int CreatePathPoints (CObject *objP, int nStartSeg, int nEndSeg, tPointSeg *pointSegP, short *numPoints,
							 int nMaxDepth, int bRandom, int bSafeMode, int nAvoidSeg)
{
	short				nCurSeg;
	short				nSide, hSide;
	int				qTail = 0, qHead = 0;
	int				h, i, j;
	sbyte				bVisited [MAX_SEGMENTS_D2X];
	segQueueEntry	segmentQ [MAX_SEGMENTS_D2X];
	short				depth [MAX_SEGMENTS_D2X];
	int				nCurDepth;
	sbyte				randomXlate [MAX_SIDES_PER_SEGMENT];
	tPointSeg		*origPointSegs = pointSegP;
	int				lNumPoints;
	CSegment			*segP;
	CFixVector		vCenter;
	int				nParentSeg, nDestSeg;
	tFVIQuery		fq;
	tFVIData			hitData;
	int				hitType;
	int				bAvoidPlayer;

#if PATH_VALIDATION
ValidateAllPaths ();
#endif

if ((objP->info.nType == OBJ_ROBOT) && (objP->cType.aiInfo.behavior == AIB_RUN_FROM) && (nAvoidSeg != -32767)) {
	bRandom = 1;
	nAvoidSeg = gameData.objs.consoleP->info.nSegment;
	}
bAvoidPlayer = gameData.objs.consoleP->info.nSegment == nAvoidSeg;
if (nMaxDepth == -1)
	nMaxDepth = MAX_PATH_LENGTH;
lNumPoints = 0;
memset (bVisited, 0, sizeof (bVisited [0]) * gameData.segs.nSegments);
memset (depth, 0, sizeof (depth [0]) * gameData.segs.nSegments);
//	If there is a CSegment we're not allowed to visit, mark it.
if (nAvoidSeg != -1) {
	Assert (nAvoidSeg <= gameData.segs.nLastSegment);
	if ((nStartSeg != nAvoidSeg) && (nEndSeg != nAvoidSeg)) {
		bVisited [nAvoidSeg] = 1;
		depth [nAvoidSeg] = 0;
		}
	}

nCurSeg = nStartSeg;
bVisited [nCurSeg] = 1;
nCurDepth = 0;

#if DBG
if (objP->Index () == nDbgObj)
	nDbgObj = nDbgObj;
#endif
if (bRandom)
	CreateRandomXlate (randomXlate);
nCurSeg = nStartSeg;
bVisited [nCurSeg] = 1;
while (nCurSeg != nEndSeg) {
	segP = SEGMENTS + nCurSeg;
	if (bRandom && (d_rand () < 8192))	//create a different xlate at random time intervals
		CreateRandomXlate (randomXlate);

	for (nSide = 0; nSide < MAX_SIDES_PER_SEGMENT; nSide++) {
		hSide = bRandom ? randomXlate [nSide] : nSide;
		if (!IS_CHILD (segP->m_children [hSide]))
			continue;
		if (!((segP->IsDoorWay (hSide, NULL) & WID_FLY_FLAG) ||
			  (AIDoorIsOpenable (objP, segP, hSide))))
			continue;
		nDestSeg = segP->m_children [hSide];
		if (bVisited [nDestSeg])
			continue;
		if (bAvoidPlayer && ((nCurSeg == nAvoidSeg) || (nDestSeg == nAvoidSeg))) {
			vCenter = segP->SideCenter (hSide);
			fq.p0					= &objP->info.position.vPos;
			fq.startSeg			= objP->info.nSegment;
			fq.p1					= &vCenter;
			fq.radP0				=
			fq.radP1				= objP->info.xSize;
			fq.thisObjNum		= objP->Index ();
			fq.ignoreObjList	= NULL;
			fq.flags				= 0;
			fq.bCheckVisibility = false;
			hitType = FindVectorIntersection (&fq, &hitData);
			if (hitType != HIT_NONE)
				continue;
			}
		if (nDestSeg < 0)
			continue;
		if (nCurSeg < 0)
			continue;
		segmentQ [qTail].start = nCurSeg;
		segmentQ [qTail].end = nDestSeg;
		segmentQ [qTail].nConnSide = (ubyte) hSide;
		bVisited [nDestSeg] = 1;
		depth [qTail++] = nCurDepth + 1;
		if (depth [qTail-1] == nMaxDepth) {
			nEndSeg = segmentQ [qTail-1].end;
			goto pathTooLong;
			}	// end if (depth [...
		}	//	for (nSide.p...

	if (qHead >= qTail) {
		//	Couldn't get to goal, return a path as far as we got, which is probably acceptable to the unparticular caller.
		nEndSeg = segmentQ [qTail-1].end;
		break;
		}
	nCurSeg = segmentQ [qHead].end;
	nCurDepth = depth [qHead];
	qHead++;

pathTooLong: ;
	}	//	while (nCurSeg ...
//	Set qTail to the CSegment which ends at the goal.
while (segmentQ [--qTail].end != nEndSeg)
	if (qTail < 0) {
		*numPoints = lNumPoints;
		return -1;
		}
for (i = qTail; i >= 0; ) {
	nParentSeg = segmentQ [i].start;
	lNumPoints++;
	if (nParentSeg == nStartSeg)
		break;
	while (segmentQ [--i].end != nParentSeg)
		Assert (i >= 0);
	}

if (bSafeMode && ((pointSegP - gameData.ai.routeSegs) + 2 * lNumPoints + 1 >= LEVEL_POINT_SEGS)) {
	//	Ouch! Cannot insert center points in path.  So return unsafe path.
#if TRACE
	console.printf (CON_DBG, "Resetting all paths because of bSafeMode.p.\n");
#endif
	AIResetAllPaths ();
	*numPoints = lNumPoints;
	return -1;
	}
pointSegP->nSegment = nStartSeg;
pointSegP->point = SEGMENTS [nStartSeg].Center ();
if (bSafeMode)
	lNumPoints *= 2;
j = lNumPoints++;
h = bSafeMode + 1;
for (i = qTail; i >= 0; j -= h) {
	nDestSeg = segmentQ [i].end;
	nParentSeg = segmentQ [i].start;
	pointSegP [j].nSegment = nDestSeg;
	pointSegP [j].point = SEGMENTS [nDestSeg].Center ();
	pointSegP [j].nConnSide = segmentQ [i].nConnSide;
	if (nParentSeg == nStartSeg)
		break;
	while (segmentQ [--i].end != nParentSeg)
		Assert (qTail >= 0);
	}
if (bSafeMode) {
	for (i = 0; i < lNumPoints - 1; i = j) {
		j = i + 2;
		InsertTransitPoint (pointSegP + i + 1, pointSegP + i, pointSegP + j, pointSegP [j].nConnSide);
		}
	lNumPoints = OptimizePath (pointSegP, lNumPoints);
	}
pointSegP += lNumPoints;

#if PATH_VALIDATION
ValidatePath (2, origPointSegs, lNumPoints);
#endif

#if PATH_VALIDATION
ValidatePath (3, origPointSegs, lNumPoints);
#endif

// -- MK, 10/30/95 -- This code causes apparent discontinuities in the path, moving a point
//	into a new CSegment.  It is not necessarily bad, but it makes it hard to track down actual
//	discontinuity xProblems.
if ((objP->info.nType == OBJ_ROBOT) && ROBOTINFO (objP->info.nId).companion)
	MoveTowardsOutside (origPointSegs, &lNumPoints, objP, 0);

#if PATH_VALIDATION
ValidatePath (4, origPointSegs, lNumPoints);
#endif

*numPoints = lNumPoints;
return 0;
}