Commit 7dbb0da3 authored by dickelbeck's avatar dickelbeck

more amazing free specctra import/export software

parent f0ba106e
...@@ -8,7 +8,10 @@ email address. ...@@ -8,7 +8,10 @@ email address.
2008-Feb-7 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Feb-7 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
+pcbnew +pcbnew
specctra import of *.ses, done by end of today probably. specctra import of *.ses, did tracks and components.
renamed copy_track.cpp to copy_track.cpp.notused
removed copy_track.cpp from pcbnew/CMakeLists.txt
added setlocale() around import and export for float text style.
2008-Feb-6 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Feb-6 UPDATE Dick Hollenbeck <dick@softplc.com>
......
...@@ -39,7 +39,7 @@ SET(PCBNEW_SRCS ...@@ -39,7 +39,7 @@ SET(PCBNEW_SRCS
collectors.cpp collectors.cpp
connect.cpp connect.cpp
controle.cpp controle.cpp
copy_track.cpp # copy_track.cpp
cotation.cpp cotation.cpp
cross-probing.cpp cross-probing.cpp
deltrack.cpp deltrack.cpp
......
...@@ -282,7 +282,7 @@ void WinEDA_BasePcbFrame::SetCurItem( BOARD_ITEM* aItem ) ...@@ -282,7 +282,7 @@ void WinEDA_BasePcbFrame::SetCurItem( BOARD_ITEM* aItem )
{ {
aItem->Display_Infos( this ); aItem->Display_Infos( this );
#if 0 && defined(DEBUG) #if 1 && defined(DEBUG)
aItem->Show( 0, std::cout ); aItem->Show( 0, std::cout );
#endif #endif
......
/*******************************************/
/* Track editing: routines to copy tracks */
/*******************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "pcbnew.h"
#include "autorout.h"
#include "drag.h"
#include "protos.h"
/* local functions */
/* variables locales */
#if 0
/***************************************************************/
void WinEDA_PcbFrame::Place_Dupl_Track(Track * Track, wxDC * DC)
/***************************************************************/
/*
Routine de placement d'une piste (succession de segments)
*/
{
D_PAD * pt_pad;
TRACK * pt_track, *Track, * pt_classe, *NextS;
int masquelayer;
EDA_BaseStruct * LockPoint;
int ii, old_net_code, new_net_code, DRC_error = 0;
wxDC * DC = Cmd->DC;
ActiveDrawPanel->ManageCurseur = NULL;
if( NewTrack == NULL ) return ;
old_net_code = NewTrack->net_code;
/* Placement du flag BUSY de la piste originelle, qui ne doit
pas etre vue dans les recherches de raccordement suivantes */
ii = NbPtNewTrack; pt_track = NewTrack;
for ( ; ii > 0; ii --, pt_track = (TRACK*) pt_track->Pnext)
{
pt_track->SetState(BUSY, ON);
}
/* Detection du nouveau net_code */
ii = NbPtNewTrack; pt_track = NewTrack;
for ( ; ii > 0; ii --, pt_track = (TRACK*) pt_track->Pnext)
{
pt_track->net_code = 0;
}
new_net_code = 0;
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack ; ii++, pt_track = (TRACK*)pt_track->Pnext)
{
/* Localisation de la pastille ou segment en debut de segment: */
masquelayer = tab_layer[pt_track->Layer];
LockPoint = LocateLockPoint(pt_track->m_Start.x,pt_track->m_Start.y,masquelayer);
if( LockPoint )
{
if ( LockPoint->Type() == TYPEPAD )
{
pt_pad = (D_PAD*) LockPoint;
new_net_code = pt_pad->net_code;
if ( new_net_code > 0 ) break;
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK *) LockPoint;
new_net_code = Track->net_code;
if ( new_net_code > 0 ) break;
}
}
LockPoint = LocateLockPoint(pt_track->m_End.x,pt_track->m_End.y,masquelayer);
if( LockPoint )
{
if ( LockPoint->Type() == TYPEPAD )
{
pt_pad = (D_PAD*) LockPoint;
new_net_code = pt_pad->net_code;
if ( new_net_code > 0 ) break;
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK *) LockPoint;
new_net_code = Track->net_code;
if ( new_net_code > 0 ) break;
}
}
}
/* Mise a jour du nouveau net code de la piste */
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*)pt_track->Pnext)
{
pt_track->net_code = new_net_code;
}
/* Controle DRC de la nouvelle piste */
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = pt_track->Next() )
{
if( Drc_On == RUN )
if( drc(DC, pt_track, pt_pcb->Track, 1) == BAD_DRC )
{
if( confirmation(" Erreur DRC, Place piste:") == YES ) continue;
else { DRC_error = 1; break; }
}
}
if( DRC_error == 0)
{
if(FlagState == MOVE_ROUTE)
{
/* copie nouvelle piste */
pt_track = NewTrack;
NewTrack = pt_track->Copy(NbPtNewTrack);
/* effacement ancienne ( chainage et liens mauvais */
ii = NbPtNewTrack;
for ( ; ii > 0; ii --, pt_track = NextS)
{
NextS = (TRACK*) pt_track->Pnext;
pt_track->DeleteStructure();
}
test_1_net_connexion(DC, old_net_code );
}
pt_classe = NewTrack->GetBestInsertPoint();
NewTrack->Insert(pt_classe);
Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_OR) ;
/* Mise a jour des connexions sur pads et sur pistes */
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = NextS)
{
NextS = (TRACK*)pt_track->Pnext;
pt_track->SetState(BEGIN_ONPAD|END_ONPAD, OFF);
masquelayer = tab_layer[pt_track->Layer];
/* Localisation de la pastille ou segment sur debut segment: */
LockPoint = LocateLockPoint(pt_track->m_Start.x,pt_track->m_Start.y,masquelayer);
if( LockPoint )
{
pt_track->start = LockPoint;
if ( LockPoint->Type() == TYPEPAD )
{ /* fin de piste sur un pad */
pt_pad = (D_PAD*) LockPoint;
pt_track->SetState(BEGIN_ONPAD, ON);
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK *) LockPoint;
CreateLockPoint(&pt_track->m_Start.x,&pt_track->m_Start.y,Track,pt_track);
}
}
/* Localisation de la pastille ou segment sur fin de segment: */
LockPoint = LocateLockPoint(pt_track->m_End.x,pt_track->m_End.y,masquelayer);
if( LockPoint )
{
pt_track->end = LockPoint;
if ( LockPoint->Type() == TYPEPAD )
{ /* fin de piste sur un pad */
pt_pad = (D_PAD*) LockPoint;
pt_track->SetState(END_ONPAD, ON);
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK *) LockPoint;
CreateLockPoint(&pt_track->m_Start.x,&pt_track->m_Start.y,Track,pt_track);
}
}
}
/* Clear the BUSY flag */
ii = NbPtNewTrack; pt_track = NewTrack;
for ( ; ii > 0; ii --, pt_track = (TRACK*) pt_track->Pnext)
{
pt_track->SetState(BUSY, OFF);
}
test_1_net_connexion(DC, new_net_code );
ActiveScreen->SetModify();
}
else /* DRC error: Annulation commande */
{
DisplayOpt.DisplayPcbTrackFill = FALSE ;
Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_XOR);
DisplayOpt.DisplayPcbTrackFill = Track_fill_copy ;
if(FlagState == MOVE_ROUTE)
{ /* Remise en position de la piste deplacee */
Track = NewTrack;
PosInitX -= Track->m_Start.x; PosInitY -= Track->m_Start.y;
for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext)
{
if( Track == NULL ) break;
Track->m_Start.x += PosInitX; Track->m_Start.y += PosInitY;
Track->m_End.x += PosInitX; Track->m_End.y += PosInitY;
Track->SetState(BUSY,OFF);
}
Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_OR);
}
if (FlagState == COPY_ROUTE )
{ /* Suppression copie */
for( ii = 0; ii < NbPtNewTrack; NewTrack = NextS)
{
if(NewTrack == NULL) break;
NextS = (TRACK*) NewTrack->Pnext;
delete NewTrack;
}
}
}
NewTrack = NULL;
Affiche_Infos_Status_Pcb(Cmd);
if(Etat_Surbrillance) Hight_Light(DC);
}
/*******************************************************************************/
void WinEDA_PcbFrame::Start_CopyOrMove_Route(TRACK * track, wxDC * DC, bool Drag)
/*******************************************************************************/
/* Routine permettant la recopie d'une piste (suite de segments) deja tracee
*/
{
int ii;
TRACK *pt_segm, *pt_track;
int masquelayer = tab_layer[ActiveScreen->Active_Layer];
if( NewTrack ) return;
FlagState = (int)Cmd->Menu->param_inf;
/* Recherche de la piste sur la couche active (non zone) */
for(pt_segm = pt_pcb->Track; pt_segm != NULL; pt_segm = (TRACK*)pt_segm->Pnext)
{
pt_segm = Locate_Pistes(pt_segm,masquelayer, CURSEUR_OFF_GRILLE);
if( pt_segm == NULL ) break ;
break ;
}
if( pt_segm != NULL )
{
if (FlagState == COPY_ROUTE )
pt_track = Marque_Une_Piste(DC, pt_segm, &NbPtNewTrack, 0);
else pt_track = Marque_Une_Piste(DC, pt_segm, &NbPtNewTrack, GR_XOR);
if(NbPtNewTrack) /* Il y a NbPtNewTrack segments de piste a traiter */
{
/* effacement du flag BUSY de la piste originelle */
ii = NbPtNewTrack; pt_segm = pt_track;
for ( ; ii > 0; ii --, pt_segm = (TRACK*) pt_segm->Pnext)
{
pt_segm->SetState(BUSY, OFF);
}
if (FlagState == COPY_ROUTE )
NewTrack = pt_track->Copy(NbPtNewTrack);
else NewTrack = pt_track;
Affiche_Infos_Piste(Cmd, pt_track) ;
startX = ActiveScreen->Curseur_X;
startY = ActiveScreen->Curseur_Y;
Place_Dupl_Route_Item.State = WAIT;
ActiveDrawPanel->ManageCurseur = Show_Move_Piste;
DisplayOpt.DisplayPcbTrackFill = FALSE ;
Trace_Une_Piste(DC, NewTrack,NbPtNewTrack,GR_XOR) ;
DisplayOpt.DisplayPcbTrackFill = Track_fill_copy ;
PosInitX = NewTrack->m_Start.x; PosInitY = NewTrack->m_Start.y;
}
}
}
#endif
/*******************************************/
/* Track editing: routines to copy tracks */
/*******************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "pcbnew.h"
#include "autorout.h"
#include "drag.h"
#include "protos.h"
/* local functions */
/* variables locales */
#if 0
/***************************************************************/
void WinEDA_PcbFrame::Place_Dupl_Track( Track* Track, wxDC* DC )
/***************************************************************/
/*
* Routine de placement d'une piste (succession de segments)
*/
{
D_PAD* pt_pad;
TRACK* pt_track, * Track, * pt_classe, * NextS;
int masquelayer;
EDA_BaseStruct* LockPoint;
int ii, old_net_code, new_net_code, DRC_error = 0;
wxDC* DC = Cmd->DC;
ActiveDrawPanel->ManageCurseur = NULL;
if( NewTrack == NULL )
return;
old_net_code = NewTrack->net_code;
/* Placement du flag BUSY de la piste originelle, qui ne doit
* pas etre vue dans les recherches de raccordement suivantes */
ii = NbPtNewTrack; pt_track = NewTrack;
for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
{
pt_track->SetState( BUSY, ON );
}
/* Detection du nouveau net_code */
ii = NbPtNewTrack; pt_track = NewTrack;
for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
{
pt_track->net_code = 0;
}
new_net_code = 0;
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*) pt_track->Pnext )
{
/* Localisation de la pastille ou segment en debut de segment: */
masquelayer = tab_layer[pt_track->Layer];
LockPoint = LocateLockPoint( pt_track->m_Start.x, pt_track->m_Start.y, masquelayer );
if( LockPoint )
{
if( LockPoint->Type() == TYPEPAD )
{
pt_pad = (D_PAD*) LockPoint;
new_net_code = pt_pad->net_code;
if( new_net_code > 0 )
break;
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK*) LockPoint;
new_net_code = Track->net_code;
if( new_net_code > 0 )
break;
}
}
LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer );
if( LockPoint )
{
if( LockPoint->Type() == TYPEPAD )
{
pt_pad = (D_PAD*) LockPoint;
new_net_code = pt_pad->net_code;
if( new_net_code > 0 )
break;
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK*) LockPoint;
new_net_code = Track->net_code;
if( new_net_code > 0 )
break;
}
}
}
/* Mise a jour du nouveau net code de la piste */
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*) pt_track->Pnext )
{
pt_track->net_code = new_net_code;
}
/* Controle DRC de la nouvelle piste */
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = pt_track->Next() )
{
if( Drc_On == RUN )
if( drc( DC, pt_track, pt_pcb->Track, 1 ) == BAD_DRC )
{
if( confirmation( " Erreur DRC, Place piste:" ) == YES )
continue;
else
{
DRC_error = 1; break;
}
}
}
if( DRC_error == 0 )
{
if( FlagState == MOVE_ROUTE )
{
/* copie nouvelle piste */
pt_track = NewTrack;
NewTrack = pt_track->Copy( NbPtNewTrack );
/* effacement ancienne ( chainage et liens mauvais */
ii = NbPtNewTrack;
for( ; ii > 0; ii--, pt_track = NextS )
{
NextS = (TRACK*) pt_track->Pnext;
pt_track->DeleteStructure();
}
test_1_net_connexion( DC, old_net_code );
}
pt_classe = NewTrack->GetBestInsertPoint();
NewTrack->Insert( pt_classe );
Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR );
/* Mise a jour des connexions sur pads et sur pistes */
ii = 0; pt_track = NewTrack;
for( ; ii < NbPtNewTrack; ii++, pt_track = NextS )
{
NextS = (TRACK*) pt_track->Pnext;
pt_track->SetState( BEGIN_ONPAD | END_ONPAD, OFF );
masquelayer = tab_layer[pt_track->Layer];
/* Localisation de la pastille ou segment sur debut segment: */
LockPoint = LocateLockPoint( pt_track->m_Start.x, pt_track->m_Start.y, masquelayer );
if( LockPoint )
{
pt_track->start = LockPoint;
if( LockPoint->Type() == TYPEPAD )
{ /* fin de piste sur un pad */
pt_pad = (D_PAD*) LockPoint;
pt_track->SetState( BEGIN_ONPAD, ON );
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK*) LockPoint;
CreateLockPoint( &pt_track->m_Start.x, &pt_track->m_Start.y, Track, pt_track );
}
}
/* Localisation de la pastille ou segment sur fin de segment: */
LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer );
if( LockPoint )
{
pt_track->end = LockPoint;
if( LockPoint->Type() == TYPEPAD )
{ /* fin de piste sur un pad */
pt_pad = (D_PAD*) LockPoint;
pt_track->SetState( END_ONPAD, ON );
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK*) LockPoint;
CreateLockPoint( &pt_track->m_Start.x, &pt_track->m_Start.y, Track, pt_track );
}
}
}
/* Clear the BUSY flag */
ii = NbPtNewTrack; pt_track = NewTrack;
for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
{
pt_track->SetState( BUSY, OFF );
}
test_1_net_connexion( DC, new_net_code );
ActiveScreen->SetModify();
}
else /* DRC error: Annulation commande */
{
DisplayOpt.DisplayPcbTrackFill = FALSE;
Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_XOR );
DisplayOpt.DisplayPcbTrackFill = Track_fill_copy;
if( FlagState == MOVE_ROUTE )
{ /* Remise en position de la piste deplacee */
Track = NewTrack;
PosInitX -= Track->m_Start.x; PosInitY -= Track->m_Start.y;
for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext )
{
if( Track == NULL )
break;
Track->m_Start.x += PosInitX; Track->m_Start.y += PosInitY;
Track->m_End.x += PosInitX; Track->m_End.y += PosInitY;
Track->SetState( BUSY, OFF );
}
Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR );
}
if( FlagState == COPY_ROUTE )
{ /* Suppression copie */
for( ii = 0; ii < NbPtNewTrack; NewTrack = NextS )
{
if( NewTrack == NULL )
break;
NextS = (TRACK*) NewTrack->Pnext;
delete NewTrack;
}
}
}
NewTrack = NULL;
Affiche_Infos_Status_Pcb( Cmd );
if( Etat_Surbrillance )
Hight_Light( DC );
}
/*******************************************************************************/
void WinEDA_PcbFrame::Start_CopyOrMove_Route( TRACK* track, wxDC* DC, bool Drag )
/*******************************************************************************/
/* Routine permettant la recopie d'une piste (suite de segments) deja tracee
*/
{
int ii;
TRACK* pt_segm, * pt_track;
int masquelayer = tab_layer[ActiveScreen->Active_Layer];
if( NewTrack )
return;
FlagState = (int) Cmd->Menu->param_inf;
/* Recherche de la piste sur la couche active (non zone) */
for( pt_segm = pt_pcb->Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
{
pt_segm = Locate_Pistes( pt_segm, masquelayer, CURSEUR_OFF_GRILLE );
if( pt_segm == NULL )
break;
break;
}
if( pt_segm != NULL )
{
if( FlagState == COPY_ROUTE )
pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, 0 );
else
pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, GR_XOR );
if( NbPtNewTrack ) /* Il y a NbPtNewTrack segments de piste a traiter */
{
/* effacement du flag BUSY de la piste originelle */
ii = NbPtNewTrack; pt_segm = pt_track;
for( ; ii > 0; ii--, pt_segm = (TRACK*) pt_segm->Pnext )
{
pt_segm->SetState( BUSY, OFF );
}
if( FlagState == COPY_ROUTE )
NewTrack = pt_track->Copy( NbPtNewTrack );
else
NewTrack = pt_track;
Affiche_Infos_Piste( Cmd, pt_track );
startX = ActiveScreen->Curseur_X;
startY = ActiveScreen->Curseur_Y;
Place_Dupl_Route_Item.State = WAIT;
ActiveDrawPanel->ManageCurseur = Show_Move_Piste;
DisplayOpt.DisplayPcbTrackFill = FALSE;
Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_XOR );
DisplayOpt.DisplayPcbTrackFill = Track_fill_copy;
PosInitX = NewTrack->m_Start.x; PosInitY = NewTrack->m_Start.y;
}
}
}
#endif
...@@ -76,6 +76,43 @@ namespace DSN { ...@@ -76,6 +76,43 @@ namespace DSN {
//-----<SPECCTRA_DB>------------------------------------------------- //-----<SPECCTRA_DB>-------------------------------------------------
void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
{
// specctra wants top physical layer first, then going down to the
// bottom most physical layer in physical sequence.
// @question : why does Kicad not display layers in that order?
int layerCount = aBoard->GetCopperLayerCount();
layerIds.clear();
pcbLayer2kicad.resize( layerCount );
kicadLayer2pcb.resize( LAYER_CMP_N+1 );
for( int kiNdx=layerCount-1, pcbNdx=0; kiNdx >= 0; --kiNdx, ++pcbNdx )
{
int kilayer = kiNdx>0 && kiNdx==layerCount-1 ? LAYER_CMP_N : kiNdx;
// establish bi-directional mapping between kicad's BOARD layer and PCB layer
pcbLayer2kicad[pcbNdx] = kilayer;
kicadLayer2pcb[kilayer] = pcbNdx;
// save the specctra layer name in SPECCTRA_DB::layerIds for later.
layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( kilayer ) ) );
}
}
int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const
{
for( unsigned i=0; i<layerIds.size(); ++i )
{
if( 0 == aLayerName.compare( layerIds[i] ) )
return (int) i;
}
return -1;
}
void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError ) void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError )
{ {
wxString errText; wxString errText;
......
...@@ -3345,6 +3345,14 @@ public: ...@@ -3345,6 +3345,14 @@ public:
// delete test_points; // delete test_points;
} }
UNIT_RES* GetUnits() const
{
if( resolution )
return resolution;
return ELEM::GetUnits();
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
if( resolution ) if( resolution )
...@@ -3521,8 +3529,27 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3521,8 +3529,27 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
/// maps PCB layer number to BOARD layer numbers /// maps PCB layer number to BOARD layer numbers
std::vector<int> pcbLayer2kicad; std::vector<int> pcbLayer2kicad;
/// used during FromSESSION() only, memory for it is not owned here.
UNIT_RES* routeResolution;
/// a copy to avoid passing as an argument, memory for it is not owned here.
BOARD* sessionBoard;
static const KICAD_T scanPADs[]; static const KICAD_T scanPADs[];
/**
* Function buildLayerMaps
* creates a few data translation structures for layer name and number
* mapping between the DSN::PCB structure and the kicad BOARD structure.
* @param aBoard The BOARD to create the maps for.
*/
void buildLayerMaps( BOARD* aBoard );
/**
* Function findLayerName
* returns the PCB layer index for a given layer name
*/
int findLayerName( const std::string& aLayerName ) const;
/** /**
* Function nextTok * Function nextTok
...@@ -3698,6 +3725,17 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3698,6 +3725,17 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/ */
PADSTACK* makeVia( const SEGVIA* aVia ); PADSTACK* makeVia( const SEGVIA* aVia );
//-----<FromSESSION>-----------------------------------------------------
/**
* Function makeTRACK
* creates a TRACK form the PATH and BOARD info.
*/
TRACK* makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IOError );
//-----</FromSESSION>----------------------------------------------------
public: public:
SPECCTRA_DB() SPECCTRA_DB()
......
...@@ -701,27 +701,17 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -701,27 +701,17 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
// specctra wants top physical layer first, then going down to the // specctra wants top physical layer first, then going down to the
// bottom most physical layer in physical sequence. // bottom most physical layer in physical sequence.
// @question : why does Kicad not display layers in that order? // @question : why does Kicad not display layers in that order?
int layerCount = aBoard->GetCopperLayerCount();
layerIds.clear();
pcbLayer2kicad.resize( layerCount );
kicadLayer2pcb.resize( LAYER_CMP_N+1 );
for( int kiNdx=layerCount-1, pcbNdx=0; kiNdx >= 0; --kiNdx, ++pcbNdx )
{
int kilayer = kiNdx>0 && kiNdx==layerCount-1 ? LAYER_CMP_N : kiNdx;
// establish bi-directional mapping between kicad's BOARD layer and PCB layer buildLayerMaps( aBoard );
pcbLayer2kicad[pcbNdx] = kilayer;
kicadLayer2pcb[kilayer] = pcbNdx;
// save the specctra layer name in SPECCTRA_DB::layerIds for later. int layerCount = aBoard->GetCopperLayerCount();
layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( kilayer ) ) );
for( int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
{
LAYER* layer = new LAYER( pcb->structure ); LAYER* layer = new LAYER( pcb->structure );
pcb->structure->layers.push_back( layer ); pcb->structure->layers.push_back( layer );
layer->name = layerIds.back(); layer->name = layerIds[pcbNdx];
layer->properties.push_back( PROPERTY() ); layer->properties.push_back( PROPERTY() );
PROPERTY* property = &layer->properties.back(); PROPERTY* property = &layer->properties.back();
......
...@@ -110,32 +110,29 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) ...@@ -110,32 +110,29 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
namespace DSN { namespace DSN {
static int scale( double distance, UNIT_RES* aResolution )
static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution )
{ {
wxPoint ret;
double resValue = aResolution->GetValue(); double resValue = aResolution->GetValue();
double factor; // multiply this times units to get mils for Kicad. double factor; // multiply this times session value to get mils for Kicad.
switch( aResolution->GetEngUnits() ) switch( aResolution->GetEngUnits() )
{ {
default: default:
case T_inch: case T_inch:
factor = 0.001; factor = 1000.0;
break; break;
case T_mil: case T_mil:
factor = 1.0; factor = 1.0;
break; break;
case T_cm: case T_cm:
factor = 2.54/1000.0; factor = 1000.0/2.54;
break; break;
case T_mm: case T_mm:
factor = 25.4/1000.0; factor = 1000.0/25.4;
break; break;
case T_um: case T_um:
factor = 25.4; factor = 1.0/25.4;
break; break;
} }
...@@ -143,19 +140,47 @@ static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution ) ...@@ -143,19 +140,47 @@ static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution )
// used within Kicad. // used within Kicad.
factor *= 10.0; factor *= 10.0;
ret.x = (int) (factor * aPoint.x / resValue); return (int) round(factor * distance / resValue);
ret.y = (int) -(factor * aPoint.y / resValue); // negate y coord }
static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution )
{
wxPoint ret( scale( aPoint.x, aResolution ),
-scale( aPoint.y, aResolution )); // negate y
return ret; return ret;
} }
TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IOError )
{
int layerNdx = findLayerName( aPath->layer_id );
if( layerNdx == -1 )
{
wxString layerName = CONV_FROM_UTF8( aPath->layer_id.c_str() );
ThrowIOError( _("Session file uses invalid layer id \"%s\""),
layerName.GetData() );
}
TRACK* track = new TRACK( sessionBoard );
track->m_Start = mapPt( aPath->points[aPointIndex+0], routeResolution );
track->m_End = mapPt( aPath->points[aPointIndex+1], routeResolution );
track->SetLayer( pcbLayer2kicad[layerNdx] );
track->m_Width = scale( aPath->aperture_width, routeResolution );
track->SetNet( aNetcode );
return track;
}
// no UI code in this function, throw exception to report problems to the // no UI code in this function, throw exception to report problems to the
// UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) // UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
{ {
//wxASSERT( session ); sessionBoard = aBoard; // not owned here
if( !session ) if( !session )
ThrowIOError( _("Session file is missing the \"session\" section") ); ThrowIOError( _("Session file is missing the \"session\" section") );
...@@ -176,6 +201,8 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -176,6 +201,8 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
aBoard->DeleteMARKERs(); aBoard->DeleteMARKERs();
buildLayerMaps( aBoard );
// Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
// each COMPONENT, reposition and re-orient each component and put on // each COMPONENT, reposition and re-orient each component and put on
// correct side of the board. // correct side of the board.
...@@ -235,13 +262,53 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -235,13 +262,53 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
} }
} }
routeResolution = session->route->GetUnits();
// Walk the NET_OUTs and create tracks and vias anew. // Walk the NET_OUTs and create tracks and vias anew.
NET_OUTS& net_outs = session->route->net_outs; NET_OUTS& net_outs = session->route->net_outs;
for( NET_OUTS::iterator i=net_outs.begin(); i!=net_outs.end(); ++i ) for( NET_OUTS::iterator net=net_outs.begin(); net!=net_outs.end(); ++net )
{ {
// create a track or via and position it. wxString netName( CONV_FROM_UTF8( net->net_id.c_str() ) );
EQUIPOT* equipot = aBoard->FindNet( netName );
if( !equipot )
{
ThrowIOError( _("Session file uses invalid net::net_id \"%s\""),
netName.GetData() );
}
WIRES& wires = net->wires;
for( unsigned i=0; i<wires.size(); ++i )
{
WIRE* wire = &wires[i];
DSN_T shape = wire->shape->Type();
if( shape != T_path )
{
wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() );
ThrowIOError(
_("Unsupported wire shape: \"%s\" for net: \"%s\""),
LEXER::GetTokenString(shape).GetData(),
netId.GetData()
);
}
PATH* path = (PATH*) wire->shape;
for( unsigned pt=0; pt<path->points.size()-1; ++pt )
{
TRACK* track = makeTRACK( path, pt, equipot->GetNet() );
TRACK* insertAid = track->GetBestInsertPoint( aBoard );
track->Insert( aBoard, insertAid );
}
}
WIRE_VIAS& wire_vias = net->wire_vias;
for( unsigned i=0; i<wire_vias.size(); ++i )
{
// WIRE_VIA* wire_via = &wire_vias[i];
}
} }
} }
......
/**************************************************/ /**************************************************/
/* Edition des pistes */ /* Edition des pistes */
/* Routines de modification automatique de pistes */ /* Routines de modification automatique de pistes */
/**************************************************/ /**************************************************/
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "gr_basic.h"
...@@ -12,201 +12,219 @@ ...@@ -12,201 +12,219 @@
#include "protos.h" #include "protos.h"
/*********************************************************************/ /*********************************************************************/
int EraseOldTrack(WinEDA_BasePcbFrame * frame, BOARD * Pcb, wxDC * DC, int EraseOldTrack( WinEDA_BasePcbFrame* frame, BOARD* Pcb, wxDC* DC,
TRACK * pt_new_track, int nbptnewpiste) TRACK* pt_new_track, int nbptnewpiste )
/*********************************************************************/ /*********************************************************************/
/* Routine d'effacement de la piste redondante a la piste nouvellement cree
pointee par pt_new_track (nbptnewpiste segments)
la piste cree est supposee constituee de segments contigus en memoire avec: /* Routine d'effacement de la piste redondante a la piste nouvellement cree
point de depart pt_newtrack->m_Start.x,y * pointee par pt_new_track (nbptnewpiste segments)
point d'arrivee pt_newtrack->m_End.x,y *
*/ * la piste cree est supposee constituee de segments contigus en memoire avec:
* point de depart pt_newtrack->m_Start.x,y
* point d'arrivee pt_newtrack->m_End.x,y
*/
{ {
TRACK * StartTrack, * EndTrack; /* Pointeurs des segments de debut et fin TRACK* StartTrack, * EndTrack;/* Pointeurs des segments de debut et fin
(extremites) de la nouvelle piste */ * (extremites) de la nouvelle piste */
TRACK * EndNewTrack, /* Pointeur sur le dernier segment de la liste TRACK* EndNewTrack, /* Pointeur sur le dernier segment de la liste
chainee de la mouvelle piste */ * chainee de la mouvelle piste */
* pt_segm, * pt_del; * pt_segm, * pt_del;
int ii, jj, nb_segm, nbconnect; int ii, jj, nb_segm, nbconnect;
wxPoint start; /* coord du point de depart de la piste */ wxPoint start; /* coord du point de depart de la piste */
wxPoint end; /* coord du point de fin de la piste */ wxPoint end; /* coord du point de fin de la piste */
int startmasklayer, endmasklayer; /* masque couche de depart et de fin */ int startmasklayer, endmasklayer; /* masque couche de depart et de fin */
TRACK * BufDeb, *BufEnd; /* Pointeurs de debut et de fin de la zone TRACK* BufDeb, * BufEnd; /* Pointeurs de debut et de fin de la zone
des pistes equipotentielles */ * des pistes equipotentielles */
/* Reconstitution de la piste complete ( la nouvelle piste /* Reconstitution de la piste complete ( la nouvelle piste
a pu demarrer sur un segment de piste en l'air */ * a pu demarrer sur un segment de piste en l'air */
ListSetState(pt_new_track,nbptnewpiste,BUSY,OFF);
ListSetState( pt_new_track, nbptnewpiste, BUSY, OFF );
/* si la novelle piste commence par une via, il est plus sur de rechercher /* si la novelle piste commence par une via, il est plus sur de rechercher
la piste complete en utilisant le segment suivant comme reference, car * la piste complete en utilisant le segment suivant comme reference, car
une via est souvent sur un carrefour de segments, et ne caracterise pas * une via est souvent sur un carrefour de segments, et ne caracterise pas
une piste */ * une piste */
if( pt_new_track->Type() == TYPEVIA && (nbptnewpiste > 1 ) ) if( pt_new_track->Type() == TYPEVIA && (nbptnewpiste > 1 ) )
pt_new_track = (TRACK *) pt_new_track->Pnext; pt_new_track = (TRACK*) pt_new_track->Pnext;
pt_new_track = Marque_Une_Piste(frame, DC, pt_new_track, &nbptnewpiste, 0); pt_new_track = Marque_Une_Piste( frame, DC, pt_new_track, &nbptnewpiste, 0 );
EndNewTrack = pt_new_track; EndNewTrack = pt_new_track;
for( ii = 1; ii < nbptnewpiste; ii++ ) for( ii = 1; ii < nbptnewpiste; ii++ )
{ {
EndNewTrack = (TRACK *) EndNewTrack->Pnext; EndNewTrack = (TRACK*) EndNewTrack->Pnext;
} }
/* Calcul des limites de recherche des segments de piste */ /* Calcul des limites de recherche des segments de piste */
/* BufDeb pointe le 1er segment utile */ /* BufDeb pointe le 1er segment utile */
BufDeb = Pcb->m_Track->GetStartNetCode(pt_new_track->GetNet()); BufDeb = Pcb->m_Track->GetStartNetCode( pt_new_track->GetNet() );
/* BufEnd Pointe le dernier segment */ /* BufEnd Pointe le dernier segment */
BufEnd = BufDeb->GetEndNetCode(pt_new_track->GetNet()); BufEnd = BufDeb->GetEndNetCode( pt_new_track->GetNet() );
/* nettoyage des flags pour tout le net */ /* nettoyage des flags pour tout le net */
for(pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) for( pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext )
{ {
pt_del->SetState(BUSY|EDIT|CHAIN, OFF); pt_del->SetState( BUSY | EDIT | CHAIN, OFF );
if( pt_del == BufEnd ) break; if( pt_del == BufEnd )
break;
} }
/* Calcul des points limites de la nouvelle piste */ /* Calcul des points limites de la nouvelle piste */
if( ReturnEndsTrack(pt_new_track,nbptnewpiste, if( ReturnEndsTrack( pt_new_track, nbptnewpiste,
&StartTrack, &EndTrack) == 0 ) return(0); &StartTrack, &EndTrack ) == 0 )
return 0;
if( (StartTrack == NULL) || (EndTrack == NULL) ) return(0); if( (StartTrack == NULL) || (EndTrack == NULL) )
return 0;
/* Calcul des caracteristiques des points de debut et de fin */ /* Calcul des caracteristiques des points de debut et de fin */
start = StartTrack->m_Start; start = StartTrack->m_Start;
end = EndTrack->m_End; end = EndTrack->m_End;
/* Les points de depart et de fin doivent etre distincts */ /* Les points de depart et de fin doivent etre distincts */
if( start == end ) return(0); if( start == end )
return 0;
/* Determinations des couches interconnectees a ces points */ /* Determinations des couches interconnectees a ces points */
startmasklayer = StartTrack->ReturnMaskLayer(); startmasklayer = StartTrack->ReturnMaskLayer();
endmasklayer = EndTrack->ReturnMaskLayer(); endmasklayer = EndTrack->ReturnMaskLayer();
/* Il peut y avoir une via ou un pad sur les extremites: */ /* Il peut y avoir une via ou un pad sur les extremites: */
pt_segm = Fast_Locate_Via(Pcb->m_Track, NULL, start, startmasklayer); pt_segm = Fast_Locate_Via( Pcb->m_Track, NULL, start, startmasklayer );
if( pt_segm ) startmasklayer |= pt_segm->ReturnMaskLayer(); if( pt_segm )
startmasklayer |= pt_segm->ReturnMaskLayer();
if( StartTrack->start && (StartTrack->start->Type() == TYPEPAD) ) if( StartTrack->start && (StartTrack->start->Type() == TYPEPAD) )
{ /* start sur pad */ { /* start sur pad */
D_PAD * pt_pad = (D_PAD*) (StartTrack->start) ; D_PAD* pt_pad = (D_PAD*) (StartTrack->start);
startmasklayer |= pt_pad->m_Masque_Layer; startmasklayer |= pt_pad->m_Masque_Layer;
} }
pt_segm = Fast_Locate_Via(Pcb->m_Track, NULL, end, endmasklayer); pt_segm = Fast_Locate_Via( Pcb->m_Track, NULL, end, endmasklayer );
if( pt_segm ) endmasklayer |= pt_segm->ReturnMaskLayer(); if( pt_segm )
endmasklayer |= pt_segm->ReturnMaskLayer();
if( EndTrack->end && ( EndTrack->end->Type() == TYPEPAD) ) if( EndTrack->end && ( EndTrack->end->Type() == TYPEPAD) )
{ {
D_PAD * pt_pad = (D_PAD*) (EndTrack->end) ; D_PAD* pt_pad = (D_PAD*) (EndTrack->end);
endmasklayer |= pt_pad->m_Masque_Layer; endmasklayer |= pt_pad->m_Masque_Layer;
} }
/* Marquage a DELETED de la piste nouvelle (qui ne doit pas intervenir /* Marquage a DELETED de la piste nouvelle (qui ne doit pas intervenir
dans la recherche d'autres connexions) */ * dans la recherche d'autres connexions) */
ListSetState(pt_new_track, nbptnewpiste,DELETED,ON); ListSetState( pt_new_track, nbptnewpiste, DELETED, ON );
/* test : un segment doit etre connecte au point de depart car sinon /* test : un segment doit etre connecte au point de depart car sinon
il est inutile d'analyser l'autre point */ * il est inutile d'analyser l'autre point */
pt_segm = Fast_Locate_Piste(BufDeb, BufEnd, start, startmasklayer); pt_segm = Fast_Locate_Piste( BufDeb, BufEnd, start, startmasklayer );
if(pt_segm == NULL) /* Pas de piste reliee au point de depart */ if( pt_segm == NULL ) /* Pas de piste reliee au point de depart */
{ {
/* Suppression du flag DELETED */ /* Suppression du flag DELETED */
ListSetState(pt_new_track,nbptnewpiste, DELETED,OFF); ListSetState( pt_new_track, nbptnewpiste, DELETED, OFF );
return(0); return 0;
} }
/* Marquage a CHAIN des segments candidats connectes au point de fin /* Marquage a CHAIN des segments candidats connectes au point de fin
Remarque: les vias ne sont pas prises en compte car elles ne permettent * Remarque: les vias ne sont pas prises en compte car elles ne permettent
pas de definir une piste, puisque elles sont sur un carrefour */ * pas de definir une piste, puisque elles sont sur un carrefour */
for( pt_del = BufDeb, nbconnect = 0; ; ) for( pt_del = BufDeb, nbconnect = 0; ; )
{ {
pt_segm = Fast_Locate_Piste( pt_del,BufEnd, end, endmasklayer ); pt_segm = Fast_Locate_Piste( pt_del, BufEnd, end, endmasklayer );
if( pt_segm == NULL) break; if( pt_segm == NULL )
break;
if(pt_segm->Type() != TYPEVIA) if( pt_segm->Type() != TYPEVIA )
{ /* Segment trouve */ { /* Segment trouve */
if( pt_segm->GetState(CHAIN) == 0 ) if( pt_segm->GetState( CHAIN ) == 0 )
{ {
pt_segm->SetState(CHAIN,ON); pt_segm->SetState( CHAIN, ON );
nbconnect++; nbconnect++;
} }
} }
if( pt_del == BufEnd ) break; if( pt_del == BufEnd )
pt_del = (TRACK*)pt_segm->Pnext; break;
pt_del = (TRACK*) pt_segm->Pnext;
} }
if( nbconnect == 0 )
if( nbconnect == 0)
{ {
/* nettoyage des flags */ /* nettoyage des flags */
for(pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) for( pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext )
{ {
pt_del->SetState(DELETED|EDIT|CHAIN, OFF); pt_del->SetState( DELETED | EDIT | CHAIN, OFF );
if( pt_del == BufEnd ) break; if( pt_del == BufEnd )
break;
} }
return(0);
return 0;
} }
/* Marquage a EDIT de la piste nouvelle (qui ne doit pas intervenir /* Marquage a EDIT de la piste nouvelle (qui ne doit pas intervenir
dans la recherche d'autres pistes) */ * dans la recherche d'autres pistes) */
ListSetState(pt_new_track,nbptnewpiste, DELETED,OFF); ListSetState( pt_new_track, nbptnewpiste, DELETED, OFF );
ListSetState(pt_new_track,nbptnewpiste, EDIT,ON); ListSetState( pt_new_track, nbptnewpiste, EDIT, ON );
/* Examen de tous les segments marques */ /* Examen de tous les segments marques */
while( nbconnect ) while( nbconnect )
{ {
for(pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) for( pt_del = BufDeb; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext )
{ {
if( pt_del->GetState(CHAIN) ) break; if( pt_del->GetState( CHAIN ) )
if( pt_del == BufEnd ) break; break;
if( pt_del == BufEnd )
break;
} }
nbconnect--; pt_del->SetState(CHAIN,OFF); nbconnect--; pt_del->SetState( CHAIN, OFF );
pt_del = Marque_Une_Piste(frame, DC, pt_del, &nb_segm, 0); pt_del = Marque_Une_Piste( frame, DC, pt_del, &nb_segm, 0 );
/* Test si La piste marquee est redondante, c'est a dire si l'un des /* Test si La piste marquee est redondante, c'est a dire si l'un des
segments marques est connecte au point de depart de la piste nouvelle * segments marques est connecte au point de depart de la piste nouvelle
*/ */
ii = 0; pt_segm = pt_del; ii = 0; pt_segm = pt_del;
for( ;pt_segm && (ii < nb_segm); pt_segm = (TRACK*)pt_segm->Pnext, ii++) for( ; pt_segm && (ii < nb_segm); pt_segm = (TRACK*) pt_segm->Pnext, ii++ )
{ {
if( (pt_segm->GetState(BUSY)) == 0 ) break; if( ( pt_segm->GetState( BUSY ) ) == 0 )
break;
if( (pt_segm->m_Start == start) || (pt_segm->m_End == start) ) if( (pt_segm->m_Start == start) || (pt_segm->m_End == start) )
{ /* la piste marquee peut etre effacee */ { /* la piste marquee peut etre effacee */
TRACK* NextS; TRACK* NextS;
Trace_Une_Piste(frame->DrawPanel, DC, pt_del, nb_segm, GR_XOR|GR_SURBRILL); Trace_Une_Piste( frame->DrawPanel, DC, pt_del, nb_segm, GR_XOR | GR_SURBRILL );
for ( jj = 0; jj < nb_segm; jj++, pt_del = NextS) for( jj = 0; jj < nb_segm; jj++, pt_del = NextS )
{ {
NextS = (TRACK*) pt_del->Pnext; NextS = (TRACK*) pt_del->Pnext;
pt_del->DeleteStructure(); pt_del->DeleteStructure();
} }
/* nettoyage des flags */ /* nettoyage des flags */
for(pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) for( pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext )
{ {
if (pt_del->GetState(EDIT) ) if( pt_del->GetState( EDIT ) )
{ {
pt_del->SetState(EDIT, OFF); pt_del->SetState( EDIT, OFF );
pt_del->Draw(frame->DrawPanel, DC, GR_OR); pt_del->Draw( frame->DrawPanel, DC, GR_OR );
} }
pt_del->SetState(EDIT|CHAIN, OFF); pt_del->SetState( EDIT | CHAIN, OFF );
} }
return(1);
return 1;
} }
} }
/* nettoyage du flag BUSY puisque ici la piste marquee n'a pas /* nettoyage du flag BUSY puisque ici la piste marquee n'a pas
ete retenuee */ * ete retenuee */
ListSetState(pt_del, nb_segm, BUSY,OFF); ListSetState( pt_del, nb_segm, BUSY, OFF );
} }
/* nettoyage des flags */ /* nettoyage des flags */
for(pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*)pt_del->Pnext) for( pt_del = Pcb->m_Track; pt_del != NULL; pt_del = (TRACK*) pt_del->Pnext )
{ {
pt_del->SetState(DELETED|EDIT|CHAIN, OFF); pt_del->SetState( DELETED | EDIT | CHAIN, OFF );
if( pt_del == BufEnd ) break; if( pt_del == BufEnd )
break;
} }
return(0);
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment