⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chmazmod.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
						float value;
						int numRead = ::sscanf(LPCTSTR(strValue) + numBytes, "%g", &value);
						pEvent = new ChFloatEvent(name, value);
						break;
					}
					case ChVRMLEvent::MFFloat :
					{
						int count;
						int nBytes = numBytes;
						int n;
						int numRead = ::sscanf(LPCTSTR(strValue) + nBytes, "%d%n", &count, &n);
						if(numRead)
						{
							float *val = new float [count];
							for(int i = 0; i < count; i++)
							{
								nBytes += n;
								numRead = ::sscanf(LPCTSTR(strValue) + nBytes, "%f%n", val+i, &n);
								if(!numRead) break;
							}
							if(numRead) pEvent = new ChFloatEvent(name, count, val);
							delete []val;
						}
						break;
					}
					case ChVRMLEvent::MFRotation :
					{
						float x, y, z, angle;

						int count;
						int nBytes = numBytes;
						int n;
						int numRead = ::sscanf(LPCTSTR(strValue) + nBytes, "%d%n", &count, &n);
						if(numRead)
						{
							float *val = new float [count * 4];
							for(int i = 0; i < count; i++)
							{
								nBytes += n;
								numRead = ::sscanf(LPCTSTR(strValue) + nBytes, "%f %f %f %f%n", &x, &y, &z, &angle, &n);
								if(numRead < 4) break;
								int index = i * 4;
								val[index] = x;
								val[index+1] = y;
								val[index+2] = z;
								val[index+3] = angle;
							}
							if(numRead) pEvent = new ChRotationEvent(name, count, val);
							delete []val;
						}
						break;
					}
					case ChVRMLEvent::SFBool :
					{
						bool value = false;
						string buf;
						char *pbuf = buf.GetBuffer(1000);

						int numRead = ::sscanf(LPCTSTR(strValue) + numBytes, "%s", buf);
						buf.ReleaseBuffer();
						if(numRead)
						{
							if(	!buf.CompareNoCase("true") || 
								!buf.CompareNoCase("1") || 
								!buf.CompareNoCase("t") || 
								!buf.CompareNoCase("yes")  || 
								!buf.CompareNoCase("y")) value = true;
							// assuming illegals are false
							pEvent = new ChBoolEvent(name, value);
						}
						break;
					}
					case ChVRMLEvent::SFTime :
					{
						double value;
						int numRead = ::sscanf(LPCTSTR(strValue) + numBytes, "%lg", &value);
						pEvent = new ChTimeEvent(name, value);
						break;
					}
					case ChVRMLEvent::SFNode :
					case ChVRMLEvent::MFNode :
					{
						// Our syntax only allows one node right now
						// and only via code
						string strVrml;
						if (ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_VRML, strVrml ))
						{
							if(strVrml.Left(6) != "#VRML ")
							{
								string strBuf = strVrml;
								strVrml = string("#VRML V1.0 ascii\n ") + strBuf;
							}

							// TODO Check for optional header field	xch_vrml_hdr

							pSFNode = (ChNode*)(pBrowser->CompileVRML(strVrml));
						}
						else
						{
							// remainder of fields if any are node names; just do first for now
							int numRead, n;
							char argNodeName[1000];
							if(numRead = ::sscanf(LPCTSTR(strValue) + numBytes, "%s%n", argNodeName, &n))
							{
								string strArgNodeName (argNodeName);
								pSFNode = (pBrowser->Resolve(pNode, strArgNodeName));
								numBytes += n;
							}
							if(!pSFNode)
							{
								string strMsg;
								strMsg.Format("VRML: Event %s, node %s was not found in scene graph under node %s.\n", 
									name, argNodeName, strNode );
								((ChMazeWnd*)GetView())->OnError( CH_MAZE_ROUTE_ERROR_NODE_NOTFOUND, strMsg, ChMazeWnd::traceError);
							}

						}

						if(pSFNode) pEvent = new ChNodeEvent(name, pSFNode);
						break;
					}
					default:
					{
						// Ignore it
						break;
					}
				}
			
				if(pEvent)
				{
					if(ChIVrmlEvent::IsMultiple(eventType))
					{
						pEvent->SetMultiple(true);
					} 
					pBrowser->SendEvent(pNode, 0, pEvent);	// I'm doing this direct, so
															// don't delete the event. In the real case,
															// It needs to be deleted after sending
					pBrowser->FreeNode(pNode);				// Preservation of node is now browser's
															// responsibility. This undoes the Use()
															// implicit in Resolve()
					
				}
				if(pSFNode) pBrowser->FreeNode(pSFNode); 
			}
			else
			{
				// No node found for subject; complain
				string strMsg;
				strMsg.Format("VRML: Event %s, node %s was not found.\n", LPCTSTR(name), strNode );
				((ChMazeWnd*)GetView())->OnError( CH_MAZE_ROUTE_ERROR_NODE_NOTFOUND, strMsg, ChMazeWnd::traceError);
				//TRACE(strMsg);	// ahhh, should we print this too?
			}

		}
	}
	#endif
}


