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

📄 gamedataset.cpp

📁 网络游戏魔域源代码 测试可以完整变异
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <windows.h>

#include "mydatafile.H"
#include "basefunc.H"
#include "gamedataset.H"

// gobal 
CGameDataSet g_objGameDataSet;

// const
const char	szCOMMONANI[]	="ani/Common.ani";

const int   _MAX_ACTNAME    =32;

const int	_MEM_CHECK_TIMER	= 2000;
const int	_LOW_MEM			= 4*1024*1024;
const int	_HIGH_MEM			= 20*1024*1024;
const int	_HIGHEST_DEADLINE	= 30000;
const int	_LOWEST_DEADLINE	= 3000;

const int	_3DOBJ_DEADLINE		= 30*1000;
/*const int	_3DMOTION_DEADLINE	= 10*1000;
const int	_3DTEXTURE_DEADLINE	= 10*1000;
const int	_3DEFFECT_DEADLINE	= 10*1000;
*/

// globle....
DWORD			g_dwDeadLine	=	10000;
// local...
CRITICAL_SECTION	csReadThread;
DEQUE_ANI			dequeDataToLoad;


HANDLE			hExitEvent	=NULL;		// exit event, set if u want terminate read process
HANDLE			hReadEvent	=NULL;		// read event, for process read data
HANDLE			hReadThread	=NULL;


#ifdef _ANALYSIS_ON
DWORD g_dw3DObj=0, g_dw3DMotion=0, g_dw3DWMotion=0, g_dwTexture=0, g_dw3DEffect=0, g_dwDataAni=0;

#endif
//--------------------------------------------------------------
void AddReadDeque(CAni* pAni, int nExigence)
{
	if (!pAni)
		return;

	::EnterCriticalSection(&csReadThread);
	//------------------------------
		if(nExigence == EXIGENCE_NORMAL)
			dequeDataToLoad.push_back(pAni);
		else
			dequeDataToLoad.push_front(pAni);

	//------------------------------
	::LeaveCriticalSection(&csReadThread);


	// come on, load my data now!
	::SetEvent(hReadEvent);
}

//--------------------------------------------------------------
void UpPriority(CAni* pAni)
{
	if (!pAni)
		return;

	::EnterCriticalSection(&csReadThread);
	//------------------------------
		if (pAni->GetStatus() == ANISTATUS_INIT)
		{
			int nAmount = dequeDataToLoad.size();
			for (int i=nAmount-1; i>0; i--)	// i>0
			{
				CAni* pTheAni = dequeDataToLoad[i];
				if (pTheAni == pAni)
				{
					dequeDataToLoad.erase(dequeDataToLoad.begin()+i);
					dequeDataToLoad.push_front(pAni);
					break;
				}
			}
		}
	//------------------------------
	::LeaveCriticalSection(&csReadThread);
}


//--------------------------------------------------------------
// Name: DataReadThread
//
// Note: read thread process function
//
// In:	 none
//
// Return:	 DWORD type, always 0.
//--------------------------------------------------------------
DWORD WINAPI DataReadThread(LPVOID lpThreadParameter)
{
	HANDLE		eventHandles[2];
	eventHandles[0]	=hReadEvent;
	eventHandles[1] =hExitEvent;

	// loop waiting for player events. If the exit event is signaled
	// the thread will exit
	while (WaitForMultipleObjects(2, eventHandles, FALSE, INFINITE)==WAIT_OBJECT_0)
	{
		while(!dequeDataToLoad.empty())
		{
			CAni* pAni = NULL;
			try {
				::EnterCriticalSection(&csReadThread);
				//------------------------------			
					
					pAni = dequeDataToLoad.front();
					dequeDataToLoad.pop_front();

					pAni->SetStatus(ANISTATUS_LOADING);
				//------------------------------
				::LeaveCriticalSection(&csReadThread);

				// loading.... cost lot's of time
				pAni->Load();
			}
			catch(...)
			{
				::LogMsg("catch error in data load thread.");

				CDynamicAni* pDynaAni = (CDynamicAni*) (pAni);
				if (pDynaAni)
					::LogMsg("crashed when loading %s :%s", pDynaAni->m_szIniFile, pDynaAni->m_szIndex);
				else
					::LogMsg("can't dynamic_cast the ani pointer");
			}
		}
	}

	return 0;
}

