diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2022-02-06 16:04:38 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2022-02-06 16:04:38 +0100 | 
| commit | d0ca838c7ab297036b4a7c45351761a48fe05efd (patch) | |
| tree | f0f3cc006e8157d6bd699bd644b7dd7b35387ac2 /app/bin/cturnout.c | |
| parent | fd6639655b399a79fb72f494786a4f57da9c90e7 (diff) | |
| parent | 5d2c2b27a6323e2666378b986129b2a7c2c39e5c (diff) | |
Update upstream source from tag 'upstream/5.2.2GA'
Update to upstream version '5.2.2GA'
with Debian dir 9c80045d0b4f9e463647bc8af8c090a673df4132
Diffstat (limited to 'app/bin/cturnout.c')
| -rw-r--r-- | app/bin/cturnout.c | 4890 | 
1 files changed, 3397 insertions, 1493 deletions
| diff --git a/app/bin/cturnout.c b/app/bin/cturnout.c index 150f381..02eadef 100644 --- a/app/bin/cturnout.c +++ b/app/bin/cturnout.c @@ -1,30 +1,26 @@  /** \file cturnout.c - * T_TURNOUT + * Turnout object handling and drawing   */ -/*  XTrkCad - Model Railroad CAD - *  Copyright (C) 2005 Dave Bullis - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <ctype.h> -#include <math.h> -#include <stdint.h> -#include <string.h> - + /*  XTrkCad - Model Railroad CAD +  *  Copyright (C) 2005 Dave Bullis +  * +  *  This program is free software; you can redistribute it and/or modify +  *  it under the terms of the GNU General Public License as published by +  *  the Free Software Foundation; either version 2 of the License, or +  *  (at your option) any later version. +  * +  *  This program is distributed in the hope that it will be useful, +  *  but WITHOUT ANY WARRANTY; without even the implied warranty of +  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +  *  GNU General Public License for more details. +  * +  *  You should have received a copy of the GNU General Public License +  *  along with this program; if not, write to the Free Software +  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +  */ + +#include "common.h"  #include "ccurve.h"  #include "tbezier.h"  #include "tcornu.h" @@ -34,14 +30,13 @@  #include "cundo.h"  #include "custom.h"  #include "fileio.h" -#include "i18n.h"  #include "layout.h" -#include "messages.h"  #include "param.h" +#include "cselect.h"  #include "include/paramfile.h"  #include "track.h"  #include "trackx.h" -#include "utility.h" +#include "common-ui.h"  EXPORT TRKTYP_T T_TURNOUT = -1; @@ -51,13 +46,17 @@ EXPORT TRKTYP_T T_TURNOUT = -1;  EXPORT dynArr_t turnoutInfo_da; -EXPORT turnoutInfo_t * curTurnout = NULL; +EXPORT turnoutInfo_t* curTurnout = NULL;  EXPORT long curTurnoutEp = 0;  static int curTurnoutInx = -1; +/** @logcmd @showrefby turnout=n cturnout.c */  static int log_turnout = 0; +/** @logcmd @showrefby traverseTurnout=n cturnout.c */  static int log_traverseTurnout = 0; +/** @logcmd @showrefby suppresscheckpaths=n cturnout.c */  static int log_suppressCheckPaths = 0; +/** @logcmd @showrefby splitturnout=n cturnout.c */  static int log_splitturnout = 0;  static wMenu_p turnoutPopupM; @@ -75,33 +74,99 @@ static drawCmd_t turnoutD = {  static wIndex_t turnoutHotBarCmdInx;  static wIndex_t turnoutInx;  static long hideTurnoutWindow; -static void RedrawTurnout(void); -static void SelTurnoutEndPt( wIndex_t, coOrd ); -static void HilightEndPt( void ); +static void RedrawTurnout( wDraw_p d, void * context, wWinPix_t x, wWinPix_t y ); +static void SelTurnoutEndPt(wIndex_t, coOrd); +static void HilightEndPt(void); -static wPos_t turnoutListWidths[] = { 80, 80, 220 }; -static const char * turnoutListTitles[] = { N_("Manufacturer"), N_("Part No"), N_("Description") }; +static wWinPix_t turnoutListWidths[] = { 80, 80, 220 }; +static const char* turnoutListTitles[] = { N_("Manufacturer"), N_("Part No"), N_("Description") };  static paramListData_t listData = { 13, 400, 3, turnoutListWidths, turnoutListTitles }; -static const char * hideLabels[] = { N_("Hide"), NULL }; -static paramDrawData_t turnoutDrawData = { 490, 200, (wDrawRedrawCallBack_p)RedrawTurnout, SelTurnoutEndPt, &turnoutD }; +static const char* hideLabels[] = { N_("Hide"), NULL }; +static paramDrawData_t turnoutDrawData = { 490, 200, RedrawTurnout, SelTurnoutEndPt, &turnoutD };  static paramData_t turnoutPLs[] = {  #define I_LIST		(0)  #define turnoutListL    ((wList_p)turnoutPLs[I_LIST].control) -	{   PD_LIST, &turnoutInx, "list", PDO_NOPREF|PDO_DLGRESIZEW, &listData, NULL, BL_DUP }, +	{   PD_LIST, &turnoutInx, "list", PDO_NOPREF | PDO_DLGRESIZEW, &listData, NULL, BL_DUP },  #define I_DRAW		(1)  #define turnoutDrawD    ((wDraw_p)turnoutPLs[I_DRAW].control) -	{   PD_DRAW, NULL, "canvas", PDO_NOPSHUPD|PDO_DLGUNDERCMDBUTT|PDO_DLGRESIZE, &turnoutDrawData, NULL, 0 }, +	{   PD_DRAW, NULL, "canvas", PDO_NOPSHUPD | PDO_DLGUNDERCMDBUTT | PDO_DLGRESIZE, &turnoutDrawData, NULL, 0 },  #define I_NEW		(2)  #define turnoutNewM     ((wMenu_p)turnoutPLs[I_NEW].control)  	{   PD_MENU, NULL, "new", PDO_DLGCMDBUTTON, NULL, N_("New") },  #define I_HIDE		(3)  #define turnoutHideT    ((wChoice_p)turnoutPLs[I_HIDE].control) -	{   PD_TOGGLE, &hideTurnoutWindow, "hide", PDO_DLGCMDBUTTON, /*CAST_AWAY_CONST*/(void*)hideLabels, NULL, BC_NOBORDER } }; -static paramGroup_t turnoutPG = { "turnout", 0, turnoutPLs, sizeof turnoutPLs/sizeof turnoutPLs[0] }; +	{   PD_TOGGLE, &hideTurnoutWindow, "hide", PDO_DLGCMDBUTTON, hideLabels, NULL, BC_NOBORDER } }; +static paramGroup_t turnoutPG = { "turnout", 0, turnoutPLs, COUNT( turnoutPLs ) };  #endif +/* Draw turnout data */ + +/**  + * The types of turnouts that get enhanced drawing methods + */ +enum dtoType { +	DTO_INVALID, +	DTO_NORMAL, +	DTO_THREE, +	DTO_WYE, + +	DTO_CURVED, + +	DTO_XING, +	DTO_XNG9, +	DTO_SSLIP, +	DTO_DSLIP, + +	DTO_LCROSS, +	DTO_RCROSS, +	DTO_DCROSS +};  + +// Define to plot control points (DTO_NORMAL, DTO_CURVED, DTO_XING, DTO_LCROSS) +// #define DTO_DEBUG DTO_XING + +#define DTO_DIM 4  // Maximum number of paths +#define DTO_SEGS 24 // Maximum number of control points + +static struct DrawToData_t { +	TRKINX_T index; +	enum dtoType toType; +	track_p trk; +	int bridge;  +	int endCnt; +	int pathCnt; +	int routeCnt; +	int strCnt; +	int crvCnt; +	int rgtCnt; +	int lftCnt; +	int strPath; +	int str2Path; +	int crvPath; +	int crv2Path; +	int origCnt; +	int origins[DTO_DIM]; +	coOrd midPt; +	struct extraDataCompound_t* xx; +} dtod; + +struct DrawTo_t { +	int n; +	trkSeg_p trkSeg[DTO_SEGS]; +	coOrd base[DTO_SEGS]; +	coOrd baseLast; +	DIST_T dy[DTO_SEGS]; +	ANGLE_T angle; +	ANGLE_T crvAngle; +	coOrd pts[DTO_SEGS]; +	coOrd ptsLast; +	char type; +}; + +static struct DrawTo_t dto[DTO_DIM]; + + -  /****************************************   *   * TURNOUT LIST MANAGEMENT @@ -109,47 +174,49 @@ static paramGroup_t turnoutPG = { "turnout", 0, turnoutPLs, sizeof turnoutPLs/si   */ -EXPORT turnoutInfo_t * CreateNewTurnout( -		char * scale, -		char * title, -		wIndex_t segCnt, -		trkSeg_p segData, -		wIndex_t pathLen, -		PATHPTR_T paths, -		EPINX_T endPtCnt, -		trkEndPt_t * endPts, -		DIST_T * radii, -		wBool_t updateList ) +EXPORT turnoutInfo_t* CreateNewTurnout( +	char* scale, +	char* title, +	wIndex_t segCnt, +	trkSeg_p segData, +	PATHPTR_T paths, +	EPINX_T endPtCnt, +	trkEndPt_t* endPts, +	wBool_t updateList, +	long options)  { -	turnoutInfo_t * to; -	long changes=0; +	turnoutInfo_t* to; +	long changes = 0; -	to = FindCompound( FIND_TURNOUT, scale, title ); +	to = FindCompound(FIND_TURNOUT, scale, title);  	if (to == NULL) { -		DYNARR_APPEND( turnoutInfo_t *, turnoutInfo_da, 10 ); -		to = (turnoutInfo_t*)MyMalloc( sizeof *to ); -		turnoutInfo(turnoutInfo_da.cnt-1) = to; -		to->title = MyStrdup( title ); -		to->scaleInx = LookupScale( scale ); +		DYNARR_APPEND(turnoutInfo_t*, turnoutInfo_da, 10); +		to = (turnoutInfo_t*)MyMalloc(sizeof * to); +		turnoutInfo(turnoutInfo_da.cnt - 1) = to; +		to->title = MyStrdup(title); +		to->scaleInx = LookupScale(scale);  		changes = CHANGE_PARAMS;  	}  	to->segCnt = segCnt;  	trkSeg_p seg_p; -	to->segs = (trkSeg_p)memdup( segData, (sizeof (*segData) * segCnt )); +	to->segs = (trkSeg_p)memdup(segData, (sizeof(*segData) * segCnt));  	seg_p = to->segs; -	for (int i=0;i<segCnt;i++) { +	for (int i = 0; i < segCnt; i++) {  		seg_p[i].bezSegs.ptr = NULL;  		seg_p[i].bezSegs.cnt = 0;  		seg_p[i].bezSegs.max = 0;  	} -	CopyPoly(to->segs,segCnt); -	FixUpBezierSegs(to->segs,to->segCnt); -	GetSegBounds( zero, 0.0, segCnt, to->segs, &to->orig, &to->size ); +	CopyPoly(to->segs, segCnt); +	FixUpBezierSegs(to->segs, to->segCnt); +	GetSegBounds(zero, 0.0, segCnt, to->segs, &to->orig, &to->size);  	to->endCnt = endPtCnt; -	to->endPt = (trkEndPt_t*)memdup( endPts, (sizeof *endPts) * to->endCnt ); +	to->endPt = (trkEndPt_t*)memdup(endPts, (sizeof * endPts) * to->endCnt); -	to->pathLen = pathLen; -	to->paths = (PATHPTR_T)memdup( paths, (sizeof *to->paths) * to->pathLen ); +	if (options & COMPOUND_OPTION_PATH_OVERRIDE) +		to->pathOverRide = TRUE; +	if (options & COMPOUND_OPTION_PATH_NOCOMBINE) +		to->pathNoCombine = TRUE; +	SetParamPaths( to, paths );  	to->paramFileIndex = curParamFileIndex;  	if (curParamFileIndex == PARAM_CUSTOM)  		to->contentsLabel = MyStrdup("Custom Turnouts"); @@ -157,42 +224,40 @@ EXPORT turnoutInfo_t * CreateNewTurnout(  		to->contentsLabel = curSubContents;  #ifdef TURNOUTCMD  	if (updateList && turnoutListL != NULL) { -		FormatCompoundTitle( LABEL_TABBED|LABEL_MANUF|LABEL_PARTNO|LABEL_DESCR, title ); +		FormatCompoundTitle(LABEL_TABBED | LABEL_MANUF | LABEL_PARTNO | LABEL_DESCR, title);  		if (message[0] != '\0') -			wListAddValue( turnoutListL, message, NULL, to ); +			wListAddValue(turnoutListL, message, NULL, to);  	}  #endif -	to->barScale = curBarScale>0?curBarScale:-1; +	to->barScale = curBarScale > 0 ? curBarScale : -1;  	to->special = TOnormal; -	if (radii) { -		to->special = TOcurved; -		DYNARR_SET(DIST_T,to->u.curved.radii,to->endCnt); -		for (int i=0;i<to->endCnt;i++) { -			DYNARR_N(DIST_T,to->u.curved.radii,i) = radii[i]; -		} -	}  	if (updateList && changes) -		DoChangeNotification( changes ); +		DoChangeNotification(changes);  	return to;  }  /**   * Delete a turnout parameter from the list and free the related memory   * - * \param [IN] to turnout definition to be deleted  + * \param [IN] toInfo turnout definition to be deleted + * + * \returns True if it succeeds   */  BOOL_T -DeleteTurnout(void *toInfo) +DeleteTurnout(void* toInfo)  { -	turnoutInfo_t * to = (turnoutInfo_t *)toInfo; +	turnoutInfo_t* to = (turnoutInfo_t*)toInfo;  	MyFree(to->title);  	MyFree(to->segs);  	MyFree(to->endPt);  	MyFree(to->paths);  	if (to->special) { -		DYNARR_FREE(DIST_T, to->u.curved.radii); +		switch (to->special) { +		case TOadjustable: +		default:; +		}  	}  	MyFree(to); @@ -200,62 +265,62 @@ DeleteTurnout(void *toInfo)  }  /** - * Delete all turnout definitions that came from a specific parameter file.  - * Due to the way the definitions are loaded from file it is safe to  + * Delete all turnout definitions that came from a specific parameter file. + * Due to the way the definitions are loaded from file it is safe to   * assume that they form a contiguous block in the array. - *  + *   * \param [IN] fileIndex parameter file   */  void  DeleteTurnoutParams(int fileIndex)  { -    int inx=0; -    int startInx = -1; -    int cnt = 0; - -    // go to the start of the block -    while (inx < turnoutInfo_da.cnt && -            turnoutInfo(inx)->paramFileIndex != fileIndex) { -        startInx = inx++; -    } +	int inx = 0; +	int startInx = -1; +	int cnt = 0; + +	// go to the start of the block +	while (inx < turnoutInfo_da.cnt && +		turnoutInfo(inx)->paramFileIndex != fileIndex) { +		startInx = inx++; +	} -    // delete them -    for (; inx < turnoutInfo_da.cnt && -            turnoutInfo(inx)->paramFileIndex == fileIndex; inx++) { -        turnoutInfo_t * to = turnoutInfo(inx); -        if (to->paramFileIndex == fileIndex) { -            DeleteTurnout(to); -            cnt++; -        } -    } +	// delete them +	for (; inx < turnoutInfo_da.cnt && +		turnoutInfo(inx)->paramFileIndex == fileIndex; inx++) { +		turnoutInfo_t* to = turnoutInfo(inx); +		if (to->paramFileIndex == fileIndex) { +			DeleteTurnout(to); +			cnt++; +		} +	} -    // copy down the rest of the list to fill the gap -    startInx++; -    while (inx < turnoutInfo_da.cnt) { -        turnoutInfo(startInx++) = turnoutInfo(inx++); -    } +	// copy down the rest of the list to fill the gap +	startInx++; +	while (inx < turnoutInfo_da.cnt) { +		turnoutInfo(startInx++) = turnoutInfo(inx++); +	} -    // and reduce the actual number -    turnoutInfo_da.cnt -= cnt; +	// and reduce the actual number +	turnoutInfo_da.cnt -= cnt;  } -/**  - * Check to find out to what extent the contents of the parameter file can be used with  - * the current layout scale / gauge.  - *  +/** + * Check to find out to what extent the contents of the parameter file can be used with + * the current layout scale / gauge. + *   * If parameter scale == layout and parameter gauge == layout we have an exact fit. - * If parameter gauge == layout we have compatible track.  - * OO scale is special cased. If the layout is in OO scale track in HO is considered  + * If parameter gauge == layout we have compatible track. + * OO, O and N scales are special cased. If the layout is in OO scale track in HO is considered   * an exact fit in spite of scale differences. - *  + *   * \param paramFileIndex   * \param scaleIndex - * \return  + * \return enum paraFileState   */ -enum paramFileState  -GetTrackCompatibility(int paramFileIndex, SCALEINX_T scaleIndex) +enum paramFileState +	GetTrackCompatibility(int paramFileIndex, SCALEINX_T scaleIndex)  {  	int i;  	enum paramFileState ret = PARAMFILE_NOTUSABLE; @@ -267,224 +332,182 @@ GetTrackCompatibility(int paramFileIndex, SCALEINX_T scaleIndex)  	// loop over all parameter entries or until a exact fit is found  	for (i = 0; i < turnoutInfo_da.cnt && ret < PARAMFILE_FIT; i++) { -		turnoutInfo_t *to = turnoutInfo( i ); -		if (to->paramFileIndex == paramFileIndex ) { -			if (to->scaleInx == scaleIndex ) { +		turnoutInfo_t* to = turnoutInfo(i); +		if (to->paramFileIndex == paramFileIndex) { +			SCALE_FIT_T fit = CompatibleScale(FIT_TURNOUT, to->scaleInx, scaleIndex); +			if (fit == FIT_EXACT) {  				ret = PARAMFILE_FIT;  				break; -			} else { -				if (GetScaleTrackGauge(to->scaleInx) == gauge && -					ret < PARAMFILE_COMPATIBLE) { -					ret = PARAMFILE_COMPATIBLE; -					// handle special cases -					// if layout is OO scale, HO scale track is considered exact -					char *layoutScaleName = GetScaleName(scaleIndex); -					char *paramScaleName = GetScaleName(to->scaleInx); -					if (!strcmp(layoutScaleName, "OO") && -						!strcmp(paramScaleName, "HO")) { -						ret = PARAMFILE_FIT; -					} -					//if layout is in Japanese or British N scale, N scale is exact -					if ((!strcmp(layoutScaleName, "N(UK)") || -						!strcmp(layoutScaleName, "N(JP)")) && -						!strcmp(paramScaleName, "N")) { -						ret = PARAMFILE_FIT; -					} -				} +			} +			else if (fit == FIT_COMPATIBLE) { +				ret = PARAMFILE_COMPATIBLE;  			}  		}  	}  	return(ret);  } - +/** + * Check Paths verifies that each track segment is on at least one path. + * It will assume new-P or old-P order is possible and does not change it. + * + * \param segCnt + * \param segs + * \param paths + * + * \returns -1 if a track segment is not on a path + */  EXPORT wIndex_t CheckPaths( -		wIndex_t segCnt, -		trkSeg_p segs, -		PATHPTR_T paths ) +	wIndex_t segCnt, +	trkSeg_p segs, +	PATHPTR_T paths)  {  	if ((segCnt == 0) || !segs) return -1; +	if (!paths) return -1;  	int pc, ps;  	PATHPTR_T pp = 0; -	int inx; -	static dynArr_t segMap_da; +  	int segInx[2], segEp[2];  	int segTrkLast = -1; -	 +  	// Check that each track segment is on at least one path +	// Note - In new-P the tracks may be preceded by draws (or interspersed by them)  	int suppressCheckPaths = log_suppressCheckPaths > 0 ? logTable(log_suppressCheckPaths).level : 0; -	if ( suppressCheckPaths == 0 ) { -		char trkSegInx = 0; -		for ( int inx = 0; inx<segCnt; inx++ ) { -			if ( IsSegTrack( &segs[inx] ) ) { -				trkSegInx++; +	if (suppressCheckPaths == 0) { +		for (int inx = 0; inx < segCnt; inx++) { +			if (IsSegTrack(&segs[inx])) {  				PATHPTR_T cp = paths; -				while ( *cp ) { -					// path is: 'N' 'A' 'M' 'E' 0 1 2 0 3 4 0 0 -					// skip name -					for ( ; *cp; cp++ ); -					cp++; +				while (*cp) { +					// 0-9 are x00 to x09 or the negative equivalent (backwards) +					// Pathlist is: Path00Path000 +					// Path is: NAME01203400 +					for (; *cp; cp++);  //Skip Name +					cp++; //Skip 0 after name  					// check each path component  -					for ( ; cp[0] || cp[1];  cp++ ) -						if ( abs(*cp) == trkSegInx ) -							 break; -					if ( *cp )	// we broke early -						break; -					cp += 2;; // Skip 2nd 0 +					for (; cp[0] || cp[1]; cp++) {  //keeps going even if there are two or more parts +						if (!cp[0]) continue;   //ignore the 0 between parts of the same PATH!! +						GetSegInxEP(cp[0], &segInx[0], &segEp[0]); //GetSegInxEP subtracts one to match inx +						if (segInx[0] == inx) break;  //Found it! +					} +					if (*cp)	// we broke early +						break;  // get out - we found it +					cp++; +					cp++;  // Go to next path - past two 0s  				} -				if ( !*cp ) {	// we looked and didn't find -					InputError( "Track segment %d not on Path",  FALSE, inx+1 ); +				if (!*cp) {	// we looked through all the paths and didn't find it +					InputError("Track segment %d not on Path", FALSE, inx + 1);  					return -1;;  				}  			}  		}  	} -typedef struct { -	trkSeg_p seg; -	int indx; -} segMap_t, * segMap_p; - -#define segMap(N) DYNARR_N( segMap_t, segMap_da, N ) -	segMap_p sg; -	DYNARR_RESET( segMap_t, segMap_da ); -	// Don't reshuffle segs, but build an offset map instead just of the tracks -	// Use the map to set up the paths to point at the correct segs in the Turnout -	for ( inx=0; inx<segCnt; inx++ ) { -		if ( IsSegTrack(&segs[inx]) ) { -			DYNARR_APPEND( segMap_t, segMap_da, 10 ); -			sg = &DYNARR_LAST(segMap_t,segMap_da); -			sg->seg = &segs[inx]; -			sg->indx = inx; -		} -	} - -	for ( pc=0,pp=paths; *pp; pp+=2,pc++ ) { -		for ( ps=0,pp+=strlen((char *)pp)+1; pp[0]!=0 || pp[1]!=0; pp++,ps++ ) { -#ifdef LATER -			if (*pp >= '0' && *pp <= '9') -				*pp -= '0'; -			else if (*pp >= 'A' && *pp <= 'Z') -				*pp -= 'A' - 10; -			if (*pp < 0 || *pp > segCnt) { -				InputError( _("Turnout path[%d:%d] out of bounds: %d"), -						FALSE, pc, ps, *pp); -				return -1; +	for (pc = 0, pp = paths; *pp; pp += 2, pc++) { +		for (ps = 0, pp += strlen((char*)pp) + 1; pp[0] != 0 || pp[1] != 0; pp++, ps++) { +			if (pp[0] != 0 && ps == 0) {  // First or only one  			} -#endif -			//Rewrite the Path to point to the nth Track seg using the Map -			int old_inx; -			EPINX_T old_EP; -			if (pp[0]!=0 && ps==0) {  // First or only one -				GetSegInxEP( pp[0], &old_inx, &old_EP ); -				if (old_inx<0 || old_inx>= segMap_da.cnt) { -					InputError( _("Turnout path[%d] %d is not a valid track segment"), -						FALSE, pc, ps ); -					return -1; -				} -				SetSegInxEP( &pp[0], DYNARR_N(segMap_t,segMap_da,old_inx).indx, old_EP); -			} -			if (pp[0]!=0 && pp[1]!=0 ) { -				//Rewrite the Path to point to the nth Track seg using the Map -				GetSegInxEP( pp[1], &old_inx, &old_EP ); -				if (old_inx<0 || old_inx>= segMap_da.cnt) { -					InputError( _("Turnout path[%d] %d is not a valid track segment"), -						FALSE, pc, ps ); -					return -1; -				} -				SetSegInxEP( &pp[1], DYNARR_N(segMap_t,segMap_da,old_inx).indx, old_EP); +			if (pp[0] != 0 && pp[1] != 0) {  				/* check connectivity */  				DIST_T d; -				GetSegInxEP( pp[0], &segInx[0], &segEp[0] ); -				GetSegInxEP( pp[1], &segInx[1], &segEp[1] ); -				if ( !IsSegTrack( &segs[segInx[0]] ) ) { -					InputError( _("Turnout path[%d] %d is not a track segment"), -						FALSE, pc, pp[0] ); +				GetSegInxEP(pp[0], &segInx[0], &segEp[0]); +				GetSegInxEP(pp[1], &segInx[1], &segEp[1]); +				if (!IsSegTrack(&segs[segInx[0]])) { +					InputError(_("CheckPath: Turnout path[%d] %d is not a track segment"), +						FALSE, pc, pp[0]);  					return -1;  				} -				if ( !IsSegTrack( &segs[segInx[1]] ) ) { -					InputError( _("Turnout path[%d] %d is not a track segment"), -						FALSE, pc, pp[1] ); +				if (!IsSegTrack(&segs[segInx[1]])) { +					InputError(_("CheckPath: Turnout path[%d] %d is not a track segment"), +						FALSE, pc, pp[1]);  					return -1;  				} -				coOrd p0 = GetSegEndPt( &segs[segInx[0]], 1-segEp[0], FALSE, NULL ); -				coOrd p1 = GetSegEndPt( &segs[segInx[1]], segEp[1], FALSE, NULL ); -				d = FindDistance(p0,p1); +				coOrd p0 = GetSegEndPt(&segs[segInx[0]], 1 - segEp[0], FALSE, NULL); +				coOrd p1 = GetSegEndPt(&segs[segInx[1]], segEp[1], FALSE, NULL); +				d = FindDistance(p0, p1);  				if (d > MIN_TURNOUT_SEG_CONNECT_DIST) { -					InputError( _("Turnout path[%d] %d-%d not connected: %0.3f P0(%f,%f) P1(%f,%f)"), -						FALSE, pc, pp[0], pp[1], d, p0.x, p0.y, p1.x, p1.y ); +					InputError(_("CheckPath: Turnout path[%d] %d-%d not connected: %0.3f P0(%f,%f) P1(%f,%f)"), +						FALSE, pc, pp[0], pp[1], d, p0.x, p0.y, p1.x, p1.y);  					return -1;  				}  			}  		}  	} -	return pp-paths+1; +	return (wIndex_t)(pp - paths + 1);  }  static BOOL_T ReadTurnoutParam( -		char * firstLine ) +	char* firstLine)  {  	char scale[10]; -	char *title; -	turnoutInfo_t * to; +	char* title; +	turnoutInfo_t* to; +	PATHPTR_T cp; +	long options = 0; -	if ( !GetArgs( firstLine+8, "sq", scale, &title ) ) +	if (!GetArgs(firstLine + 8, "sqc", scale, &title, &cp))  		return FALSE; -	DYNARR_RESET( trkEndPt_t, tempEndPts_da ); +	if (cp != NULL) +		if (!GetArgs((char*)cp, "l", &options)) +			return FALSE; +	DYNARR_RESET(trkEndPt_t, tempEndPts_da);  	pathCnt = 0; -	if ( !ReadSegs() ) +	if (!ReadSegs())  		return FALSE; -	CheckPaths( tempSegs_da.cnt, &tempSegs(0), pathPtr ); -	to = CreateNewTurnout( scale, title, tempSegs_da.cnt, &tempSegs(0), -					pathCnt, pathPtr, tempEndPts_da.cnt, &tempEndPts(0), NULL, FALSE ); -	MyFree( title ); +	PATHPTR_T pPaths = NULL; +	if ( pathPtr && pathPtr[0] && pathCnt > 0 ) +		pPaths = pathPtr; +	CheckPaths( tempSegs_da.cnt, &tempSegs(0), pPaths ); +	to = CreateNewTurnout(scale, title, tempSegs_da.cnt, &tempSegs(0), +			pPaths, tempEndPts_da.cnt, &tempEndPts(0), FALSE, options ); +	MyFree(title);  	if (to == NULL)  		return FALSE;  	if (tempSpecial[0] != '\0') { -		if (strncmp( tempSpecial, ADJUSTABLE, strlen(ADJUSTABLE) ) == 0) { +		if (strncmp(tempSpecial, ADJUSTABLE, strlen(ADJUSTABLE)) == 0) {  			to->special = TOadjustable; -			if ( !GetArgs( tempSpecial+strlen(ADJUSTABLE), "ff", -					&to->u.adjustable.minD, &to->u.adjustable.maxD ) ) +			if (!GetArgs(tempSpecial + strlen(ADJUSTABLE), "ff", +				&to->u.adjustable.minD, &to->u.adjustable.maxD))  				return FALSE; -		} else { +		} +		else {  			InputError(_("Unknown special case"), TRUE);  			return FALSE;  		}  	}  	if (tempCustom[0] != '\0') { -		to->customInfo = MyStrdup( tempCustom ); +		to->customInfo = MyStrdup(tempCustom);  	}  	return TRUE;  } -EXPORT turnoutInfo_t * TurnoutAdd( long mode, SCALEINX_T scale, wList_p list, coOrd * maxDim, EPINX_T epCnt ) +EXPORT turnoutInfo_t* TurnoutAdd(long mode, SCALEINX_T scale, wList_p list, coOrd* maxDim, EPINX_T epCnt)  {  	wIndex_t inx; -	turnoutInfo_t * to, * to1 = NULL; +	turnoutInfo_t* to, * to1 = NULL;  	turnoutInx = 0; -	for ( inx = 0; inx < turnoutInfo_da.cnt; inx++ ) { +	for (inx = 0; inx < turnoutInfo_da.cnt; inx++) {  		to = turnoutInfo(inx); -		if ( IsParamValid(to->paramFileIndex) && -			 to->segCnt > 0 && -			 CompatibleScale( TRUE, to->scaleInx, scale ) && -			 /*strcasecmp( to->scale, scaleName ) == 0 && */ -			 ( epCnt <= 0 || epCnt == to->endCnt ) ) { -			if (to1==NULL) +		if (IsParamValid(to->paramFileIndex) && +			to->segCnt > 0 && +			(FIT_NONE != CompatibleScale(FIT_TURNOUT, to->scaleInx, scale)) && +			/*strcasecmp( to->scale, scaleName ) == 0 && */ +			(epCnt <= 0 || epCnt == to->endCnt)) { +			if (to1 == NULL)  				to1 = to; -			if ( to == curTurnout ) { +			if (to == curTurnout) {  				to1 = to; -				turnoutInx = wListGetCount( list ); +				turnoutInx = wListGetCount(list);  			} -			FormatCompoundTitle( mode, to->title ); +			FormatCompoundTitle(mode, to->title);  			if (message[0] != '\0') { -				wListAddValue( list, message, NULL, to ); +				wListAddValue(list, message, NULL, to);  				if (maxDim) { -					if (to->size.x > maxDim->x)  +					if (to->size.x > maxDim->x)  						maxDim->x = to->size.x; -					if (to->size.y > maxDim->y)  +					if (to->size.y > maxDim->y)  						maxDim->y = to->size.y;  				}  			} @@ -492,7 +515,7 @@ EXPORT turnoutInfo_t * TurnoutAdd( long mode, SCALEINX_T scale, wList_p list, co  	}  	return to1;  } - +  /****************************************   *   * Adjustable Track Support @@ -501,20 +524,20 @@ EXPORT turnoutInfo_t * TurnoutAdd( long mode, SCALEINX_T scale, wList_p list, co  static void ChangeAdjustableEndPt( -		track_p trk, -		EPINX_T ep, -		DIST_T d ) +	track_p trk, +	EPINX_T ep, +	DIST_T d)  { -	struct extraData * xx = GetTrkExtraData(trk); +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	coOrd pos;  	trkSeg_p segPtr; -	ANGLE_T angle = GetTrkEndAngle( trk, ep ); -	Translate( &pos, GetTrkEndPos( trk, 1-ep ), angle, d ); +	ANGLE_T angle = GetTrkEndAngle(trk, ep); +	Translate(&pos, GetTrkEndPos(trk, 1 - ep), angle, d);  	UndoModify(trk); -	SetTrkEndPoint( trk, ep, pos, angle ); -	if ( ep == 0 ) +	SetTrkEndPoint(trk, ep, pos, angle); +	if (ep == 0)  		xx->orig = pos; -	for ( segPtr=xx->segs; segPtr<&xx->segs[xx->segCnt]; segPtr++ ) { +	for (segPtr = xx->segs; segPtr < &xx->segs[xx->segCnt]; segPtr++) {  		switch (segPtr->type) {  		case SEG_STRLIN:  		case SEG_STRTRK: @@ -524,19 +547,19 @@ static void ChangeAdjustableEndPt(  			;  		}  	} -	ComputeBoundingBox( trk ); -	DrawNewTrack( trk ); +	ComputeBoundingBox(trk); +	DrawNewTrack(trk);  }  EXPORT BOOL_T ConnectAdjustableTracks( -		track_p trk1, -		EPINX_T ep1, -		track_p trk2, -		EPINX_T ep2 ) +	track_p trk1, +	EPINX_T ep1, +	track_p trk2, +	EPINX_T ep2)  { -	struct extraData * xx1; -	struct extraData * xx2; +	struct extraDataCompound_t* xx1; +	struct extraDataCompound_t* xx2;  	BOOL_T adj1, adj2;  	coOrd p1, p2;  	ANGLE_T a, a1, a2; @@ -545,65 +568,74 @@ EXPORT BOOL_T ConnectAdjustableTracks(  	coOrd off;  	DIST_T beyond; -	xx1 = GetTrkExtraData(trk1); -	xx2 = GetTrkExtraData(trk2); +	if ((GetTrkType(trk1) != T_TURNOUT) && (GetTrkType(trk2) != T_TURNOUT)) return FALSE; +  	adj1 = adj2 = FALSE; -	if (GetTrkType(trk1) == T_TURNOUT && xx1->special == TOadjustable) -		adj1 = TRUE; -	if (GetTrkType(trk2) == T_TURNOUT && xx2->special == TOadjustable) -		adj2 = TRUE; + +	if (GetTrkType(trk1) == T_TURNOUT) { +		xx1 = GET_EXTRA_DATA(trk1, T_TURNOUT, extraDataCompound_t); +		if (xx1->special == TOadjustable) +			adj1 = TRUE; +	} +	if (GetTrkType(trk2) == T_TURNOUT) { +		xx2 = GET_EXTRA_DATA(trk2, T_TURNOUT, extraDataCompound_t); +		if (xx2->special == TOadjustable) +			adj2 = TRUE; +	}  	if (adj1 == FALSE && adj2 == FALSE)  		return FALSE; -	a1 = GetTrkEndAngle( trk1, ep1 ); -	a2 = GetTrkEndAngle( trk2, ep2 ); -	a = NormalizeAngle( a1 - a2 + 180.0 + connectAngle/2.0); -	if (a>connectAngle) +	a1 = GetTrkEndAngle(trk1, ep1); +	a2 = GetTrkEndAngle(trk2, ep2); +	a = NormalizeAngle(a1 - a2 + 180.0 + connectAngle / 2.0); +	if (a > connectAngle)  		return FALSE; -	UndoStart( _("Connect Adjustable Tracks"), "changeAdjustableEndPt" ); +	UndoStart(_("Connect Adjustable Tracks"), "changeAdjustableEndPt");  	maxD = 0.0;  	if (adj1) { -		p1 = GetTrkEndPos( trk1, 1-ep1 ); -		Translate( &p1, p1, a1, xx1->u.adjustable.minD ); -		maxD += xx1->u.adjustable.maxD-xx1->u.adjustable.minD; -	} else { -		p1 = GetTrkEndPos( trk1, ep1 ); +		p1 = GetTrkEndPos(trk1, 1 - ep1); +		Translate(&p1, p1, a1, xx1->u.adjustable.minD); +		maxD += xx1->u.adjustable.maxD - xx1->u.adjustable.minD; +	} +	else { +		p1 = GetTrkEndPos(trk1, ep1);  	}  	if (adj2) { -		p2 = GetTrkEndPos( trk2, 1-ep2 ); -		Translate( &p2, p2, a2, xx2->u.adjustable.minD ); -		maxD += xx2->u.adjustable.maxD-xx2->u.adjustable.minD; -	} else { -		p2 = GetTrkEndPos( trk2, ep2 ); +		p2 = GetTrkEndPos(trk2, 1 - ep2); +		Translate(&p2, p2, a2, xx2->u.adjustable.minD); +		maxD += xx2->u.adjustable.maxD - xx2->u.adjustable.minD; +	} +	else { +		p2 = GetTrkEndPos(trk2, ep2);  	} -	d = FindDistance( p1, p2 ); +	d = FindDistance(p1, p2);  	rc = TRUE;  	if (d > maxD) {  		d = maxD;  		rc = FALSE;  	} -	FindPos( &off, &beyond, p1, p2, a1, 10000.0 ); +	FindPos(&off, &beyond, p1, p2, a1, DIST_INF);  	if (fabs(off.y) > connectDistance)  		rc = FALSE;  	if (adj1) { -		UndrawNewTrack( trk1 ); -		d1 = d * (xx1->u.adjustable.maxD-xx1->u.adjustable.minD)/maxD + xx1->u.adjustable.minD; -		ChangeAdjustableEndPt( trk1, ep1, d1 ); +		UndrawNewTrack(trk1); +		d1 = d * (xx1->u.adjustable.maxD - xx1->u.adjustable.minD) / maxD + xx1->u.adjustable.minD; +		ChangeAdjustableEndPt(trk1, ep1, d1);  	}  	if (adj2) { -		UndrawNewTrack( trk2 ); -		d2 = d * (xx2->u.adjustable.maxD-xx2->u.adjustable.minD)/maxD + xx2->u.adjustable.minD; -		ChangeAdjustableEndPt( trk2, ep2, d2 ); +		UndrawNewTrack(trk2); +		d2 = d * (xx2->u.adjustable.maxD - xx2->u.adjustable.minD) / maxD + xx2->u.adjustable.minD; +		ChangeAdjustableEndPt(trk2, ep2, d2);  	}  	if (rc) { -		DrawEndPt( &mainD, trk1, ep1, wDrawColorWhite ); -		DrawEndPt( &mainD, trk2, ep2, wDrawColorWhite ); -		ConnectTracks( trk1, ep1, trk2, ep2 ); -		DrawEndPt( &mainD, trk1, ep1, wDrawColorBlack ); -		DrawEndPt( &mainD, trk2, ep2, wDrawColorBlack ); +		DrawEndPt(&mainD, trk1, ep1, wDrawColorWhite); +		DrawEndPt(&mainD, trk2, ep2, wDrawColorWhite); +		ConnectTracks(trk1, ep1, trk2, ep2); +		DrawEndPt(&mainD, trk1, ep1, wDrawColorBlack); +		DrawEndPt(&mainD, trk2, ep2, wDrawColorBlack);  	}  	return rc;  } - +  /****************************************   *   * Draw Turnout Roadbed @@ -613,81 +645,84 @@ EXPORT BOOL_T ConnectAdjustableTracks(  int roadbedOnScreen = 0; -void DrawTurnoutRoadbedSide( drawCmd_p d, wDrawColor color, coOrd orig, ANGLE_T angle, trkSeg_p sp, ANGLE_T side, int first, int last ) +void DrawTurnoutRoadbedSide(drawCmd_p d, wDrawColor color, coOrd orig, ANGLE_T angle, trkSeg_p sp, ANGLE_T side, int first, int last)  {  	segProcData_t data; -	if (last<=first) +	if (last <= first)  		return;  	data.drawRoadbedSide.first = first;  	data.drawRoadbedSide.last = last;  	data.drawRoadbedSide.side = side;  	data.drawRoadbedSide.roadbedWidth = roadbedWidth; -	data.drawRoadbedSide.rbw = (wDrawWidth)floor(roadbedLineWidth*(d->dpi/d->scale)+0.5); +	data.drawRoadbedSide.rbw = (wDrawWidth)floor(roadbedLineWidth * (d->dpi / d->scale) + 0.5);  	data.drawRoadbedSide.orig = orig;  	data.drawRoadbedSide.angle = angle;  	data.drawRoadbedSide.color = color;  	data.drawRoadbedSide.d = d; -	SegProc( SEGPROC_DRAWROADBEDSIDE, sp, &data ); +	SegProc(SEGPROC_DRAWROADBEDSIDE, sp, &data);  }  static void ComputeAndDrawTurnoutRoadbedSide( -		drawCmd_p d, -		wDrawColor color, -		coOrd orig, -		ANGLE_T angle, -		trkSeg_p segPtr, -		int segCnt, -		int segInx, -		ANGLE_T side ) +	drawCmd_p d, +	wDrawColor color, +	coOrd orig, +	ANGLE_T angle, +	trkSeg_p segPtr, +	int segCnt, +	int segInx, +	ANGLE_T side)  {  	unsigned long res, res1;  	int b0, b1; -	res = ComputeTurnoutRoadbedSide( segPtr, segCnt, segInx, side, roadbedWidth ); +	res = ComputeTurnoutRoadbedSide(segPtr, segCnt, segInx, side, roadbedWidth);  	if (res == 0L) { -	} else if (res == 0xFFFFFFFF) { -		DrawTurnoutRoadbedSide( d, color, orig, angle, &segPtr[segInx], side, 0, 32 ); -	} else { -		for ( b0=0, res1=0x00000001; res1&&(res1&res); b0++,res1<<=1 ); -		for ( b1=32,res1=0x80000000; res1&&(res1&res); b1--,res1>>=1 ); -		DrawTurnoutRoadbedSide( d, color, orig, angle, &segPtr[segInx], side, 0, b0 ); -		DrawTurnoutRoadbedSide( d, color, orig, angle, &segPtr[segInx], side, b1, 32 ); +	} +	else if (res == 0xFFFFFFFF) { +		DrawTurnoutRoadbedSide(d, color, orig, angle, &segPtr[segInx], side, 0, 32); +	} +	else { +		for (b0 = 0, res1 = 0x00000001; res1 && (res1 & res); b0++, res1 <<= 1); +		for (b1 = 32, res1 = 0x80000000; res1 && (res1 & res); b1--, res1 >>= 1); +		DrawTurnoutRoadbedSide(d, color, orig, angle, &segPtr[segInx], side, 0, b0); +		DrawTurnoutRoadbedSide(d, color, orig, angle, &segPtr[segInx], side, b1, 32);  	}  }  static void DrawTurnoutRoadbed( -		drawCmd_p d, -		wDrawColor color, -		coOrd orig, -		ANGLE_T angle, -		trkSeg_p segPtr, -		int segCnt ) -{ -	int inx, trkCnt=0, segInx=0; -	for (inx=0;inx<segCnt;inx++) { -		if ( IsSegTrack(&segPtr[inx]) ) { +	drawCmd_p d, +	wDrawColor color, +	coOrd orig, +	ANGLE_T angle, +	trkSeg_p segPtr, +	int segCnt) +{ +	int inx, trkCnt = 0, segInx = 0; +	for (inx = 0; inx < segCnt; inx++) { +		if (IsSegTrack(&segPtr[inx])) {  			segInx = inx;  			trkCnt++; -			if (trkCnt>1) +			if (trkCnt > 1)  				break;  		}  	} -	if (trkCnt==0) +	if (trkCnt == 0)  		return;  	if (trkCnt == 1) { -		DrawTurnoutRoadbedSide( d, color, orig, angle, &segPtr[segInx], +90, 0, 32 ); -		DrawTurnoutRoadbedSide( d, color, orig, angle, &segPtr[segInx], -90, 0, 32 ); -	} else { -		for (inx=0;inx<segCnt;inx++) { -			if ( IsSegTrack(&segPtr[inx]) ) { -				ComputeAndDrawTurnoutRoadbedSide( d, color, orig, angle, segPtr, segCnt, inx, +90 ); -				ComputeAndDrawTurnoutRoadbedSide( d, color, orig, angle, segPtr, segCnt, inx, -90 ); +		DrawTurnoutRoadbedSide(d, color, orig, angle, &segPtr[segInx], +90, 0, 32); +		DrawTurnoutRoadbedSide(d, color, orig, angle, &segPtr[segInx], -90, 0, 32); +	} +	else { +		for (inx = 0; inx < segCnt; inx++) { +			if (IsSegTrack(&segPtr[inx])) { +				ComputeAndDrawTurnoutRoadbedSide(d, color, orig, angle, segPtr, segCnt, inx, +90); +				ComputeAndDrawTurnoutRoadbedSide(d, color, orig, angle, segPtr, segCnt, inx, -90);  			}  		}  	}  } - +  /****************************************   *   * HAND LAID TURNOUTS @@ -695,47 +730,47 @@ static void DrawTurnoutRoadbed(   */  track_p NewHandLaidTurnout( -		coOrd p0, -		ANGLE_T a0, -		coOrd p1, -		ANGLE_T a1, -		coOrd p2, -		ANGLE_T a2, -		ANGLE_T frogA ) +	coOrd p0, +	ANGLE_T a0, +	coOrd p1, +	ANGLE_T a1, +	coOrd p2, +	ANGLE_T a2, +	ANGLE_T frogA)  {  	track_p trk; -	struct extraData * xx; +	struct extraDataCompound_t* xx;  	trkSeg_t segs[2]; -	sprintf( message, "\tHand Laid Turnout, Angle=%0.1f\t", frogA ); -	DYNARR_SET( trkEndPt_t, tempEndPts_da, 2 ); -	memset( &tempEndPts(0), 0, tempEndPts_da.cnt * sizeof tempEndPts(0) ); +	sprintf(message, "\tHand Laid Turnout, Angle=%0.1f\t", frogA); +	DYNARR_SET(trkEndPt_t, tempEndPts_da, 2); +	memset(&tempEndPts(0), 0, tempEndPts_da.cnt * sizeof tempEndPts(0));  	tempEndPts(0).pos = p0;  	tempEndPts(0).angle = a0;  	tempEndPts(1).pos = p1;  	tempEndPts(1).angle = a1;  	tempEndPts(2).pos = p2;  	tempEndPts(2).angle = a2; -	Rotate( &p1, p0, -a0 ); +	Rotate(&p1, p0, -a0);  	p1.x -= p0.x;  	p1.y -= p0.y;  	segs[0].type = SEG_STRTRK;  	segs[0].color = wDrawColorBlack;  	segs[0].u.l.pos[0] = zero;  	segs[0].u.l.pos[1] = p1; -	Rotate( &p2, p0, -a0 ); +	Rotate(&p2, p0, -a0);  	p2.x -= p0.x;  	p2.y -= p0.y;  	segs[1].type = SEG_STRTRK;  	segs[1].color = wDrawColorBlack;  	segs[1].u.l.pos[0] = zero;  	segs[1].u.l.pos[1] = p2; -	trk = NewCompound( T_TURNOUT, 0, p0, a0, message, 3, &tempEndPts(0), NULL, 22, "Normal\0\1\0\0Reverse\0\2\0\0\0", 2, segs ); -	xx = GetTrkExtraData(trk); +	trk = NewCompound(T_TURNOUT, 0, p0, a0, message, 3, &tempEndPts(0), (PATHPTR_T)"Normal\0\1\0\0Reverse\0\2\0\0\0", 2, segs); +	xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	xx->handlaid = TRUE;  	return trk;  } - +  /****************************************   *   * GENERIC FUNCTIONS @@ -743,136 +778,1982 @@ track_p NewHandLaidTurnout(   */  static coOrd MapPathPos( -		struct extraData * xx, -		signed char segInx, -		EPINX_T ep ) +	struct extraDataCompound_t* xx, +	signed char segInx, +	EPINX_T ep)  {  	trkSeg_p segPtr;  	coOrd pos; -	if ( segInx < 0 ) { -		segInx = - segInx; -		ep = 1-ep; +	if (segInx < 0) { +		segInx = -segInx; +		ep = 1 - ep;  	} -	segPtr=xx->segs+(segInx-1); +	segPtr = xx->segs + (segInx - 1);  	if (!IsSegTrack(segPtr)) { -		fprintf( stderr, "mapPathPos: bad segInx: %d\n", segInx ); +		fprintf(stderr, "mapPathPos: bad segInx: %d\n", segInx);  		return zero;  	} -	pos = GetSegEndPt( segPtr, ep, FALSE, NULL ); -	REORIGIN1( pos, xx->angle, xx->orig ); +	pos = GetSegEndPt(segPtr, ep, FALSE, NULL); +	REORIGIN1(pos, xx->angle, xx->orig);  	return pos;  } +static trkSeg_p MapPathSeg( +	struct extraDataCompound_t* xx, +	signed char segInx) { +	if (segInx < 0) { +		segInx = -segInx; +	} +	return xx->segs + (segInx - 1); +} + + +/**************************************** + * + * TURNOUT DRAWING + * + */ + + /** + * Get the paths from the turnout definition. Puts the results into static dto structure. + * Curved segments are broken up into short sections of the lesser of 5 degrees or 5 * tie spacing.  + * + * \param trk track_p pointer to a track + * \param xx  pointer to the extraDataCompound struct + * + * \returns the number of paths + */ +int GetTurnoutPaths(track_p trk, struct extraDataCompound_t* xx) { +	wIndex_t segInx; +	wIndex_t segEP; + +	SCALEINX_T scaleInx = GetTrkScale(trk); +	tieData_p td = GetScaleTieData(scaleInx); + +	int i; +	ANGLE_T a0, a1, aa0, aa1; +	DIST_T r, len; +	coOrd p0, p1; + +	PATHPTR_T pp; +	int pathCnt = 0, routeCnt = 0; + +	for (i = 0; i < DTO_DIM; i++) +		dto[i].n = 0; + +	dtod.trk = trk; +	dtod.index = trk->index; +	dtod.xx = xx; + +	// Validate that the first segment starts at (0, 0) +	// and if STR p1.y == 0, if CRV angle == 0 or angle == 180 +	GetSegInxEP(1, &segInx, &segEP); +	trkSeg_p segPtr = &xx->segs[segInx]; +	switch (segPtr->type) { +	case SEG_STRTRK: +		p0 = segPtr->u.l.pos[0]; +		p1 = segPtr->u.l.pos[1]; +		if ((FindDistance(p0, zero) > EPSILON) || (fabs(p1.y) > EPSILON)) +			return -1; +		break; +	case SEG_CRVTRK: +		r = fabs(segPtr->u.c.radius); +		a0 = segPtr->u.c.a0; +		a1 = segPtr->u.c.a1; + +		if (segPtr->u.c.radius > 0) { +			aa0 = a0; +		} +		else { +			aa0 = a0 + a1; +		} +		PointOnCircle(&p0, segPtr->u.c.center, r, aa0); +		if ((FindDistance(p0, zero) > EPSILON) +			|| ((fabs(aa0 - 180) > EPSILON) && (fabs(aa0) > EPSILON))) +			return -1; +		break; +	} + +	pp = GetPaths(trk); +	while (pp[0]) { +		pp += strlen((char*)pp) + 1; + +		ANGLE_T angle = 0; +		while (pp[0]) { +			if (pathCnt < DTO_DIM) +				dto[pathCnt].type = 'S'; +			while (pp[0]) { +				GetSegInxEP(pp[0], &segInx, &segEP); +				// trkSeg_p  +				segPtr = &xx->segs[segInx]; +				switch (segPtr->type) { +				case SEG_STRTRK: +					p0 = segPtr->u.l.pos[0]; +					p1 = segPtr->u.l.pos[1]; + +					wIndex_t n = dto[pathCnt].n; +					dto[pathCnt].trkSeg[n] = segPtr; +					dto[pathCnt].base[n] = p0; +					n++; +					dto[pathCnt].trkSeg[n] = segPtr; +					dto[pathCnt].base[n] = p1; +					// n++; +					dto[pathCnt].n = n; + +					if (n >= DTO_SEGS - 1) return -1; + +					break; +				case SEG_CRVTRK: +					r = fabs(segPtr->u.c.radius); + +					dto[pathCnt].type = segPtr->u.c.center.y < 0 ? 'R' : 'L'; + +					a0 = segPtr->u.c.a0; +					a1 = segPtr->u.c.a1; + +					angle += a1; + +					len = D2R(a1) * r; +					// Every 5 degrees or 5 * tie spacing +					int cnt = (int)floor(a1 / 5.0); +					int cnt2 = (int)floor(len / 5 / td->spacing); +					if (cnt2 > cnt) cnt = cnt2; +					if (cnt <= 0) cnt = 1; + +					aa1 = a1 / cnt; +					if (dto[pathCnt].type == 'R') { +						aa0 = a0; +					} +					else { +						aa0 = a0 + a1; +						aa1 = -aa1; +					} +					PointOnCircle(&p0, segPtr->u.c.center, r, aa0); +					n = dto[pathCnt].n; +					dto[pathCnt].trkSeg[n] = segPtr; +					dto[pathCnt].base[n] = p0; +					n++; +					dto[pathCnt].n = n; + +					while (cnt > 0) { +						aa0 += aa1; +						PointOnCircle(&p0, segPtr->u.c.center, r, aa0); + +						// n = dto[pathCnt].n; +						dto[pathCnt].trkSeg[n] = segPtr; +						dto[pathCnt].base[n] = p0; +						n++; + +						if (n >= DTO_SEGS - 1) return -1; + +						cnt--; +					} +					n--; // remove that last point count +					dto[pathCnt].n = n; +				} +				pp++; +			} +			// Include the last point +			dto[pathCnt].crvAngle = angle; +			dto[pathCnt].n++; + +			pathCnt++; +			if (pathCnt > DTO_DIM) return -1; +			pp++; +		} +		routeCnt++; +		pp++; +	} +	dtod.pathCnt = pathCnt; +	dtod.routeCnt = routeCnt; +	dtod.endCnt = trk->endCnt; + +	// Guard value: n < DTO_SEGS - 2 +	for (i = 0; i < pathCnt; i++) +		dto[i].pts[dto[i].n].x = DIST_INF; + +	return pathCnt; +} + +/** +* Sets the turnout type if compatible with enhanced drawing methods. The data is +* from the path data saved in dtod and dto by GetTurnoutPaths. The turnout type is +* stored in the dtod.toType. DTO_INVALID (0) if the enhanced methods cannot handle +* it. +*/ +void GetTurnoutType() { +	dtod.strPath = -1; +	dtod.str2Path = -1; +	dtod.crvPath = -1; +	dtod.crv2Path = -1; + +	dtod.toType = DTO_INVALID; + +	int strCnt = 0, crvCnt = 0, lftCnt = 0, rgtCnt = 0; +	enum dtoType toType = DTO_INVALID; +	int i, j; + +	// Count path origins +	dtod.origCnt = 1; +	dtod.origins[0] = 0; + +	for (i = 1; i < dtod.pathCnt; i++) { +		int eq = 0; +		for (j = 0; j < i; j++) { +			if (CoOrdEqual(dto[dtod.origins[j]].base[0], dto[i].base[0])) +				eq++; +		} +		if (eq == 0) { +			dtod.origins[dtod.origCnt] = i; +			dtod.origCnt++; +		} + +		if (dtod.origCnt > 4) +			return; +	} + +	// Determine the path type +	for (i = 0; i < dtod.pathCnt; i++) { +		switch (dto[i].type) { +		case 'S': +			strCnt++; +			if (strCnt == 1) +				dtod.strPath = i; +			else +				dtod.str2Path = i; +			break; +		case 'L': +			lftCnt++; +			crvCnt++; +			if (crvCnt == 1) +				dtod.crvPath = i; +			else +				dtod.crv2Path = i; +			break; +		case 'R': +			rgtCnt++; +			crvCnt++; +			if (crvCnt == 1) +				dtod.crvPath = i; +			else +				dtod.crv2Path = i; +			break; +		} +	} + +	dtod.strCnt = strCnt; +	dtod.crvCnt = crvCnt; +	dtod.lftCnt = lftCnt; +	dtod.rgtCnt = rgtCnt; + +	// Normal two- or three-way turnout, or a curved turnout +	if (dtod.origCnt == 1) { +		if (dtod.pathCnt == 2) { +			if (strCnt == 1 && crvCnt == 1) { +				dtod.toType = DTO_NORMAL; +			} +			else if ((strCnt == 0) && ((lftCnt == 2) || (rgtCnt == 2))) { +				// Assumes outer curve is [0] and inner is [1] +				if ((dto[0].crvAngle <= 20) && (dto[1].crvAngle - dto[0].crvAngle <= 15)) +					dtod.toType = DTO_CURVED; +			} +			else if (lftCnt == 1 && rgtCnt == 1) { +				dtod.toType = DTO_WYE; +			} +		} +		else if ((dtod.pathCnt == 3) && (strCnt == 1) +			&& (lftCnt == 1) && (rgtCnt == 1)) { +			dtod.toType = DTO_THREE; +		} +	} +	else +		// Crossing, single- and double-slip +		if ((dtod.origCnt == 2) && (dtod.endCnt == 4) +			&& strCnt == 2) { + +			ANGLE_T a0, a1, a2; +			a1 = FindAngle(dto[dtod.strPath].base[0], dto[dtod.strPath].base[1]); +			a2 = FindAngle(dto[dtod.str2Path].base[0], dto[dtod.str2Path].base[1]); +			// Swap the ends of the strPath if large angle +			if((a1 > 180.0) && (dto[dtod.strPath].n == 2)) +			{ +				coOrd tmp = dto[dtod.strPath].base[0]; +				dto[dtod.strPath].base[0] = dto[dtod.strPath].base[1]; +				dto[dtod.strPath].base[1] = tmp; + +				i = dto[dtod.strPath].n - 1; +				tmp = dto[dtod.strPath].pts[0]; +				dto[dtod.strPath].pts[0] = dto[dtod.strPath].pts[i]; +				dto[dtod.strPath].pts[i] = tmp; + +				a1 = a1 - 180.0;  +				dto[dtod.strPath].angle = a1; +			} +			// Swap the ends of the str2Path if large angle +			if((a2 > 180.0) && (dto[dtod.str2Path].n == 2)) +			{ +				coOrd tmp = dto[dtod.str2Path].base[0]; +				dto[dtod.str2Path].base[0] = dto[dtod.str2Path].base[1]; +				dto[dtod.str2Path].base[1] = tmp; +				 +				i = dto[dtod.str2Path].n - 1; +				tmp = dto[dtod.str2Path].pts[0]; +				dto[dtod.str2Path].pts[0] = dto[dtod.str2Path].pts[i]; +				dto[dtod.str2Path].pts[i] = tmp; + +				a2 = a2 - 180.0;  +				dto[dtod.str2Path].angle = a2; +			} +			a0 = DifferenceBetweenAngles(a1, a2); +			if(a0 < 0) +			{ +				int tmp = dtod.strPath; +				dtod.strPath = dtod.str2Path; +				dtod.str2Path = tmp; +				a0 = NormalizeAngle(-a0); +			} +			if ((a0 > 90.0) || (a0 < 0.0)) +				return; + +			coOrd p1 = dto[dtod.strPath].base[0]; +			coOrd p2 = dto[dtod.str2Path].base[0]; +			coOrd pos = zero; +			int intersect = FindIntersection(&pos, p1, a1, p2, a2); + +			if (intersect) { +				if(strCnt == 2 && dtod.pathCnt == 2){ +					if((a0 <= 61) && (a0 >= -61)) +						dtod.toType = DTO_XING; +					else +						dtod.toType = DTO_XNG9; +				} +				else if(dtod.pathCnt == 3 && (lftCnt == 1 || rgtCnt == 1)){ +					dtod.toType = DTO_SSLIP; +				} +				else if(dtod.pathCnt == 4 && lftCnt == 1 && rgtCnt == 1){ +					dtod.toType = DTO_DSLIP; +				} +			} +			// No intersect, it could be a crossover +			else if (strCnt == 2) { +				if (dtod.pathCnt == 4 && lftCnt == 1 && rgtCnt == 1) { +					dtod.toType = DTO_DCROSS; +				} +				else if(dtod.pathCnt == 3){ +					// Perverse test because the cross paths go Left then Right, for example +					if(lftCnt == 1){ +						dtod.toType = DTO_RCROSS; +					} +					else if(rgtCnt == 1){ +						dtod.toType = DTO_LCROSS; +					} +					else{ +						dtod.toType = DTO_INVALID; +					} +				} +			} +		} +} + +/** + * Draw Layout lines and points + *  + * \param d The drawing object + * \param scaleInx The layout/track scale index + */ +static void DrawDtoLayout( +	drawCmd_p d, +	SCALEINX_T scaleInx +) +{ +	tieData_p td; +	td = GetScaleTieData(scaleInx); + +	// Draw the points and lines from dto +	double r = td->width / 2; +	// if (r < 1) r = 1; + +	int i, j; +	for (i = 0; i < DTO_DIM; i++) { +		for (j = 0; j < dto[i].n; j++) { +			DrawFillCircle(d, dto[i].pts[j], r, drawColorPurple); +			if (j < dto[i].n - 1) +				DrawLine(d, dto[i].pts[j], dto[i].pts[j + 1], 0, drawColorPurple); +		} +	} +} + +/** +* Use the coOrds to build a polygon and draw the bridge fill. Note that the coordinates are  +* passed as pairs, and rearranged into a polygon with the 1,2,4,3 order.  +*  +* \param d The drawing object +* \param b1 The first coordinate +* \param b2 The second coordinate +* \param b3 The third coordinate +* \param b4 The fourth coordinate +*/ +static void DrawBridgeFill( +	drawCmd_p d,  +	coOrd b1, +	coOrd b2, +	coOrd b3, +	coOrd b4 +	)  +{ +	coOrd p[4] = {b1, b2, b4, b3}; +	DrawPoly(d,4,p,NULL,drawColorGrey90,0,DRAW_FILL );  +} + +/** +* Draw Bridge parapets and background for a turnout +*  +* \param d The drawing object +* \param path1 The first path +* \param path2 The second path +*/ +static void DrawTurnoutBridge( +    drawCmd_p d, +    int path1, +    int path2 +) +{ +    DIST_T trackGauge = GetTrkGauge(dtod.trk); +    wDrawWidth width2 = (wDrawWidth)round((2.0 * d->dpi) / BASE_DPI); +	if (d->options&DC_PRINT) +		width2 = (wDrawWidth)round(d->dpi / BASE_DPI); + +    coOrd b1,b2,b3,b4,b5,b6; +    ANGLE_T angle = dtod.xx->angle,a = 0.0; +    int i,j,i1,i2; +    i1 = path1; +    i2 = path2; +    if(dto[i1].base[dto[i1].n - 1].y < dto[i2].base[dto[i2].n - 1].y) { +        i1 = path2; +        i2 = path1; +        // a = -a; +    } + +    if(dtod.toType == DTO_THREE) { +        i = dtod.strPath; +        DIST_T dy = fabs(dto[i].dy[0]) + trackGauge * 1.5; +        b1 = dto[i].pts[0]; +        Translate(&b3,b1,(angle + a),dy); +        b1 = dto[i].pts[dto[i].n - 1]; +        Translate(&b4,b1,(angle + a),dy); +        b2 = dto[i].pts[0]; +        Translate(&b5,b2,(angle + a),-dy); +        b2 = dto[i].pts[dto[i].n - 1]; +        Translate(&b6,b2,(angle + a),-dy); + +        // Draw the bridge background +        DrawBridgeFill(d,b3,b4,b5,b6); +    } + +    for(i = i1; 1; i = i2,a = 180.0) { +        DIST_T dy = fabs(dto[i].dy[0]) + trackGauge * 1.5; +        b1 = dto[i].pts[0]; +        Translate(&b3,b1,(angle + a),dy); +        Translate(&b5,b1,(angle + a),-(dy * 0.75)); +        for(j = 1; j < dto[i].n; j++) { +            dy = fabs(dto[i].dy[j]) + trackGauge * 1.5; +            b2 = dto[i].pts[j]; +            Translate(&b4,b2,(angle + a),dy); +            Translate(&b6,b2,(angle + a),-(dy * 0.75)); + +            // Draw the bridge background +            DrawBridgeFill(d,b3,b4,b5,b6); + +            // Draw the bridge edge +            DrawLine(d,b3,b4,width2,drawColorBlack); + +            b1 = b2; +            b3 = b4; +            b5 = b6; +        } + +        if(i == i2) +            break; +    } + +    EPINX_T ep; +    coOrd p; +    track_p trk1; +    coOrd p0,p1; + +    for(ep = 0; ep < 3; ep++) { +        trk1 = GetTrkEndTrk(dtod.trk,ep); + +        if((trk1) && (!GetTrkBridge(trk1))) { + +            p = GetTrkEndPos(dtod.trk,ep); +            a = GetTrkEndAngle(dtod.trk,ep) + 90.0; + +            int i = (dtod.lftCnt > 0) && (dtod.rgtCnt == 0) ? 2 : 1; +            if(ep != i) { +                Translate(&p0,p,a,trackGauge * 1.5); +                Translate(&p1,p0,a - 45.0,trackGauge * 1.5); +                DrawLine(d,p0,p1,width2,drawColorBlack); +            } +            if(ep != (3 - i)) { +                Translate(&p0,p,a,-trackGauge * 1.5); +                Translate(&p1,p0,a + 45.0,-trackGauge * 1.5); +                DrawLine(d,p0,p1,width2,drawColorBlack); +            } +        } +    } +} + +/** +* Draw Bridge parapets and background for a cross-over +*  +* \param d The drawing object +* \param path1 The first path, straight +* \param path2 The second path, straight +*/ +static void DrawCrossBridge( +	drawCmd_p d,  +	int path1, +	int path2 +) +{ +	DIST_T trackGauge = GetTrkGauge(dtod.trk); +	wDrawWidth width2 = (wDrawWidth)round((2.0 * d->dpi)/BASE_DPI); +	if (d->options&DC_PRINT) +		width2 = (wDrawWidth)round(d->dpi / BASE_DPI); + +	coOrd b1, b2, b3, b4, b5, b6; +	ANGLE_T angle = dtod.xx->angle, a = 0.0; +	int i1, i2; +	i1 = path1; +	i2 = path2; +	if(dto[i1].base[dto[i1].n - 1].y < dto[i2].base[dto[i2].n - 1].y) { +		i1 = path2; +		i2 = path1; +		// a = -a; +	} + +	DIST_T dy = fabs(dto[i1].dy[0]) + trackGauge * 1.5; +	b1 = dto[i1].pts[0]; +	Translate(&b3,b1,(angle + a),dy); +	b1 = dto[i1].pts[dto[i1].n-1]; +	Translate(&b4,b1,(angle + a),dy); +	b2 = dto[i2].pts[0]; +	Translate(&b5,b2,(angle + a),-dy); +	b2 = dto[i2].pts[dto[i2].n-1]; +	Translate(&b6,b2,(angle + a),-dy); + +	// Draw the bridge background +	DrawBridgeFill(d, b3, b4, b5, b6); + +	// Draw the bridge edges +	DrawLine(d,b3,b4,width2,drawColorBlack); +	DrawLine(d,b5,b6,width2,drawColorBlack); + +    EPINX_T ep; +    coOrd p; +    track_p trk1; +    coOrd p0,p1; + +    for(ep = 0; ep < 4; ep++) { +        trk1 = GetTrkEndTrk(dtod.trk,ep); + +        if((trk1) && (!GetTrkBridge(trk1))) { +            p = GetTrkEndPos(dtod.trk,ep); +            a = GetTrkEndAngle(dtod.trk,ep) + 90.0; + +            if((ep == 1) || (ep == 2)) { +                Translate(&p0,p,a,trackGauge * 1.5); +                Translate(&p1,p0,a - 45.0,trackGauge * 1.5); +                DrawLine(d,p0,p1,width2,drawColorBlack); +            } +            if((ep == 0) || (ep == 3)) { +                Translate(&p0,p,a,-trackGauge * 1.5); +                Translate(&p1,p0,a + 45.0,-trackGauge * 1.5); +                DrawLine(d,p0,p1,width2,drawColorBlack); +            } +        } +    } +} + +/** +* Draw Bridge parapets and background for a crossing +*  +* \param d The drawing object +* \param path1 The first path +* \param path2 The second path +*/ +static void DrawXingBridge( +	drawCmd_p d,  +	int path1, +	int path2 +) +{ +	DIST_T trackGauge = GetTrkGauge(dtod.trk); +	wDrawWidth width2 = (wDrawWidth)round((2.0 * d->dpi)/BASE_DPI); +	if (d->options&DC_PRINT) +		width2 = (wDrawWidth)round(d->dpi / BASE_DPI); + +	coOrd b0, b1, b2, b3, b4, b5, b6; +	int i, j, i1, i2; +	i1 = dtod.strPath; +	i2 = dtod.str2Path; + +	// Bridge fill both straight sections +	wDrawWidth width3 = (wDrawWidth)round(trackGauge * 3 * d->dpi/d->scale);  +	b1 = dto[i1].pts[0]; +	b2 = dto[i1].pts[dto[i1].n-1]; +	DrawLine(d,b1,b2,width3,wDrawColorGrey90); +	b1 = dto[i2].pts[0]; +	b2 = dto[i2].pts[dto[i1].n-1]; +	DrawLine(d,b1,b2,width3,wDrawColorGrey90); + +	i1 = path1; +	i2 = path2; +	if(dto[i1].base[dto[i1].n - 1].y < dto[i2].base[dto[i2].n - 1].y) { +		i1 = path2; +		i2 = path1; +	} + +	// Handle curved sections for slips +	BOOL_T hasLeft = 0, hasRgt = 0; +	ANGLE_T angle = dtod.xx->angle, a = 0.0; +	for(i = i1; 1; i = i2,a = 180.0) { +		DIST_T dy = fabs(dto[i].dy[0]) + trackGauge * 1.5; +		b1 = dto[i].pts[0]; +		Translate(&b3,b1,(angle + a),dy); +		Translate(&b5,b1,(angle + a),-(dy * 0.75)); +		if(dto[i].type != 'S') { +			if(dto[i].type == 'L') +				hasLeft = 1; +			else if(dto[i].type == 'R') +				hasRgt = 1; +			for(j = 1; j < dto[i].n; j++) { +				dy = fabs(dto[i].dy[j]) + trackGauge * 1.5; +				b2 = dto[i].pts[j]; +				Translate(&b4,b2,(angle + a),dy); +				Translate(&b6,b2,(angle + a),-(dy * 0.75)); + +				// Draw the bridge background +				DrawBridgeFill(d,b3,b4,b5,b6); + +				// Draw the bridge edge +				DrawLine(d,b3,b4,width2,drawColorBlack); +				b1 = b2; +				b3 = b4; +				b5 = b6; +			} +		} +		if(i == i2) +			break; +	} + +	if(dtod.strPath >= 0 && dtod.str2Path >= 0) { +		i1 = dtod.strPath; +		i2 = dtod.str2Path; +		if(!hasRgt) { +			DIST_T dy = trackGauge * 1.5; +			ANGLE_T a1, a2; +			b1 = dto[i1].pts[0]; +            a1 = dto[i1].angle + 90; +			Translate(&b3,b1,a1,dy); + +			b2 = dto[i2].pts[dto[i2].n - 1]; +            a2 = dto[i2].angle + 90; +			Translate(&b4,b2,a2,dy); + +			FindIntersection(&b0, b3, a1-90.0, b4, a2-90.0); + +			// Draw the bridge edge +			DrawLine(d,b3,b0,width2,drawColorBlack); +			DrawLine(d,b0,b4,width2,drawColorBlack); +		} + +		if(!hasLeft) { +			DIST_T dy = trackGauge * 1.5; +			ANGLE_T a1, a2; +			b1 = dto[i2].pts[0]; +			a1 = dto[i2].angle - 90; +			Translate(&b3,b1,a1,dy); + +			b2 = dto[i1].pts[dto[i1].n - 1]; +			a2 = dto[i1].angle - 90; +			Translate(&b4,b2,a2,dy); + +			FindIntersection(&b0, b3, a1+90.0, b4, a2+90.0); + +			// Draw the bridge edge +			DrawLine(d,b3,b0,width2,drawColorBlack); +			DrawLine(d,b0,b4,width2,drawColorBlack); +		} + +		if(dtod.toType == DTO_XNG9) { +			DIST_T dy = trackGauge * 1.5; +			ANGLE_T a1, a2; +			b1 = dto[i1].pts[dto[i1].n - 1]; +			a1 = dto[i1].angle + 90; +			Translate(&b3,b1,a1,dy); + +			b2 = dto[i2].pts[dto[i2].n - 1]; +			a2 = dto[i2].angle - 90; +			Translate(&b4,b2,a2,dy); + +			FindIntersection(&b0, b3, a1-90.0, b4, a2+90.0); + +			// Draw the bridge edge +			DrawLine(d,b3,b0,width2,drawColorBlack); +			DrawLine(d,b0,b4,width2,drawColorBlack); + +			b1 = dto[i1].pts[0]; +			a1 = dto[i1].angle - 90; +			Translate(&b3,b1,a1,dy); + +			b2 = dto[i2].pts[0]; +			a2 = dto[i2].angle + 90; +			Translate(&b4,b2,a2,dy); + +			FindIntersection(&b0, b3, a1+90.0, b4, a2-90.0); + +			// Draw the bridge edge +			DrawLine(d,b3,b0,width2,drawColorBlack); +			DrawLine(d,b0,b4,width2,drawColorBlack); +		} +	} + +    // Bridge wings +    EPINX_T ep; +    coOrd p; +    track_p trk1; +    coOrd p0,p1; + +    for(ep = 0; ep < 4; ep++) { +        trk1 = GetTrkEndTrk(dtod.trk,ep); + +        if((trk1) && (!GetTrkBridge(trk1))) { +            p = GetTrkEndPos(dtod.trk,ep); +            a = GetTrkEndAngle(dtod.trk,ep) + 90.0; + +            if((dtod.toType == DTO_XNG9) || (ep == 2) || (ep == 3)) { +                Translate(&p0,p,a,trackGauge * 1.5); +                Translate(&p1,p0,a - 45.0,trackGauge * 1.5); +                DrawLine(d,p0,p1,width2,drawColorBlack); +            } +            if((dtod.toType == DTO_XNG9) || (ep == 0) || (ep == 1)) { +                Translate(&p0,p,a,-trackGauge * 1.5); +                Translate(&p1,p0,a + 45.0,-trackGauge * 1.5); +                DrawLine(d,p0,p1,width2,drawColorBlack); +            } +        } +    } +} + +/** + * Init Normal Turnout data structure + * Calculates the dy value of each segment + * Sets pts values REORIGIN base to actual position and angle + * Save often used last base and last point coOrd + */ +static void DrawDtoInit() +{ +	struct extraDataCompound_t* xx = dtod.xx; +	coOrd p1; +	int i, j; + +	for(i = 0; i < DTO_DIM; i++) { +		int n = dto[i].n; +		for(j = 0; j < n; j++) { +			REORIGIN(p1,dto[i].base[j],xx->angle,xx->orig); +			dto[i].pts[j] = p1; +			if(j < n - 1) +				dto[i].dy[j] = (dto[i].base[j + 1].y - dto[i].base[j].y) / (dto[i].base[j + 1].x - dto[i].base[j].x); +		} +		dto[i].ptsLast = dto[i].pts[n - 1]; +		dto[i].baseLast = dto[i].base[n - 1]; +	} +} + +/** + * Draw Normal (Single Origin) Turnout Bridge and Ties. Uses the static dto and dtod structures. + * + * \param d The drawing object + * \param scaleInx The layout/track scale index + * \param color The tie color. If black the color is read from the global tieColor. + */ +static void DrawNormalTurnout( +	drawCmd_p d, +	SCALEINX_T scaleInx, +	BOOL_T omitTies, +	wDrawColor color) +{ +	tieData_p td; +	DIST_T len; +	coOrd pos; +	int cnt; +	ANGLE_T angle; +	coOrd s1, s2, p1, p2, q1, q2; +	int s0, p0, q0; +	ANGLE_T a0; + +	if (color == wDrawColorBlack) +		color = tieColor; + +	DIST_T trackGauge = GetTrkGauge(dtod.trk); + +	DrawDtoInit(); + +	// draw the points +#ifdef DTO_DEBUG +	if (DTO_DEBUG == DTO_NORMAL) DrawDtoLayout(d, scaleInx); +#endif + +	int strPath = dtod.strPath, othPath = 0, secPath = 1; +	int toType = dtod.toType; +	int first = 1; + +	switch (toType) { +	case DTO_NORMAL: +		othPath = 1 - strPath; +		secPath = strPath; +		break; +	case DTO_WYE: +		// strPath = 2; +		othPath = 0; secPath = 1; +		break; +	case DTO_THREE: +		switch (strPath) { +		case 0: +			othPath = 1; secPath = 2; +			break; +		case 1: +			othPath = 0; secPath = 2; +			break; +		case 2: +			othPath = 0; secPath = 1; +			break; +		} +		break; +	} + +	if(dtod.bridge) { +		DrawTurnoutBridge(d,othPath,secPath); +	} +	if (omitTies) +		return; + +	// Straight vector for tie angle +	if (toType == DTO_WYE) { +		s1 = dto[othPath].pts[0]; +		s2 = MidPtCoOrd(dto[othPath].ptsLast, dto[secPath].ptsLast); +	} +	else { +		s1 = dto[strPath].pts[0]; +		s2 = dto[strPath].ptsLast; +	} +	// Diverging vector(s) +	p1 = dto[othPath].pts[0]; +	p2 = dto[othPath].ptsLast; +	q1 = dto[secPath].pts[0]; +	q2 = dto[secPath].ptsLast; + +	td = GetScaleTieData(scaleInx); +	len = FindDistance(s1, s2); +	angle = FindAngle(s1, s2); // The straight segment + +	cnt = (int)floor(len / td->spacing + 0.5); +	if (cnt > 0) { +		int pn = dto[othPath].n; +		int qn = dto[secPath].n; +		DIST_T dx = len / cnt; +		s0 = p0 = q0 = 0; +		DIST_T tdlen = td->length; +		DIST_T tdmax = (toType == DTO_WYE) ? 2.0 * tdlen : 2.5 * tdlen; +		DIST_T px = len, dlenx = dx / 2; + +		cnt = cnt > 1 ? cnt - 1 : 1; +		for (px = dlenx; cnt; cnt--, px += dx) { +			if (px >= dto[othPath].base[p0 + 1].x) p0++; +			if (px >= dto[secPath].base[q0 + 1].x) q0++; +			if (p0 >= pn || q0 >= qn) +				break; + +			if ((px + dx >= dto[othPath].baseLast.x) || (px + dx >= dto[secPath].baseLast.x)) { +				break; +			} + +			DIST_T dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +			DIST_T dy2 = dto[secPath].base[q0].y + (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +			tdlen = td->length + fabs(dy1) + fabs(dy2); +			if (tdlen > tdmax) +				break; + +			DIST_T dy = dy1 + dy2; +			Translate(&pos, s1, angle, px); +			Translate(&pos, pos, (angle - 90.0), dy / 2); + +			DrawTie(d, pos, angle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +		} + +		// Asymmetric? Use longer ties for remaining two tracks (strPath, othPath) +		DIST_T sx = px; // Save these values for second code block +		int s0 = p0; +		if((dtod.toType == DTO_THREE) && (px + dx >= dto[secPath].baseLast.x)){ +			for ( ; cnt; cnt--, px += dx) { +				if (px >= dto[othPath].base[p0 + 1].x) p0++; +				// if (px >= dto[secPath].base[q0 + 1].x) q0++; +				if (p0 >= pn) +					break; + +				if (px + dx >= dto[othPath].baseLast.x) { +					break; +				} + +				DIST_T dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +				tdlen = td->length + fabs(dy1); +				if (tdlen > tdmax) +					break; + +				DIST_T dy = dy1; +				Translate(&pos, s1, angle, px); +				Translate(&pos, pos, (angle - 90.0), dy / 2); + +				DrawTie(d, pos, angle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +			} +		} + +		// Draw remaining ties, if any +		if (px + dx < dto[othPath].baseLast.x){ +			p1 = dto[othPath].pts[p0]; +			p2 = dto[othPath].ptsLast; +			angle = FindAngle(p1, p2); +			a0 = FindAngle(dto[othPath].base[p0], dto[othPath].baseLast); +			DIST_T lenr = (dto[othPath].baseLast.x - px + dlenx) / cos(D2R(90.0 - a0)); +			Translate(&p1, p2, angle, -lenr); +			DrawStraightTies(d, scaleInx, p1, p2, color); +		} +		else { +			p1 = dto[othPath].pts[pn - 2]; +			a0 = FindAngle(p1, p2); +			Translate(&pos, p2, a0, -dx / 2); +			DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +		} +		// Restore saved values +		if(dtod.toType == DTO_THREE){ +			px = sx; +			p0 = s0; +		} + +		// Asymmetric? Use longer ties for remaining two tracks (strPath, secPath) +		if((dtod.toType == DTO_THREE) && (px + dx >= dto[othPath].baseLast.x)){ +			for ( ; cnt; cnt--, px += dx) { +				// if (px >= dto[othPath].base[p0 + 1].x) p0++; +				if (px >= dto[secPath].base[q0 + 1].x) q0++; +				if (q0 >= qn) +					break; + +				if (px + dx >= dto[secPath].baseLast.x) { +					break; +				} + +				DIST_T dy1 = dto[secPath].base[q0].y + (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +				tdlen = td->length + fabs(dy1); +				if (tdlen > tdmax) +					break; + +				DIST_T dy = dy1; +				Translate(&pos, s1, angle, px); +				Translate(&pos, pos, (angle - 90.0), dy / 2); + +				DrawTie(d, pos, angle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +			} +		} +		if (px + dx < dto[secPath].baseLast.x) { +			q1 = dto[secPath].pts[q0]; +			q2 = dto[secPath].ptsLast; +			angle = FindAngle(q1, q2); +			a0 = FindAngle(dto[secPath].base[q0], dto[secPath].baseLast); +			DIST_T lenr = (dto[secPath].baseLast.x - px + dlenx) / cos(D2R(90.0 - a0)); +			Translate(&q1, q2, angle, -lenr); +			DrawStraightTies(d, scaleInx, q1, q2, color); +		} +		else { +			q1 = dto[secPath].pts[qn - 2]; +			a0 = FindAngle(q1, q2); +			Translate(&pos, q2, a0, -dx / 2); +			DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +		} + +		// Final ties at end +		if (dtod.toType == DTO_THREE) { + +			int n = (int)(dto[strPath].baseLast.x); +			if (px + dx < len) { +				angle = FindAngle(s1, s2); +				DIST_T lenr = len - px + dlenx; +				Translate(&s1, s2, angle, -lenr); +				DrawStraightTies(d, scaleInx, s1, s2, color); +			} +			else { +				n = dto[strPath].n; +				s1 = dto[strPath].pts[n - 2]; +				a0 = FindAngle(s1, s2); +				Translate(&pos, s2, a0, -dx / 2); +				DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +			} +		} +	} +} + +/** + * Draw Curved (Single Origin) Turnout Bridge and Ties. Uses the static dto and dtod structures. + * + * \param d The drawing object + * \param scaleInx The layout/track scale index + * \param color The tie color. If black the color is read from the global tieColor. + */ +static void DrawCurvedTurnout( +	drawCmd_p d, +	SCALEINX_T scaleInx, +	BOOL_T omitTies, +	wDrawColor color) +{ +	tieData_p td; +	DIST_T len, r; +	coOrd pos; +	int cnt; +	ANGLE_T angle, dang; +	coOrd center; +	coOrd p1, p2, q1, q2; +	ANGLE_T a0, a1, a2; +	struct extraDataCompound_t* xx = dtod.xx; + +	if (color == wDrawColorBlack) +		color = tieColor; + +	DrawDtoInit(); + +	// draw the points +#ifdef DTO_DEBUG +	if (DTO_DEBUG == DTO_CURVED) DrawDtoLayout(d, scaleInx); +#endif + +	int othPath = 0, secPath = 1; +	int toType = dtod.toType; + +	if(dtod.bridge) { +		DrawTurnoutBridge(d,othPath,secPath); +	} +	if (omitTies) +		return; + +	td = GetScaleTieData(scaleInx); + +	// Save the ending coordinates +	coOrd othEnd = zero, secEnd = zero; + +	trkSeg_p trk; +	DIST_T tdlen = td->length, tdmax = tdlen * 2.5; +	DIST_T tdspc = td->spacing, tdspc2 = tdspc / 2.0; +	double rdot = td->width / 2; + +	int pn = dto[othPath].n; +	int qn = dto[secPath].n; +	int p0 = 0, q0 = 0; +	DIST_T px = 0, qx = 0, dy = 0, dy1 = 0, dy2 = 0; + +	double cosAdj = 1.0; + +	angle = 0; +	px = tdspc2; +	qx = tdspc2; +	int segs = max(dto[othPath].n, dto[secPath].n); +	for (; segs > 0; segs--) { + +		if (px >= dto[othPath].base[p0 + 1].x) +			p0++; +		if (qx >= dto[secPath].base[q0 + 1].x) +			q0++; +		if ((p0 >= pn - 1) || (q0 >= qn - 1)) { +			break; +		} + +		trk = dto[othPath].trkSeg[p0]; +		if (trk->type == SEG_CRVTRK) { + +			center = trk->u.c.center; +			r = fabs(trk->u.c.radius); +			a0 = NormalizeAngle(trk->u.c.a0 + dtod.xx->angle); +			a1 = trk->u.c.a1; + +			pos = center; +			REORIGIN(center, pos, xx->angle, xx->orig); + +			len = r * D2R(a1); +			cnt = (int)floor(len / tdspc + 0.5); +			if (len - tdspc * cnt >= tdspc2) { +				cnt++; +			} +			DIST_T tdlen = td->length; +			DIST_T dx = len / cnt, dx2 = dx / 2; + +			if (cnt != 0) { +				dang = (len / cnt) * 360 / (2 * M_PI * r); +				DIST_T dx = len / cnt, dx2 = dx / 2; + +				if (dto[othPath].type == 'R') { +					a2 = a0 + dang / 2; +				} +				else { +					a2 = a0 + a1 - dang / 2; +					dang = -dang; +				} +				angle += fabs(dang / 2); + +				cosAdj = fabs(cos(D2R(angle))); +				px += dx2 * cosAdj; +				qx += dx2 * cosAdj; + +				for (; cnt; cnt--, a2 += dang, angle += dang) { +					if (px >= dto[othPath].base[p0 + 1].x) +						p0++; +					if (qx >= dto[secPath].base[q0 + 1].x) +						q0++; +					if ((p0 >= pn - 1) || (q0 >= qn - 1)) { +						break; +					} + +					coOrd e1, e2; +					PointOnCircle(&e1, center, r, a2); + +					q1 = dto[secPath].pts[q0]; +					q2 = dto[secPath].pts[q0 + 1]; +					FindIntersection(&e2, e1, a2, q1, FindAngle(q1, q2)); + +					dy = FindDistance(e1, e2); +					DIST_T tlen = tdlen + dy; + +					if (tlen > tdmax) { +						break; +					} + +					Translate(&pos, e1, a2, -dy / 2); +					DrawTie(d, pos, angle + xx->angle + 90, tlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +					// Assures that these ends are the last point drawn before break +					othEnd = e1; +					secEnd = e2; + +					cosAdj = fabs(cos(D2R(angle))); +					if (cnt > 1) { +						px += dx * cosAdj; +						qx += dx * cosAdj; +					} +					else { +						px += dx2 * cosAdj; +						qx += dx2 * cosAdj; +					} +				} +			} +		} +		else { +			cosAdj = fabs(cos(D2R(angle))); + +			p1 = dto[othPath].base[p0]; +			p2 = dto[othPath].base[p0 + 1]; +			len = FindDistance(p1, p2); +			cnt = (int)floor(len / tdspc + 0.6); +			if (cnt > 0) { +				DIST_T dx = len / cnt, dx2 = dx / 2; + +				for (; cnt; cnt--) { +					if (px >= dto[othPath].base[p0 + 1].x) +						p0++; +					if (qx >= dto[secPath].base[q0 + 1].x) +						q0++; +					if ((p0 >= pn - 1) || (q0 >= qn - 1)) { +						break; +					} + +					p1 = dto[othPath].base[p0]; +					p2 = dto[othPath].base[p0 + 1]; + +					if ((px >= dto[othPath].baseLast.x) +						|| (qx >= dto[secPath].baseLast.x)) { +						break; +					} + +					dy1 = dto[secPath].base[q0].y + (qx - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +					dy2 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +					dy = dy1 - dy2; +					DIST_T tlen = tdlen + fabs(cosAdj * dy); +					if (tlen > tdmax) { +						break; +					} + +					q1 = dto[secPath].pts[q0]; +					q2 = dto[secPath].pts[q0 + 1]; +					a1 = FindAngle(q1, q2); +					DIST_T xlen = qx - dto[secPath].base[q0].x; +					Translate(&pos, q1, a1, xlen); +					secEnd = pos; + +					q1 = dto[othPath].pts[p0]; +					q2 = dto[othPath].pts[p0 + 1]; +					a1 = FindAngle(q1, q2); +					xlen = px - dto[othPath].base[p0].x; +					Translate(&pos, q1, a1, xlen); +					othEnd = pos; + +					Translate(&pos, pos, (a1 - 90.0), dy / 2); +					DrawTie(d, pos, a1, tlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +					cosAdj = fabs(cos(D2R(angle))); +					px += dx * cosAdj; +					qx += dx * cosAdj; +				} +			} +			else { +				break; +			} +		} +	} + +#ifdef DTO_DEBUG +	if (DTO_DEBUG == DTO_CURVED) { +		DrawFillCircle(d, othEnd, rdot, drawColorGreen); +		DrawFillCircle(d, secEnd, rdot, drawColorGreen); + +		DrawFillCircle(d, dto[othPath].pts[p0], rdot, drawColorBlue); +		DrawFillCircle(d, dto[secPath].pts[q0], rdot, drawColorBlue); +	} +#endif + +	// Draw remaining ties, if any +	p1 = othEnd; +	p2 = dto[othPath].ptsLast; +	a0 = FindAngle(p1, p2); +	len = FindDistance(p1, p2); +	if (len >= 2 * tdspc) { +		Translate(&p1, p1, a0, tdspc2); +		DrawStraightTies(d, scaleInx, p1, p2, color); +	} +	else if (len > tdspc2) {  +		Translate(&p2, p2, a0, -tdspc2); +		DrawTie(d, p2, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +	} + +	q1 = secEnd; +	q2 = dto[secPath].ptsLast; +	a0 = FindAngle(q1, q2); +	len = FindDistance(q1, q2); +	if (len >= 2 * tdspc) { +		Translate(&q1, q1, a0, tdspc2); +		DrawStraightTies(d, scaleInx, q1, q2, color); +	} +	else if (len > tdspc2) { +		Translate(&q2, q2, a0, -tdspc2); +		DrawTie(d, q2, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +	} +} + +/** +  * Draw Crossing and Slip Turnout Bridge and Ties - Uses the static dto and dtod structures. +  * +  * \param d The drawing object +  * \param scaleInx The layout/track scale index +  * \param color The tie color. If black the color is read from the global tieColor. +  */ +static void DrawXingTurnout( +	drawCmd_p d, +	SCALEINX_T scaleInx, +	BOOL_T omitTies, +	wDrawColor color) +{ +	tieData_p td; +	DIST_T len; +	coOrd pos; +	int cnt; +	ANGLE_T cAngle; + +	if (color == wDrawColorBlack) +		color = tieColor; + +	coOrd c1, c2, s1, s2, p1, p2, q1; +	int p0, q0; +	ANGLE_T a0, a1, a2; +	int strPath = dtod.strPath, str2Path = dtod.str2Path; + +	struct extraDataCompound_t* xx = dtod.xx; + +	DrawDtoInit(); + +	dto[strPath].angle = FindAngle(dto[strPath].pts[0], dto[strPath].ptsLast); +	dto[str2Path].angle = FindAngle(dto[str2Path].pts[0], dto[str2Path].ptsLast); + +	int othPath = strPath, secPath = str2Path; +	int toType = dtod.toType; + +	int i, j; +	switch (toType) { +	case DTO_XING: +	case DTO_XNG9: +		break; +	case DTO_SSLIP: +		for (i = 0; i < dtod.pathCnt; i++) { +			if (dto[i].type == 'L' || dto[i].type == 'R') { +				secPath = i; +				break; +			} +		} +		break; +	case DTO_DSLIP: +		for (i = 0; i < dtod.pathCnt; i++) { +			if (dto[i].type == 'L') { +				othPath = i; +			} +			else if (dto[i].type == 'R') { +				secPath = i; +			} +		} +		break; +	} + +	if(dtod.bridge) { +		DrawXingBridge(d,othPath,secPath); +	} +	// draw the points +#ifdef DTO_DEBUG +	if (DTO_DEBUG == DTO_XING) DrawDtoLayout(d, scaleInx); +#endif + +	if (omitTies) +		return; + +	td = GetScaleTieData(scaleInx); +	DIST_T tdlen = td->length, tdmax = 2.0 * tdlen; +	DIST_T tdspc = td->spacing, tdspc2 = tdspc / 2; + +	// Midpoint +	p1 = dto[strPath].pts[0]; +	a1 = dto[strPath].angle; + +	q1 = dto[str2Path].pts[0]; +	a2 = dto[str2Path].angle; + +	FindIntersection(&pos, p1, a1, q1, a2); +	dtod.midPt = pos; + +#ifdef DTO_DEBUG +	if(DTO_DEBUG == DTO_XING) +	{ +		double r = td->width / 2; +		DrawFillCircle(d,p1,r,drawColorPurple); +		DrawFillCircle(d,q1,r,drawColorPurple); +		DrawFillCircle(d,dtod.midPt,r,drawColorPurple); +	} +#endif + +	// Tie length adjust +	double dAngle = fabs(DifferenceBetweenAngles(a1, a2)); +	double magic = 1.0; + +	// Short circuit the complex code for this simple case +	if (toType == DTO_XNG9) { +		p1 = dto[strPath].pts[0]; +		p2 = dto[strPath].ptsLast; +		DrawStraightTies(d, scaleInx, p1, p2, color); + +		p1 = dto[str2Path].pts[0]; +		p2 = dto[str2Path].ptsLast; +		 +		// Omit the center ties +		magic = 1 / cos(D2R(90 - dAngle)); +		DIST_T tdadj = (tdlen / 2) * magic; +		DIST_T tdadj2 = tdspc2 * magic; + +		dAngle = (dAngle - 90) / 2; +		Translate(&pos, dtod.midPt, a2, -tdadj - tdadj2); +		DrawTie(d, pos, a2 - dAngle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +		Translate(&pos, dtod.midPt, a2, -tdadj - tdspc); +		DrawStraightTies(d, scaleInx, p1, pos, color); + +		Translate(&pos, dtod.midPt, a2, tdadj + tdadj2); +		DrawTie(d, pos, a2 - dAngle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +		Translate(&pos, dtod.midPt, a2, tdadj + tdspc); +		DrawStraightTies(d, scaleInx, pos, p2, color); +		return; +	} + +	// Straight vector for tie angle +	s1 = MidPtCoOrd(dto[strPath].base[0], dto[str2Path].base[0]); +	s2 = MidPtCoOrd(dto[strPath].baseLast, dto[str2Path].baseLast); + +	// Rotate base coordinates so that the tie line is aligned with x-axis and origin is at zero +	cAngle = FindAngle(s1, s2); +	for (i = 0; i < DTO_DIM; i++) +		for (j = 0; j < dto[i].n; j++) { +			dto[i].base[j].x -= s1.x; +			dto[i].base[j].y -= s1.y; +			Rotate(&dto[i].base[j], zero, (90.0 - cAngle)); +		} + +	for (i = 0; i < DTO_DIM; i++) { +		for (j = 0; j < dto[i].n - 1; j++) { +			dto[i].dy[j] = (dto[i].base[j + 1].y - dto[i].base[j].y) / (dto[i].base[j + 1].x - dto[i].base[j].x); +		} +		if (dto[i].type == 'S') +			dto[i].angle = FindAngle(dto[i].pts[0], dto[i].ptsLast); +	} + +	// Tie center line in drawing coordinates +	REORIGIN(c1, s1, xx->angle, xx->orig); +	REORIGIN(c2, s2, xx->angle, xx->orig); +	cAngle = FindAngle(c1, c2); + +	int pn = dto[othPath].n; +	int qn = dto[secPath].n; + +	// Tie length adjust +	magic = 1 / cos(0.5 * D2R(dAngle)); +	// Extra ties length adjust +	double magic2 =	1.0 / cos(0.5 * D2R(dAngle));  + +	// Draw right half +	len = FindDistance(dtod.midPt, c2); +	cnt = (int)floor(len / td->spacing + 0.5); +	if (cnt <= 0) +		return; + +	DIST_T dx = len / cnt; +	p0 = q0 = 0; +	DIST_T dx2 = dx / 2; +	DIST_T px = len + dx2; +	DIST_T lenx = 0; + +	while (p0 < pn && px > dto[othPath].base[p0 + 1].x) p0++; +	while (q0 < qn && px > dto[secPath].base[q0 + 1].x) q0++; +	while (p0 < pn && q0 < qn) { +		if (px > dto[othPath].base[p0 + 1].x) p0++; +		if (px > dto[secPath].base[q0 + 1].x) q0++; +		if (p0 >= pn || q0 >= qn) +			break; +		// Dont use baseLast, as base coOrds have been rotated +		if ((px + dx >= dto[othPath].base[pn - 1].x) +			|| (px + dx >= dto[secPath].base[qn - 1].x)) { +			break; +		} + +		DIST_T dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +		DIST_T dy2 = dto[secPath].base[q0].y + (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +		tdlen = (td->length + fabs(dy1) + fabs(dy2)) * magic; +		if(tdlen > tdmax) +		{ +			if(dAngle >= 30) +			{ +				DIST_T dy = (dy1 + dy2) / 2; +				Translate(&pos,dtod.midPt,cAngle,px - len); +				Translate(&pos,pos,(cAngle - 90.0),dy); +				DrawTie(d,pos,cAngle,tdlen - td->length * magic,td->width,color,tieDrawMode == TIEDRAWMODE_SOLID); +				lenx += dx2 * magic2; +			} +			break; +		} + +		DIST_T dy = (dy1 + dy2) / 2; +		Translate(&pos, dtod.midPt, cAngle, px - len); +		Translate(&pos, pos, (cAngle - 90.0), dy); +		DrawTie(d, pos, cAngle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +		px += dx; +		lenx += dx; +	} + +	p1 = dtod.midPt; +	p2 = dto[strPath].ptsLast; +	DIST_T lenr = FindDistance(p1, p2) - lenx * magic2; +	a0 = dto[strPath].angle; +	if (lenr > dx) { +		Translate(&pos, p2, a0, -lenr); +		DrawStraightTies(d, scaleInx, pos, p2, color); +	} +	else { +		Translate(&pos, p2, a0, -dx2); +		DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +	} + +	// p1 = dtod.midPt; +	p2 = dto[str2Path].ptsLast; +	lenr = FindDistance(p1, p2) - lenx * magic2; +	a0 = dto[str2Path].angle; +	if (lenr > dx) { +		Translate(&pos, p2, a0, -lenr); +		DrawStraightTies(d, scaleInx, pos, p2, color); +	} +	else { +		Translate(&pos, p2, a0, -dx2); +		DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +	} + +	// Draw left half +	// Change the straight path used +	if (dtod.toType == DTO_SSLIP) { +		othPath = str2Path; +	} + +	len = FindDistance(c1, dtod.midPt); +	cnt = (int)floor(len / td->spacing + 0.5); +	if (cnt <= 0) +		return; + +	p0 = q0 = 0; +	tdlen = td->length; + +	dx = len / cnt; +	dx2 = dx / 2; +	px = len - dx2; +	lenx = 0; + +	while (p0 < pn && px > dto[othPath].base[p0 + 1].x) p0++; +	while (q0 < qn && px > dto[secPath].base[q0 + 1].x) q0++; +	while (p0 >= 0 && q0 >= 0) { +		if (px < dto[othPath].base[p0].x) p0--; +		if (px < dto[secPath].base[q0].x) q0--; +		if (p0 < 0 || q0 < 0) +			break; + +		if ((px - dx < dto[othPath].base[0].x) +			|| (px - dx < dto[secPath].base[0].x)) { +			break; +		} + +		DIST_T dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +		DIST_T dy2 = dto[secPath].base[q0].y + (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +		tdlen = (td->length + fabs(dy1) + fabs(dy2)) * magic; +		if(tdlen > tdmax) +		{ +			if(dAngle >= 30) +			{ +				DIST_T dy = (dy1 + dy2) / 2; +				Translate(&pos,dtod.midPt,cAngle,px - len); +				Translate(&pos,pos,(cAngle - 90.0),dy); +				DrawTie(d,pos,cAngle,tdlen - td->length * magic,td->width,color,tieDrawMode == TIEDRAWMODE_SOLID); +				lenx += dx2 * magic2; +			} +			break; +		} + +		DIST_T dy = (dy1 + dy2) / 2; +		Translate(&pos, dtod.midPt, cAngle, px - len); +		Translate(&pos, pos, (cAngle - 90.0), dy); +		DrawTie(d, pos, cAngle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +		px -= dx; +		lenx += dx; +	} + +	p1 = dto[strPath].pts[0]; +	p2 = dtod.midPt; +	a0 = dto[strPath].angle; +	lenr = FindDistance(p1, p2) - lenx * magic2; +	if (lenr > dx) { +		Translate(&pos, p1, a0, lenr); +		DrawStraightTies(d, scaleInx, p1, pos, color); +	} +	else { +		Translate(&pos, p1, a0, dx2); +		DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +	} +	p1 = dto[str2Path].pts[0]; +	// p2 = dtod.midPt; +	a0 = dto[str2Path].angle; +	lenr = FindDistance(p1, p2) - lenx * magic2; +	if (lenr > dx) { +		Translate(&pos, p1, a0, lenr); +		DrawStraightTies(d, scaleInx, p1, pos, color); +	} +	else { +		Translate(&pos, p1, a0, dx2); +		DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +	} +} + +/** + * Draw Crossover (Two Origin) Turnout Bridge and Ties. Uses the static dto and dtod structures. + * + * \param d The drawing object + * \param scaleInx The layout/track scale index + * \param color The tie color. If black the color is read from the global tieColor. + */ +static void DrawCrossTurnout( +	drawCmd_p d, +	SCALEINX_T scaleInx, +	BOOL_T omitTies, +	wDrawColor color) +{ +	tieData_p td; +	DIST_T len, dx; +	coOrd pos; +	int cnt; +	ANGLE_T angle; + +	if (color == wDrawColorBlack) +		color = tieColor; + +	struct extraDataCompound_t* xx = dtod.xx; + +	DrawDtoInit(); + +	// draw the points +#ifdef DTO_DEBUG +	if (DTO_DEBUG == DTO_LCROSS) DrawDtoLayout(d, scaleInx); +#endif + +	int strPath = dtod.strPath, str2Path = dtod.str2Path; +	// Bad assumption +	int othPath = 2, secPath = 2; +	if (dtod.pathCnt == 4) secPath = 3; + +	dto[strPath].angle = FindAngle(dto[strPath].pts[0], dto[strPath].ptsLast); +	dto[str2Path].angle = FindAngle(dto[str2Path].pts[0], dto[str2Path].ptsLast); + +	if(dtod.bridge) { +		DrawCrossBridge(d,strPath,str2Path); +	} +	if (omitTies) +		return; + +	td = GetScaleTieData(scaleInx); + +	coOrd s1, s2, t1, t2, p1, p2, q1, q2; +	int s0, t0, p0, q0; + +	int sn = dto[strPath].n; +	int tn = dto[str2Path].n; +	int pn = dto[othPath].n; +	int qn = dto[secPath].n; + +	s1 = dto[strPath].pts[0]; +	s2 = dto[strPath].ptsLast; +	t1 = dto[str2Path].pts[0]; +	t2 = dto[str2Path].ptsLast; +	angle = dto[strPath].angle;  + +	p1 = dto[othPath].base[0]; +	p2 = dto[othPath].baseLast; +	q1 = dto[secPath].base[0]; +	q2 = dto[secPath].baseLast; + +	td = GetScaleTieData(scaleInx); +	len = FindDistance(s1, s2); +	angle = dto[strPath].angle; + +	cnt = (int)floor(len / td->spacing + 0.5); +	if (cnt > 0) { +		DIST_T px = 0; +		DIST_T dy, dy1, dy2; +		int cflag = 0; +		dy = dto[str2Path].base[0].y - dto[strPath].base[0].y; + +		dx = len / cnt; +		s0 = t0 = p0 = q0 = 0; +		DIST_T tdlen = td->length; +		DIST_T dlenx = dx / 2; + +		DIST_T px1 = len / 2 - dlenx * 5, +			px2 = len / 2 + dlenx * 4; + +		for (px = dlenx; cnt; cnt--, px += dx) { +			if (px >= dto[strPath].base[s0 + 1].x) s0++; +			if (px >= dto[str2Path].base[t0 + 1].x) t0++; +			if (px >= dto[othPath].base[p0 + 1].x) p0++; +			if (px >= dto[secPath].base[q0 + 1].x) q0++; +			if (s0 >= sn || t0 >= tn || p0 >= pn || q0 >= qn) +				break; + +			if ((px >= dto[strPath].baseLast.x) +				|| (px >= dto[str2Path].baseLast.x)) { +				break; +			} + +			dy1 = dy2 = 0; +			cflag = 0; +			if (px < px1) { +				switch (dtod.toType) { +				case DTO_DCROSS: +					dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +					dy2 = dy - dto[secPath].base[q0].y - (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +					break; +				case DTO_LCROSS: +					dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +					dy2 = 0; +					break; +				case DTO_RCROSS: +					dy1 = 0; +					dy2 = dy - dto[secPath].base[q0].y - (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +					break; +				default: +					break; +				} +			} +			else if (px < px2) { +				dy1 = (dto[str2Path].base[s0].y - dto[strPath].base[t0].y); +				dy2 = 0; +				cflag = 1; +			} +			else { +				switch (dtod.toType) { +				case DTO_DCROSS: +					dy1 = dto[secPath].base[q0].y + (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +					dy2 = dy - dto[othPath].base[p0].y - (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +					break; +				case DTO_LCROSS: +					dy1 = 0; +					dy2 = dy - dto[secPath].base[q0].y - (px - dto[secPath].base[q0].x) * dto[secPath].dy[q0]; +					break; +				case DTO_RCROSS: +					dy1 = dto[othPath].base[p0].y + (px - dto[othPath].base[p0].x) * dto[othPath].dy[p0]; +					dy2 = 0; +					break; +				default: +					break; +				} +			} + +			if (fabs(dy1) + fabs(dy2) >= dy) { +				dy1 = (dto[str2Path].base[s0].y - dto[strPath].base[t0].y); +				dy2 = 0; +				cflag = 1; +			} + +			tdlen = td->length + fabs(dy1); +			Translate(&pos, s1, angle, px); +			Translate(&pos, pos, (angle - 90.0), dy1 / 2); +			DrawTie(d, pos, angle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); + +			if (!cflag) { +				tdlen = td->length + fabs(dy2); +				Translate(&pos, t1, angle, px); +				Translate(&pos, pos, (angle - 90.0), -dy2 / 2); +				DrawTie(d, pos, angle, tdlen, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +			} +		} +		return; + +		// Draw remaining ties, if any +		// Currently by definition, there won't be any +		/* +		if (px + dx < dto[strPath].baseLast.x) { +			p1 = dto[strPath].pts[p0]; +			p2 = dto[strPath].ptsLast; +			angle = FindAngle(p1, p2); +			a0 = FindAngle(dto[strPath].base[p0], dto[strPath].baseLast); +			DIST_T lenr = (dto[strPath].baseLast.x - px + dlenx) / cos(D2R(90.0 - a0)); +			Translate(&p1, p2, angle, -lenr); +			DrawStraightTies(d, scaleInx, p1, p2, color); +		} +		else { +			p1 = dto[strPath].pts[pn - 2]; +			a0 = FindAngle(p1, p2); +			Translate(&pos, p2, a0, -dx / 2); +			DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +		} + +		if (px + dx < dto[str2Path].baseLast.x) { +			q1 = dto[str2Path].pts[q0]; +			q2 = dto[str2Path].ptsLast; +			angle = FindAngle(q1, q2); +			a0 = FindAngle(dto[str2Path].base[q0], dto[str2Path].baseLast); +			DIST_T lenr = (dto[str2Path].baseLast.x - px + dlenx) / cos(D2R(90.0 - a0)); +			Translate(&q1, q2, angle, -lenr); +			DrawStraightTies(d, scaleInx, q1, q2, color); +		} +		else { +			q1 = dto[str2Path].pts[qn - 2]; +			a0 = FindAngle(q1, q2); +			Translate(&pos, q2, a0, -dx / 2); +			DrawTie(d, pos, a0, td->length, td->width, color, tieDrawMode == TIEDRAWMODE_SOLID); +		} +		*/ +	} +} + +/** +  * Draw all turnout components: ties, rail, roadbed, etc. The turnout is checked +  * to see if the enhanced methods can be used. If so the ties are drawn and the +  * TB_NOTIES bit is set so that the rails and such are drawn on top of the ties. +  * That bit is restored to its previous state before return. +  * +  * \param trk Pointer to the track object +  * \param d The drawing object +  * \param color The turnout color. +  */  static void DrawTurnout( -		track_p trk, -		drawCmd_p d, -		wDrawColor color ) +	track_p trk, +	drawCmd_p d, +	wDrawColor color)  { -	struct extraData *xx = GetTrkExtraData(trk); +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	wIndex_t i;  	long widthOptions = 0; -	DIST_T scale2rail; +	SCALEINX_T scaleInx = GetTrkScale(trk); +	DIST_T scale2rail = (d->options & DC_PRINT) ? (twoRailScale * 2 + 1) : twoRailScale; +	BOOL_T omitTies = !DoDrawTies(d, trk) || (d->scale > scale2rail) || ((d->options & DC_SIMPLE) != 0); // || (scaleInx == 0); + +	widthOptions = DTS_LEFT | DTS_RIGHT; + +	int noTies = GetTrkNoTies(trk); +	int bridge = GetTrkBridge(trk); + +	long skip = 0; +	/** @prefs [Preference] NormalTurnoutDraw=1 to skip enhanced drawing methods */ +	wPrefGetInteger("Preference", "NormalTurnoutDraw", (long *) &skip, 0); + +	int pathCnt = (skip == 0 ? GetTurnoutPaths(trk, xx) : 0); + +	if ( (pathCnt > 1) && (pathCnt <= DTO_DIM) +		&& (trk->endCnt <= 4) +		&& (xx->special == TOnormal) ) +		{ + +		dtod.bridge = bridge;  + +		int strPath = -1; +		GetTurnoutType(); + +		if (dtod.toType != DTO_INVALID) { + +			switch (dtod.toType) +			{ +			case DTO_NORMAL: +			case DTO_THREE: +			case DTO_WYE: +				DrawNormalTurnout(d, scaleInx, omitTies, color); +				break; +			case DTO_CURVED: +				DrawCurvedTurnout(d, scaleInx, omitTies, color); +				break; +			case DTO_XING: +			case DTO_XNG9: +			case DTO_SSLIP: +			case DTO_DSLIP: +				DrawXingTurnout(d, scaleInx, omitTies, color); +				break; +			case DTO_LCROSS: +			case DTO_RCROSS: +			case DTO_DCROSS: +				DrawCrossTurnout(d, scaleInx, omitTies, color); +				break; +			default: +				break; +			} +			SetTrkNoTies(trk, 1);  +            ClrTrkBits(trk, TB_BRIDGE);  +		} +	} -	widthOptions = DTS_LEFT|DTS_RIGHT; -     -	scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale; -	DrawSegsO( d, trk, xx->orig, xx->angle, xx->segs, xx->segCnt, GetTrkGauge(trk), color, widthOptions | DTS_NOCENTER );  // no curve center for turnouts +	// Begin standard DrawTurnout code to draw rails or centerline +	DrawSegsO(d, trk, xx->orig, xx->angle, xx->segs, xx->segCnt, GetTrkGauge(trk), color, widthOptions | DTS_NOCENTER);  // no curve center for turnouts -	for (i=0; i<GetTrkEndPtCnt(trk); i++) { -		DrawEndPt( d, trk, i, color ); +	for (i = 0; i < GetTrkEndPtCnt(trk); i++) { +		DrawEndPt(d, trk, i, color);  	} -	if ( (d->options & DC_SIMPLE) == 0 && -		 (labelWhen == 2 || (labelWhen == 1 && (d->options&DC_PRINT))) && -		 labelScale >= d->scale && -		 ( GetTrkBits( trk ) & TB_HIDEDESC ) == 0 ) { -		DrawCompoundDescription( trk, d, color ); +	if ((d->options & DC_SIMPLE) == 0 && +		(labelWhen == 2 || (labelWhen == 1 && (d->options & DC_PRINT))) && +		labelScale >= d->scale && +		(GetTrkBits(trk) & TB_HIDEDESC) == 0) { +		DrawCompoundDescription(trk, d, color);  		if (!xx->handlaid) -			LabelLengths( d, trk, color ); +			LabelLengths(d, trk, color);  	} -	if ( roadbedWidth > GetTrkGauge(trk) && -		( ((d->options&DC_PRINT) && d->scale <= (twoRailScale*2+1)/2.0) || -		  (roadbedOnScreen && d->scale <= twoRailScale) ) ) -		DrawTurnoutRoadbed( d, color, xx->orig, xx->angle, xx->segs, xx->segCnt ); - +	if (roadbedWidth > GetTrkGauge(trk) && +		(((d->options & DC_PRINT) && d->scale <= (twoRailScale * 2 + 1) / 2.0) || +			(roadbedOnScreen && d->scale <= twoRailScale))) +		DrawTurnoutRoadbed(d, color, xx->orig, xx->angle, xx->segs, xx->segCnt); + +	// Restore these settings +	if (noTies == 0) ClrTrkBits(trk, TB_NOTIES); +	if (bridge) SetTrkBits(trk, TB_BRIDGE);  }  static BOOL_T ReadTurnout( -		char * line ) +	char* line)  { -	if ( !ReadCompound( line+8, T_TURNOUT ) ) +	if (!ReadCompound(line + 8, T_TURNOUT))  		return FALSE;  	return TRUE;  }  static ANGLE_T GetAngleTurnout( -		track_p trk, -		coOrd pos, -		EPINX_T *ep0, -		EPINX_T *ep1 ) +	track_p trk, +	coOrd pos, +	EPINX_T* ep0, +	EPINX_T* ep1)  { -	struct extraData * xx = GetTrkExtraData(trk); +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	wIndex_t segCnt, segInx;  	ANGLE_T angle; -	if ( ep0 && ep1 ) -		*ep0 = *ep1 = PickEndPoint( pos, trk ); -	coOrd pos0=pos; -	double dd = 10000.0; +	if (ep0 && ep1) +		*ep0 = *ep1 = PickEndPoint(pos, trk); +	coOrd pos0 = pos; +	double dd = DIST_INF;  	int found = -1;  	//Cope with tracks not being first -	for (segCnt =0; segCnt<xx->segCnt ; segCnt++ ) { +	for (segCnt = 0; segCnt < xx->segCnt; segCnt++) {  		if (IsSegTrack(&xx->segs[segCnt])) { -			double d = DistanceSegs( xx->orig, xx->angle, 1, &xx->segs[segCnt], &pos0, NULL ); -			if (d<dd) { +			double d = DistanceSegs(xx->orig, xx->angle, 1, &xx->segs[segCnt], &pos0, NULL); +			if (d < dd) {  				dd = d;  				found = segCnt;  			}  		}  		pos0 = pos;  	} -	if (found>=0) { +	if (found >= 0) {  		pos.x -= xx->orig.x;  		pos.y -= xx->orig.y; -		Rotate( &pos, zero, -xx->angle ); -		angle = GetAngleSegs( 1, &xx->segs[found], &pos, &segInx, NULL, NULL, NULL, NULL ); -		return NormalizeAngle( angle+xx->angle ); -	} else return 0.0; +		Rotate(&pos, zero, -xx->angle); +		angle = GetAngleSegs(1, &xx->segs[found], &pos, &segInx, NULL, NULL, NULL, NULL); +		return NormalizeAngle(angle + xx->angle); +	} +	else return 0.0;  }  static BOOL_T SplitTurnoutCheckPath( -		wIndex_t segInxEnd, -		PATHPTR_T pp1, -		int dir1, -		PATHPTR_T pp2, -		int dir2, -		trkSeg_p segs, -		coOrd epPos ) +	wIndex_t segInxEnd, +	PATHPTR_T pp1, +	int dir1, +	PATHPTR_T pp2, +	int dir2, +	trkSeg_p segs, +	coOrd epPos)  {  	wIndex_t segInx1, segInx2;  	EPINX_T segEP;  	coOrd pos;  	DIST_T dist; -	GetSegInxEP( pp2[0], &segInx2, &segEP ); -	if ( dir2 < 0 ) segEP = 1-segEP; -	pos = GetSegEndPt( &segs[segInx2], segEP, FALSE, NULL ); -	dist = FindDistance( pos, epPos ); -	if ( dist>connectDistance ) +	GetSegInxEP(pp2[0], &segInx2, &segEP); +	if (dir2 < 0) segEP = 1 - segEP; +	pos = GetSegEndPt(&segs[segInx2], segEP, FALSE, NULL); +	dist = FindDistance(pos, epPos); +	if (dist > connectDistance)  		return TRUE; -	while ( pp2[0] ) { -		GetSegInxEP( pp1[0], &segInx1, &segEP ); -		GetSegInxEP( pp2[0], &segInx2, &segEP ); -		if ( segInx1 != segInx2 ) +	while (pp2[0]) { +		GetSegInxEP(pp1[0], &segInx1, &segEP); +		GetSegInxEP(pp2[0], &segInx2, &segEP); +		if (segInx1 != segInx2)  			break; -		if ( segInxEnd == segInx2 ) +		if (segInxEnd == segInx2)  			return TRUE;  		pp1 += dir1;  		pp2 += dir2; @@ -882,21 +2763,21 @@ static BOOL_T SplitTurnoutCheckPath(  static BOOL_T SplitTurnoutCheckEP( -		wIndex_t segInx0, -		coOrd epPos, -		PATHPTR_T pp1, -		int dir1, -		PATHPTR_T pp, -		trkSeg_p segs ) -{ -	while ( pp[0] ) { -		pp += strlen((char *)pp)+1; -		while ( pp[0] ) { -			if (!SplitTurnoutCheckPath( segInx0, pp1, dir1, pp, 1, segs, epPos )) +	wIndex_t segInx0, +	coOrd epPos, +	PATHPTR_T pp1, +	int dir1, +	PATHPTR_T pp, +	trkSeg_p segs) +{ +	while (pp[0]) { +		pp += strlen((char*)pp) + 1; +		while (pp[0]) { +			if (!SplitTurnoutCheckPath(segInx0, pp1, dir1, pp, 1, segs, epPos))  				return FALSE; -			while ( pp[0] ) +			while (pp[0])  				pp++; -			if (!SplitTurnoutCheckPath( segInx0, pp1, dir1, pp-1, -1, segs, epPos )) +			if (!SplitTurnoutCheckPath(segInx0, pp1, dir1, pp - 1, -1, segs, epPos))  				return FALSE;  			pp++;  		} @@ -907,11 +2788,11 @@ static BOOL_T SplitTurnoutCheckEP(  EXPORT EPINX_T TurnoutPickEndPt( -		coOrd epPos, -		track_p trk ) +	coOrd epPos, +	track_p trk)  { -	struct extraData * xx = GetTrkExtraData(trk); -	wIndex_t segCnt, segInx, segInx0; +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t); +	wIndex_t segInx, segInx0;  	EPINX_T segEP;  	PATHPTR_T cp, cq, pps[2];  	coOrd pos; @@ -920,38 +2801,37 @@ EXPORT EPINX_T TurnoutPickEndPt(  	EPINX_T ep, epCnt, eps[2];  	BOOL_T unique_eps[2]; -	for ( segCnt=0; segCnt<xx->segCnt && IsSegTrack(&xx->segs[segCnt]); segCnt++ ); -	DistanceSegs( xx->orig, xx->angle, segCnt, xx->segs, &epPos, &segInx0 ); -	Rotate( &epPos, xx->orig, xx->angle ); +	DistanceSegs(xx->orig, xx->angle, xx->segCnt, xx->segs, &epPos, &segInx0); +	Rotate(&epPos, xx->orig, xx->angle);  	epPos.x -= xx->orig.x;  	epPos.y -= xx->orig.y;  	epCnt = GetTrkEndPtCnt(trk); -	cp = xx->paths; +	cp = GetPaths(trk);  	eps[0] = eps[1] = -1;  	unique_eps[0] = unique_eps[1] = TRUE; -	while ( cp[0] ) { -		cp += strlen((char *)cp)+1; -		while ( cp[0] ) { -			while ( cp[0] ) { -				GetSegInxEP( cp[0], &segInx, &segEP ); -				if ( segInx == segInx0 ) { -					for ( dir=0; dir<2; dir++ ) { -						for ( cq=cp; cq[dir?-1:1]; cq += (dir?-1:1) ); -						GetSegInxEP( cq[0], &segInx, &segEP ); -						if ( dir==0 ) segEP = 1-segEP; -						pos = GetSegEndPt( &xx->segs[segInx], segEP, FALSE, NULL ); -						dist = FindDistance( pos, epPos ); -						if ( eps[dir] < 0 || dist < dists[dir] ) { +	while (cp[0]) { +		cp += strlen((char*)cp) + 1; +		while (cp[0]) { +			while (cp[0]) { +				GetSegInxEP(cp[0], &segInx, &segEP); +				if (segInx == segInx0) { +					for (dir = 0; dir < 2; dir++) { +						for (cq = cp; cq[dir ? -1 : 1]; cq += (dir ? -1 : 1)); +						GetSegInxEP(cq[0], &segInx, &segEP); +						if (dir == 0) segEP = 1 - segEP; +						pos = GetSegEndPt(&xx->segs[segInx], segEP, FALSE, NULL); +						dist = FindDistance(pos, epPos); +						if (eps[dir] < 0 || dist < dists[dir]) {  							dists[dir] = dist;  							pos.x += xx->orig.x;  							pos.y += xx->orig.y; -							Rotate( &pos, xx->orig, xx->angle ); -							for ( ep=0; ep<epCnt; ep++ ) { -								if ( FindDistance( pos, GetTrkEndPos(trk,ep) ) < connectDistance ) +							Rotate(&pos, xx->orig, xx->angle); +							for (ep = 0; ep < epCnt; ep++) { +								if (FindDistance(pos, GetTrkEndPos(trk, ep)) < connectDistance)  									break;  							} -							if ( ep<epCnt ) { -								if ( eps[dir] >= 0 && eps[dir] != ep ) +							if (ep < epCnt) { +								if (eps[dir] >= 0 && eps[dir] != ep)  									unique_eps[dir] = FALSE;  								eps[dir] = ep;  								dists[dir] = dist; @@ -967,27 +2847,27 @@ EXPORT EPINX_T TurnoutPickEndPt(  		cp++;  	} -	for ( dir=0; dir<2; dir++ ) { -		if ( unique_eps[dir] && eps[dir] >= 0 ) { -			GetSegInxEP( pps[dir][0], &segInx, &segEP ); -			if ( dir == 0 ) segEP = 1-segEP; -			epPos = GetSegEndPt( &xx->segs[segInx], segEP, FALSE, NULL ); -			if ( ! SplitTurnoutCheckEP( segInx0, epPos, pps[dir], dir?1:-1, xx->paths, xx->segs ) ) -				unique_eps[dir] = FALSE;  +	for (dir = 0; dir < 2; dir++) { +		if (unique_eps[dir] && eps[dir] >= 0) { +			GetSegInxEP(pps[dir][0], &segInx, &segEP); +			if (dir == 0) segEP = 1 - segEP; +			epPos = GetSegEndPt(&xx->segs[segInx], segEP, FALSE, NULL); +			if (!SplitTurnoutCheckEP(segInx0, epPos, pps[dir], dir ? 1 : -1, GetPaths(trk), xx->segs)) +				unique_eps[dir] = FALSE;  		}  	} -	if ( unique_eps[0] == unique_eps[1] ) { -		if ( eps[0] >= 0 && eps[1] >= 0 ) -			return ( dists[0] < dists[1] ) ? eps[0] : eps[1] ; +	if (unique_eps[0] == unique_eps[1]) { +		if (eps[0] >= 0 && eps[1] >= 0) +			return (dists[0] < dists[1]) ? eps[0] : eps[1];  	} -	if ( unique_eps[0] && eps[0] >= 0 ) +	if (unique_eps[0] && eps[0] >= 0)  		return eps[0]; -	if ( unique_eps[1] && eps[1] >= 0 ) +	if (unique_eps[1] && eps[1] >= 0)  		return eps[1]; -	if ( eps[0] >= 0 && eps[1] >= 0 ) -		return ( dists[0] < dists[1] ) ? eps[0] : eps[1] ; -	return eps[0] >= 0 ? eps[0] : eps[1] ; +	if (eps[0] >= 0 && eps[1] >= 0) +		return (dists[0] < dists[1]) ? eps[0] : eps[1]; +	return eps[0] >= 0 ? eps[0] : eps[1];  } @@ -996,11 +2876,11 @@ static PATHPTR_T splitTurnoutRoot;  static int splitTurnoutDir;  static void SplitTurnoutCheckEndPt( -		PATHPTR_T path, -		int dir, -		trkSeg_p segs, -		coOrd epPos, -		coOrd splitPos ) +	PATHPTR_T path, +	int dir, +	trkSeg_p segs, +	coOrd epPos, +	coOrd splitPos)  {  	PATHPTR_T path0;  	wIndex_t segInx; @@ -1009,21 +2889,21 @@ static void SplitTurnoutCheckEndPt(  	DIST_T dist, minDist;  	path0 = path; -	GetSegInxEP( path[0], &segInx, &segEP ); -	if ( dir < 0 ) segEP = 1-segEP; -	pos = GetSegEndPt( &segs[segInx], segEP, FALSE, NULL ); -	dist = FindDistance( pos, epPos ); -	LOG( log_splitturnout, 1, ( "  SPTChkEp P%d DIR:%d SegInx:%d SegEP:%d POS[%0.3f %0.3f] DIST:%0.3f\n", *path, dir, segInx, segEP, pos.x, pos.y, dist ) ); -	if ( dist>connectDistance ) +	GetSegInxEP(path[0], &segInx, &segEP); +	if (dir < 0) segEP = 1 - segEP; +	pos = GetSegEndPt(&segs[segInx], segEP, FALSE, NULL); +	dist = FindDistance(pos, epPos); +	LOG(log_splitturnout, 1, ("  SPTChkEp P%d DIR:%d SegInx:%d SegEP:%d POS[%0.3f %0.3f] DIST:%0.3f\n", *path, dir, segInx, segEP, pos.x, pos.y, dist)); +	if (dist > connectDistance)  		return;  	minDist = trackGauge; -	while ( path[0] ) { -		GetSegInxEP( path[0], &segInx, &segEP ); -		if ( dir < 0 ) segEP = 1-segEP; +	while (path[0]) { +		GetSegInxEP(path[0], &segInx, &segEP); +		if (dir < 0) segEP = 1 - segEP;  		pos = splitPos; -		dist = DistanceSegs( zero, 0.0, 1, &segs[segInx], &pos, NULL ); -		LOG( log_splitturnout, 1, ( "  - P:%d SegInx:%d SegEP:%d DIST:%0.3f\n", path[0], segInx, segEP, dist ) ); -		if ( dist < minDist ) { +		dist = DistanceSegs(zero, 0.0, 1, &segs[segInx], &pos, NULL); +		LOG(log_splitturnout, 1, ("  - P:%d SegInx:%d SegEP:%d DIST:%0.3f\n", path[0], segInx, segEP, dist)); +		if (dist < minDist) {  			minDist = dist;  			splitTurnoutPath = path;  			splitTurnoutDir = -dir; @@ -1034,26 +2914,26 @@ static void SplitTurnoutCheckEndPt(  }  EXPORT BOOL_T SplitTurnoutCheck( -			track_p trk, -			coOrd pos, -			EPINX_T ep, -			track_p *leftover, -			EPINX_T * ep0, -			EPINX_T * ep1, -			BOOL_T check, -			coOrd * outPos, -			ANGLE_T * outAngle ) -	{ -	struct extraData * xx = GetTrkExtraData( trk ); +	track_p trk, +	coOrd pos, +	EPINX_T ep, +	track_p* leftover, +	EPINX_T* ep0, +	EPINX_T* ep1, +	BOOL_T check, +	coOrd* outPos, +	ANGLE_T* outAngle) +{ +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	wIndex_t segInx0, segInx, segCnt; -	EPINX_T segEP, epCnt, ep2=0, epN; +	EPINX_T segEP, epCnt, ep2 = 0, epN;  	PATHPTR_T pp, pp1, pp2;  	unsigned char c; -	char * cp; +	char* cp;  	int negCnt, posCnt, pathCnt, dir;  	segProcData_t segProcDataSplit;  	segProcData_t segProcDataNewTrack; -	track_p trk2=NULL; +	track_p trk2 = NULL;  	static dynArr_t segIndexMap_da;  #define segIndexMap(N) DYNARR_N( int, segIndexMap_da, N )  	static dynArr_t newPath_da; @@ -1064,9 +2944,9 @@ EXPORT BOOL_T SplitTurnoutCheck(  	int s0, s1;  	trkSeg_t newSeg; -	if ( (MyGetKeyState()&WKEY_SHIFT) == 0 ) { +	if ((MyGetKeyState() & WKEY_SHIFT) == 0) {  		if (!check) -			ErrorMessage( MSG_CANT_SPLIT_TRK, _("Turnout") ); +			ErrorMessage(MSG_CANT_SPLIT_TRK, _("Turnout"));  		return FALSE;  	} @@ -1074,62 +2954,62 @@ EXPORT BOOL_T SplitTurnoutCheck(  	 * 1. Find segment on path that ends at 'ep'  	 */  	epCnt = GetTrkEndPtCnt(trk); -	epPos = GetTrkEndPos( trk, ep ); -	for ( segCnt=0; segCnt<xx->segCnt && IsSegTrack(&xx->segs[segCnt]); segCnt++ ); -	Rotate( &pos, xx->orig, -xx->angle ); +	epPos = GetTrkEndPos(trk, ep); +	for (segCnt = 0; segCnt < xx->segCnt && IsSegTrack(&xx->segs[segCnt]); segCnt++); +	Rotate(&pos, xx->orig, -xx->angle);  	pos.x -= xx->orig.x;  	pos.y -= xx->orig.y; -	Rotate( &epPos, xx->orig, -xx->angle ); +	Rotate(&epPos, xx->orig, -xx->angle);  	epPos.x -= xx->orig.x;  	epPos.y -= xx->orig.y;  	splitTurnoutPath = NULL; -	pp = xx->paths; -	LOG( log_splitturnout, 1, ( "SplitTurnoutCheck T%d POS[%0.3f %0.3f] EP:%d CHK:%d EPPOS[%0.3f %0.3f]\n", trk?trk->index:0, pos.x, pos.y, ep, check, epPos.x, epPos.y ) ); -	while ( pp[0] ) { -		pp += strlen((char *)pp)+1; -		while ( pp[0] ) { -			SplitTurnoutCheckEndPt( pp, 1, xx->segs, epPos, pos ); -			if ( splitTurnoutPath != NULL ) +	pp = GetPaths(trk); +	LOG(log_splitturnout, 1, ("SplitTurnoutCheck T%d POS[%0.3f %0.3f] EP:%d CHK:%d EPPOS[%0.3f %0.3f]\n", trk ? trk->index : 0, pos.x, pos.y, ep, check, epPos.x, epPos.y)); +	while (pp[0]) { +		pp += strlen((char*)pp) + 1; +		while (pp[0]) { +			SplitTurnoutCheckEndPt(pp, 1, xx->segs, epPos, pos); +			if (splitTurnoutPath != NULL)  				goto foundSeg; -			while ( pp[0] ) +			while (pp[0])  				pp++; -			SplitTurnoutCheckEndPt( pp-1, -1, xx->segs, epPos, pos ); -			if ( splitTurnoutPath != NULL ) +			SplitTurnoutCheckEndPt(pp - 1, -1, xx->segs, epPos, pos); +			if (splitTurnoutPath != NULL)  				goto foundSeg;  			pp++;  		}  		pp++;  	}  	if (!check) -		ErrorMessage( _("splitTurnout: can't find segment") ); +		ErrorMessage(_("splitTurnout: can't find segment"));  	return FALSE;  foundSeg:  	/*  	 * 2a. Check that all other paths thru found segment are the same  	 */ -	GetSegInxEP( splitTurnoutPath[0], &segInx0, &segEP ); -	LOG( log_splitturnout, 1, (" Found Seg: %d SEG:%d EP:%d\n", *splitTurnoutPath, segInx0, segEP ) ); -	pp = xx->paths; +	GetSegInxEP(splitTurnoutPath[0], &segInx0, &segEP); +	LOG(log_splitturnout, 1, (" Found Seg: %d SEG:%d EP:%d\n", *splitTurnoutPath, segInx0, segEP)); +	pp = GetPaths(trk);  	pathCnt = 0; -	while ( pp[0] ) { -		pp += strlen((char *)pp)+1; -		while ( pp[0] ) { -			while ( pp[0] ) { -				GetSegInxEP( pp[0], &segInx, &segEP ); -				if ( segInx == segInx0 ) { +	while (pp[0]) { +		pp += strlen((char*)pp) + 1; +		while (pp[0]) { +			while (pp[0]) { +				GetSegInxEP(pp[0], &segInx, &segEP); +				if (segInx == segInx0) {  					pp1 = splitTurnoutPath;  					pp2 = pp; -					dir = (pp2[0]>0?1:-1) * splitTurnoutDir; -					while ( pp1[0] && pp2[0] ) { -						if ( splitTurnoutDir * pp1[0] != dir * pp2[0] ) +					dir = (pp2[0] > 0 ? 1 : -1) * splitTurnoutDir; +					while (pp1[0] && pp2[0]) { +						if (splitTurnoutDir * pp1[0] != dir * pp2[0])  							break;  						pp1 += splitTurnoutDir;  						pp2 += dir;  					} -					if ( pp1[0]!='\0' || pp2[0]!='\0' ) { +					if (pp1[0] != '\0' || pp2[0] != '\0') {  						if (!check) -							ErrorMessage( MSG_SPLIT_POS_BTW_MERGEPTS ); +							ErrorMessage(MSG_SPLIT_POS_BTW_MERGEPTS);  						return FALSE;  					}  				} @@ -1143,20 +3023,20 @@ foundSeg:  	/*  	 * 2b. Check that all paths from ep pass thru segInx0  	 */ -	if ( !SplitTurnoutCheckEP( segInx0, epPos, splitTurnoutRoot, -splitTurnoutDir, xx->paths, xx->segs ) ) { +	if (!SplitTurnoutCheckEP(segInx0, epPos, splitTurnoutRoot, -splitTurnoutDir, GetPaths(trk), xx->segs)) {  		if (!check) -			ErrorMessage( MSG_SPLIT_PATH_NOT_UNIQUE ); +			ErrorMessage(MSG_SPLIT_PATH_NOT_UNIQUE);  		return FALSE;  	}  	if (check) {  		segProcDataSplit.getAngle.pos = pos; -		SegProc( SEGPROC_GETANGLE, xx->segs+segInx0, &segProcDataSplit ); -		*outAngle = NormalizeAngle(segProcDataSplit.getAngle.angle+xx->angle); +		SegProc(SEGPROC_GETANGLE, xx->segs + segInx0, &segProcDataSplit); +		*outAngle = NormalizeAngle(segProcDataSplit.getAngle.angle + xx->angle);  		*outPos = segProcDataSplit.getAngle.pos;  		(*outPos).x += xx->orig.x;  		(*outPos).y += xx->orig.y; -		Rotate( outPos, xx->orig, xx->angle ); +		Rotate(outPos, xx->orig, xx->angle);  		return TRUE;  	} @@ -1165,53 +3045,56 @@ foundSeg:  	 */  	segProcDataSplit.split.pos = pos;  	s0 = (splitTurnoutPath[0] > 0) != (splitTurnoutDir > 0); -	s1 = 1-s0; -	SegProc( SEGPROC_SPLIT, xx->segs+segInx0, &segProcDataSplit ); -	if ( segProcDataSplit.split.length[s1] <= minLength ) { -		if ( splitTurnoutPath[splitTurnoutDir] == '\0' ) +	s1 = 1 - s0; +	SegProc(SEGPROC_SPLIT, xx->segs + segInx0, &segProcDataSplit); +	if (segProcDataSplit.split.length[s1] <= minLength) { +		if (splitTurnoutPath[splitTurnoutDir] == '\0')  			return FALSE;  		segProcDataSplit.split.length[s0] += segProcDataSplit.split.length[s1];  		segProcDataSplit.split.length[s1] = 0;  		segProcDataSplit.split.newSeg[s0] = xx->segs[segInx0]; -		epPos = GetSegEndPt( &segProcDataSplit.split.newSeg[s0], s1, FALSE, &epAngle ); -	} else if ( segProcDataSplit.split.length[s0] <= minLength ) { +		epPos = GetSegEndPt(&segProcDataSplit.split.newSeg[s0], s1, FALSE, &epAngle); +	} +	else if (segProcDataSplit.split.length[s0] <= minLength) {  		segProcDataSplit.split.length[s1] += segProcDataSplit.split.length[s0];  		segProcDataSplit.split.length[s0] = 0;  		segProcDataSplit.split.newSeg[s1] = xx->segs[segInx0]; -		epPos = GetSegEndPt( &segProcDataSplit.split.newSeg[s1], s0, FALSE, &epAngle ); +		epPos = GetSegEndPt(&segProcDataSplit.split.newSeg[s1], s0, FALSE, &epAngle);  		epAngle += 180.0; -	} else { -		epPos = GetSegEndPt( &segProcDataSplit.split.newSeg[s1], s0, FALSE, &epAngle ); +	} +	else { +		epPos = GetSegEndPt(&segProcDataSplit.split.newSeg[s1], s0, FALSE, &epAngle);  		epAngle += 180.0;  	}  	/*  	 * 4. Map the old segments to new  	 */ -	DYNARR_SET( int, segIndexMap_da, xx->segCnt ); -	for ( segInx=0; segInx<xx->segCnt; segInx++ ) -		segIndexMap(segInx) = segInx+1; +	DYNARR_SET(int, segIndexMap_da, xx->segCnt); +	for (segInx = 0; segInx < xx->segCnt; segInx++) +		segIndexMap(segInx) = segInx + 1;  	pp = splitTurnoutPath; -	if ( segProcDataSplit.split.length[s0] > minLength ) +	if (segProcDataSplit.split.length[s0] > minLength)  		pp += splitTurnoutDir;  	negCnt = 0; -	while ( *pp ) { -		GetSegInxEP( *pp, &segInx, &segEP ); -		segIndexMap(segInx) = - segIndexMap(segInx); +	while (*pp) { +		GetSegInxEP(*pp, &segInx, &segEP); +		segIndexMap(segInx) = -segIndexMap(segInx);  		negCnt++;  		pp += splitTurnoutDir;  	} -	for ( segInx=posCnt=0; segInx<xx->segCnt; segInx++ ) { -		if ( segIndexMap(segInx) > 0 ) +	for (segInx = posCnt = 0; segInx < xx->segCnt; segInx++) { +		if (segIndexMap(segInx) > 0)  			segIndexMap(segInx) = ++posCnt;  	} -	DYNARR_SET( trkSeg_t, tempSegs_da, posCnt ); -	for ( segInx=posCnt=0; segInx<xx->segCnt; segInx++ ) { -		if ( segIndexMap(segInx) > 0 ) { -			if ( segInx == segInx0 ) { -				tempSegs(segIndexMap(segInx)-1) = segProcDataSplit.split.newSeg[s0]; -			} else { -				tempSegs(segIndexMap(segInx)-1) = xx->segs[segInx]; +	DYNARR_SET(trkSeg_t, tempSegs_da, posCnt); +	for (segInx = posCnt = 0; segInx < xx->segCnt; segInx++) { +		if (segIndexMap(segInx) > 0) { +			if (segInx == segInx0) { +				tempSegs(segIndexMap(segInx) - 1) = segProcDataSplit.split.newSeg[s0]; +			} +			else { +				tempSegs(segIndexMap(segInx) - 1) = xx->segs[segInx];  			}  			posCnt++;  		} @@ -1220,19 +3103,19 @@ foundSeg:  	/*  	 * 5. Remap paths by removing trailing segments  	 */ -	DYNARR_SET( char, newPath_da, xx->pathLen ); -	pp = xx->paths; +	pp = GetPaths(trk); +	DYNARR_SET(char, newPath_da, GetPathsLength(pp));  	pp1 = (PATHPTR_T)&newPath(0); -	while ( *pp ) { -		strcpy( (char *)pp1, (char *)pp ); -		pp += strlen( (char *)pp )+1; -		pp1 += strlen( (char *)pp1 )+1; -		while ( *pp ) { -			while ( *pp ) { -				GetSegInxEP( *pp, &segInx, &segEP ); -				if ( segIndexMap(segInx) > 0 ) { +	while (*pp) { +		strcpy((char*)pp1, (char*)pp); +		pp += strlen((char*)pp) + 1; +		pp1 += strlen((char*)pp1) + 1; +		while (*pp) { +			while (*pp) { +				GetSegInxEP(*pp, &segInx, &segEP); +				if (segIndexMap(segInx) > 0) {  					c = segIndexMap(segInx); -					if ( *pp<0 ) +					if (*pp < 0)  						c = -c;  					*pp1++ = c;  				} @@ -1249,23 +3132,25 @@ foundSeg:  	/*  	 * 6. Reorigin segments  	 */ -	GetSegBounds( zero, 0, tempSegs_da.cnt, &tempSegs(0), &orig, &size ); +	GetSegBounds(zero, 0, tempSegs_da.cnt, &tempSegs(0), &orig, &size);  	orig.x = -orig.x;  	orig.y = -orig.y; -	MoveSegs( tempSegs_da.cnt, &tempSegs(0), orig ); +	MoveSegs(tempSegs_da.cnt, &tempSegs(0), orig);  	epPos.x += orig.x;  	epPos.y += orig.y; -	cp = strchr( xx->title, '\t' ); -	if ( cp ) { -		if ( strncmp( cp+1, "Split ", 6 ) != 0 ) { -			memcpy( message, xx->title, cp-xx->title+1 ); -			strcpy( message+(cp-xx->title+1), "Split " ); -			strcat( message, cp+1 ); -		} else { -			strcpy( message, xx->title ); +	cp = strchr(xx->title, '\t'); +	if (cp) { +		if (strncmp(cp + 1, "Split ", 6) != 0) { +			memcpy(message, xx->title, cp - xx->title + 1); +			strcpy(message + (cp - xx->title + 1), "Split "); +			strcat(message, cp + 1); +		} +		else { +			strcpy(message, xx->title);  		} -	} else { -		sprintf( message, "Split %s", xx->title ); +	} +	else { +		sprintf(message, "Split %s", xx->title);  	}  	/* @@ -1273,28 +3158,30 @@ foundSeg:  	 */  	int trks = 0;  	path = splitTurnoutPath; -	if ( segProcDataSplit.split.length[s1] < minLength ) +	if (segProcDataSplit.split.length[s1] < minLength)  		path += splitTurnoutDir; -	while ( path[0] ) { -		GetSegInxEP( path[0], &segInx, &segEP ); +	while (path[0]) { +		GetSegInxEP(path[0], &segInx, &segEP);  		s0 = (path[0] > 0) != (splitTurnoutDir > 0); -		if ( segInx0 != segInx ) { +		if (segInx0 != segInx) {  			newSeg = xx->segs[segInx]; -		} else { +		} +		else {  			newSeg = segProcDataSplit.split.newSeg[s1];  		} -		MoveSegs( 1, &newSeg, xx->orig ); -		RotateSegs( 1, &newSeg, xx->orig, xx->angle ); -		SegProc( SEGPROC_NEWTRACK, &newSeg, &segProcDataNewTrack ); -		if ( *leftover == NULL ) { +		MoveSegs(1, &newSeg, xx->orig); +		RotateSegs(1, &newSeg, xx->orig, xx->angle); +		SegProc(SEGPROC_NEWTRACK, &newSeg, &segProcDataNewTrack); +		if (*leftover == NULL) {  			*ep0 = segProcDataNewTrack.newTrack.ep[s0];  			*leftover = trk2 = segProcDataNewTrack.newTrack.trk; -			ep2 = 1-*ep0; -		} else { +			ep2 = 1 - *ep0; +		} +		else {  			epN = segProcDataNewTrack.newTrack.ep[s0]; -			ConnectTracks( trk2, ep2, segProcDataNewTrack.newTrack.trk, epN ); +			ConnectTracks(trk2, ep2, segProcDataNewTrack.newTrack.trk, epN);  			trk2 = segProcDataNewTrack.newTrack.trk; -			ep2 = 1-epN; +			ep2 = 1 - epN;  		}  		++trks;  		path += splitTurnoutDir; @@ -1304,40 +3191,39 @@ foundSeg:  	 * 8. Replace segments, paths, and endPt in original turnout  	 */  	xx->split = TRUE; -	Rotate( &orig, zero, xx->angle ); +	Rotate(&orig, zero, xx->angle);  	xx->orig.x -= orig.x;  	xx->orig.y -= orig.y;  	xx->segCnt = tempSegs_da.cnt; -	xx->segs = (trkSeg_p)memdup( &tempSegs(0), tempSegs_da.cnt * sizeof tempSegs(0) ); -	CloneFilledDraw( xx->segCnt, xx->segs, TRUE ); -	xx->pathLen = pp1-(PATHPTR_T)&newPath(0); -	xx->pathCurr = xx->paths = memdup( &newPath(0), xx->pathLen ); -	epAngle = NormalizeAngle( xx->angle+epAngle ); +	xx->segs = (trkSeg_p)memdup(&tempSegs(0), tempSegs_da.cnt * sizeof tempSegs(0)); +	CloneFilledDraw(xx->segCnt, xx->segs, TRUE); +	SetPaths(trk, (PATHPTR_T)&newPath(0)); +	epAngle = NormalizeAngle(xx->angle + epAngle);  	epPos.x += xx->orig.x;  	epPos.y += xx->orig.y; -	Rotate( &epPos, xx->orig, xx->angle ); -	SetTrkEndPoint( trk, ep, epPos, epAngle ); -	ComputeCompoundBoundingBox( trk ); +	Rotate(&epPos, xx->orig, xx->angle); +	SetTrkEndPoint(trk, ep, epPos, epAngle); +	ComputeCompoundBoundingBox(trk);  	return TRUE;  }  static BOOL_T SplitTurnout( -		track_p trk, -		coOrd pos, -		EPINX_T ep, -		track_p *leftover, -		EPINX_T * ep0, -		EPINX_T * ep1 ) +	track_p trk, +	coOrd pos, +	EPINX_T ep, +	track_p* leftover, +	EPINX_T* ep0, +	EPINX_T* ep1)  { -	return SplitTurnoutCheck(trk,pos,ep,leftover,ep0,ep1,FALSE,NULL,NULL); +	return SplitTurnoutCheck(trk, pos, ep, leftover, ep0, ep1, FALSE, NULL, NULL);  }  static BOOL_T CheckTraverseTurnout( -		track_p trk, -		coOrd pos ) +	track_p trk, +	coOrd pos)  { -	struct extraData * xx = GetTrkExtraData(trk); +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	coOrd pos1;  #ifdef LATER  	int inx, foundInx = 0; @@ -1348,65 +3234,67 @@ static BOOL_T CheckTraverseTurnout(  	int segInx;  	EPINX_T segEP; -LOG( log_traverseTurnout, 1, ( "CheckTraverseTurnout( T%d, [%0.3f %0.3f])\n", GetTrkIndex(trk), pos.x, pos.y ) ) -	Rotate( &pos, xx->orig, -xx->angle ); +	LOG(log_traverseTurnout, 1, ("CheckTraverseTurnout( T%d, [%0.3f %0.3f])\n", GetTrkIndex(trk), pos.x, pos.y)) +		Rotate(&pos, xx->orig, -xx->angle);  	pos.x -= xx->orig.x;  	pos.y -= xx->orig.y; -LOG( log_traverseTurnout, 1, ( "After rotation = [%0.3f %0.3f])\n", pos.x, pos.y ) ) -	 +	LOG(log_traverseTurnout, 1, ("After rotation = [%0.3f %0.3f])\n", pos.x, pos.y)) +  #ifdef LATER -	for ( inx=0; inx<xx->segCnt; inx++ ) { -		switch ( xx->segs[inx].type ) { -		case SEG_STRTRK: -		case SEG_CRVTRK: -			pos1 = GetSegEndPt( &xx->segs[inx], 0, FALSE, NULL ); -			d = FindDistance( pos, pos1 ); -			if ( foundInx == 0 || d < foundD ) { -				foundInx = inx+1; -				foundD = d; -			} -			pos1 = GetSegEndPt( &xx->segs[inx], 1, FALSE, NULL ); -			d = FindDistance( pos, pos1 ); -			if ( foundInx == 0 || d < foundD ) { -				foundInx = -(inx+1); -				foundD = d; +		for (inx = 0; inx < xx->segCnt; inx++) { +			switch (xx->segs[inx].type) { +			case SEG_STRTRK: +			case SEG_CRVTRK: +				pos1 = GetSegEndPt(&xx->segs[inx], 0, FALSE, NULL); +				d = FindDistance(pos, pos1); +				if (foundInx == 0 || d < foundD) { +					foundInx = inx + 1; +					foundD = d; +				} +				pos1 = GetSegEndPt(&xx->segs[inx], 1, FALSE, NULL); +				d = FindDistance(pos, pos1); +				if (foundInx == 0 || d < foundD) { +					foundInx = -(inx + 1); +					foundD = d; +				} +				break;  			} -			break;  		} -	} -	if ( foundInx == 0 ) +	if (foundInx == 0)  		return FALSE;  #endif -	for ( pathCurr = xx->pathCurr+strlen((char*)xx->pathCurr)+1; pathCurr[0] || pathCurr[1]; pathCurr++ ) { -LOG( log_traverseTurnout, 1, ( "P[%d] = %d ", pathCurr-xx->paths, pathCurr[0] ) ) -		if ( pathCurr[-1] == 0 ) { -			GetSegInxEP( pathCurr[0], &segInx, &segEP ); -			pos1 = GetSegEndPt( &xx->segs[segInx], segEP, FALSE, NULL ); -			d = FindDistance( pos, pos1 ); -LOG( log_traverseTurnout, 1, ( "d=%0.3f\n", d ) ) -			if ( d < connectDistance ) -				return TRUE; -		} -		if ( pathCurr[1] == 0 ) { -			GetSegInxEP( pathCurr[0], &segInx, &segEP ); -			pos1 = GetSegEndPt( &xx->segs[segInx], 1-segEP, FALSE, NULL ); -			d = FindDistance( pos, pos1 ); -LOG( log_traverseTurnout, 1, ( "d=%0.3f\n", d ) ) -			if ( d < connectDistance ) -				return TRUE; -		} -	} -LOG( log_traverseTurnout, 1, ( " not found\n" ) ) -	return FALSE; +	PATHPTR_T pathName = GetCurrPath(trk); +	for (pathCurr = pathName + strlen((char*)pathName) + 1; +		pathCurr[0] || pathCurr[1]; pathCurr++) { +		LOG(log_traverseTurnout, 1, ("P[%d] = %d ", pathCurr - GetPaths(trk), pathCurr[0])) +			if (pathCurr[-1] == 0) { +				GetSegInxEP(pathCurr[0], &segInx, &segEP); +				pos1 = GetSegEndPt(&xx->segs[segInx], segEP, FALSE, NULL); +				d = FindDistance(pos, pos1); +				LOG(log_traverseTurnout, 1, ("d=%0.3f\n", d)) +					if (d < connectDistance) +						return TRUE; +			} +		if (pathCurr[1] == 0) { +			GetSegInxEP(pathCurr[0], &segInx, &segEP); +			pos1 = GetSegEndPt(&xx->segs[segInx], 1 - segEP, FALSE, NULL); +			d = FindDistance(pos, pos1); +			LOG(log_traverseTurnout, 1, ("d=%0.3f\n", d)) +				if (d < connectDistance) +					return TRUE; +		} +	} +	LOG(log_traverseTurnout, 1, (" not found\n")) +		return FALSE;  }  static BOOL_T TraverseTurnout( -		traverseTrack_p trvTrk, -		DIST_T * distR ) +	traverseTrack_p trvTrk, +	DIST_T* distR)  {  	track_p trk = trvTrk->trk; -	struct extraData * xx = GetTrkExtraData(trk); +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	coOrd pos0, pos1, pos2;  	DIST_T d, dist;  	PATHPTR_T path, pathCurr; @@ -1416,37 +3304,38 @@ static BOOL_T TraverseTurnout(  	EPINX_T segEP;  	segProcData_t segProcData; -	d = 10000; +	d = DIST_INF;  	pos0 = trvTrk->pos; -	Rotate( &pos0, xx->orig, -xx->angle ); +	Rotate(&pos0, xx->orig, -xx->angle);  	pos0.x -= xx->orig.x;  	pos0.y -= xx->orig.y;  	dist = *distR; -LOG( log_traverseTurnout, 1, ( "TraverseTurnout( T%d, [%0.3f %0.3f] [%0.3f %0.3f], A%0.3f, D%0.3f\n", GetTrkIndex(trk), trvTrk->pos.x, trvTrk->pos.y, pos0.x, pos0.y, trvTrk->angle, *distR ) ) -	pathCurr = 0; -	for ( path = xx->pathCurr+strlen((char*)xx->pathCurr)+1; path[0] || path[1]; path++ ) { -		if ( path[0] == 0 ) +	LOG(log_traverseTurnout, 1, ("TraverseTurnout( T%d, [%0.3f %0.3f] [%0.3f %0.3f], A%0.3f, D%0.3f\n", GetTrkIndex(trk), trvTrk->pos.x, trvTrk->pos.y, pos0.x, pos0.y, trvTrk->angle, *distR)) +		pathCurr = 0; +	path = GetCurrPath(trk); +	for (path += strlen((char*)path) + 1; path[0] || path[1]; path++) { +		if (path[0] == 0)  			continue; -		GetSegInxEP( path[0], &segInx, &segEP ); -		segPtr = xx->segs+segInx; +		GetSegInxEP(path[0], &segInx, &segEP); +		segPtr = xx->segs + segInx;  		segProcData.distance.pos1 = pos0; -		SegProc( SEGPROC_DISTANCE, segPtr, &segProcData ); -		if ( segProcData.distance.dd < d ) { +		SegProc(SEGPROC_DISTANCE, segPtr, &segProcData); +		if (segProcData.distance.dd < d) {  			d = segProcData.distance.dd;  			pos2 = segProcData.distance.pos1;  			pathCurr = path;  		}  	} -	if ( d > 10 || pathCurr == 0 ) { -		ErrorMessage( "traverseTurnout: Not near: %0.3f", d ); +	if (d > 10 || pathCurr == 0) { +		ErrorMessage("traverseTurnout: Not near: %0.3f", d);  		return FALSE;  	} -LOG( log_traverseTurnout, 1, ( "  PC=%d ", pathCurr[0] ) ) -	GetSegInxEP( pathCurr[0], &segInx, &segEP ); -	segPtr = xx->segs+segInx; +	LOG(log_traverseTurnout, 1, ("  PC=%d ", pathCurr[0])) +		GetSegInxEP(pathCurr[0], &segInx, &segEP); +	segPtr = xx->segs + segInx;  	segProcData.traverse1.pos = pos2; -	segProcData.traverse1.angle = -xx->angle+trvTrk->angle; -	SegProc( SEGPROC_TRAVERSE1, segPtr, &segProcData ); +	segProcData.traverse1.angle = -xx->angle + trvTrk->angle; +	SegProc(SEGPROC_TRAVERSE1, segPtr, &segProcData);  	dist += segProcData.traverse1.dist;  	//Get ready for Traverse2 - copy all Traverse1 first  	BOOL_T backwards = segProcData.traverse1.backwards; @@ -1461,111 +3350,112 @@ LOG( log_traverseTurnout, 1, ( "  PC=%d ", pathCurr[0] ) )  	BOOL_T turnout_backwards = backwards;  	if (segEP) turnout_backwards = !turnout_backwards; //direction modified if path reversed -LOG( log_traverseTurnout, 2, ( " SI%d TB%d SP%d B%d SB%d N%d BSI%d D%0.3f\n", segInx, turnout_backwards, segEP, backwards, segs_backwards, neg, BezSegInx, dist ) ) -	while ( *pathCurr ) { -		//Set up Traverse2 -		GetSegInxEP( pathCurr[0], &segInx, &segEP ); -		segPtr = xx->segs+segInx; -		segProcData.traverse2.segDir = backwards; -		segProcData.traverse2.dist = dist; -		segProcData.traverse2.BezSegInx = BezSegInx; -		segProcData.traverse2.segs_backwards = segs_backwards; -		SegProc( SEGPROC_TRAVERSE2, segPtr, &segProcData ); -		if ( segProcData.traverse2.dist <= 0 ) { -			*distR = 0; -			REORIGIN( trvTrk->pos, segProcData.traverse2.pos, xx->angle, xx->orig ); -			trvTrk->angle = NormalizeAngle( xx->angle+segProcData.traverse2.angle ); -LOG( log_traverseTurnout, 2, ( "  -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR )) -			return TRUE; +	LOG(log_traverseTurnout, 2, (" SI%d TB%d SP%d B%d SB%d N%d BSI%d D%0.3f\n", segInx, turnout_backwards, segEP, backwards, segs_backwards, neg, BezSegInx, dist)) +		while (*pathCurr) { +			//Set up Traverse2 +			GetSegInxEP(pathCurr[0], &segInx, &segEP); +			segPtr = xx->segs + segInx; +			segProcData.traverse2.segDir = backwards; +			segProcData.traverse2.dist = dist; +			segProcData.traverse2.BezSegInx = BezSegInx; +			segProcData.traverse2.segs_backwards = segs_backwards; +			SegProc(SEGPROC_TRAVERSE2, segPtr, &segProcData); +			if (segProcData.traverse2.dist <= 0) { +				*distR = 0; +				REORIGIN(trvTrk->pos, segProcData.traverse2.pos, xx->angle, xx->orig); +				trvTrk->angle = NormalizeAngle(xx->angle + segProcData.traverse2.angle); +				LOG(log_traverseTurnout, 2, ("  -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR)) +					return TRUE; +			} +			dist = segProcData.traverse2.dist;			//Remainder after segment +			pathCurr += (turnout_backwards ? -1 : 1);		//Use master direction for turnout +			//Redrive Traverse 1 for each segment for Bezier - to pick up backwards elements +			if (pathCurr[0] == '\0') continue;          // +			//Set up Traverse1 - copy all of Traverse2 values first +			GetSegInxEP(pathCurr[0], &segInx, &segEP); +			segPtr = xx->segs + segInx; +			ANGLE_T angle = segProcData.traverse2.angle; +			coOrd pos = segProcData.traverse2.pos; +			LOG(log_traverseTurnout, 1, (" Loop2-1 SI%d SP%d [%0.3f %0.3f] A%0.3f D%0.3f\n", segInx, segEP, pos.x, pos.y, angle, dist)) +				segProcData.traverse1.pos = pos; +			segProcData.traverse1.angle = angle; +			SegProc(SEGPROC_TRAVERSE1, segPtr, &segProcData); +			// dist += segProcData.traverse1.dist;	               //Add distance from end to pos (could be zero or whole length if backwards) +			backwards = segProcData.traverse1.backwards; +			segs_backwards = segProcData.traverse1.segs_backwards; +			neg = segProcData.traverse1.negative; +			BezSegInx = segProcData.traverse1.BezSegInx; +			LOG(log_traverseTurnout, 1, (" Loop1-2 B%d SB%d N%d BSI%d D%0.3f\n", backwards, segs_backwards, neg, BezSegInx, dist))  		} -		dist = segProcData.traverse2.dist;			//Remainder after segment -		pathCurr += (turnout_backwards?-1:1);		//Use master direction for turnout -		//Redrive Traverse 1 for each segment for Bezier - to pick up backwards elements -		if (pathCurr[0] == '\0') continue;          // -		//Set up Traverse1 - copy all of Traverse2 values first -		GetSegInxEP( pathCurr[0], &segInx, &segEP ); -		segPtr = xx->segs+segInx; -		ANGLE_T angle = segProcData.traverse2.angle; -		coOrd pos = segProcData.traverse2.pos; -LOG( log_traverseTurnout, 1, ( " Loop2-1 SI%d SP%d [%0.3f %0.3f] A%0.3f D%0.3f\n", segInx, segEP, pos.x, pos.y, angle, dist ) ) -		segProcData.traverse1.pos = pos; -		segProcData.traverse1.angle = angle; -		SegProc( SEGPROC_TRAVERSE1, segPtr, &segProcData ); -		// dist += segProcData.traverse1.dist;	               //Add distance from end to pos (could be zero or whole length if backwards) -		backwards = segProcData.traverse1.backwards; -		segs_backwards = segProcData.traverse1.segs_backwards; -		neg = segProcData.traverse1.negative; -		BezSegInx = segProcData.traverse1.BezSegInx; -LOG( log_traverseTurnout, 1, ( " Loop1-2 B%d SB%d N%d BSI%d D%0.3f\n", backwards, segs_backwards, neg, BezSegInx, dist ) ) -	} - -	pathCurr += (turnout_backwards?1:-1); -	pos1 = MapPathPos( xx, pathCurr[0], (turnout_backwards?0:1) ); + +	pathCurr += (turnout_backwards ? 1 : -1); +	pos1 = MapPathPos(xx, pathCurr[0], (turnout_backwards ? 0 : 1));  	*distR = dist;  	epCnt = GetTrkEndPtCnt(trk);  	ep = 0; -	dist = FindDistance( pos1, GetTrkEndPos(trk,0) ); -	for ( ep2=1; ep2<epCnt; ep2++ ) { -		d = FindDistance( pos1, GetTrkEndPos(trk,ep2) ); -		if ( d < dist ) { +	dist = FindDistance(pos1, GetTrkEndPos(trk, 0)); +	for (ep2 = 1; ep2 < epCnt; ep2++) { +		d = FindDistance(pos1, GetTrkEndPos(trk, ep2)); +		if (d < dist) {  			dist = d;  			ep = ep2;  		}  	} -	if ( dist > connectDistance ) { +	if (dist > connectDistance) {  		trk = NULL;  		trvTrk->pos = pos1; -	} else { -		trvTrk->pos = GetTrkEndPos( trk, ep ); -		trvTrk->angle = GetTrkEndAngle( trk, ep ); -		trk = GetTrkEndTrk( trk, ep ); -	} -	dist = FindDistance( trvTrk->pos, pos1 ); -LOG( log_traverseTurnout, 1, ( "  -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR ) ) -	trvTrk->trk = trk; +	} +	else { +		trvTrk->pos = GetTrkEndPos(trk, ep); +		trvTrk->angle = GetTrkEndAngle(trk, ep); +		trk = GetTrkEndTrk(trk, ep); +	} +	dist = FindDistance(trvTrk->pos, pos1); +	LOG(log_traverseTurnout, 1, ("  -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR)) +		trvTrk->trk = trk;  	return TRUE;  } -static STATUS_T ModifyTurnout( track_p trk, wAction_t action, coOrd pos ) +static STATUS_T ModifyTurnout(track_p trk, wAction_t action, coOrd pos)  { -	struct extraData *xx; +	struct extraDataCompound_t* xx;  	static EPINX_T ep;  	static wBool_t curved;  	DIST_T d; -	xx = GetTrkExtraData(trk); -	if ( xx->special == TOadjustable ) { -		switch ( action ) { +	xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t); +	if (xx->special == TOadjustable) { +		switch (action) {  		case C_START:  			ep = -1;  			curved = FALSE;  			return C_CONTINUE;  		case C_DOWN: -			ep = PickUnconnectedEndPoint( pos, trk ); +			ep = PickUnconnectedEndPoint(pos, trk);  			if (ep == -1)  				return C_ERROR; -			UndrawNewTrack( trk ); +			UndrawNewTrack(trk);  			tempSegs(0).type = SEG_STRTRK;  			tempSegs(0).width = 0; -			tempSegs(0).u.l.pos[0] = GetTrkEndPos( trk, 1-ep ); +			tempSegs(0).u.l.pos[0] = GetTrkEndPos(trk, 1 - ep);  			tempSegs_da.cnt = 1; -			InfoMessage( _("Drag to change track length") ); +			InfoMessage(_("Drag to change track length"));  			return C_CONTINUE;  		case C_MOVE: -			d = FindDistance( tempSegs(0).u.l.pos[0], pos ); -			if ( d < xx->u.adjustable.minD ) +			d = FindDistance(tempSegs(0).u.l.pos[0], pos); +			if (d < xx->u.adjustable.minD)  				d = xx->u.adjustable.minD; -			else if ( d > xx->u.adjustable.maxD ) +			else if (d > xx->u.adjustable.maxD)  				d = xx->u.adjustable.maxD; -			Translate( &tempSegs(0).u.l.pos[1], tempSegs(0).u.l.pos[0], GetTrkEndAngle( trk, ep ), d ); +			Translate(&tempSegs(0).u.l.pos[1], tempSegs(0).u.l.pos[0], GetTrkEndAngle(trk, ep), d);  			tempSegs_da.cnt = 1;  			if (action == C_MOVE) -				InfoMessage( _("Length=%s"), FormatDistance( d ) ); +				InfoMessage(_("Length=%s"), FormatDistance(d));  			return C_CONTINUE;  		case C_UP: -			d = FindDistance( tempSegs(0).u.l.pos[0],tempSegs(0).u.l.pos[1] ); -			ChangeAdjustableEndPt( trk, ep, d ); +			d = FindDistance(tempSegs(0).u.l.pos[0], tempSegs(0).u.l.pos[1]); +			ChangeAdjustableEndPt(trk, ep, d);  			return C_TERMINATE;  		default:  			return C_CONTINUE; @@ -1576,141 +3466,130 @@ static STATUS_T ModifyTurnout( track_p trk, wAction_t action, coOrd pos )  } -static BOOL_T GetParamsTurnout( int inx, track_p trk, coOrd pos, trackParams_t * params ) +static BOOL_T GetParamsTurnout(int inx, track_p trk, coOrd pos, trackParams_t* params)  { -	struct extraData *xx; -	xx = GetTrkExtraData(trk); +	struct extraDataCompound_t* xx; +	xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  	params->type = curveTypeStraight; -    if (inx == PARAMS_TURNOUT) { -        params->len = 0.0; -        int epCnt = GetTrkEndPtCnt(trk); -        if (epCnt < 3) { -            double d = 10000.0; -            params->centroid = zero; -            //calculate path length from endPt (either to end or to other end) -            segProcData_t segProcData; -            trkSeg_p seg; -            int segInx; -            int segEP; -            trkSeg_p segPtr; -            PATHPTR_T path,pathCurr; -            //Find starting seg on path (nearest to end Pt) -            for ( path = xx->pathCurr+strlen((char*)xx->pathCurr)+1; path[0] || path[1]; path++ ) { -                if ( path[0] == 0 ) -                    continue; -                GetSegInxEP( path[0], &segInx, &segEP ); -                segPtr = xx->segs+segInx; -                segProcData.distance.pos1 = pos; -                SegProc( SEGPROC_DISTANCE, segPtr, &segProcData ); -                if ( segProcData.distance.dd < d ) { -                    d = segProcData.distance.dd; -                    pathCurr = path; -                } -            } -            GetSegInxEP( pathCurr[0], &segInx, &segEP ); -            seg = xx->segs+segInx; -            d = 0.0; -            //Loop through segs on path from endPt adding -            while (pathCurr[0]) { -                GetSegInxEP( pathCurr[0], &segInx, &segEP ); -                seg = xx->segs+segInx; -                SegProc(SEGPROC_LENGTH, seg, &segProcData ); -                d += segProcData.length.length; -                pathCurr += segEP?1:-1; -            } -            params->len = d; -        } else { -            double x, y; -            x = 0; y = 0; -            for (int i=0;i<epCnt; i++) { -                coOrd cpos = GetTrkEndPos(trk,i); -                x += cpos.x; -                y += cpos.y; -            } -            params->centroid.x = x/epCnt; -            params->centroid.y = y/epCnt; -            params->len = FindDistance(params->centroid,pos)*2;  //Times two because it will be halved by track.c -        } -        return TRUE; -    } -	if ((inx == PARAMS_CORNU)  || (inx == PARAMS_EXTEND)) { +	if (inx == PARAMS_TURNOUT) { +		params->len = 0.0; +		int epCnt = GetTrkEndPtCnt(trk); +		if (epCnt < 3) { +			double d = DIST_INF; +			params->centroid = zero; +			//calculate path length from endPt (either to end or to other end) +			segProcData_t segProcData; +			trkSeg_p seg; +			int segInx; +			int segEP; +			trkSeg_p segPtr; +			PATHPTR_T path, pathCurr; +			//Find starting seg on path (nearest to end Pt) +			path = GetCurrPath(trk); +			pathCurr = path; +			for (path += strlen((char*)path) + 1; path[0] || path[1]; path++) { +				if (path[0] == 0) +					continue; +				GetSegInxEP(path[0], &segInx, &segEP); +				segPtr = xx->segs + segInx; +				segProcData.distance.pos1 = pos; +				SegProc(SEGPROC_DISTANCE, segPtr, &segProcData); +				if (segProcData.distance.dd < d) { +					d = segProcData.distance.dd; +					pathCurr = path; +				} +			} +			GetSegInxEP(pathCurr[0], &segInx, &segEP); +			seg = xx->segs + segInx; +			d = 0.0; +			//Loop through segs on path from endPt adding +			while (pathCurr[0]) { +				GetSegInxEP(pathCurr[0], &segInx, &segEP); +				seg = xx->segs + segInx; +				SegProc(SEGPROC_LENGTH, seg, &segProcData); +				d += segProcData.length.length; +				pathCurr += segEP ? 1 : -1; +			} +			params->len = d; +		} +		else { +			// Centroid is middle of bounding box +			params->centroid.x = (trk->lo.x + trk->hi.x) / 2.0; +			params->centroid.y = (trk->lo.y + trk->hi.y) / 2.0; +			params->len = FindDistance(params->centroid, pos) * 2;  //Times two because it will be halved by track.c +		} +		return TRUE; +	} +	if ((inx == PARAMS_CORNU) || (inx == PARAMS_EXTEND)) {  		params->type = curveTypeStraight;  		params->arcR = 0.0;  		params->arcP = zero; -	    params->ep = PickEndPoint(pos, trk); +		params->ep = PickEndPoint(pos, trk);  		params->circleOrHelix = FALSE; -		if (params->ep>=0) { -			params->angle = GetTrkEndAngle(trk,params->ep); -			params->track_angle = params->angle + params->ep?0:180; -		} else { -			params->angle = params-> track_angle = 0; +		if (params->ep >= 0) { +			params->angle = GetTrkEndAngle(trk, params->ep); +			params->track_angle = params->angle + params->ep ? 0 : 180; +		} +		else { +			params->angle = params->track_angle = 0;  			return FALSE;  		} -		/* Use end radii if we have them */ -		//if (xx->special == TOcurved) { -		//	params->type = curveTypeCurve; -		//	params->arcR = fabs(DYNARR_N(DIST_T,xx->u.curved.radii,params->ep)); -		//	if (params->arcR != 0.0) -		//		Translate(¶ms->arcP,pos,params->track_angle-90.0,params->arcR); -		//	else -		//		params->type = curveTypeStraight; -		//	return TRUE; -		//}  		/* Find the path we are closest to */  		PATHPTR_T pathCurr = 0;  		int segInx, subSegInx;  		trkSeg_p segPtr; -		double d = 10000; -		struct extraData * xx = GetTrkExtraData(trk); +		DIST_T d = DIST_INF; +		struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t);  		/* Get parms from that seg */ -		wBool_t back,negative; +		wBool_t back, negative;  		coOrd segPos = pos; -		Rotate(&segPos,xx->orig,-xx->angle); +		Rotate(&segPos, xx->orig, -xx->angle);  		segPos.x -= xx->orig.x;  		segPos.y -= xx->orig.y;  		params->track_angle = GetAngleSegs(		  		//Find correct subSegment -							xx->segCnt,xx->segs, -							&segPos, &segInx, &d , &back, &subSegInx, &negative ); -		if (segInx ==- 1) return FALSE; -		segPtr = xx->segs+segInx; +			xx->segCnt, xx->segs, +			&segPos, &segInx, &d, &back, &subSegInx, &negative); +		if (segInx == -1) return FALSE; +		segPtr = xx->segs + segInx;  		switch (segPtr->type) { -			case SEG_BEZTRK: -				if ( negative != back ) params->track_angle = NormalizeAngle(params->track_angle+180);  //Bezier is in reverse -				segPtr = xx->segs + segInx; -				trkSeg_p subSegPtr = (trkSeg_p)segPtr->bezSegs.ptr+subSegInx; -				if (subSegPtr->type == SEG_CRVTRK) { -					params->type = curveTypeCurve; -					params->arcR = fabs(subSegPtr->u.c.radius); -					params->arcP = subSegPtr->u.c.center; -					params->arcP.x += xx->orig.x; -					params->arcP.y += xx->orig.y; -					Rotate(¶ms->arcP,xx->orig,xx->angle); -					params->arcA0 = subSegPtr->u.c.a0; -					params->arcA1 = subSegPtr->u.c.a1; -				} -				return TRUE; -				break; -			case SEG_CRVTRK: +		case SEG_BEZTRK: +			if (negative != back) params->track_angle = NormalizeAngle(params->track_angle + 180);  //Bezier is in reverse +			segPtr = xx->segs + segInx; +			trkSeg_p subSegPtr = (trkSeg_p)segPtr->bezSegs.ptr + subSegInx; +			if (subSegPtr->type == SEG_CRVTRK) {  				params->type = curveTypeCurve; -				params->arcR = fabs(segPtr->u.c.radius); -				params->arcP = segPtr->u.c.center; +				params->arcR = fabs(subSegPtr->u.c.radius); +				params->arcP = subSegPtr->u.c.center;  				params->arcP.x += xx->orig.x;  				params->arcP.y += xx->orig.y; -				Rotate(¶ms->arcP,xx->orig,xx->angle); -				params->arcA0 = segPtr->u.c.a0; -				params->arcA1 = segPtr->u.c.a1; -				return TRUE; -				break; -        } -        params->arcR = 0.0; +				Rotate(¶ms->arcP, xx->orig, xx->angle); +				params->arcA0 = subSegPtr->u.c.a0; +				params->arcA1 = subSegPtr->u.c.a1; +			} +			return TRUE; +			break; +		case SEG_CRVTRK: +			params->type = curveTypeCurve; +			params->arcR = fabs(segPtr->u.c.radius); +			params->arcP = segPtr->u.c.center; +			params->arcP.x += xx->orig.x; +			params->arcP.y += xx->orig.y; +			Rotate(¶ms->arcP, xx->orig, xx->angle); +			params->arcA0 = segPtr->u.c.a0; +			params->arcA1 = segPtr->u.c.a1; +			return TRUE; +			break; +		} +		params->arcR = 0.0;  		params->arcP = zero; -		params->ep = PickEndPoint(pos,trk);   //Nearest -		if (params->ep>=0) { -			params->angle = GetTrkEndAngle(trk,params->ep); -		    params->track_angle = params->angle + params->ep?0:180; -		} else { -			params->angle = params-> track_angle = 0; +		params->ep = PickEndPoint(pos, trk);   //Nearest +		if (params->ep >= 0) { +			params->angle = GetTrkEndAngle(trk, params->ep); +			params->track_angle = params->angle + params->ep ? 0 : 180; +		} +		else { +			params->angle = params->track_angle = 0;  			return FALSE;  		}  		return TRUE; @@ -1718,49 +3597,49 @@ static BOOL_T GetParamsTurnout( int inx, track_p trk, coOrd pos, trackParams_t *  	if ((inx == PARAMS_1ST_JOIN) || (inx == PARAMS_2ND_JOIN))  		params->ep = PickEndPoint(pos, trk);  	else -		params->ep = PickUnconnectedEndPointSilent( pos, trk ); +		params->ep = PickUnconnectedEndPointSilent(pos, trk);  	if (params->ep == -1) -				 return FALSE; -	params->lineOrig = GetTrkEndPos(trk,params->ep); +		return FALSE; +	params->lineOrig = GetTrkEndPos(trk, params->ep);  	params->lineEnd = params->lineOrig;  	params->len = 0.0; -	params->angle = GetTrkEndAngle(trk,params->ep); +	params->angle = GetTrkEndAngle(trk, params->ep);  	params->arcR = 0.0;  	return TRUE;  } -static BOOL_T MoveEndPtTurnout( track_p *trk, EPINX_T *ep, coOrd pos, DIST_T d0 ) +static BOOL_T MoveEndPtTurnout(track_p* trk, EPINX_T* ep, coOrd pos, DIST_T d0)  {  	ANGLE_T angle0;  	DIST_T d;  	track_p trk1; -	angle0 = GetTrkEndAngle(*trk,*ep); -	d = FindDistance( GetTrkEndPos(*trk,*ep), pos); +	angle0 = GetTrkEndAngle(*trk, *ep); +	d = FindDistance(GetTrkEndPos(*trk, *ep), pos);  	if (d0 > 0.0) {  		d -= d0;  		if (d < 0.0) { -			ErrorMessage( MSG_MOVED_BEFORE_END_TURNOUT ); +			ErrorMessage(MSG_MOVED_BEFORE_END_TURNOUT);  			return FALSE;  		} -		Translate( &pos, pos, angle0+180, d0 ); +		Translate(&pos, pos, angle0 + 180, d0);  	}  	if (d > minLength) { -		trk1 = NewStraightTrack( GetTrkEndPos(*trk,*ep), pos ); -		CopyAttributes( *trk, trk1 ); -		ConnectTracks( *trk, *ep, trk1, 0 ); +		trk1 = NewStraightTrack(GetTrkEndPos(*trk, *ep), pos); +		CopyAttributes(*trk, trk1); +		ConnectTracks(*trk, *ep, trk1, 0);  		*trk = trk1;  		*ep = 1; -		DrawNewTrack( *trk ); +		DrawNewTrack(*trk);  	}  	return TRUE;  } -static BOOL_T QueryTurnout( track_p trk, int query ) +static BOOL_T QueryTurnout(track_p trk, int query)  { -	switch ( query ) { +	switch (query) {  	case Q_IGNORE_EASEMENT_ON_EXTEND:  	case Q_DRAWENDPTV_1:  	case Q_CAN_GROUP: @@ -1774,12 +3653,16 @@ static BOOL_T QueryTurnout( track_p trk, int query )  	case Q_IS_TURNOUT:  		return TRUE;  	case Q_CAN_PARALLEL: -		if( GetTrkEndPtCnt( trk ) == 2 && fabs( GetTrkEndAngle( trk, 0 ) - GetTrkEndAngle( trk, 1 )) == 180.0 ) +		if (GetTrkEndPtCnt(trk) == 2 && fabs(GetTrkEndAngle(trk, 0) - GetTrkEndAngle(trk, 1)) == 180.0)  			return TRUE;  		else  			return FALSE;  	case Q_CAN_NEXT_POSITION: -		return ( GetTrkEndPtCnt(trk) > 2 ); +		{ +			PATHPTR_T path = GetPaths( trk ); // QueryTurnout +			for ( path += strlen((char*)path) + 1; path[0] || path[1]; path++ ); +			return ( path[2] != 0 ); +		}  	case Q_CORNU_CAN_MODIFY:  		return FALSE;  	default: @@ -1789,54 +3672,70 @@ static BOOL_T QueryTurnout( track_p trk, int query )  EXPORT int doDrawTurnoutPosition = 1; -static wIndex_t drawTurnoutPositionWidth=3; +static wIndex_t drawTurnoutPositionWidth = 3;  static void DrawTurnoutPositionIndicator( -		track_p trk, -		wDrawColor color ) +	track_p trk, +	wDrawColor color)  { -	struct extraData * xx = GetTrkExtraData(trk); -	PATHPTR_T path = xx->pathCurr; -	coOrd pos0, pos1; +	struct extraDataCompound_t* xx = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t); +	PATHPTR_T path, path1; +	coOrd pos0 = zero, pos1; +	trkSeg_p seg; +	BOOL_T multiPart = FALSE; -	if ( xx->pathCurr == xx->paths ) { -		for ( path=xx->pathCurr+strlen((char *)xx->pathCurr); path[0] || path[1]; path++ ); -		if ( path[2] == 0 ) -			return; -	} -	for ( path=xx->pathCurr+strlen((char *)xx->pathCurr); path[0] || path[1]; path++ ) { -		if ( path[0] == 0 ) { -			pos0 = MapPathPos( xx, path[1], 0 ); -		} else if ( path[1] == 0 ) { -			pos1 = MapPathPos( xx, path[0], 1 ); -			DrawLine( &tempD, pos0, pos1, drawTurnoutPositionWidth, color ); +	// Only 1 path?  Don't draw +	if ( ! QueryTurnout( trk, Q_CAN_NEXT_POSITION ) ) +		return; + +	path = GetCurrPath(trk); + +	//Is this a multi-part path? +	path1 = path; +	for (path1 += strlen((char*)path1) + 1; path1[0]; path1++); +	if (path1[1] != 0) multiPart = TRUE; + + +	for (path += strlen((char*)path); path[0] || path[1]; path++) { + +		if (path[0] == 0) { +			pos0 = MapPathPos(xx, path[1], 0); +			if ((tempD.scale <= 10) || !multiPart) { +				seg = MapPathSeg(xx, path[1]); +				DrawSegsO(&tempD, trk, xx->orig, xx->angle, seg, 1, GetTrkGauge(trk), color, DTS_CENTERONLY); +			} +		} +		else if (path[1] == 0) { +			pos1 = MapPathPos(xx, path[0], 1); +			if ((tempD.scale > 10) && multiPart) +				DrawLine(&tempD, pos0, pos1, drawTurnoutPositionWidth, color); +			else { +				seg = MapPathSeg(xx, path[0]); +				DrawSegsO(&tempD, trk, xx->orig, xx->angle, seg, 1, GetTrkGauge(trk), color, DTS_CENTERONLY); +			} +		} +		else if ((tempD.scale <= 10) || !multiPart) { +			seg = MapPathSeg(xx, path[0]); +			DrawSegsO(&tempD, trk, xx->orig, xx->angle, seg, 1, GetTrkGauge(trk), color, DTS_CENTERONLY);  		}  	}  }  EXPORT void AdvanceTurnoutPositionIndicator( -		track_p trk, -		coOrd pos, -		coOrd *posR, -		ANGLE_T *angleR ) +	track_p trk, +	coOrd pos, +	coOrd* posR, +	ANGLE_T* angleR)  { -	struct extraData * xx = GetTrkExtraData(trk); -	PATHPTR_T path;  	traverseTrack_t trvtrk;  	DIST_T dist; -	if ( GetTrkType(trk) != T_TURNOUT ) -		AbortProg( "nextTurnoutPosition" ); - -	path = xx->pathCurr; -	path += strlen((char *)path)+1; -	while ( path[0] || path[1] ) -		path++; -	path += 2; -	if ( *path == 0 ) -		path = xx->paths; -	xx->pathCurr = path; -	if ( angleR == NULL || posR == NULL ) +	if (GetTrkType(trk) != T_TURNOUT) +		AbortProg("nextTurnoutPosition"); + +	SetCurrPathIndex(trk, GetCurrPathIndex(trk) + 1); +	InfoMessage(_("Turnout %d Path: %s"), GetTrkIndex(trk), GetCurrPath(trk)); +	if (angleR == NULL || posR == NULL)  		return;  	trvtrk.trk = trk;  	trvtrk.length = 0; @@ -1844,17 +3743,17 @@ EXPORT void AdvanceTurnoutPositionIndicator(  	trvtrk.pos = *posR;  	trvtrk.angle = *angleR;  	dist = 0; -	if ( !TraverseTurnout( &trvtrk, &dist ) ) +	if (!TraverseTurnout(&trvtrk, &dist))  		return; -	if ( NormalizeAngle( trvtrk.angle-*angleR+90.0 ) > 180 ) -		trvtrk.angle = NormalizeAngle( trvtrk.angle+180.0 ); +	if (NormalizeAngle(trvtrk.angle - *angleR + 90.0) > 180) +		trvtrk.angle = NormalizeAngle(trvtrk.angle + 180.0);  	*posR = trvtrk.pos;  	*angleR = trvtrk.angle;  }  /**   * Create a parallel track for a turnout. - *  + *   *   * \param trk IN existing track   * \param pos IN ?? @@ -1866,60 +3765,56 @@ EXPORT void AdvanceTurnoutPositionIndicator(   */  static BOOL_T MakeParallelTurnout( -		track_p trk, -		coOrd pos, -		DIST_T sep, -		DIST_T factor, -		track_p * newTrk, -		coOrd * p0R, -		coOrd * p1R, -		BOOL_T track) -{ -	ANGLE_T angle = GetTrkEndAngle(trk,1); -	struct extraData *xx, *yy; -	coOrd *endPts; +	track_p trk, +	coOrd pos, +	DIST_T sep, +	DIST_T factor, +	track_p* newTrk, +	coOrd* p0R, +	coOrd* p1R, +	BOOL_T track) +{ +	ANGLE_T angle = GetTrkEndAngle(trk, 1); +	struct extraDataCompound_t* xx, * yy; +	coOrd* endPts;  	trkEndPt_p endPt;  	int i;  	int option;  	DIST_T d; -	if ( NormalizeAngle( FindAngle( GetTrkEndPos(trk,0), pos ) - GetTrkEndAngle(trk,1) ) < 180.0 ) +	if (NormalizeAngle(FindAngle(GetTrkEndPos(trk, 0), pos) - GetTrkEndAngle(trk, 1)) < 180.0)  		angle += 90;  	else -		angle -= 90;  +		angle -= 90;  	/*  	 * get all endpoints of current piece and translate them for the new piece  	 */ -	endPts = MyMalloc( GetTrkEndPtCnt( trk ) * sizeof( coOrd )); -	for( i = 0; i < GetTrkEndPtCnt( trk ); i++) { -		Translate( &(endPts[ i ]), GetTrkEndPos( trk, i ), angle, sep ); +	endPts = MyMalloc(GetTrkEndPtCnt(trk) * sizeof(coOrd)); +	for (i = 0; i < GetTrkEndPtCnt(trk); i++) { +		Translate(&(endPts[i]), GetTrkEndPos(trk, i), angle, sep);  	}  	/* -	 * get information about the current piece and copy data  +	 * get information about the current piece and copy data  	 */ -	if( newTrk ) { +	if (newTrk) {  		if (track) { -			endPt = MyMalloc( GetTrkEndPtCnt( trk ) * sizeof( trkEndPt_t )); -			endPt[ 0 ].pos = endPts[ 0 ]; -			endPt[ 0 ].angle = GetTrkEndAngle( trk, 0 ); -			endPt[ 1 ].pos = endPts[ 1 ]; -			endPt[ 1 ].angle = GetTrkEndAngle( trk, 1 ); - -			yy = GetTrkExtraData(trk); - -			DIST_T * radii = NULL; -			if (yy->special == TOcurved) { -				radii = MyMalloc(GetTrkEndPtCnt(trk) * sizeof(DIST_T)); -				for (int i=0;i<GetTrkEndPtCnt( trk );i++) { -					radii[i] = DYNARR_N(DIST_T,yy->u.curved.radii,i); -				} -			} +			endPt = MyMalloc(GetTrkEndPtCnt(trk) * sizeof(trkEndPt_t)); +			endPt[0].pos = endPts[0]; +			endPt[0].angle = GetTrkEndAngle(trk, 0); +			endPt[1].pos = endPts[1]; +			endPt[1].angle = GetTrkEndAngle(trk, 1); -			*newTrk = NewCompound( T_TURNOUT, 0, endPt[ 0 ].pos, endPt[ 0 ].angle + 90.0, yy->title, 2, endPt, radii, yy->pathLen, (char *)yy->paths, yy->segCnt, yy->segs ); -			xx = GetTrkExtraData(*newTrk); +			yy = GET_EXTRA_DATA(trk, T_TURNOUT, extraDataCompound_t); + + +			PATHPTR_T paths = GetPaths(trk); // MakeParallelTurnout +			*newTrk = NewCompound(T_TURNOUT, 0, endPt[0].pos, endPt[0].angle + 90.0, +				yy->title, 2, endPt, paths, +				yy->segCnt, yy->segs); +			xx = GET_EXTRA_DATA(*newTrk, T_TURNOUT, extraDataCompound_t);  			xx->customInfo = yy->customInfo;  			/*	if (connection((int)curTurnoutEp).trk) { @@ -1927,62 +3822,66 @@ static BOOL_T MakeParallelTurnout(  				SetTrkScale( newTrk, curScaleInx );  			} */  			xx->special = yy->special; +			xx->pathOverRide = yy->pathOverRide; +			xx->pathNoCombine = yy->pathNoCombine;  			xx->u = yy->u; -			SetDescriptionOrig( *newTrk ); +			SetDescriptionOrig(*newTrk);  			xx->descriptionOff = zero;  			xx->descriptionSize = zero;  			SetTrkElev(*newTrk, GetTrkElevMode(trk), GetTrkElev(trk)); -			GetTrkEndElev( trk, 0, &option, &d ); -			SetTrkEndElev( *newTrk, 0, option, d, NULL ); -			GetTrkEndElev( trk, 1, &option, &d ); -			SetTrkEndElev( *newTrk, 1, option, d, NULL ); +			GetTrkEndElev(trk, 0, &option, &d); +			SetTrkEndElev(*newTrk, 0, option, d, NULL); +			GetTrkEndElev(trk, 1, &option, &d); +			SetTrkEndElev(*newTrk, 1, option, d, NULL); -			MyFree( endPt ); -		} else { +			MyFree(endPt); +		} +		else {  			tempSegs(0).color = wDrawColorBlack;  			tempSegs(0).width = 0;  			tempSegs_da.cnt = 1; -			tempSegs(0).type = track?SEG_STRTRK:SEG_STRLIN; -			tempSegs(0).u.l.pos[0] = endPts[ 0 ]; -			tempSegs(0).u.l.pos[1] = endPts[ 1 ]; -			*newTrk = MakeDrawFromSeg( zero, 0.0, &tempSegs(0) ); +			tempSegs(0).type = track ? SEG_STRTRK : SEG_STRLIN; +			tempSegs(0).u.l.pos[0] = endPts[0]; +			tempSegs(0).u.l.pos[1] = endPts[1]; +			*newTrk = MakeDrawFromSeg(zero, 0.0, &tempSegs(0));  		} -	} else {  +	} +	else {  		/* draw some temporary track while command is in process */  		tempSegs(0).color = wDrawColorBlack;  		tempSegs(0).width = 0;  		tempSegs_da.cnt = 1; -		tempSegs(0).type = track?SEG_STRTRK:SEG_STRLIN; -		tempSegs(0).u.l.pos[0] = endPts[ 0 ]; -		tempSegs(0).u.l.pos[1] = endPts[ 1 ]; +		tempSegs(0).type = track ? SEG_STRTRK : SEG_STRLIN; +		tempSegs(0).u.l.pos[0] = endPts[0]; +		tempSegs(0).u.l.pos[1] = endPts[1];  	} -	if ( p0R ) *p0R = endPts[ 0 ]; -	if ( p1R ) *p1R = endPts[ 1 ]; +	if (p0R) *p0R = endPts[0]; +	if (p1R) *p1R = endPts[1]; -	MyFree( endPts ); +	MyFree(endPts);  	return TRUE;  } -static wBool_t CompareTurnout( track_cp trk1, track_cp trk2 ) +static wBool_t CompareTurnout(track_cp trk1, track_cp trk2)  { -	struct extraData *xx1 = GetTrkExtraData( trk1 ); -	struct extraData *xx2 = GetTrkExtraData( trk2 ); -	char * cp = message + strlen(message); -	REGRESS_CHECK_POS( "Orig", xx1, xx2, orig ) -	REGRESS_CHECK_ANGLE( "Angle", xx1, xx2, angle ) -	REGRESS_CHECK_INT( "Handlaid", xx1, xx2, handlaid ) -	REGRESS_CHECK_INT( "Flipped", xx1, xx2, flipped ) -	REGRESS_CHECK_INT( "Ungrouped", xx1, xx2, ungrouped ) -	REGRESS_CHECK_INT( "Split", xx1, xx2, split ) -	/* desc orig is not stable -	REGRESS_CHECK_POS( "DescOrig", xx1, xx2, descriptionOrig ) */ -	REGRESS_CHECK_POS( "DescOff", xx1, xx2, descriptionOff ) -	REGRESS_CHECK_POS( "DescSize", xx1, xx2, descriptionSize ) -	return CompareSegs( xx1->segs, xx1->segCnt, xx1->segs, xx1->segCnt ); +	struct extraDataCompound_t* xx1 = GET_EXTRA_DATA(trk1, T_TURNOUT, extraDataCompound_t); +	struct extraDataCompound_t* xx2 = GET_EXTRA_DATA(trk2, T_TURNOUT, extraDataCompound_t); +	char* cp = message + strlen(message); +	REGRESS_CHECK_POS("Orig", xx1, xx2, orig) +		REGRESS_CHECK_ANGLE("Angle", xx1, xx2, angle) +		REGRESS_CHECK_INT("Handlaid", xx1, xx2, handlaid) +		REGRESS_CHECK_INT("Flipped", xx1, xx2, flipped) +		REGRESS_CHECK_INT("Ungrouped", xx1, xx2, ungrouped) +		REGRESS_CHECK_INT("Split", xx1, xx2, split) +		/* desc orig is not stable +		REGRESS_CHECK_POS( "DescOrig", xx1, xx2, descriptionOrig ) */ +		REGRESS_CHECK_POS("DescOff", xx1, xx2, descriptionOff) +		REGRESS_CHECK_POS("DescSize", xx1, xx2, descriptionSize) +		return CompareSegs(xx1->segs, xx1->segCnt, xx1->segs, xx1->segCnt);  }  static trackCmd_t turnoutCmds = { @@ -2022,7 +3921,7 @@ static trackCmd_t turnoutCmds = {  		NULL,  		CompareTurnout }; - +  #ifdef TURNOUTCMD  /*****************************************   * @@ -2032,84 +3931,84 @@ static trackCmd_t turnoutCmds = {  static coOrd maxTurnoutDim; -static void AddTurnout( void ); +static void AddTurnout(void);  static wWin_p turnoutW; -static void RescaleTurnout( void ) +static void RescaleTurnout(void)  {  	DIST_T xscale, yscale; -	wPos_t ww, hh; +	wWinPix_t ww, hh;  	DIST_T w, h; -	wDrawGetSize( turnoutD.d, &ww, &hh ); -	w = ww/turnoutD.dpi; -	h = hh/turnoutD.dpi; -	xscale = maxTurnoutDim.x/w; -	yscale = maxTurnoutDim.y/h; -	turnoutD.scale = max(xscale,yscale); +	wDrawGetSize(turnoutD.d, &ww, &hh); +	w = ww / turnoutD.dpi; +	h = hh / turnoutD.dpi; +	xscale = maxTurnoutDim.x / w; +	yscale = maxTurnoutDim.y / h; +	turnoutD.scale = max(xscale, yscale);  	if (turnoutD.scale == 0.0)  		turnoutD.scale = 1.0; -	turnoutD.size.x = w*turnoutD.scale; -	turnoutD.size.y = h*turnoutD.scale; +	turnoutD.size.x = w * turnoutD.scale; +	turnoutD.size.y = h * turnoutD.scale;  	return;  } -static void TurnoutChange( long changes ) +static void TurnoutChange(long changes)  { -	static char * lastScaleName = NULL; +	static char* lastScaleName = NULL;  	if (turnoutW == NULL)  		return; -	wListSetIndex( turnoutListL, 0 ); -	if ( (!wWinIsVisible(turnoutW)) || -	   ( ((changes&CHANGE_SCALE) == 0 || lastScaleName == curScaleName) && -		  (changes&CHANGE_PARAMS) == 0 ) ) +	wListSetIndex(turnoutListL, 0); +	if ((!wWinIsVisible(turnoutW)) || +		(((changes & CHANGE_SCALE) == 0 || lastScaleName == curScaleName) && +			(changes & CHANGE_PARAMS) == 0))  		return;  	lastScaleName = curScaleName;  	//curTurnout = NULL;  	curTurnoutEp = 0; -	wControlShow( (wControl_p)turnoutListL, FALSE ); -	wListClear( turnoutListL ); +	wControlShow((wControl_p)turnoutListL, FALSE); +	wListClear(turnoutListL);  	maxTurnoutDim.x = maxTurnoutDim.y = 0.0;  	if (turnoutInfo_da.cnt <= 0)  		return; -	curTurnout = TurnoutAdd( LABEL_TABBED|LABEL_MANUF|LABEL_PARTNO|LABEL_DESCR, GetLayoutCurScale(), turnoutListL, &maxTurnoutDim, -1 ); -	wListSetIndex( turnoutListL, turnoutInx ); -	wControlShow( (wControl_p)turnoutListL, TRUE ); +	curTurnout = TurnoutAdd(LABEL_TABBED | LABEL_MANUF | LABEL_PARTNO | LABEL_DESCR, GetLayoutCurScale(), turnoutListL, &maxTurnoutDim, -1); +	wListSetIndex(turnoutListL, turnoutInx); +	wControlShow((wControl_p)turnoutListL, TRUE);  	if (curTurnout == NULL) { -		wDrawClear( turnoutD.d ); +		wDrawClear(turnoutD.d);  		return;  	}  	turnoutD.orig.x = -trackGauge;  	turnoutD.orig.y = -trackGauge; -	maxTurnoutDim.x += 2*trackGauge; -	maxTurnoutDim.y += 2*trackGauge; +	maxTurnoutDim.x += 2 * trackGauge; +	maxTurnoutDim.y += 2 * trackGauge;  	/*RescaleTurnout();*/ -	RedrawTurnout(); +	RedrawTurnout( turnoutD.d, NULL, 0, 0 );  	return;  } -static void RedrawTurnout() +static void RedrawTurnout( wDraw_p d, void * context, wWinPix_t x, wWinPix_t y )  {  	RescaleTurnout(); -LOG( log_turnout, 2, ( "SelTurnout(%s)\n", (curTurnout?curTurnout->title:"<NULL>") ) ) +	LOG(log_turnout, 2, ("SelTurnout(%s)\n", (curTurnout ? curTurnout->title : "<NULL>"))) -	wDrawClear( turnoutD.d ); +		wDrawClear(turnoutD.d);  	if (curTurnout == NULL) {  		return;  	}  	turnoutD.orig.x = curTurnout->orig.x - trackGauge;  	turnoutD.orig.y = (curTurnout->size.y + curTurnout->orig.y) - turnoutD.size.y + trackGauge; -	DrawSegs( &turnoutD, zero, 0.0, curTurnout->segs, curTurnout->segCnt, -					 trackGauge, wDrawColorBlack ); +	DrawSegs(&turnoutD, zero, 0.0, curTurnout->segs, curTurnout->segCnt, +		trackGauge, wDrawColorBlack);  	curTurnoutEp = 0;  	HilightEndPt();  } -static void TurnoutOk( void ) +static void TurnoutOk(void)  {  	AddTurnout();  	Reset(); @@ -2117,33 +4016,33 @@ static void TurnoutOk( void )  static void TurnoutDlgUpdate( -		paramGroup_p pg, -		int inx, -		void * valueP ) +	paramGroup_p pg, +	int inx, +	void* valueP)  { -	turnoutInfo_t * to; -	if ( inx != I_LIST ) return; -	to = (turnoutInfo_t*)wListGetItemContext( (wList_p)pg->paramPtr[inx].control, (wIndex_t)*(long*)valueP ); +	turnoutInfo_t* to; +	if (inx != I_LIST) return; +	to = (turnoutInfo_t*)wListGetItemContext((wList_p)pg->paramPtr[inx].control, (wIndex_t) * (long*)valueP);  	AddTurnout();  	curTurnout = to; -	RedrawTurnout(); -/*	ParamDialogOkActive( &turnoutPG, FALSE ); */ +	RedrawTurnout( turnoutD.d, NULL, 0, 0 ); +	/*	ParamDialogOkActive( &turnoutPG, FALSE ); */  }  static wIndex_t TOpickEndPoint( -		coOrd p, -		turnoutInfo_t *to ) +	coOrd p, +	turnoutInfo_t* to)  {  	wIndex_t inx, i;  	DIST_T d, dd;  	coOrd posI; -	d = FindDistance( p, to->endPt[0].pos ); +	d = FindDistance(p, to->endPt[0].pos);  	inx = 0; -	for ( i=1; i<to->endCnt; i++ ) { +	for (i = 1; i < to->endCnt; i++) {  		posI = to->endPt[i].pos; -		if ((dd=FindDistance(p, posI)) < d) { +		if ((dd = FindDistance(p, posI)) < d) {  			d = dd;  			inx = i;  		} @@ -2152,57 +4051,55 @@ static wIndex_t TOpickEndPoint(  } -static void HilightEndPt( void ) +static void HilightEndPt(void)  {  	coOrd p, s;  	p.x = curTurnout->endPt[(int)curTurnoutEp].pos.x - trackGauge;  	p.y = curTurnout->endPt[(int)curTurnoutEp].pos.y - trackGauge; -	s.x = s.y = trackGauge*2.0 /*+ turnoutD.minSize*/; -	wDrawSetTempMode( turnoutD.d, TRUE ); -	DrawHilight( &turnoutD, p, s, FALSE ); -	wDrawSetTempMode( turnoutD.d, FALSE ); +	s.x = s.y = trackGauge * 2.0 /*+ turnoutD.minSize*/; +	DrawHilight(&turnoutD, p, s, FALSE);  }  static void SelTurnoutEndPt( -		wIndex_t action, -		coOrd pos ) +	wIndex_t action, +	coOrd pos)  {  	if (action != C_DOWN) return; -	curTurnoutEp = TOpickEndPoint( pos, curTurnout ); +	curTurnoutEp = TOpickEndPoint(pos, curTurnout);  	HilightEndPt(); -LOG( log_turnout, 3, (" selected (action=%d) %ld\n", action, curTurnoutEp ) ) +	LOG(log_turnout, 3, (" selected (action=%d) %ld\n", action, curTurnoutEp))  }  #endif - +  /****************************************   *   * GRAPHICS COMMANDS   *   */ -/* - * STATE INFO - */ + /* +  * STATE INFO +  */  static struct { -		int state; -		coOrd pos; -		coOrd place; -		track_p trk; -		ANGLE_T angle; -		coOrd rot0, rot1; -		} Dto; +	int state; +	coOrd pos; +	coOrd place; +	track_p trk; +	ANGLE_T angle; +	coOrd rot0, rot1; +} Dto;  static dynArr_t vector_da;  #define vector(N) DYNARR_N( vector_t, vector_da, N )  typedef struct { -		DIST_T off; -		ANGLE_T angle; -		EPINX_T ep; -		track_p trk; -		} vector_t; +	DIST_T off; +	ANGLE_T angle; +	EPINX_T ep; +	track_p trk; +} vector_t;  /*   * PlaceTurnoutTrial @@ -2216,13 +4113,13 @@ typedef struct {   * OUT Vector   - An array of end points positions and offsets   */  static void PlaceTurnoutTrial( -		track_p *trkR, -		coOrd *posR, -		ANGLE_T *angle1R, -		ANGLE_T *angle2R, -		int *connCntR, -		DIST_T *maxDR, -		vector_t *v ) +	track_p* trkR, +	coOrd* posR, +	ANGLE_T* angle1R, +	ANGLE_T* angle2R, +	int* connCntR, +	DIST_T* maxDR, +	vector_t* v)  {  	coOrd pos = *posR;  	ANGLE_T aa; @@ -2235,82 +4132,86 @@ static void PlaceTurnoutTrial(  	DIST_T d, maxD = 0;  	coOrd testP = pos; -	if (*trkR && (GetTrkDistance(*trkR,&testP)<trackGauge)) {   //Have Track, stick with it unless outside bounds +	if (*trkR && (GetTrkDistance(*trkR, &testP) < trackGauge)) {   //Have Track, stick with it unless outside bounds  		trk = *trkR;  		pos = testP; -	} else *trkR = trk = OnTrack( &pos, FALSE, TRUE ); -    if ( (trk) != NULL && -		 !QueryTrack(trk,Q_CANNOT_PLACE_TURNOUT) && -		 (ep0 = PickEndPoint( pos, trk )) >= 0 && -		 ! ( GetTrkType(trk) == T_TURNOUT && -			 (trk1=GetTrkEndTrk(trk,ep0)) && -			 GetTrkType(trk1) == T_TURNOUT) && -		 ! GetLayerFrozen(GetTrkLayer(trk)) && -		 ! GetLayerModule(GetTrkLayer(trk))) { -		epPos = GetTrkEndPos( trk, ep0 ); -		d = FindDistance( pos, epPos ); +	} +	else *trkR = trk = OnTrack(&pos, FALSE, TRUE); +	if ((trk) != NULL && +		!QueryTrack(trk, Q_CANNOT_PLACE_TURNOUT) && +		(ep0 = PickEndPoint(pos, trk)) >= 0 && +		!(GetTrkType(trk) == T_TURNOUT && +			(trk1 = GetTrkEndTrk(trk, ep0)) && +			GetTrkType(trk1) == T_TURNOUT) && +		!GetLayerFrozen(GetTrkLayer(trk)) && +		!GetLayerModule(GetTrkLayer(trk))) { +		epPos = GetTrkEndPos(trk, ep0); +		d = FindDistance(pos, epPos);  		if (d <= minLength)  			pos = epPos; -		if ( GetTrkType(trk) == T_TURNOUT ) {				//Only on the end -			ep0 = ep1 = PickEndPoint( pos, trk ); -			angle = GetTrkEndAngle( trk, ep0 ); -		} else { -			angle = GetAngleAtPoint( trk, pos, &ep0, &ep1 ); -			if (ep0==1) angle = NormalizeAngle(angle+180);      //Reverse if curve backwards -		} -		angle = NormalizeAngle( angle + 180.0 ); -		if ( NormalizeAngle( FindAngle( pos, *posR ) - angle ) < 180.0 && ep0 != ep1 ) -			angle = NormalizeAngle( angle + 180 ); +		if (GetTrkType(trk) == T_TURNOUT) {				//Only on the end +			ep0 = ep1 = PickEndPoint(pos, trk); +			angle = GetTrkEndAngle(trk, ep0); +		} +		else { +			angle = GetAngleAtPoint(trk, pos, &ep0, &ep1); +			if (ep0 == 1) angle = NormalizeAngle(angle + 180);      //Reverse if curve backwards +		} +		angle = NormalizeAngle(angle + 180.0); +		if (NormalizeAngle(FindAngle(pos, *posR) - angle) < 180.0 && ep0 != ep1) +			angle = NormalizeAngle(angle + 180);  		*angle2R = angle;  		epPos = curTurnout->endPt[(int)curTurnoutEp].pos; -		*angle1R = angle = NormalizeAngle( angle - curTurnout->endPt[(int)curTurnoutEp].angle ); -		Rotate( &epPos, zero, angle ); +		*angle1R = angle = NormalizeAngle(angle - curTurnout->endPt[(int)curTurnoutEp].angle); +		Rotate(&epPos, zero, angle);  		pos.x -= epPos.x;  		pos.y -= epPos.y;  		*posR = pos;			//The place the Turnout end sits -LOG( log_turnout, 3, ( "placeTurnout T%d (%0.3f %0.3f) A%0.3f\n", -				GetTrkIndex(trk), pos.x, pos.y, angle ) ) -		/*InfoMessage( "Turnout(%d): Angle=%0.3f", GetTrkIndex(trk), angle );*/ -		track_p ctrk = NULL; +		LOG(log_turnout, 3, ("placeTurnout T%d (%0.3f %0.3f) A%0.3f\n", +			GetTrkIndex(trk), pos.x, pos.y, angle)) +			/*InfoMessage( "Turnout(%d): Angle=%0.3f", GetTrkIndex(trk), angle );*/ +			track_p ctrk = NULL;  		int ccnt = 0; -		DIST_T clarge = 100000; -		for (i=0;i<curTurnout->endCnt;i++) { +		DIST_T clarge = DIST_INF; +		for (i = 0; i < curTurnout->endCnt; i++) {  			posI = curTurnout->endPt[i].pos; -			epPos = AddCoOrd( pos, posI, angle ); -			epAngle = NormalizeAngle( curTurnout->endPt[i].angle + angle ); +			epPos = AddCoOrd(pos, posI, angle); +			epAngle = NormalizeAngle(curTurnout->endPt[i].angle + angle);  			conPos = epPos;  			if ((trk = OnTrack(&conPos, FALSE, TRUE)) != NULL &&  				!GetLayerFrozen(GetTrkLayer(trk)) &&  				!GetLayerModule(GetTrkLayer(trk))) { -				v->off = FindDistance( epPos, conPos ); -				v->angle = FindAngle( epPos, conPos ); -				if ( GetTrkType(trk) == T_TURNOUT ) { -					ep0 = ep1 = PickEndPoint( conPos, trk ); -					aa = GetTrkEndAngle( trk, ep0 ); -				} else { -					aa = GetAngleAtPoint( trk, conPos, &ep0, &ep1 ); +				v->off = FindDistance(epPos, conPos); +				v->angle = FindAngle(epPos, conPos); +				if (GetTrkType(trk) == T_TURNOUT) { +					ep0 = ep1 = PickEndPoint(conPos, trk); +					aa = GetTrkEndAngle(trk, ep0); +				} +				else { +					aa = GetAngleAtPoint(trk, conPos, &ep0, &ep1);  					if (ep0) 					//Backwards - so reverse -						aa = NormalizeAngle(aa+180); +						aa = NormalizeAngle(aa + 180);  				}  				v->ep = i; -				aa = fabs(DifferenceBetweenAngles( aa, epAngle )); -				if (QueryTrack(trk,Q_IS_CORNU) ) {			//Make sure only two conns to each Cornu -					int k=0; +				aa = fabs(DifferenceBetweenAngles(aa, epAngle)); +				if (QueryTrack(trk, Q_IS_CORNU)) {			//Make sure only two conns to each Cornu +					int k = 0;  					v->trk = trk; -					for (int j=0; j<i;j++) { +					for (int j = 0; j < i; j++) {  						if (vector(j).trk == trk) k++;  					} -					if (k<2) {						//Already two conns to this track +					if (k < 2) {						//Already two conns to this track  						connCnt++;  						if (v->off > maxD)  							maxD = v->off;  						v++;  					} -				} else if (( IsClose(v->off) && (aa<connectAngle || aa>180-connectAngle) && -				  !( GetTrkType(trk) == T_TURNOUT && -						 (trk1=GetTrkEndTrk(trk,ep0)) && -						 GetTrkType(trk1) == T_TURNOUT )) ) { +				} +				else if ((IsClose(v->off) && (aa < connectAngle || aa>180 - connectAngle) && +					!(GetTrkType(trk) == T_TURNOUT && +						(trk1 = GetTrkEndTrk(trk, ep0)) && +						GetTrkType(trk1) == T_TURNOUT))) {  					if (v->off > maxD)  						maxD = v->off;  					connCnt++; @@ -2318,7 +4219,8 @@ LOG( log_turnout, 3, ( "placeTurnout T%d (%0.3f %0.3f) A%0.3f\n",  				}  			}  		} -	} else { +	} +	else {  		trk = NULL;  		*trkR = NULL;  	} @@ -2328,51 +4230,51 @@ LOG( log_turnout, 3, ( "placeTurnout T%d (%0.3f %0.3f) A%0.3f\n",  static void PlaceTurnout( -		coOrd pos, track_p trk ) +	coOrd pos, track_p trk)  {  	coOrd p, pos1, pos2;  	track_p trk1, trk2;  	ANGLE_T a, a1, a2, a3;  	int i, connCnt1, connCnt2;  	DIST_T d, maxD1, maxD2, sina; -	vector_t *V, * maxV; +	vector_t* V, * maxV; + -	  	pos1 = Dto.place = Dto.pos = pos; -LOG( log_turnout, 1, ( "Place Turnout @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +	LOG(log_turnout, 1, ("Place Turnout @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  	if (curTurnoutEp >= (long)curTurnout->endCnt)  		curTurnoutEp = 0; -	DYNARR_SET( vector_t, vector_da, curTurnout->endCnt ); +	DYNARR_SET(vector_t, vector_da, curTurnout->endCnt);  	if (trk) trk1 = trk;  	else trk1 = NULL; -	PlaceTurnoutTrial( &trk1, &pos1, &a1, &a2, &connCnt1, &maxD1, &vector(0) ); +	PlaceTurnoutTrial(&trk1, &pos1, &a1, &a2, &connCnt1, &maxD1, &vector(0));  	if (connCnt1 > 0) {  		Dto.pos = pos1;		//First track pos -LOG( log_turnout, 1, ( " trial 1 @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +		LOG(log_turnout, 1, (" trial 1 @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  		Dto.trk = trk1;		//Track  		Dto.angle = a1;		//Angle of track to put down -		if ( ((MyGetKeyState()&WKEY_SHIFT)==0) && (connCnt1 > 1) && (maxD1 >= 0.001) ) {  //Adjust if not Shift +		if (((MyGetKeyState() & WKEY_SHIFT) == 0) && (connCnt1 > 1) && (maxD1 >= 0.001)) {  //Adjust if not Shift  			maxV = &vector(0); -			for ( i=1; i<connCnt1; i++ ) {		//Ignore first point +			for (i = 1; i < connCnt1; i++) {		//Ignore first point  				V = &vector(i); -				if ( V->off > maxV->off ) { +				if (V->off > maxV->off) {  					maxV = V;  				}  			} -			a3 = NormalizeAngle( Dto.angle + curTurnout->endPt[maxV->ep].angle ); -			a = NormalizeAngle( a2 - a3 ); +			a3 = NormalizeAngle(Dto.angle + curTurnout->endPt[maxV->ep].angle); +			a = NormalizeAngle(a2 - a3);  			sina = sin(D2R(a));  			if (fabs(sina) > 0.01) { -				d = maxV->off/sina; -				if (NormalizeAngle( maxV->angle - a3) > 180) +				d = maxV->off / sina; +				if (NormalizeAngle(maxV->angle - a3) > 180)  					d = -d; -				Translate( &pos2, pos, a2, d ); +				Translate(&pos2, pos, a2, d);  				trk2 = trk1; -				PlaceTurnoutTrial( &trk2, &pos2, &a2, &a, &connCnt2, &maxD2, &vector(0) ); -				if ( connCnt2 >= connCnt1 && maxD2 < maxD1 ) { +				PlaceTurnoutTrial(&trk2, &pos2, &a2, &a, &connCnt2, &maxD2, &vector(0)); +				if (connCnt2 >= connCnt1 && maxD2 < maxD1) {  					Dto.pos = pos2; -LOG( log_turnout, 1, ( " trial 2 @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +					LOG(log_turnout, 1, (" trial 2 @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  					Dto.trk = trk2;  					Dto.angle = a2;  					maxD1 = maxD2; @@ -2381,37 +4283,37 @@ LOG( log_turnout, 1, ( " trial 2 @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) );  			}  		}  	} -	if ( connCnt1 > 0 ) { -		FormatCompoundTitle( listLabels, curTurnout->title ); -		InfoMessage( _("%d connections, max distance %0.3f (%s)"), -				connCnt1, PutDim(maxD1), message ); -	} else { +	if (connCnt1 > 0) { +		FormatCompoundTitle(listLabels, curTurnout->title); +		InfoMessage(_("%d connections, max distance %0.3f (%s)"), +			connCnt1, PutDim(maxD1), message); +	} +	else {  		Dto.trk = NULL; -		FormatCompoundTitle( listLabels, curTurnout->title ); -		InfoMessage( _("0 connections (%s)"), message ); +		FormatCompoundTitle(listLabels, curTurnout->title); +		InfoMessage(_("0 connections (%s)"), message);  		p = curTurnout->endPt[(int)curTurnoutEp].pos; -		Rotate( &p, zero, Dto.angle ); +		Rotate(&p, zero, Dto.angle);  		Dto.pos.x = pos.x - p.x;  		Dto.pos.y = pos.y - p.y; -LOG( log_turnout, 1, ( " final @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +		LOG(log_turnout, 1, (" final @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  	}  } -static void AddTurnout( void ) +static void AddTurnout(void)  {  	track_p newTrk;  	track_p trk, trk1; -	struct extraData *xx; +	struct extraDataCompound_t* xx;  	coOrd epPos;  	DIST_T d;  	ANGLE_T a, aa;  	EPINX_T ep0, ep1, epx, epy; -	wIndex_t i,j; -	wIndex_t titleLen; +	wIndex_t i, j;  	typedef struct {  		track_p trk;  		EPINX_T ep; -		} junk_t; +	} junk_t;  	static dynArr_t connection_da;  	static dynArr_t leftover_da;  #define connection(N) DYNARR_N( junk_t, connection_da, N ) @@ -2425,27 +4327,26 @@ static void AddTurnout( void )  		return;  	if (curTurnout->segCnt < 1 || curTurnout->endCnt < 1) { -		AbortProg( "addTurnout: bad cnt" ); +		AbortProg("addTurnout: bad cnt");  	} -	UndoStart( _("Place New Turnout"), "addTurnout" ); -	titleLen = strlen( curTurnout->title ); +	UndoStart(_("Place New Turnout"), "addTurnout"); -	DYNARR_SET( trkEndPt_t, tempEndPts_da, curTurnout->endCnt ); -	DYNARR_SET( junk_t, connection_da, curTurnout->endCnt ); -	DYNARR_SET( junk_t, leftover_da, curTurnout->endCnt ); +	DYNARR_SET(trkEndPt_t, tempEndPts_da, curTurnout->endCnt); +	DYNARR_SET(junk_t, connection_da, curTurnout->endCnt); +	DYNARR_SET(junk_t, leftover_da, curTurnout->endCnt); -	for (i=0; i<curTurnout->endCnt; i++ ) { +	for (i = 0; i < curTurnout->endCnt; i++) {  		coOrd posI;  		posI = curTurnout->endPt[i].pos; -		tempEndPts(i).pos = AddCoOrd( Dto.pos, posI, Dto.angle ); -		tempEndPts(i).angle = NormalizeAngle( curTurnout->endPt[i].angle + Dto.angle ); +		tempEndPts(i).pos = AddCoOrd(Dto.pos, posI, Dto.angle); +		tempEndPts(i).angle = NormalizeAngle(curTurnout->endPt[i].angle + Dto.angle);  	} -	AuditTracks( "addTurnout begin" ); +	AuditTracks("addTurnout begin"); -	for (i=0;i<curTurnout->endCnt;i++) { -		AuditTracks( "addTurnout [%d]", i ); +	for (i = 0; i < curTurnout->endCnt; i++) { +		AuditTracks("addTurnout [%d]", i);  		connection(i).trk = leftover(i).trk = NULL;  		connection(i).ep = -1;  		leftover(i).ep = -1; @@ -2453,70 +4354,72 @@ static void AddTurnout( void )  		epPos = tempEndPts(i).pos;  		if ((trk = OnTrack(&epPos, FALSE, TRUE)) != NULL &&    //Adjust epPos onto existing track  			(!GetLayerFrozen(GetTrkLayer(trk))) && -			(!GetLayerModule(GetTrkLayer(trk)))  && -			(!QueryTrack(trk,Q_CANNOT_PLACE_TURNOUT)) ) { -LOG( log_turnout, 1, ( "ep[%d] on T%d @(%0.3f %0.3f)\n", -					i, GetTrkIndex(trk), epPos.x, epPos.y ) ) -			DIST_T dd = 10000.0; +			(!GetLayerModule(GetTrkLayer(trk))) && +			(!QueryTrack(trk, Q_CANNOT_PLACE_TURNOUT))) { +			LOG(log_turnout, 1, ("ep[%d] on T%d @(%0.3f %0.3f)\n", +				i, GetTrkIndex(trk), epPos.x, epPos.y)) +				DIST_T dd = DIST_INF;  			int nearest = -1; -			for (int j=0;j<curTurnout->endCnt;j++) { -				if (j<i && (connection(j).trk == trk)) { +			for (int j = 0; j < curTurnout->endCnt; j++) { +				if (j < i && (connection(j).trk == trk)) {  					nearest = -1;  					goto nextEnd;  //Track already chosen in use  				} -				if (dd>FindDistance(epPos,tempEndPts(j).pos)) { -					dd = FindDistance(epPos,tempEndPts(j).pos); +				if (dd > FindDistance(epPos, tempEndPts(j).pos)) { +					dd = FindDistance(epPos, tempEndPts(j).pos);  					nearest = j;  				}  			}  			if (nearest != i) continue;    //Not this one -			d = FindDistance( tempEndPts(i).pos, epPos ); -			if ( GetTrkType(trk) == T_TURNOUT ) { -				ep0 = ep1 = PickEndPoint( epPos, trk ); -				a = GetTrkEndAngle( trk, ep0 ); -			} else { -				a = GetAngleAtPoint( trk, epPos, &ep0, &ep1 ); -			} -			aa = fabs(DifferenceBetweenAngles( a , tempEndPts(i).angle)); -			if ((QueryTrack(trk,Q_IS_CORNU) && (d<trackGauge*2)) || -				(( IsClose(d) &&  ( ((ep0!=ep1) && (aa<=connectAngle)) || ((aa<=connectAngle) || (aa>180-connectAngle)) ) && -				 ! ( GetTrkType(trk) == T_TURNOUT && -				   (trk1=GetTrkEndTrk(trk,ep0)) && -				   GetTrkType(trk1) == T_TURNOUT )) ) ) { +			d = FindDistance(tempEndPts(i).pos, epPos); +			if (GetTrkType(trk) == T_TURNOUT) { +				ep0 = ep1 = PickEndPoint(epPos, trk); +				a = GetTrkEndAngle(trk, ep0); +			} +			else { +				a = GetAngleAtPoint(trk, epPos, &ep0, &ep1); +			} +			aa = fabs(DifferenceBetweenAngles(a, tempEndPts(i).angle)); +			if ((QueryTrack(trk, Q_IS_CORNU) && (d < trackGauge * 2)) || +				((IsClose(d) && (((ep0 != ep1) && (aa <= connectAngle)) || ((aa <= connectAngle) || (aa > 180 - connectAngle))) && +					!(GetTrkType(trk) == T_TURNOUT && +						(trk1 = GetTrkEndTrk(trk, ep0)) && +						GetTrkType(trk1) == T_TURNOUT)))) {  				/* ... if they are close enough to a track and line up */ -				if (aa<90) { -				   epx = ep1; -				   epy = ep0; -				} else { -				   epx = ep0; -				   epy = ep1; +				if (aa < 90) { +					epx = ep1; +					epy = ep0;  				} -LOG( log_turnout, 1, ( "   Attach! epx=%d\n", epx ) ) -				if ( (epx != epy) && -					((d=FindDistance(GetTrkEndPos(trk,epy), epPos)) < minLength) && -					((trk1=GetTrkEndTrk(trk,epy)) != NULL) ) { -					epx = GetEndPtConnectedToMe( trk1, trk ); -					trk = trk1; +				else { +					epx = ep0; +					epy = ep1;  				} +				LOG(log_turnout, 1, ("   Attach! epx=%d\n", epx)) +					if ((epx != epy) && +						((d = FindDistance(GetTrkEndPos(trk, epy), epPos)) < minLength) && +						((trk1 = GetTrkEndTrk(trk, epy)) != NULL)) { +						epx = GetEndPtConnectedToMe(trk1, trk); +						trk = trk1; +					}  				/* split the track at the intersection point */ -		AuditTracks( "addTurnout [%d] before splitTrack", i ); -				if (SplitTrack( trk, epPos, epx, &leftover(i).trk, TRUE )) { -		AuditTracks( "addTurnout [%d], after splitTrack", i ); +				AuditTracks("addTurnout [%d] before splitTrack", i); +				if (SplitTrack(trk, epPos, epx, &leftover(i).trk, TRUE)) { +					AuditTracks("addTurnout [%d], after splitTrack", i);  					/* remember so we can fix up connection later */  					connection(i).trk = trk;  					connection(i).ep = epx;  					if (leftover(i).trk != NULL) { -						leftover(i).ep = 1-epx; +						leftover(i).ep = 1 - epx;  						/* did we already split this track? */ -						for (j=0;j<i;j++) { -							if ( connection(i).trk == leftover(j).trk ) { +						for (j = 0; j < i; j++) { +							if (connection(i).trk == leftover(j).trk) {  								/* yes.  Remove the latest leftover piece */ -LOG( log_turnout, 1, ( "   deleting leftover T%d\n", -										GetTrkIndex(leftover(i).trk) ) ) -		AuditTracks( "addTurnout [%d] before delete", i ); -								UndrawNewTrack( leftover(i).trk ); -								DeleteTrack( leftover(i).trk, FALSE ); -		AuditTracks( "addTurnout [%d] before delete", i ); +								LOG(log_turnout, 1, ("   deleting leftover T%d\n", +									GetTrkIndex(leftover(i).trk))) +									AuditTracks("addTurnout [%d] before delete", i); +								UndrawNewTrack(leftover(i).trk); +								DeleteTrack(leftover(i).trk, FALSE); +								AuditTracks("addTurnout [%d] before delete", i);  								leftover(i).trk = NULL;  								leftover(i).ep = -1;  								leftover(j).trk = NULL; //Forget this leftover @@ -2528,112 +4431,110 @@ LOG( log_turnout, 1, ( "   deleting leftover T%d\n",  				}  			}  		} -nextEnd:; +	nextEnd:;  	} -	AuditTracks( "addTurnout after loop" ); +	AuditTracks("addTurnout after loop");  	/*  	 * copy data */ -	newTrk = NewCompound( T_TURNOUT, 0, Dto.pos, Dto.angle, curTurnout->title, tempEndPts_da.cnt, &tempEndPts(0), NULL, curTurnout->pathLen, (char *)curTurnout->paths, curTurnout->segCnt, curTurnout->segs ); -	xx = GetTrkExtraData(newTrk); +	newTrk = NewCompound(T_TURNOUT, 0, Dto.pos, Dto.angle, curTurnout->title, tempEndPts_da.cnt, &tempEndPts(0), GetParamPaths(curTurnout), curTurnout->segCnt, curTurnout->segs); +	xx = GET_EXTRA_DATA(newTrk, T_TURNOUT, extraDataCompound_t);  	xx->customInfo = curTurnout->customInfo;  	if (connection((int)curTurnoutEp).trk) { -		CopyAttributes( connection((int)curTurnoutEp).trk, newTrk ); -		SetTrkScale( newTrk, GetLayoutCurScale()); +		CopyAttributes(connection((int)curTurnoutEp).trk, newTrk); +		SetTrkScale(newTrk, GetLayoutCurScale());  	}  	xx->special = curTurnout->special; -	if (xx->special == TOcurved) { -		DYNARR_SET(DIST_T,xx->u.curved.radii,curTurnout->endCnt); -		for (int i=0;i<curTurnout->endCnt;i++) { -			DYNARR_N(DIST_T,xx->u.curved.radii,i) = DYNARR_N(DIST_T,curTurnout->u.curved.radii,i); -		} -	}  	xx->u = curTurnout->u; +	xx->pathOverRide = curTurnout->pathOverRide; +	xx->pathNoCombine = curTurnout->pathNoCombine;  	/* Make the connections */  	visible = FALSE;  	no_ties = FALSE;  	noConnections = TRUE; -	AuditTracks( "addTurnout T%d before connection", GetTrkIndex(newTrk) ); -	for (i=0;i<curTurnout->endCnt;i++) { -		if ( connection(i).trk != NULL ) { -			if (GetTrkEndTrk(connection(i).trk,connection(i).ep)) continue; -			p0 = GetTrkEndPos( newTrk, i ); -			p1 = GetTrkEndPos( connection(i).trk, connection(i).ep ); -			ANGLE_T a0 = GetTrkEndAngle( newTrk, i); -			ANGLE_T a1 = GetTrkEndAngle( connection(i).trk, connection(i).ep ); -			ANGLE_T a = fabs(DifferenceBetweenAngles(a0+180,a1)); -			d = FindDistance( p0, p1 ); -			if (QueryTrack(connection(i).trk,Q_IS_CORNU)) { -				ANGLE_T a = DifferenceBetweenAngles(FindAngle(p0,p1),a0); -				if (IsClose(d) || fabs(a)<=90.0) { +	AuditTracks("addTurnout T%d before connection", GetTrkIndex(newTrk)); +	for (i = 0; i < curTurnout->endCnt; i++) { +		if (connection(i).trk != NULL) { +			if (GetTrkEndTrk(connection(i).trk, connection(i).ep)) continue; +			p0 = GetTrkEndPos(newTrk, i); +			p1 = GetTrkEndPos(connection(i).trk, connection(i).ep); +			ANGLE_T a0 = GetTrkEndAngle(newTrk, i); +			ANGLE_T a1 = GetTrkEndAngle(connection(i).trk, connection(i).ep); +			ANGLE_T a = fabs(DifferenceBetweenAngles(a0 + 180, a1)); +			d = FindDistance(p0, p1); +			if (QueryTrack(connection(i).trk, Q_IS_CORNU)) { +				ANGLE_T a = DifferenceBetweenAngles(FindAngle(p0, p1), a0); +				if (IsClose(d) || fabs(a) <= 90.0) {  					trk1 = connection(i).trk;  					ep0 = connection(i).ep; -					if (GetTrkEndTrk(trk1,ep0)) continue; -					DrawEndPt( &mainD, trk1, ep0, wDrawColorWhite ); +					if (GetTrkEndTrk(trk1, ep0)) continue; +					DrawEndPt(&mainD, trk1, ep0, wDrawColorWhite);  					trackParams_t params; -					GetTrackParams( PARAMS_EXTEND, newTrk, GetTrkEndPos(newTrk,i), ¶ms); -					SetCornuEndPt(trk1, ep0, GetTrkEndPos(newTrk,i), params.arcP, NormalizeAngle(params.angle+180.0), params.arcR); -					ConnectTracks(newTrk,i,trk1,ep0); -					DrawEndPt( &mainD, trk1, ep0, wDrawColorBlack ); +					GetTrackParams(PARAMS_EXTEND, newTrk, GetTrkEndPos(newTrk, i), ¶ms); +					SetCornuEndPt(trk1, ep0, GetTrkEndPos(newTrk, i), params.arcP, NormalizeAngle(params.angle + 180.0), params.arcR); +					ConnectTracks(newTrk, i, trk1, ep0); +					DrawEndPt(&mainD, trk1, ep0, wDrawColorBlack);  				} -			} else if ( d < connectDistance && (a<=connectAngle)) { +			} +			else if (d < connectDistance && (a <= connectAngle)) {  				noConnections = FALSE;  				trk1 = connection(i).trk;  				ep0 = connection(i).ep; -				DrawEndPt( &mainD, trk1, ep0, wDrawColorWhite ); -				ConnectTracks( newTrk, i, trk1, ep0 ); +				DrawEndPt(&mainD, trk1, ep0, wDrawColorWhite); +				ConnectTracks(newTrk, i, trk1, ep0);  				visible |= GetTrkVisible(trk1);  				no_ties |= GetTrkNoTies(trk1); -				DrawEndPt( &mainD, trk1, ep0, wDrawColorBlack ); +				DrawEndPt(&mainD, trk1, ep0, wDrawColorBlack);  			}  		}  	}  	if (noConnections)  		visible = TRUE; -	SetTrkVisible( newTrk, visible); +	SetTrkVisible(newTrk, visible);  	SetTrkNoTies(newTrk, no_ties);  	SetTrkBridge(newTrk, FALSE); -	AuditTracks( "addTurnout T%d before dealing with leftovers", GetTrkIndex(newTrk) ); +	AuditTracks("addTurnout T%d before dealing with leftovers", GetTrkIndex(newTrk));  	/* deal with the leftovers */ -	for (i=0;i<curTurnout->endCnt;i++) { -		if ( (trk=leftover(i).trk) != NULL && !IsTrackDeleted(trk) ) { +	for (i = 0; i < curTurnout->endCnt; i++) { +		if ((trk = leftover(i).trk) != NULL) { +			ASSERT( !IsTrackDeleted(trk) );  			/* move endPt beyond the turnout */  			/* it it is short then delete it */  			coOrd off;  			DIST_T maxX;  			track_p lt = leftover(i).trk; -			if (QueryTrack(lt,Q_IS_CORNU)) { +			if (QueryTrack(lt, Q_IS_CORNU)) {  				UndrawNewTrack(lt); -				DeleteTrack(lt,TRUE); +				DeleteTrack(lt, TRUE);  				leftover(i).trk = NULL;  				continue;  			} -			EPINX_T ep, le = leftover(i).ep, nearest_ep =-1; +			EPINX_T ep, le = leftover(i).ep, nearest_ep = -1;  			coOrd pos, nearest_pos = zero;  			ANGLE_T nearest_angle = 0.0;  			DIST_T nearest_radius = 0.0;  			coOrd nearest_center = zero;  			trackParams_t params;  			maxX = 0.0; -			DIST_T dd = 10000.0; -			a = NormalizeAngle( GetTrkEndAngle(lt,le) + 180.0 ); -			for (ep=0; ep<curTurnout->endCnt; ep++) { -				FindPos( &off, NULL, GetTrkEndPos(newTrk,ep), GetTrkEndPos(lt,le), a, 100000.0 ); -				pos = GetTrkEndPos(newTrk,ep); +			DIST_T dd = DIST_INF; +			a = NormalizeAngle(GetTrkEndAngle(lt, le) + 180.0); +			for (ep = 0; ep < curTurnout->endCnt; ep++) { +				FindPos(&off, NULL, GetTrkEndPos(newTrk, ep), GetTrkEndPos(lt, le), a, DIST_INF); +				pos = GetTrkEndPos(newTrk, ep);  				DIST_T d = GetTrkDistance(lt, &pos); -				if ((d<dd) && ( d<trackGauge/2)) { -					ANGLE_T a = GetTrkEndAngle( lt, le ); -					ANGLE_T a2 = fabs(DifferenceBetweenAngles(GetTrkEndAngle(newTrk,ep),a+180)); -					if (GetTrkEndTrk(newTrk,ep)==NULL) { //Not if joined already -						if (a2<90 && QueryTrack(lt,Q_IS_CORNU)) { //And Cornu in the right direction -							GetTrackParams( PARAMS_EXTEND, newTrk, GetTrkEndPos(newTrk,ep), ¶ms); -							nearest_pos = GetTrkEndPos(newTrk,ep); -							nearest_angle = NormalizeAngle(params.angle+180.0); +				if ((d < dd) && (d < trackGauge / 2)) { +					ANGLE_T a = GetTrkEndAngle(lt, le); +					ANGLE_T a2 = fabs(DifferenceBetweenAngles(GetTrkEndAngle(newTrk, ep), a + 180)); +					if (GetTrkEndTrk(newTrk, ep) == NULL) { //Not if joined already +						if (a2 < 90 && QueryTrack(lt, Q_IS_CORNU)) { //And Cornu in the right direction +							GetTrackParams(PARAMS_EXTEND, newTrk, GetTrkEndPos(newTrk, ep), ¶ms); +							nearest_pos = GetTrkEndPos(newTrk, ep); +							nearest_angle = NormalizeAngle(params.angle + 180.0);  							nearest_radius = params.arcR;  							nearest_center = params.arcP;  							nearest_ep = ep; @@ -2646,30 +4547,33 @@ nextEnd:;  			}  			maxX += trackGauge;  			pos = Dto.pos; -			if (QueryTrack(lt,Q_IS_CORNU)) { -				if (nearest_ep >=0) { +			if (QueryTrack(lt, Q_IS_CORNU)) { +				if (nearest_ep >= 0) {  					SetCornuEndPt(lt, le, nearest_pos, nearest_center, nearest_angle, nearest_radius); -					ConnectTracks(newTrk,nearest_ep,lt,le); -				} else { +					ConnectTracks(newTrk, nearest_ep, lt, le); +				} +				else {  					UndrawNewTrack(lt); -					DeleteTrack(lt,TRUE); +					DeleteTrack(lt, TRUE); +					leftover(i).trk = NULL;  				} -			} else { -	AuditTracks( "addTurnout T%d[%d] before trimming L%d[%d]", GetTrkIndex(newTrk), i, GetTrkIndex(lt), le ); -				wBool_t rc = TrimTrack( lt, le, maxX, nearest_pos, nearest_angle, nearest_radius, nearest_center ); -	AuditTracks( "addTurnout T%d[%d] after trimming L%d[%d]", GetTrkIndex(newTrk), i, GetTrkIndex(lt), le ); +			} +			else { +				AuditTracks("addTurnout T%d[%d] before trimming L%d[%d]", GetTrkIndex(newTrk), i, GetTrkIndex(lt), le); +				wBool_t rc = TrimTrack(lt, le, maxX, nearest_pos, nearest_angle, nearest_radius, nearest_center); +				AuditTracks("addTurnout T%d[%d] after trimming L%d[%d]", GetTrkIndex(newTrk), i, GetTrkIndex(lt), le);  			}  		}  	} -	SetDescriptionOrig( newTrk ); +	SetDescriptionOrig(newTrk);  	xx->descriptionOff = zero;  	xx->descriptionSize = zero; -	DrawNewTrack( newTrk ); +	DrawNewTrack(newTrk); -	AuditTracks( "addTurnout T%d returns", GetTrkIndex(newTrk) ); +	AuditTracks("addTurnout T%d returns", GetTrkIndex(newTrk));  	UndoEnd();  	Dto.state = 0;  	Dto.trk = NULL; @@ -2677,14 +4581,14 @@ nextEnd:;  } -static void TurnoutRotate( void * pangle ) +static void TurnoutRotate(void* pangle)  {  	if (Dto.state == 0)  		return; -	ANGLE_T angle = (ANGLE_T)(long)pangle; +	ANGLE_T angle = (ANGLE_T)VP2L(pangle);  	angle /= 1000.0;  	Dto.pos = cmdMenuPos; -	Rotate( &Dto.pos, cmdMenuPos, angle ); +	Rotate(&Dto.pos, cmdMenuPos, angle);  	Dto.angle += angle;  	TempRedraw(); // TurnoutRotate  } @@ -2692,59 +4596,59 @@ static void TurnoutRotate( void * pangle )  static dynArr_t anchors_da;  #define anchors(N) DYNARR_N(trkSeg_t,anchors_da,N) -void static CreateArrowAnchor(coOrd pos,ANGLE_T a,DIST_T len) { -	DYNARR_APPEND(trkSeg_t,anchors_da,1); -	int i = anchors_da.cnt-1; +void static CreateArrowAnchor(coOrd pos, ANGLE_T a, DIST_T len) { +	DYNARR_APPEND(trkSeg_t, anchors_da, 1); +	int i = anchors_da.cnt - 1;  	anchors(i).type = SEG_STRLIN;  	anchors(i).width = 0;  	anchors(i).u.l.pos[0] = pos; -	Translate(&anchors(i).u.l.pos[1],pos,NormalizeAngle(a+135),len); +	Translate(&anchors(i).u.l.pos[1], pos, NormalizeAngle(a + 135), len);  	anchors(i).color = wDrawColorBlue; -	DYNARR_APPEND(trkSeg_t,anchors_da,1); -	i = anchors_da.cnt-1; +	DYNARR_APPEND(trkSeg_t, anchors_da, 1); +	i = anchors_da.cnt - 1;  	anchors(i).type = SEG_STRLIN;  	anchors(i).width = 0;  	anchors(i).u.l.pos[0] = pos; -	Translate(&anchors(i).u.l.pos[1],pos,NormalizeAngle(a-135),len); +	Translate(&anchors(i).u.l.pos[1], pos, NormalizeAngle(a - 135), len);  	anchors(i).color = wDrawColorBlue;  }  void static CreateRotateAnchor(coOrd pos) { -	DIST_T d = tempD.scale*0.15; -	DYNARR_APPEND(trkSeg_t,anchors_da,1); -	int i = anchors_da.cnt-1; +	DIST_T d = tempD.scale * 0.15; +	DYNARR_APPEND(trkSeg_t, anchors_da, 1); +	int i = anchors_da.cnt - 1;  	anchors(i).type = SEG_CRVLIN;  	anchors(i).width = 0.5;  	anchors(i).u.c.center = pos;  	anchors(i).u.c.a0 = 180.0;  	anchors(i).u.c.a1 = 360.0; -	anchors(i).u.c.radius = d*2; +	anchors(i).u.c.radius = d * 2;  	anchors(i).color = wDrawColorAqua;  	coOrd head;					//Arrows -	for (int j=0;j<3;j++) { -		Translate(&head,pos,j*120,d*2); -		CreateArrowAnchor(head,NormalizeAngle((j*120)+90),d); +	for (int j = 0; j < 3; j++) { +		Translate(&head, pos, j * 120, d * 2); +		CreateArrowAnchor(head, NormalizeAngle((j * 120) + 90), d);  	}  }  void static CreateMoveAnchor(coOrd pos) { -	DYNARR_SET(trkSeg_t,anchors_da,anchors_da.cnt+5); -	DrawArrowHeads(&DYNARR_N(trkSeg_t,anchors_da,anchors_da.cnt-5),pos,0,TRUE,wDrawColorBlue); -	DYNARR_SET(trkSeg_t,anchors_da,anchors_da.cnt+5); -	DrawArrowHeads(&DYNARR_N(trkSeg_t,anchors_da,anchors_da.cnt-5),pos,90,TRUE,wDrawColorBlue); +	DYNARR_SET(trkSeg_t, anchors_da, anchors_da.cnt + 5); +	DrawArrowHeads(&DYNARR_N(trkSeg_t, anchors_da, anchors_da.cnt - 5), pos, 0, TRUE, wDrawColorBlue); +	DYNARR_SET(trkSeg_t, anchors_da, anchors_da.cnt + 5); +	DrawArrowHeads(&DYNARR_N(trkSeg_t, anchors_da, anchors_da.cnt - 5), pos, 90, TRUE, wDrawColorBlue);  } -	 +  /**   * Process the mouse events for laying track.   *   * \param action IN event type - * \param pos    IN mouse position  + * \param pos    IN mouse position   * \return    		next state   */  EXPORT STATUS_T CmdTurnoutAction( -		wAction_t action, -		coOrd pos ) +	wAction_t action, +	coOrd pos)  {  	ANGLE_T angle;  	static BOOL_T validAngle; @@ -2760,155 +4664,154 @@ EXPORT STATUS_T CmdTurnoutAction(  		Dto.state = 0;  		Dto.trk = NULL;  		Dto.angle = 0.0; -		DYNARR_RESET(trkSeg_t,anchors_da); +		DYNARR_RESET(trkSeg_t, anchors_da); +		SetAllTrackSelect(FALSE);  		return C_CONTINUE;  	case wActionMove: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if (Dto.state && (MyGetKeyState()&WKEY_CTRL)) { +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (Dto.state && (MyGetKeyState() & WKEY_CTRL)) {  			CreateRotateAnchor(pos); -		} else { +		} +		else {  			CreateMoveAnchor(pos);  		}  		return C_CONTINUE;  		break;  	case C_DOWN: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if ( curTurnout == NULL ) return C_CONTINUE; -		PlaceTurnout( pos, NULL ); +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (curTurnout == NULL) return C_CONTINUE; +		PlaceTurnout(pos, NULL);  		Dto.state = 1; -		CreateMoveAnchor(pos);  		return C_CONTINUE;  	case C_MOVE: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if ( curTurnout == NULL ) return C_CONTINUE; -		if ( curTurnoutEp >= (long)curTurnout->endCnt ) +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (curTurnout == NULL) return C_CONTINUE; +		if (curTurnoutEp >= (long)curTurnout->endCnt)  			curTurnoutEp = 0;  		Dto.state = 1; -		PlaceTurnout( pos, Dto.trk ); -		CreateMoveAnchor(pos); +		PlaceTurnout(pos, Dto.trk);  		return C_CONTINUE;  	case C_UP: -		DYNARR_RESET(trkSeg_t,anchors_da); -		CreateMoveAnchor(pos); -		InfoMessage( _("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel") ); +		DYNARR_RESET(trkSeg_t, anchors_da); +		InfoMessage(_("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel"));  		return C_CONTINUE;  	case C_RDOWN: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if ( curTurnout == NULL ) return C_CONTINUE; +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (curTurnout == NULL) return C_CONTINUE;  		if (Dto.state == 0) {  			Dto.pos = pos;      // If first, use pos, otherwise use current -LOG( log_turnout, 1, ( "RDOWN @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +			LOG(log_turnout, 1, ("RDOWN @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  		}  		Dto.rot0 = Dto.rot1 = pos; -		CreateRotateAnchor(pos);  		Dto.state = 2;  		origPos = Dto.pos;  #ifdef NEWROTATE  		origAngle = Dto.angle;  #else -		Rotate( &origPos, Dto.rot0, -(Dto.angle + curTurnout->endPt[(int)curTurnoutEp].angle) ); +		Rotate(&origPos, Dto.rot0, -(Dto.angle + curTurnout->endPt[(int)curTurnoutEp].angle));  #endif  		validAngle = FALSE;  		return C_CONTINUE;  	case C_RMOVE: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if ( curTurnout == NULL ) return C_CONTINUE; +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (curTurnout == NULL) return C_CONTINUE;  		Dto.rot1 = pos; -		if ( FindDistance(Dto.rot0, Dto.rot1) > 0.1*mainD.scale ) { -			angle = FindAngle( Dto.rot0, Dto.rot1 ); +		if (FindDistance(Dto.rot0, Dto.rot1) > 0.1 * mainD.scale) { +			angle = FindAngle(Dto.rot0, Dto.rot1);  			if (!validAngle) {  				baseAngle = angle/* - Dto.angle*/;  				validAngle = TRUE;  			}  			Dto.pos = origPos; -LOG( log_turnout, 1, ( "RMOVE pre @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +			LOG(log_turnout, 1, ("RMOVE pre @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  #ifdef NEWROTATE  			angle -= baseAngle; -			Dto.angle = NormalizeAngle( origAngle + angle ); +			Dto.angle = NormalizeAngle(origAngle + angle);  #else  			angle += 180.0;  			Dto.angle = angle - curTurnout->endPt[(int)curTurnoutEp].angle;  #endif -			Rotate( &Dto.pos, Dto.rot0, angle ); -LOG( log_turnout, 1, ( "RMOVE post @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) ); +			Rotate(&Dto.pos, Dto.rot0, angle); +			LOG(log_turnout, 1, ("RMOVE post @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y));  		} -		FormatCompoundTitle( listLabels, curTurnout->title ); -		InfoMessage( _("Angle = %0.3f (%s)"), PutAngle( NormalizeAngle(Dto.angle + 90.0) ), message ); +		FormatCompoundTitle(listLabels, curTurnout->title); +		InfoMessage(_("Angle = %0.3f (%s)"), PutAngle(NormalizeAngle(Dto.angle + 90.0)), message);  		Dto.state = 2; -		CreateRotateAnchor(Dto.rot0);  		return C_CONTINUE;  	case C_RUP: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if ( curTurnout == NULL ) return C_CONTINUE; +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (curTurnout == NULL) return C_CONTINUE;  		Dto.state = 1; -		CreateMoveAnchor(pos); -		InfoMessage( _("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel") ); +		InfoMessage(_("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel"));  		return C_CONTINUE;  	case C_LCLICK: -		DYNARR_RESET(trkSeg_t,anchors_da); -		if ( curTurnout == NULL ) return C_CONTINUE; -		if ( MyGetKeyState() & WKEY_SHIFT ) { +		DYNARR_RESET(trkSeg_t, anchors_da); +		if (curTurnout == NULL) return C_CONTINUE; +		if (MyGetKeyState() & WKEY_SHIFT) {  			angle = curTurnout->endPt[(int)curTurnoutEp].angle;  			curTurnoutEp++;  			if (curTurnoutEp >= (long)curTurnout->endCnt)  				curTurnoutEp = 0;  			if (Dto.trk == NULL) -				Dto.angle = NormalizeAngle( Dto.angle + (angle - curTurnout->endPt[(int)curTurnoutEp].angle ) ); -			PlaceTurnout( Dto.place, Dto.trk ); -		} else { -			CmdTurnoutAction( C_DOWN, pos ); -			CmdTurnoutAction( C_UP, pos ); +				Dto.angle = NormalizeAngle(Dto.angle + (angle - curTurnout->endPt[(int)curTurnoutEp].angle)); +			PlaceTurnout(Dto.place, Dto.trk); +		} +		else { +			CmdTurnoutAction(C_DOWN, pos); +			CmdTurnoutAction(C_UP, pos);  		}  		return C_CONTINUE;  	case C_REDRAW: +		wSetCursor(mainD.d, defaultCursor);  		if (Dto.state) { -			DrawSegs( &tempD, Dto.pos, Dto.angle, -				curTurnout->segs, curTurnout->segCnt, trackGauge, wDrawColorBlue ); +			DrawSegs(&tempD, Dto.pos, Dto.angle, +				curTurnout->segs, curTurnout->segCnt, trackGauge, selectedColor);  		} -		if (anchors_da.cnt>0) { -			DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack ); +		if (anchors_da.cnt > 0) { +			DrawSegs(&tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack); +			wSetCursor(mainD.d, wCursorNone);  		}  		if (Dto.state == 2) -			DrawLine( &tempD, Dto.rot0, Dto.rot1, 0, wDrawColorBlack ); +			DrawLine(&tempD, Dto.rot0, Dto.rot1, 0, wDrawColorBlue);  		return C_CONTINUE;  	case C_CANCEL: -		DYNARR_RESET(trkSeg_t,anchors_da); +		DYNARR_RESET(trkSeg_t, anchors_da);  		Dto.state = 0;  		Dto.trk = NULL;  		/*wHide( newTurn.reg.win );*/  		return C_TERMINATE;  	case C_TEXT: -		if ((action>>8) != ' ')  +		if ((action >> 8) != ' ')  			return C_CONTINUE;  		/*no break*/  	case C_OK: -		DYNARR_RESET(trkSeg_t,anchors_da); +		DYNARR_RESET(trkSeg_t, anchors_da);  		AddTurnout(); -		Dto.state=0; +		Dto.state = 0;  		Dto.trk = NULL;  		return C_TERMINATE;  	case C_FINISH: -		DYNARR_RESET(trkSeg_t,anchors_da); +		DYNARR_RESET(trkSeg_t, anchors_da);  		if (Dto.state != 0 && Dto.trk != NULL) -			CmdTurnoutAction( C_OK, pos ); +			CmdTurnoutAction(C_OK, pos);  		else -			CmdTurnoutAction( C_CANCEL, pos ); +			CmdTurnoutAction(C_CANCEL, pos);  		return C_TERMINATE;  	case C_CMDMENU:  		menuPos = pos; -		wMenuPopupShow( turnoutPopupM ); +		wMenuPopupShow(turnoutPopupM);  		return C_CONTINUE;  	default: @@ -2919,83 +4822,84 @@ LOG( log_turnout, 1, ( "RMOVE post @ %0.3fx%0.3f\n", Dto.pos.x, Dto.pos.y ) );  #ifdef TURNOUTCMD  static STATUS_T CmdTurnout( -		wAction_t action, -		coOrd pos ) +	wAction_t action, +	coOrd pos)  {  	wIndex_t turnoutIndex; -	turnoutInfo_t * turnoutPtr; +	turnoutInfo_t* turnoutPtr;  	switch (action & 0xFF) {  	case C_START:  		if (turnoutW == NULL) { -/*			turnoutW = ParamCreateDialog( &turnoutPG, MakeWindowTitle("Turnout"), "Ok", , (paramActionCancelProc)Reset, TRUE, NULL, F_RESIZE|F_RECALLSIZE, TurnoutDlgUpdate ); */ -			turnoutW = ParamCreateDialog( &turnoutPG, MakeWindowTitle(_("Turnout")), _("Close"), (paramActionOkProc)TurnoutOk, wHide, TRUE, NULL, F_RESIZE|F_RECALLSIZE|PD_F_ALT_CANCELLABEL, TurnoutDlgUpdate ); -			InitNewTurn( turnoutNewM ); +			/*			turnoutW = ParamCreateDialog( &turnoutPG, MakeWindowTitle("Turnout"), "Ok", , (paramActionCancelProc)Reset, TRUE, NULL, F_RESIZE|F_RECALLSIZE, TurnoutDlgUpdate ); */ +			turnoutW = ParamCreateDialog(&turnoutPG, MakeWindowTitle(_("Turnout")), _("Close"), (paramActionOkProc)TurnoutOk, wHide, TRUE, NULL, F_RESIZE | F_RECALLSIZE | PD_F_ALT_CANCELLABEL, TurnoutDlgUpdate); +			InitNewTurn(turnoutNewM);  		} -/*		ParamDialogOkActive( &turnoutPG, FALSE ); */ -		turnoutIndex = wListGetIndex( turnoutListL ); +		/*		ParamDialogOkActive( &turnoutPG, FALSE ); */ +		turnoutIndex = wListGetIndex(turnoutListL);  		turnoutPtr = curTurnout; -		wShow( turnoutW ); -		TurnoutChange( CHANGE_PARAMS|CHANGE_SCALE ); +		wShow(turnoutW); +		TurnoutChange(CHANGE_PARAMS | CHANGE_SCALE);  		if (curTurnout == NULL) { -			NoticeMessage2( 0, MSG_TURNOUT_NO_TURNOUT, _("Ok"), NULL ); +			NoticeMessage2(0, MSG_TURNOUT_NO_TURNOUT, _("Ok"), NULL);  			return C_TERMINATE;  		}  		if (turnoutIndex > 0 && turnoutPtr) {  			curTurnout = turnoutPtr; -			wListSetIndex( turnoutListL, turnoutIndex ); -			RedrawTurnout(); +			wListSetIndex(turnoutListL, turnoutIndex); +			RedrawTurnout( turnoutD.d, NULL, 0, 0 );  		} -		InfoMessage( _("Pick turnout and active End Point, then place on the layout")); -		ParamLoadControls( &turnoutPG ); -		ParamGroupRecord( &turnoutPG ); -		return CmdTurnoutAction( action, pos ); +		InfoMessage(_("Pick turnout and active End Point, then place on the layout")); +		ParamLoadControls(&turnoutPG); +		ParamGroupRecord(&turnoutPG); +		SetAllTrackSelect(FALSE); +		return CmdTurnoutAction(action, pos);  	case wActionMove: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	case C_DOWN:  	case C_RDOWN: -		ParamDialogOkActive( &turnoutPG, TRUE ); +		ParamDialogOkActive(&turnoutPG, TRUE);  		if (hideTurnoutWindow) -			wHide( turnoutW ); -		 if (((action&0xFF) == C_DOWN) && (MyGetKeyState()&WKEY_CTRL)) +			wHide(turnoutW); +		if (((action & 0xFF) == C_DOWN) && (MyGetKeyState() & WKEY_CTRL))  			return CmdTurnoutAction(C_RDOWN, pos);     //Convert CTRL into Right  		/*no break*/  	case C_MOVE: -		if (MyGetKeyState()&WKEY_CTRL) -			return CmdTurnoutAction (C_RMOVE, pos); +		if (MyGetKeyState() & WKEY_CTRL) +			return CmdTurnoutAction(C_RMOVE, pos);  		/*no break*/  	case C_RMOVE: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	case C_UP:  	case C_RUP:  		if (hideTurnoutWindow) -			wShow( turnoutW ); +			wShow(turnoutW); -		InfoMessage( _("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel") ); -		if (((action&0xFF) == C_UP) && (MyGetKeyState()&WKEY_CTRL)) -						return CmdTurnoutAction (C_RUP, pos); -		return CmdTurnoutAction( action, pos ); +		InfoMessage(_("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel")); +		if (((action & 0xFF) == C_UP) && (MyGetKeyState() & WKEY_CTRL)) +			return CmdTurnoutAction(C_RUP, pos); +		return CmdTurnoutAction(action, pos);  	case C_LCLICK: -		CmdTurnoutAction( action, pos ); +		CmdTurnoutAction(action, pos);  		HilightEndPt();  		return C_CONTINUE;  	case C_CANCEL: -		wHide( turnoutW ); -		return CmdTurnoutAction( action, pos ); +		wHide(turnoutW); +		return CmdTurnoutAction(action, pos);  	case C_TEXT: -		CmdTurnoutAction( action, pos ); +		CmdTurnoutAction(action, pos);  		return C_CONTINUE;  	case C_OK:  	case C_FINISH:  	case C_CMDMENU:  	case C_REDRAW: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	default:  		return C_CONTINUE; @@ -3003,59 +4907,59 @@ static STATUS_T CmdTurnout(  }  #endif - +  /**   * Event procedure for the hotbar.   *   * \param op   IN requested function - * \param data IN	pointer to info on selected element	 + * \param data IN	pointer to info on selected element   * \param d    IN   * \param origP IN - * \return    + * \return   */ -static char * CmdTurnoutHotBarProc( -		hotBarProc_e op, -		void * data, -		drawCmd_p d, -		coOrd * origP ) +static char* CmdTurnoutHotBarProc( +	hotBarProc_e op, +	void* data, +	drawCmd_p d, +	coOrd* origP)  { -	turnoutInfo_t * to = (turnoutInfo_t*)data; -	switch ( op ) { +	turnoutInfo_t* to = (turnoutInfo_t*)data; +	switch (op) {  	case HB_SELECT:		/* new element is selected */ -		CmdTurnoutAction( C_FINISH, zero ); 		/* finish current operation */ +		CmdTurnoutAction(C_FINISH, zero); 		/* finish current operation */  		curTurnout = to; -		DoCommandB( (void*)(intptr_t)turnoutHotBarCmdInx ); /* continue with new turnout / structure */ +		DoCommandB(I2VP(turnoutHotBarCmdInx)); /* continue with new turnout / structure */  		return NULL;  	case HB_LISTTITLE: -		FormatCompoundTitle( listLabels, to->title ); +		FormatCompoundTitle(listLabels, to->title);  		if (message[0] == '\0') -			FormatCompoundTitle( listLabels|LABEL_DESCR, to->title ); +			FormatCompoundTitle(listLabels | LABEL_DESCR, to->title);  		return message;  	case HB_BARTITLE: -		FormatCompoundTitle( hotBarLabels<<1, to->title ); +		FormatCompoundTitle(hotBarLabels << 1, to->title);  		return message;  	case HB_FULLTITLE:  		return to->title;  	case HB_DRAW: -		DrawSegs( d, *origP, 0.0, to->segs, to->segCnt, trackGauge, wDrawColorBlack ); +		DrawSegs(d, *origP, 0.0, to->segs, to->segCnt, trackGauge, wDrawColorBlack);  		return NULL;  	}  	return NULL;  } -EXPORT void AddHotBarTurnouts( void ) +EXPORT void AddHotBarTurnouts(void)  {  	wIndex_t inx; -	turnoutInfo_t * to; -	for ( inx=0; inx < turnoutInfo_da.cnt; inx ++ ) { +	turnoutInfo_t* to; +	for (inx = 0; inx < turnoutInfo_da.cnt; inx++) {  		to = turnoutInfo(inx); -		if ( !( IsParamValid(to->paramFileIndex) && -				to->segCnt > 0 && -				CompatibleScale( TRUE, to->scaleInx, GetLayoutCurScale()) ) ) -				continue; -		AddHotBarElement( to->contentsLabel, to->size, to->orig, TRUE, FALSE, to->barScale, to, CmdTurnoutHotBarProc ); +		if (!(IsParamValid(to->paramFileIndex) && +			to->segCnt > 0 && +			(FIT_NONE != CompatibleScale(FIT_TURNOUT, to->scaleInx, GetLayoutCurScale())))) +			continue; +		AddHotBarElement(to->contentsLabel, to->size, to->orig, TRUE, FALSE, to->barScale, to, CmdTurnoutHotBarProc);  	}  } @@ -3068,8 +4972,8 @@ EXPORT void AddHotBarTurnouts( void )   */  static STATUS_T CmdTurnoutHotBar( -		wAction_t action, -		coOrd pos ) +	wAction_t action, +	coOrd pos)  {  	switch (action & 0xFF) { @@ -3077,61 +4981,61 @@ static STATUS_T CmdTurnoutHotBar(  	case C_START:  		//TurnoutChange( CHANGE_PARAMS|CHANGE_SCALE );  		if (curTurnout == NULL) { -			NoticeMessage2( 0, MSG_TURNOUT_NO_TURNOUT, _("Ok"), NULL ); +			NoticeMessage2(0, MSG_TURNOUT_NO_TURNOUT, _("Ok"), NULL);  			return C_TERMINATE;  		} -		FormatCompoundTitle( listLabels|LABEL_DESCR, curTurnout->title ); -		InfoMessage( _("Place %s and draw into position"), message ); -        wIndex_t listIndex = FindListItemByContext( turnoutListL, curTurnout ); -        if ( listIndex > 0 ) -                turnoutInx = listIndex; -        ParamLoadControls( &turnoutPG ); -        ParamGroupRecord( &turnoutPG ); -		return CmdTurnoutAction( action, pos ); +		FormatCompoundTitle(listLabels | LABEL_DESCR, curTurnout->title); +		InfoMessage(_("Place %s and draw into position"), message); +		wIndex_t listIndex = FindListItemByContext(turnoutListL, curTurnout); +		if (listIndex >= 0) +			turnoutInx = listIndex; +		ParamLoadControls(&turnoutPG); +		ParamGroupRecord(&turnoutPG); +		return CmdTurnoutAction(action, pos);  	case wActionMove: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	case C_DOWN: -		if (MyGetKeyState()&WKEY_CTRL) { -			return CmdTurnoutAction( C_RDOWN, pos ); +		if (MyGetKeyState() & WKEY_CTRL) { +			return CmdTurnoutAction(C_RDOWN, pos);  		}  		/*no break*/  	case C_RDOWN: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	case C_MOVE: -		if (MyGetKeyState()&WKEY_CTRL) { -			return CmdTurnoutAction( C_RMOVE, pos ); +		if (MyGetKeyState() & WKEY_CTRL) { +			return CmdTurnoutAction(C_RMOVE, pos);  		}  		/*no break*/  	case C_RMOVE: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	case C_UP: -		if (MyGetKeyState()&WKEY_CTRL) { -			return CmdTurnoutAction( C_RUP, pos ); +		if (MyGetKeyState() & WKEY_CTRL) { +			return CmdTurnoutAction(C_RUP, pos);  		}  		/*no break*/  	case C_RUP: -		InfoMessage( _("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel") ); -		return CmdTurnoutAction( action, pos ); +		InfoMessage(_("Left-Drag to place, Ctrl+Left-Drag or Right-Drag to Rotate, Space or Enter to accept, Esc to Cancel")); +		return CmdTurnoutAction(action, pos);  	case C_REDRAW: -			return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	case C_TEXT: -		if ((action>>8) != ' ') +		if ((action >> 8) != ' ')  			return C_CONTINUE;  		/* no break*/  	case C_OK: -		CmdTurnoutAction( action, pos ); +		CmdTurnoutAction(action, pos);  		return C_CONTINUE;  	case C_CANCEL:  		HotBarCancel();  		/*no break*/  	default: -		return CmdTurnoutAction( action, pos ); +		return CmdTurnoutAction(action, pos);  	}  } @@ -3139,96 +5043,96 @@ static STATUS_T CmdTurnoutHotBar(  #include "bitmaps/turnout.xpm" -EXPORT void InitCmdTurnout( wMenu_p menu ) +EXPORT void InitCmdTurnout(wMenu_p menu)  { -	AddMenuButton( menu, CmdTurnout, "cmdTurnout", _("Predefined Track"), wIconCreatePixMap(turnout_xpm), LEVEL0_50, IC_WANT_MOVE|IC_STICKY|IC_LCLICK|IC_CMDMENU|IC_POPUP2, ACCL_TURNOUT, NULL ); -	turnoutHotBarCmdInx = AddMenuButton( menu, CmdTurnoutHotBar, "cmdTurnoutHotBar", "", NULL, LEVEL0_50, IC_WANT_MOVE|IC_STICKY|IC_LCLICK|IC_CMDMENU|IC_POPUP2, 0, NULL ); -	RegisterChangeNotification( TurnoutChange ); -	ParamRegister( &turnoutPG ); -	log_turnout = LogFindIndex( "turnout" ); -	log_traverseTurnout = LogFindIndex( "traverseTurnout" ); -	log_suppressCheckPaths = LogFindIndex( "suppresscheckpaths" ); -	log_splitturnout = LogFindIndex( "splitturnout" ); -	if ( turnoutPopupM == NULL ) { -		turnoutPopupM = MenuRegister( "Turnout Rotate" ); -		AddRotateMenu( turnoutPopupM, TurnoutRotate ); +	AddMenuButton(menu, CmdTurnout, "cmdTurnout", _("Predefined Track"), wIconCreatePixMap(turnout_xpm[iconSize]), LEVEL0_50, IC_WANT_MOVE | IC_STICKY | IC_LCLICK | IC_CMDMENU | IC_POPUP2, ACCL_TURNOUT, NULL); +	turnoutHotBarCmdInx = AddMenuButton(menu, CmdTurnoutHotBar, "cmdTurnoutHotBar", "", NULL, LEVEL0_50, IC_WANT_MOVE | IC_STICKY | IC_LCLICK | IC_CMDMENU | IC_POPUP2, 0, NULL); +	RegisterChangeNotification(TurnoutChange); +	ParamRegister(&turnoutPG); +	log_turnout = LogFindIndex("turnout"); +	log_traverseTurnout = LogFindIndex("traverseTurnout"); +	log_suppressCheckPaths = LogFindIndex("suppresscheckpaths"); +	log_splitturnout = LogFindIndex("splitturnout"); +	if (turnoutPopupM == NULL) { +		turnoutPopupM = MenuRegister("Turnout Rotate"); +		AddRotateMenu(turnoutPopupM, TurnoutRotate);  	}  }  #endif -EXPORT void InitTrkTurnout( void ) +EXPORT void InitTrkTurnout(void)  { -	T_TURNOUT = InitObject( &turnoutCmds ); +	T_TURNOUT = InitObject(&turnoutCmds);  	/*InitDebug( "Turnout", &debugTurnout );*/ -	AddParam( "TURNOUT ", ReadTurnoutParam); +	AddParam("TURNOUT ", ReadTurnoutParam);  } - +  #ifdef TEST  wDrawable_t turnoutD; -void wListAddValue( wList_p bl, char * val, wIcon_p, void * listData, void * itemData ) +void wListAddValue(wList_p bl, char* val, wIcon_p, void* listData, void* itemData)  {  } -void wListClear( wList_p bl ) +void wListClear(wList_p bl)  {  } -void wDrawSetScale( wDrawable_p d ) +void wDrawSetScale(wDrawable_p d)  {  	d->scale = 1.0;  } -void wDrawClear( wDrawable_p d ) +void wDrawClear(wDrawable_p d)  {  } -void GetTrkCurveCenter( track_p t, coOrd *pos, DIST_T *radius ) +void GetTrkCurveCenter(track_p t, coOrd* pos, DIST_T* radius)  {  }  #ifdef NOTRACK_C -track_p NewTrack( wIndex_t index, TRKTYP_T type, EPINX_T endCnt, SIZE_T extraSize ) +track_p NewTrack(wIndex_t index, TRKTYP_T type, EPINX_T endCnt, SIZE_T extraSize)  {  	return NULL;  } -track_p OnTrack( coOrd *pos ) +track_p OnTrack(coOrd* pos)  {  	return NULL;  } -void ErrorMessage( char * msg, ... ) +void ErrorMessage(char* msg, ...)  { -	lprintf( "ERROR : %s\n", msg ); +	lprintf("ERROR : %s\n", msg);  } -void DeleteTrack( track_p t ) +void DeleteTrack(track_p t)  {  } -void ConnectTracks( track_p t0, EPINX_T ep0, track_p t1, EPINX_T ep1 ) +void ConnectTracks(track_p t0, EPINX_T ep0, track_p t1, EPINX_T ep1)  {  }  #endif -main( INT_T argc, char * argv[] ) +main(INT_T argc, char* argv[])  { -	FILE * f; +	FILE* f;  	char line[STR_SIZE];  	wIndex_t lineCnt = 0;  	/*debugTurnout = 3;*/ -	if ((f = fopen("turnout.params", "r" )) == NULL ) { -		Perror( "turnout.params" ); +	if ((f = fopen("turnout.params", "r")) == NULL) { +		Perror("turnout.params");  		Exit(1);  	} -	while ( fgets( line, sizeof line, f ) != NULL ) { +	while (fgets(line, sizeof line, f) != NULL) {  		lineCnt++; -		ReadTurnoutParam( &lineCnt ); +		ReadTurnoutParam(&lineCnt);  	}  }  #endif | 