void ChMazeMainInfo::SetupPositionNotification(const string &strArgs)
{
	// Call this with a blank string to reset

	/* <img xch_event="move" 
			xch_minTime=nnn 
			xch_maxTime=nnn 
			xch_maxMove=nnn.nn 
			xch_startTime=nnn 
			params="position look up time orientation velocity slewrate">

			defaults:
				xch_minTime=1000 
				xch_maxTime=10000 
				xch_maxMove=0.5 
				xch_startTime=0 
				params="position" - specifying empty gives no args

			where notification param formats are:
				position f f f
				look	f f f
				up f f f
				time : long milliseconds since startTime 
				orientation f f f f (axis, then angle)
				velocity f f f
				slewRate f f f f (axis, then angular velocity)

				all units are in meters or radians, or meter/sec or rads/sec
				all time is in milliseconds
	*/
	// Defaults
	long 	lMinTime=1000; 
	long 	lMaxTime=10000; 
	float 	fMaxMove=0.5;
	float 	fMaxRotation=3.1415927 / 12;	   // 15 degrees
	char 	params[CH_MAX_NOTIFICATION_PARAMS];
	chint32 ticks = ::GetMessageTime();
	bool	boolEnabled = false;
	double 	dOffset=-ticks;

	memset(params, 0, sizeof(params));
	params[0] = 'p';
	

	if(!strArgs.IsEmpty())
	{
		lMinTime=m_minNotifyTime;     // we'll just modify current
		lMaxTime=m_maxNotifyTime;   
		fMaxMove=m_maxMove;     
		fMaxRotation=m_maxRotation;     
		dOffset=m_dTimeOffset;
		boolEnabled = true;     
		memmove(params, m_params, sizeof(params));
		double t;
		int numRead;
		string strValue;
		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_CMD_MINTIME, strValue ))
		{
			if((numRead = sscanf(LPCTSTR(strValue), "%lg", &t)) >= 1 )
			{
				lMinTime = long(t);
			} 
		}
			
		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_CMD_MAXTIME, strValue ))
		{
			if((numRead = sscanf(LPCTSTR(strValue), "%lg", &t)) >= 1 )
			{
				lMaxTime = long(t);
			} 
		}

		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_CMD_MAXMOVE, strValue ))	
		{
			if((numRead = sscanf(LPCTSTR(strValue), "%lg", &t)) >= 1 )
			{
				fMaxMove = t;
			} 
		}
			
		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_CMD_MAXROTATION, strValue ))	
		{
			if((numRead = sscanf(LPCTSTR(strValue), "%lg", &t)) >= 1 )
			{
				fMaxRotation = t;
			} 
		}
			
		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_CMD_STARTTIME, strValue ))	
		{
			if((numRead = sscanf(LPCTSTR(strValue), "%lg", &t)) >= 1 )
			{
				dOffset = (t - ticks);
			} 
		}
			
		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_CMD_NAME, strValue ))	
		{
			if( strValue.IsEmpty()) boolEnabled = false;
			else boolEnabled = true;
			// No processing of name yet
		}
			
		if(ChHtmlWnd::GetHTMLAttribute( strArgs, CH_GRAPH_CMD_PARAMS, strValue ))
		{
			char *pTxt = strValue.GetBuffer(100);
			char key[200];
			int n, i = 0;
			memset(params, 0, sizeof(params));

			while(i < CH_MAX_NOTIFICATION_PARAMS && pTxt && *pTxt && sscanf( pTxt, "%s%n", key, &n))
			{
				string sKey(key);					      

				if(!sKey.CompareNoCase("position") ||
					!sKey.CompareNoCase("look") ||
					!sKey.CompareNoCase("up") ||
					!sKey.CompareNoCase("time") ||
					!sKey.CompareNoCase("orientation") ||
					!sKey.CompareNoCase("velocity") ||
					!sKey.CompareNoCase("slewrate"))
				{
					params[i++] = tolower(key[0]);		// first letter is key
				}
				pTxt += n;		
			}
		}	
	}
	

	// Copy the stuff into 'this'
	m_minNotifyTime 	=	lMinTime;	
	m_maxNotifyTime 	=	lMaxTime;	  
	m_maxMove       	=	fMaxMove;	
	m_maxRotation       =	fMaxRotation;	
	m_dTimeOffset   	=	dOffset;
	m_boolNotificationEnabled	= boolEnabled;		  
	memmove(m_params, params, sizeof(params));
 

}