//--------------------------------------------------------------
BOOL DataReadThreadInit(void)
{
	hReadEvent =CreateEvent	 (NULL,		// no security
							  FALSE,	// auto reset
							  FALSE,	// initial event reset
							  NULL);	// no name

	if (!hReadEvent)
		return false;

	hExitEvent =CreateEvent  (NULL,		// no security
							  FALSE,	// auto reset
							  FALSE,	// initial event reset
							  NULL);	// no name
	if (!hExitEvent)
		return false;

	//---------------------------------
	dequeDataToLoad.clear();
	

	//---------------------------------
	DWORD dwIdThread;
	hReadThread		=CreateThread(NULL,				// default security
								  0,				// default stack size
								  DataReadThread,	// pointer to thread routine
								  NULL,				// argument for thread
								  0,				// start it right away
								  &dwIdThread);
	if(!hReadThread)
		return false;

	SetThreadPriority(hReadThread, g_objGameDataSet.m_dwReadThreadPriority);

	return true;
}

//--------------------------------------------------------------
void DataReadThreadDestroy(void)
{
	while (true)
	{
		if (dequeDataToLoad.size() <= 0)
			break;

		Sleep(50);		
	}

	if(hReadThread)
	{
		SetEvent(hExitEvent);

		Sleep(100);	// waiting for thread exit
		CloseHandle(hReadThread);
		hReadThread	=NULL;
	}
	
	if(hReadEvent)
	{
		CloseHandle(hReadEvent);
		hReadEvent	=NULL;
	}

	if(hExitEvent)
	{
		CloseHandle(hExitEvent);
		hExitEvent	=NULL;
	}
}


//--------------------------------------------------------------
// CGameDataSet
//--------------------------------------------------------------
CGameDataSet::CGameDataSet(void)
{
}

CGameDataSet::~CGameDataSet(void)
{
	this->Destroy();
	//------------------------------------
	::DeleteCriticalSection(&csReadThread);
	extern CRITICAL_SECTION	sAniCritical;
	::DeleteCriticalSection(&sAniCritical);
}

//--------------------------------------------------------------
void CGameDataSet::Init(void)
{
	DWORD m_dw3DMotionLife			=	30*1000;
	DWORD m_dw3DTextureLife			=	30*1000;
	DWORD m_dw3DEffectLife			=	30*1000;
	DWORD m_dwPuzzleLife			=	30*1000;
	DWORD m_dwPuzzlePreloadSize		=	1;
	DWORD m_dwReadThreadPriority	=	THREAD_PRIORITY_NORMAL;

	this->InitSystemPolicy();

	m_mapDataAni.clear();
	m_set3DObj.clear();
	m_set3DMotion.clear();
	m_set3DWeaponMotion.clear();
	m_set3DMantleMotion.clear();
	m_set3DMountMotion.clear();
	m_set3DTexture.clear();
	m_set3DEffect.clear();
	m_setEmotion.clear ();
	
	this->LoadRes("ini/3dobj.ini", m_mapResMesh);
	this->LoadRes("ini/3dtexture.ini", m_mapResTexture);
	this->LoadRes("ini/3dmotion.ini", m_mapResMotion);	
	this->LoadRes("ini/3deffectobj.ini", m_mapResEffectObj);
	this->LoadRes("ini/weaponmotion.ini", m_mapResWeaponMotion);
	this->LoadRes("ini/mantlemotion.ini", m_mapResMantleMotion);
	this->LoadRes("ini/mountmotion.ini", m_mapResMountMotion);
	this->LoadRes("ini/sound.ini", m_mapSound);
	this->CreateItemEffectInfo();
	::InitializeCriticalSection(&csReadThread);
	extern CRITICAL_SECTION	sAniCritical;
	::InitializeCriticalSection(&sAniCritical);
	if (!::DataReadThreadInit())
		::ErrorOut("动态数据读入线程初始化错误!");

	m_timerCheck = ::TimeGet();
	g_dwDeadLine	= 10000;

	// open pack data file
	this->InitDnp();
	m_objStrRes.Init();
	this->CreateEmotionInfo ();
}

