Пример #1
0
int main()
{
	CBufferEvent::SetReadCallBack(CEasyReadHandle<CReadHandle>::ReadHandle);
	CNet* pNet = CNet::getInstance();
	if (pNet->Listen("127.0.0.1", 9995))
	{
		while (true)
		{
			pNet->Dispatch();
			Sleep(2);
		}
	}


}
Пример #2
0
bool CConnectManager::Abort ( void )
{
    // Stop the attempt
    CNet* pNet = CCore::GetSingleton ().GetNetwork ();
    pNet->StopNetwork ();
    pNet->Reset ();

    // Reset our variables
    m_strHost = "";
    m_strNick = "";
    m_strPassword = "";

    m_usPort = 0;
    m_bIsConnecting = false;
    m_tConnectStarted = 0;

    // Success
    return true;
}
Пример #3
0
bool CConnectManager::Connect ( const char* szHost, unsigned short usPort, const char* szNick, const char* szPassword )
{
    assert ( szHost );
    assert ( szNick );
    assert ( szPassword );

    // Are we already connecting?
    CNet* pNet = CCore::GetSingleton ().GetNetwork ();
    if ( m_bIsConnecting || pNet->IsConnected () )
    {
        CModManager::GetSingleton ().Unload ();
    }    

    // Is the nick valid?
    if ( !CheckNickProvided ( (char*) szNick ) )
    {
        SString strBuffer = "Connecting failed. Invalid nick provided!";
        CCore::GetSingleton ().ShowMessageBox ( "Error", strBuffer, MB_BUTTON_OK | MB_ICON_ERROR );
        return false;
    }

    // Save the nick too
    CVARS_SET ( "nick", std::string ( szNick ) );

    // Reset the network
    pNet->Reset ();
    assert ( pNet->GetServerBitStreamVersion () == 0 );

    // Set our packet handler
    pNet->RegisterPacketHandler ( CConnectManager::StaticProcessPacket, true );

    // Set our MTU size to the default
    pNet->SetMTUSize ( m_usMTUSize );

    // Try to start a network to connect
    if ( !pNet->StartNetwork ( szHost, usPort ) )
    {
        SString strBuffer ( "Connecting to %s at port %u failed!", szHost, usPort );
        CCore::GetSingleton ().ShowMessageBox ( "Error", strBuffer, MB_BUTTON_OK | MB_ICON_ERROR );
        return false;
    }

    m_strHost = szHost;
    m_strNick = szNick;
    m_strPassword = szPassword;

    // Store the port and that we're connecting
    m_usPort = usPort;
    m_bIsConnecting = true;
    m_tConnectStarted = time ( NULL );

    // Display the status box
    SString strBuffer ( "Connecting to %s:%u ...", m_strHost.c_str(), usPort );
    CCore::GetSingleton ().ShowMessageBox ( "CONNECTING", strBuffer, MB_BUTTON_CANCEL | MB_ICON_INFO, m_pOnCancelClick );

    return true;
}
Пример #4
0
bool CConnectManager::Abort ( void )
{
    // Stop the attempt
    CNet* pNet = CCore::GetSingleton ().GetNetwork ();
    pNet->StopNetwork ();
    pNet->Reset ();

    // Reset our variables
    m_strHost = "";
    m_strNick = "";
    m_strPassword = "";

    m_Address.s_addr = 0;
    m_usPort = 0;
    m_bIsConnecting = false;
    m_bIsDetectingVersion = false;
    m_tConnectStarted = 0;
    SAFE_DELETE ( m_pServerItem );

    // Success
    return true;
}
Пример #5
0
THREAD_FUN CNet::DemonLoop(LPVOID p) {
    CNet * pThis = (CNet *)p;
    s64 lTick = ::GetCurrentTimeTick();
    while (true) {
        struct iocp_event * pEvent = NULL;
        if (pThis->m_queue.read(pEvent)) {
            if (pEvent != NULL) {
                switch (pEvent->event) {
                case EVENT_ASYNC_ACCEPT:
                    pThis->DealAcceptEvent(pEvent);
                    break;
                case EVENT_ASYNC_CONNECT:
                    pThis->DealConnectEvent(pEvent);
                    break;
                case EVENT_ASYNC_RECV:
                    pThis->DealRecvEvent(pEvent);
                    break;
                case EVENT_ASYNC_SEND:
                    pThis->DealSendEvent(pEvent);
                    break;
                default:
                    break;
                }
            }
        } else if (pThis->m_stop && pThis->m_queue.IsEmpty()) {
            NET_TRACE("DemonLoop 停止工作");
            return 0;
        }

        if(!pThis->m_demo) {
            if (::GetCurrentTimeTick() - lTick > (u32)(pThis->m_nFrameMs) && pThis->m_nFrameMs != 0) {
                break;
            }
        }
    }
    return 0;
}
Пример #6
0
int _tmain(int argc, _TCHAR* argv[])
{
    oLog::initialise();
    sLog.Init( 5, LOGON_LOG );

    LOG_DETAIL( "服务器启动..." );
    CNet net;
    if ( !net.Startup() )
    {
        return -1;
    }

    CServer server;
    CClient client;


    net.Listen( 6000, &server );

    net.Connect( "127.0.0.1", 6000, &client );

    LOG_DETAIL( "%s", "welcome, the serve is started..." );

    while( 1 )
    {
        net.Process();
        server.Process();
        client.Process();

    }

    net.Clearup();

    LOG_DETAIL( "服务器退出..." );

    sLog.Close();
    oLog::release();
    return 0;
}
Пример #7
0
void CCrashDumpWriter::DumpMiniDump ( _EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation )
{
    WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump" );

    // Try to load the DLL in our directory
    HMODULE hDll = NULL;
    char szDbgHelpPath [MAX_PATH];
    if ( GetModuleFileNameA ( NULL, szDbgHelpPath, MAX_PATH ) )
    {
        char* pSlash = _tcsrchr ( szDbgHelpPath, '\\' );
        if ( pSlash )
        {
            _tcscpy ( pSlash + 1, "DBGHELP.DLL" );
            hDll = LoadLibrary ( szDbgHelpPath );
        }
    }

    // If we couldn't load the one in our dir, load any version available
    if ( !hDll )
    {
        hDll = LoadLibrary( "DBGHELP.DLL" );
    }

    if ( !hDll )
        AddReportLog( 9201, "CCrashDumpWriter::DumpMiniDump - Could not load DBGHELP.DLL" );

    // We could load a dll?
    if ( hDll )
    {
        // Grab the MiniDumpWriteDump proc address
        MINIDUMPWRITEDUMP pDump = reinterpret_cast < MINIDUMPWRITEDUMP > ( GetProcAddress( hDll, "MiniDumpWriteDump" ) );
        if ( !pDump )
            AddReportLog( 9202, "CCrashDumpWriter::DumpMiniDump - Could not find MiniDumpWriteDump" );

        if ( pDump )
        {
            // Create the file
            HANDLE hFile = CreateFile ( CalcMTASAPath ( "mta\\core.dmp" ), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
            if ( hFile == INVALID_HANDLE_VALUE )
                AddReportLog( 9203, SString( "CCrashDumpWriter::DumpMiniDump - Could not create '%s'", *CalcMTASAPath ( "mta\\core.dmp" ) ) );

            if ( hFile != INVALID_HANDLE_VALUE )
            {
                // Create an exception information struct
                _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
                ExInfo.ThreadId = GetCurrentThreadId ();
                ExInfo.ExceptionPointers = pException;
                ExInfo.ClientPointers = FALSE;

                // Write the dump
                BOOL bResult = pDump ( GetCurrentProcess(), GetCurrentProcessId(), hFile, (MINIDUMP_TYPE)( MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory ), &ExInfo, NULL, NULL );

                if ( !bResult )
                    AddReportLog( 9204, SString( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump failed (%08x)", GetLastError() ) );
                else
                    WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded" );

                // Close the dumpfile
                CloseHandle ( hFile );

                // Grab the current time
                // Ask windows for the system time.
                SYSTEMTIME SystemTime;
                GetLocalTime ( &SystemTime );

                // Create the dump directory
                CreateDirectory ( CalcMTASAPath ( "mta\\dumps" ), 0 );
                CreateDirectory ( CalcMTASAPath ( "mta\\dumps\\private" ), 0 );

                SString strModuleName = pExceptionInformation->GetModuleBaseName ();
                strModuleName = strModuleName.ReplaceI ( ".dll", "" ).Replace ( ".exe", "" ).Replace ( "_", "" ).Replace ( ".", "" ).Replace ( "-", "" );
                if ( strModuleName.length () == 0 )
                    strModuleName = "unknown";

                SString strMTAVersionFull = SString ( "%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting ( "mta-version-ext" ).SplitRight ( ".", NULL, -2 ) );
                SString strSerialPart = GetApplicationSetting ( "serial" ).substr ( 0, 5 );
                uint uiServerIP = GetApplicationSettingInt ( "last-server-ip" );
                uint uiServerPort = GetApplicationSettingInt ( "last-server-port" );
                int uiServerTime = GetApplicationSettingInt ( "last-server-time" );
                int uiServerDuration = _time32 ( NULL ) - uiServerTime;
                uiServerDuration = Clamp ( 0, uiServerDuration + 1, 0xfff );

                // Get path to mta dir
                SString strPathCode;
                {
                    std::vector < SString > parts;
                    PathConform ( CalcMTASAPath ( "" ) ).Split ( PATH_SEPERATOR, parts );
                    for ( uint i = 0 ; i < parts.size () ; i++ )
                    {
                        if ( parts[i].CompareI ( "Program Files" ) )
                            strPathCode += "Pr";
                        else
                        if ( parts[i].CompareI ( "Program Files (x86)" ) )
                            strPathCode += "Px";
                        else
                        if ( parts[i].CompareI ( "MTA San Andreas" ) )
                            strPathCode += "Mt";
                        else
                        if ( parts[i].BeginsWithI ( "MTA San Andreas" ) )
                            strPathCode += "Mb";
                        else
                            strPathCode += parts[i].Left ( 1 ).ToUpper ();
                    }
                }

                // Ensure filename parts match up with EDumpFileNameParts
                SString strFilename ( "mta\\dumps\\private\\client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp",
                                             strMTAVersionFull.c_str (),
                                             strModuleName.c_str (),
                                             pExceptionInformation->GetAddressModuleOffset (),
                                             pExceptionInformation->GetCode () & 0xffff,
                                             strPathCode.c_str (),
                                             uiServerIP,
                                             uiServerPort,
                                             uiServerDuration,
                                             strSerialPart.c_str (),
                                             SystemTime.wYear,
                                             SystemTime.wMonth,
                                             SystemTime.wDay,
                                             SystemTime.wHour,
                                             SystemTime.wMinute
                                           );

                SString strPathFilename = CalcMTASAPath ( strFilename );

                // Copy the file
                CopyFile ( CalcMTASAPath ( "mta\\core.dmp" ), strPathFilename, false );

                // For the dump uploader
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "none" );
                SetApplicationSetting ( "diagnostics", "last-dump-save", strPathFilename );

                // Try to append pool sizes info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-pools" );
                CBuffer poolInfo;
                GetPoolInfo ( poolInfo );
                AppendToDumpFile ( strPathFilename, poolInfo, 'POLs', 'POLe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-pools" );

                // Try to append d3d state info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-d3d" );
                CBuffer d3dInfo;
                GetD3DInfo ( d3dInfo );
                AppendToDumpFile ( strPathFilename, d3dInfo, 'D3Ds', 'D3De' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-d3d" );

                // Try to append crash averted stats to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-crash-averted" );
                CBuffer crashAvertedStats;
                GetCrashAvertedStats ( crashAvertedStats );
                AppendToDumpFile ( strPathFilename, crashAvertedStats, 'CASs', 'CASe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-crash-averted" );

                // Try to append log info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-log" );
                CBuffer logInfo;
                GetLogInfo ( logInfo );
                AppendToDumpFile ( strPathFilename, logInfo, 'LOGs', 'LOGe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-log" );

                // Try to append dx info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" );
                CBuffer dxInfo;
                GetDxInfo ( dxInfo );
                AppendToDumpFile ( strPathFilename, dxInfo, 'DXIs', 'DXIe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" );

                // Try to append misc info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" );
                CBuffer miscInfo;
                GetMiscInfo ( miscInfo );
                AppendToDumpFile ( strPathFilename, miscInfo, 'MSCs', 'MSCe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" );

                // Try to append memory info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-mem" );
                CBuffer memInfo;
                GetMemoryInfo ( memInfo );
                AppendToDumpFile ( strPathFilename, memInfo, 'MEMs', 'MEMe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-mem" );

                // Try to logfile.txt to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-logfile" );
                CBuffer logfileContent;
                logfileContent.LoadFromFile( CalcMTASAPath( PathJoin( "mta", "logs", "logfile.txt" ) ) );
                AppendToDumpFile ( strPathFilename, logfileContent, 'LOGs', 'LOGe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-logfile" );

                // Try to report.log to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-report" );
                CBuffer reportLogContent;
                reportLogContent.LoadFromFile( PathJoin( GetMTADataPath(), "report.log" ) );
                AppendToDumpFile ( strPathFilename, reportLogContent, 'REPs', 'REPe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-report" );
            }
        }

        // Free the DLL again
        FreeLibrary ( hDll );
    }

    // Auto-fixes

    // Check if crash was in volumetric shadow code
    if ( ms_uiInCrashZone == 1 || ms_uiInCrashZone == 2 )
    {
        CVARS_SET( "volumetric_shadows", false );
        CCore::GetSingleton().SaveConfig();
        AddReportLog( 9205, "Disabled volumetric shadows" );
    }

    CNet* pNet = CCore::GetSingleton().GetNetwork();
    if ( pNet )
        pNet->PostCrash();    
}
Пример #8
0
bool CConnectManager::Connect ( const char* szHost, unsigned short usPort, const char* szNick, const char* szPassword, bool bNotifyServerBrowser, bool bForceInternalHTTPServer )
{
    assert ( szHost );
    assert ( szNick );
    assert ( szPassword );

    m_bNotifyServerBrowser = bNotifyServerBrowser;

    // Hide certain questions
    CCore::GetSingleton ().GetLocalGUI ()->GetMainMenu ()->GetQuestionWindow ()->OnConnect ();

    // Hide the server queue
    CServerInfo::GetSingletonPtr()->Hide( );

    // Save the browser state
    CServerBrowser::GetSingletonPtr()->SaveOptions( );

    // Are we already connecting?
    CNet* pNet = CCore::GetSingleton ().GetNetwork ();
    if ( m_bIsConnecting || pNet->IsConnected () )
    {
        CModManager::GetSingleton ().Unload ();
    }    

    // Is the nick valid?
    if ( !CheckNickProvided ( (char*) szNick ) )
    {
        SString strBuffer = _("Connecting failed. Invalid nick provided!");
        CCore::GetSingleton ().ShowMessageBox ( _("Error")+_E("CC20"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR ); // Invalid nick provided
        return false;
    }

    // Save the nick too
    CVARS_SET ( "nick", std::string ( szNick ) );

    // Reset the network
    pNet->Reset ();
    assert ( pNet->GetServerBitStreamVersion () == 0 );

    // Save input
    m_strHost = szHost;
    m_strNick = szNick;
    m_strPassword = szPassword;
    m_Address.s_addr = 0;
    m_usPort = usPort;
    m_bForceInternalHTTPServer = bForceInternalHTTPServer;
    m_bSave = true;

    m_strLastHost = m_strHost;
    m_usLastPort = m_usPort;
    m_strLastPassword = m_strPassword;

    // Parse host into a server item
    if ( !CServerListItem::Parse ( m_strHost.c_str(), m_Address ) )
    {
        SString strBuffer = _("Connecting failed. Invalid host provided!");
        CCore::GetSingleton ().ShowMessageBox ( _("Error")+_E("CC21"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR ); // Invalid host provided
        return false;
    }

    // No connect if disk space is low
    if ( !CCore::GetSingleton ().CheckDiskSpace () )
        return false;

    // Set our packet handler
    pNet->RegisterPacketHandler ( CConnectManager::StaticProcessPacket );

    // Try to start a network to connect
    SString strAddress = inet_ntoa ( m_Address );
    if ( m_usPort && !pNet->StartNetwork ( strAddress, m_usPort, CVARS_GET_VALUE < bool > ( "packet_tag" ) ) )
    {
        SString strBuffer ( _("Connecting to %s at port %u failed!"), m_strHost.c_str (), m_usPort );
        CCore::GetSingleton ().ShowMessageBox ( _("Error")+_E("CC22"), strBuffer, MB_BUTTON_OK | MB_ICON_ERROR ); // Failed to connect
        return false;
    }

    m_bIsConnecting = true;
    m_tConnectStarted = time ( NULL );

    // Load server password
    if ( m_strPassword.empty () )
        m_strPassword = CServerBrowser::GetSingletonPtr()->GetServerPassword ( m_strHost + ":" + SString ( "%u", m_usPort ) );

    // Start server version detection
    SAFE_DELETE ( m_pServerItem );
    m_pServerItem = new CServerListItem ( m_Address, m_usPort );
    m_pServerItem->m_iTimeoutLength = 2000;
    m_bIsDetectingVersion = true;

    // Display the status box
    SString strBuffer ( _("Connecting to %s:%u ..."), m_strHost.c_str(), m_usPort );
    CCore::GetSingleton ().ShowMessageBox ( _("CONNECTING"), strBuffer, MB_BUTTON_CANCEL | MB_ICON_INFO, m_pOnCancelClick );
    WriteDebugEvent( SString( "Connecting to %s:%u ...", m_strHost.c_str(), m_usPort ) );
    return true;
}
Пример #9
0
void  CRBox::mbkload (MBK::CFig *mbkfig
                     , int z
                     , int zup
                     , int rtype
                     , bool halfpitch
                     , bool xhalfpitch
                     , bool yhalfpitch
                     , bool rotate
                     , set<string>* subNetList )
{
    MBK::MIns::iterator   itIns, endInstances, endOrphans;
  MBK::MLosig::iterator   endSig;
  MBK::MLosig::iterator   sig;
                   long   mX, mY, mZ, x, y, zz, xadjust, yadjust, yoffsetslice;
                   long   XRW1, YRW1, XRW2, YRW2;
                   bool   use_global;
                   long   northPad, southPad, eastPad, westPad;
                   long   xoffsettrack, yoffsettrack;
        MBK::chain_list  *pChain;
        MBK::locon_list  *pLocon;
        MBK::phcon_list  *pPhcon;
        MBK::losig_list  *pSig;
        MBK::phseg_list  *pSeg, flatSeg;
        MBK::phvia_list  *pVIA;
        MBK::phfig_list  *pModel;
            MBK::CXRect  *rect;
              MBK::CIns  *pIns;
                   CNet  *pNet;
                 string   sig_name, term_name, ins_name;
      CDRGrid::iterator   coord;
                  CNode  *node;


  cmess1 << "\n";
  cmess1 << "  o  Loading design into grid...\n";

  ischip       = false;
  fig          = mbkfig;
  endInstances = fig->instances.end ();
  endOrphans   = fig->orphans.end   ();
  endSig       = fig->lofig.signals.end ();

  northPad     = 0;
  southPad     = 0;
  westPad      = 0;
  eastPad      = 0;
  xoffsettrack = 0;
  yoffsettrack = 0;

  // Half pitch offset.
  if ( halfpitch ) {
    xoffsettrack = D::X_GRID / 2;
    yoffsettrack = D::Y_GRID / 2;
  }
  else if ( xhalfpitch ) {
    xoffsettrack = D::X_GRID / 2;
  }
  else if ( yhalfpitch ) {
    yoffsettrack = D::Y_GRID / 2;
  }

  // Search for pads.
  for (itIns = fig->instances.begin(); itIns != endInstances; itIns++) {
    pModel = itIns->second->getmodel ();

    if ( MBK::IsPxLib(pModel) ) {
      switch ( itIns->second->phins->TRANSF ) {
        case NOSYM:
          ischip = true;
          if ( northPad == 0 ) {
            cmess2 << "     o  North pad found.\n";
            northPad = pModel->YAB2 - pModel->YAB1 - MBK::SCALE(15);
          }
          break;
        case SYM_Y:
          ischip = true;
          if ( southPad == 0 ) {
            cmess2 << "     o  South pad found.\n";
            southPad = pModel->YAB2 - pModel->YAB1 - MBK::SCALE(15);
          }
          break;
        case ROT_P:
          ischip = true;
          if ( eastPad == 0 ) {
            cmess2 << "     o  East pad found.\n";
            eastPad = pModel->YAB2 - pModel->YAB1 - MBK::SCALE(15);
          }
          break;
        case SY_RP:
          ischip = true;
          if ( westPad == 0 ) {
            cmess2 << "     o  West pad found.\n";
            westPad = pModel->YAB2 - pModel->YAB1 - MBK::SCALE(15);
          }
          break;
        default:
          cerr << hwarn ("")
               << "  Pad " << itIns->second->phins->INSNAME
               << " have an invalid orientation.\n";
          break;
      }
    }
  }


  //southPad = northPad = westPad = eastPad = MBK::SCALE(50);
  //westPad = MBK::SCALE(100);


  // Default Routing Widow size : the AB.
  XRW1 = fig->XAB1 () + westPad;
  YRW1 = fig->YAB1 () + southPad;
  XRW2 = fig->XAB2 () - eastPad;
  YRW2 = fig->YAB2 () - northPad;

  // Find the a seed cell (one either from sxlib or dp_sxlib to
  // track adjust the grid).
  for (itIns = fig->instances.begin(); ; itIns++) {
    if (itIns == endInstances) {
      xadjust      = xoffsettrack;
      yadjust      = yoffsettrack;
      yoffsetslice = 0;
      cout << hwarn ("")
           << "  Unable to found a seed cell (i.e. belonging to either\n"
           << "  sxlib or dp_sxlib) grid could be misplaced.\n";
      break;
    }

    pModel = itIns->second->getmodel ();

    if ( !MBK::IsPxLib(pModel) ) {
      cmess2 << "     o  Using seed cell \"" << itIns->first
             << "\" (model \"" << pModel->NAME << "\").\n";
      xadjust      = abs((itIns->second->phins->XINS - XRW1) % D::X_GRID ) + xoffsettrack;
      yadjust      = abs((itIns->second->phins->YINS - YRW1) % D::Y_GRID ) + yoffsettrack;
      yoffsetslice = abs((itIns->second->phins->YINS - YRW1) % D::Y_SLICE) + YRW1;

      break;
    }
  }
  
  xoffsetgrid = XRW1 + xadjust;
  yoffsetgrid = YRW1 + yadjust;

  cmess2 << "     o  Grid offset : ("
         << MBK::UNSCALE(xoffsetgrid) << ","
         << MBK::UNSCALE(yoffsetgrid) << ")"
         << " [adjust ("
         << MBK::UNSCALE(xadjust) << ","
         << MBK::UNSCALE(yadjust) << ")]\n";

  // Compute the routing grid size.
  mX = (XRW2 - XRW1) / D::X_GRID + ((xadjust==0)?1:0);
  mY = (YRW2 - YRW1) / D::Y_GRID + ((yadjust==0)?1:0);
  mZ = z;


  // Is the design a complete chip.
  if (ischip)
    cmess2 << "     o  Design have pads, treated as a complete chip.\n";


  // Selecting the whether to use global routing.
  use_global = (mX + mY) > (2 * D::GLOBAL_HP);
  if (rtype == D::ROUTING_CHOOSE) {
    if (use_global) {
      cmess2 << "     o  Big design, global routing enabled.\n";
      rglobal = true;

      if (z < 5) {
        cmess2 << "        - Forcing 4 routing layers.\n";
        mZ = 5;
      }
    } else {
      cmess2 << "     o  Small design, global routing disabled.\n";
      rglobal = false;
    }
  } else {
    if (rtype == D::ROUTING_GLOBAL) {
      rglobal = true;
      if (!use_global) {
        cout << hwarn ("")
             << "  You have enabled global routing on a small design,\n"
             << "  this will waste upper routing layers.\n";
      }
    }
    if (rtype == D::ROUTING_LOCAL ) {
      rglobal = false;
      if (use_global) {
        cout << hwarn ("")
             << "  You have disabled global routing on a big design,\n"
             << "  this will slow down the routing.\n";
      }
    }
  }


  cmess2 << "     o  Allocating grid size ["
         << mX << "," << mY << "," << mZ << "].\n";

  float  mXf      = mX;
  float  mYf      = mY;
  float  mZf      = mZ;
  float  overflow = INT_MAX;

  if ( mXf * mYf * mZf >= overflow ) {
    cerr << herr("")
         << "  Internal routing grid capacity exceeded :\n"
         << "  More than " << INT_MAX << "nodes (INT_MAX).\n";
    throw except_done();
  }

  // Allocating the routing grid.
  drgrid = new CDRGrid (xoffsetgrid, yoffsetgrid, mX, mY, mZ, zup);


  rect = new MBK::CXRect (drgrid);


  cmess2 << "     o  Loading external terminals.\n";

  // Browse layout for terminals.
  for (pPhcon = fig->phfig.fig->PHCON; pPhcon != NULL; pPhcon = pPhcon->NEXT) {
    if (fig->lofig.signals.find(pPhcon->NAME) == endSig) {
      cerr << hwarn ("")
           << "  The terminal \"" << pPhcon->NAME << "\" at ("
           << MBK::UNSCALE (pPhcon->XCON) << ","
           << MBK::UNSCALE (pPhcon->YCON) << ") layer "
           << MBK::layer2a (pPhcon->LAYER) << "\n"
           << "  do not not belong to any logical signal : ignored.\n";

      continue;
    }

    pNet = getnet (pPhcon->NAME);

    term_name  = "external.";
    term_name += pPhcon->NAME;

    flatSeg.X1    = pPhcon->XCON;
    flatSeg.Y1    = pPhcon->YCON;
    flatSeg.X2    = pPhcon->XCON;
    flatSeg.Y2    = pPhcon->YCON;
    flatSeg.WIDTH = MBK::env.layer2width (pPhcon->LAYER);
    flatSeg.LAYER = pPhcon->LAYER;
    flatSeg.NAME  = pPhcon->NAME;

    rect->setSeg  (flatSeg);

    if ( rect->isInGrid() ) {
      pNet->newaccess ( term_name
                      , rect->grid
                      , MBK::env.layer2z (pPhcon->LAYER)
                      );
    } else {
      cerr << hwarn ("")
           << "  The terminal \"" << pPhcon->NAME << "\" at ("
           << MBK::UNSCALE (pPhcon->XCON) << ","
           << MBK::UNSCALE (pPhcon->YCON) << ") layer "
           << MBK::layer2a (pPhcon->LAYER) << "\n"
           << "  is outside the routing grid : ignored.\n";
    }

  }


  cmess2 << "     o  Finding obstacles.\n";


  // Browse father for obstacles (powers are obstacles) and already
  // routed or partially routed signals.
  for (pSeg = fig->phfig.fig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) {
    // There must not be obstacle in the father!
    if (MBK::isobs (pSeg->LAYER)) {
      cerr << hwarn ("")
           << "  An obstacle has been found at design top level, ignored.\n";

      continue;
    }

    // Power grid.
    if (MBK::ISVDD (pSeg->NAME) || MBK::ISVSS (pSeg->NAME)) {
      if (pSeg->LAYER != MBK::CALU1) {
        rect->setSeg (*pSeg);
        
        //cerr << "+ Top power obstacle\n" << rect;

        if ( rect->isInGrid() )
          drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));
      }

      continue;
    }

    // Unnamed signals : ignored.
    if (pSeg->NAME == NULL) {
      cerr << hwarn ("")
           << "  An unnamed segment has been found at design top level, ignored.\n";

      continue;
    }

    // Partially routed signals.
    sig = fig->lofig.signals.find(pSeg->NAME);
    if ( sig == endSig) {
      cerr << hwarn ("")
           << "  The segment \"" << pSeg->NAME << "\" at ("
           << MBK::UNSCALE (pSeg->X1) << ","
           << MBK::UNSCALE (pSeg->Y1) << ") ("
           << MBK::UNSCALE (pSeg->X2) << ","
           << MBK::UNSCALE (pSeg->Y2) << ") layer "
           << MBK::layer2a (pSeg->LAYER) << "\n"
           << "  do not not belong to any logical signal : ignored.";

      continue;
    }

    pNet = getnet (getsigname(sig->second));
    if ( !pNet->fixed ) {
      cmess2 << "     o  Signal " << pNet->name << " is assumed to be routed.\n";
      pNet->fixed = true;
    }

    rect->setSeg  (*pSeg);

    if ( rect->isInGrid() ) {
      //pNet->newaccess ( pSeg->NAME
      //                , rect->grid
      //                , MBK::env.layer2z (pSeg->LAYER)
      //                );
      //cerr << "+ Net obstacle\n" << rect;
      drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));
    } else {
      cerr << hwarn ("")
           << "  The segment \"" << pSeg->NAME << "\" at ("
           << MBK::UNSCALE (pSeg->X1) << ","
           << MBK::UNSCALE (pSeg->Y1) << ") ("
           << MBK::UNSCALE (pSeg->X2) << ","
           << MBK::UNSCALE (pSeg->Y2) << ") layer "
           << MBK::layer2a (pSeg->LAYER) << "\n"
           << "  is outside the routing grid : ignored.";
    }
  }


  // Browse for obstacle VIAs.
  for (pVIA = fig->phfig.fig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) {
    // Only power VIAs must be obstacles.
    if ( (! MBK::ISVDD (pVIA->NAME)) && (! MBK::ISVSS (pVIA->NAME))) {
      pNet = getnet (pVIA->NAME);
      if ( pNet && !pNet->fixed ) continue;
    }

    for (x = 0; x < 2; x++) {
      switch (x) {
        case 0: flatSeg.LAYER = MBK::topVIALayer    (pVIA->TYPE); break;
        case 1: flatSeg.LAYER = MBK::bottomVIALayer (pVIA->TYPE); break;
      }

      if (flatSeg.LAYER == MBK::CALU1) continue;

      long  xVIAshrink = 0;
      if (pVIA->DX) { xVIAshrink = (pVIA->DX - MBK::SCALE(3)) / 2; }
      flatSeg.X1    = pVIA->XVIA - xVIAshrink;
      flatSeg.X2    = pVIA->XVIA + xVIAshrink;
      flatSeg.Y1    = pVIA->YVIA;
      flatSeg.Y2    = pVIA->YVIA;
      flatSeg.WIDTH = pVIA->DY;

      rect->setSeg (flatSeg);

      //cerr << "+ Top VIA obstacle ("
      //     << MBK::UNSCALE(pVIA->XVIA) << ","
      //     << MBK::UNSCALE(pVIA->YVIA) << ") "
      //     << MBK::layer2a(flatSeg.LAYER) << endl;
      //cerr << rect;

      if ( rect->isInGrid() )
        drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (flatSeg.LAYER));
    }
  }


  // Browse instances & orphans for obstacles.
  for (itIns = fig->instances.begin(); ; itIns++) {
    if (itIns == endInstances) itIns = fig->orphans.begin ();
    if (itIns == endOrphans  ) break;

    pModel = itIns->second->getmodel ();

    cdebug << "+          - \"" << itIns->first
           << "\" (model \"" << pModel->NAME << "\").\n";


    // Find the obstacles in the current instance :
    // 1. - TALUx segments.
    // 2. - Power Terminals (vdd & vss), in CALUx layers & not CALU1.
    for (pSeg = pModel->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) {
      if (   MBK::isobs (pSeg->LAYER)
          || ((   MBK::ISVDD (pSeg->NAME)
               || MBK::ISVSS (pSeg->NAME)) && MBK::isCALU (pSeg->LAYER)
                                           && (pSeg->LAYER != MBK::CALU1))) {
        itIns->second->flatseg (flatSeg, *pSeg);
        rect->setSeg (flatSeg);

        //cerr << "+ Instance obstacle (" << flatSeg.X1 << "," << flatSeg.Y1 << ")"
        //     << MBK::layer2a(flatSeg.LAYER) << endl;

        if ( rect->isInGrid() )
          drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));

        if ( !MBK::ISVDD (pSeg->NAME) && !MBK::ISVSS (pSeg->NAME) )
          fig->addphseg ( flatSeg, true, ischip );
      }
    }
  }


  cmess2 << "     o  Loading nets into grid.\n";

  // Process the signals.
  for (pSig = fig->LOSIG (); pSig != NULL; pSig = pSig->NEXT) {
    sig_name = MBK::getsigname (pSig);

    cdebug << "+          - Signal \"" << sig_name << "\".\n";

    // Do not process power nets.
    // Temporary disabled.
    //if (   (MBK::ISVDD ((char*)sig_name.c_str ()) != 0)
    //    || (MBK::ISVSS ((char*)sig_name.c_str ()) != 0)) continue;

    // In the case of external terminals, override the signal name by
    // the terminal name.
    pChain = (MBK::chain_list*)(MBK::getptype (pSig->USER, LOFIGCHAIN)->DATA);
    for (; pChain != NULL; pChain = pChain->NEXT) {
      pLocon = (MBK::locon_list *)(pChain->DATA);

      if (pLocon->TYPE == EXTERNAL) {
        sig_name = pLocon->NAME;
        break;;
      }
    }

    pNet = getnet (sig_name);

    // Process each terminal of the signal.
    pChain = (MBK::chain_list*)(MBK::getptype (pSig->USER, LOFIGCHAIN)->DATA);

    for (; pChain != NULL; pChain = pChain->NEXT) {
      pLocon = (MBK::locon_list *)(pChain->DATA);

      if (pLocon->TYPE == EXTERNAL) {
        pNet->external = true;

        continue;
      }

      ins_name  = ((MBK::loins_list*)(pLocon->ROOT))->INSNAME;
      pIns      = fig->instances[ins_name];

      term_name = ins_name + "." + pLocon->NAME;
      cdebug << "+             I.T : " << term_name << " " << pIns->model->NAME << ".\n";

      // Find physical segments / CA of the terminal.
      for (pSeg = pIns->model->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) {
        if (!MBK::isCALU (pSeg->LAYER)) continue;
        if (pLocon->NAME != pSeg->NAME) continue;

        pIns->flatseg (flatSeg, *pSeg);
        rect->setSeg  (flatSeg);

        if ( MBK::IsPxLib(pIns->model) &&
             ( (pLocon->NAME == MBK::namealloc("pad" )) ||
               (pLocon->NAME == MBK::namealloc("vddi")) || 
               (pLocon->NAME == MBK::namealloc("vssi")) || 
               (pLocon->NAME == MBK::namealloc("vdde")) || 
               (pLocon->NAME == MBK::namealloc("vsse")) ) ) {
          flatSeg.NAME = (char*)sig_name.c_str();
          fig->addphseg (flatSeg,true,false);
          continue;
        }

        if (   (MBK::ISVDD ((char*)sig_name.c_str ()) != 0)
            || (MBK::ISVSS ((char*)sig_name.c_str ()) != 0)) continue;

        if (rect->isInGrid()) {
          if ( pNet->fixed ) {
            drgrid->nodes->obstacle (rect->grid, MBK::env.layer2z (pSeg->LAYER));
          } else {
            pNet->newaccess ( term_name
                            , rect->grid
                            , MBK::env.layer2z (pSeg->LAYER)
                            );
          }
        } else {
          //if ( MBK::IsPxLib(pModel) ) {
          //  flatSeg.NAME = (char*)sig_name.c_str();
          //  fig->addphseg (flatSeg,true,false);
          //} else {
            cerr << hwarn ("")
                 << "  The connector segment \"" << pSeg->NAME << "\" at ("
                 << MBK::UNSCALE (pSeg->X1) << ","
                 << MBK::UNSCALE (pSeg->Y1) << ") ("
                 << MBK::UNSCALE (pSeg->X2) << ","
                 << MBK::UNSCALE (pSeg->Y2) << ") layer "
                 << MBK::layer2a (pSeg->LAYER) << "\n"
                 << "  is outside of the grid : ignored.";
          }
        //}
      }
    } // End of "pChain" (terminal) loop.

    // Reorder terminals (nearest).
    pNet->order     ();
    pNet->lockalone (rglobal);
    
    cdebug << "+            " << pNet->bb << ".\n";
  } // End of "pSig" (signal) loop.

  // Restrict routed nets to the subNetList.
  if ( subNetList ) {
    for ( MNet::iterator it=nets.begin() ; it != nets.end() ; it++ ) {
      if ( subNetList->find(it->first) != subNetList->end() ) {
        cmess2 << "     o  Restricting nets to route.\n";
        cmess2 << "        - \"" << it->first << "\".\n";
      } else
        it->second->fixed = true;
    }
  }


  // Allocate the net scheduler.
  cmess2 << "     o  Allocating the net scheduler.\n";
  netsched  = new CASimple (&nets, drgrid);


  // Rebuild the power grid from the instances.
  if ( !ischip ) {
    cmess2 << "     o  Reading power grid.\n";
    powers[MBK::CALU1] = new MBK::CPowers ( fig
                                          , xadjust - xoffsettrack
                                          , yoffsetslice
                                          , C_HORIZONTAL
                                          , MBK::ALU1
                                          , D::WIDTH_VDD
                                          );
  }


  // Forbid the use of the edges of the routing box (only allow
  // peripheral terminals).
  coord = drgrid->origin;

  // Left & Right vertical edges.
  if ( xadjust == 0 ) {
    for (x = 0; x < mX; x += mX - 1) {
      for (y = 0; y < mY; y++) {
        for (zz = 1; zz < mZ; zz++) {
          node = &( coord.set(x,y,zz).node() );
          
          if ( !node->terminal() ) node->data.obstacle = true;
        }
      }
    }
  }

  // Bottom & top horizontal edges.
  if ( yadjust == 0 ) {
    for (y = 0; y < mY; y += mY - 1) {
      for (x = 0; x < mX; x++) {
        for (zz = 1; zz < mZ; zz++) {
          node = &( coord.set(x,y,zz).node() );
          
          if ( !node->terminal() ) node->data.obstacle = true;
        }
      }
    }
  }

  // On routing level above zupper (ALU4), use only half of the tracks.
  for (zz = zup; zz < mZ; zz++) {
    switch ((zz+rotate) % 2) {
      case 0:
        // Vertical tracks.
        for (x = 2; x < mX; x += 2) {
          for (y = 1; y < mY - 1; y++) {
            node = &( coord.set(x,y,zz).node() );

            if ( !node->terminal() ) node->data.obstacle = true;
          }
        }
        break;
      case 1:
        // Horizontal tracks.
        for (y = 2; y < mY; y += 2) {
          for (x = 1; x < mX; x++) {
            node = &( coord.set(x,y,zz).node() );
            if ( !node->terminal() ) node->data.obstacle = true;
          }
        }
        break;
    }
  }


  // This flag ensure that a figure has been successfully loaded.
  loaded = true;


  delete rect;
}
CRBox::CRBox (int rtype, bool debug)
{
  int     X, Y, Z;
  CNet   *pNet;
  CTerm  *pTerm;
  //CCoord  coord;


  cdebug << "ENTERING: CRBox::CRBox ()\n";
  X = 10 ; //10;
  Y = 15 ; //15;
  Z = 3;


  // Creating routing matrix.
  cdebug << "  Routing matrix size := (10, 15, 5)\n";

  drgrid = new CDRGrid (0, 0, X, Y, Z, 4);


  // Adding signal "sig_one".
  cdebug << "  Creating net \"sig_one\".\n";
  pNet = getnet ("sig_one");


  // Adding terminal "i0" of "sig_one".
  cdebug << "    Adding terminal \"i0\".\n";
  cdebug << "      Adding CA \"(0,0,0)\".\n";
  pNet->newaccess ("i0", 0, 0, 0);
  //cdebug << "      Adding CA \"(0,0,1)\".\n";
  //nets["sig_one"]->newaccess ("i0", 0, 0, 1);
  //cdebug << "      Adding CA \"(0,1,1)\".\n";
  //nets["sig_one"]->newaccess ("i0", 0, 1, 1);


  // Adding terminal "i1" of "sig_one".
  cdebug << "    Adding terminal \"i1\".\n";
  cdebug << "      Adding CA \"(9,0,0)\".\n";
  pNet->newaccess ("i1", 9, 0, 0);


  // Adding terminal "o" of "sig_one".
  cdebug << "    Adding terminal \"o\".\n";
  //cdebug << "      Adding CA \"(5,10,0)\".\n";
  //nets["sig_one"]->newaccess ("o", 5, 10, 0);

  //cdebug << "      Adding CA \"(7,12,0)\".\n";
  //nets["sig_one"]->newaccess ("o", 7, 12, 0);


  // Adding signal "sig_two".
  //cdebug << "  Creating net \"sig_two\".\n";
  //nets["sig_two"] = new CNet ("sig_two");


  // Adding terminal "i0" of "sig_two".
  //cdebug << "    Adding terminal \"i0\".\n";
  //cdebug << "      Adding CA \"(4,1,0)\".\n";
  //nets["sig_two"]->newaccess ("i0", 4, 1, 0);


  // Adding terminal "o" of "sig_two".
  //cdebug << "    Adding terminal \"o\".\n";
  //cdebug << "      Adding CA \"(4,11,0)\".\n";
  //nets["sig_two"]->newaccess ("o", 4, 11, 0);


  //{
  //  int j;

  //  for (j = 0; j < Y; j++) {
  //    (*::grid)[coord.set (160, j, 1)]->data.pri = 128;
  //    (*::grid)[coord.set (160, j, 2)]->data.pri = 128;
  //  } 
  //}
  // Putting obstacles.
  //(*::grid)[coord.set (5, 5, 2)]->data.pri = 128;
  //(*::grid)[coord.set (6, 5, 2)]->data.pri = 128;
  //(*::grid)[coord.set (7, 5, 2)]->data.pri = 128;
  //(*::grid)[coord.set (8, 5, 2)]->data.pri = 128;
  //(*::grid)[coord.set (9, 5, 2)]->data.pri = 128;


  netsched  = new CASimple (&nets, drgrid);

  cdebug << "EXITING: CRBox::CRBox ()\n";
}