ChMazeMainInfo * ChMazeMainInfo::Add(ChGraphicHTTPReq *pInProgressReq)
{
	if(!m_pInProgressReqs)
	{
		//m_pInProgressReqs = new ChPtrList<ChGraphicHTTPReq>;
		m_pInProgressReqs = new ChGraphicHTTPReqList;
	}
	m_pInProgressReqs->AddTail(pInProgressReq);
	return this;
}

ChMazeMainInfo * ChMazeMainInfo::Delete(ChGraphicHTTPReq *pInProgressReq)
{
	if(m_pInProgressReqs)
	{
		ChPosition	pos;
		if(!m_pInProgressReqs->IsEmpty())
		{
			pos = m_pInProgressReqs->Find(pInProgressReq, 0 );
			if(pos) m_pInProgressReqs->Remove(pos);
		}
		if(m_pInProgressReqs->IsEmpty())
		{
			delete m_pInProgressReqs;
			m_pInProgressReqs = 0;
		}
	}
	return this;
}

ChMazeMainInfo * ChMazeMainInfo::CancelInProgressReqs()
{
	if(m_pInProgressReqs)
	{
		while(!m_pInProgressReqs->IsEmpty())
		{
			ChGraphicHTTPReq *pReq = m_pInProgressReqs->RemoveHead();
			pReq->Cancel();
		}
		delete m_pInProgressReqs;
		m_pInProgressReqs = 0;
	}
	return this;
}