//--------------------------------------------------------------
void CGameDataSet::InitSystemPolicy(void)
{
	// get total memory
	MEMORYSTATUS stat;
	::GlobalMemoryStatus(&stat);
	char szTitle[64];
	if(stat.dwTotalPhys >= 400*1000*1000)
		strcpy(szTitle, "MEM512");
	else if(stat.dwTotalPhys >= 192*1000*1000)
		strcpy(szTitle, "MEM256");
	else
		strcpy(szTitle, "MEM128");

	const char szCommon[] = "ini/common.ini";
	char szSubtitle[128];
	int nData;
	strcpy(szSubtitle, "3DMotionLife");
	if(::IniDataGet(szCommon, szTitle, szSubtitle, nData))
		m_dw3DMotionLife = nData;

	strcpy(szSubtitle, "3DTextureLife");
	if(::IniDataGet(szCommon, szTitle, szSubtitle, nData))
		m_dw3DTextureLife = nData;

	strcpy(szSubtitle, "3DEffectLife");
	if(::IniDataGet(szCommon, szTitle, szSubtitle, nData))
		m_dw3DEffectLife = nData;

	strcpy(szSubtitle, "PuzzleLife");
	if(::IniDataGet(szCommon, szTitle, szSubtitle, nData))
		m_dwPuzzleLife = nData;

	strcpy(szSubtitle, "PuzzlePreloadSize");
	if(::IniDataGet(szCommon, szTitle, szSubtitle, nData))
		m_dwPuzzlePreloadSize = nData;

	strcpy(szSubtitle, "ReadThreadPriority");
	if(::IniDataGet(szCommon, szTitle, szSubtitle, nData))
	{
		switch(nData)
		{
		case -1:
			m_dwReadThreadPriority = THREAD_PRIORITY_BELOW_NORMAL;
			break;
		case 0:
			m_dwReadThreadPriority = THREAD_PRIORITY_NORMAL;
			break;
		case 1:
			m_dwReadThreadPriority = THREAD_PRIORITY_ABOVE_NORMAL;
			break;
		default:
			m_dwReadThreadPriority = THREAD_PRIORITY_NORMAL;
			break;
		}
	}
}
//--------------------------------------------------------------
void CGameDataSet::Destroy	(void)
{
	// got anyting to load by loading thread?
	::DataReadThreadDestroy();

	// free pack data file
	::MyDataFileClose();

	this->DestroyDataAni();
	this->Destroy3DMotion();
	this->Destroy3DObj();
	this->Destroy3DTexture();
	this->Destroy3DEffect();
	this->Destroy3DWeaponMotion();
	this->Destroy3DMantleMotion();
	this->DestroyItemEffectInfo();
	// res
	m_mapResMesh.clear();
	m_mapResMotion.clear();
	m_mapResTexture.clear();
	m_mapResEffectObj.clear();
	m_mapResWeaponMotion.clear();
	m_mapResMantleMotion.clear();
	m_objStrRes.Destroy();
	m_mapSound.clear();
	m_setEmotion.clear ();
	// quit 3d device now
	CMyBitmap::Quit3D();
	SAFE_DELETE(CAni::s_pDai);
	SAFE_DELETE(CAni::s_pFrameSet);
}

//--------------------------------------------------------------
void CGameDataSet::LoadRes(const char* pszResFile, MAP_RES& mapRes)
{
	if (!pszResFile)
		return;

	FILE* fp = fopen(pszResFile, "r");
	if (!fp)
	{
		::ErrorOut("can't open file:%s!", pszResFile);
		return;
	}

	mapRes.clear();
	while(true)
	{
		char szLine[1024] = "";
		if (EOF == fscanf(fp, "%s\n", szLine))
			break;

		OBJID id = ID_NONE;
		char szFile[256]	= "";

		if (2 == sscanf(szLine, "%u=%s", &id, szFile))
		{
			string strFile = szFile;
			mapRes[id] = strFile; 
		}
	}

	fclose(fp);
}

//--------------------------------------------------------------
void CGameDataSet::Process(void)
{
	this->ProcessDataAni();
	this->Process3DMotionSet();
	this->Process3DWeaponMotionSet();
	this->Process3DMantalMotionSet();
	//this->Process3DObjSet();
	this->Process3DTextureSet();
	this->Process3DEffectSet();
}

