summaryrefslogtreecommitdiff
path: root/app/bin/track.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/track.c')
-rw-r--r--app/bin/track.c2546
1 files changed, 1253 insertions, 1293 deletions
diff --git a/app/bin/track.c b/app/bin/track.c
index c9ec7db..951eec3 100644
--- a/app/bin/track.c
+++ b/app/bin/track.c
@@ -1,5 +1,5 @@
/** \file track.c
- * Track
+ * Track
*/
/* XTrkCad - Model Railroad CAD
@@ -17,16 +17,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 <assert.h>
-#include <time.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <math.h>
-#include <string.h>
-
#include "ccurve.h"
#include "cjoin.h"
#include "compound.h"
@@ -36,36 +29,36 @@
#include "custom.h"
#include "draw.h"
#include "fileio.h"
-#include "i18n.h"
#include "layout.h"
-#include "messages.h"
#include "param.h"
#include "paths.h"
#include "track.h"
-#include "utility.h"
+#include "trackx.h"
+#include "trkendpt.h"
#include "misc.h"
#include "ctrain.h"
+#include "common-ui.h"
+#include "version.h"
-#ifndef TRACKDEP
-#ifndef FASTTRACK
-#include "trackx.h"
-#endif
-#endif
+#include <inttypes.h>
-#ifndef WINDOWS
-#include <errno.h>
-#else
-// starting from Visual Studio 2015 round is in the runtime library, fake otherwise
-#if ( _MSC_VER < 1900 )
-#define round(x) floor((x)+0.5)
-#endif
-#endif
+#include <stdint.h>
+
+#define SLOG_FMT "0x%.12" PRIxPTR
EXPORT char tempSpecial[4096];
+/** @logcmd @showrefby track=n track.c */
static int log_track = 0;
+/** @logcmd @showrefby endPt=n track.c */
static int log_endPt = 0;
+/** @logcmd @showrefby readTracks=n track.c */
static int log_readTracks = 0;
+/** @logcmd @showrefby timedrawtracks=n track.c */
+static int log_timedrawtracks = 0;
+
+// Enable trkType checks on extraData*_t
+#define CHECK_EXTRA_DATA
/*****************************************************************************
*
@@ -77,15 +70,20 @@ static int log_readTracks = 0;
#define CLOSETOTHEEDGE (10) /**< minimum distance between paste position and edge of window */
+EXPORT DIST_T trackGauge;
+EXPORT DIST_T minLength = 0.1;
+EXPORT DIST_T connectDistance = 0.1;
+EXPORT ANGLE_T connectAngle = 1.0;
+EXPORT long twoRailScale = 16;
+
EXPORT wIndex_t trackCount;
EXPORT long drawEndPtV = 2;
EXPORT long drawUnconnectedEndPt = 0; /**< How do we draw Unconnected EndPts */
-EXPORT long centerDrawMode = FALSE; /**< flag to control drawing of circle centers */
-EXPORT long printCenterLines = FALSE; /**< flag to control drawing of centerline in Print */
+EXPORT long centerDrawMode =
+ FALSE; /**< flag to control drawing of circle centers */
-static BOOL_T exportingTracks = FALSE;
EXPORT signed char * pathPtr;
EXPORT int pathCnt = 0;
@@ -101,10 +99,7 @@ EXPORT unsigned int curTrackLayer;
EXPORT coOrd descriptionOff;
EXPORT DIST_T roadbedWidth = 0.0;
-EXPORT DIST_T roadbedLineWidth = 3.0/75.0;
-
-//EXPORT DIST_T minTrackRadius;
-//EXPORT DIST_T maxTrackGrade = 5.0;
+EXPORT DIST_T roadbedLineWidth = 3.0/BASE_DPI;
static int suspendElevUpdates = FALSE;
@@ -114,19 +109,23 @@ EXPORT BOOL_T onTrackInSplit = FALSE;
static BOOL_T inDrawTracks;
-static wBool_t bWriteEndPtDirectIndex = FALSE;
+EXPORT wBool_t bFreeTrack = FALSE;
+
+EXPORT long colorTrack = 0;
+EXPORT long colorDraw = 0;
-#ifndef TRACKDEP
/*****************************************************************************
*
- *
+ *
*
*/
-EXPORT void ActivateTrack( track_cp trk) {
+EXPORT void ActivateTrack( track_cp trk)
+{
int inx = GetTrkType(trk);
- if (trackCmds( inx )->activate != NULL)
+ if (trackCmds( inx )->activate != NULL) {
trackCmds( inx )->activate (trk);
+ }
}
@@ -150,20 +149,21 @@ EXPORT DIST_T GetTrkDistance( track_cp trk, coOrd * pos )
/**
* Check whether the track passed as parameter is close to an existing piece. Track
* pieces that aren't visible (in a tunnel or on an invisble layer) can be ignored,
- * depending on flag. If there is a track closeby, the passed track is moved to that
+ * depending on flag. If there is a track closeby, the passed track is moved to that
* position. This implements the snap feature.
*
* \param fp IN/OUT the old and the new position
* \param complain IN show error message if there is no other piece of track
- * \param track IN
+ * \param track IN
* \param ignoreHidden IN decide whether hidden track is ignored or not
- * \return NULL if there is no track, pointer to track otherwise
+ * \return NULL if there is no track, pointer to track otherwise
*/
-EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track, BOOL_T ignoreHidden, track_p t )
+EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track,
+ BOOL_T ignoreHidden, track_p t )
{
track_p trk;
- DIST_T distance, closestDistance = 1000000;
+ DIST_T distance, closestDistance = DIST_INF;
track_p closestTrack = NULL;
coOrd p, closestPos, q0, q1;
@@ -173,30 +173,38 @@ EXPORT track_p OnTrack2( coOrd * fp, BOOL_T complain, BOOL_T track, BOOL_T ignor
q0.y -= 1.0;
q1.y += 1.0;
TRK_ITERATE( trk ) {
- if ( track && !IsTrack(trk) )
+ if ( track && !IsTrack(trk) ) {
continue;
- if (trk == t) continue;
+ }
+ if (trk == t) { continue; }
+ // Bounding box check
if (trk->hi.x < q0.x ||
- trk->lo.x > q1.x ||
- trk->hi.y < q0.y ||
- trk->lo.y > q1.y )
+ trk->lo.x > q1.x ||
+ trk->hi.y < q0.y ||
+ trk->lo.y > q1.y ) {
continue;
+ }
if ( ignoreHidden ) {
- if ( (!GetTrkVisible(trk)) && drawTunnel == DRAW_TUNNEL_NONE)
+ if ( (!GetTrkVisible(trk)) && drawTunnel == DRAW_TUNNEL_NONE) {
continue;
- if ( !GetLayerVisible( GetTrkLayer( trk ) ) )
+ }
+ if ( !GetLayerVisible( GetTrkLayer( trk ) ) ) {
continue;
+ }
}
+
p = *fp;
distance = trackCmds( GetTrkType(trk) )->distance( trk, &p );
- if (fabs(distance) <= fabs(closestDistance)) { //Make the last (highest) preferred
+ if (fabs(distance) <= fabs(
+ closestDistance)) { //Make the last (highest) preferred
closestDistance = distance;
closestTrack = trk;
closestPos = p;
}
}
- if (closestTrack && closestDistance <0 ) closestDistance = 0.0; //Turntable was closest - inside well
- if (closestTrack && ((closestDistance <= mainD.scale*0.25) || (closestDistance <= trackGauge*2.0) )) {
+ if (closestTrack && closestDistance <0 ) { closestDistance = 0.0; } //Turntable was closest - inside well
+ if (closestTrack && ((closestDistance <= mainD.scale*0.25)
+ || (closestDistance <= trackGauge*2.0) )) {
*fp = closestPos;
return closestTrack;
}
@@ -218,7 +226,9 @@ EXPORT track_p OnTrack( coOrd * fp, BOOL_T complain, BOOL_T track )
return OnTrack2( fp, complain, track, TRUE, NULL );
}
-EXPORT track_p OnTrackIgnore (coOrd * fp, BOOL_T complain, BOOL_T track, track_p t ) {
+EXPORT track_p OnTrackIgnore (coOrd * fp, BOOL_T complain, BOOL_T track,
+ track_p t )
+{
return OnTrack2(fp, complain, track, TRUE, t);
}
@@ -231,8 +241,9 @@ EXPORT BOOL_T CheckTrackLayer( track_p trk )
} else if (GetLayerModule( GetTrkLayer( trk ) ) ) {
ErrorMessage( MSG_CANT_MODIFY_MODULE_TRK );
return FALSE;
- } else
+ } else {
return TRUE;
+ }
}
EXPORT BOOL_T CheckTrackLayerSilent( track_p trk )
@@ -241,8 +252,9 @@ EXPORT BOOL_T CheckTrackLayerSilent( track_p trk )
return FALSE;
} else if (GetLayerModule( GetTrkLayer( trk ) ) ) {
return FALSE;
- } else
+ } else {
return TRUE;
+ }
}
/******************************************************************************
@@ -252,27 +264,42 @@ EXPORT BOOL_T CheckTrackLayerSilent( track_p trk )
*/
-EXPORT void EnumerateTracks( void )
+EXPORT void EnumerateTracks( void * unused )
{
track_p trk;
TRKINX_T inx;
- enumerateMaxDescLen = strlen("Description");
+ enumerateMaxDescLen = (int)strlen("Description");
+
+ BOOL_T content = FALSE;
TRK_ITERATE( trk ) {
- /*
+ /*
* process track piece if none are selected (list all) or if it is one of the
* selected pieces (list only selected )
*/
- if ((!selectedTrackCount || GetTrkSelected(trk)) && trackCmds(trk->type)->enumerate != NULL)
- trackCmds(trk->type)->enumerate( trk );
+ if ((!selectedTrackCount || GetTrkSelected(trk))
+ && trackCmds(trk->type)->enumerate != NULL) {
+ if (trackCmds(trk->type)->enumerate( trk )==TRUE) { content = TRUE; }
+ }
+ }
+
+ if (content == FALSE) {
+ wBeep();
+ if (selectedTrackCount == 0) {
+ InfoMessage(_("No track or structure pieces are present in layout"));
+ } else {
+ InfoMessage(_("No track or structure pieces are selected"));
+ }
+ return;
}
EnumerateStart();
for (inx=1; inx<trackCmds_da.cnt; inx++)
- if (trackCmds(inx)->enumerate != NULL)
+ if (trackCmds(inx)->enumerate != NULL) {
trackCmds(inx)->enumerate( NULL );
+ }
EnumerateEnd();
}
@@ -285,32 +312,33 @@ EXPORT void EnumerateTracks( void )
static void AbortNoTrack( void )
{
- AbortProg( "No Track Op called" );
+ CHECKMSG( FALSE, ( "No Track Op called" ) );
}
static trackCmd_t notrackCmds = {
- "NOTRACK",
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack,
- (void*)AbortNoTrack };
+ "NOTRACK",
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack,
+ (void*)AbortNoTrack
+};
EXPORT TRKTYP_T InitObject( trackCmd_t * cmds )
{
@@ -328,6 +356,7 @@ EXPORT void InitTrkTrack( void )
log_track = LogFindIndex( "track" );
log_endPt = LogFindIndex( "endPt" );
log_readTracks = LogFindIndex( "readTracks" );
+ log_timedrawtracks = LogFindIndex( "timedrawtracks" );
}
/*****************************************************************************
@@ -337,7 +366,6 @@ EXPORT void InitTrkTrack( void )
*/
-#ifndef FASTTRACK
EXPORT TRKINX_T GetTrkIndex( track_p trk )
{
@@ -346,14 +374,15 @@ EXPORT TRKINX_T GetTrkIndex( track_p trk )
EXPORT TRKTYP_T GetTrkType( track_p trk )
{
- ASSERT( trk->type != T_NOTRACK && !IsTrackDeleted(trk) );
+ CHECK( trk->type != T_NOTRACK && !IsTrackDeleted(trk) );
return trk->type;
}
EXPORT SCALEINX_T GetTrkScale( track_p trk )
{
- if ( trk )
+ if ( trk ) {
return (SCALEINX_T)trk->scale;
+ }
return 0;
}
@@ -367,6 +396,14 @@ EXPORT unsigned int GetTrkLayer( track_p trk )
return trk->layer;
}
+EXPORT tieData_t GetTrkTieData( track_p trk )
+{
+ if (!GetLayerUseDefault(GetTrkLayer(trk))) {
+ return GetLayerTieData(GetTrkLayer(trk));
+ }
+ return GetScaleTieData(GetTrkScale(trk));
+}
+
EXPORT void SetBoundingBox( track_p trk, coOrd hi, coOrd lo )
{
trk->hi.x = (float)hi.x;
@@ -389,58 +426,53 @@ EXPORT EPINX_T GetTrkEndPtCnt( track_cp trk )
return trk->endCnt;
}
-EXPORT struct extraData * GetTrkExtraData( track_cp trk )
-{
- return trk->extraData;
-}
-EXPORT void SetTrkEndPoint( track_p trk, EPINX_T ep, coOrd pos, ANGLE_T angle )
+EXPORT trkEndPt_p GetTrkEndPt(track_cp trk, EPINX_T ep )
{
- ASSERT( ep < trk->endCnt );
- if (trk->endPt[ep].track != NULL) {
- AbortProg( "setTrkEndPoint: endPt is connected" );
- }
- trk->endPt[ep].pos = pos;
- trk->endPt[ep].angle = angle;
+ CHECK( ep < GetTrkEndPtCnt(trk) );
+ return EndPtIndex( trk->endPt, ep );
}
-EXPORT coOrd GetTrkEndPos( track_p trk, EPINX_T e )
-{
- ASSERT( e < trk->endCnt );
- return trk->endPt[e].pos;
-}
-EXPORT ANGLE_T GetTrkEndAngle( track_p trk, EPINX_T e )
+EXPORT struct extraDataBase_t * GetTrkExtraData( track_cp trk,
+ TRKTYP_T trkType )
{
- ASSERT( e < trk->endCnt );
- return trk->endPt[e].angle;
+//printf( "GTXD T%d TY%d\n", GetTrkIndex(trk), trkType );
+ if ( IsTrackDeleted(trk) ) {
+ // We've been called by FreeTracks() which is called from
+ // - ClearTracks to remove all tracks
+ // - DoRegression to remove expected track
+ // - UndoStart / UndoDelete
+ // Anywhere else: needs investigation
+ if ( bFreeTrack == FALSE ) {
+ printf( "GetExtraData T%d is deleted!\n", trk->index );
+ }
+ return trk->extraData;
+ }
+#ifdef CHECK_EXTRA_DATA
+ CHECK( trk->extraData );
+ CHECK( trk->type == trk->extraData->trkType );
+ CHECK( trkType == T_NOTRACK || trk->type == trkType );
+#endif
+ return trk->extraData;
}
-EXPORT track_p GetTrkEndTrk( track_p trk, EPINX_T e )
-{
- ASSERT( e < trk->endCnt );
- return trk->endPt[e].track;
-}
-EXPORT long GetTrkEndOption( track_p trk, EPINX_T e )
+EXPORT void ResizeExtraData( track_p trk, CSIZE_T newSize )
{
- ASSERT( e < trk->endCnt );
- return trk->endPt[e].option;
+ trk->extraData = MyRealloc( trk->extraData, newSize );
+ trk->extraSize = newSize;
}
-EXPORT long SetTrkEndOption( track_p trk, EPINX_T e, long option )
-{
- ASSERT( e < trk->endCnt );
- return trk->endPt[e].option = option;
-}
EXPORT DIST_T GetTrkGauge(
- track_cp trk )
+ track_cp trk )
{
- if (trk)
+ if (trk) {
return GetScaleTrackGauge( GetTrkScale( trk ) );
- else
+ } else {
return trackGauge;
+ }
}
EXPORT int GetTrkWidth( track_p trk )
@@ -455,7 +487,11 @@ EXPORT void SetTrkWidth( track_p trk, int width )
EXPORT int GetTrkBits( track_p trk )
{
- return trk->bits;
+ if (trk) {
+ return trk->bits;
+ } else {
+ return 0;
+ }
}
EXPORT int SetTrkBits( track_p trk, int bits )
@@ -476,101 +512,25 @@ EXPORT BOOL_T IsTrackDeleted( track_p trk )
{
return trk->deleted;
}
-#endif
-
-EXPORT void SetTrkEndElev( track_p trk, EPINX_T ep, int option, DIST_T height, char * station )
-{
- track_p trk1;
- EPINX_T ep1;
- trk->endPt[ep].elev.option = option;
- trk->endPt[ep].elev.cacheSet = FALSE;
- if (EndPtIsDefinedElev(trk,ep)) {
- trk->endPt[ep].elev.u.height = height;
- } else if (EndPtIsStationElev(trk,ep)) {
- if (station == NULL)
- station = "";
- trk->endPt[ep].elev.u.name = MyStrdup(station);
- }
- if ( (trk1=GetTrkEndTrk(trk, ep)) != NULL ) {
- ep1 = GetEndPtConnectedToMe( trk1, trk );
- if (ep1 >= 0) {
- trk1->endPt[ep1].elev.option = option;
- trk1->endPt[ep1].elev.u.height = height;
- if (EndPtIsDefinedElev(trk1,ep1))
- trk1->endPt[ep1].elev.u.height = height;
- else if (EndPtIsStationElev(trk,ep))
- trk1->endPt[ep1].elev.u.name = MyStrdup(station);
- }
- }
-}
-
-
-EXPORT void GetTrkEndElev( track_p trk, EPINX_T e, int *option, DIST_T *height )
-{
- *option = trk->endPt[e].elev.option;
- *height = trk->endPt[e].elev.u.height;
-}
-
-
-EXPORT int GetTrkEndElevUnmaskedMode( track_p trk, EPINX_T e )
-{
- return trk->endPt[e].elev.option;
-}
-
-
-EXPORT int GetTrkEndElevMode( track_p trk, EPINX_T e )
-{
- return trk->endPt[e].elev.option&ELEV_MASK;
-}
-
-
-EXPORT DIST_T GetTrkEndElevHeight( track_p trk, EPINX_T e )
-{
- ASSERT( EndPtIsDefinedElev(trk,e) );
- return trk->endPt[e].elev.u.height;
-}
-
-EXPORT BOOL_T GetTrkEndElevCachedHeight (track_p trk, EPINX_T e, DIST_T * height, DIST_T * length)
-{
- if (trk->endPt[e].elev.cacheSet) {
- *height = trk->endPt[e].elev.cachedElev;
- *length = trk->endPt[e].elev.cachedLength;
- return TRUE;
- }
- return FALSE;
-}
-
-EXPORT void SetTrkEndElevCachedHeight ( track_p trk, EPINX_T e, DIST_T height, DIST_T length)
-{
- trk->endPt[e].elev.cachedElev = height;
- trk->endPt[e].elev.cachedLength = length;
- trk->endPt[e].elev.cacheSet = TRUE;
-}
-
-
-EXPORT char * GetTrkEndElevStation( track_p trk, EPINX_T e )
-{
- ASSERT( EndPtIsStationElev(trk,e) );
- if ( trk->endPt[e].elev.u.name == NULL )
- return "";
- else
- return trk->endPt[e].elev.u.name;
-}
EXPORT void SetTrkEndPtCnt( track_p trk, EPINX_T cnt )
{
EPINX_T oldCnt = trk->endCnt;
trk->endCnt = cnt;
- if ((trk->endPt = MyRealloc( trk->endPt, trk->endCnt * sizeof trk->endPt[0] )) == NULL) {
- AbortProg("setTrkEndPtCnt: No memory" );
+ trk->endPt = MyRealloc( trk->endPt, EndPtSize(trk->endCnt) );
+ if (oldCnt < cnt) {
+ memset( GetTrkEndPt( trk, oldCnt ), 0, EndPtSize(cnt-oldCnt) );
+ for ( EPINX_T ep = oldCnt; ep<cnt; ep++ ) {
+ // Set .index to -1
+ SetEndPtTrack( GetTrkEndPt( trk, ep ), NULL );
+ }
}
- if (oldCnt < cnt)
- memset( &trk->endPt[oldCnt], 0, (cnt-oldCnt) * sizeof *trk->endPt );
}
+
/**
- * Set the layer for a track.
+ * Set the layer for a track.
*
* \param trk IN the layer to change the layer for
* \param layer IN the new layer for the track
@@ -579,10 +539,11 @@ void SetTrkLayer( track_p trk, int layer )
{
DecrementLayerObjects(trk->layer);
- if (useCurrentLayer)
+ if (useCurrentLayer) {
trk->layer = (unsigned int)curLayer;
- else
+ } else {
trk->layer = (unsigned int)layer;
+ }
IncrementLayerObjects(trk->layer);
}
@@ -603,8 +564,9 @@ EXPORT int ClrAllTrkBitsRedraw( int bits, wBool_t bRedraw )
if (trk->bits&bits) {
cnt++;
trk->bits &= ~bits;
- if ( bRedraw )
+ if ( bRedraw ) {
DrawNewTrack( trk );
+ }
}
}
return cnt;
@@ -617,9 +579,7 @@ EXPORT void SetTrkElev( track_p trk, int mode, DIST_T elev )
SetTrkBits( trk, TB_ELEVPATH );
trk->elev = elev;
trk->elevMode = mode;
- for (int i=0;i<trk->endCnt;i++) {
- trk->endPt[i].elev.cacheSet = FALSE;
- }
+ ClrEndPtElevCache( trk->endCnt, trk->endPt );
}
@@ -647,7 +607,7 @@ EXPORT void ClearElevPath( void )
EXPORT BOOL_T GetTrkOnElevPath( track_p trk, DIST_T * elev )
{
if (trk->bits&TB_ELEVPATH) {
- if ( elev ) *elev = trk->elev;
+ if ( elev ) { *elev = trk->elev; }
return TRUE;
} else {
return FALSE;
@@ -670,67 +630,23 @@ EXPORT void CopyAttributes( track_p src, track_p dst )
*/
-EXPORT BOOL_T WriteEndPt( FILE * f, track_cp trk, EPINX_T ep )
-{
- trkEndPt_p endPt = &trk->endPt[ep];
- BOOL_T rc = TRUE;
- long option;
-
- assert ( endPt != NULL );
- if (bWriteEndPtDirectIndex && endPt->index > 0) {
- rc &= fprintf( f, "\tT4 %d ", endPt->index )>0;
- } else if (endPt->track == NULL ||
- ( exportingTracks && !GetTrkSelected(endPt->track) ) ) {
- rc &= fprintf( f, "\tE4 " )>0;
- } else {
- rc &= fprintf( f, "\tT4 %d ", endPt->track->index )>0;
- }
- rc &= fprintf( f, "%0.6f %0.6f %0.6f", endPt->pos.x, endPt->pos.y, endPt->angle )>0;
- option = (endPt->option<<8) | (endPt->elev.option&0xFF);
- if ( option != 0 ) {
- rc &= fprintf( f, " %ld %0.6f %0.6f", option, endPt->elev.doff.x, endPt->elev.doff.y )>0;
- switch ( endPt->elev.option&ELEV_MASK ) {
- case ELEV_DEF:
- rc &= fprintf( f, " %0.6f ", endPt->elev.u.height )>0;
- break;
- case ELEV_STATION:
- rc &= fprintf( f, " \"%s\" ", PutTitle( endPt->elev.u.name ) )>0;
- break;
- default:
- rc &= fprintf( f, " 0.0 ")>0;
- }
- } else {
- rc &= fprintf( f, " 0 0.0 0.0 0.0 ")>0;
- }
- if ((endPt->elev.option&ELEV_MASK) == ELEV_DEF)
- rc &= fprintf( f, "%0.6f ",endPt->elev.u.height)>0;
- else
- rc &= fprintf( f, "0.0 ")>0;
- long elevVisible = (endPt->elev.option&ELEV_VISIBLE)?1:0;
- long elevType = endPt->elev.option&ELEV_MASK;
- long gapType = endPt->option;
- rc &= fprintf( f, "%ld %ld %ld ", elevVisible, elevType, gapType)>0;
- rc &= fprintf( f, "%0.6f ", trk->elev)>0;
- rc &= fprintf( f, "\n" )>0;
- return rc;
-}
-
-
EXPORT EPINX_T PickEndPoint( coOrd p, track_cp trk )
{
EPINX_T inx, i;
DIST_T d, dd;
coOrd pos;
- if (trk->endCnt <= 0)
+ if (trk->endCnt <= 0) {
return -1;
+ }
if ( onTrackInSplit && trk->endCnt > 2 ) {
- if (GetTrkType(trk) == T_TURNOUT)
+ if (GetTrkType(trk) == T_TURNOUT) {
return TurnoutPickEndPt( p, trk );
+ }
}
- d = FindDistance( p, trk->endPt[0].pos );
+ d = FindDistance( p, GetEndPtPos( trk->endPt ) );
inx = 0;
for ( i=1; i<trk->endCnt; i++ ) {
- pos = trk->endPt[i].pos;
+ pos = GetEndPtPos( EndPtIndex( trk->endPt, i ) );
dd=FindDistance(p, pos);
if (dd < d) {
d = dd;
@@ -741,39 +657,38 @@ EXPORT EPINX_T PickEndPoint( coOrd p, track_cp trk )
}
+/**
+ * Find an endpoint of trk that is close to coOrd p.
+ * Returns index of endpoint or displays a message
+ * and returns -1 if none found.
+ */
EXPORT EPINX_T PickUnconnectedEndPoint( coOrd p, track_cp trk )
{
- EPINX_T inx, i;
- DIST_T d=0, dd;
- coOrd pos;
- inx = -1;
+ EPINX_T inx;
- for ( i=0; i<trk->endCnt; i++ ) {
- if (trk->endPt[i].track == NULL) {
- pos = trk->endPt[i].pos;
- dd=FindDistance(p, pos);
- if (inx == -1 || dd <= d) {
- d = dd;
- inx = i;
- }
- }
- }
+ inx = PickUnconnectedEndPointSilent( p, trk );
- if (inx == -1)
+ if (inx == -1) {
ErrorMessage( MSG_NO_UNCONN_EP );
+ }
return inx;
}
+/**
+ * Find an endpoint of trk that is close to coOrd p.
+ * Returns index of endpoint or -1 if none found.
+ */
EXPORT EPINX_T PickUnconnectedEndPointSilent( coOrd p, track_cp trk )
{
EPINX_T inx, i;
- DIST_T d=10000.0, dd;
+ DIST_T d=DIST_INF, dd;
coOrd pos;
inx = -1;
for ( i=0; i<trk->endCnt; i++ ) {
- if (trk->endPt[i].track == NULL) {
- pos = trk->endPt[i].pos;
+ trkEndPt_p epp = EndPtIndex( trk->endPt, i );
+ if (GetEndPtTrack( epp ) == NULL) {
+ pos = GetEndPtPos( epp );
dd=FindDistance(p, pos);
if (inx == -1 || dd <= d) {
d = dd;
@@ -786,55 +701,85 @@ EXPORT EPINX_T PickUnconnectedEndPointSilent( coOrd p, track_cp trk )
}
+/**
+ * Connect all the end points to this track (trk0) that are close enough
+ * (distance and angle) to another track's unconnected endpoint.
+ */
+EXPORT void ConnectAllEndPts(track_p trk0)
+{
+ for (EPINX_T ep0 = 0; ep0 < GetTrkEndPtCnt(trk0); ep0++) {
+ // Skip if already connected
+ if (GetTrkEndTrk(trk0, ep0) != NULL) { continue; }
+
+ coOrd pos0 = GetTrkEndPos(trk0, ep0);
+ track_p trk2 = OnTrack2(&pos0, FALSE, TRUE, TRUE, trk0);
+
+ // Not near another track?
+ if (trk2 == NULL) { continue; }
+ EPINX_T ep2 = PickUnconnectedEndPointSilent(pos0, trk2);
+
+ // Close enough?
+ coOrd pos2 = GetTrkEndPos(trk2, ep2);
+ DIST_T distance = FindDistance(pos0, pos2);
+ if (distance > connectDistance) { continue; }
+
+ // Aligned?
+ ANGLE_T a = fabs(DifferenceBetweenAngles(
+ GetTrkEndAngle(trk0, ep0),
+ GetTrkEndAngle(trk2, ep2) + 180.0));
+ if (a > connectAngle) { continue; }
+
+ // Make the connection
+ ConnectTracks(trk0, ep0, trk2, ep2);
+ DrawNewTrack(trk2);
+ }
+}
EXPORT EPINX_T GetEndPtConnectedToMe( track_p trk, track_p me )
{
EPINX_T ep;
for (ep=0; ep<trk->endCnt; ep++)
- if (trk->endPt[ep].track == me)
+ if (GetEndPtTrack( EndPtIndex( trk->endPt, ep ) ) == me) {
return ep;
+ }
return -1;
}
-EXPORT EPINX_T GetNearestEndPtConnectedToMe( track_p trk, track_p me, coOrd pos) {
+EXPORT EPINX_T GetNearestEndPtConnectedToMe( track_p trk, track_p me,
+ coOrd pos)
+{
EPINX_T ep, found = -1;
- DIST_T d = 10000;
+ DIST_T d = DIST_INF;
DIST_T dd;
- for (ep=0; ep<trk->endCnt; ep++) {
- if (trk->endPt[ep].track == me) {
- dd = FindDistance(pos,trk->endPt[ep].pos);
- if (dd<d) {
- found = ep;
- d = dd;
- }
+ for (ep=0; ep<trk->endCnt; ep++) {
+ trkEndPt_p epp = EndPtIndex( trk->endPt, ep );
+ if (GetEndPtTrack( epp ) == me) {
+ coOrd pos1 = GetEndPtPos( epp );
+ dd = FindDistance(pos, pos1 );
+ if (dd<d) {
+ found = ep;
+ d = dd;
}
}
- return found;
+ }
+ return found;
}
EXPORT void SetEndPts( track_p trk, EPINX_T cnt )
{
- EPINX_T inx;
-
-LOG1( log_readTracks, ( "SetEndPts( T%d, %d )\n", trk->index, cnt ) )
- if (cnt > 0 && tempEndPts_da.cnt != cnt) {
- InputError( "Incorrect number of End Points for track, read %d, expected %d.\n", FALSE, tempEndPts_da.cnt, cnt );
+ LOG1( log_readTracks, ( "SetEndPts( T%d, %d )\n", trk->index, cnt ) )
+ if (cnt > 0 && TempEndPtsCount() != cnt) {
+ InputError( "Incorrect number of End Points for track, read %d, expected %d.\n",
+ FALSE, TempEndPtsCount(), cnt );
return;
}
- if (tempEndPts_da.cnt) {
- trk->endPt = (trkEndPt_p)MyMalloc( tempEndPts_da.cnt * sizeof *trk->endPt );
- } else {
+ trk->endCnt = TempEndPtsCount();
+ if ( trk->endCnt <= 0 ) {
trk->endPt = NULL;
+ } else {
+ trk->endPt = (trkEndPt_p)memdup( TempEndPt(0), EndPtSize( trk->endCnt ) );
}
- for ( inx=0; inx<tempEndPts_da.cnt; inx++ ) {
- trk->endPt[inx].index = tempEndPts(inx).index;
- trk->endPt[inx].pos = tempEndPts(inx).pos;
- trk->endPt[inx].angle = tempEndPts(inx).angle;
- trk->endPt[inx].elev = tempEndPts(inx).elev;
- trk->endPt[inx].option = tempEndPts(inx).option;
- }
- trk->endCnt = tempEndPts_da.cnt;
}
@@ -842,8 +787,11 @@ EXPORT void MoveTrack( track_p trk, coOrd orig )
{
EPINX_T ep;
for (ep=0; ep<trk->endCnt; ep++) {
- trk->endPt[ep].pos.x += orig.x;
- trk->endPt[ep].pos.y += orig.y;
+ trkEndPt_p epp = EndPtIndex( trk->endPt, ep );
+ coOrd pos = GetEndPtPos( epp );
+ pos.x += orig.x;
+ pos.y += orig.y;
+ SetEndPt( epp, pos, GetEndPtAngle( epp ) );
}
trackCmds( trk->type )->move( trk, orig );
}
@@ -852,11 +800,14 @@ EXPORT void MoveTrack( track_p trk, coOrd orig )
EXPORT void RotateTrack( track_p trk, coOrd orig, ANGLE_T angle )
{
EPINX_T ep;
- if ( trackCmds( trk->type )->rotate == NULL )
- return;
+ if ( trackCmds( trk->type )->rotate == NULL ) {
+ return;
+ }
for (ep=0; ep<trk->endCnt; ep++) {
- Rotate( &trk->endPt[ep].pos, orig, angle );
- trk->endPt[ep].angle = NormalizeAngle( trk->endPt[ep].angle + angle );
+ trkEndPt_p epp = EndPtIndex( trk->endPt, ep );
+ coOrd pos = GetEndPtPos( epp );
+ Rotate( &pos, orig, angle );
+ SetEndPt( epp, pos, NormalizeAngle( GetEndPtAngle(epp) + angle ) );
}
trackCmds( trk->type )->rotate( trk, orig, angle );
}
@@ -865,11 +816,15 @@ EXPORT void RotateTrack( track_p trk, coOrd orig, ANGLE_T angle )
EXPORT void RescaleTrack( track_p trk, FLOAT_T ratio, coOrd shift )
{
EPINX_T ep;
- if ( trackCmds( trk->type )->rescale == NULL )
+ if ( trackCmds( trk->type )->rescale == NULL ) {
return;
+ }
for (ep=0; ep<trk->endCnt; ep++) {
- trk->endPt[ep].pos.x *= ratio;
- trk->endPt[ep].pos.y *= ratio;
+ trkEndPt_p epp = EndPtIndex( trk->endPt, ep );
+ coOrd pos = GetEndPtPos( epp );
+ pos.x *= ratio;
+ pos.y *= ratio;
+ SetEndPt( epp, pos, GetEndPtAngle(epp) );
}
trackCmds( trk->type )->rescale( trk, ratio );
MoveTrack( trk, shift );
@@ -877,9 +832,9 @@ EXPORT void RescaleTrack( track_p trk, FLOAT_T ratio, coOrd shift )
EXPORT void FlipPoint(
- coOrd * pos,
- coOrd orig,
- ANGLE_T angle )
+ coOrd * pos,
+ coOrd orig,
+ ANGLE_T angle )
{
Rotate( pos, orig, -angle );
pos->x = 2*orig.x - pos->x;
@@ -888,33 +843,35 @@ EXPORT void FlipPoint(
EXPORT void FlipTrack(
- track_p trk,
- coOrd orig,
- ANGLE_T angle )
+ track_p trk,
+ coOrd orig,
+ ANGLE_T angle )
{
EPINX_T ep;
- trkEndPt_t endPt;
for ( ep=0; ep<trk->endCnt; ep++ ) {
- FlipPoint( &trk->endPt[ep].pos, orig, angle );
- trk->endPt[ep].angle = NormalizeAngle( 2*angle - trk->endPt[ep].angle );
- }
- if ( trackCmds(trk->type)->flip )
+ trkEndPt_p epp = EndPtIndex( trk->endPt, ep );
+ coOrd pos1 = GetEndPtPos( epp );
+ FlipPoint( &pos1, orig, angle );
+ ANGLE_T angle1 = GetEndPtAngle( epp );
+ angle1 = NormalizeAngle( 2*angle - angle1 );
+ SetEndPt( epp, pos1, angle1 );
+ }
+ if ( trackCmds(trk->type)->flip ) {
trackCmds(trk->type)->flip( trk, orig, angle );
+ }
if ( QueryTrack( trk, Q_FLIP_ENDPTS ) ) {
- endPt = trk->endPt[0];
- trk->endPt[0] = trk->endPt[1];
- trk->endPt[1] = endPt;
+ SwapEndPts( trk->endPt, 0, 1 );
}
}
-EXPORT EPINX_T GetNextTrk(
- track_p trk1,
- EPINX_T ep1,
- track_p *Rtrk,
- EPINX_T *Rep,
- int mode )
+EXPORT EPINX_T GetNextTrk(
+ track_p trk1,
+ EPINX_T ep1,
+ track_p *Rtrk,
+ EPINX_T *Rep,
+ int mode )
{
EPINX_T ep, epCnt = GetTrkEndPtCnt(trk1), epRet=-1;
track_p trk;
@@ -922,21 +879,25 @@ EXPORT EPINX_T GetNextTrk(
*Rtrk = NULL;
*Rep = 0;
for (ep=0; ep<epCnt; ep++) {
- if (ep==ep1)
+ if (ep==ep1) {
continue;
+ }
trk = GetTrkEndTrk( trk1, ep );
if (trk==NULL) {
#ifdef LATER
- if (isElev)
+ if (isElev) {
epRet = ep;
+ }
#endif
continue;
}
if ( (mode&GNTignoreIgnore) &&
- ((trk1->endPt[ep].elev.option&ELEV_MASK)==ELEV_IGNORE))
+ ((GetTrkEndElevMode(trk1,ep) == ELEV_IGNORE)) ) {
continue;
- if (*Rtrk != NULL)
+ }
+ if (*Rtrk != NULL) {
return -1;
+ }
*Rtrk = trk;
*Rep = GetEndPtConnectedToMe( trk, trk1 );
epRet = ep;
@@ -945,46 +906,51 @@ EXPORT EPINX_T GetNextTrk(
}
EXPORT BOOL_T MakeParallelTrack(
- track_p trk,
- coOrd pos,
- DIST_T dist,
- DIST_T factor,
- track_p * newTrkR,
- coOrd * p0R,
- coOrd * p1R,
- BOOL_T track)
-{
- if ( trackCmds(trk->type)->makeParallel )
- return trackCmds(trk->type)->makeParallel( trk, pos, dist, factor, newTrkR, p0R, p1R, track);
+ track_p trk,
+ coOrd pos,
+ DIST_T dist,
+ DIST_T factor,
+ track_p * newTrkR,
+ coOrd * p0R,
+ coOrd * p1R,
+ BOOL_T track)
+{
+ if ( trackCmds(trk->type)->makeParallel ) {
+ return trackCmds(trk->type)->makeParallel( trk, pos, dist, factor, newTrkR, p0R,
+ p1R, track);
+ }
return FALSE;
}
EXPORT BOOL_T RebuildTrackSegs(
- track_p trk)
+ track_p trk)
{
- if (trackCmds(trk->type)->rebuildSegs)
+ if (trackCmds(trk->type)->rebuildSegs) {
return trackCmds(trk->type)->rebuildSegs(trk);
+ }
return FALSE;
}
EXPORT BOOL_T ReplayTrackData(
- track_p trk,
- void * data,
- long length)
+ track_p trk,
+ void * data,
+ long length)
{
- if (trackCmds(trk->type)->replayData)
- return trackCmds(trk->type)->replayData(trk,data,length);
- return FALSE;
+ if (trackCmds(trk->type)->replayData) {
+ return trackCmds(trk->type)->replayData(trk,data,length);
+ }
+ return FALSE;
}
EXPORT BOOL_T StoreTrackData(
- track_p trk,
- void ** data,
- long * length)
+ track_p trk,
+ void ** data,
+ long * length)
{
- if (trackCmds(trk->type)->storeData)
+ if (trackCmds(trk->type)->storeData) {
return trackCmds(trk->type)->storeData(trk,data,length);
- return FALSE;
+ }
+ return FALSE;
}
@@ -996,19 +962,29 @@ EXPORT BOOL_T StoreTrackData(
*/
-
EXPORT track_p to_first = NULL;
-
EXPORT TRKINX_T max_index = 0;
EXPORT track_p * to_last = &to_first;
+EXPORT track_p GetFirstTrack()
+{
+ return to_first;
+}
+
+EXPORT track_p GetNextTrack( track_p trk )
+{
+ return trk->next;
+}
+
+
+
static struct {
- track_p first;
- track_p *last;
- wIndex_t count;
- wIndex_t changed;
- TRKINX_T max_index;
- } savedTrackState;
+ track_p first;
+ track_p *last;
+ wIndex_t count;
+ wIndex_t changed;
+ TRKINX_T max_index;
+} savedTrackState;
EXPORT void RenumberTracks( void )
@@ -1021,10 +997,10 @@ EXPORT void RenumberTracks( void )
}
-EXPORT track_p NewTrack( TRKINX_T index, TRKTYP_T type, EPINX_T endCnt, CSIZE_T extraSize )
+EXPORT track_p NewTrack( TRKINX_T index, TRKTYP_T type, EPINX_T endCnt,
+ CSIZE_T extraSize )
{
track_p trk;
- EPINX_T ep;
trk = (track_p ) MyMalloc( sizeof *trk );
*to_last = trk;
to_last = &trk->next;
@@ -1034,26 +1010,31 @@ EXPORT track_p NewTrack( TRKINX_T index, TRKTYP_T type, EPINX_T endCnt, CSIZE_T
} else if (max_index < index) {
max_index = index;
}
-LOG( log_track, 1, ( "NewTrack( T%d, t%d, E%d, X%ld)\n", index, type, endCnt, extraSize ) )
+ LOG( log_track, 1, ( "NewTrack( T%d, t%d, E%d, X%ld)\n", index, type, endCnt,
+ extraSize ) )
trk->index = index;
trk->type = type;
trk->layer = curLayer;
- trk->scale = (char)GetLayoutCurScale();
+ trk->scale = (char)GetLayerScale(curLayer); // (char)GetLayoutCurScale();
trk->bits = TB_VISIBLE;
trk->elevMode = ELEV_ALONE;
trk->elev = 0;
- trk->endCnt = endCnt;
trk->hi.x = trk->hi.y = trk->lo.x = trk->lo.y = (float)0.0;
+ trk->endCnt = endCnt;
if (endCnt) {
- trk->endPt = (trkEndPt_p)MyMalloc( endCnt * sizeof *trk->endPt );
- for ( ep = 0; ep < endCnt; ep++ )
- trk->endPt[ep].index = -1;
- } else
+ trk->endPt = (trkEndPt_p)MyMalloc( EndPtSize(endCnt) );
+ for ( EPINX_T ep = 0; ep<endCnt; ep++ ) {
+ SetEndPtTrack( GetTrkEndPt( trk, ep ), NULL );
+ }
+ } else {
trk->endPt = NULL;
+ }
if (extraSize) {
- trk->extraData = MyMalloc( extraSize );
- } else
+ trk->extraData = (struct extraDataBase_t*)MyMalloc( extraSize );
+ trk->extraData->trkType = type;
+ } else {
trk->extraData = NULL;
+ }
trk->extraSize = extraSize;
UndoNew( trk );
trackCount++;
@@ -1065,12 +1046,16 @@ LOG( log_track, 1, ( "NewTrack( T%d, t%d, E%d, X%ld)\n", index, type, endCnt, ex
EXPORT void FreeTrack( track_p trk )
{
- trackCmds(trk->type)->delete( trk );
- if (trk->endPt)
+ bFreeTrack = TRUE;
+ trackCmds(trk->type)->deleteTrk( trk );
+ if (trk->endPt) {
MyFree(trk->endPt);
- if (trk->extraData)
+ }
+ if (trk->extraData) {
MyFree(trk->extraData);
+ }
MyFree(trk);
+ bFreeTrack = FALSE;
}
@@ -1097,7 +1082,7 @@ EXPORT track_p FindTrack( TRKINX_T index )
{
track_p trk;
TRK_ITERATE(trk) {
- if (trk->index == index) return trk;
+ if (trk->index == index) { return trk; }
}
return NULL;
}
@@ -1108,19 +1093,26 @@ EXPORT void ResolveIndex( void )
track_p trk;
EPINX_T ep;
TRK_ITERATE(trk) {
- LOG (log_track, 1, ( "ResNextTrack( T%d, t%d, E%d, X%ld)\n", trk->index, trk->type, trk->endCnt, trk->extraSize ));
- for (ep=0; ep<trk->endCnt; ep++)
- if (trk->endPt[ep].index >= 0) {
- trk->endPt[ep].track = FindTrack( trk->endPt[ep].index );
- if (trk->endPt[ep].track == NULL) {
- int rc = NoticeMessage( MSG_RESOLV_INDEX_BAD_TRK, _("Continue"), _("Quit"), trk->index, ep, trk->endPt[ep].index );
- if ( rc != 1 )
+ LOG (log_track, 1, ( "ResNextTrack( T%d, t%d, E%d, X%ld)\n", trk->index,
+ trk->type, trk->endCnt, trk->extraSize ));
+ for (ep=0; ep<trk->endCnt; ep++) {
+ trkEndPt_p epp = GetTrkEndPt( trk, ep );
+ TRKINX_T index = GetEndPtIndex( epp );
+ if (index >= 0) {
+ track_p track = FindTrack( index );
+ if (track == NULL) {
+ int rc = NoticeMessage( MSG_RESOLV_INDEX_BAD_TRK, _("Continue"), _("Quit"),
+ trk->index, ep, index );
+ if ( rc != 1 ) {
return;
+ }
}
+ SetEndPtTrack( epp, track );
}
- ResolveBlockTrack (trk);
- ResolveSwitchmotorTurnout (trk);
- }
+ }
+ ResolveBlockTrack (trk);
+ ResolveSwitchmotorTurnout (trk);
+ }
AuditTracks( "readTracks" );
}
@@ -1129,11 +1121,13 @@ EXPORT BOOL_T DeleteTrack( track_p trk, BOOL_T all )
{
EPINX_T i, ep2;
track_p trk2;
-LOG( log_track, 4, ( "DeleteTrack(T%d)\n", GetTrkIndex(trk) ) )
+ LOG( log_track, 4, ( "DeleteTrack(T%d)\n", GetTrkIndex(trk) ) )
if (all) {
if (!QueryTrack(trk,Q_CANNOT_BE_ON_END)) {
- for (i=0;i<trk->endCnt;i++) {
- if ((trk2=trk->endPt[i].track) != NULL) {
+ for (i=0; i<trk->endCnt; i++) {
+ trkEndPt_p epp = EndPtIndex( trk->endPt, i );
+ trk2 = GetEndPtTrack(epp);
+ if (trk2 != NULL) {
if (QueryTrack(trk2,Q_CANNOT_BE_ON_END)) {
DeleteTrack( trk2, FALSE );
}
@@ -1141,17 +1135,27 @@ LOG( log_track, 4, ( "DeleteTrack(T%d)\n", GetTrkIndex(trk) ) )
}
}
}
- for (i=0;i<trk->endCnt;i++) {
- if ((trk2=trk->endPt[i].track) != NULL) {
+ /* If Car, simulate Remove Car -> uncouple and mark deleted (no Undo) */
+ if (QueryTrack(trk,Q_ISTRAIN)) {
+ UncoupleCars( trk, 0 );
+ UncoupleCars( trk, 1 );
+ trk->deleted = TRUE;
+ ClrTrkBits( trk, TB_SELECTED ); // Make sure we don't select a deleted car
+ return TRUE;
+ }
+ for (i=0; i<trk->endCnt; i++) {
+ trkEndPt_p epp = EndPtIndex( trk->endPt, i );
+ if ((trk2=GetEndPtTrack(epp)) != NULL) {
ep2 = GetEndPtConnectedToMe( trk2, trk );
DisconnectTracks( trk2, ep2, trk, i );
- if ( QueryTrack(trk,Q_CANNOT_BE_ON_END) )
+ if ( QueryTrack(trk,Q_CANNOT_BE_ON_END) ) {
UndoJoint( trk2, ep2, trk, i );
+ }
}
}
- CheckDeleteSwitchmotor( trk );
- CheckDeleteBlock( trk );
- CheckCarTraverse( trk );
+ CheckDeleteSwitchmotor( trk );
+ CheckDeleteBlock( trk );
+ CheckCarTraverse( trk );
DecrementLayerObjects(trk->layer);
trackCount--;
AuditTracks( "deleteTrack T%d", trk->index);
@@ -1191,18 +1195,27 @@ EXPORT void RestoreTrackState( void )
BOOL_T TrackIterate( track_p * trk )
{
track_p trk1;
- if (!*trk)
+ if (!*trk) {
trk1 = to_first;
- else
+ } else {
trk1 = (*trk)->next;
- while (trk1 && IsTrackDeleted(trk1))
+ }
+ while (trk1 && IsTrackDeleted(trk1)) {
trk1 = trk1->next;
+ }
*trk = trk1;
return trk1 != NULL;
}
-wBool_t IsPosClose( coOrd pos1, coOrd pos2 ) {
+/*****************************************************************************
+*
+* REGRESSION
+*
+*/
+
+wBool_t IsPosClose( coOrd pos1, coOrd pos2 )
+{
DIST_T d = FindDistance( pos1, pos2 );
return d < 0.1;
}
@@ -1211,8 +1224,9 @@ wBool_t IsPosClose( coOrd pos1, coOrd pos2 ) {
wBool_t IsAngleClose( ANGLE_T angle1, ANGLE_T angle2 )
{
ANGLE_T angle = NormalizeAngle( angle1 - angle2 );
- if (angle > 180)
+ if (angle > 180) {
angle = 360-angle;
+ }
return angle < 0.01;
}
@@ -1228,16 +1242,19 @@ wBool_t IsWidthClose( DIST_T dist1, DIST_T dist2 )
// width is computed by pixels/dpi
// problem is when widths are computed on platforms with differing dpi
DIST_T dist = fabs( dist1 - dist2 );
- if ( dist < 0.01 )
+ if ( dist < 0.05 ) {
return TRUE;
-#ifdef WINDOWS
- dist1 *= 96.0/72.0;
-#else
- dist1 *= 72.0/96.0;
-#endif
+ }
+// This was using BASE_DPI(=75.0) based on ancient monitors.
+// 96 DPI is more reasonable today
+// TODO: review BASE_DPI with a plan to change it to 96.0
+// printf( "WidthClose %s:%d D2:%0.3f D1:%0.3f", paramFileName, paramLineNum, dist2, dist1 );
+ dist1 *= mainD.dpi/96.0;
dist = fabs( dist1 - dist2 );
- if ( dist < 0.01 )
+// printf( " -> %0.3f D:%0.3f\n", dist1, dist );
+ if ( dist < 0.05 ) {
return TRUE;
+ }
return FALSE;
}
@@ -1255,17 +1272,17 @@ wBool_t IsColorClose( wDrawColor color1, wDrawColor color2 )
return (diff < 7);
}
-wBool_t CompareTrack( track_cp trk1, track_cp trk2 )
+static wBool_t CompareTrack( track_cp trk1, track_cp trk2 )
{
- wBool_t rc = FALSE;
+// wBool_t rc = FALSE;
if ( trk1 == NULL ) {
sprintf( message, "Compare: T%d not found\n", trk2->index );
return FALSE;
}
sprintf( message, "Compare T:%d - ", GetTrkIndex(trk1) );
char * cp = message+strlen(message);
- REGRESS_CHECK_INT( "Type", trk1, trk2, type )
- REGRESS_CHECK_INT( "Index", trk1, trk2, index )
+ REGRESS_CHECK_INT( "Type", trk1, trk2, type )
+ REGRESS_CHECK_INT( "Index", trk1, trk2, index )
REGRESS_CHECK_INT( "Layer", trk1, trk2, layer )
REGRESS_CHECK_INT( "Scale", trk1, trk2, scale )
REGRESS_CHECK_INT( "EndPtCnt", trk1, trk2, endCnt )
@@ -1274,25 +1291,139 @@ wBool_t CompareTrack( track_cp trk1, track_cp trk2 )
cp = cq;
sprintf( cp, "EP:%d - ", inx );
cp += strlen(cp);
- REGRESS_CHECK_POS( "Pos", trk1, trk2, endPt[inx].pos )
- REGRESS_CHECK_ANGLE( "Angle", trk1, trk2, endPt[inx].angle )
- int inx1 = trk1->endPt[inx].index;
- track_cp trk1x = GetTrkEndTrk( trk1, inx );
- if ( trk1x )
- inx1 = GetTrkIndex( trk1x );
- int inx2 = trk2->endPt[inx].index;
- if ( inx1 != inx2 ) {
- sprintf( cp, "Index: Actual` %d, Expected %d\n", inx1, inx2 );
+ if ( ! CompareEndPt( cp, trk1, trk2, inx ) ) {
return FALSE;
}
- REGRESS_CHECK_INT( "Option", trk1, trk2, endPt[inx].option )
}
- if ( trackCmds( GetTrkType( trk1 ) )->compare == NULL )
+ if ( trackCmds( GetTrkType( trk1 ) )->compare == NULL ) {
return TRUE;
+ }
return trackCmds( GetTrkType( trk1 ) )->compare( trk1, trk2 );
}
-
+EXPORT int CheckRegressionResult( long regressVersion,char * sFileName,
+ wBool_t bQuiet )
+{
+ wBool_t bWroteActualTracks = FALSE;
+ int nFail = 0;
+ FILE * fRegression = NULL;
+ char * sRegressionFile = NULL;
+ track_p to_first_save = to_first;
+ track_p* to_last_save = to_last;
+ MakeFullpath( &sRegressionFile, workingDir, "xtrkcad.regress", NULL );
+
+ while ( GetNextLine() ) {
+ if ( paramLine[0] == '#' ) {
+ continue;
+ }
+ // Read Expected track
+ to_first = NULL;
+ to_last = &to_first;
+ paramVersion = regressVersion;
+ if ( !ReadTrack( paramLine ) ) {
+ if ( paramFile == NULL ) {
+ return -1;
+ }
+ break;
+ }
+ if ( to_first == NULL ) {
+ // Something bad happened
+ break;
+ }
+ track_cp tExpected = to_first;
+ to_first = to_first_save;
+ // Find corresponding Actual track
+ track_cp tActual = FindTrack( GetTrkIndex( tExpected ) );
+ strcat( message, "Regression " );
+ if ( ! CompareTrack( tActual, tExpected ) ) {
+ nFail++;
+ // Actual doesn't match Expected
+ lprintf( " FAIL: %s\n", message);
+ fRegression = fopen( sRegressionFile, "a" );
+ if ( fRegression == NULL ) {
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Regression"),
+ sRegressionFile, strerror(errno) );
+ break;
+ }
+ fprintf( fRegression, "REGRESSION FAIL %d\n",
+ PARAMVERSION );
+ fprintf( fRegression, "# %s - %d\n", sFileName, paramLineNum );
+ fprintf( fRegression, "# %s", message );
+ if ( !bWroteActualTracks ) {
+ // Print Actual tracks
+ fprintf( fRegression, "Actual Tracks\n" );
+ paramVersion = PARAMVERSION;
+ WriteTracks( fRegression, FALSE );
+ bWroteActualTracks = TRUE;
+ }
+ // Print Expected track
+ to_first = tExpected;
+ fprintf( fRegression, "Expected Track\n" );
+ WriteTracks( fRegression, FALSE );
+ fclose( fRegression );
+ strcat( message, "Continue test?" );
+ if ( ! bQuiet ) {
+ int rc = wNoticeEx( NT_ERROR, message, _("Stop"), _("Continue") );
+ if ( !rc ) {
+ while ( GetNextLine() &&
+ strncmp( paramLine, "REGRESSION END", 14 ) != 0 )
+ ;
+ break;
+ }
+ }
+ }
+ // Delete Expected track
+ to_first = tExpected;
+ to_last = &to_first;
+ FreeTrack( tExpected );
+ }
+ to_first = to_first_save;
+ to_last = to_last_save;
+ if ( strncmp( paramLine, "REGRESSION END", 14 ) != 0 ) {
+ InputError( "Expected REGRESSION END", TRUE );
+ }
+ return nFail;
+}
+
+
+/*****************************************************************************
+*
+* LAYER
+*
+*/
+
+/**
+ * @brief Add 1 to track layer numbers that are greater than or equal to New Layer
+ * @param newLayer
+*/
+EXPORT void TrackInsertLayer( int newLayer )
+{
+ track_p trk;
+
+ TRK_ITERATE( trk ) {
+ int layer = GetTrkLayer(trk);
+ if (layer >= newLayer) {
+ SetTrkLayer(trk, layer + 1);
+ }
+ }
+}
+
+/**
+* @brief Subtract 1 from track layer numbers that are greater than Removed Layer
+* @param removeLayer
+*/
+EXPORT void TrackDeleteLayer( int removeLayer )
+{
+ track_p trk;
+
+ TRK_ITERATE( trk ) {
+ int layer = GetTrkLayer(trk);
+ if (layer > removeLayer) {
+ SetTrkLayer(trk, layer - 1);
+ }
+ }
+}
+
/*****************************************************************************
*
* ABOVE / BELOW
@@ -1304,10 +1435,11 @@ static void ExciseSelectedTracks( track_p * pxtrk, track_p * pltrk )
track_p trk, *ptrk;
for (ptrk=&to_first; *ptrk!=NULL; ) {
trk = *ptrk;
- if (IsTrackDeleted(trk) || !GetTrkSelected(trk)) {
+ if (!GetTrkSelected(trk)) {
ptrk = &(*ptrk)->next;
continue;
}
+ CHECK( !IsTrackDeleted(trk) );
UndoModify( *ptrk );
UndoModify( trk );
*ptrk = trk->next;
@@ -1319,7 +1451,7 @@ static void ExciseSelectedTracks( track_p * pxtrk, track_p * pltrk )
}
-EXPORT void SelectAbove( void )
+EXPORT void SelectAbove( void * unused )
{
track_p xtrk, ltrk;
if (selectedTrackCount<=0) {
@@ -1334,11 +1466,11 @@ EXPORT void SelectAbove( void )
to_last = &ltrk->next;
}
UndoEnd();
- DrawSelectedTracks( &mainD );
+ DrawSelectedTracks( &mainD, false );
}
-EXPORT void SelectBelow( void )
+EXPORT void SelectBelow( void * unused )
{
track_p xtrk, ltrk, trk;
coOrd lo, hi, lowest, highest;
@@ -1355,14 +1487,18 @@ EXPORT void SelectBelow( void )
GetBoundingBox( trk, &highest, &lowest );
} else {
GetBoundingBox( trk, &hi, &lo );
- if (highest.x < hi.x)
+ if (highest.x < hi.x) {
highest.x = hi.x;
- if (highest.y < hi.y)
+ }
+ if (highest.y < hi.y) {
highest.y = hi.y;
- if (lowest.x > lo.x)
+ }
+ if (lowest.x > lo.x) {
lowest.x = lo.x;
- if (lowest.y > lo.y)
+ }
+ if (lowest.y > lo.y) {
lowest.y = lo.y;
+ }
}
ClrTrkBits( trk, TB_SELECTED );
}
@@ -1376,16 +1512,16 @@ EXPORT void SelectBelow( void )
}
-#include "bitmaps/above.xpm"
-#include "bitmaps/below.xpm"
+#include "bitmaps/top.xpm3"
+#include "bitmaps/bottom.xpm3"
EXPORT void InitCmdAboveBelow( void )
{
wIcon_p bm_p;
- bm_p = wIconCreatePixMap( above_xpm );
- AddToolbarButton( "cmdAbove", bm_p, IC_SELECTED|IC_POPUP, (addButtonCallBack_t)SelectAbove, NULL );
- bm_p = wIconCreatePixMap( below_xpm );
- AddToolbarButton( "cmdBelow", bm_p, IC_SELECTED|IC_POPUP, (addButtonCallBack_t)SelectBelow, NULL );
+ bm_p = wIconCreatePixMap( top_xpm3[iconSize] );
+ AddToolbarButton( "cmdAbove", bm_p, IC_SELECTED|IC_POPUP, SelectAbove, NULL );
+ bm_p = wIconCreatePixMap( bottom_xpm3[iconSize] );
+ AddToolbarButton( "cmdBelow", bm_p, IC_SELECTED|IC_POPUP, SelectBelow, NULL );
}
/*****************************************************************************
@@ -1415,38 +1551,40 @@ EXPORT BOOL_T ReadTrack( char * line )
return TRUE;
}
-if (bsearchRead) {
- if (sortedCmds == NULL) {
- sortedCmds = (trackCmd_t**)MyMalloc( (trackCmds_da.cnt-1) * sizeof *(trackCmd_t*)0 );
- for (inx=1; inx<trackCmds_da.cnt; inx++)
- sortedCmds[inx-1] = trackCmds(inx);
- qsort( sortedCmds, trackCmds_da.cnt-1, sizeof *(trackCmd_t**)0, CompareCmds );
- }
-
- lo = 0;
- hi = trackCmds_da.cnt-2;
- do {
- inx = (lo+hi)/2;
- cmp = strncmp( line, sortedCmds[inx]->name, strlen(sortedCmds[inx]->name) );
- if (cmp == 0) {
- return sortedCmds[inx]->read(line);
- } else if (cmp < 0) {
- hi = inx-1;
- } else {
- lo = inx+1;
- }
- } while ( lo <= hi );
-} else {
- for (inx=1; inx<trackCmds_da.cnt; inx++) {
- if (strncmp( line, trackCmds(inx)->name, strlen(trackCmds(inx)->name) ) == 0 ) {
- trackCmds(inx)->read( line );
- // Return TRUE means we found the object type and processed it
- // Any errors will be handled by the callee's:
- // Either skip the definition (ReadSegs) or skip the remainder of the file (InputError)
- return TRUE;
- }
+ if (bsearchRead) {
+ if (sortedCmds == NULL) {
+ sortedCmds = (trackCmd_t**)MyMalloc( (trackCmds_da.cnt-1) * sizeof *
+ (trackCmd_t*)0 );
+ for (inx=1; inx<trackCmds_da.cnt; inx++) {
+ sortedCmds[inx-1] = trackCmds(inx);
+ }
+ qsort( sortedCmds, trackCmds_da.cnt-1, sizeof *(trackCmd_t**)0, CompareCmds );
+ }
+
+ lo = 0;
+ hi = trackCmds_da.cnt-2;
+ do {
+ inx = (lo+hi)/2;
+ cmp = strncmp( line, sortedCmds[inx]->name, strlen(sortedCmds[inx]->name) );
+ if (cmp == 0) {
+ return sortedCmds[inx]->read(line);
+ } else if (cmp < 0) {
+ hi = inx-1;
+ } else {
+ lo = inx+1;
+ }
+ } while ( lo <= hi );
+ } else {
+ for (inx=1; inx<trackCmds_da.cnt; inx++) {
+ if (strncmp( line, trackCmds(inx)->name, strlen(trackCmds(inx)->name) ) == 0 ) {
+ trackCmds(inx)->read( line );
+ // Return TRUE means we found the object type and processed it
+ // Any errors will be handled by the callee's:
+ // Either skip the definition (ReadSegs) or skip the remainder of the file (InputError)
+ return TRUE;
+ }
+ }
}
-}
// Object type not found
return FALSE;
}
@@ -1456,16 +1594,19 @@ EXPORT BOOL_T WriteTracks( FILE * f, wBool_t bFull )
{
track_p trk;
BOOL_T rc = TRUE;
- if ( bFull )
+ if ( bFull ) {
RenumberTracks();
- if ( !bFull )
+ }
+ if ( !bFull ) {
bWriteEndPtDirectIndex = TRUE;
+ }
TRK_ITERATE( trk ) {
rc &= trackCmds(GetTrkType(trk))->write( trk, f );
}
bWriteEndPtDirectIndex = FALSE;
- if ( bFull )
+ if ( bFull ) {
rc &= WriteCars( f );
+ }
return rc;
}
@@ -1485,8 +1626,8 @@ EXPORT void ImportEnd( coOrd offset, wBool_t import, wBool_t inPlace )
wIndex_t trackCountOld;
track_p trk;
coOrd pos;
- wPos_t x, y;
- wPos_t ww, hh;
+ wDrawPix_t x, y;
+ wWinPix_t ww, hh;
wBool_t offscreen = FALSE;
double xmin = 0.0;
@@ -1497,27 +1638,26 @@ EXPORT void ImportEnd( coOrd offset, wBool_t import, wBool_t inPlace )
// get the current mouse position
GetMousePosition( &x, &y );
mainD.Pix2CoOrd( &mainD, x, y, &pos );
-
+
// get the size of the drawing area
wDrawGetSize( mainD.d, &ww, &hh );
coOrd middle_screen;
- wPos_t mx,my;
+ wDrawPix_t mx,my;
- mx = ww/2;
- my = hh/2;
+ mx = ww/2.0;
+ my = hh/2.0;
mainD.Pix2CoOrd( &mainD, mx, my, &middle_screen );
for ( trk=*importTrack; trk; trk=trk->next ) {
- if (!IsTrackDeleted(trk)) {
- if (trk->hi.y > ymax ) ymax = trk->hi.y;
- if (trk->lo.y < ymin ) ymin = trk->lo.y;
- if (trk->hi.x > xmax ) xmax = trk->hi.x;
- if (trk->lo.x < xmin ) xmin = trk->lo.x;
- }
+ CHECK(!IsTrackDeleted(trk)); // Export ignores deleted tracks
+ if (trk->hi.y > ymax ) { ymax = trk->hi.y; }
+ if (trk->lo.y < ymin ) { ymin = trk->lo.y; }
+ if (trk->hi.x > xmax ) { xmax = trk->hi.x; }
+ if (trk->lo.x < xmin ) { xmin = trk->lo.x; }
}
coOrd size = {xmax-xmin,ymax-ymin};
@@ -1541,10 +1681,10 @@ EXPORT void ImportEnd( coOrd offset, wBool_t import, wBool_t inPlace )
middle_object.x = offset.x + (size.x/2);
middle_object.y = offset.y + (size.y/2);
- wPos_t ox,oy;
+ wDrawPix_t ox,oy;
mainD.CoOrd2Pix( &mainD, middle_object, &ox, &oy );
- if ((ox<0) || (ox>ww) || (oy<0) || (oy>hh) ) offscreen = TRUE;
+ if ((ox<0) || (ox>ww) || (oy<0) || (oy>hh) ) { offscreen = TRUE; }
to_firstOld = to_first;
to_first = *importTrack;
@@ -1554,7 +1694,8 @@ EXPORT void ImportEnd( coOrd offset, wBool_t import, wBool_t inPlace )
RenumberTracks();
// move the imported track into place
- for ( trk=*importTrack; trk; trk=trk->next ) if (!IsTrackDeleted(trk)) {
+ for ( trk=*importTrack; trk; trk=trk->next ) {
+ CHECK( !IsTrackDeleted(trk) );
coOrd move;
move.x = offset.x;
move.y = offset.y;
@@ -1562,33 +1703,36 @@ EXPORT void ImportEnd( coOrd offset, wBool_t import, wBool_t inPlace )
trk->bits |= TB_SELECTED;
DrawTrack( trk, &mainD, wDrawColorBlack );
}
- importTrack = NULL;
+ importTrack = NULL;
trackCount = trackCountOld;
InfoCount( trackCount );
// Pan screen if needed to center of new
if (offscreen) {
panCenter = middle_object;
- PanHere((void*)0);
+ PanHere(I2VP(0));
}
}
/*******
* Move Selected Tracks to origin zero and write out
*******/
-EXPORT BOOL_T ExportTracks( FILE * f, coOrd * offset)
+EXPORT BOOL_T ExportTracks( FILE * f, coOrd * offset )
{
track_p trk;
coOrd xlat,orig;
-
- exportingTracks = TRUE;
+
+ bWriteEndPtExporting = TRUE;
orig = mapD.size;
max_index = 0;
TRK_ITERATE(trk) {
if ( GetTrkSelected(trk) ) {
- if (trk->lo.x < orig.x)
+ if (QueryTrack(trk,Q_ISTRAIN)) { continue; } //Don't bother with CARs
+ if (trk->lo.x < orig.x) {
orig.x = trk->lo.x;
- if (trk->lo.y < orig.y)
+ }
+ if (trk->lo.y < orig.y) {
orig.y = trk->lo.y;
+ }
trk->index = ++max_index;
}
}
@@ -1599,13 +1743,14 @@ EXPORT BOOL_T ExportTracks( FILE * f, coOrd * offset)
xlat.y = - orig.y;
TRK_ITERATE( trk ) {
if ( GetTrkSelected(trk) ) {
+ if (QueryTrack(trk,Q_ISTRAIN)) { continue; } //Don't bother with CARs
MoveTrack( trk, xlat );
trackCmds(GetTrkType(trk))->write( trk, f );
MoveTrack( trk, orig );
}
}
RenumberTracks();
- exportingTracks = FALSE;
+ bWriteEndPtExporting = FALSE;
return TRUE;
}
@@ -1637,7 +1782,8 @@ static void AuditPrint( char * msg )
auditFile = fopen( path, "a+" );
free(path);
if (auditFile == NULL) {
- NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Audit"), message, strerror(errno) );
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Audit"), message,
+ strerror(errno) );
auditIgnore = TRUE;
return;
}
@@ -1649,12 +1795,14 @@ static void AuditPrint( char * msg )
}
fprintf(auditFile, "# " );
fprintf(auditFile, "%s", msg );
- if (auditIgnore)
+ if (auditIgnore) {
return;
+ }
NoticeMessage( MSG_AUDIT_PRINT_MSG, _("Ok"), NULL, msg );
if (++auditCount>10) {
- if (NoticeMessage( MSG_AUDIT_PRINT_IGNORE, _("Yes"), _("No") ) )
+ if (NoticeMessage( MSG_AUDIT_PRINT_IGNORE, _("Yes"), _("No") ) ) {
auditIgnore = TRUE;
+ }
auditCount = 0;
}
}
@@ -1663,7 +1811,7 @@ static void AuditPrint( char * msg )
EXPORT void CheckTrackLength( track_cp trk )
{
DIST_T dist;
-
+
if (trackCmds(trk->type)->getLength) {
dist = trackCmds(trk->type)->getLength( trk );
} else {
@@ -1693,11 +1841,11 @@ EXPORT void AuditTracks( char * event, ... )
*msgp++ = '\n';
trackCount = 0;
- for (i=0;i<sizeof used;i++) {
+ for (i=0; i<sizeof used; i++) {
used[i] = 0;
}
if (*to_last) {
- sprintf( msgp, "*to_last is not NULL (%lx)", (long)*to_last );
+ sprintf( msgp, "*to_last is not NULL ("SLOG_FMT")", (uintptr_t)*to_last );
AuditPrint( msg );
}
TRK_ITERATE( trk ) {
@@ -1712,8 +1860,9 @@ EXPORT void AuditTracks( char * event, ... )
AuditPrint( msg );
}
if ((auditCmd = trackCmds( trk->type )->audit) != NULL) {
- if (!auditCmd( trk, msgp ))
+ if (!auditCmd( trk, msgp )) {
AuditPrint( msg );
+ }
}
if (trk->index < 8*sizeof used) {
if (BIT_SET(used,trk->index)) {
@@ -1723,45 +1872,52 @@ EXPORT void AuditTracks( char * event, ... )
SET_BIT(used, trk->index);
}
for (i=0; i<trk->endCnt; i++) {
- if ( (tn = trk->endPt[i].track) != NULL ) {
- if (IsTrackDeleted(trk)) {
+ trkEndPt_p epp = EndPtIndex( trk->endPt, i );
+ if ( (tn = GetEndPtTrack(epp)) != NULL ) {
+ if (IsTrackDeleted(tn)) {
sprintf( msgp, "T%d[%d]: T%d is deleted\n", trk->index, i, tn->index );
AuditPrint( msg );
- trk->endPt[i].track = NULL;
+ SetEndPtTrack( epp, NULL );
} else {
- for (j=0;j<tn->endCnt;j++)
- if (tn->endPt[j].track == trk)
+ for (j=0; j<tn->endCnt; j++) {
+ if (GetEndPtTrack( EndPtIndex( tn->endPt, j ) ) == trk) {
goto nextEndPt;
+ }
+ }
sprintf( msgp, "T%d[%d]: T%d doesn\'t point back\n", trk->index, i, tn->index );
AuditPrint( msg );
- trk->endPt[i].track = NULL;
+ SetEndPtTrack( epp, NULL );
}
}
nextEndPt:;
}
if (!trk->next) {
if (to_last != &trk->next) {
- sprintf( msgp, "last track (T%d @ %lx) is not to_last (%lx)\n",
- trk->index, (long)trk, (long)to_last );
+ sprintf( msgp, "last track (T%d @ "SLOG_FMT") is not to_last ("SLOG_FMT")\n",
+ trk->index, (uintptr_t)trk, (uintptr_t)to_last );
AuditPrint( msg );
}
}
}
InfoCount( trackCount );
if (auditFile != NULL) {
- if (auditStop)
- if (NoticeMessage( MSG_AUDIT_WRITE_FILE, _("Yes"), _("No"))) {
- fprintf( auditFile, "# before undo\n" );
- WriteTracks(auditFile, TRUE);
- Rdump( auditFile );
- if (strcmp("undoUndo",event)==0) {
- fprintf( auditFile, "# failure in undo\n" );
- } else if (UndoUndo()) {
- fprintf( auditFile, "# after undo\n" );
+ if (auditStop) {
+ if (NoticeMessage( MSG_AUDIT_WRITE_FILE, _("Yes"), _("No"))) {
+ fprintf( auditFile, "# before undo\n" );
WriteTracks(auditFile, TRUE);
Rdump( auditFile );
- } else {
- fprintf( auditFile, "# undo stack is empty\n" );
+ if (strcmp("undoUndo",event)==0) {
+ fprintf( auditFile, "# failure in undo\n" );
+ } else {
+ UndoUndo( NULL );
+ if ( undoStatus ) {
+ fprintf( auditFile, "# after undo\n" );
+ WriteTracks(auditFile, TRUE);
+ Rdump( auditFile );
+ } else {
+ fprintf( auditFile, "# undo stack is empty\n" );
+ }
+ }
}
}
if (NoticeMessage( MSG_AUDIT_ABORT, _("Yes"), _("No"))) {
@@ -1787,103 +1943,26 @@ EXPORT void ComputeBoundingBox( track_p trk )
{
EPINX_T i;
- if (trk->endCnt <= 0)
- AbortProg("computeBoundingBox - endCnt<=0");
+ CHECK( trk->endCnt > 0 );
- trk->hi.x = trk->lo.x = (float)trk->endPt[0].pos.x;
- trk->hi.y = trk->lo.y = (float)trk->endPt[0].pos.y;
+ coOrd pos = GetEndPtPos( trk->endPt );
+ trk->hi.x = trk->lo.x = (float)pos.x;
+ trk->hi.y = trk->lo.y = (float)pos.y;
for ( i=1; i<trk->endCnt; i++ ) {
- if (trk->endPt[i].pos.x > trk->hi.x)
- trk->hi.x = (float)trk->endPt[i].pos.x;
- if (trk->endPt[i].pos.y > trk->hi.y)
- trk->hi.y = (float)trk->endPt[i].pos.y;
- if (trk->endPt[i].pos.x < trk->lo.x)
- trk->lo.x = (float)trk->endPt[i].pos.x;
- if (trk->endPt[i].pos.y < trk->lo.y)
- trk->lo.y = (float)trk->endPt[i].pos.y;
- }
-}
-
-
-
-EXPORT DIST_T EndPtDescriptionDistance(
- coOrd pos,
- track_p trk,
- EPINX_T ep,
- coOrd *dpos,
- BOOL_T show_hidden,
- BOOL_T * hidden)
-{
- elev_t *e;
- coOrd pos1;
- track_p trk1;
- *dpos = pos;
- if (hidden) *hidden = FALSE;
- e = &trk->endPt[ep].elev;
- if ((e->option&ELEV_MASK)==ELEV_NONE)
- return 100000;
- if (((e->option&ELEV_VISIBLE)==0) && !show_hidden)
- return 100000;
- if ((trk1=GetTrkEndTrk(trk,ep)) && GetTrkIndex(trk1)<GetTrkIndex(trk))
- return 100000;
- if ((e->option&ELEV_VISIBLE)==0) { //Hidden - disregard offset
- if (hidden) *hidden = TRUE;
- return FindDistance( GetTrkEndPos(trk,ep), pos );
- }
- /*REORIGIN( pos1, e->doff, GetTrkEndPos(trk,ep), GetTrkEndAngle(trk,ep) );*/
- pos1 = GetTrkEndPos(trk,ep);
- pos1.x += e->doff.x;
- pos1.y += e->doff.y;
- *dpos = pos1;
- if (hidden) *hidden = !(e->option&ELEV_VISIBLE);
- return FindDistance( pos1, pos );
-}
-
-
-EXPORT STATUS_T EndPtDescriptionMove(
- track_p trk,
- EPINX_T ep,
- wAction_t action,
- coOrd pos )
-{
- static coOrd p0, p1;
- static BOOL_T editState = FALSE;
- elev_t *e, *e1;
- track_p trk1;
-
- e = &trk->endPt[ep].elev;
- switch (action) {
- case C_DOWN:
- p0 = GetTrkEndPos(trk,ep);
- p1 = pos;
- e->option |= ELEV_VISIBLE; //Make sure we make visible
- DrawEndElev( &mainD, trk, ep, wDrawColorWhite );
- /*no break*/
- case C_MOVE:
- case C_UP:
- editState = TRUE;
- p1 = pos;
- e->doff.x = (pos.x-p0.x);
- e->doff.y = (pos.y-p0.y);
- if ((trk1=GetTrkEndTrk(trk,ep))) {
- e1 = &trk1->endPt[GetEndPtConnectedToMe(trk1,trk)].elev;
- e1->doff = e->doff;
+ pos = GetEndPtPos( EndPtIndex( trk->endPt, i ) );
+ if (pos.x > trk->hi.x) {
+ trk->hi.x = (float)pos.x;
}
- if ( action == C_UP ) {
- editState = FALSE;
- wDrawColor color = GetTrkColor( trk, &mainD );
- DrawEndElev( &mainD, trk, ep, color );
+ if (pos.y > trk->hi.y) {
+ trk->hi.y = (float)pos.y;
}
- return action==C_UP?C_TERMINATE:C_CONTINUE;
-
- case C_REDRAW:
- DrawEndElev( &tempD, trk, ep, wDrawColorBlue );
- if ( editState ) {
- DrawLine( &tempD, p0, p1, 0, wDrawColorBlue );
+ if (pos.x < trk->lo.x) {
+ trk->lo.x = (float)pos.x;
+ }
+ if (pos.y < trk->lo.y) {
+ trk->lo.y = (float)pos.y;
}
- break;
}
- return C_CONTINUE;
}
@@ -1894,119 +1973,118 @@ EXPORT STATUS_T EndPtDescriptionMove(
*/
-static DIST_T distanceEpsilon = 0.0;
-static ANGLE_T angleEpsilon = 0.0;
+//static DIST_T distanceEpsilon = 0.0;
+//static ANGLE_T angleEpsilon = 0.0;
-EXPORT void LoosenTracks( void )
+EXPORT int ConnectTracks( track_p trk0, EPINX_T inx0, track_p trk1,
+ EPINX_T inx1 )
{
- track_p trk, trk1;
- EPINX_T ep0, ep1;
- ANGLE_T angle0, angle1;
- coOrd pos0, pos1;
DIST_T d;
ANGLE_T a;
- int count;
+ coOrd pos0, pos1;
+ trkEndPt_p epp0 = EndPtIndex( trk0->endPt, inx0 );
+ trkEndPt_p epp1 = EndPtIndex( trk1->endPt, inx1 );
- count = 0;
- TRK_ITERATE(trk) {
- for (ep0=0; ep0<trk->endCnt; ep0++) {
- trk1 = GetTrkEndTrk( trk, ep0 );
- if (trk1 == NULL)
- continue;
- ASSERT( !IsTrackDeleted(trk1) );
- ep1 = GetEndPtConnectedToMe( trk1, trk );
- if (ep1 < 0)
- continue;
- pos0 = GetTrkEndPos( trk, ep0 );
- pos1 = GetTrkEndPos( trk1, ep1 );
- angle0 = GetTrkEndAngle( trk, ep0 );
- angle1 = GetTrkEndAngle( trk1, ep1 );
- d = FindDistance( pos0, pos1 );
- a = NormalizeAngle( 180+angle0-angle1+angleEpsilon );
- if (d > distanceEpsilon || a > angleEpsilon*2.0) {
- DisconnectTracks( trk, ep0, trk1, ep1 );
- count++;
- InfoMessage( _("%d Track(s) loosened"), count );
- }
+ if (QueryTrack(trk0,Q_ISTRAIN)) {
+ if (!QueryTrack(trk1,Q_ISTRAIN)) {
+ NoticeMessage( _("Connecting a car to a non-car T%d T%d"), _("Continue"), NULL,
+ GetTrkIndex(trk0), GetTrkIndex(trk1) );
+ return -1;
}
+ SetEndPtTrack( epp0, trk1 );
+ SetEndPtTrack( epp1, trk0 );
+ return 0;
}
- if (count)
- MainRedraw(); // LoosenTracks
- else
- InfoMessage(_("No tracks loosened"));
-}
-
-EXPORT int ConnectTracks( track_p trk0, EPINX_T inx0, track_p trk1, EPINX_T inx1 )
-{
- DIST_T d;
- ANGLE_T a;
- coOrd pos0, pos1;
if ( !IsTrack(trk0) ) {
- NoticeMessage( _("Connecting a non-track(%d) to (%d)"), _("Continue"), NULL, GetTrkIndex(trk0), GetTrkIndex(trk1) );
+ NoticeMessage( _("Connecting a non-track(%d) to (%d)"), _("Continue"), NULL,
+ GetTrkIndex(trk0), GetTrkIndex(trk1) );
return -1;
}
if ( !IsTrack(trk1) ) {
- NoticeMessage( _("Connecting a non-track(%d) to (%d)"), _("Continue"), NULL, GetTrkIndex(trk1), GetTrkIndex(trk0) );
+ NoticeMessage( _("Connecting a non-track(%d) to (%d)"), _("Continue"), NULL,
+ GetTrkIndex(trk1), GetTrkIndex(trk0) );
return -1;
}
- pos0 = trk0->endPt[inx0].pos;
- pos1 = trk1->endPt[inx1].pos;
-LOG( log_track, 3, ( "ConnectTracks( T%d[%d] @ [%0.3f, %0.3f] = T%d[%d] @ [%0.3f %0.3f]\n", trk0->index, inx0, pos0.x, pos0.y, trk1->index, inx1, pos1.x, pos1.y ) )
+ pos0 = GetEndPtPos( epp0 );
+ pos1 = GetEndPtPos( epp1 );
+ LOG( log_track, 3,
+ ( "ConnectTracks( T%d[%d] @ [%0.3f, %0.3f] = T%d[%d] @ [%0.3f %0.3f]\n",
+ trk0->index, inx0, pos0.x, pos0.y, trk1->index, inx1, pos1.x, pos1.y ) )
d = FindDistance( pos0, pos1 );
- a = fabs(DifferenceBetweenAngles( trk0->endPt[inx0].angle,
- trk1->endPt[inx1].angle + 180.0 ));
+ a = fabs(DifferenceBetweenAngles( GetEndPtAngle(epp0),
+ GetEndPtAngle(epp1) + 180.0 ));
if (d > connectDistance || (a > connectAngle ) ) {
LOG( log_endPt, 1, ( "connectTracks: T%d[%d] T%d[%d] d=%0.3f a=%0.3f\n",
- trk0->index, inx0, trk1->index, inx1, d, a ) );
- NoticeMessage( MSG_CONNECT_TRK, _("Continue"), NULL, trk0->index, inx0, trk1->index, inx1, d, a );
+ trk0->index, inx0, trk1->index, inx1, d, a ) );
+ NoticeMessage( MSG_CONNECT_TRK, _("Continue"), NULL, trk0->index, inx0,
+ trk1->index, inx1, d, a );
return -1; /* Stop connecting out of alignment tracks! */
}
UndoModify( trk0 );
UndoModify( trk1 );
- if (!suspendElevUpdates)
+ if (!suspendElevUpdates) {
SetTrkElevModes( TRUE, trk0, inx0, trk1, inx1 );
- trk0->endPt[inx0].track = trk1;
- trk1->endPt[inx1].track = trk0;
- AuditTracks( "connectTracks T%d[%d], T%d[%d]", trk0->index, inx0, trk1->index, inx1 );
+ }
+ SetEndPtTrack( epp0, trk1 );
+ SetEndPtTrack( epp1, trk0 );
+ AuditTracks( "connectTracks T%d[%d], T%d[%d]", trk0->index, inx0, trk1->index,
+ inx1 );
return 0;
}
-EXPORT void DisconnectTracks( track_p trk1, EPINX_T ep1, track_p trk2, EPINX_T ep2 )
+EXPORT void DisconnectTracks( track_p trk1, EPINX_T ep1, track_p trk2,
+ EPINX_T ep2 )
{
- if (trk1->endPt[ep1].track != trk2 ||
- trk2->endPt[ep2].track != trk1 )
- AbortProg("disconnectTracks: tracks not connected" );
+ trkEndPt_p epp1 = EndPtIndex( trk1->endPt, ep1 );
+ trkEndPt_p epp2 = EndPtIndex( trk2->endPt, ep2 );
+ // Check tracks are connected
+ CHECK( GetEndPtTrack(epp1) == trk2 );
+ CHECK( GetEndPtTrack(epp2) == trk1 );
+ if (QueryTrack(trk1,Q_ISTRAIN)) {
+ if (!QueryTrack(trk2,Q_ISTRAIN)) {
+ NoticeMessage( _("Disconnecting a car from a non-car T%d T%d"), _("Continue"),
+ NULL, GetTrkIndex(trk1), GetTrkIndex(trk2) );
+ return;
+ }
+ SetEndPtTrack( epp1, NULL );
+ SetEndPtTrack( epp2, NULL );
+ return;
+ }
+
UndoModify( trk1 );
UndoModify( trk2 );
- trk1->endPt[ep1].track = NULL;
- trk2->endPt[ep2].track = NULL;
- if (!suspendElevUpdates)
+ SetEndPtTrack( epp1, NULL );
+ SetEndPtTrack( epp2, NULL );
+ if (!suspendElevUpdates) {
SetTrkElevModes( FALSE, trk1, ep1, trk2, ep2 );
+ }
}
EXPORT BOOL_T ConnectAbuttingTracks(
- track_p trk0,
- EPINX_T ep0,
- track_p trk1,
- EPINX_T ep1 )
+ track_p trk0,
+ EPINX_T ep0,
+ track_p trk1,
+ EPINX_T ep1 )
{
DIST_T d;
ANGLE_T a;
d = FindDistance( GetTrkEndPos(trk0,ep0),
- GetTrkEndPos(trk1,ep1 ) );
+ GetTrkEndPos(trk1,ep1 ) );
a = NormalizeAngle( GetTrkEndAngle(trk0,ep0) -
- GetTrkEndAngle(trk1,ep1) +
- (180.0+connectAngle/2.0) );
- if ( a < connectAngle &&
- d < connectDistance ) {
- UndoStart( _("Join Abutting Tracks"), "ConnectAbuttingTracks( T%d[%d] T%d[%d] )", GetTrkIndex(trk0), ep0, GetTrkIndex(trk1), ep1 );
+ GetTrkEndAngle(trk1,ep1) +
+ (180.0+connectAngle/2.0) );
+ if ( a < connectAngle &&
+ d < connectDistance ) {
+ UndoStart( _("Join Abutting Tracks"),
+ "ConnectAbuttingTracks( T%d[%d] T%d[%d] )", GetTrkIndex(trk0), ep0,
+ GetTrkIndex(trk1), ep1 );
DrawEndPt( &mainD, trk0, ep0, wDrawColorWhite );
DrawEndPt( &mainD, trk1, ep1, wDrawColorWhite );
ConnectTracks( trk0, ep0,
- trk1, ep1 );
+ trk1, ep1 );
DrawEndPt( &mainD, trk0, ep0, wDrawColorBlack );
DrawEndPt( &mainD, trk1, ep1, wDrawColorBlack );
UndoEnd();
@@ -2016,20 +2094,22 @@ EXPORT BOOL_T ConnectAbuttingTracks(
}
-EXPORT ANGLE_T GetAngleAtPoint( track_p trk, coOrd pos, EPINX_T *ep0, EPINX_T *ep1 )
+EXPORT ANGLE_T GetAngleAtPoint( track_p trk, coOrd pos, EPINX_T *ep0,
+ EPINX_T *ep1 )
{
ANGLE_T (*getAngleCmd)( track_p, coOrd, EPINX_T *, EPINX_T * );
- if ((getAngleCmd = trackCmds(trk->type)->getAngle) != NULL)
+ if ((getAngleCmd = trackCmds(trk->type)->getAngle) != NULL) {
return getAngleCmd( trk, pos, ep0, ep1 );
- else {
+ } else {
NoticeMessage( MSG_GAAP_BAD_TYPE, _("Continue"), NULL, trk->type, trk->index );
return 0;
}
}
-EXPORT BOOL_T SplitTrack( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover, BOOL_T disconnect )
+EXPORT BOOL_T SplitTrack( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover,
+ BOOL_T disconnect )
{
DIST_T d;
track_p trk0, trk2, trkl;
@@ -2038,28 +2118,45 @@ EXPORT BOOL_T SplitTrack( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover,
BOOL_T (*splitCmd)( track_p, coOrd, EPINX_T, track_p *, EPINX_T *, EPINX_T * );
coOrd pos0;
+ if (!IsTrack(trk)) {
+ if ((splitCmd = trackCmds(trk->type)->split) == NULL) { return FALSE; }
+ UndrawNewTrack( trk );
+ UndoModify( trk );
+ rc = splitCmd( trk, pos, ep, leftover, &epl, &ep1 );
+ if (*leftover) {
+ SetTrkLayer(*leftover,GetTrkLayer( trk ));
+ DrawNewTrack( *leftover );
+ }
+ DrawNewTrack( trk );
+ return rc;
+ }
+
trk0 = trk;
epl = ep;
epCnt = GetTrkEndPtCnt(trk);
*leftover = NULL;
-LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos.x, pos.y ) )
+ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep,
+ pos.x, pos.y ) )
+ trkEndPt_p epp = EndPtIndex( trk->endPt, ep );
+ pos0 = GetEndPtPos( epp );
if (((splitCmd = trackCmds(trk->type)->split) == NULL)) {
- if (!(FindDistance( trk->endPt[ep].pos, pos) <= minLength)) {
- ErrorMessage( MSG_CANT_SPLIT_TRK, trackCmds(trk->type)->name );
- return FALSE;
+ if (!(FindDistance( pos0, pos) <= minLength)) {
+ ErrorMessage(MSG_SPLITTED_OBJECT_TOO_SHORT, PutDim(fabs(minLength)));
+ return FALSE;
}
}
UndrawNewTrack( trk );
UndoModify( trk );
- pos0 = trk->endPt[ep].pos;
if ((d = FindDistance( pos0, pos )) <= minLength) {
/* easy: just disconnect */
- if ((trk2=trk->endPt[ep].track) != NULL) {
+ trk2 = GetEndPtTrack(epp);
+ if (trk2 != NULL) {
UndrawNewTrack( trk2 );
ep2 = GetEndPtConnectedToMe( trk2, trk );
- if (ep2 < 0)
+ if (ep2 < 0) {
return FALSE;
+ }
DisconnectTracks( trk, ep, trk2, ep2 );
LOG( log_track, 2, ( " at endPt with T%d[%d]\n", trk2->index, ep2 ) )
DrawNewTrack( trk2 );
@@ -2070,13 +2167,15 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
} else if ( epCnt == 2 &&
- (d = FindDistance( trk->endPt[1-ep].pos, pos )) <= minLength) {
+ (d = FindDistance( GetEndPtPos(EndPtIndex(trk->endPt,1-ep)),
+ pos )) <= minLength) {
/* easy: just disconnect */
- if ((trk2=trk->endPt[1-ep].track) != NULL) {
+ if ((trk2=GetEndPtTrack(EndPtIndex(trk->endPt,1-ep))) != NULL) {
UndrawNewTrack( trk2 );
ep2 = GetEndPtConnectedToMe( trk2, trk );
- if (ep2 < 0)
+ if (ep2 < 0) {
return FALSE;
+ }
DisconnectTracks( trk, 1-ep, trk2, ep2 );
LOG( log_track, 2, ( " at endPt with T%d[%d]\n", trk2->index, ep2 ) )
DrawNewTrack( trk2 );
@@ -2089,16 +2188,18 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
} else {
/* TODO circle's don't have ep's */
trk2 = GetTrkEndTrk( trk, ep );
- if ( !disconnect )
+ if ( !disconnect ) {
suspendElevUpdates = TRUE;
+ }
if (trk2 != NULL) {
ep2 = GetEndPtConnectedToMe( trk2, trk );
DisconnectTracks( trk, ep, trk2, ep2 );
}
rc = splitCmd( trk, pos, ep, leftover, &epl, &ep1 );
if (!rc) {
- if ( trk2 != NULL )
+ if ( trk2 != NULL ) {
ConnectTracks( trk, ep, trk2, ep2 );
+ }
suspendElevUpdates = FALSE;
DrawNewTrack( trk );
return FALSE;
@@ -2107,20 +2208,23 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
if (*leftover) {
trkl = *leftover;
ep0 = epl;
- if ( !disconnect )
+ if ( !disconnect ) {
ConnectTracks( trk, ep, trkl, epl );
+ }
ep0 = 1-epl;
while ( 1 ) {
CopyAttributes( trk, trkl );
ClrTrkElev( trkl );
trk0 = GetTrkEndTrk(trkl,ep0);
- if ( trk0 == NULL || trk0->type == T_TURNOUT )
+ if ( trk0 == NULL || trk0->type == T_TURNOUT ) {
break;
+ }
ep0 = 1-GetEndPtConnectedToMe(trk0,trkl);
trkl = trk0;
}
- if (trk2)
+ if (trk2) {
ConnectTracks( trkl, ep0, trk2, ep2 );
+ }
LOG( log_track, 2, ( " midTrack (leftover = T%d)\n", (trkl)->index ) )
}
suspendElevUpdates = FALSE;
@@ -2131,8 +2235,9 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
while ( 1 ) {
DrawNewTrack( trkl );
trk0 = GetTrkEndTrk(trkl,ep0);
- if ( trk0 == NULL || trk0 == trk2 || trk0->type == T_TURNOUT)
+ if ( trk0 == NULL || trk0 == trk2 || trk0->type == T_TURNOUT) {
break;
+ }
ep0 = 1-GetEndPtConnectedToMe(trk0,trkl);
trkl = trk0;
}
@@ -2143,30 +2248,35 @@ LOG( log_track, 2, ( "SplitTrack( T%d[%d], (%0.3f %0.3f)\n", trk->index, ep, pos
EXPORT BOOL_T TraverseTrack(
- traverseTrack_p trvTrk,
- DIST_T * distR )
+ traverseTrack_p trvTrk,
+ DIST_T * distR )
{
track_p oldTrk;
EPINX_T ep;
while ( *distR > 0.0 && trvTrk->trk ) {
- if ( trackCmds((trvTrk->trk)->type)->traverse == NULL )
+ if ( trackCmds((trvTrk->trk)->type)->traverse == NULL ) {
return FALSE;
+ }
oldTrk = trvTrk->trk;
- if ( !trackCmds((trvTrk->trk)->type)->traverse( trvTrk, distR ) )
+ if ( !trackCmds((trvTrk->trk)->type)->traverse( trvTrk, distR ) ) {
return FALSE;
- if ( *distR <= 0.0 )
+ }
+ if ( *distR <= 0.0 ) {
return TRUE;
- if ( !trvTrk->trk )
+ }
+ if ( !trvTrk->trk ) {
return FALSE;
+ }
ep = GetNearestEndPtConnectedToMe( trvTrk->trk, oldTrk, trvTrk->pos );
if ( ep != -1 ) {
trvTrk->pos = GetTrkEndPos( trvTrk->trk, ep );
trvTrk->angle = NormalizeAngle( GetTrkEndAngle( trvTrk->trk, ep ) + 180.0 );
}
if ( trackCmds((trvTrk->trk)->type)->checkTraverse &&
- !trackCmds((trvTrk->trk)->type)->checkTraverse( trvTrk->trk, trvTrk->pos ) )
+ !trackCmds((trvTrk->trk)->type)->checkTraverse( trvTrk->trk, trvTrk->pos ) ) {
return FALSE;
+ }
trvTrk->length = -1;
trvTrk->dist = 0.0;
@@ -2181,20 +2291,25 @@ EXPORT BOOL_T RemoveTrack( track_p * trk, EPINX_T * ep, DIST_T *dist )
track_p trk1;
EPINX_T ep1=-1;
while ( *dist > 0.0 ) {
- if (trackCmds((*trk)->type)->getLength == NULL)
+ if (trackCmds((*trk)->type)->getLength == NULL) {
return FALSE;
- if (GetTrkEndPtCnt(*trk) != 2)
+ }
+ if (GetTrkEndPtCnt(*trk) != 2) {
return FALSE;
+ }
dist1 = trackCmds((*trk)->type)->getLength(*trk);
- if ( dist1 > *dist )
+ if ( dist1 > *dist ) {
break;
+ }
*dist -= dist1;
trk1 = GetTrkEndTrk( *trk, 1-*ep );
- if (trk1)
+ if (trk1) {
ep1 = GetEndPtConnectedToMe( trk1, *trk );
+ }
DeleteTrack( *trk, FALSE );
- if (!trk1)
+ if (!trk1) {
return FALSE;
+ }
*trk = trk1;
*ep = ep1;
}
@@ -2204,22 +2319,26 @@ EXPORT BOOL_T RemoveTrack( track_p * trk, EPINX_T * ep, DIST_T *dist )
}
-EXPORT BOOL_T TrimTrack( track_p trk, EPINX_T ep, DIST_T dist, coOrd pos, ANGLE_T angle, DIST_T radius, coOrd center )
+EXPORT BOOL_T TrimTrack( track_p trk, EPINX_T ep, DIST_T dist, coOrd pos,
+ ANGLE_T angle, DIST_T radius, coOrd center )
{
- if (trackCmds(trk->type)->trim)
+ if (trackCmds(trk->type)->trim) {
return trackCmds(trk->type)->trim( trk, ep, dist, pos, angle, radius, center );
- else
+ } else {
return FALSE;
+ }
}
-EXPORT BOOL_T MergeTracks( track_p trk0, EPINX_T ep0, track_p trk1, EPINX_T ep1 )
+EXPORT BOOL_T MergeTracks( track_p trk0, EPINX_T ep0, track_p trk1,
+ EPINX_T ep1 )
{
if (trk0->type == trk1->type &&
- trackCmds(trk0->type)->merge)
+ trackCmds(trk0->type)->merge) {
return trackCmds(trk0->type)->merge( trk0, ep0, trk1, ep1 );
- else
+ } else {
return FALSE;
+ }
}
EXPORT STATUS_T ExtendTrackFromOrig( track_p trk, wAction_t action, coOrd pos )
@@ -2236,15 +2355,17 @@ EXPORT STATUS_T ExtendTrackFromOrig( track_p trk, wAction_t action, coOrd pos )
switch ( action ) {
case C_DOWN:
ep = PickUnconnectedEndPoint( pos, trk );
- if ( ep == -1 )
+ if ( ep == -1 ) {
return C_ERROR;
+ }
pos = GetTrkEndPos(trk,ep);
- if (!GetTrackParams(PARAMS_CORNU,trk,pos,&params)) return C_ERROR;
+ if (!GetTrackParams(PARAMS_CORNU,trk,pos,&params)) { return C_ERROR; }
end_pos = pos;
+ DYNARR_SET( trkSeg_t, tempSegs_da, 1 );
if (params.type == curveTypeCurve) {
curved = TRUE;
tempSegs(0).type = SEG_CRVTRK;
- tempSegs(0).width = 0;
+ tempSegs(0).lineWidth = 0;
tempSegs(0).u.c.radius = params.arcR;
tempSegs(0).u.c.center = params.arcP;
tempSegs(0).u.c.a0 = FindAngle(params.arcP,GetTrkEndPos(trk,ep));
@@ -2252,23 +2373,29 @@ EXPORT STATUS_T ExtendTrackFromOrig( track_p trk, wAction_t action, coOrd pos )
} else {
curved = FALSE;
tempSegs(0).type = SEG_STRTRK;
- tempSegs(0).width = 0;
+ tempSegs(0).lineWidth = 0;
tempSegs(0).u.l.pos[0] = tempSegs(0).u.l.pos[1] = GetTrkEndPos( trk, ep );
}
valid = FALSE;
InfoMessage( _("Drag to change track length") );
+ DYNARR_RESET( trkSeg_t, tempSegs_da );
return C_CONTINUE;
- /*no break*/
+
case C_MOVE:
+ DYNARR_SET( trkSeg_t, tempSegs_da, 1 );
if (curved) {
//Normalize pos
- PointOnCircle( &pos, tempSegs(0).u.c.center, tempSegs(0).u.c.radius, FindAngle(tempSegs(0).u.c.center,pos) );
- ANGLE_T a = FindAngle(tempSegs(0).u.c.center,pos)-FindAngle(tempSegs(0).u.c.center,end_pos);
+ PointOnCircle( &pos, tempSegs(0).u.c.center, tempSegs(0).u.c.radius,
+ FindAngle(tempSegs(0).u.c.center,pos) );
+ ANGLE_T a = FindAngle(tempSegs(0).u.c.center,
+ pos)-FindAngle(tempSegs(0).u.c.center,end_pos);
d = fabs(a)*2*M_PI/360*tempSegs(0).u.c.radius;
if ( d <= minLength ) {
- if (action == C_MOVE)
+ if (action == C_MOVE) {
ErrorMessage( MSG_TRK_TOO_SHORT, _("Connecting "), PutDim(fabs(minLength-d)) );
+ }
valid = FALSE;
+ DYNARR_RESET( trkSeg_t, tempSegs_da );
return C_CONTINUE;
}
//Restrict to outside track
@@ -2278,6 +2405,7 @@ EXPORT STATUS_T ExtendTrackFromOrig( track_p trk, wAction_t action, coOrd pos )
tempSegs(0).u.c.a1 = 0;
tempSegs(0).u.c.a0 = end_angle;
InfoMessage( _("Inside turnout track"));
+ DYNARR_RESET( trkSeg_t, tempSegs_da );
return C_CONTINUE;
}
end_angle = GetTrkEndAngle( trk, ep );
@@ -2285,51 +2413,57 @@ EXPORT STATUS_T ExtendTrackFromOrig( track_p trk, wAction_t action, coOrd pos )
PointOnCircle( &pos, tempSegs(0).u.c.center, tempSegs(0).u.c.radius, a );
ANGLE_T a2 = FindAngle(tempSegs(0).u.c.center,end_pos);
if ((end_angle > 180 && (a2>90 && a2 <270)) ||
- (end_angle < 180 && (a2<90 || a2 >270))) {
+ (end_angle < 180 && (a2<90 || a2 >270))) {
tempSegs(0).u.c.a0 = a2;
tempSegs(0).u.c.a1 = NormalizeAngle(a-a2);
} else {
tempSegs(0).u.c.a0 = a;
tempSegs(0).u.c.a1 = NormalizeAngle(a2-a);
}
- tempSegs_da.cnt = 1;
valid = TRUE;
if (action == C_MOVE)
InfoMessage( _("Curve: Length=%s Radius=%0.3f Arc=%0.3f"),
- FormatDistance( d ), FormatDistance(tempSegs(0).u.c.radius), PutAngle( fabs(a) ) );
+ FormatDistance( d ), FormatDistance(tempSegs(0).u.c.radius),
+ PutAngle( tempSegs(0).u.c.a1 ));
return C_CONTINUE;
} else {
d = FindDistance( end_pos, pos );
valid = TRUE;
if ( d <= minLength ) {
- if (action == C_MOVE)
+ if (action == C_MOVE) {
ErrorMessage( MSG_TRK_TOO_SHORT, _("Connecting "), PutDim(fabs(minLength-d)) );
+ }
valid = FALSE;
+ DYNARR_RESET( trkSeg_t, tempSegs_da );
return C_CONTINUE;
}
- ANGLE_T diff = NormalizeAngle(GetTrkEndAngle( trk, ep )-FindAngle(end_pos, pos));
+ ANGLE_T diff = NormalizeAngle(GetTrkEndAngle( trk, ep )-FindAngle(end_pos,
+ pos));
if (diff>=90.0 && diff<=270.0) {
valid = FALSE;
- tempSegs(0).u.c.a1 = 0;
- tempSegs(0).u.c.a0 = end_angle;
InfoMessage( _("Inside turnout track"));
+ DYNARR_RESET( trkSeg_t, tempSegs_da );
return C_CONTINUE;
}
- Translate( &tempSegs(0).u.l.pos[1], tempSegs(0).u.l.pos[0], GetTrkEndAngle( trk, ep ), d );
- tempSegs_da.cnt = 1;
+
+ Translate( &tempSegs(0).u.l.pos[1], tempSegs(0).u.l.pos[0], GetTrkEndAngle( trk,
+ ep ), d );
if (action == C_MOVE)
InfoMessage( _("Straight: Length=%s Angle=%0.3f"),
- FormatDistance( d ), PutAngle( GetTrkEndAngle( trk, ep ) ) );
+ FormatDistance( d ), PutAngle( GetTrkEndAngle( trk, ep ) ) );
}
return C_CONTINUE;
case C_UP:
- if (!valid)
+ if (!valid) {
return C_TERMINATE;
+ }
+ DYNARR_RESET( trkSeg_t, tempSegs_da );
UndrawNewTrack( trk );
EPINX_T jp;
if (curved) {
- trk1 = NewCurvedTrack(tempSegs(0).u.c.center, tempSegs(0).u.c.radius, tempSegs(0).u.c.a0, tempSegs(0).u.c.a1, 0);
+ trk1 = NewCurvedTrack(tempSegs(0).u.c.center, tempSegs(0).u.c.radius,
+ tempSegs(0).u.c.a0, tempSegs(0).u.c.a1, 0);
jp = PickUnconnectedEndPoint(end_pos,trk1);
} else {
trk1 = NewStraightTrack( tempSegs(0).u.l.pos[0], tempSegs(0).u.l.pos[1] );
@@ -2347,7 +2481,8 @@ EXPORT STATUS_T ExtendTrackFromOrig( track_p trk, wAction_t action, coOrd pos )
return C_ERROR;
}
-EXPORT STATUS_T ExtendStraightFromOrig( track_p trk, wAction_t action, coOrd pos )
+EXPORT STATUS_T ExtendStraightFromOrig( track_p trk, wAction_t action,
+ coOrd pos )
{
static EPINX_T ep;
static BOOL_T valid;
@@ -2357,10 +2492,12 @@ EXPORT STATUS_T ExtendStraightFromOrig( track_p trk, wAction_t action, coOrd pos
switch ( action ) {
case C_DOWN:
ep = PickUnconnectedEndPoint( pos, trk );
- if ( ep == -1 )
+ if ( ep == -1 ) {
return C_ERROR;
+ }
+ DYNARR_SET( trkSeg_t, tempSegs_da, 1 );
tempSegs(0).type = SEG_STRTRK;
- tempSegs(0).width = 0;
+ tempSegs(0).lineWidth = 0;
tempSegs(0).u.l.pos[0] = GetTrkEndPos( trk, ep );
InfoMessage( _("Drag to change track length") );
@@ -2368,21 +2505,23 @@ EXPORT STATUS_T ExtendStraightFromOrig( track_p trk, wAction_t action, coOrd pos
d = FindDistance( tempSegs(0).u.l.pos[0], pos );
valid = TRUE;
if ( d <= minLength ) {
- if (action == C_MOVE)
+ if (action == C_MOVE) {
ErrorMessage( MSG_TRK_TOO_SHORT, _("Connecting "), PutDim(fabs(minLength-d)) );
+ }
valid = FALSE;
return C_CONTINUE;
}
- Translate( &tempSegs(0).u.l.pos[1], tempSegs(0).u.l.pos[0], GetTrkEndAngle( trk, ep ), d );
- tempSegs_da.cnt = 1;
+ Translate( &tempSegs(0).u.l.pos[1], tempSegs(0).u.l.pos[0], GetTrkEndAngle( trk,
+ ep ), d );
if (action == C_MOVE)
InfoMessage( _("Straight: Length=%s Angle=%0.3f"),
- FormatDistance( d ), PutAngle( GetTrkEndAngle( trk, ep ) ) );
+ FormatDistance( d ), PutAngle( GetTrkEndAngle( trk, ep ) ) );
return C_CONTINUE;
case C_UP:
- if (!valid)
+ if (!valid) {
return C_TERMINATE;
+ }
UndrawNewTrack( trk );
trk1 = NewStraightTrack( tempSegs(0).u.l.pos[0], tempSegs(0).u.l.pos[1] );
CopyAttributes( trk, trk1 );
@@ -2409,12 +2548,13 @@ EXPORT STATUS_T ModifyTrack( track_p trk, wAction_t action, coOrd pos )
}
-EXPORT BOOL_T GetTrackParams( int inx, track_p trk, coOrd pos, trackParams_t * params )
+EXPORT BOOL_T GetTrackParams( int inx, track_p trk, coOrd pos,
+ trackParams_t * params )
{
if ( trackCmds(trk->type)->getTrackParams ) {
return trackCmds(trk->type)->getTrackParams( inx, trk, pos, params );
} else {
- ASSERT( FALSE ); /* CHECKME */
+ CHECK( FALSE ); /* CHECKME */
return FALSE;
}
}
@@ -2473,23 +2613,29 @@ EXPORT DIST_T GetFlexLength( track_p trk0, EPINX_T ep, coOrd * pos )
d = 0.0;
while(1) {
trk1 = GetTrkEndTrk( trk, ep );
- if (trk1 == NULL)
+ if (trk1 == NULL) {
break;
- if (trk1 == trk0)
+ }
+ if (trk1 == trk0) {
break;
+ }
ep1 = GetEndPtConnectedToMe( trk1, trk );
- if (ep1 < 0 || ep1 > 1)
+ if (ep1 < 0 || ep1 > 1) {
break;
- if (trackCmds(trk1->type)->getLength == NULL)
+ }
+ if (trackCmds(trk1->type)->getLength == NULL) {
break;
+ }
dd = trackCmds(trk1->type)->getLength(trk1);
- if (dd <= 0.0)
+ if (dd <= 0.0) {
break;
+ }
d += dd;
trk = trk1;
ep = 1-ep1;
- if (d>1000000.0)
+ if (d>DIST_INF) {
break;
+ }
}
*pos = GetTrkEndPos( trk, ep );
return d;
@@ -2500,12 +2646,13 @@ EXPORT DIST_T GetTrkLength( track_p trk, EPINX_T ep0, EPINX_T ep1 )
{
coOrd pos0, pos1;
DIST_T d;
- if (ep0 == ep1)
+ if (ep0 == ep1) {
return 0.0;
- else if (trackCmds(trk->type)->getLength != NULL) {
+ } else if (trackCmds(trk->type)->getLength != NULL) {
d = trackCmds(trk->type)->getLength(trk);
- if (ep1==-1)
- d /= 2.0;
+ if (ep1==-1) {
+ d = d/2.0;
+ }
return d;
} else {
pos0 = GetTrkEndPos(trk,ep0);
@@ -2545,13 +2692,10 @@ EXPORT DIST_T GetTrkLength( track_p trk, EPINX_T ep0, EPINX_T ep1 )
return fabs(pos1.y);
}
}
-#endif
/*#define DRAW_TUNNEL_NONE (0)*/
#define DRAW_TUNNEL_DASH (1)
#define DRAW_TUNNEL_SOLID (2)
EXPORT long drawTunnel = DRAW_TUNNEL_DASH;
-EXPORT long colorTrack;
-EXPORT long colorDraw;
/******************************************************************************
*
@@ -2561,33 +2705,86 @@ EXPORT long colorDraw;
EXPORT long tieDrawMode = TIEDRAWMODE_SOLID;
EXPORT wDrawColor tieColor;
+EXPORT wDrawColor bridgeColor;
+EXPORT wDrawColor roadbedColor;
+
+/**
+ * Draw tracks with 2 rails when zoomed in
+ *
+ * \param d drawing context
+ * \return true is we draw tracks with 2 rails
+ */
+EXPORT BOOL_T DrawTwoRails( drawCmd_p d, DIST_T factor )
+{
+ DIST_T scale = twoRailScale;
+ if ( d->options&DC_PRINT ) {
+ scale = scale*2+1;
+ }
+ scale /= factor;
+ return d->scale <= scale;
+}
+
+
+/**
+ * Centerline drawing test
+ *
+ * \param d drawing context
+ * \return true for centerline, false if no centerline to draw
+ */
+
+EXPORT BOOL_T
+hasTrackCenterline( drawCmd_p d )
+{
+ // for printing, drawing of center line depends on the scale
+ if( d->options & DC_CENTERLINE && d->options & DC_PRINT ) {
+ return DrawTwoRails(d,1);
+ }
+
+ // all other cases of explicit centerline option (ie. bitmap)
+ if( d->options & DC_CENTERLINE ) {
+ return true;
+ }
+
+ // if zoomed in beyond 1:1 draw centerline when not doing a simple draw
+ if( ( d->scale <= 1.0 ) && !( d->options & DC_SIMPLE ) ) {
+ return true;
+ }
+
+ return false;
+}
-static wBool_t DoDrawTies( drawCmd_p d, track_cp trk )
+EXPORT wBool_t
+DoDrawTies( drawCmd_p d, track_cp trk )
{
- DIST_T scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale;
- if ( !trk )
+ if ( !trk ) {
return FALSE;
- if (GetTrkNoTies(trk))
- return FALSE; //No Ties for this Track
- if ( tieDrawMode == TIEDRAWMODE_NONE )
+ }
+ if (GetTrkNoTies(trk)) {
+ return FALSE; //No Ties for this Track
+ }
+ if ( tieDrawMode == TIEDRAWMODE_NONE ) {
return FALSE;
- if ( d == &mapD )
+ }
+ if ( d == &mapD ) {
return FALSE;
- if ( d->scale >= scale2rail )
+ }
+ if ( !DrawTwoRails(d,1) ) {
return FALSE;
- if ( !(GetTrkVisible(trk) || drawTunnel==DRAW_TUNNEL_SOLID) )
+ }
+ if ( !(GetTrkVisible(trk) || drawTunnel==DRAW_TUNNEL_SOLID) ) {
return FALSE;
+ }
return TRUE;
}
EXPORT void DrawTie(
- drawCmd_p d,
- coOrd pos,
- ANGLE_T angle,
- DIST_T length,
- DIST_T width,
- wDrawColor color,
- BOOL_T solid )
+ drawCmd_p d,
+ coOrd pos,
+ ANGLE_T angle,
+ DIST_T length,
+ DIST_T width,
+ wDrawColor color,
+ BOOL_T solid )
{
coOrd lo, hi;
coOrd p[4];
@@ -2609,7 +2806,7 @@ EXPORT void DrawTie(
Translate( &p[3], p[2], angle-90, width );
Translate( &p[2], p[2], angle+90, width );
- for (int i=0;i<4;i++) {
+ for (int i=0; i<4; i++) {
t[i] = 0;
}
@@ -2618,342 +2815,53 @@ EXPORT void DrawTie(
lo.y -= TBORDER/mainD.dpi*mainD.scale;
hi.x += LBORDER/mainD.dpi*mainD.scale;
hi.y += BBORDER/mainD.dpi*mainD.scale;
- if ( OFF_D( d->orig, d->size, lo, hi ) )
+ if ( OFF_D( d->orig, d->size, lo, hi ) ) {
return;
- }
- if ( solid ) {
- DrawPoly( d, 4, p, t, color, 0, 1, 0 );
- } else {
- DrawPoly( d, 4, p, t, color, 0, 0, 0);
- }
-}
-
-
-static void DrawCurvedTies(
- drawCmd_p d,
- SCALEINX_T scaleInx,
- coOrd p,
- DIST_T r,
- ANGLE_T a0,
- ANGLE_T a1,
- wDrawColor color )
-{
- tieData_p td;
- DIST_T len;
- ANGLE_T ang, dang;
- coOrd pos;
- int cnt;
-
- if ( (d->options&DC_SIMPLE) != 0 )
- return;
-
- if ( scaleInx < 0 )
- return;
- td = GetScaleTieData( scaleInx );
-
- if (color == wDrawColorBlack)
- color = tieColor;
- len = 2*M_PI*r*a1/360.0;
- cnt = (int)floor(len/td->spacing+0.5);
- if ( len-td->spacing*cnt-(td->width/2) > (td->spacing-td->width)/2 ) {
- cnt++;
- }
- if ( cnt != 0 ) {
- dang = (360.0*(len)/cnt)/(2*M_PI*r);
- for ( ang=a0+dang/2; cnt; cnt--,ang+=dang ) {
- PointOnCircle( &pos, p, r, ang );
- DrawTie( d, pos, ang+90, td->length, td->width, color, tieDrawMode==TIEDRAWMODE_SOLID );
- }
-
- }
-}
-
-
-EXPORT void DrawCurvedTrack(
- drawCmd_p d,
- coOrd p,
- DIST_T r,
- ANGLE_T a0,
- ANGLE_T a1,
- coOrd p0,
- coOrd p1,
- track_p trk,
- wDrawColor color,
- long options )
-{
- DIST_T scale2rail;
- DIST_T trackGauge = GetTrkGauge(trk);
- wDrawWidth width=0;
- trkSeg_p segPtr;
-
- if ( (d->options&DC_SEGTRACK) ) {
- DYNARR_APPEND( trkSeg_t, tempSegs_da, 10 );
- segPtr = &tempSegs(tempSegs_da.cnt-1);
- segPtr->type = SEG_CRVTRK;
- segPtr->width = 0;
- segPtr->color = wDrawColorBlack;
- segPtr->u.c.center = p;
- segPtr->u.c.a0 = a0;
- segPtr->u.c.a1 = a1;
- segPtr->u.c.radius = r;
- return;
- }
-
- scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale;
- width = trk ? GetTrkWidth( trk ): 0;
- if ( d->options&DC_THICK )
- width = 3;
- if ( color == wDrawColorPreviewSelected || color == wDrawColorPreviewUnselected )
- width = 3;
-#ifdef WINDOWS
- width *= (wDrawWidth)(d->dpi/mainD.dpi);
-#else
- if (d->options&DC_PRINT)
- width *= 300/75;
-#endif
-
-LOG( log_track, 4, ( "DST( (%0.3f %0.3f) R%0.3f A%0.3f..%0.3f)\n",
- p.x, p.y, r, a0, a1 ) )
- if ( DoDrawTies( d, trk ) )
- DrawCurvedTies( d, GetTrkScale(trk), p, r, a0, a1, color );
- if (color == wDrawColorBlack)
- color = normalColor;
- if ( d->scale >= scale2rail ) {
- DrawArc( d, p, r, a0, a1, ((d->scale<32) && centerDrawMode && !(options&DTS_NOCENTER)) ? 1 : 0, width, color );
- } else {
- if ( (d->scale <= 1 && (d->options&DC_SIMPLE)==0) || (d->options&DC_CENTERLINE)!=0
- || (d->scale <= scale2rail/2 && ((d->options&DC_PRINT) && printCenterLines))) { // if printing two rails respect print CenterLine option
- long options = d->options;
- d->options |= DC_DASH;
- DrawArc( d, p, r, a0, a1, 0, 0, color );
- d->options = options;
- }
- DrawArc( d, p, r+trackGauge/2.0, a0, a1, 0, width, color );
- DrawArc( d, p, r-trackGauge/2.0, a0, a1, (centerDrawMode && !(options&DTS_NOCENTER) ? 1: 0), width, color );
- if ( (d->options&DC_PRINT) && roadbedWidth > trackGauge && d->scale <= scale2rail/2 ) {
- wDrawWidth rbw = (wDrawWidth)floor(roadbedLineWidth*(d->dpi/d->scale)+0.5);
- if ( options&DTS_RIGHT ) {
- DrawArc( d, p, r+roadbedWidth/2.0, a0, a1, 0, rbw, color );
- }
- if ( options&DTS_LEFT ) {
- DrawArc( d, p, r-roadbedWidth/2.0, a0, a1, 0, rbw, color );
- }
- }
- }
- if (trk && GetTrkBridge( trk ) ) {
-
- ANGLE_T a2,a3;
- coOrd pp0,pp1,pp2,pp3;
-
- a2 = a0+R2D(trackGauge*1.0/r);
- a3 = a1-R2D(trackGauge*2.0/r);
-
- wDrawWidth width2 = (wDrawWidth)round((2.0 * d->dpi)/75.0);
-
- DrawArc( d, p, r+(trackGauge*1.5), a2, a3, 0, width2, color );
-
- PointOnCircle(&pp0,p,r+(trackGauge*1.5),a2);
- PointOnCircle(&pp1,p,r+(trackGauge*1.5),a3+a2);
-
- Translate( &pp2,pp0, a2-90+45, trackGauge);
- DrawLine( d, pp0, pp2, width2, color );
- Translate( &pp3,pp1, a2+a3+90-45, trackGauge);
- DrawLine( d, pp1, pp3, width2, color );
-
- DrawArc( d, p, r-(trackGauge*1.5), a2, a3, 0, width2, color );
-
- PointOnCircle(&pp0,p,r-(trackGauge*1.5),a2);
- PointOnCircle(&pp1,p,r-(trackGauge*1.5),a3+a2);
-
- Translate( &pp2,pp0, a2-90-45, trackGauge);
- DrawLine( d, pp0, pp2, width2, color );
- Translate( &pp3,pp1, a2+a3+90+45, trackGauge);
- DrawLine( d, pp1, pp3, width2, color );
-
}
-
-}
-
-
-static void DrawStraightTies(
- drawCmd_p d,
- SCALEINX_T scaleInx,
- coOrd p0,
- coOrd p1,
- wDrawColor color )
-{
- tieData_p td;
- DIST_T tieOff0=0.0, tieOff1=0.0;
- DIST_T len, dlen;
- coOrd pos;
- int cnt;
- ANGLE_T angle;
-
- if ( (d->options&DC_SIMPLE) != 0 )
- return;
-
- if ( color == wDrawColorBlack )
- color = tieColor;
- if ( scaleInx < 0 )
- return;
- td = GetScaleTieData( scaleInx );
- len = FindDistance( p0, p1 );
- len -= tieOff0+tieOff1;
- angle = FindAngle( p0, p1 );
- cnt = (int)floor(len/td->spacing+0.5);
- if ( len-td->spacing*cnt-td->width > (td->spacing-td->width)/2 ) {
- cnt++;
- }
- if ( cnt != 0 ) {
- dlen = FindDistance( p0, p1 )/cnt;
- double endsize = FindDistance( p0, p1 )-cnt*dlen-td->width;
- for ( len=dlen/2; cnt; cnt--,len+=dlen ) {
- Translate( &pos, p0, angle, len );
- DrawTie( d, pos, angle, td->length, td->width, color, tieDrawMode==TIEDRAWMODE_SOLID );
- }
- }
-}
-
-
-EXPORT void DrawStraightTrack(
- drawCmd_p d,
- coOrd p0,
- coOrd p1,
- ANGLE_T angle,
- track_cp trk,
- wDrawColor color,
- long options )
-{
- coOrd pp0, pp1;
- DIST_T scale2rail;
- DIST_T trackGauge = GetTrkGauge(trk);
- wDrawWidth width=0;
- trkSeg_p segPtr;
-
- if ( (d->options&DC_SEGTRACK) ) {
- DYNARR_APPEND( trkSeg_t, tempSegs_da, 10 );
- segPtr = &tempSegs(tempSegs_da.cnt-1);
- segPtr->type = SEG_STRTRK;
- segPtr->width = 0;
- segPtr->color = wDrawColorBlack;
- segPtr->u.l.pos[0] = p0;
- segPtr->u.l.pos[1] = p1;
- segPtr->u.l.angle = angle;
- segPtr->u.l.option = 0;
- return;
}
-
- scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale;
-
- width = trk ? GetTrkWidth( trk ): 0;
- if ( d->options&DC_THICK )
- width = 3;
- if ( color == wDrawColorPreviewSelected || color == wDrawColorPreviewUnselected )
- width = 3;
-#ifdef WINDOWS
- width *= (wDrawWidth)(d->dpi/mainD.dpi);
-#else
- if (d->options&DC_PRINT)
- width *= 300/75;
-#endif
-LOG( log_track, 4, ( "DST( (%0.3f %0.3f) .. (%0.3f..%0.3f)\n",
- p0.x, p0.y, p1.x, p1.y ) )
- if ( DoDrawTies( d, trk ) )
- DrawStraightTies( d, GetTrkScale(trk), p0, p1, color );
- if (color == wDrawColorBlack)
- color = normalColor;
- if ( d->scale >= scale2rail ) {
- DrawLine( d, p0, p1, width, color );
+ if ( solid ) {
+ DrawPoly( d, 4, p, t, color, 0, DRAW_FILL );
} else {
- if ( (d->scale <= 1 && (d->options&DC_SIMPLE)==0) || (d->options&DC_CENTERLINE)!=0
- || (d->scale <= scale2rail/2 && ((d->options&DC_PRINT) && printCenterLines))) { // if printing two rails respect print CenterLine option
- long options = d->options;
- d->options |= DC_DASH;
- DrawLine( d, p0, p1, 0, color );
- d->options = options;
- }
- Translate( &pp0, p0, angle+90, trackGauge/2.0 );
- Translate( &pp1, p1, angle+90, trackGauge/2.0 );
- DrawLine( d, pp0, pp1, width, color );
- Translate( &pp0, p0, angle-90, trackGauge/2.0 );
- Translate( &pp1, p1, angle-90, trackGauge/2.0 );
- DrawLine( d, pp0, pp1, width, color );
- if ( (d->options&DC_PRINT) && roadbedWidth > trackGauge && d->scale <= scale2rail/2.0) {
- wDrawWidth rbw = (wDrawWidth)floor(roadbedLineWidth*(d->dpi/d->scale)+0.5);
- if ( options&DTS_RIGHT ) {
- Translate( &pp0, p0, angle+90, roadbedWidth/2.0 );
- Translate( &pp1, p1, angle+90, roadbedWidth/2.0 );
- DrawLine( d, pp0, pp1, rbw, color );
- }
- if ( options&DTS_LEFT ) {
- Translate( &pp0, p0, angle-90, roadbedWidth/2.0 );
- Translate( &pp1, p1, angle-90, roadbedWidth/2.0 );
- DrawLine( d, pp0, pp1, rbw, color );
- }
- }
- }
- if (trk && GetTrkBridge( trk ) ) {
-
- coOrd pp2,pp3;
- wDrawWidth width2 = (wDrawWidth)round((2.0 * d->dpi)/75.0);
-
- Translate( &pp0, p0, angle+90, trackGauge*1.5 );
- Translate( &pp1, p1, angle+90, trackGauge*1.5 );
- Translate( &pp0, pp0, angle+180, trackGauge*1.5 );
- Translate( &pp1, pp1, angle, trackGauge*1.5 );
- DrawLine( d, pp0, pp1, width2, color );
- Translate( &pp2,pp0, angle+90-45, trackGauge);
- DrawLine( d, pp0, pp2, width2, color );
- Translate( &pp3,pp1, angle+90+45, trackGauge);
- DrawLine( d, pp1, pp3, width2, color );
-
- Translate( &pp0, p0, angle-90, trackGauge*1.5 );
- Translate( &pp1, p1, angle-90, trackGauge*1.5 );
- Translate( &pp0, pp0, angle+180, trackGauge*1.5 );
- Translate( &pp1, pp1, angle, trackGauge*1.5 );
- DrawLine( d, pp0, pp1, width2, color );
- Translate( &pp2,pp0, angle-90+45, trackGauge);
- DrawLine( d, pp0, pp2, width2, color );
- Translate( &pp3,pp1, angle-90-45, trackGauge);
- DrawLine( d, pp1, pp3, width2, color );
-
+ DrawPoly( d, 4, p, t, color, 0, DRAW_CLOSED);
}
}
EXPORT wDrawColor GetTrkColor( track_p trk, drawCmd_p d )
{
- DIST_T len, len1, elev0, elev1;
+ DIST_T len, elev0, elev1;
ANGLE_T grade = 0.0;
if ( IsTrack( trk ) && GetTrkEndPtCnt(trk) == 2 ) {
- if (GetTrkEndElevCachedHeight(trk,0,&elev0,&len) && GetTrkEndElevCachedHeight(trk,1,&elev1,&len1)) {
- grade = fabs( (elev1-elev0)/(len+len1))*100.0;
- } else {
- len = GetTrkLength( trk, 0, 1 );
- if (len>0.1) {
- ComputeElev( trk, 0, FALSE, &elev0, NULL, FALSE );
- ComputeElev( trk, 1, FALSE, &elev1, NULL, FALSE );
- grade = fabs( (elev1-elev0)/len )*100.0;
- }
+ ComputeElev( trk, 0, FALSE, &elev0, NULL, FALSE );
+ len = GetTrkLength( trk, 0, 1 );
+ ComputeElev( trk, 1, FALSE, &elev1, NULL, FALSE );
+ if (len>0.1) {
+ grade = fabs( (elev1-elev0)/len)*100.0;
}
}
- if ( (d->options&(DC_SIMPLE|DC_SEGTRACK)) != 0 )
+ if ( (d->options&(DC_SIMPLE|DC_SEGTRACK)) != 0 ) {
return wDrawColorBlack;
- if ( grade > GetLayoutMaxTrackGrade())
+ }
+ if ( grade > GetLayerMaxTrackGrade(GetTrkLayer(trk))) {
return exceptionColor;
- if ( QueryTrack( trk, Q_EXCEPTION ) )
+ }
+ if ( QueryTrack( trk, Q_EXCEPTION ) ) {
return exceptionColor;
+ }
if ( (d->options&(DC_PRINT)) == 0 ) {
- if (GetTrkBits(trk)&TB_PROFILEPATH)
+ if (GetTrkBits(trk)&TB_PROFILEPATH) {
return profilePathColor;
- if ((d->options&DC_PRINT)==0 && GetTrkSelected(trk))
+ }
+ if ((d->options&DC_PRINT)==0 && GetTrkSelected(trk) && d == &tempD) {
return selectedColor;
+ }
}
if ( (IsTrack(trk)?(colorTrack):(colorDraw)) ) {
unsigned int iLayer = GetTrkLayer( trk );
- if (GetLayerUseColor( iLayer ) )
+ if (GetLayerUseColor( iLayer ) ) {
return GetLayerColor( iLayer );
+ }
}
return wDrawColorBlack;
}
@@ -2964,31 +2872,37 @@ EXPORT void DrawTrack( track_cp trk, drawCmd_p d, wDrawColor color )
TRKTYP_T trkTyp;
// Hack for WINDOWS
- if ( trk->bits & TB_UNDRAWN )
+ if ( trk->bits & TB_UNDRAWN ) {
return;
+ }
trkTyp = GetTrkType(trk);
curTrackLayer = GetTrkLayer(trk);
if (d != &mapD ) {
if ( (!GetTrkVisible(trk)) ) {
- if ( drawTunnel==DRAW_TUNNEL_NONE )
+ if ( drawTunnel==DRAW_TUNNEL_NONE ) {
return;
- if ( drawTunnel==DRAW_TUNNEL_DASH )
+ }
+ if ( drawTunnel==DRAW_TUNNEL_DASH ) {
d->options |= DC_DASH;
+ }
}
if (color == wDrawColorBlack) {
color = GetTrkColor( trk, d );
}
- if (color == wDrawColorPreviewSelected || color == wDrawColorPreviewUnselected ) {
+ if (color == wDrawColorPreviewSelected
+ || color == wDrawColorPreviewUnselected ) {
d->options |= DC_THICK;
}
}
- if (d == &mapD && !GetLayerOnMap(curTrackLayer))
+ if (d == &mapD && !GetLayerOnMap(curTrackLayer)) {
return;
+ }
if ( (IsTrack(trk)?(colorTrack):(colorDraw)) &&
- d != &mapD && color == wDrawColorBlack )
- if (GetLayerUseColor((unsigned int)curTrackLayer))
+ (d != &mapD) && (color == wDrawColorBlack) )
+ if (GetLayerUseColor((unsigned int)curTrackLayer)) {
color = GetLayerColor((unsigned int)curTrackLayer);
+ }
trackCmds(trkTyp)->draw( trk, d, color );
d->options &= ~DC_DASH;
@@ -3022,17 +2936,21 @@ EXPORT void DrawPositionIndicators( void )
{
track_p trk;
coOrd hi, lo;
- if ( !doDrawPositionIndicator )
+ if ( !doDrawPositionIndicator ) {
return;
+ }
TRK_ITERATE( trk ) {
if ( trackCmds(trk->type)->drawPositionIndicator ) {
- if ( drawTunnel==DRAW_TUNNEL_NONE && (!GetTrkVisible(trk)) )
+ if ( drawTunnel==DRAW_TUNNEL_NONE && (!GetTrkVisible(trk)) ) {
continue;
+ }
GetBoundingBox( trk, &hi, &lo );
- if ( OFF_MAIND( lo, hi ) )
+ if ( OFF_MAIND( lo, hi ) ) {
continue;
- if (!GetLayerVisible( GetTrkLayer(trk) ) )
+ }
+ if (!GetLayerVisible( GetTrkLayer(trk) ) ) {
continue;
+ }
trackCmds(trk->type)->drawPositionIndicator( trk, selectedColor );
}
}
@@ -3040,13 +2958,14 @@ EXPORT void DrawPositionIndicators( void )
EXPORT void AdvancePositionIndicator(
- track_p trk,
- coOrd pos,
- coOrd * posR,
- ANGLE_T * angleR )
+ track_p trk,
+ coOrd pos,
+ coOrd * posR,
+ ANGLE_T * angleR )
{
- if ( trackCmds(trk->type)->advancePositionIndicator )
+ if ( trackCmds(trk->type)->advancePositionIndicator ) {
trackCmds(trk->type)->advancePositionIndicator( trk, pos, posR, angleR );
+ }
}
/*****************************************************************************
*
@@ -3054,84 +2973,23 @@ EXPORT void AdvancePositionIndicator(
*
*/
-static void DrawUnconnectedEndPt( drawCmd_p d, coOrd p, ANGLE_T a, DIST_T trackGauge, wDrawColor color )
+static void DrawUnconnectedEndPt( drawCmd_p d, coOrd p, ANGLE_T a,
+ DIST_T trackGauge, wDrawColor color )
{
coOrd p0, p1;
+ Translate( &p0, p, a, trackGauge );
+ Translate( &p1, p, a-180.0, trackGauge );
+ DrawLine( d, p0, p1, 0, color );
+ if (d->scale < 8 || drawUnconnectedEndPt > 0) {
+ Translate( &p, p, a+90.0, 0.2 );
Translate( &p0, p, a, trackGauge );
Translate( &p1, p, a-180.0, trackGauge );
- DrawLine( d, p0, p1, 0, color );
- if (d->scale < 8 || drawUnconnectedEndPt > 0) {
- Translate( &p, p, a+90.0, 0.2 );
- Translate( &p0, p, a, trackGauge );
- Translate( &p1, p, a-180.0, trackGauge );
- DrawLine( d, p0, p1, (drawUnconnectedEndPt>0)?4:0, (color==wDrawColorWhite)?color:(drawUnconnectedEndPt>1)?exceptionColor:color );
- }
-}
-
-
-EXPORT void DrawEndElev( drawCmd_p d, track_p trk, EPINX_T ep, wDrawColor color )
-{
- coOrd pp;
- wFont_p fp;
- elev_t * elev;
- track_p trk1;
- DIST_T elev0, grade;
- ANGLE_T a=0;
- int style = BOX_BOX;
- BOOL_T gradeOk = TRUE;
- char *elevStr;
-
- if ((labelEnable&LABELENABLE_ENDPT_ELEV)==0)
- return;
- elev = &trk->endPt[ep].elev; /* TRACKDEP */
- if ( (elev->option&ELEV_MASK)==ELEV_NONE ||
- (elev->option&ELEV_VISIBLE)==0 )
- return;
- if ( (trk1=GetTrkEndTrk(trk,ep)) && GetTrkIndex(trk1)<GetTrkIndex(trk) )
- return;
-
- fp = wStandardFont( F_HELV, FALSE, FALSE );
- pp = GetTrkEndPos( trk, ep );
- switch ((elev->option&ELEV_MASK)) {
- case ELEV_COMP:
- case ELEV_GRADE:
- if ( color == wDrawColorWhite ) {
- elev0 = grade = elev->u.height;
- } else if ( !ComputeElev( trk, ep, FALSE, &elev0, &grade, FALSE ) ) {
- elev0 = grade = 0;
- gradeOk = FALSE;
- }
- if ((elev->option&ELEV_MASK)==ELEV_COMP) {
- elevStr = FormatDistance(elev0);
- elev->u.height = elev0;
- } else if (gradeOk) {
- sprintf( message, "%0.1f%%", round(fabs(grade*100.0)*10)/10 );
- elevStr = message;
- a = GetTrkEndAngle( trk, ep );
- style = BOX_ARROW;
- if (grade <= -0.001)
- a = NormalizeAngle( a+180.0 );
- else if ( grade < 0.001 )
- style = BOX_BOX;
- elev->u.height = grade;
- } else {
- elevStr = "????%%";
- }
- break;
- case ELEV_DEF:
- elevStr = FormatDistance( elev->u.height);
- break;
- case ELEV_STATION:
- elevStr = elev->u.name;
- break;
- default:
- return;
+ DrawLine( d, p0, p1, (drawUnconnectedEndPt>0)?4:0,
+ (color==wDrawColorWhite)?color:(drawUnconnectedEndPt>1)?exceptionColor:color );
}
- pp.x += elev->doff.x;
- pp.y += elev->doff.y;
- DrawBoxedString( style, d, pp, elevStr, fp, (wFontSize_t)descriptionFontSize, color, a );
}
+
/**
* Draw track endpoints. The correct track endpoint (connected, unconnected etc.)
* is drawn to the track. In case the endpoint is on the transition into a
@@ -3144,127 +3002,154 @@ EXPORT void DrawEndElev( drawCmd_p d, track_p trk, EPINX_T ep, wDrawColor color
*/
EXPORT void DrawEndPt(
- drawCmd_p d,
- track_p trk,
- EPINX_T ep,
- wDrawColor color )
+ drawCmd_p d,
+ track_p trk,
+ EPINX_T ep,
+ wDrawColor color)
{
coOrd p;
ANGLE_T a;
track_p trk1;
- coOrd p0, p1, p2;
+ coOrd p0,p1,p2;
BOOL_T sepBoundary;
+ BOOL_T showBridge = 1;
DIST_T trackGauge;
wDrawWidth width;
wDrawWidth width2;
- if ( (d->options & (DC_SIMPLE|DC_SEGTRACK)) != 0)
+ if((d->options & (DC_SIMPLE | DC_SEGTRACK)) != 0) {
return;
- if ( trk && QueryTrack( trk, Q_NODRAWENDPT ) )
+ }
+ if(trk && QueryTrack(trk,Q_NODRAWENDPT)) {
return;
- if (trk == NULL || ep < 0)
+ }
+ if(trk == NULL || ep < 0) {
return;
+ }
+
+ // line width for the tunnel portal and bridge parapets, make sure it is rounded correctly
+ width2 = (wDrawWidth)round((2.0 * d->dpi) / BASE_DPI);
+ if ((d->options&DC_PRINT) && (d->dpi>2*BASE_DPI)) {
+ width2 = (wDrawWidth)round(d->dpi / BASE_DPI);
+ }
- // line width for the tunnel portal, make sure it is rounded correctly
- width2 = (wDrawWidth)round((2.0 * d->dpi)/75.0);
- if (color == wDrawColorBlack)
+ if(color == wDrawColorBlack) {
color = normalColor;
+ }
- if (labelScale >= d->scale)
- DrawEndElev( d, trk, ep, color );
+ if(((d->options & DC_PRINT) ? (labelScale * 2 + 1) : labelScale) >= d->scale) {
+ DrawEndElev(d,trk,ep,color);
+ }
trk1 = GetTrkEndTrk(trk,ep);
- p = GetTrkEndPos( trk, ep );
- a = GetTrkEndAngle( trk, ep ) + 90.0;
+ p = GetTrkEndPos(trk,ep);
+ a = GetTrkEndAngle(trk,ep) + 90.0;
trackGauge = GetTrkGauge(trk);
- if (trk1 == NULL) {
- DrawUnconnectedEndPt( d, p, a, trackGauge, color );
+ if(trk1 == NULL) {
+ DrawUnconnectedEndPt(d,p,a,trackGauge,color);
return;
}
- if ( d->scale >= ((d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale) )
- return;
-
sepBoundary = FALSE;
- if ( inDrawTracks && (d->options&DC_PRINT)==0 && importTrack == NULL && GetTrkSelected(trk) && (!GetTrkSelected(trk1))) {
- DIST_T len;
- len = trackGauge*2.0;
- if (len < 0.10*d->scale)
- len = 0.10*d->scale;
- long oldOptions = d->options;
- d->options &= ~DC_NOTSOLIDLINE;
- Translate( &p0, p, a+45, len );
- Translate( &p1, p, a+225, len );
- DrawLine( d, p0, p1, 2, selectedColor );
- Translate( &p0, p, a-45, len );
- Translate( &p1, p, a-225, len );
- DrawLine( d, p0, p1, 2, selectedColor );
- d->options = oldOptions;
- sepBoundary = TRUE;
- } else if ((d->options&DC_PRINT)==0 && importTrack == NULL && (!GetTrkSelected(trk)) && GetTrkSelected(trk1)) {
- sepBoundary = TRUE;
+ if ( DrawTwoRails(d,1) ) {
+ if(inDrawTracks && (d->options & DC_PRINT) == 0 && importTrack == NULL
+ && GetTrkSelected(trk) && (!GetTrkSelected(trk1))) {
+ DIST_T len;
+ len = trackGauge * 2.0;
+ if(len < 0.10 * d->scale) {
+ len = 0.10 * d->scale;
+ }
+ long oldOptions = d->options;
+ d->options &= ~DC_NOTSOLIDLINE;
+ Translate(&p0,p,a + 45,len);
+ Translate(&p1,p,a + 225,len);
+ DrawLine(d,p0,p1,2,selectedColor);
+ Translate(&p0,p,a - 45,len);
+ Translate(&p1,p,a - 225,len);
+ DrawLine(d,p0,p1,2,selectedColor);
+ d->options = oldOptions;
+ sepBoundary = TRUE;
+ } else if((d->options & DC_PRINT) == 0 && importTrack == NULL
+ && (!GetTrkSelected(trk)) && GetTrkSelected(trk1)) {
+ sepBoundary = TRUE;
+ }
}
// is the endpoint a transition into a tunnel?
- if (GetTrkVisible(trk) && (!GetTrkVisible(trk1))) {
+ if(GetTrkVisible(trk) && (!GetTrkVisible(trk1))) {
// yes, draw tunnel portal
- Translate( &p0, p, a, trackGauge );
- Translate( &p1, p, a+180, trackGauge );
- DrawLine( d, p0, p1, width2, color );
- Translate( &p2, p0, a+45, trackGauge/2.0 );
- DrawLine( d, p0, p2, width2, color );
- Translate( &p2, p1, a+135, trackGauge/2.0 );
- DrawLine( d, p1, p2, width2, color );
- if ( d == &mainD ) {
- width = (wDrawWidth)ceil(trackGauge*d->dpi/2.0/d->scale);
- if ( width > 1 ) {
- if ( (GetTrkEndOption(trk,ep)&EPOPT_GAPPED) != 0 ) {
- Translate( &p0, p, a, trackGauge );
- DrawLine( d, p0, p, width, color );
+ Translate(&p0,p,a,trackGauge);
+ Translate(&p1,p,a + 180,trackGauge);
+ DrawLine(d,p0,p1,width2,color);
+ Translate(&p2,p0,a + 45,trackGauge / 2.0);
+ DrawLine(d,p0,p2,width2,color);
+ Translate(&p2,p1,a + 135,trackGauge / 2.0);
+ DrawLine(d,p1,p2,width2,color);
+ if(d == &mainD) {
+ width = (wDrawWidth)ceil(trackGauge * d->dpi / 2.0 / d->scale);
+ if(width > 1) {
+ if((GetTrkEndOption(trk,ep) & EPOPT_GAPPED) != 0) {
+ Translate(&p0,p,a,trackGauge);
+ DrawLine(d,p0,p,width,color);
}
trk1 = GetTrkEndTrk(trk,ep);
- if ( trk1 ) {
- ep = GetEndPtConnectedToMe( trk1, trk );
- if ( (GetTrkEndOption(trk1,ep)&EPOPT_GAPPED) != 0 ) {
- Translate( &p0, p, a+180.0, trackGauge );
- DrawLine( d, p0, p, width, color );
+ if(trk1) {
+ ep = GetEndPtConnectedToMe(trk1,trk);
+ if((GetTrkEndOption(trk1,ep) & EPOPT_GAPPED) != 0) {
+ Translate(&p0,p,a + 180.0,trackGauge);
+ DrawLine(d,p0,p,width,color);
}
}
}
+ showBridge = 0;
}
- } else if ((!GetTrkVisible(trk)) && GetTrkVisible(trk1)) {
- ;
- } else if ( GetLayerVisible( GetTrkLayer( trk ) ) && !GetLayerVisible( GetTrkLayer( trk1 ) ) ) {
+ } else if((!GetTrkVisible(trk)) && GetTrkVisible(trk1)) {
+ showBridge = 0;
+ } else if(GetLayerVisible(GetTrkLayer(trk))
+ && !GetLayerVisible(GetTrkLayer(trk1))) {
a -= 90.0;
- Translate( &p, p, a, trackGauge/2.0 );
- Translate( &p0, p, a-135.0, trackGauge*2.0 );
- DrawLine( d, p0, p, width2, color );
- Translate( &p0, p, a+135.0, trackGauge*2.0 );
- DrawLine( d, p0, p, width2, color );
- } else if ( !GetLayerVisible( GetTrkLayer( trk ) ) && GetLayerVisible( GetTrkLayer( trk1 ) ) ) {
- ;
- } else if ( sepBoundary ) {
+ Translate(&p,p,a,trackGauge / 2.0);
+ Translate(&p0,p,a - 135.0,trackGauge * 2.0);
+ DrawLine(d,p0,p,width2,color);
+ Translate(&p0,p,a + 135.0,trackGauge * 2.0);
+ DrawLine(d,p0,p,width2,color);
+
+ showBridge = 0;
+ } else if(!GetLayerVisible(GetTrkLayer(trk))
+ && GetLayerVisible(GetTrkLayer(trk1))) {
+ showBridge = 0;
+ } else if(sepBoundary) {
;
- } else if ( (drawEndPtV == 1 && (QueryTrack(trk,Q_DRAWENDPTV_1) || QueryTrack(trk1,Q_DRAWENDPTV_1)) ) ||
- (drawEndPtV == 2) ) {
- Translate( &p0, p, a, trackGauge );
+ } else if((drawEndPtV == 1 && (QueryTrack(trk,Q_DRAWENDPTV_1)
+ || QueryTrack(trk1,Q_DRAWENDPTV_1))) || (drawEndPtV == 2)) {
+ Translate(&p0,p,a,trackGauge);
width = 0;
- if ( d != &mapD && d != &tempD && (GetTrkEndOption(trk,ep)&EPOPT_GAPPED) != 0 )
- width = (wDrawWidth)ceil(trackGauge*d->dpi/2.0/d->scale);
- DrawLine( d, p0, p, width, color );
+ if(d != &mapD && d != &tempD && (GetTrkEndOption(trk,ep) & EPOPT_GAPPED) != 0) {
+ width = (wDrawWidth)ceil(trackGauge * d->dpi / 2.0 / d->scale);
+ }
+ DrawLine(d,p0,p,width,color);
} else {
;
}
+
+ if(showBridge && GetTrkBridge(trk) && (!GetTrkBridge(trk1))) {
+ Translate(&p0,p,a,trackGauge * 1.5);
+ Translate(&p1,p0,a - 45.0,trackGauge * 1.5);
+ DrawLine(d,p0,p1,width2,color);
+ Translate(&p0,p,a,-trackGauge * 1.5);
+ Translate(&p1,p0,a + 45.0,-trackGauge * 1.5);
+ DrawLine(d,p0,p1,width2,color);
+ }
}
EXPORT void DrawEndPt2(
- drawCmd_p d,
- track_p trk,
- EPINX_T ep,
- wDrawColor color )
+ drawCmd_p d,
+ track_p trk,
+ EPINX_T ep,
+ wDrawColor color )
{
track_p trk1;
EPINX_T ep1;
@@ -3272,8 +3157,9 @@ EXPORT void DrawEndPt2(
trk1 = GetTrkEndTrk( trk, ep );
if (trk1) {
ep1 = GetEndPtConnectedToMe( trk1, trk );
- if (ep1>=0)
+ if (ep1>=0) {
DrawEndPt( d, trk1, ep1, color );
+ }
}
}
@@ -3284,46 +3170,53 @@ EXPORT void DrawTracks( drawCmd_p d, DIST_T scale, coOrd orig, coOrd size )
wIndex_t count = 0;
coOrd lo, hi;
BOOL_T doSelectRecount = FALSE;
-
+ unsigned long time0 = wGetTimer();
+
inDrawTracks = TRUE;
InfoCount( 0 );
TRK_ITERATE( trk ) {
if ( (d->options&DC_PRINT) != 0 &&
- wPrintQuit() ) {
+ wPrintQuit() ) {
inDrawTracks = FALSE;
return;
}
- if ( GetTrkSelected(trk) &&
- ( (!GetLayerVisible(GetTrkLayer(trk))) ||
- (drawTunnel==0 && !GetTrkVisible(trk)) ) ) {
+ if ( GetTrkSelected(trk) &&
+ ( (!GetLayerVisible(GetTrkLayer(trk))) ||
+ (drawTunnel==0 && !GetTrkVisible(trk)) ) ) {
ClrTrkBits( trk, TB_SELECTED );
doSelectRecount = TRUE;
}
GetBoundingBox( trk, &hi, &lo );
if ( OFF_D( orig, size, lo, hi ) ||
- (d != &mapD && !GetLayerVisible( GetTrkLayer(trk) ) ) ||
- (d == &mapD && !GetLayerOnMap( GetTrkLayer(trk) ) ) )
+ (d != &mapD && !GetLayerVisible( GetTrkLayer(trk) ) ) ||
+ (d == &mapD && !GetLayerOnMap( GetTrkLayer(trk) ) ) ) {
continue;
+ }
DrawTrack( trk, d, wDrawColorBlack );
count++;
- if (count%10 == 0)
+ if (count%10 == 0) {
InfoCount( count );
+ }
}
if (d == &mainD) {
for (inx=1; inx<trackCmds_da.cnt; inx++)
- if (trackCmds(inx)->redraw != NULL)
+ if (trackCmds(inx)->redraw != NULL) {
trackCmds(inx)->redraw();
+ }
+ LOG( log_timedrawtracks, 1, ( "DrawTracks time = %lu mS\n",
+ wGetTimer()-time0 ) );
}
InfoCount( trackCount );
inDrawTracks = FALSE;
- if ( doSelectRecount )
+ if ( doSelectRecount ) {
SelectRecount();
+ }
}
-EXPORT void DrawSelectedTracks( drawCmd_p d )
+EXPORT void DrawSelectedTracks( drawCmd_p d, BOOL_T all )
{
track_cp trk;
wIndex_t count;
@@ -3332,11 +3225,12 @@ EXPORT void DrawSelectedTracks( drawCmd_p d )
InfoCount( 0 );
TRK_ITERATE( trk ) {
- if ( GetTrkSelected( trk ) ) {
+ if ( (all && GetLayerVisible(GetTrkLayer(trk))) || GetTrkSelected( trk ) ) {
DrawTrack( trk, d, wDrawColorBlack );
count++;
- if (count%10 == 0)
+ if (count%10 == 0) {
InfoCount( count );
+ }
}
}
InfoCount( trackCount );
@@ -3354,24 +3248,29 @@ EXPORT void HilightElevations( BOOL_T hilight )
DIST_T radius;
radius = 0.05*mainD.scale;
- if ( radius < trackGauge/2.0 )
+ if ( radius < trackGauge/2.0 ) {
radius = trackGauge/2.0;
+ }
TRK_ITERATE( trk ) {
- for (ep=0;ep<GetTrkEndPtCnt(trk);ep++) {
- GetTrkEndElev( trk, ep, &mode, &elev ); /* TRACKDEP */
+ for (ep=0; ep<GetTrkEndPtCnt(trk); ep++) {
+ GetTrkEndElev( trk, ep, &mode, &elev );
if ((mode&ELEV_MASK)==ELEV_DEF || (mode&ELEV_MASK)==ELEV_IGNORE) {
if ((trk1=GetTrkEndTrk(trk,ep)) != NULL &&
- GetTrkIndex(trk1) < GetTrkIndex(trk))
+ GetTrkIndex(trk1) < GetTrkIndex(trk)) {
continue;
- if (drawTunnel == DRAW_TUNNEL_NONE && (!GetTrkVisible(trk)) && (trk1==NULL||!GetTrkVisible(trk1)) )
+ }
+ if (drawTunnel == DRAW_TUNNEL_NONE && (!GetTrkVisible(trk)) && (trk1==NULL
+ ||!GetTrkVisible(trk1)) ) {
continue;
+ }
if ((!GetLayerVisible(GetTrkLayer(trk))) &&
- (trk1==NULL||!GetLayerVisible(GetTrkLayer(trk1))))
+ (trk1==NULL||!GetLayerVisible(GetTrkLayer(trk1)))) {
continue;
+ }
pos = GetTrkEndPos(trk,ep);
if ( !OFF_MAIND( pos, pos ) ) {
DrawFillCircle( &tempD, pos, radius,
- ((mode&ELEV_MASK)==ELEV_DEF?elevColorDefined:elevColorIgnore) );
+ ((mode&ELEV_MASK)==ELEV_DEF?elevColorDefined:elevColorIgnore) );
}
}
}
@@ -3382,7 +3281,7 @@ EXPORT void HilightElevations( BOOL_T hilight )
EXPORT void HilightSelectedEndPt( BOOL_T show, track_p trk, EPINX_T ep )
{
coOrd pos;
- if (!trk || (ep==-1)) return;
+ if (!trk || (ep==-1)) { return; }
pos = GetTrkEndPos( trk, ep );
if ( show == TRUE ) {
pos = GetTrkEndPos( trk, ep );
@@ -3404,15 +3303,17 @@ EXPORT void LabelLengths( drawCmd_p d, track_p trk, wDrawColor color )
char * msg;
coOrd textsize;
- if ((labelEnable&LABELENABLE_LENGTHS)==0)
+ if ((labelEnable&LABELENABLE_LENGTHS)==0) {
return;
+ }
fp = wStandardFont( F_HELV, FALSE, FALSE );
fs = (float)descriptionFontSize/d->scale;
for (i=0; i<GetTrkEndPtCnt(trk); i++) {
p0 = GetTrkEndPos( trk, i );
dist = GetFlexLength( trk, i, &p1 );
- if (dist < 0.1)
+ if (dist < 0.1) {
continue;
+ }
if (dist < 3.0) {
p0.x = (p0.x+p1.x)/2.0;
p0.y = (p0.y+p1.y)/2.0;
@@ -3426,3 +3327,62 @@ EXPORT void LabelLengths( drawCmd_p d, track_p trk, wDrawColor color )
DrawString( d, p0, 0.0, msg, fp, fs*d->scale, color );
}
}
+
+EXPORT void AddTrkDetails(drawCmd_p d,track_p trk,coOrd pos, DIST_T length,
+ wDrawColor color)
+{
+#define DESC_LENGTH 6.0;
+ double division;
+ division = length/DESC_LENGTH;
+ division = ceil(division);
+ DIST_T dist = length/division, dist1;
+ traverseTrack_t tt;
+ tt.trk = trk;
+ tt.angle = GetTrkEndAngle(trk,0)+180.0;
+ tt.pos = GetTrkEndPos(trk,0);
+
+ dynArr_t pos_array;
+ DYNARR_INIT( pos_angle_t, pos_array );
+
+ typedef struct {
+ coOrd pos;
+ ANGLE_T angle;
+ } pos_angle_t;
+
+ DYNARR_SET(pos_angle_t,pos_array,(int)division+1);
+ DYNARR_N(pos_angle_t,pos_array,0).pos = GetTrkEndPos(trk,0);
+ DYNARR_N(pos_angle_t,pos_array,0).angle = NormalizeAngle(GetTrkEndAngle(trk,
+ 0)+180.0);
+ for (int i=1; i<pos_array.cnt; i++) {
+ tt.dist = dist;
+ dist1 = dist;
+ TraverseTrack(&tt,&dist1);
+ if (dist1 > 0 || tt.trk != trk
+ || IsClose(FindDistance(tt.pos,GetTrkEndPos(trk,1)))) {
+ DYNARR_N(pos_angle_t,pos_array,i).pos = GetTrkEndPos(trk,1);
+ DYNARR_N(pos_angle_t,pos_array,i).angle = GetTrkEndAngle(trk,1);
+ // Truncate pos_array
+ DYNARR_SET( pos_angle_t, pos_array, i+1 );
+ break;
+ }
+ DYNARR_N(pos_angle_t,pos_array,i).pos = tt.pos;
+ DYNARR_N(pos_angle_t,pos_array,i).angle = tt.angle;
+ }
+ message[0]='\0';
+ for (int i=0; i<pos_array.cnt; i++) {
+ if (i==pos_array.cnt-1) {
+ sprintf( &message[strlen(message)], _("[%0.2f,%0.2f] A%0.2f"),
+ PutDim(DYNARR_N(pos_angle_t,pos_array,i).pos.x),PutDim(DYNARR_N(pos_angle_t,
+ pos_array,i).pos.y),DYNARR_N(pos_angle_t,pos_array,i).angle );
+ } else {
+ sprintf( &message[strlen(message)], _("[%0.2f,%0.2f] A%0.2f\n"),
+ PutDim(DYNARR_N(pos_angle_t,pos_array,i).pos.x),PutDim(DYNARR_N(pos_angle_t,
+ pos_array,i).pos.y),DYNARR_N(pos_angle_t,pos_array,i).angle);
+ }
+ }
+ wFont_p fp = wStandardFont( F_TIMES, FALSE, FALSE );
+ DrawBoxedString(BOX_BOX,d,pos,message,fp,(wFontSize_t)descriptionFontSize,color,
+ 0.0);
+ DYNARR_FREE( pos_angle_t, pos_array );
+}
+