// Release the Layer-3 interface void L3FreeInterface(L3IF *f) { UINT i; L3PACKET *p; PKT *pkt; // Validate arguments if (f == NULL) { return; } for (i = 0;i < LIST_NUM(f->ArpTable);i++) { L3ARPENTRY *a = LIST_DATA(f->ArpTable, i); Free(a); } ReleaseList(f->ArpTable); f->ArpTable = NULL; for (i = 0;i < LIST_NUM(f->ArpWaitTable);i++) { L3ARPWAIT *w = LIST_DATA(f->ArpWaitTable, i); Free(w); } ReleaseList(f->ArpWaitTable); f->ArpWaitTable = NULL; while (p = GetNext(f->IpPacketQueue)) { Free(p->Packet->PacketData); FreePacket(p->Packet); Free(p); } ReleaseQueue(f->IpPacketQueue); f->IpPacketQueue = NULL; for (i = 0;i < LIST_NUM(f->IpWaitList);i++) { L3PACKET *p = LIST_DATA(f->IpWaitList, i); Free(p->Packet->PacketData); FreePacket(p->Packet); Free(p); } ReleaseList(f->IpWaitList); f->IpWaitList = NULL; while (pkt = GetNext(f->SendQueue)) { Free(pkt->PacketData); FreePacket(pkt); } ReleaseQueue(f->SendQueue); f->SendQueue = NULL; }
// Release the SSTP server void FreeSstpServer(SSTP_SERVER *s) { // Validate arguments if (s == NULL) { return; } TubeDisconnect(s->TubeRecv); TubeDisconnect(s->TubeSend); WaitThread(s->PPPThread, INFINITE); ReleaseThread(s->PPPThread); while (true) { BLOCK *b = GetNext(s->RecvQueue); if (b == NULL) { break; } FreeBlock(b); } while (true) { BLOCK *b = GetNext(s->SendQueue); if (b == NULL) { break; } FreeBlock(b); } ReleaseQueue(s->RecvQueue); ReleaseQueue(s->SendQueue); ReleaseSockEvent(s->SockEvent); FreeInterruptManager(s->Interrupt); ReleaseCedar(s->Cedar); ReleaseTube(s->TubeSend); ReleaseTube(s->TubeRecv); Free(s); }
extern Bool EnQueue( Queue *que, void *data) { QueueElement *el; Bool rc; ENTER_FUNC; if ( ( que != NULL ) && ( LockQueue(que) == 0 ) ) { el = New(QueueElement); el->data = data; el->prev = que->tail; el->next = NULL; if ( que->tail == NULL ) { que->head = el; } else { que->tail->next = el; } que->tail = el; que->length++; UnLockQueue(que); ReleaseQueue(que); rc = TRUE; } else { rc = FALSE; } LEAVE_FUNC; return (rc); }
// Release void NullPaFree(SESSION *s) { // Validate arguments NULL_LAN *n; BLOCK *b; if (s == NULL || (n = s->PacketAdapter->Param) == NULL) { return; } n->Halt = true; Set(n->Event); WaitThread(n->PacketGeneratorThread, INFINITE); ReleaseThread(n->PacketGeneratorThread); LockQueue(n->PacketQueue); { while (b = GetNext(n->PacketQueue)) { FreeBlock(b); } } UnlockQueue(n->PacketQueue); ReleaseQueue(n->PacketQueue); ReleaseCancel(n->Cancel); ReleaseEvent(n->Event); s->PacketAdapter->Param = NULL; Free(n); }
// Release the packet adapter void LinkPaFree(SESSION *s) { LINK *k; // Validate arguments if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return; } // Stop the server session StopSession(k->ServerSession); ReleaseSession(k->ServerSession); // Release the transmission packet queue LockQueue(k->SendPacketQueue); { BLOCK *block; while (block = GetNext(k->SendPacketQueue)) { FreeBlock(block); } } UnlockQueue(k->SendPacketQueue); ReleaseQueue(k->SendPacketQueue); }
// パケットアダプタの解放 void LinkPaFree(SESSION *s) { LINK *k; // 引数チェック if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return; } // サーバーセッションの停止 StopSession(k->ServerSession); ReleaseSession(k->ServerSession); // 送信パケットキューの解放 LockQueue(k->SendPacketQueue); { BLOCK *block; while (block = GetNext(k->SendPacketQueue)) { FreeBlock(block); } } UnlockQueue(k->SendPacketQueue); ReleaseQueue(k->SendPacketQueue); }
// Release the packet adapter void LinkPaFree(SESSION *s) { LINK *k; // Validate arguments if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL) { return; } CedarAddQueueBudget(k->Cedar, -((int)k->LastServerConnectionReceivedBlocksNum)); k->LastServerConnectionReceivedBlocksNum = 0; // Stop the server session StopSession(k->ServerSession); ReleaseSession(k->ServerSession); // Release the transmission packet queue LockQueue(k->SendPacketQueue); { BLOCK *block; while (block = GetNext(k->SendPacketQueue)) { FreeBlock(block); } } UnlockQueue(k->SendPacketQueue); ReleaseQueue(k->SendPacketQueue); k->CurrentSendPacketQueueSize = 0; }
// Release the UDP acceleration function void FreeUdpAccel(UDP_ACCEL *a) { // Validate arguments if (a == NULL) { return; } while (true) { BLOCK *b = GetNext(a->RecvBlockQueue); if (b == NULL) { break; } FreeBlock(b); } ReleaseQueue(a->RecvBlockQueue); ReleaseSock(a->UdpSock); if (a->IsInCedarPortList) { LockList(a->Cedar->UdpPortList); { DelInt(a->Cedar->UdpPortList, a->MyPort); } UnlockList(a->Cedar->UdpPortList); } // Release of NAT-T related a->NatT_Halt = true; Set(a->NatT_HaltEvent); if (a->NatT_GetIpThread != NULL) { WaitThread(a->NatT_GetIpThread, INFINITE); ReleaseThread(a->NatT_GetIpThread); } ReleaseEvent(a->NatT_HaltEvent); DeleteLock(a->NatT_Lock); ReleaseCedar(a->Cedar); Free(a); }
// Close adapter void CloseEth(ETH *e) { BLOCK *b; // Validate arguments if (e == NULL) { return; } ReleaseCancel(e->Cancel); if (e->SuAdapter != NULL) { // Close SeLow adapter SuCloseAdapter(e->SuAdapter); SuFree(e->Su); } else { // Close SEE adapter wp->PacketCloseAdapter(e->Adapter); wp->PacketFreePacket(e->Packet); wp->PacketFreePacket(e->PutPacket); } while (b = GetNext(e->PacketQueue)) { FreeBlock(b); } ReleaseQueue(e->PacketQueue); Free(e->Name); Free(e->Title); Free(e->Buffer); Free(e); }
void CtestDlg::DrawPolygon() { RECT rect; this->GetClientRect(&rect); Queue* result = Endtest(m_test, rect.right, rect.bottom); int resultCount = GetDataCountFromQueue(result); m_result.clear(); for (int i = 0; i < resultCount; ++i) { MeshPolygon* p = (MeshPolygon*)GetDataFromQueueByIndex(result, i); const Point* pointList = GetPolygonPointList(p); for (int t = 0; t < 3; ++t) { int n = t + 1 == 3 ? 0 : t + 1; Point a = {pointList[t].x, pointList[t].z}; Point b = {pointList[n].x, pointList[n].z}; m_result.push_back(std::make_pair(a, b)); } ReleasePolygon(p); } ReleaseQueue(result); RedrawWindow(); return; }
int main(void) { PQ q = CreateQueue(10); PushQueue(q, GetRand()); PushQueue(q, GetRand()); PushQueue(q, GetRand()); PushQueue(q, GetRand()); PrintQueue(q); int i = 0; for( ; i < 10; ++i) { PushQueue(q, GetRand()); PopQueue(q); PrintQueue(q); } ReleaseQueue(q); return 0; }
// End the tracking of the routing table void RouteTrackingStop(SESSION *s, ROUTE_TRACKING *t) { ROUTE_ENTRY *e; ROUTE_TABLE *table; IP dns_ip; bool network_has_changed = false; bool do_not_delete_routing_entry = false; // Validate arguments if (s == NULL || t == NULL) { return; } Zero(&dns_ip, sizeof(dns_ip)); // Remove the default gateway added by the virtual LAN card if (MsIsVista() == false) { if (t->DefaultGatewayByVLan != NULL) { Debug("Default Gateway by VLAN was deleted.\n"); DeleteRouteEntry(t->DefaultGatewayByVLan); } if (t->VistaOldDefaultGatewayByVLan != NULL) { FreeRouteEntry(t->VistaOldDefaultGatewayByVLan); } } if (t->DefaultGatewayByVLan != NULL) { FreeRouteEntry(t->DefaultGatewayByVLan); t->DefaultGatewayByVLan = NULL; } if (t->VistaDefaultGateway1 != NULL) { Debug("Vista PPP Fix Route Table Deleted.\n"); DeleteRouteEntry(t->VistaDefaultGateway1); FreeRouteEntry(t->VistaDefaultGateway1); DeleteRouteEntry(t->VistaDefaultGateway2); FreeRouteEntry(t->VistaDefaultGateway2); } if (MsIsNt() == false) { // Only in the case of Windows 9x, release the DHCP address of the virtual LAN card Win32ReleaseDhcp9x(t->VLanInterfaceId, false); } // Clear the DNS cache Win32FlushDnsCache(); if (s->Cedar->Client != NULL && s->Account != NULL) { UINT i; ACCOUNT *a; for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++) { a = LIST_DATA(s->Cedar->Client->AccountList, i); Lock(a->lock); { SESSION *sess = a->ClientSession; if (sess != NULL && sess != s) { VLAN *v = sess->PacketAdapter->Param; if (v != NULL) { ROUTE_TRACKING *tr = v->RouteState; if (tr != NULL) { if (Cmp(tr->RouteToServer, t->RouteToServer, sizeof(ROUTE_ENTRY)) == 0) { do_not_delete_routing_entry = true; } } } } } Unlock(a->lock); } Lock(s->Account->lock); } if (do_not_delete_routing_entry == false) { // Delete the route that is added firstly if (t->RouteToServerAlreadyExists == false) { DeleteRouteEntry(t->RouteToServer); } DeleteRouteEntry(t->RouteToDefaultDns); DeleteRouteEntry(t->RouteToNatTServer); DeleteRouteEntry(t->RouteToRealServerGlobal); } FreeRouteEntry(t->RouteToDefaultDns); FreeRouteEntry(t->RouteToServer); FreeRouteEntry(t->RouteToEight); FreeRouteEntry(t->RouteToNatTServer); FreeRouteEntry(t->RouteToRealServerGlobal); t->RouteToDefaultDns = t->RouteToServer = t->RouteToEight = t->RouteToNatTServer = t->RouteToRealServerGlobal = NULL; if (s->Cedar->Client != NULL && s->Account != NULL) { Unlock(s->Account->lock); } #if 0 // Get the current DNS server if (GetDefaultDns(&dns_ip)) { if (IPToUINT(&t->OldDnsServer) != 0) { if (IPToUINT(&t->OldDnsServer) != IPToUINT(&dns_ip)) { char s1[MAX_SIZE], s2[MAX_SIZE]; network_has_changed = true; IPToStr(s1, sizeof(s1), &t->OldDnsServer); IPToStr(s2, sizeof(s2), &dns_ip); Debug("Old Dns: %s, New Dns: %s\n", s1, s2); } } } if (network_has_changed == false) { Debug("Network: not changed.\n"); } else { Debug("Network: Changed.\n"); } #endif // Get the current routing table table = GetRouteTable(); // Restore the routing table which has been removed so far while (e = GetNext(t->DeletedDefaultGateway)) { bool restore = true; UINT i; // If the restoring routing entry is a default gateway and // the existing routing table contains another default gateway // on the interface, give up restoring the entry if (IPToUINT(&e->DestIP) == 0 && IPToUINT(&e->DestMask) == 0) { for (i = 0;i < table->NumEntry;i++) { ROUTE_ENTRY *r = table->Entry[i]; if (IPToUINT(&r->DestIP) == 0 && IPToUINT(&r->DestMask) == 0) { if (r->InterfaceID == e->InterfaceID) { restore = false; } } } if (network_has_changed) { restore = false; } } if (restore) { // Routing table restoration AddRouteEntry(e); } // Memory release FreeRouteEntry(e); } // Release FreeRouteTable(table); ReleaseQueue(t->DeletedDefaultGateway); FreeRouteChange(t->RouteChange); Free(t); }
// Close Ethernet adapter void CloseEth(ETH *e) { // Validate arguments if (e == NULL) { return; } if (e->Tap != NULL) { #ifndef NO_VLAN FreeTap(e->Tap); #endif // NO_VLAN } #ifdef BRIDGE_PCAP { struct CAPTUREBLOCK *block; pcap_breakloop(e->Pcap); WaitThread(e->CaptureThread, INFINITE); ReleaseThread(e->CaptureThread); pcap_close(e->Pcap); while (block = GetNext(e->Queue)){ Free(block->Buf); FreeCaptureBlock(block); } ReleaseQueue(e->Queue); } #endif // BRIDGE_PCAP #ifdef BRIDGE_BPF #ifdef BRIDGE_BPF_THREAD { struct CAPTUREBLOCK *block; int fd = e->Socket; e->Socket = INVALID_SOCKET; WaitThread(e->CaptureThread, INFINITE); ReleaseThread(e->CaptureThread); e->Socket = fd; // restore to close after while (block = GetNext(e->Queue)){ Free(block->Buf); FreeCaptureBlock(block); } ReleaseQueue(e->Queue); } #else // BRIDGE_BPF_THREAD Free(e->Buffer); #endif // BRIDGE_BPF_THREAD #endif // BRIDGE_BPF ReleaseCancel(e->Cancel); Free(e->Name); Free(e->Title); // Restore MTU value EthSetMtu(e, 0); if (e->Socket != INVALID_SOCKET) { #if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP) || defined(UNIX_SOLARIS) close(e->Socket); #else // BRIDGE_PCAP closesocket(e->Socket); #endif // BRIDGE_PCAP #if defined(BRIDGE_BPF) || defined(UNIX_SOLARIS) if (e->SocketBsdIf != INVALID_SOCKET) { close(e->SocketBsdIf); } #endif // BRIDGE_BPF || UNIX_SOLARIS } Free(e); }
// IPv6 パケットヘッダ部のビルド BUF *BuildIPv6PacketHeader(IPV6_HEADER_PACKET_INFO *info, UINT *bytes_before_payload) { BUF *b; QUEUE *q; UINT bbp = 0; // 引数チェック if (info == NULL) { return NULL; } b = NewBuf(); q = NewQueueFast(); // オプションヘッダの一覧を作成 if (info->HopHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_HOP); } if (info->EndPointHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_ENDPOINT); } if (info->RoutingHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_ROUTING); } if (info->FragmentHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_FRAGMENT); } InsertQueueInt(q, info->Protocol); // IPv6 ヘッダ info->IPv6Header->NextHeader = IPv6GetNextHeaderFromQueue(q); WriteBuf(b, info->IPv6Header, sizeof(IPV6_HEADER)); // ホップバイホップオプションヘッダ if (info->HopHeader != NULL) { BuildAndAddIPv6PacketOptionHeader(b, info->HopHeader, IPv6GetNextHeaderFromQueue(q), info->HopHeaderSize); } // 終点オプションヘッダ if (info->EndPointHeader != NULL) { BuildAndAddIPv6PacketOptionHeader(b, info->EndPointHeader, IPv6GetNextHeaderFromQueue(q), info->EndPointHeaderSize); } // ルーティングヘッダ if (info->RoutingHeader != NULL) { BuildAndAddIPv6PacketOptionHeader(b, info->RoutingHeader, IPv6GetNextHeaderFromQueue(q), info->RoutingHeaderSize); } // フラグメントヘッダ if (info->FragmentHeader != NULL) { info->FragmentHeader->NextHeader = IPv6GetNextHeaderFromQueue(q); WriteBuf(b, info->FragmentHeader, sizeof(IPV6_FRAGMENT_HEADER)); } bbp = b->Size; if (info->FragmentHeader == NULL) { bbp += sizeof(IPV6_FRAGMENT_HEADER); } // ペイロード if (info->Protocol != IPV6_HEADER_NONE) { WriteBuf(b, info->Payload, info->PayloadSize); } ReleaseQueue(q); SeekBuf(b, 0, 0); // ペイロード長さ ((IPV6_HEADER *)b->Buf)->PayloadLength = Endian16(b->Size - (USHORT)sizeof(IPV6_HEADER)); if (bytes_before_payload != NULL) { // ペイロードの直前までの長さ (ただしフラグメントヘッダは必ず含まれると仮定) // を計算する *bytes_before_payload = bbp; } return b; }
int ConvexPolygonClipping(const MeshPolygon* clippedPolygon, const MeshPolygon* clippingWindow, Queue* queue) { if(NULL == clippedPolygon || NULL == clippingWindow || NULL == queue) { return WRONG_PARAM; } int allPointCountForClipping = 0; const Point* pointListForClipingWindow = GetPolygonPointList(clippingWindow); const int pointCountForClippingWindow = GetPolygonPointCount(clippingWindow); allPointCountForClipping += pointCountForClippingWindow; int clipingWindowPointInClippedWindowCount[3] = {0}; for (int i = 0; i < pointCountForClippingWindow; ++i) { int checkResult = PointInPolygon(clippedPolygon, pointListForClipingWindow[i].x, pointListForClipingWindow[i].z); ++clipingWindowPointInClippedWindowCount[checkResult + 1]; } //裁剪多边形的顶点都位于被裁剪多边形的内部或者边上 //目前无法裁剪这种情况 if (0 == clipingWindowPointInClippedWindowCount[0]) { return CLIPPING_WINDOW_ALL_IN_CLIPPED_POLYGON; } const Point* pointListForClippedPolygon = GetPolygonPointList(clippedPolygon); const int pointCountForClippedPolygon = GetPolygonPointCount(clippedPolygon); int clippedPolygonointInClippedWindowCount[3] = {0}; for (int i = 0; i < pointCountForClippedPolygon; ++i) { int checkResult = PointInPolygon(clippingWindow, pointListForClippedPolygon[i].x, pointListForClippedPolygon[i].z); ++clippedPolygonointInClippedWindowCount[checkResult + 1]; } allPointCountForClipping += pointCountForClippedPolygon; //被裁剪的多边形的顶点全部为与裁剪多边形内或边上 //不需要参见 if (0 == clippedPolygonointInClippedWindowCount[0]) { return ALL_POINT_IN_CLIPPING_WINDOW; } //两多边形不相交 不需要裁剪 if (0 == clipingWindowPointInClippedWindowCount[2] && 0 == clippedPolygonointInClippedWindowCount[2]) { return NOT_NEED_CLIPPING; } ClippingInterPoint* pointChainForClippingWindow = CreateClippingWindowData(clippedPolygon, clippingWindow); ClippingInterPoint* pointChainForClippedPolygon = CreateClippedPolygonData(clippedPolygon, clippingWindow); //查找交点并将交点插入正确的位置 const Vector* const pNormalOfClippedPolygon = GetPolygonNormal(clippedPolygon); Rect checkRect; for (int indexOfClippingWindow = 0; indexOfClippingWindow < pointCountForClippingWindow; ++indexOfClippingWindow) { int nextIndexOfClippingWindow = indexOfClippingWindow + 1 == pointCountForClippingWindow ? 0 : indexOfClippingWindow + 1; for (int indexOfclippedPolygon = 0; indexOfclippedPolygon < pointCountForClippedPolygon; ++indexOfclippedPolygon) { int nextIndexOfClippedPolygon = indexOfclippedPolygon + 1 == pointCountForClippedPolygon ? 0 : indexOfclippedPolygon + 1; ClippingInterPoint* const pBeginPointOfClippinWindow = &pointChainForClippingWindow[indexOfClippingWindow]; ClippingInterPoint* const pEndPointOfClippinWindow = &pointChainForClippingWindow[nextIndexOfClippingWindow]; ClippingInterPoint* const pBeginPointOfClippedPolygon = &pointChainForClippedPolygon[indexOfclippedPolygon]; ClippingInterPoint* const pEndPointOfClippedPolygon = &pointChainForClippedPolygon[nextIndexOfClippedPolygon]; Vector toBeginPoint = {pBeginPointOfClippinWindow->point.x - pBeginPointOfClippedPolygon->point.x, 0.0f, pBeginPointOfClippinWindow->point.z - pBeginPointOfClippedPolygon->point.z}; Vector toEndPoint = {pEndPointOfClippinWindow->point.x - pBeginPointOfClippedPolygon->point.x, 0.0f, pEndPointOfClippinWindow->point.z - pBeginPointOfClippedPolygon->point.z}; float cosofToBeginPoint = VectorDotProduct(&toBeginPoint, &pNormalOfClippedPolygon[indexOfclippedPolygon]); float cosofToEndPoint = VectorDotProduct(&toEndPoint, &pNormalOfClippedPolygon[indexOfclippedPolygon]); bool beginPointIsSpecial = (FloatEqualZero(cosofToBeginPoint) && cosofToEndPoint > 0.0f); bool endPointIsSpecial = (FloatEqualZero(cosofToEndPoint) && cosofToBeginPoint> 0.0f); if (beginPointIsSpecial || endPointIsSpecial) { //特殊点,即交点在被裁减的多边形的边上,且同在内侧 ClippingInterPoint* pTempPoint = beginPointIsSpecial ? pBeginPointOfClippinWindow : pEndPointOfClippinWindow; pTempPoint->pointType = INTER_POINT_TYPE_CLIPPING_WINDOW_POINT_AN_INSERCTION_POINT; ClippingInterPoint* pCurrentPositon = &pointChainForClippedPolygon[indexOfclippedPolygon]; ClippingInterPoint* pNextPosition = pCurrentPositon->next2ClippedPolygon; ClippingInterPoint* pEndPosition = &pointChainForClippedPolygon[nextIndexOfClippedPolygon]; pTempPoint->tValueForClippedPolygon = GetTValue(&pBeginPointOfClippedPolygon->point, &pEndPointOfClippedPolygon->point, &pTempPoint->point); while (true) { if( pTempPoint->tValueForClippedPolygon < pCurrentPositon->tValueForClippedPolygon) { ClippingInterPoint* pLastPosition = pCurrentPositon->prev2ClippedPolygon; pLastPosition->next2ClippedPolygon = pTempPoint; pCurrentPositon->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pLastPosition; pTempPoint->next2ClippedPolygon = pCurrentPositon; break; } else if (pEndPosition == pNextPosition) { pCurrentPositon->next2ClippedPolygon = pTempPoint; pNextPosition->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pCurrentPositon; pTempPoint->next2ClippedPolygon = pNextPosition; break; } pCurrentPositon = pNextPosition; pNextPosition = pCurrentPositon->next2ClippedPolygon; } continue; } if (FloatEqualZero(cosofToBeginPoint) && cosofToEndPoint < 0.0f) { //特殊点,即交点在被裁减的多边形的边上,且同在外侧 //直接抛弃,不处理 continue; } if (FloatEqualZero(cosofToEndPoint) && cosofToBeginPoint < 0.0f) { //特殊点,即交点在被裁减的多边形的边上,且同在外侧 //直接抛弃,不处理 continue; } //如果两点在边的同一侧,即没有交点,直接跳过 if (cosofToBeginPoint > 0.0f && cosofToEndPoint > 0.0f) { continue; } if (cosofToBeginPoint < 0.0f && cosofToEndPoint < 0.0f) { continue; } //如果有交点,则求交点并将交点插入正确的位置 //两相交线段求交点 //从而可以求出p的坐标 具体算法可以参考图形学算法 float tValue =cosofToBeginPoint; tValue /= (cosofToBeginPoint - cosofToEndPoint); float insertionX = pBeginPointOfClippinWindow->point.x + tValue * (pEndPointOfClippinWindow->point.x - pBeginPointOfClippinWindow->point.x); float insertionZ = pBeginPointOfClippinWindow->point.z + tValue * (pEndPointOfClippinWindow->point.z - pBeginPointOfClippinWindow->point.z); //检查点是否在线段的延长线上 Point point = {insertionX, insertionZ}; Point a = pBeginPointOfClippedPolygon->point; Point b = pEndPointOfClippedPolygon->point; MakeRectByPoint(&checkRect, &a, &b); if(true != InRect(&checkRect, &point)) { continue; } a = pBeginPointOfClippinWindow->point; b = pEndPointOfClippinWindow->point; MakeRectByPoint(&checkRect, &a, &b); if(true != InRect(&checkRect, &point)) { continue; } ClippingInterPoint* pTempPoint = (ClippingInterPoint*)malloc(sizeof(ClippingInterPoint)); ++allPointCountForClipping; pTempPoint->point = point; pTempPoint->tValueForClippingWindow = tValue; pTempPoint->tValueForClippedPolygon = GetTValue(&pBeginPointOfClippedPolygon->point, &pEndPointOfClippedPolygon->point, &point); //通过遍历链表查找正确的位置插入生成点 ClippingInterPoint* pCurrentPositon = &pointChainForClippingWindow[indexOfClippingWindow]; ClippingInterPoint* pNextPosition = pCurrentPositon->next2ClippingdWindow; ClippingInterPoint* pEndPosition = &pointChainForClippingWindow[nextIndexOfClippingWindow]; bool pointIsAdd = false; while(true) { if (IsSamePoint(&pTempPoint->point, &pCurrentPositon->point)) { //检查该点以否已经添加,如果已经添加则退出循环 //防止重复添加导致在后面在裁剪的时候死循环 pointIsAdd = true; break; } if( pTempPoint->tValueForClippingWindow < pCurrentPositon->tValueForClippingWindow) { ClippingInterPoint* pLastPosition = pCurrentPositon->prev2ClippingdWindow; pLastPosition->next2ClippingdWindow = pTempPoint; pCurrentPositon->prev2ClippingdWindow = pTempPoint; pTempPoint->prev2ClippingdWindow = pLastPosition; pTempPoint->next2ClippingdWindow = pCurrentPositon; break; } else if (pEndPosition == pNextPosition) { pCurrentPositon->next2ClippingdWindow = pTempPoint; pNextPosition->prev2ClippingdWindow = pTempPoint; pTempPoint->prev2ClippingdWindow = pCurrentPositon; pTempPoint->next2ClippingdWindow = pNextPosition; break; } pCurrentPositon = pNextPosition; pNextPosition = pCurrentPositon->next2ClippingdWindow; } if (true == pointIsAdd) { free(pTempPoint); continue; } //通过遍历链表查找正确的位置插入生成点 pCurrentPositon = &pointChainForClippedPolygon[indexOfclippedPolygon]; pNextPosition = pCurrentPositon->next2ClippedPolygon; pEndPosition = &pointChainForClippedPolygon[nextIndexOfClippedPolygon]; while (true) { if( pTempPoint->tValueForClippedPolygon < pCurrentPositon->tValueForClippedPolygon) { ClippingInterPoint* pLastPosition = pCurrentPositon->prev2ClippedPolygon; pLastPosition->next2ClippedPolygon = pTempPoint; pCurrentPositon->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pLastPosition; pTempPoint->next2ClippedPolygon = pCurrentPositon; break; } else if (pEndPosition == pNextPosition) { pCurrentPositon->next2ClippedPolygon = pTempPoint; pNextPosition->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pCurrentPositon; pTempPoint->next2ClippedPolygon = pNextPosition; break; } pCurrentPositon = pNextPosition; pNextPosition = pCurrentPositon->next2ClippedPolygon; } if (cosofToBeginPoint < 0.0f && cosofToEndPoint > 0.0f) { pTempPoint->pointType = INTER_POINT_TYPE_INTERSECTION_POINT_FOR_IN; } else if(cosofToBeginPoint > 0.0f && cosofToEndPoint < 0.0f) { pTempPoint->pointType = INTER_POINT_TYPE_INTERSECTION_POINT_FOR_OUT; } else { assert(0); } } } //完成链表构建 //开始生成convex polygon //首先检查是否有足够的空间容纳结果 int* bufferForPolygonConverCount = (int*)malloc(sizeof(int*) * allPointCountForClipping); GenerateConvexPolygon(pointChainForClippedPolygon, pointCountForClippedPolygon, NULL, bufferForPolygonConverCount, allPointCountForClipping); //完成链表构建 //开始生成convex polygon for (int i = 0; i < pointCountForClippedPolygon; ++i) { pointChainForClippedPolygon[i].state = PROCESS_STATE_UNPROCESSED; int checkResult = PointInPolygon(clippingWindow, pointChainForClippedPolygon[i].point.x, pointChainForClippedPolygon[i].point.z); if (checkResult >= 0) { pointChainForClippedPolygon[i].state = PROCESS_STATE_NO_NEED_PROCESS; } } GenerateConvexPolygon(pointChainForClippedPolygon, pointCountForClippedPolygon, queue, bufferForPolygonConverCount, allPointCountForClipping); //释放分配的内存 ClippingInterPoint* pCurrent = &pointChainForClippedPolygon[0]; ClippingInterPoint* pNext = pCurrent->next2ClippedPolygon; while (pNext != &pointChainForClippedPolygon[0]) { if (INTER_POINT_TYPE_INTERSECTION_POINT_FOR_IN == pNext->pointType || INTER_POINT_TYPE_INTERSECTION_POINT_FOR_OUT == pNext->pointType) { pCurrent = pNext; pNext = pNext->next2ClippedPolygon; free(pCurrent); } else { pNext = pNext->next2ClippedPolygon; } } Queue* checkQueue = CreateQueue(GetDataCountFromQueue(queue)); while (MeshPolygon* checkPolygon = (MeshPolygon*)PopDataFromQueue(queue)) { if (true != IsSamePolygon(checkPolygon, clippedPolygon)) { PushDataToQueue(checkQueue, (void*)checkPolygon); } } ShiftQueueData(queue, checkQueue); ReleaseQueue(checkQueue); free(bufferForPolygonConverCount); free(pointChainForClippedPolygon); free(pointChainForClippingWindow); return 0; }
unsigned int CallDosDebug( dos_debug __far *buff ) { QMSG qmsg; int num_paints; int i; struct { RECTL rcl; HWND hwnd; } paints[MAX_PAINTS]; HPS ps; char class_name[80]; TID tid; if( !IsPMDebugger() ) { return( Call32BitDosDebug( buff ) ); } switch( buff->Cmd ) { case DBG_C_ClearWatch: case DBG_C_Freeze: case DBG_C_LinToSel: case DBG_C_NumToAddr: case DBG_C_ReadCoRegs: case DBG_C_ReadMemBuf: case DBG_C_ReadMem_D: case DBG_C_ReadReg: case DBG_C_SelToLin: case DBG_C_SetWatch: case DBG_C_ThrdStat: case DBG_C_WriteCoRegs: case DBG_C_WriteMemBuf: case DBG_C_WriteMem_D: case DBG_C_WriteReg: return( Call32BitDosDebug( buff ) ); } switch( buff->Cmd ) { case DBG_C_Go: case DBG_C_SStep: case DBG_C_Term: ReleaseQueue( buff->Pid, buff->Tid ); } DebugReqBuff = buff; StopBuff = *buff; DosSemSet( &DebugDoneSem ); DosSemClear( &DebugReqSem ); num_paints = 0; if( IsPMDebugger() ) { while( WinGetMsg( HabDebugger, &qmsg, 0L, 0, 0 ) || InDosDebug ) { WinQueryClassName( qmsg.hwnd, MAX_CLASS_NAME, class_name ); switch( qmsg.msg ) { case WM_CHAR: if( ( SHORT1FROMMP( qmsg.mp1 ) & KC_VIRTUALKEY ) && ( SHORT2FROMMP( qmsg.mp2 ) == VK_BREAK ) ) { SetBrkPending(); DosCreateThread( StopApplication, &tid, stack2 + STACK_SIZE ); DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 10, tid ); WakeThreads( StopBuff.Pid ); DosSemWait( &StopDoneSem, SEM_INDEFINITE_WAIT ); DosSemSet( &StopDoneSem ); } break; case WM_COMMAND: CantDoIt(); break; default: if( strcmp( class_name, "GUIClass" ) == 0 || strcmp( class_name, "WTool" ) == 0 ) { switch( qmsg.msg ) { case WM_PAINT: if( num_paints >= MAX_PAINTS ) --num_paints; paints[num_paints].hwnd = qmsg.hwnd; ps = WinBeginPaint( qmsg.hwnd, 0, &paints[ num_paints ].rcl ); GpiErase( ps ); WinEndPaint( ps ); num_paints++; break; case WM_BUTTON1DOWN: case WM_BUTTON2DOWN: case WM_BUTTON3DOWN: CantDoIt(); break; case WM_MOUSEMOVE: { HPOINTER hourglass = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE ); if( WinQueryPointer( HWND_DESKTOP ) != hourglass ) { WinSetPointer( HWND_DESKTOP, hourglass ); } break; } default: WinDefWindowProc( qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2 ); } } else { WinDispatchMsg( HabDebugger, &qmsg ); } } } } else { DosSemWait( &DebugDoneSem, SEM_INDEFINITE_WAIT ); } switch( buff->Cmd ) { case DBG_N_Exception: case DBG_N_AsyncStop: case DBG_N_Watchpoint: AssumeQueue( buff->Pid, buff->Tid ); break; } for( i = 0; i < num_paints; ++i ) { WinInvalidateRect( paints[i].hwnd, &paints[i].rcl, FALSE ); } return( DebugReqResult ); }