DWORD g_dwEgLoad = 0, g_dwImLoad = 0, g_dwNmLoad = 0;

//--------------------------------------------------------------
//--------------------------------------------------------------
CAni* CGameDataSet::GetDataAni	(const char* pszFileName, const char* pszTitle, int nExigence, DWORD dwLife)
{
	// check ...
	if((!pszFileName || strlen(pszFileName) < 1) || (!pszTitle || strlen(pszTitle) < 1) )
		return NULL;

	// CreateID
	static char szTemp[256];
	strcpy(szTemp, pszFileName);
	strcat((char*)szTemp, pszTitle);

	extern DWORD Str2ID( const char* str );
	OBJID idAni = Str2ID(szTemp);

	// search ...
	MAP_DYNAMICANI::iterator iter = m_mapDataAni.find(idAni);
	if(iter != m_mapDataAni.end())
	{
		CDynamicAni* pDAni = iter->second;
		if (pDAni)
		{
			// found it!
			switch (pDAni->GetStatus())
			{
			case ANISTATUS_INIT:
			case ANISTATUS_LOADING:
				{
					if (nExigence == EXIGENCE_IMMEDIATE)
					{	
						g_dwEgLoad ++;

						// still waiting load?
						if (ANISTATUS_INIT == pDAni->GetStatus())
							::UpPriority(pDAni);

						// we must waiting the accomplish of data loading 
						DWORD timeBegin = ::TimeGet();
						while (ANISTATUS_INIT == pDAni->GetStatus() 
								|| ANISTATUS_LOADING == pDAni->GetStatus())
						{
							::Sleep(30);
							if (::TimeGet() >= timeBegin+3000)
							{
								::LogMsg("Error: can't complete ani loading in 3 sec. ani(%s :%s)", pDAni->m_szIniFile, pDAni->m_szIndex);
								timeBegin = ::TimeGet();
							}
						}
						
						// loading complished
						if (ANISTATUS_LOADED == pDAni->GetStatus())
						{
							pDAni->ResetLife();
							return pDAni;
						}
						else
						{
							return NULL;
						}
					}
					else
						return NULL;
				}
				break;

			case ANISTATUS_LOADED:
				{
					pDAni->ResetLife();
					return pDAni;
				}
				break;
				
			case ANISTATUS_FAILED:
				{
#ifdef _DEBUG
//					::ErrorOut("ERROR: hahaha Ani:[%s] of [%s] load failed", pszTitle, pszFileName);
#endif
					m_mapDataAni.erase(iter);
					SAFE_DELETE (pDAni);
					return NULL;
				}
				break;
				
			default:
				{
					::ErrorOut("ERROR: Ani:[%s] of [%s] got invalid status:%u CGameDataSet::GetDataAni()", pszTitle, pszFileName, pDAni->GetStatus());

					m_mapDataAni.erase(iter);
					SAFE_DELETE (pDAni);
					return NULL;
				}
				break;
			}							
		}
		else
		{
			::LogMsg("Error: found invalid data ani in CGameDataSet::GetDataAni()");

			m_mapDataAni.erase(iter);
		}
	}

	// ani data not found, so we must create new one...
	//CAni::s_setAniFile.AddAniFile((char*)pszFileName);
	CAni::s_pDai->Load(pszFileName, true);
	CDynamicAni* pNewDAni = new CDynamicAni(pszFileName, pszTitle);
	if (!pNewDAni)
		return NULL;

	pNewDAni->SetLife(dwLife);
	if (EXIGENCE_IMMEDIATE == nExigence)
	{
		g_dwImLoad ++;
		if (pNewDAni->Load() && ANISTATUS_LOADED == pNewDAni->GetStatus())
		{
			m_mapDataAni[pNewDAni->m_idAni] = pNewDAni;
			return pNewDAni;
		}
		else
		{
#ifdef _DEBUG
			::ErrorOut("ERROR: Ani:[%s] not found in [%s]", pszTitle, pszFileName);
#endif
			// Test if the resource is the second resource
			if ( strcmp ( pszFileName, "ani/Control2.Ani" ) == 0 )
				::PostCmd(CMD_RESOURCE_LOSE) ;

			SAFE_DELETE (pNewDAni) ;
			return NULL;
		}

⌨️ 快捷键说明

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