void ChMazeMainInfo::OnTick()
{
	// Bootleg the animation tick for our own purposes

	chint32 ticks = ::GetMessageTime();
	if(IsShown() && m_boolNotificationEnabled && ticks - m_lastTick >= m_minNotifyTime)
	{
		// notify mud
		// if moved or if over max time for notify, do it
		ChPuebloVrmlWnd* pWnd =	(ChPuebloVrmlWnd*)m_pWnd;
		GxVec3f loc =  pWnd->GetCameraControl()->GetLoc();
		GxVec3f look =  pWnd->GetCameraControl()->GetLookDir();
		GxVec3f up =  pWnd->GetCameraControl()->GetUp();
		GxVec3f delta = loc;
		delta -= m_lastLoc;
		float distance = delta.magnitude();
		float cosm = cos(m_maxRotation);
		if(!m_lastTick 
			|| distance > m_maxMove 
			|| ticks - m_lastTick > m_maxNotifyTime
			|| (m_maxRotation > 0 && m_lastLook.dot(look) < cosm)
			|| (m_maxRotation > 0 && m_lastUp.dot(up) < cosm) )
		{
			string command;

			FormatMoveCommand(command);
			NotifyAnchor(command);

			m_lastTick = ticks;
			m_lastLoc = loc;
			m_lastUp = up;
			m_lastLook = look;
		}

	}
}
void ChMazeMainInfo::FormatMoveCommand(string &command)
{

	command = "xch_cmd=\"PUEBLOMOVE";
	for(int i = 0; i < CH_MAX_NOTIFICATION_PARAMS; i++)
	{
		char buf[100];						      
		GxVec3f vec;
		buf[0] = 0;
		ChPuebloVrmlWnd* pWnd =	(ChPuebloVrmlWnd*)m_pWnd;
						       
		// possibilities:
		// position look up time orientation velocity slewrate
		switch(m_params[i])
		{
			case 'p':
			{
				vec = pWnd->GetCameraControl()->GetLoc();
				sprintf(buf, " %6.3f %6.3f %6.3f", double(vec.x()), double(vec.y()), double(vec.z()));
				break;
			}
			case 'l':
			{
				vec = pWnd->GetCameraControl()->GetLookDir();
				sprintf(buf, " %6.3f %6.3f %6.3f", double(vec.x()), double(vec.y()), double(vec.z()));
				break;
			}
			case 'u':
			{
				vec = pWnd->GetCameraControl()->GetUp();
				sprintf(buf, " %6.3f %6.3f %6.3f", double(vec.x()), double(vec.y()), double(vec.z()));
				break;
			}
			case 't':
			{
				chint32 lTime = chint32(::GetMessageTime() + m_dTimeOffset);
				sprintf(buf, " %ld", lTime);
				break;
			}
			case 'o':
			{
				float angle;
				pWnd->GetCameraControl()->GetOrientation(vec, angle);
				sprintf(buf, " %6.3f %6.3f %6.3f %6.3f", double(vec.x()), double(vec.y()), double(vec.z()), double(angle));
				break;
			}
			#if 1
			case 'v':
			{
				pWnd->GetVelocity(vec);
				sprintf(buf, " %6.3f %6.3f %6.3f", double(vec.x()), double(vec.y()), double(vec.z()));
				break;
			}
			case 's':
			{
				float angle;
				pWnd->GetAngularVelocity(vec, angle);
				sprintf(buf, " %6.3f %6.3f %6.3f %6.3f", double(vec.x()), double(vec.y()), double(vec.z()), double(angle));
				break;
			}
			#endif
		}
		command += buf;
	}
	command += "\"";
}

bool ChMazeMainInfo::OnCameraChange(int efChanged)
{
	return true;
}

/*----------------------------------------------------------------------------
	ChMazeMainInfo protected methods
----------------------------------------------------------------------------*/

void ChMazeMainInfo::ReadPreferences()
{
	GetSettings()->ReadPreferences( "", "", GR_PREFS_GROUP );
}

void ChMazeMainInfo::UpdatePreferences( bool boolMoveVector,
										bool boolScaleTextures,
										ChShadingLevel renderQuality,
										ChShadingLevel moveRenderQuality,
										float fHeadlight,
										#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
										int iAsciiTextQuality,
										bool boolCollisionAlarm
										#else
										int iAsciiTextQuality
										#endif
										 )
{
	GetSettings()->UpdatePreferences( boolMoveVector,
										boolScaleTextures,
										renderQuality,
										moveRenderQuality,
										fHeadlight,
										#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
										iAsciiTextQuality,
										boolCollisionAlarm        
										#else
										1 
										#endif
										);	// 
	GetView()->GetRenderContext()->SetDirty();
	GetView()->Invalidate(false);
}

void ChMazeMainInfo::OnParseComplete(string &strURL, chparam data)
{
	ChGraphicDocumentHTTPReq*pReq = (ChGraphicDocumentHTTPReq*)data;
	DoQueuedCommands(pReq);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -