Exemplo n.º 1
0
// 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;
}
Exemplo n.º 2
0
// 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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
// 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);
}
Exemplo n.º 5
0
// 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);
}
Exemplo n.º 6
0
// パケットアダプタの解放
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);
}
Exemplo n.º 7
0
// 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;
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
0
// 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);
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
0
// 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);
}
Exemplo n.º 14
0
// 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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
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 );
}