diff options
Diffstat (limited to 'app/bin/compound.c')
-rw-r--r-- | app/bin/compound.c | 1150 |
1 files changed, 696 insertions, 454 deletions
diff --git a/app/bin/compound.c b/app/bin/compound.c index 627d2ef..dea754d 100644 --- a/app/bin/compound.c +++ b/app/bin/compound.c @@ -18,14 +18,9 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <ctype.h> -#include <math.h> -#include <string.h> - - #include "tbezier.h" #include "cjoin.h" #include "common.h" @@ -33,75 +28,224 @@ #include "cundo.h" #include "dynstring.h" #include "fileio.h" -#include "i18n.h" #include "shrtpath.h" #include "track.h" -#include "utility.h" -#include "messages.h" +#include "trkendpt.h" +#include "draw.h" #include "include/paramfile.h" +#include "common-ui.h" /***************************************************************************** * - * Misc + * Paths * */ -//Convert the internal path segment into the external one - which is based on the index count of only the track segments -char ConvertPathSegToExternal(char signed pp, int segCnt,trkSeg_p segs) { +#ifndef NEWPATH +/* GetPaths() + * + * Return the paths for 'trk'. + * + * \param trk IN Get paths for track 'trk' + */ +EXPORT PATHPTR_T GetPaths( track_p trk ) +{ + struct extraDataCompound_t * xx = GET_EXTRA_DATA( trk, T_NOTRACK, + extraDataCompound_t ); + if ( GetTrkType(trk) == T_STRUCTURE && xx->paths != NULL ) { + LogPrintf( "GetPaths( STRUCTURE, paths!=NULL )\n" ); + } + if ( GetTrkType(trk) == T_TURNOUT && xx->paths == NULL ) { + LogPrintf( "GetPaths( TURNOUT, paths==NULL )\n" ); + } + return xx->paths; +} +#endif - char signed new_pp; - int old_inx; - EPINX_T old_EP; - GetSegInxEP(pp,&old_inx,&old_EP); - int j = old_inx; - for (int i=0;i<old_inx;i++) { - if ( !IsSegTrack(&segs[i]) ) { - j--; - } +/* GetPathsLength() + * + * Return the length of the paths object + * + * \param paths IN paths object + */ +EXPORT wIndex_t GetPathsLength( PATHPTR_T paths ) +{ + PATHPTR_T pp; + CHECK( paths != NULL ); + for ( pp = paths; pp[0]; pp+=2 ) + for ( pp += strlen( (char*)pp ); pp[0] || pp[1]; pp++ ); + return (wIndex_t)(pp - paths + 1); +} + + +#ifndef NEWPATH +/* SetPaths() + * + * Set the paths for 'trk'. + * Called when paths are read from a layout file, copied from a param def'n or + * from a Spilt turnout. + * + * \param trk IN + * \param paths IN + */ +EXPORT void SetPaths( track_p trk, PATHPTR_T paths ) +{ + if ( GetTrkType(trk) == T_STRUCTURE && paths != NULL ) { + LogPrintf( "SetPaths( STRUCTURE, paths!=NULL )\n" ); + } + if ( GetTrkType(trk) == T_TURNOUT && paths == NULL ) { + LogPrintf( "SetPaths( TURNOUT, paths==NULL )\n" ); + } + + struct extraDataCompound_t * xx = GET_EXTRA_DATA( trk, T_NOTRACK, + extraDataCompound_t ); + if ( xx->paths ) { + MyFree( xx->paths ); } - SetSegInxEP(&new_pp,j,old_EP); - return new_pp; + if ( paths == NULL ) { + xx->paths = NULL; + } else { + wIndex_t pathLen = GetPathsLength( paths ); + xx->paths = memdup( paths, pathLen * sizeof *xx->paths ); + } + xx->currPath = NULL; + xx->currPathIndex = 0; +} +#endif + + +/* GetCurrPath() + * + * Return the current path for 'trk'. + * Current path is the .currPathIndex'th path + * If the .currPathIndex is greater then the number of paths, return the first + * + * \param trk IN + */ +EXPORT PATHPTR_T GetCurrPath( track_p trk ) +{ + struct extraDataCompound_t * xx = GET_EXTRA_DATA( trk, T_TURNOUT, + extraDataCompound_t ); + if ( xx->currPath ) { + return xx->currPath; + } + PATHPTR_T path = GetPaths( trk ); + for ( wIndex_t position = xx->currPathIndex; + position > 0 && path[0]; + path+=2, position-- ) { + for ( path += strlen( (char*)path ); path[0] || path[1]; path++ ); + } + if ( !path[0] ) { + xx->currPathIndex = 0; + path = GetPaths( trk ); + } + xx->currPath = path; + return xx->currPath; +} + +EXPORT long GetCurrPathIndex( track_p trk ) +{ + if ( GetTrkType( trk ) != T_TURNOUT ) { + return 0; + } + struct extraDataCompound_t * xx = GET_EXTRA_DATA( trk, T_TURNOUT, + extraDataCompound_t ); + return xx->currPathIndex; } -BOOL_T WriteCompoundPathsEndPtsSegs( - FILE * f, - PATHPTR_T paths, - wIndex_t segCnt, - trkSeg_p segs, - EPINX_T endPtCnt, - trkEndPt_t * endPts ) + +EXPORT void SetCurrPathIndex( track_p trk, long position ) +{ + if ( GetTrkType( trk ) != T_TURNOUT ) { + return; + } + struct extraDataCompound_t * xx = GET_EXTRA_DATA( trk, T_TURNOUT, + extraDataCompound_t ); + xx->currPathIndex = position; + xx->currPath = NULL; +} + +#ifndef NEWPATH +/* GetParamPaths() + * + * Return the paths for turnout parameter 'to'. + * + * \param to IN + */ +PATHPTR_T GetParamPaths( turnoutInfo_t * to ) +{ + return to->paths; +} + +/* SetParamPaths() + * + * Set paths for a Turnout Parameter 'to' + * Used when creating a new turnout def'n + * + * \param to IN + * \param paths IN + */ +void SetParamPaths( turnoutInfo_t * to, PATHPTR_T paths ) +{ + if ( paths ) { + wIndex_t len = GetPathsLength(paths); + to->paths = (PATHPTR_T)memdup( paths, len * ( sizeof * to->paths ) ); + } else { + to->paths = NULL; + } +} +#endif + +/***************************************************************************** + * + * + * + */ + +EXPORT BOOL_T WriteCompoundPathsEndPtsSegs( + FILE * f, + PATHPTR_T paths, + wIndex_t segCnt, + trkSeg_p segs, + EPINX_T endPtCnt, + trkEndPt_p endPts ) { int i; PATHPTR_T pp; BOOL_T rc = TRUE; - for ( pp=paths; *pp; pp+=2 ) { - rc &= fprintf( f, "\tP \"%s\"", pp )>0; - for ( pp+=strlen((char *)pp)+1; pp[0]!=0 || pp[1]!=0; pp++ ) - rc &= fprintf( f, " %d", ConvertPathSegToExternal(pp[0],segCnt,segs) )>0; - rc &= fprintf( f, "\n" )>0; + if ( paths ) { + for ( pp=paths; *pp; pp+=2 ) { + rc &= fprintf( f, "\tP \"%s\"", pp )>0; + for ( pp+=strlen((char *)pp)+1; pp[0]!=0 || pp[1]!=0; pp++ ) { + rc &= fprintf( f, " %d", pp[0] )>0; + } + rc &= fprintf( f, "\n" )>0; + } } - for ( i=0; i<endPtCnt; i++ ) + for ( i=0; i<endPtCnt; i++ ) { + trkEndPt_p epp = EndPtIndex( endPts, i ); rc &= fprintf( f, "\tE %0.6f %0.6f %0.6f\n", - endPts[i].pos.x, endPts[i].pos.y, endPts[i].angle )>0; + GetEndPtPos(epp).x, GetEndPtPos(epp).y, GetEndPtAngle(epp) ) > 0; + } rc &= WriteSegs( f, segCnt, segs )>0; return rc; } EXPORT void ParseCompoundTitle( - char * title, - char * * manufP, - int * manufL, - char * * nameP, - int * nameL, - char * * partnoP, - int * partnoL ) + char * title, + char * * manufP, + int * manufL, + char * * nameP, + int * nameL, + char * * partnoP, + int * partnoL ) { char * cp1, *cp2; - int len; + size_t len; *manufP = *nameP = *partnoP = NULL; *manufL = *nameL = *partnoL = 0; len = strlen( title ); @@ -111,27 +255,29 @@ EXPORT void ParseCompoundTitle( if ( cp2 ) { cp2++; *partnoP = cp2; - *partnoL = title+len-cp2; + *partnoL = (int)(title+len-cp2); len = cp2-title-1; } cp1++; *nameP = cp1; - *nameL = title+len-cp1; + *nameL = (int)(title+len-cp1); *manufP = title; - *manufL = cp1-title-1; + *manufL = (int)(cp1-title-1); } else { *nameP = title; - *nameL = len; + *nameL = (int)len; } } +EXPORT long listLabels = 7; +EXPORT long layoutLabels = 1; -void FormatCompoundTitle( - long format, - char * title ) +EXPORT void FormatCompoundTitle( + long format, + char * title ) { char *cp1, *cp2=NULL, *cq; - int len; + size_t len; FLOAT_T price; BOOL_T needSep; cq = message; @@ -146,8 +292,9 @@ void FormatCompoundTitle( cq += strlen(cq); } cp1 = strchr( title, '\t' ); - if ( cp1 != NULL ) + if ( cp1 != NULL ) { cp2 = strchr( cp1+1, '\t' ); + } if (cp2 == NULL) { if ( (format&LABEL_TABBED) ) { *cq++ = '\t'; @@ -208,12 +355,12 @@ void FormatCompoundTitle( void ComputeCompoundBoundingBox( - track_p trk ) + track_p trk ) { - struct extraData *xx; + struct extraDataCompound_t *xx; coOrd hi, lo; - xx = GetTrkExtraData(trk); + xx = GET_EXTRA_DATA(trk, T_NOTRACK, extraDataCompound_t); GetSegBounds( xx->orig, xx->angle, xx->segCnt, xx->segs, &lo, &hi ); hi.x += lo.x; @@ -228,32 +375,33 @@ turnoutInfo_t * FindCompound( long type, char * scale, char * title ) wIndex_t inx; SCALEINX_T scaleInx; - if ( scale ) + if ( scale ) { scaleInx = LookupScale( scale ); - else + } else { scaleInx = -1; + } if ( type&FIND_TURNOUT ) - for (inx=0; inx<turnoutInfo_da.cnt; inx++) { - to = turnoutInfo(inx); - if ( IsParamValid(to->paramFileIndex) && - to->segCnt > 0 && - (scaleInx == -1 || to->scaleInx == scaleInx ) && - to->segCnt != 0 && - strcmp( to->title, title ) == 0 ) { - return to; + for (inx=0; inx<turnoutInfo_da.cnt; inx++) { + to = turnoutInfo(inx); + if ( IsParamValid(to->paramFileIndex) && + to->segCnt > 0 && + (scaleInx == -1 || to->scaleInx == scaleInx ) && + to->segCnt != 0 && + strcmp( to->title, title ) == 0 ) { + return to; + } } - } if ( type&FIND_STRUCT ) - for (inx=0; inx<structureInfo_da.cnt; inx++) { - to = structureInfo(inx); - if ( IsParamValid(to->paramFileIndex) && - to->segCnt > 0 && - (scaleInx == -1 || to->scaleInx == scaleInx ) && - to->segCnt != 0 && - strcmp( to->title, title ) == 0 ) { - return to; + for (inx=0; inx<structureInfo_da.cnt; inx++) { + to = structureInfo(inx); + if ( IsParamValid(to->paramFileIndex) && + to->segCnt > 0 && + (scaleInx == -1 || to->scaleInx == scaleInx ) && + to->segCnt != 0 && + strcmp( to->title, title ) == 0 ) { + return to; + } } - } return NULL; } @@ -271,13 +419,17 @@ EXPORT void CompoundClearDemoDefns( void ) for (inx=0; inx<turnoutInfo_da.cnt; inx++) { to = turnoutInfo(inx); - if ( to->paramFileIndex == PARAM_CUSTOM && strcasecmp( GetScaleName(to->scaleInx), "DEMO" ) == 0 ) + if ( to->paramFileIndex == PARAM_CUSTOM + && strcasecmp( GetScaleName(to->scaleInx), "DEMO" ) == 0 ) { to->segCnt = 0; + } } for (inx=0; inx<structureInfo_da.cnt; inx++) { to = structureInfo(inx); - if ( to->paramFileIndex == PARAM_CUSTOM && strcasecmp( GetScaleName(to->scaleInx), "DEMO" ) == 0 ) + if ( to->paramFileIndex == PARAM_CUSTOM + && strcasecmp( GetScaleName(to->scaleInx), "DEMO" ) == 0 ) { to->segCnt = 0; + } } } @@ -288,13 +440,14 @@ EXPORT void CompoundClearDemoDefns( void ) */ void SetDescriptionOrig( - track_p trk ) + track_p trk ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); int i, j; coOrd p0, p1; - for (i=0,j=-1;i<xx->segCnt;i++) { + for (i=0,j=-1; i<xx->segCnt; i++) { if ( IsSegTrack( &xx->segs[i] ) ) { if (j == -1) { j = i; @@ -307,8 +460,8 @@ void SetDescriptionOrig( if (j != -1 && xx->segs[j].type == SEG_CRVTRK) { REORIGIN( p0, xx->segs[j].u.c.center, xx->angle, xx->orig ) Translate( &p0, p0, - xx->segs[j].u.c.a0 + xx->segs[j].u.c.a1/2.0 + xx->angle, - fabs(xx->segs[j].u.c.radius) ); + xx->segs[j].u.c.a0 + xx->segs[j].u.c.a1/2.0 + xx->angle, + fabs(xx->segs[j].u.c.radius) ); } else { GetBoundingBox( trk, (&p0), (&p1) ); @@ -322,74 +475,97 @@ void SetDescriptionOrig( void DrawCompoundDescription( - track_p trk, - drawCmd_p d, - wDrawColor color ) + track_p trk, + drawCmd_p d, + wDrawColor color ) { wFont_p fp; coOrd p1; - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); char * desc; long layoutLabelsOption = layoutLabels; - if (layoutLabels == 0) + if (layoutLabels == 0) { return; - if ((labelEnable&LABELENABLE_TRKDESC)==0) + } + if ((labelEnable&LABELENABLE_TRKDESC)==0) { return; - if ( (d->options&DC_SIMPLE) ) + } + if ( (d->options&(DC_SIMPLE|DC_SEGTRACK)) ) { return; - if ( xx->special == TOpier ) { - desc = xx->u.pier.name; - } else { - if ( xx->flipped ) - layoutLabelsOption |= LABEL_FLIPPED; - if ( xx->ungrouped ) - layoutLabelsOption |= LABEL_UNGROUPED; - if ( xx->split ) - layoutLabelsOption |= LABEL_SPLIT; - FormatCompoundTitle( layoutLabelsOption, xtitle(xx) ); - desc = message; + } + if ( xx->special == TOpier ) { + desc = xx->u.pier.name; + } else { + if ( xx->flipped ) { + layoutLabelsOption |= LABEL_FLIPPED; } - p1 = xx->descriptionOrig; - Rotate( &p1, zero, xx->angle ); - p1.x += xx->orig.x + xx->descriptionOff.x; - p1.y += xx->orig.y + xx->descriptionOff.y; + if ( xx->ungrouped ) { + layoutLabelsOption |= LABEL_UNGROUPED; + } + if ( xx->split ) { + layoutLabelsOption |= LABEL_SPLIT; + } + FormatCompoundTitle( layoutLabelsOption, xtitle(xx) ); + desc = message; + } + p1 = xx->descriptionOrig; + Rotate( &p1, zero, xx->angle ); + coOrd p0; + p0.x = p1.x+xx->orig.x; + p0.y = p1.y+xx->orig.y; + p1.x += xx->orig.x + xx->descriptionOff.x; + p1.y += xx->orig.y + xx->descriptionOff.y; + if (color == drawColorPreviewSelected) { + DrawLine( d, p0, p1, 0, color ); + } fp = wStandardFont( F_TIMES, FALSE, FALSE ); - DrawBoxedString( (xx->special==TOpier)?BOX_INVERT:BOX_NONE, d, p1, desc, fp, (wFontSize_t)descriptionFontSize, color, 0.0 ); + DrawBoxedString( (xx->special==TOpier)?BOX_INVERT:BOX_NONE, d, p1, desc, fp, + (wFontSize_t)descriptionFontSize, color, 0.0 ); } DIST_T CompoundDescriptionDistance( - coOrd pos, - track_p trk, - coOrd * dpos, - BOOL_T show_hidden, - BOOL_T * hidden) + coOrd pos, + track_p trk, + coOrd * dpos, + BOOL_T show_hidden, + BOOL_T * hidden) { - struct extraData *xx = GetTrkExtraData(trk); coOrd p1; - if (GetTrkType(trk) != T_TURNOUT && GetTrkType(trk) != T_STRUCTURE) - return 100000; - if ( ((GetTrkBits( trk ) & TB_HIDEDESC) != 0 ) && !show_hidden) - return 100000; + if (GetTrkType(trk) != T_TURNOUT && GetTrkType(trk) != T_STRUCTURE) { + return DIST_INF; + } + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); + if ( ((GetTrkBits( trk ) & TB_HIDEDESC) != 0 ) && !show_hidden) { + return DIST_INF; + } p1 = xx->descriptionOrig; coOrd offset = xx->descriptionOff; - if ( (GetTrkBits( trk ) & TB_HIDEDESC) != 0 ) offset = zero; + if ( (GetTrkBits( trk ) & TB_HIDEDESC) != 0 ) { offset = zero; } Rotate( &p1, zero, xx->angle ); p1.x += xx->orig.x + offset.x; p1.y += xx->orig.y + offset.y; - if (hidden) *hidden = (GetTrkBits( trk ) & TB_HIDEDESC); + if (hidden) { *hidden = (GetTrkBits( trk ) & TB_HIDEDESC); } *dpos = p1; + + coOrd tpos = pos; + if (DistanceCompound(trk,&tpos)<FindDistance( p1, pos )) { + return DistanceCompound(trk,&pos); + } return FindDistance( p1, pos ); } STATUS_T CompoundDescriptionMove( - track_p trk, - wAction_t action, - coOrd pos ) + track_p trk, + wAction_t action, + coOrd pos ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); static coOrd p0, p1; static BOOL_T editMode; wDrawColor color; @@ -437,9 +613,9 @@ STATUS_T CompoundDescriptionMove( */ EXPORT void SetSegInxEP( - signed char * segChar, - int segInx, - EPINX_T segEP ) + signed char * segChar, + int segInx, + EPINX_T segEP ) { if (segEP == 1) { * segChar = -(segInx+1); @@ -450,9 +626,9 @@ EXPORT void SetSegInxEP( } EXPORT void GetSegInxEP( - signed char segChar, - int * segInx, - EPINX_T * segEP ) + signed char segChar, + int * segInx, + EPINX_T * segEP ) { int inx; inx = segChar; @@ -467,12 +643,14 @@ EXPORT void GetSegInxEP( DIST_T DistanceCompound( - track_p t, - coOrd * p ) + track_p t, + coOrd * p ) { - struct extraData *xx = GetTrkExtraData(t); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, + extraDataCompound_t); EPINX_T ep; - DIST_T d0, d1; + DIST_T d0; +// DIST_T d1; coOrd p0, p2; PATHPTR_T path; int segInx; @@ -483,7 +661,7 @@ DIST_T DistanceCompound( d0 = DistanceSegs( xx->orig, xx->angle, xx->segCnt, xx->segs, p, NULL ); } else if ( programMode != MODE_TRAIN || GetTrkEndPtCnt(t) <= 0 ) { d0 = DistanceSegs( xx->orig, xx->angle, xx->segCnt, xx->segs, p, NULL ); - if (programMode != MODE_TRAIN && GetTrkEndPtCnt(t) > 0 && d0 < 10000.0) { + if (programMode != MODE_TRAIN && GetTrkEndPtCnt(t) > 0 && d0 < DIST_INF) { ep = PickEndPoint( *p, t ); *p = GetTrkEndPos(t,ep); } @@ -492,11 +670,11 @@ DIST_T DistanceCompound( Rotate( &p0, xx->orig, -xx->angle ); p0.x -= xx->orig.x; p0.y -= xx->orig.y; - d0 = 1000000.0; - path = xx->pathCurr; - for ( path=xx->pathCurr+strlen((char *)xx->pathCurr)+1; path[0] || path[1]; path++ ) { + d0 = DIST_INF; + path = GetCurrPath( t ); + for ( path += strlen((char *)path)+1; path[0] || path[1]; path++ ) { if ( path[0] != 0 ) { - d1 = 1000000.0; +// d1 = DIST_INF; GetSegInxEP( *path, &segInx, &segEP ); segProcData.distance.pos1 = p0; SegProc( SEGPROC_DISTANCE, &xx->segs[segInx], &segProcData ); @@ -506,7 +684,7 @@ DIST_T DistanceCompound( } } } - if ( d0 < 1000000.0 ) { + if ( d0 < DIST_INF ) { p2.x += xx->orig.x; p2.y += xx->orig.y; Rotate( &p2, xx->orig, xx->angle ); @@ -518,64 +696,67 @@ DIST_T DistanceCompound( static struct { - coOrd endPt[4]; - ANGLE_T endAngle[4]; - DIST_T endRadius[4]; - coOrd endCenter[4]; - FLOAT_T elev[4]; - coOrd orig; - ANGLE_T angle; - descPivot_t pivot; - char manuf[STR_SIZE]; - char name[STR_SIZE]; - char partno[STR_SIZE]; - long epCnt; - long segCnt; - long pathCnt; - FLOAT_T grade; - DIST_T length; - drawLineType_e linetype; - unsigned int layerNumber; - } compoundData; + coOrd endPt[4]; + ANGLE_T endAngle[4]; + DIST_T endRadius[4]; + coOrd endCenter[4]; + FLOAT_T elev[4]; + coOrd orig; + ANGLE_T angle; + descPivot_t pivot; + char manuf[STR_SIZE]; + char name[STR_SIZE]; + char partno[STR_SIZE]; + long epCnt; + long segCnt; + long pathCnt; + FLOAT_T grade; + DIST_T length; + drawLineType_e linetype; + unsigned int layerNumber; +} compoundData; typedef enum { E0, A0, C0, R0, Z0, E1, A1, C1, R1, Z1, E2, A2, C2, R2, Z2, E3, A3, C3, R3, Z3, GR, OR, AN, PV, MN, NM, PN, LT, SC, LY } compoundDesc_e; static descData_t compoundDesc[] = { -/*E0*/ { DESC_POS, N_("End Pt 1: X,Y"), &compoundData.endPt[0] }, -/*A0*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[0] }, -/*C0*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[0] }, -/*R0*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[0] }, -/*Z0*/ { DESC_DIM, N_("Z1"), &compoundData.elev[0] }, -/*E1*/ { DESC_POS, N_("End Pt 2: X,Y"), &compoundData.endPt[1] }, -/*A1*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[1] }, -/*C1*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[1] }, -/*R1*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[1] }, -/*Z1*/ { DESC_DIM, N_("Z2"), &compoundData.elev[1] }, -/*E2*/ { DESC_POS, N_("End Pt 3: X,Y"), &compoundData.endPt[2] }, -/*A2*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[2] }, -/*C2*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[2] }, -/*R2*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[2] }, -/*Z2*/ { DESC_DIM, N_("Z3"), &compoundData.elev[2] }, -/*E3*/ { DESC_POS, N_("End Pt 4: X,Y"), &compoundData.endPt[3] }, -/*A3*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[3] }, -/*C3*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[3] }, -/*R3*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[3] }, -/*Z3*/ { DESC_DIM, N_("Z4"), &compoundData.elev[3] }, -/*GR*/ { DESC_FLOAT, N_("Grade"), &compoundData.grade }, -/*OR*/ { DESC_POS, N_("Origin: X,Y"), &compoundData.orig }, -/*AN*/ { DESC_ANGLE, N_("Angle"), &compoundData.angle }, -/*PV*/ { DESC_PIVOT, N_("Pivot"), &compoundData.pivot }, -/*MN*/ { DESC_STRING, N_("Manufacturer"), &compoundData.manuf, sizeof(compoundData.manuf)}, -/*NM*/ { DESC_STRING, N_("Name"), &compoundData.name, sizeof(compoundData.name) }, -/*PN*/ { DESC_STRING, N_("Part No"), &compoundData.partno, sizeof(compoundData.partno)}, -/*LT*/ { DESC_LIST, N_("LineType"), &compoundData.linetype }, -/*SC*/ { DESC_LONG, N_("# Segments"), &compoundData.segCnt }, -/*LY*/ { DESC_LAYER, N_("Layer"), &compoundData.layerNumber }, - { DESC_NULL } }; + /*E0*/ { DESC_POS, N_("End Pt 1: X,Y"), &compoundData.endPt[0] }, + /*A0*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[0] }, + /*C0*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[0] }, + /*R0*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[0] }, + /*Z0*/ { DESC_DIM, N_("Z1"), &compoundData.elev[0] }, + /*E1*/ { DESC_POS, N_("End Pt 2: X,Y"), &compoundData.endPt[1] }, + /*A1*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[1] }, + /*C1*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[1] }, + /*R1*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[1] }, + /*Z1*/ { DESC_DIM, N_("Z2"), &compoundData.elev[1] }, + /*E2*/ { DESC_POS, N_("End Pt 3: X,Y"), &compoundData.endPt[2] }, + /*A2*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[2] }, + /*C2*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[2] }, + /*R2*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[2] }, + /*Z2*/ { DESC_DIM, N_("Z3"), &compoundData.elev[2] }, + /*E3*/ { DESC_POS, N_("End Pt 4: X,Y"), &compoundData.endPt[3] }, + /*A3*/ { DESC_ANGLE, N_("Angle"), &compoundData.endAngle[3] }, + /*C3*/ { DESC_POS, N_("Center X,Y"), &compoundData.endCenter[3] }, + /*R3*/ { DESC_DIM, N_("Radius"), &compoundData.endRadius[3] }, + /*Z3*/ { DESC_DIM, N_("Z4"), &compoundData.elev[3] }, + /*GR*/ { DESC_FLOAT, N_("Grade"), &compoundData.grade }, + /*OR*/ { DESC_POS, N_("Origin: X,Y"), &compoundData.orig }, + /*AN*/ { DESC_ANGLE, N_("Angle"), &compoundData.angle }, + /*PV*/ { DESC_PIVOT, N_("Pivot"), &compoundData.pivot }, + /*MN*/ { DESC_STRING, N_("Manufacturer"), &compoundData.manuf, sizeof(compoundData.manuf)}, + /*NM*/ { DESC_STRING, N_("Name"), &compoundData.name, sizeof(compoundData.name) }, + /*PN*/ { DESC_STRING, N_("Part No"), &compoundData.partno, sizeof(compoundData.partno)}, + /*LT*/ { DESC_LIST, N_("LineType"), &compoundData.linetype }, + /*SC*/ { DESC_LONG, N_("# Segments"), &compoundData.segCnt }, + /*LY*/ { DESC_LAYER, N_("Layer"), &compoundData.layerNumber }, + { DESC_NULL } +}; #define MAX_DESCRIBE_ENDS 4 -static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T needUndoStart ) +static void UpdateCompound( track_p trk, int inx, descData_p descUpd, + BOOL_T needUndoStart ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); const char * manufS, * nameS, * partnoS; char * mP, *nP, *pP; int mL, nL, pL; @@ -592,18 +773,19 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee case PN: titleChanged = FALSE; ParseCompoundTitle( xtitle(xx), &mP, &mL, &nP, &nL, &pP, &pL ); - if (mP == NULL) mP = ""; - if (nP == NULL) nP = ""; - if (pP == NULL) pP = ""; + if (mP == NULL) { mP = ""; } + if (nP == NULL) { nP = ""; } + if (pP == NULL) { pP = ""; } manufS = wStringGetValue( (wString_p)compoundDesc[MN].control0 ); size_t max_manustr = 256, max_partstr = 256, max_namestr = 256; - if (compoundDesc[MN].max_string) + if (compoundDesc[MN].max_string) { max_manustr = compoundDesc[MN].max_string-1; + } if (strlen(manufS)>max_manustr) { NoticeMessage2(0, MSG_ENTERED_STRING_TRUNCATED, _("Ok"), NULL, max_manustr-1); } message[0] = '\0'; - strncat( message, manufS, max_manustr-1 ); + strncat( message, manufS, max_manustr-1 ); if ( strncmp( manufS, mP, mL ) != 0 || mL != strlen(manufS) ) { titleChanged = TRUE; } @@ -612,8 +794,9 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee split = xx->split; nameS = wStringGetValue( (wString_p)compoundDesc[NM].control0 ); max_namestr = 256; - if (compoundDesc[NM].max_string) + if (compoundDesc[NM].max_string) { max_namestr = compoundDesc[NM].max_string; + } if (strlen(nameS)>max_namestr) { NoticeMessage2(0, MSG_ENTERED_STRING_TRUNCATED, _("Ok"), NULL, max_namestr-1); } @@ -636,17 +819,18 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee split = FALSE; } if ( strncmp( nameS, nP, nL ) != 0 || nL != strlen(nameS) || - xx->flipped != flipped || - xx->ungrouped != ungrouped || - xx->split != split ) { + xx->flipped != flipped || + xx->ungrouped != ungrouped || + xx->split != split ) { titleChanged = TRUE; } strcat( message, "\t" ); strncat( message, nameS, max_namestr-1 ); partnoS = wStringGetValue( (wString_p)compoundDesc[PN].control0 ); max_partstr = 256; - if (compoundDesc[PN].max_string) + if (compoundDesc[PN].max_string) { max_partstr = compoundDesc[PN].max_string; + } if (strlen(partnoS)>max_partstr) { NoticeMessage2(0, MSG_ENTERED_STRING_TRUNCATED, _("Ok"), NULL, max_partstr-1); } @@ -660,22 +844,23 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee MyFree(newTitle); return; } - if ( needUndoStart ) - UndoStart( _("Change Track"), "Change Track" ); + if ( needUndoStart ) { + UndoStart( _("Change Track"), "Change Track" ); + } UndoModify( trk ); GetBoundingBox( trk, &hi, &lo ); if ( labelScale >= mainD.scale && - !OFF_MAIND( lo, hi ) ) { + !OFF_MAIND( lo, hi ) ) { DrawCompoundDescription( trk, &mainD, wDrawColorWhite ); } /*sprintf( message, "%s\t%s\t%s", manufS, nameS, partnoS );*/ - if (xx->title) MyFree(xx->title); + if (xx->title) { MyFree(xx->title); } xx->title = newTitle; xx->flipped = flipped; xx->ungrouped = ungrouped; xx->split = split; if ( labelScale >= mainD.scale && - !OFF_MAIND( lo, hi ) ) { + !OFF_MAIND( lo, hi ) ) { DrawCompoundDescription( trk, &mainD, GetTrkColor(trk,&tempD) ); } return; @@ -694,29 +879,30 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee case A1: case A2: case A3: - if (inx==A3) ep=3; - else if (inx==A2) ep=2; - else if (inx==A1) ep=1; - else ep=0; - RotateTrack( trk, GetTrkEndPos(trk,ep), NormalizeAngle( compoundData.endAngle[ep]-GetTrkEndAngle(trk,ep) ) ); + if (inx==A3) { ep=3; } + else if (inx==A2) { ep=2; } + else if (inx==A1) { ep=1; } + else { ep=0; } + RotateTrack( trk, GetTrkEndPos(trk,ep), + NormalizeAngle( compoundData.endAngle[ep]-GetTrkEndAngle(trk,ep) ) ); ComputeCompoundBoundingBox( trk ); break; case AN: orig = xx->orig; GetBoundingBox(trk,&hi,&lo); switch (compoundData.pivot) { - case DESC_PIVOT_MID: - orig.x = (hi.x-lo.x)/2+lo.x; - orig.y = (hi.y-lo.y)/2+lo.y; - break; - case DESC_PIVOT_SECOND: - orig.x = (hi.x-lo.x)/2+lo.x; - orig.y = (hi.y-lo.y)/2+lo.y; - orig.x = (orig.x - xx->orig.x)*2+xx->orig.x; - orig.y = (orig.y - xx->orig.y)*2+xx->orig.y; - break; - default: - break; + case DESC_PIVOT_MID: + orig.x = (hi.x-lo.x)/2+lo.x; + orig.y = (hi.y-lo.y)/2+lo.y; + break; + case DESC_PIVOT_SECOND: + orig.x = (hi.x-lo.x)/2+lo.x; + orig.y = (hi.y-lo.y)/2+lo.y; + orig.x = (orig.x - xx->orig.x)*2+xx->orig.x; + orig.y = (orig.y - xx->orig.y)*2+xx->orig.y; + break; + default: + break; } RotateTrack( trk, orig, NormalizeAngle( compoundData.angle-xx->angle ) ); ComputeCompoundBoundingBox( trk ); @@ -725,10 +911,10 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee case E1: case E2: case E3: - if (inx==E3) ep=3; - else if (inx==E2) ep=2; - else if (inx==E1) ep=1; - else ep=0; + if (inx==E3) { ep=3; } + else if (inx==E2) { ep=2; } + else if (inx==E1) { ep=1; } + else { ep=0; } pos = GetTrkEndPos(trk,ep); pos.x = compoundData.endPt[ep].x - pos.x; pos.y = compoundData.endPt[ep].y - pos.y; @@ -740,17 +926,21 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee case Z2: case Z3: ep = (inx==Z0?0:(inx==Z1?1:(inx==Z2?2:3))); - UpdateTrkEndElev( trk, ep, GetTrkEndElevUnmaskedMode(trk,ep), compoundData.elev[ep], NULL ); - if ( GetTrkEndPtCnt(trk) == 1 ) - break; - for (int i=0;i<compoundData.epCnt;i++) { - if (i==ep) continue; + UpdateTrkEndElev( trk, ep, GetTrkEndElevUnmaskedMode(trk,ep), + compoundData.elev[ep], NULL ); + if ( GetTrkEndPtCnt(trk) == 1 ) { + break; + } + for (int i=0; i<compoundData.epCnt; i++) { + if (i==ep) { continue; } ComputeElev( trk, i, FALSE, &compoundData.elev[i], NULL, TRUE ); } - if ( compoundData.length > minLength ) - compoundData.grade = fabs( (compoundData.elev[0]-compoundData.elev[1])/compoundData.length )*100.0; - else + if ( compoundData.length > minLength ) { + compoundData.grade = fabs( (compoundData.elev[0] + -compoundData.elev[1])/compoundData.length )*100.0; + } else { compoundData.grade = 0.0; + } compoundDesc[GR].mode |= DESC_CHANGE; compoundDesc[Z0+(E1-E0)*inx].mode |= DESC_CHANGE; break; @@ -760,18 +950,18 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee default: break; } - switch ( inx ) { - case A0: - case A1: - case A2: - case A3: - case E0: - case E1: - case E2: - case E3: - case AN: - case OR: - for (int i=0;(i<compoundData.epCnt)&&(i<MAX_DESCRIBE_ENDS);i++) { + switch ( inx ) { + case A0: + case A1: + case A2: + case A3: + case E0: + case E1: + case E2: + case E3: + case AN: + case OR: + for (int i=0; (i<compoundData.epCnt)&&(i<MAX_DESCRIBE_ENDS); i++) { compoundData.endPt[i] = GetTrkEndPos(trk,i); compoundDesc[i*(E1-E0)+E0].mode |= DESC_CHANGE; trackParams_t params; @@ -780,20 +970,20 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee GetTrackParams(PARAMS_CORNU,trk,compoundData.endPt[i],¶ms); compoundData.endRadius[i] = params.arcR; if (params.arcR != 0.0) { - compoundData.endCenter[i] = params.arcP; - compoundDesc[i*(E1-E0)+C0].mode |= DESC_CHANGE; + compoundData.endCenter[i] = params.arcP; + compoundDesc[i*(E1-E0)+C0].mode |= DESC_CHANGE; } } compoundData.orig = xx->orig; compoundDesc[OR].mode |= DESC_CHANGE; compoundData.angle = xx->angle; compoundDesc[AN].mode |= DESC_CHANGE; - break; - case LT: - xx->lineType = compoundData.linetype; - break; - default: - break; + break; + case LT: + xx->lineType = compoundData.linetype; + break; + default: + break; }; DrawNewTrack( trk ); @@ -802,11 +992,12 @@ static void UpdateCompound( track_p trk, int inx, descData_p descUpd, BOOL_T nee void DescribeCompound( - track_p trk, - char * str, - CSIZE_T len ) + track_p trk, + char * str, + CSIZE_T len ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); int fix; EPINX_T ep, epCnt; char * mP, *nP, *pP, *cnP; @@ -814,31 +1005,35 @@ void DescribeCompound( long mode; long listLabelsOption = listLabels; DynString description; - char *trackType; + char *trackType; - if ( xx->flipped ) + if ( xx->flipped ) { listLabelsOption |= LABEL_FLIPPED; - if ( xx->ungrouped ) + } + if ( xx->ungrouped ) { listLabelsOption |= LABEL_UNGROUPED; - if ( xx->split ) + } + if ( xx->split ) { listLabelsOption |= LABEL_SPLIT; + } FormatCompoundTitle( listLabelsOption, xtitle(xx) ); - if (message[0] == '\0') + if (message[0] == '\0') { FormatCompoundTitle( listLabelsOption|LABEL_DESCR, xtitle(xx) ); + } - if (GetTrkEndPtCnt(trk) <= 1) { + if (GetTrkEndPtCnt(trk) < 1) { trackType = _("Structure"); } else { trackType = GetTrkEndPtCnt(trk) > 2 ? _("Turnout") : _("Sectional Track"); } DynStringMalloc(&description, len); DynStringPrintf(&description, - _("%s (%d) Layer= %d %s"), - trackType, - GetTrkIndex(trk), - GetTrkLayer(trk) + 1, - message); - + _("%s (%d) Layer= %d %s"), + trackType, + GetTrkIndex(trk), + GetTrkLayer(trk) + 1, + message); + if (DynStringSize(&description) > (unsigned)len) { strncpy(str, DynStringToCStr(&description), len - 1); strcpy(str + len - 4, "..."); @@ -899,7 +1094,7 @@ void DescribeCompound( for ( int i=0 ; i<4 ; i++) { compoundDesc[E0+(E1-E0)*i].mode = DESC_IGNORE; - compoundDesc[A0+(E1-E0)*i].mode = DESC_IGNORE; + compoundDesc[A0+(E1-E0)*i].mode = DESC_IGNORE; compoundDesc[R0+(E1-E0)*i].mode = DESC_IGNORE; compoundDesc[C0+(E1-E0)*i].mode = DESC_IGNORE; compoundDesc[Z0+(E1-E0)*i].mode = DESC_IGNORE; @@ -907,16 +1102,16 @@ void DescribeCompound( compoundDesc[GR].mode = DESC_IGNORE; compoundDesc[OR].mode = - compoundDesc[AN].mode = fix?DESC_RO:0; + compoundDesc[AN].mode = fix?DESC_RO:0; compoundDesc[MN].mode = - compoundDesc[NM].mode = - compoundDesc[PN].mode = 0 /*DESC_NOREDRAW*/; + compoundDesc[NM].mode = + compoundDesc[PN].mode = 0 /*DESC_NOREDRAW*/; compoundDesc[SC].mode = DESC_RO; compoundDesc[LY].mode = DESC_NOREDRAW; compoundDesc[PV].mode = 0; compoundData.pivot = DESC_PIVOT_FIRST; if (compoundData.epCnt >0) { - for (int i=0;(i<compoundData.epCnt)&&(i<MAX_DESCRIBE_ENDS);i++) { + for (int i=0; (i<compoundData.epCnt)&&(i<MAX_DESCRIBE_ENDS); i++) { compoundDesc[A0+(E1-E0)*i].mode = (int)mode; compoundDesc[R0+(E1-E0)*i].mode = DESC_RO; compoundDesc[C0+(E1-E0)*i].mode = DESC_RO; @@ -933,33 +1128,42 @@ void DescribeCompound( compoundDesc[R0+(E1-E0)*i].mode = DESC_IGNORE; } ComputeElev( trk, i, FALSE, &compoundData.elev[i], NULL, FALSE ); - compoundDesc[Z0+(E1-E0)*i].mode = (EndPtIsDefinedElev(trk,i)?0:DESC_RO)|DESC_NOREDRAW; + compoundDesc[Z0+(E1-E0)*i].mode = (EndPtIsDefinedElev(trk, + i)?0:DESC_RO)|DESC_NOREDRAW; } compoundDesc[GR].mode = DESC_RO; } - if ( compoundData.epCnt == 2 ) + if ( compoundData.epCnt == 2 ) { compoundData.length = GetTrkLength( trk, 0, 1 ); - if ( compoundData.length > minLength && compoundData.epCnt > 1) - compoundData.grade = fabs( (compoundData.elev[0]-compoundData.elev[1])/compoundData.length )*100.0; - else + } + if ( compoundData.length > minLength && compoundData.epCnt > 1) { + compoundData.grade = fabs( (compoundData.elev[0] + -compoundData.elev[1])/compoundData.length )*100.0; + } else { compoundData.grade = 0.0; + } if (GetTrkEndPtCnt(trk) == 0) { compoundDesc[LT].mode = 0; - } else + } else { compoundDesc[LT].mode = DESC_IGNORE; + } DoDescribe(trackType, trk, compoundDesc, UpdateCompound); if ( compoundDesc[LT].control0!=NULL) { wListClear( (wList_p)compoundDesc[LT].control0 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("Solid"), NULL, (void*)0 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("Dash"), NULL, (void*)1 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("Dot"), NULL, (void*)2 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("DashDot"), NULL, (void*)3 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("DashDotDot"), NULL, (void*)4 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("CenterDot"), NULL, (void*)5 ); - wListAddValue( (wList_p)compoundDesc[LT].control0, _("PhantomDot"), NULL, (void*)6 ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("Solid"), NULL, I2VP(0) ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("Dash"), NULL, I2VP(1) ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("Dot"), NULL, I2VP(2) ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("DashDot"), NULL, + I2VP(3) ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("DashDotDot"), NULL, + I2VP(4) ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("CenterDot"), NULL, + I2VP(5) ); + wListAddValue( (wList_p)compoundDesc[LT].control0, _("PhantomDot"), NULL, + I2VP(6) ); wListSetIndex( (wList_p)compoundDesc[LT].control0, compoundData.linetype ); } @@ -967,74 +1171,82 @@ void DescribeCompound( void DeleteCompound( - track_p t ) + track_p t ) { - struct extraData *xx = GetTrkExtraData(t); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, + extraDataCompound_t); FreeFilledDraw( xx->segCnt, xx->segs ); - MyFree( xx->segs ); + if (xx->segCnt>0) { MyFree( xx->segs ); } xx->segs = NULL; } BOOL_T WriteCompound( - track_p t, - FILE * f ) + track_p t, + FILE * f ) { - struct extraData *xx = GetTrkExtraData(t); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, + extraDataCompound_t); EPINX_T ep, epCnt; + int bits; long options; - long position = 0; +// long position = 0; drawLineType_e lineType = 0; - PATHPTR_T path; BOOL_T rc = TRUE; options = (long)GetTrkWidth(t); - if (xx->handlaid) - options |= 0x08; - if (xx->flipped) - options |= 0x10; - if (xx->ungrouped) - options |= 0x20; - if (xx->split) - options |= 0x40; - if ( ( GetTrkBits( t ) & TB_HIDEDESC ) != 0 ) - options |= 0x80; - epCnt = GetTrkEndPtCnt(t); - if ( epCnt > -0 ) { - path = xx->paths; - while ( path != xx->pathCurr ) { - path += strlen((char*)path)+1; - while ( path[0] || path[1] ) - path++; - path += 2; - if ( *path == 0 ) - break; - position++; - } + if (xx->handlaid) { + options |= COMPOUND_OPTION_HANDLAID; + } + if (xx->flipped) { + options |= COMPOUND_OPTION_FLIPPED; + } + if (xx->ungrouped) { + options |= COMPOUND_OPTION_UNGROUPED; } + if (xx->split) { + options |= COMPOUND_OPTION_SPLIT; + } + if (xx->pathOverRide) { + options |= COMPOUND_OPTION_PATH_OVERRIDE; + } + if (xx->pathNoCombine) { + options |= COMPOUND_OPTION_PATH_NOCOMBINE; + } + if ( ( GetTrkBits( t ) & TB_HIDEDESC ) != 0 ) { + options |= COMPOUND_OPTION_HIDEDESC; + } + epCnt = GetTrkEndPtCnt(t); lineType = xx->lineType; + bits = GetTrkVisible(t)|(GetTrkNoTies(t)?1<<2:0)|(GetTrkBridge(t)?1<<3:0)| + (GetTrkRoadbed(t)?1<<4:0); rc &= fprintf(f, "%s %d %d %ld %ld %d %s %d %0.6f %0.6f 0 %0.6f \"%s\"\n", - GetTrkTypeName(t), - GetTrkIndex(t), GetTrkLayer(t), options, position, lineType, - GetTrkScaleName(t), GetTrkVisible(t)|(GetTrkNoTies(t)?1<<2:0)|(GetTrkBridge(t)?1<<3:0), - xx->orig.x, xx->orig.y, xx->angle, - PutTitle(xtitle(xx)) )>0; - for (ep=0; ep<epCnt; ep++ ) + GetTrkTypeName(t), + GetTrkIndex(t), GetTrkLayer(t), options, + GetCurrPathIndex(t), lineType, + GetTrkScaleName(t), bits, + xx->orig.x, xx->orig.y, xx->angle, + PutTitle(xtitle(xx)) )>0; + for (ep=0; ep<epCnt; ep++ ) { WriteEndPt( f, t, ep ); + } switch ( xx->special ) { case TOadjustable: rc &= fprintf( f, "\tX %s %0.3f %0.3f\n", ADJUSTABLE, - xx->u.adjustable.minD, xx->u.adjustable.maxD )>0; + xx->u.adjustable.minD, xx->u.adjustable.maxD )>0; break; case TOpier: - rc &= fprintf( f, "\tX %s %0.6f \"%s\"\n", PIER, xx->u.pier.height, xx->u.pier.name )>0; + rc &= fprintf( f, "\tX %s %0.6f \"%s\"\n", PIER, xx->u.pier.height, + xx->u.pier.name )>0; break; default: ; } - rc &= fprintf( f, "\tD %0.6f %0.6f\n", xx->descriptionOff.x, xx->descriptionOff.y )>0; - rc &= WriteCompoundPathsEndPtsSegs( f, xpaths(xx), xx->segCnt, xx->segs, 0, NULL ); + rc &= fprintf( f, "\tD %0.6f %0.6f\n", xx->descriptionOff.x, + xx->descriptionOff.y )>0; + rc &= WriteCompoundPathsEndPtsSegs( f, GetPaths( t ), xx->segCnt, xx->segs, 0, + NULL ); return rc; } @@ -1047,8 +1259,10 @@ BOOL_T WriteCompound( * */ -EXPORT void SetCompoundLineType( track_p trk, int width ) { - struct extraData * xx = GetTrkExtraData(trk); +EXPORT void SetCompoundLineType( track_p trk, int width ) +{ + struct extraDataCompound_t * xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); switch(width) { case 0: xx->lineType = DRAWLINESOLID; @@ -1077,25 +1291,23 @@ EXPORT void SetCompoundLineType( track_p trk, int width ) { EXPORT track_p NewCompound( - TRKTYP_T trkType, - TRKINX_T index, - coOrd pos, - ANGLE_T angle, - char * title, - EPINX_T epCnt, - trkEndPt_t * epp, - DIST_T * radii, - int pathLen, - char * paths, - wIndex_t segCnt, - trkSeg_p segs ) + TRKTYP_T trkType, + TRKINX_T index, + coOrd pos, + ANGLE_T angle, + char * title, + EPINX_T epCnt, + trkEndPt_p epp0, + PATHPTR_T paths, + wIndex_t segCnt, + trkSeg_p segs ) { track_p trk; - struct extraData * xx; + struct extraDataCompound_t * xx; EPINX_T ep; trk = NewTrack( index, trkType, epCnt, sizeof (*xx) + 1 ); - xx = GetTrkExtraData(trk); + xx = GET_EXTRA_DATA(trk, trkType, extraDataCompound_t); xx->orig = pos; xx->angle = angle; xx->handlaid = FALSE; @@ -1107,41 +1319,28 @@ EXPORT track_p NewCompound( xx->title = MyStrdup( title ); xx->customInfo = NULL; xx->special = TOnormal; - if ( pathLen > 0 ) - xx->paths = memdup( paths, pathLen ); - else - xx->paths = (PATHPTR_T)""; - xx->pathLen = pathLen; - xx->pathCurr = xx->paths; + SetPaths( trk, paths ); xx->segCnt = segCnt; xx->segs = memdup( segs, segCnt * sizeof *segs ); - trkSeg_p p = xx->segs; +// trkSeg_p p = xx->segs; CopyPoly(xx->segs, xx->segCnt); FixUpBezierSegs(xx->segs,xx->segCnt); ComputeCompoundBoundingBox( trk ); SetDescriptionOrig( trk ); -// if (radii) { -// xx->special = TOcurved; -// xx->u.curved.radii.max = 0; -// xx->u.curved.radii.cnt = 0; -// DYNARR_SET(DIST_T,xx->u.curved.radii,epCnt); -// } for ( ep=0; ep<epCnt; ep++ ) { - SetTrkEndPoint( trk, ep, epp[ep].pos, epp[ep].angle ); -// if (radii) { -// DYNARR_N(DIST_T,xx->u.curved.radii,ep) = radii[ep]; -// } + trkEndPt_p epp = EndPtIndex( epp0, ep ); + SetTrkEndPoint( trk, ep, GetEndPtPos(epp), GetEndPtAngle(epp) ); } return trk; } BOOL_T ReadCompound( - char * line, - TRKTYP_T trkType ) + char * line, + TRKTYP_T trkType ) { track_p trk; - struct extraData *xx; + struct extraDataCompound_t *xx; TRKINX_T index; BOOL_T visible; coOrd orig; @@ -1154,31 +1353,41 @@ BOOL_T ReadCompound( long options = 0; long position = 0; long lineType = 0; - PATHPTR_T path=NULL; if (paramVersion<3) { if ( !GetArgs( line, "dXsdpfq", - &index, &layer, scale, &visible, &orig, &angle, &title ) ) + &index, &layer, scale, &visible, &orig, &angle, &title ) ) { return FALSE; + } } else if (paramVersion <= 5 && trkType == T_STRUCTURE) { if ( !GetArgs( line, "dL00sdpfq", - &index, &layer, scale, &visible, &orig, &angle, &title ) ) + &index, &layer, scale, &visible, &orig, &angle, &title ) ) { return FALSE; + } } else { if ( !GetArgs( line, paramVersion<9?"dLlldsdpYfq":"dLlldsdpffq", - &index, &layer, &options, &position, &lineType, scale, &visible, &orig, &elev, &angle, &title ) ) + &index, &layer, &options, &position, &lineType, scale, &visible, &orig, &elev, + &angle, &title ) ) { return FALSE; + } } - if (paramVersion >=3 && paramVersion <= 5 && trkType == T_STRUCTURE) + if (paramVersion >=3 && paramVersion <= 5 && trkType == T_STRUCTURE) { strcpy( scale, curScaleName ); - DYNARR_RESET( trkEndPt_t, tempEndPts_da ); + } + TempEndPtsReset(); pathCnt = 0; - if ( !ReadSegs() ) + if ( !ReadSegs() ) { return FALSE; - path = pathPtr; - if ( tempEndPts_da.cnt > 0 && pathCnt <= 1 ) { - pathCnt = 10; - path = (PATHPTR_T)"Normal\01\0\0"; + } + if ( trkType == T_TURNOUT ) { + if ( TempEndPtsCount() <= 0 ) { + InputError( "Turnout defn without EndPoints", TRUE ); + return FALSE; + } + if ( pathCnt <= 1 ) { + InputError( "Turnout defn without a Path", TRUE ); + return FALSE; + } } if (paramVersion<6 && strlen( title ) > 2) { cp = strchr( title, '\t' ); @@ -1189,68 +1398,67 @@ BOOL_T ReadCompound( UpdateTitleMark( title, LookupScale(scale) ); } } - trk = NewCompound( trkType, index, orig, angle, title, 0, NULL, NULL, pathCnt, (char *)path, tempSegs_da.cnt, &tempSegs(0) ); + trk = NewCompound( trkType, index, orig, angle, title, 0, NULL, + pathCnt > 1 ? pathPtr : NULL, + tempSegs_da.cnt, &tempSegs(0) ); SetEndPts( trk, 0 ); if ( paramVersion < 3 ) { SetTrkVisible(trk, visible!=0); SetTrkNoTies(trk, FALSE); SetTrkBridge(trk, FALSE); + SetTrkRoadbed(trk, FALSE); } else { SetTrkVisible(trk, visible&2); SetTrkNoTies(trk, visible&4); SetTrkBridge(trk, visible&8); + SetTrkRoadbed(trk, visible&16); } SetTrkScale(trk, LookupScale( scale )); SetTrkLayer(trk, layer); SetTrkWidth(trk, (int)(options&3)); - xx = GetTrkExtraData(trk); - xx->handlaid = (int)((options&0x08)!=0); - xx->flipped = (int)((options&0x10)!=0); - xx->ungrouped = (int)((options&0x20)!=0); - xx->split = (int)((options&0x40)!=0); + xx = GET_EXTRA_DATA(trk, trkType, extraDataCompound_t); + xx->handlaid = (int)((options&COMPOUND_OPTION_HANDLAID)!=0); + xx->flipped = (int)((options&COMPOUND_OPTION_FLIPPED)!=0); + xx->ungrouped = (int)((options&COMPOUND_OPTION_UNGROUPED)!=0); + xx->split = (int)((options&COMPOUND_OPTION_SPLIT)!=0); + xx->pathOverRide = (int)((options&COMPOUND_OPTION_PATH_OVERRIDE)!=0); + xx->pathNoCombine = (int)((options&COMPOUND_OPTION_PATH_NOCOMBINE)!=0); xx->lineType = lineType; xx->descriptionOff = descriptionOff; - if ( ( options & 0x80 ) != 0 ) + if ( ( options & COMPOUND_OPTION_HIDEDESC ) != 0 ) { SetTrkBits( trk, TB_HIDEDESC ); + } if (tempSpecial[0] != '\0') { if (strncmp( tempSpecial, ADJUSTABLE, strlen(ADJUSTABLE) ) == 0) { xx->special = TOadjustable; if ( !GetArgs( tempSpecial+strlen(ADJUSTABLE), "ff", - &xx->u.adjustable.minD, &xx->u.adjustable.maxD ) ) + &xx->u.adjustable.minD, &xx->u.adjustable.maxD ) ) { return FALSE; + } } else if (strncmp( tempSpecial, PIER, strlen(PIER) ) == 0) { xx->special = TOpier; if ( !GetArgs( tempSpecial+strlen(PIER), "fq", - &xx->u.pier.height, &xx->u.pier.name ) ) + &xx->u.pier.height, &xx->u.pier.name ) ) { return FALSE; + } } else { InputError("Unknown special case", TRUE); return FALSE; } } - if (pathCnt > 0) { - path = xx->pathCurr; - while ( position-- ) { - path += strlen((char *)path)+1; - while ( path[0] || path[1] ) - path++; - path += 2; - if ( *path == 0 ) - path = xx->paths; - } - } - xx->pathCurr = path; + SetCurrPathIndex( trk, position ); return TRUE; } void MoveCompound( - track_p trk, - coOrd orig ) + track_p trk, + coOrd orig ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); xx->orig.x += orig.x; xx->orig.y += orig.y; ComputeCompoundBoundingBox( trk ); @@ -1258,11 +1466,12 @@ void MoveCompound( void RotateCompound( - track_p trk, - coOrd orig, - ANGLE_T angle ) + track_p trk, + coOrd orig, + ANGLE_T angle ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); Rotate( &xx->orig, orig, angle ); xx->angle = NormalizeAngle( xx->angle + angle ); Rotate( &xx->descriptionOff, zero, angle ); @@ -1271,10 +1480,11 @@ void RotateCompound( void RescaleCompound( - track_p trk, - FLOAT_T ratio ) + track_p trk, + FLOAT_T ratio ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); xx->orig.x *= ratio; xx->orig.y *= ratio; xx->descriptionOff.x *= ratio; @@ -1286,11 +1496,12 @@ void RescaleCompound( void FlipCompound( - track_p trk, - coOrd orig, - ANGLE_T angle ) + track_p trk, + coOrd orig, + ANGLE_T angle ) { - struct extraData *xx = GetTrkExtraData(trk); + struct extraDataCompound_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK, + extraDataCompound_t); EPINX_T ep, epCnt; char * mP, *nP, *pP; int mL, nL, pL; @@ -1310,16 +1521,18 @@ void FlipCompound( xx->descriptionOrig.y = - xx->descriptionOrig.y; ComputeCompoundBoundingBox( trk ); epCnt = GetTrkEndPtCnt( trk ); - if ( epCnt >= 1 && epCnt <= 2 ) + if ( epCnt >= 1 && epCnt <= 2 ) { return; + } ParseCompoundTitle( xtitle(xx), &mP, &mL, &nP, &nL, &pP, &pL ); - to = FindCompound( epCnt==0?FIND_STRUCT:FIND_TURNOUT, GetScaleName(GetTrkScale(trk)), xx->title ); + to = FindCompound( epCnt==0?FIND_STRUCT:FIND_TURNOUT, + GetScaleName(GetTrkScale(trk)), xx->title ); if ( epCnt!=0 && to && to->customInfo ) { if ( GetArgs( to->customInfo, "qc", &type, &cp ) ) { if ( strcmp( type, "Regular Turnout" ) == 0 || - strcmp( type, "Curved Turnout" ) == 0 ) { + strcmp( type, "Curved Turnout" ) == 0 ) { if ( GetArgs( cp, "qqqqq", &mfg, &descL, &partL, &descR, &partR ) && - mP && strcmp( mP, mfg ) == 0 && nP && pP ) { + mP && strcmp( mP, mfg ) == 0 && nP && pP ) { if ( strcmp( nP, descL ) == 0 && strcmp( pP, partL ) == 0 ) { sprintf( message, "%s\t%s\t%s", mfg, descR, partR ); xx->title = MyStrdup( message ); @@ -1331,7 +1544,7 @@ void FlipCompound( return; } } - } + } } } if ( epCnt == 3 || epCnt == 4 ) { @@ -1345,54 +1558,66 @@ void FlipCompound( if ( epCnt == 3 ) { /* Wye? */ if ( fabs(endPos[1].x-endPos[2].x) < SMALLVALUE && - fabs(endPos[1].y+endPos[2].y) < SMALLVALUE ) + fabs(endPos[1].y+endPos[2].y) < SMALLVALUE ) { return; + } } else { /* Crossing */ - if ( fabs( (endPos[1].x-endPos[3].x) - (endPos[2].x-endPos[0].x ) ) < SMALLVALUE && - fabs( (endPos[2].y+endPos[3].y) ) < SMALLVALUE && - fabs( (endPos[0].y-endPos[1].y) ) < SMALLVALUE && - NormalizeAngle( (endAngle[2]-endAngle[3]-180+0.05) ) < 0.10 ) + if ( fabs( (endPos[1].x-endPos[3].x) - (endPos[2].x-endPos[0].x ) ) < SMALLVALUE + && + fabs( (endPos[2].y+endPos[3].y) ) < SMALLVALUE && + fabs( (endPos[0].y-endPos[1].y) ) < SMALLVALUE && + NormalizeAngle( (endAngle[2]-endAngle[3]-180+0.05) ) < 0.10 ) { return; + } /* 3 way */ if ( fabs( (endPos[1].x-endPos[2].x) ) < SMALLVALUE && - fabs( (endPos[1].y+endPos[2].y) ) < SMALLVALUE && - fabs( (endPos[0].y-endPos[3].y) ) < SMALLVALUE && - NormalizeAngle( (endAngle[1]+endAngle[2]-180+0.05) ) < 0.10 ) + fabs( (endPos[1].y+endPos[2].y) ) < SMALLVALUE && + fabs( (endPos[0].y-endPos[3].y) ) < SMALLVALUE && + NormalizeAngle( (endAngle[1]+endAngle[2]-180+0.05) ) < 0.10 ) { return; + } } toBest = NULL; d0 = 0.0; for (inx=0; inx<turnoutInfo_da.cnt; inx++) { to = turnoutInfo(inx); if ( IsParamValid(to->paramFileIndex) && - to->segCnt > 0 && - to->scaleInx == GetTrkScale(trk) && - to->segCnt != 0 && - to->endCnt == epCnt ) { + to->segCnt > 0 && + to->scaleInx == GetTrkScale(trk) && + to->segCnt != 0 && + to->endCnt == epCnt ) { d1 = 0; a1 = 0; for ( ep=0; ep<epCnt; ep++ ) { - d2 = FindDistance( endPos[ep], to->endPt[ep].pos ); - if ( d2 > SMALLVALUE ) + trkEndPt_p epp = EndPtIndex( to->endPt, ep ); + d2 = FindDistance( endPos[ep], GetEndPtPos(epp) ); + if ( d2 > SMALLVALUE ) { break; - if ( d2 > d1 ) + } + if ( d2 > d1 ) { d1 = d2; - a2 = NormalizeAngle( endAngle[ep] - to->endPt[ep].angle + 0.05 ); - if ( a2 > 0.1 ) + } + a2 = NormalizeAngle( endAngle[ep] - GetEndPtAngle(epp) + 0.05 ); + if ( a2 > 0.1 ) { break; - if ( a2 > a1 ) + } + if ( a2 > a1 ) { a1 = a2; + } } - if ( ep<epCnt ) + if ( ep<epCnt ) { continue; - if ( toBest == NULL || d1 < d0 ) + } + if ( toBest == NULL || d1 < d0 ) { toBest = to; + } } } if ( toBest ) { - if ( strcmp( xx->title, toBest->title ) != 0 ) + if ( strcmp( xx->title, toBest->title ) != 0 ) { xx->title = MyStrdup( toBest->title ); + } return; } } @@ -1401,51 +1626,64 @@ void FlipCompound( typedef struct { - long count; - char * type; - char * name; - FLOAT_T price; - } enumCompound_t; + long count; + char * type; + char * name; + FLOAT_T price; + DynString indexes; +} enumCompound_t; static dynArr_t enumCompound_da; #define EnumCompound(N) DYNARR_N( enumCompound_t,enumCompound_da,N) BOOL_T EnumerateCompound( track_p trk ) { - struct extraData *xx; + struct extraDataCompound_t *xx; INT_T inx, inx2; int cmp; long listLabelsOption = listLabels; + char * index = MyMalloc(10); if ( trk != NULL ) { - xx = GetTrkExtraData(trk); - if ( xx->flipped ) + xx = GET_EXTRA_DATA(trk, T_NOTRACK, extraDataCompound_t); + if ( xx->flipped ) { listLabelsOption |= LABEL_FLIPPED; + } #ifdef LATER - if ( xx->ungrouped ) + if ( xx->ungrouped ) { listLabelsOption |= LABEL_UNGROUPED; - if ( xx->split ) + } + if ( xx->split ) { listLabelsOption |= LABEL_SPLIT; + } #endif FormatCompoundTitle( listLabelsOption, xtitle(xx) ); - if (message[0] == '\0') - return TRUE; + if (message[0] == '\0') { + return FALSE; //No content + } for (inx = 0; inx < enumCompound_da.cnt; inx++ ) { cmp = strcmp( EnumCompound(inx).name, message ); if ( cmp == 0 ) { EnumCompound(inx).count++; + sprintf(index,",%d",GetTrkIndex(trk)); + DynStringCatCStr(&(EnumCompound(inx).indexes),index); + MyFree(index); return TRUE; } else if ( cmp > 0 ) { break; } } DYNARR_APPEND( enumCompound_t, enumCompound_da, 10 ); - for ( inx2 = enumCompound_da.cnt-1; inx2 > inx; inx2-- ) + for ( inx2 = enumCompound_da.cnt-1; inx2 > inx; inx2-- ) { EnumCompound(inx2) = EnumCompound(inx2-1); + } EnumCompound(inx).name = MyStrdup( message ); - if (strlen(message) > (size_t)enumerateMaxDescLen) - enumerateMaxDescLen = strlen(message); + if (strlen(message) > (size_t)enumerateMaxDescLen) { + enumerateMaxDescLen = (int)strlen(message); + } EnumCompound(inx).type = GetTrkTypeName( trk ); EnumCompound(inx).count = 1; + DynStringMalloc(&(EnumCompound(inx).indexes),100); + DynStringPrintf(&(EnumCompound(inx).indexes),"%d",GetTrkIndex(trk)); FormatCompoundTitle( LABEL_MANUF|LABEL_DESCR|LABEL_PARTNO, xtitle(xx) ); wPrefGetFloat( "price list", message, &(EnumCompound(inx).price), 0.0 ); } else { @@ -1454,13 +1692,17 @@ BOOL_T EnumerateCompound( track_p trk ) for (inx = 0; inx < enumCompound_da.cnt; inx++ ) { if (EnumCompound(inx).type[0] == *type) { EnumerateList( EnumCompound(inx).count, - EnumCompound(inx).price, - EnumCompound(inx).name ); + EnumCompound(inx).price, + EnumCompound(inx).name, + DynStringSize(&(EnumCompound(inx).indexes))?DynStringToCStr(&(EnumCompound( + inx).indexes)):NULL); } + DynStringFree(&(EnumCompound(inx).indexes)); } } DYNARR_RESET( enumCompound_t, enumCompound_da ); } + MyFree(index); return TRUE; } |