// init level-info subsystem void LoadLevelsList(void) { CPrintF(TRANSV("Reading levels directory...\n")); // list the levels directory with subdirs CDynamicStackArray<CTFileName> afnmDir; MakeDirList(afnmDir, CTString("Levels\\"), CTString("*.wld"), DLI_RECURSIVE|DLI_SEARCHCD); // for each file in the directory for (INDEX i=0; i<afnmDir.Count(); i++) { CTFileName fnm = afnmDir[i]; CPrintF(TRANSV(" file '%s' : "), (const char *)fnm); // try to load its info, and if valid CLevelInfo li; if (GetLevelInfo(li, fnm)) { CPrintF(TRANSV("'%s' spawn=0x%08x\n"), (const char *) li.li_strName, li.li_ulSpawnFlags); // create new info for that file CLevelInfo *pliNew = new CLevelInfo; *pliNew = li; // add it to list of all levels _lhAllLevels.AddTail(pliNew->li_lnNode); } else { CPrintF(TRANSV("invalid level\n")); } } // sort the list _lhAllLevels.Sort(qsort_CompareLevels, _offsetof(CLevelInfo, li_lnNode)); }
void CStageLoading::Init() { CLoadingImage::getSingleton()->InitLoadingData(); CUIManager* pUIManager = CUIManager::getSingleton(); _pNetwork->TogglePause(); if(CZoneInfo::getSingleton()->GetZoneType(g_slZone) == ZONE_SDUNGEON) { CPrintF("===Start Single Mode===\n"); _pNetwork->m_bSingleMode = TRUE; _pNetwork->wo_dwEnemyCount = 0; _pNetwork->wo_dwKilledEnemyCount = 0; ((CPlayerEntity*)CEntity::GetPlayerEntity(0))->SingleModeOn(); } else { CPrintF("===End Single Mode===\n"); _pNetwork->m_bSingleMode = FALSE; pUIManager->GetSingleBattle()->Close(); ((CPlayerEntity*)CEntity::GetPlayerEntity(0))->FieldModeOn(); } _pNetwork->ChangeLevel(CZoneInfo::getSingleton()->GetZoneWldFile(g_slZone), FALSE, 0); _pNetwork->SetLoadingZone( g_slZone ); pUIManager->SetUIGameState(); pUIManager->GetGame()->gm_bGameOn = FALSE; _pGameState->GetGameMode() = CGameState::GM_NETWORK; EPreLevelChange ePreChange; ePreChange.iUserData = _pNetwork->ga_iNextLevelUserData; _pNetwork->ga_sesSessionState.SendLevelChangeNotification(ePreChange); CEntity::HandleSentEvents(); _pNetwork->ChangeLevel_internal(); EPostLevelChange ePostChange; ePostChange.iUserData = _pNetwork->ga_iNextLevelUserData; _pNetwork->ga_sesSessionState.SendLevelChangeNotification(ePostChange); CEntity::HandleSentEvents(); _lphCurrent=LCP_NOCHANGE; for(std::vector<CEntity*>::iterator iter = _pNetwork->ga_World.m_vectorPreCreateNPC.begin(); iter != _pNetwork->ga_World.m_vectorPreCreateNPC.end(); ++iter) { (*iter)->Reinitialize(); } _pNetwork->ga_World.m_vectorPreCreateNPC.clear(); if (g_slZone == 42) // 임시 설정. { _pNetwork->SetRvrZone(TRUE); ACTORMGR()->initSyndiMark(); } else _pNetwork->SetRvrZone(FALSE); m_bGameStart = false; pUIManager->GetOption()->UpdateTerMul(); }
// initialize/end the decoding support engine(s) void CSoundDecoder::InitPlugins(void) { try { // load vorbis if (_hOV==NULL) { #ifndef NDEBUG //안태훈 수정 시작 //(Exception Check & Fix)(0.1) #define VORBISLIB "vorbisfile.dll" // #define VORBISLIB "vorbisfile_d.dll" //안태훈 수정 끝 //(Exception Check & Fix)(0.1) #else #define VORBISLIB "vorbisfile.dll" #endif _hOV = ::LoadLibrary(VORBISLIB); } if( _hOV == NULL) { ThrowF_t(TRANS("Cannot load vorbisfile.dll.")); } // prepare function pointers OV_SetFunctionPointers_t(); // if all successful, enable mpx playing _bOVEnabled = TRUE; CPrintF(TRANS(" vorbisfile.dll loaded, ogg playing enabled\n")); } catch (char *strError) { CPrintF(TRANS("OGG playing disabled: %s\n"), strError); } try { // load amp11lib if (_hAmp11lib==NULL) { _hAmp11lib = ::LoadLibrary( "amp11lib.dll"); } if( _hAmp11lib == NULL) { ThrowF_t(TRANS("Cannot load amp11lib.dll.")); } // prepare function pointers AMP11_SetFunctionPointers_t(); // initialize amp11lib before calling any of its functions palInitLibrary(); // if all successful, enable mpx playing _bAMP11Enabled = TRUE; CPrintF(TRANS(" amp11lib.dll loaded, mpx playing enabled\n")); } catch (char *strError) { CPrintF(TRANS("MPX playing disabled: %s\n"), strError); } }
// inits imm ifeel device BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd) { _pShell->DeclareSymbol("void inp_IFeelGainChange(INDEX);", &ifeel_GainChange); _pShell->DeclareSymbol("persistent user FLOAT inp_fIFeelGain post:inp_IFeelGainChange;", &ifeel_fGain); _pShell->DeclareSymbol("const user INDEX sys_bIFeelEnabled;", &ifeel_bEnabled); IFeel_ChangeGain(ifeel_fGain); // load iFeel lib CTFileName fnmExpanded; #ifndef WORLD_EDITOR ExpandFilePath(EFP_READ | EFP_NOZIPS,(CTString)IFEEL_DLL_NAME,fnmExpanded); #else // WORLD_EDITOR fnmExpanded = _fnmApplicationPath + _fnmApplicationExe.FileDir() + "ImmWrapper.dll"; #endif // WORLD_EDITOR if(_hLib!=NULL) return FALSE; UINT iOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS); _hLib = LoadLibrary(fnmExpanded); SetErrorMode(iOldErrorMode); if(_hLib==NULL) { CPrintF("Error loading ImmWraper.dll.\n\tIFeel disabled\n"); return FALSE; } // take func pointers immCreateDevice = (BOOL(*)(HINSTANCE &hInstance, HWND &hWnd)) GetProcAddress(_hLib,"Imm_CreateDevice"); immDeleteDevice = (void(*)(void)) GetProcAddress(_hLib,"Imm_DeleteDevice"); immProductName = (BOOL(*)(char *strProduct,int iMaxCount)) GetProcAddress(_hLib,"Imm_GetProductName"); immLoadFile = (BOOL(*)(const char *fnFile))GetProcAddress(_hLib,"Imm_LoadFile"); immUnloadFile = (void(*)(void))GetProcAddress(_hLib,"immUnloadFile"); immPlayEffect = (void(*)(const char *pstrEffectName))GetProcAddress(_hLib,"Imm_PlayEffect"); immStopEffect = (void(*)(const char *pstrEffectName))GetProcAddress(_hLib,"Imm_StopEffect"); immChangeGain = (void(*)(const float fGain))GetProcAddress(_hLib,"Imm_ChangeGain"); // create device if(immCreateDevice == NULL) { return FALSE; } BOOL hr = immCreateDevice(hInstance,hWnd); if(!hr) { CPrintF("IFeel mouse not found.\n"); IFeel_DeleteDevice(); return FALSE; } CPrintF("IFeel mouse '%s' initialized\n",(const char*)IFeel_GetProductName()); ifeel_bEnabled = TRUE; return TRUE; }
static void LoadOneFile(const CTFileName &fnm) { try { // open the file CTFileStream strm; strm.Open_t(fnm); // count number of lines INDEX ctLines = 0; while(!strm.AtEOF()) { CTString strLine; strm.GetLine_t(strLine); ctLines++; } strm.SetPos_t(0); // allocate that much CTString *astr = _astrCredits.Push(ctLines); // load all lines for(INDEX iLine = 0; iLine<ctLines && !strm.AtEOF(); iLine++) { strm.GetLine_t(astr[iLine]); } strm.Close(); _bCreditsOn = TRUE; } catch (char *strError) { CPrintF("%s\n", strError); } }
// change parent of model instance void CModelInstance::ChangeParent(CModelInstance *pmiOldParent, CModelInstance *pmiNewParent) { SKAASSERT(pmiOldParent!=NULL); SKAASSERT(pmiNewParent!=NULL); if(pmiOldParent == NULL) { CPrintF("Model Instance doesn't have a parent\n"); return; } if(pmiNewParent == NULL) { CPrintF("New parent of model instance is NULL\n"); return; } pmiOldParent->mi_cmiChildren.Remove(this); pmiNewParent->mi_cmiChildren.Add(this); }
void RenderMessagePicture(CDrawPort *pdp) { CCompMessage &cm = _acmMessages[_iActiveMessage]; // try to try { // load image _toPicture.SetData_t(cm.cm_fnmPicture); ((CTextureData*)_toPicture.GetData())->Force(TEX_CONSTANT); // if failed } catch(char *strError) { // report error CPrintF("Cannot load '%s':\n%s\n", (CTString&)cm.cm_fnmPicture, strError); // do nothing return; } // get image and box sizes PIX pixImgSizeI = _toPicture.GetWidth(); PIX pixImgSizeJ = _toPicture.GetHeight(); PIXaabbox2D boxPic(PIX2D(_pixMarginI, _pixMarginJ), PIX2D(_boxMsgImage.Size()(1)-_pixMarginI, _boxMsgImage.Size()(2)-_pixMarginJ)); PIX pixBoxSizeI = boxPic.Size()(1); PIX pixBoxSizeJ = boxPic.Size()(2); PIX pixCenterI = _boxMsgImage.Size()(1)/2; PIX pixCenterJ = _boxMsgImage.Size()(2)/2; // find image stretch to fit in box FLOAT fStretch = Min(FLOAT(pixBoxSizeI)/pixImgSizeI, FLOAT(pixBoxSizeJ)/pixImgSizeJ); // draw the image pdp->PutTexture(&_toPicture, PIXaabbox2D( PIX2D(pixCenterI-pixImgSizeI*fStretch/2, pixCenterJ-pixImgSizeJ*fStretch/2), PIX2D(pixCenterI+pixImgSizeI*fStretch/2, pixCenterJ+pixImgSizeJ*fStretch/2))); }
void InitializeGame(void) { try { #ifndef NDEBUG #define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+"D.dll" #else #define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+".dll" #endif CTFileName fnmExpanded; ExpandFilePath(EFP_READ, CTString(GAMEDLL), fnmExpanded); CPrintF(TRANS("Loading game library '%s'...\n"), (const char *)fnmExpanded); HMODULE hGame = LoadLibraryA(fnmExpanded); if (hGame==NULL) { ThrowF_t("%s", GetWindowsError(GetLastError())); } CGame* (*GAME_Create)(void) = (CGame* (*)(void))GetProcAddress(hGame, "GAME_Create"); if (GAME_Create==NULL) { ThrowF_t("%s", GetWindowsError(GetLastError())); } _pGame = GAME_Create(); } catch (char *strError) { FatalError("%s", strError); } // init game - this will load persistent symbols _pGame->Initialize(CTString("Data\\DedicatedServer.gms")); }
void ExecScript(const CTString &str) { CPrintF("Executing: '%s'\n", str); CTString strCmd; strCmd.PrintF("include \"%s\"", str); _pShell->Execute(strCmd); }
extern void ModConnectConfirm(void) { CConfirmMenu &gmCurrent = _pGUIM->gmConfirmMenu; if (_fnmModSelected == " ") { _fnmModSelected = CTString("SeriousSam"); } CTFileName fnmModPath = "Mods\\" + _fnmModSelected + "\\"; if (!FileExists(fnmModPath + "BaseWriteInclude.lst") && !FileExists(fnmModPath + "BaseWriteExclude.lst") && !FileExists(fnmModPath + "BaseBrowseInclude.lst") && !FileExists(fnmModPath + "BaseBrowseExclude.lst")) { extern void ModNotInstalled(void); ModNotInstalled(); return; } CPrintF(TRANS("Server is running a different MOD (%s).\nYou need to reload to connect.\n"), (const char *) _fnmModSelected); gmCurrent._pConfimedYes = &ModConnect; gmCurrent._pConfimedNo = NULL; gmCurrent.gm_mgConfirmLabel.mg_strText = TRANS("CHANGE THE MOD?"); gmCurrent.gm_pgmParentMenu = pgmCurrentMenu; gmCurrent.BeLarge(); ChangeToMenu(&gmCurrent); }
// Initialize the console. void CConsole::Initialize(const CTFileName &fnmLog, INDEX ctCharsPerLine, INDEX ctLines) { con_csConsole.cs_iIndex = -1; // synchronize access to console CTSingleLock slConsole(&con_csConsole, TRUE); // allocate the buffer con_ctCharsPerLine = ctCharsPerLine; con_ctLines = ctLines; con_ctLinesPrinted = 0; // note: we add +1 for '\n' perline and +1 '\0' at the end of buffer con_strBuffer = (char *)AllocMemory((ctCharsPerLine+2)*ctLines+1); con_strLineBuffer = (char *)AllocMemory(ctCharsPerLine+2); // includes '\n' and '\0' con_atmLines = (TIME*)AllocMemory((ctLines+1)*sizeof(TIME)); // make it empty for(INDEX iLine=0; iLine<ctLines; iLine++) { ClearLine(iLine); } // add string terminator at the end con_strBuffer[(ctCharsPerLine+1)*ctLines] = 0; // start printing in last line con_strLastLine = con_strBuffer+(ctCharsPerLine+1)*(ctLines-1); con_strCurrent = con_strLastLine; //안태훈 수정 시작 //(Block Log)(0.1) //CreateLogFile(fnmLog); //로그파일 생성을 막는다. //안태훈 수정 끝 //(Block Log)(0.1) // print one dummy line on start CPrintF("\n"); }
void CAM_Start(const CTFileName &fnmDemo) { _bCameraOn = FALSE; CTFileName fnmScript = fnmDemo.NoExt()+".ini"; if( cam_bRecord) { try { _strScript.Create_t(fnmScript); } catch(char *strError) { CPrintF("Camera: %s\n", strError); return; }; _cp.cp_vPos = FLOAT3D(0,0,0); _cp.cp_aRot = ANGLE3D(0,0,0); _cp.cp_aFOV = 90.0f; _cp.cp_fSpeed = 1; _cp.cp_tmTick = 0.0f; } else { try { _strScript.Open_t(fnmScript); } catch(char *strError) { (void)strError; return; }; } _bCameraOn = TRUE; _bInitialized = FALSE; }
CTString IFeel_GetProjectFileName() { CTString strIFeelTable; CTFileName fnIFeelTable = (CTString)"Data\\IFeel.txt"; CTString strDefaultProjectFile = "Data\\Default.ifr"; // get product name CTString strProduct = IFeel_GetProductName(); try { strIFeelTable.Load_t(fnIFeelTable); } catch(char *strErr) { CPrintF("%s\n",strErr); return ""; } CTString strLine; // read up to 1000 devices for(INDEX idev=0;idev<1000;idev++) { char strDeviceName[256]; char strProjectFile[256]; strLine = strIFeelTable; // read first line strLine.OnlyFirstLine(); if(strLine==strIFeelTable) { break; } // remove that line strIFeelTable.RemovePrefix(strLine); strIFeelTable.DeleteChar(0); // read device name and project file name strIFeelTable.ScanF("\"%256[^\"]\" \"%256[^\"]\"",&strDeviceName,&strProjectFile); // check if this is default if(strcmp(strDeviceName,"Default")==0) strDefaultProjectFile = strProjectFile; // check if this is current device if(strProduct == strDeviceName) return strProjectFile; } // device was not found, return default project file CPrintF("No project file specified for device '%s'.\nUsing default project file\n",strProduct); return strDefaultProjectFile; }
void CUnixDynamicLoader::SetError(void) { const char *errmsg = ::dlerror(); delete err; err = NULL; if (errmsg != NULL) { CPrintF("CUnixDynamicLoader error: %s\n", errmsg); err = new CTString(errmsg); } }
// loads project file BOOL IFeel_LoadFile(CTFileName fnFile) { CTFileName fnmExpanded; ExpandFilePath(EFP_READ | EFP_NOZIPS,fnFile,fnmExpanded); if(immLoadFile!=NULL) { BOOL hr = immLoadFile((const char*)fnmExpanded); if(hr) { CPrintF("IFeel project file '%s' loaded\n", fnFile); return TRUE; } else { CPrintF("Error loading IFeel project file '%s'\n", fnFile); return FALSE; } } return FALSE; }
// read one block from buffer to stream BOOL CBlockBuffer::ReadBlockToStream(CTStream &strm) { // must not be inside block reading ASSERT(bb_slBlockSizeRead==0); // read header of next block in incoming buffer struct BlockHeader bh; SLONG slbhSize; slbhSize = ReadBytes(&bh, sizeof(bh)); // if the header information is not in buffer if (slbhSize < sizeof(bh)) { // unwind UnreadBytes(slbhSize); // nothing to receive return FALSE; } // if the block has not yet been received if (QueryReadBytes() < bh.bh_slSize) { // unwind UnreadBytes(slbhSize); // nothing to receive return FALSE; } // if using stats if (bb_pbbsStats!=NULL) { // if block could not have been received yet, due to time limits if (bh.bh_tvFinalTime>_pTimer->GetHighPrecisionTimer()) { // unwind UnreadBytes(slbhSize); // nothing to receive return FALSE; } } // read from buffer to destination buffer try { SLONG slSize = ReadBytesToStream(strm, bh.bh_slSize); ASSERT(slSize == bh.bh_slSize); } catch (char *strError) { ASSERT(FALSE); CPrintF(TRANS("Buffer error reading to stream: %s\n"), strError); return FALSE; } return TRUE; }
void ReadPos(CCameraPos &cp) { try { CTString strLine; _strScript.GetLine_t(strLine); strLine.ScanF("%g: %g: %g %g %g:%g %g %g:%g", &cp.cp_tmTick, &cp.cp_fSpeed, &cp.cp_vPos(1), &cp.cp_vPos(2), &cp.cp_vPos(3), &cp.cp_aRot(1), &cp.cp_aRot(2), &cp.cp_aRot(3), &cp.cp_aFOV); } catch (char *strError) { CPrintF("Camera: %s\n", strError); } }
void WritePos(CCameraPos &cp) { try { CTString strLine; strLine.PrintF("%g: %g: %g %g %g:%g %g %g:%g", _pTimer->GetLerpedCurrentTick()-_fStartTime, 1.0f, cp.cp_vPos(1), cp.cp_vPos(2), cp.cp_vPos(3), cp.cp_aRot(1), cp.cp_aRot(2), cp.cp_aRot(3), cp.cp_aFOV); _strScript.PutLine_t(strLine); } catch (char *strError) { CPrintF("Camera: %s\n", strError); } }
// add one file to active list and get its crc void CRCT_AddFile_t(const CTFileName &fnm, ULONG ulCRC/*=0*/) // throw char * { // if not gathering CRCs now if (!CRCT_bGatherCRCs) { // do nothing return; } // try to find it in table CCRCEntry *pce = _ntEntries.Find(fnm); BOOL bNew = FALSE; // if found if (pce!=NULL) { // just activate it bNew = !pce->ce_bActive; pce->ce_bActive = TRUE; // if crc is given if (ulCRC!=0) { // force it pce->ce_ulCRC = ulCRC; } // if not found } else { // calculate checksum if (ulCRC==0) { if (FileMatchesList(_afnmNoCRC, fnm)) { ulCRC = 0x12345678; } else { ulCRC = GetFileCRC32_t(fnm); } } // add to the table pce = &_aceEntries.Push(); pce->ce_fnmFile = fnm; pce->ce_ulCRC = ulCRC; pce->ce_bActive = TRUE; _ntEntries.Add(pce); bNew = TRUE; } if (bNew && net_bReportCRC) { CPrintF("CRC %08x: '%s'\n", pce->ce_ulCRC, (const char*)pce->ce_fnmFile); } }
void CMGTrigger::Render(CDrawPort *pdp) { SetFontMedium(pdp); PIXaabbox2D box = FloatBoxToPixBox(pdp, mg_boxOnScreen); PIX pixIL = box.Min()(1) + box.Size()(1)*0.45f; PIX pixIR = box.Min()(1) + box.Size()(1)*0.55f; PIX pixJ = box.Min()(2); COLOR col = GetCurrentColor(); if (!mg_bVisual || mg_strValue == "") { CTString strValue = mg_strValue; if (mg_bVisual) { strValue = TRANS("none"); } if (mg_iCenterI == -1) { pdp->PutText(mg_strLabel, box.Min()(1), pixJ, col); pdp->PutTextR(strValue, box.Max()(1), pixJ, col); } else { pdp->PutTextR(mg_strLabel, pixIL, pixJ, col); pdp->PutText(strValue, pixIR, pixJ, col); } } else { CTString strLabel = mg_strLabel + ": "; pdp->PutText(strLabel, box.Min()(1), pixJ, col); CTextureObject to; try { to.SetData_t(mg_strValue); CTextureData *ptd = (CTextureData *)to.GetData(); PIX pixSize = box.Size()(2); PIX pixCX = box.Max()(1) - pixSize / 2; PIX pixCY = box.Center()(2); pdp->PutTexture(&to, PIXaabbox2D( PIX2D(pixCX - pixSize / 2, pixCY - pixSize / 2), PIX2D(pixCX - pixSize / 2 + pixSize, pixCY - pixSize / 2 + pixSize)), C_WHITE | 255); } catch (char *strError) { CPrintF("%s\n", strError); } to.SetData(NULL); } }
// load a filelist static BOOL LoadFileList(CDynamicStackArray<CTFileName> &afnm, const CTFileName &fnmList) { afnm.PopAll(); try { CTFileStream strm; strm.Open_t(fnmList); while(!strm.AtEOF()) { CTString strLine; strm.GetLine_t(strLine); strLine.TrimSpacesLeft(); strLine.TrimSpacesRight(); if (strLine!="") { afnm.Push() = strLine; } } return TRUE; } catch(char *strError) { CPrintF("%s\n", strError); return FALSE; } }
void CCommunicationInterface::InitWinsock(void) { #ifdef PLATFORM_WIN32 if (cci_bWinSockOpen) { return; } // start winsock WSADATA winsockdata; WORD wVersionRequested; wVersionRequested = MAKEWORD(1, 1); int iResult = WSAStartup(wVersionRequested, &winsockdata); // if winsock open ok if (iResult==0) { // remember that cci_bWinSockOpen = TRUE; CPrintF(TRANSV(" winsock opened ok\n")); } #else cci_bWinSockOpen = TRUE; #endif };
// write bytes to buffer void CBuffer::WriteBytes(const void *pv, SLONG slSize) { ASSERT(slSize>=0 && pv!=NULL); // if there is nothing to write if (slSize==0) { // do nothing return; } // check for errors if (slSize<0) { CPrintF("WARNING: WriteBytes(): slSize<0\n!"); return; } // if there is not enough free space if (bu_slFree<slSize) { // expand the buffer Expand(bu_slSize+ ((slSize-bu_slFree+bu_slAllocationStep-1)/bu_slAllocationStep)*bu_slAllocationStep ); ASSERT(bu_slFree>=slSize); } UBYTE *pub = (UBYTE*)pv; // write part of block at the end of buffer SLONG slSizeEnd = __min(bu_slSize-bu_slWriteOffset, slSize); memcpy(bu_pubBuffer+bu_slWriteOffset, pub, slSizeEnd); pub+=slSizeEnd; memcpy(bu_pubBuffer, pub, slSize-slSizeEnd); // move write pointer bu_slWriteOffset+=slSize; bu_slWriteOffset%=bu_slSize; bu_slFree-=slSize; ASSERT(bu_slWriteOffset>=0 && bu_slWriteOffset<bu_slSize); ASSERT(bu_slFree>=0 && bu_slFree<=bu_slSize); }
/* Benchmark current driver. */ void CGfxLibrary::Benchmark(CViewPort *pvp, CDrawPort *pdp) { // remember drawport/viewport _pdp = pdp; _pvp = pvp; _pixSizeI = pdp->GetWidth(); _pixSizeJ = pdp->GetHeight(); CTString strAPI = ""; if( _pGfx->gl_eCurrentAPI==GAT_OGL) strAPI = "OpenGL"; #ifdef SE1_D3D else if( _pGfx->gl_eCurrentAPI==GAT_D3D) strAPI = "Direct3D"; #endif // SE1_D3D CPrintF("=====================================\n"); CPrintF("%s performance testing ...\n", (const char *) strAPI); InitTexture(); InitTris(); CPrintF("\n--- Texture upload\n"); _ulTexFormat = TS.ts_tfRGBA8; _bSubImage = FALSE; RunTest(TextureUpload, 10); CPrintF("RGBA8 full: %6.02f +- %5.02f Mtex/s;" , _dX/1000/1000, _dD/1000/1000); _bSubImage = TRUE; RunTest(TextureUpload, 10); CPrintF( " sub: %6.02f +- %5.02f Mtex/s\n", _dX/1000/1000, _dD/1000/1000); _ulTexFormat = TS.ts_tfRGB8; _bSubImage = FALSE; RunTest(TextureUpload, 10); CPrintF("RGB8 full: %6.02f +- %5.02f Mtex/s;" , _dX/1000/1000, _dD/1000/1000); _bSubImage = TRUE; RunTest(TextureUpload, 10); CPrintF( " sub: %6.02f +- %5.02f Mtex/s\n", _dX/1000/1000, _dD/1000/1000); _ulTexFormat = TS.ts_tfRGBA4; _bSubImage = FALSE; RunTest(TextureUpload, 10); CPrintF("RGBA4 full: %6.02f +- %5.02f Mtex/s;" , _dX/1000/1000, _dD/1000/1000); _bSubImage = TRUE; RunTest(TextureUpload, 10); CPrintF( " sub: %6.02f +- %5.02f Mtex/s\n", _dX/1000/1000, _dD/1000/1000); _ulTexFormat = TS.ts_tfRGB5; _bSubImage = FALSE; RunTest(TextureUpload, 10); CPrintF("RGB5 full: %6.02f +- %5.02f Mtex/s;" , _dX/1000/1000, _dD/1000/1000); _bSubImage = TRUE; RunTest(TextureUpload, 10); CPrintF( " sub: %6.02f +- %5.02f Mtex/s\n", _dX/1000/1000, _dD/1000/1000); CPrintF("\n--- Fill rate\n"); _bMultiTexture = 0; _bBlend = 0; _bDepth = 0; _bTexture = 0; RunTest(FillRate, 10); CPrintF("%-38s %6.02f +- %5.02f Mpix/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); _bBlend = 0; _bDepth = 0; _bTexture = 1; RunTest(FillRate, 10); CPrintF("%-38s %6.02f +- %5.02f Mpix/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); _bBlend = 0; _bDepth = 1; _bTexture = 1; RunTest(FillRate, 10); CPrintF("%-38s %6.02f +- %5.02f Mpix/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); _bBlend = 1; _bDepth = 1; _bTexture = 1; RunTest(FillRate, 10); CPrintF("%-38s %6.02f +- %5.02f Mpix/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); if( _pGfx->gl_ctTextureUnits>1) { _bMultiTexture = 1; RunTest(FillRate, 10); CPrintF("%-38s %6.02f +- %5.02f Mpix/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); } CPrintF("\n--- Geometry speed (%dpix tris)\n", (_pixSizeI/_ctR)*(_pixSizeI/_ctC)/2); _bMultiTexture = 0; _bBlend = 0; _bDepth = 1; _bTexture = 1; RunTest(TrisTroughput, 10); CPrintF("%-34s %6.02f +- %5.02f Mtri/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); _bBlend = 1; _bDepth = 1; _bTexture = 1; RunTest(TrisTroughput, 10); CPrintF("%-34s %6.02f +- %5.02f Mtri/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); if( _pGfx->gl_ctTextureUnits>1) { _bMultiTexture = 1; RunTest(TrisTroughput, 10); CPrintF("%-34s %6.02f +- %5.02f Mtri/s\n", (const char *) FillRateString(), _dX/1000/1000, _dD/1000/1000); } EndTris(); EndTexture(); }
// ---------------------------------------------------------------------------- // Name : MouseMessage() // Desc : // ---------------------------------------------------------------------------- WMSG_RESULT CUIChildQuickSlot::MouseMessage( MSG *pMsg ) { WMSG_RESULT wmsgResult; // Title bar static BOOL bDragAreaClick = FALSE; // Extended button clicked static BOOL bLButtonDownInBtn = FALSE; // Mouse point static int nOldX, nOldY; int nX = LOWORD( pMsg->lParam ); int nY = HIWORD( pMsg->lParam ); // Mouse message switch( pMsg->message ) { case WM_MOUSEMOVE: { CUIManager* pUIManager = CUIManager::getSingleton(); m_bIsInside = IsInside( nX, nY ); if (m_bIsInside) { if (*(m_bRotation[m_nCurSlot]) == 0) // 0 세로 일 때 버튼 위치 설정 [12/21/2012 Ranma] { int nPosY = 16; for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++, nPosY += 35 ) { (*m_abtnItems)[m_nCurSlot + 1][iBtn]->SetPos( m_nPosX + 3,m_nPosY + nPosY); } } else { int nPosX = 16; for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++, nPosX += 35 ) { (*m_abtnItems)[m_nCurSlot + 1][iBtn]->SetPos( m_nPosX + nPosX, m_nPosY + 3); } } } if( IsInside( nX, nY ) ) pUIManager->SetMouseCursorInsideUIs(); int ndX = nX - nOldX; int ndY = nY - nOldY; if (pUIManager->GetDragIcon() == NULL && bLButtonDownInBtn && (pMsg->wParam & MK_LBUTTON) && (ndX != 0 || ndY != 0)&& !* (m_bLock[m_nCurSlot])) { if( m_nSelSlotBtnID >= 0 ) { ndX = abs( ndX ); ndY = abs( ndY ); static int nD = 7; CPrintF( "%d, %d", ndX, ndY ); if( ndX > nD || ndY > nD ) { int nSelTab = m_nCurSlot + 1; int nSelBtn = m_nSelSlotBtnID; pUIManager->SetHoldBtn( (*m_abtnItems)[nSelTab][nSelBtn] ); bLButtonDownInBtn = FALSE; } } } // Move quick slot if( bDragAreaClick && ( pMsg->wParam & MK_LBUTTON ) ) { nOldX = nX; nOldY = nY; Move( ndX, ndY ); SetPosEXQSlot(); return WMSG_SUCCESS; } else if( m_btnVertical.MouseMessage( pMsg ) != WMSG_FAIL ) { return WMSG_SUCCESS; } else if( m_btnHorizontal.MouseMessage( pMsg ) != WMSG_FAIL ) { return WMSG_SUCCESS; } if (*(m_bLock[m_nCurSlot])) { if( m_btnLock.MouseMessage( pMsg ) != WMSG_FAIL ) return WMSG_SUCCESS; } else { if( m_btnUnLock.MouseMessage( pMsg ) != WMSG_FAIL ) return WMSG_SUCCESS; } for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++ ) { if ((*m_abtnItems)[m_nCurSlot + 1][iBtn]->MouseMessage( pMsg ) != WMSG_FAIL) return WMSG_SUCCESS; } }break; case WM_LBUTTONDOWN: { m_bIsInside = IsInside( nX, nY ); m_nSelSlotBtnID = -1; if( IsInside( nX, nY ) ) { CUIManager* pUIManager = CUIManager::getSingleton(); nOldX = nX; nOldY = nY; // DregArea if( IsInsideRect( nX, nY, m_rcDragArea ) ) { bDragAreaClick = TRUE; } else if( m_btnVertical.MouseMessage( pMsg ) != WMSG_FAIL ) { } else if( m_btnHorizontal.MouseMessage( pMsg ) != WMSG_FAIL ) { } if (*(m_bLock[m_nCurSlot])) m_btnLock.MouseMessage( pMsg ); else m_btnUnLock.MouseMessage( pMsg ); for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++ ) { if( (*m_abtnItems)[m_nCurSlot + 1][iBtn]->MouseMessage( pMsg ) != WMSG_FAIL ) { // Update selected button m_nSelSlotBtnID = iBtn; bLButtonDownInBtn = TRUE; pUIManager->RearrangeOrder( m_nID, TRUE ); return WMSG_SUCCESS; } } pUIManager->RearrangeOrder( m_nID, TRUE ); return WMSG_SUCCESS; } }break; case WM_LBUTTONUP: { CUIManager* pUIManager = CUIManager::getSingleton(); bLButtonDownInBtn = FALSE; m_bIsInside = IsInside( nX, nY ); if (m_bIsInside) { if (*(m_bRotation[m_nCurSlot]) == 0) // 0 세로 일 때 버튼 위치 설정 [12/21/2012 Ranma] { int nPosY = 16; for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++, nPosY += 35 ) { (*m_abtnItems)[m_nCurSlot + 1][iBtn]->SetPos( m_nPosX + 3,m_nPosY + nPosY); } } else { int nPosX = 16; for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++, nPosX += 35 ) { (*m_abtnItems)[m_nCurSlot + 1][iBtn]->SetPos( m_nPosX + nPosX, m_nPosY + 3); } } } // If holding button doesn't exist if (pUIManager->GetDragIcon() == NULL) { // If quick slot isn't focused if( !IsFocused() ) return WMSG_FAIL; bDragAreaClick = FALSE; if (*(m_bLock[m_nCurSlot])) { if( m_btnLock.MouseMessage( pMsg ) != WMSG_FAIL ) { *(m_bLock[m_nCurSlot]) = 0; return WMSG_SUCCESS; } } else { if( m_btnUnLock.MouseMessage( pMsg ) != WMSG_FAIL ) { *(m_bLock[m_nCurSlot]) = 1; return WMSG_SUCCESS; } } if( m_btnVertical.MouseMessage( pMsg ) != WMSG_FAIL ) { *(m_bRotation[m_nCurSlot]) = 1; Rotation(); return WMSG_SUCCESS; } else if( m_btnHorizontal.MouseMessage( pMsg ) != WMSG_FAIL ) { *(m_bRotation[m_nCurSlot]) = 0; Rotation(); return WMSG_SUCCESS; } else if( IsInsideRect( nX, nY, m_rcDragArea ) ) { return WMSG_SUCCESS; } // Slot else if( IsInsideRect( nX, nY, m_rcSlot ) ) { m_nSelSlotBtnID = -1; for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++ ) { if( ( wmsgResult = (*m_abtnItems)[m_nCurSlot + 1][iBtn]->MouseMessage( pMsg ) ) != WMSG_FAIL ) { pUIManager->GetQuickSlot()->UseQuickSlot( iBtn , m_nCurSlot + 1); return WMSG_SUCCESS; } } } } // If holding button exists else { if( IsInside( nX, nY )) { pUIManager->GetMessenger()->SetDragging(false); CUIIcon* pDrag = pUIManager->GetDragIcon(); // If holding button comes from quick slot if (pDrag->GetWhichUI() == UI_QUICKSLOT) { if( IsInsideRect( nX, nY, m_rcSlot ) ) { for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++ ) { if ((*m_abtnItems)[m_nCurSlot + 1][iBtn]->IsInside( nX, nY ) && (*m_abtnItems)[m_nCurSlot + 1][iBtn]->GetQuickSlotID() != pDrag->GetQuickSlotID()) { int nBtnID = pDrag->GetQuickSlotID(); int nPageIndex = nBtnID / QSLOT_BTN_COUNT; int nSlotIndex = nBtnID % QSLOT_BTN_COUNT; if( !*(m_bLock[m_nCurSlot]) ) pUIManager->GetQuickSlot()->SwapBtnsInQuickSlot( nPageIndex, nSlotIndex, m_nCurSlot + 1, iBtn ); break; } } } } else if ((pDrag->getBtnType() == UBET_SKILL && (pDrag->GetWhichUI() == UI_SKILL_NEW || pDrag->GetWhichUI() == UI_CHARACTERINFO)) || (pDrag->getBtnType() == UBET_SKILL && pDrag->GetWhichUI() == UI_PETINFO) || (pDrag->getBtnType() == UBET_ACTION && pDrag->GetWhichUI() == UI_CHARACTERINFO) || (pDrag->getBtnType() == UBET_ITEM && pDrag->GetWhichUI() == UI_INVENTORY) || (pDrag->getBtnType() == UBET_SKILL && pDrag->GetWhichUI() == UI_WILDPET_INFO) || (pDrag->getBtnType() == UBET_SKILL && pDrag->GetWhichUI() == UI_GUILD)) { if( IsInsideRect( nX, nY, m_rcSlot ) ) { if (pDrag->getBtnType() == UBET_ITEM) { CItemData* pItemData = CItemData::getData(pDrag->getIndex()); if( (pItemData->GetType() == CItemData::ITEM_ETC //Etc(x) // [070604: Su-won] 1차 펫 기능 개선 // 생산품을 퀵슬롯에 넣을 수 있게... &&pItemData->GetSubType() !=CItemData::ITEM_ETC_PRODUCT ) || (pItemData->GetType() == CItemData::ITEM_ACCESSORY // Accessory(x) // [070604: Su-won] 1차 펫 기능 개선 // 펫을 퀵슬롯에 넣을 수 있게... && pItemData->GetSubType() !=CItemData::ACCESSORY_PET && pItemData->GetSubType() !=CItemData::ACCESSORY_WILDPET && pItemData->GetSubType() != CItemData::ITEM_ETC_MONSTER_MERCENARY_CARD ) || ( pItemData->GetType() == CItemData::ITEM_BULLET && // Bullet - arrow(x) pItemData->GetSubType() == CItemData::ITEM_BULLET_ARROW ) ) { // Reset holding button pUIManager->ResetHoldBtn(); return WMSG_SUCCESS; } } for( int iBtn = 0; iBtn < QSLOT_BTN_COUNT; iBtn++ ) { if( (*m_abtnItems)[m_nCurSlot+1][iBtn]->IsInside( nX, nY ) ) { if( !*(m_bLock[m_nCurSlot]) ) pUIManager->GetQuickSlot()->AddBtnToQuickSlot( iBtn, m_nCurSlot + 1 ); break; } } } } // Reset holding button pUIManager->ResetHoldBtn(); return WMSG_SUCCESS; } } }break; case WM_LBUTTONDBLCLK: { m_bIsInside = IsInside( nX, nY ); if( IsInside( nX, nY ) ) { return WMSG_SUCCESS; } }break; } return WMSG_FAIL; }
// find shortest path from one marker to another static BOOL FindPath(CNavigationMarker *pnmSrc, CNavigationMarker *pnmDst) { ASSERT(pnmSrc!=pnmDst); CPathNode *ppnSrc = pnmSrc->GetPathNode(); CPathNode *ppnDst = pnmDst->GetPathNode(); PRINTOUT(CPrintF("--------------------\n")); PRINTOUT(CPrintF("FindPath(%s, %s)\n", ppnSrc->GetName(), ppnDst->GetName())); // start with empty open and closed lists ASSERT(_lhOpen.IsEmpty()); ASSERT(_lhClosed.IsEmpty()); // add the start node to open list ppnSrc->pn_fG = 0.0f; ppnSrc->pn_fH = NodeDistance(ppnSrc, ppnDst); ppnSrc->pn_fF = ppnSrc->pn_fG +ppnSrc->pn_fH; _lhOpen.AddTail(ppnSrc->pn_lnInOpen); PRINTOUT(CPrintF("StartState: %s\n", ppnSrc->GetName())); // while the open list is not empty while (!_lhOpen.IsEmpty()) { // get the first node from open list (that is, the one with lowest F) CPathNode *ppnNode = LIST_HEAD(_lhOpen, CPathNode, pn_lnInOpen); ppnNode->pn_lnInOpen.Remove(); _lhClosed.AddTail(ppnNode->pn_lnInClosed); PRINTOUT(CPrintF("Node: %s - moved from OPEN to CLOSED\n", ppnNode->GetName())); // if this is the goal if (ppnNode==ppnDst) { PRINTOUT(CPrintF("PATH FOUND!\n")); // the path is found return TRUE; } // for each link of current node CPathNode *ppnLink = NULL; for(INDEX i=0; (ppnLink=ppnNode->GetLink(i))!=NULL; i++) { PRINTOUT(CPrintF(" Link %d: %s\n", i, ppnLink->GetName())); // get cost to get to this node if coming from current node FLOAT fNewG = ppnLink->pn_fG+NodeDistance(ppnNode, ppnLink); // if a shorter path already exists if ((ppnLink->pn_lnInOpen.IsLinked() || ppnLink->pn_lnInClosed.IsLinked()) && fNewG>=ppnLink->pn_fG) { PRINTOUT(CPrintF(" shorter path exists through: %s\n", ppnLink->pn_ppnParent->GetName())); // skip this link continue; } // remember this path ppnLink->pn_ppnParent = ppnNode; ppnLink->pn_fG = fNewG; ppnLink->pn_fH = NodeDistance(ppnLink, ppnDst); ppnLink->pn_fF = ppnLink->pn_fG + ppnLink->pn_fH; // remove from closed list, if in it if (ppnLink->pn_lnInClosed.IsLinked()) { ppnLink->pn_lnInClosed.Remove(); PRINTOUT(CPrintF(" %s removed from CLOSED\n", ppnLink->GetName())); } // add to open if not in it if (!ppnLink->pn_lnInOpen.IsLinked()) { SortIntoOpenList(ppnLink); PRINTOUT(CPrintF(" %s added to OPEN\n", ppnLink->GetName())); } } } // if we get here, there is no path PRINTOUT(CPrintF("PATH NOT FOUND!\n")); return FALSE; }
BOOL CCommunicationInterface::Server_Update() { CTSingleLock slComm(&cm_csComm, TRUE); CPacket *ppaPacket; CPacket *ppaPacketCopy; CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); INDEX iClient; // transfer packets for the local client if (cm_ciLocalClient.ci_bUsed && cm_ciLocalClient.ci_pciOther != NULL) { cm_ciLocalClient.ExchangeBuffers(); }; cm_aciClients[0].UpdateOutputBuffers(); // if not just playing single player if (cci_bServerInitialized) { Broadcast_Update_t(); // for each client transfer packets from the output buffer to the master output buffer for (iClient=1; iClient<SERVER_CLIENTS; iClient++) { CClientInterface &ci = cm_aciClients[iClient]; // if not connected if (!ci.ci_bUsed) { // skip it continue; } // update its buffers, if a reliable packet is overdue (has not been delivered too long) // disconnect the client if (ci.UpdateOutputBuffers() != FALSE) { // transfer packets ready to be sent out to the master output buffer while (ci.ci_pbOutputBuffer.pb_ulNumOfPackets > 0) { ppaPacket = ci.ci_pbOutputBuffer.PeekFirstPacket(); if (ppaPacket->pa_tvSendWhen < tvNow) { ci.ci_pbOutputBuffer.RemoveFirstPacket(FALSE); if (ppaPacket->pa_ubReliable & UDP_PACKET_RELIABLE) { ppaPacketCopy = new CPacket; *ppaPacketCopy = *ppaPacket; ci.ci_pbWaitAckBuffer.AppendPacket(*ppaPacketCopy,FALSE); } cci_pbMasterOutput.AppendPacket(*ppaPacket,FALSE); } else { break; } } } else { CPrintF(TRANSV("Unable to deliver data to client '%s', disconnecting.\n"),(const char *) AddressToString(cm_aciClients[iClient].ci_adrAddress.adr_ulAddress)); Server_ClearClient(iClient); _pNetwork->ga_srvServer.HandleClientDisconected(iClient); } } // update broadcast output buffers // update its buffers cm_ciBroadcast.UpdateOutputBuffers(); // transfer packets ready to be sent out to the master output buffer while (cm_ciBroadcast.ci_pbOutputBuffer.pb_ulNumOfPackets > 0) { ppaPacket = cm_ciBroadcast.ci_pbOutputBuffer.PeekFirstPacket(); if (ppaPacket->pa_tvSendWhen < tvNow) { cm_ciBroadcast.ci_pbOutputBuffer.RemoveFirstPacket(FALSE); cci_pbMasterOutput.AppendPacket(*ppaPacket,FALSE); } else { break; } } // send/receive packets over the TCP/IP stack UpdateMasterBuffers(); // dispatch all packets from the master input buffer to the clients' input buffers while (cci_pbMasterInput.pb_ulNumOfPackets > 0) { BOOL bClientFound; ppaPacket = cci_pbMasterInput.GetFirstPacket(); bClientFound = FALSE; if (ppaPacket->pa_adrAddress.adr_uwID==SLASHSLASH || ppaPacket->pa_adrAddress.adr_uwID==0) { cm_ciBroadcast.ci_pbInputBuffer.AppendPacket(*ppaPacket,FALSE); bClientFound = TRUE; } else { for (iClient=0; iClient<SERVER_CLIENTS; iClient++) { if (ppaPacket->pa_adrAddress.adr_uwID == cm_aciClients[iClient].ci_adrAddress.adr_uwID) { cm_aciClients[iClient].ci_pbInputBuffer.AppendPacket(*ppaPacket,FALSE); bClientFound = TRUE; break; } } } if (!bClientFound) { // warn about possible attack extern INDEX net_bReportMiscErrors; if (net_bReportMiscErrors) { CPrintF(TRANSV("WARNING: Invalid message from: %s\n"), (const char *) AddressToString(ppaPacket->pa_adrAddress.adr_ulAddress)); } } } for (iClient=1; iClient<SERVER_CLIENTS; iClient++) { cm_aciClients[iClient].UpdateInputBuffers(); } } cm_aciClients[0].UpdateInputBuffers(); cm_ciLocalClient.UpdateInputBuffers(); cm_ciBroadcast.UpdateInputBuffersBroadcast(); Broadcast_Update_t(); return TRUE; };
// prepares the comm interface for use - MUST be invoked before any data can be sent/received void CCommunicationInterface::PrepareForUse(BOOL bUseNetwork, BOOL bClient) { // clear the network conditions emulation data _pbsSend.Clear(); _pbsRecv.Clear(); // if the network is already initialized, shut it down before proceeding if (cm_bNetworkInitialized) { Unprepare(); } // make sure winsock is off (could be on if enumeration was triggered) GameAgent_EnumCancel(); EndWinsock(); if (bUseNetwork) { CPrintF(TRANSV("Initializing TCP/IP...\n")); if (bClient) { CPrintF(TRANSV(" opening as client\n")); } else { CPrintF(TRANSV(" opening as server\n")); } // make sure winsock is on InitWinsock(); // no address by default cm_ulLocalHost = 0; // if there is a desired local address if (net_strLocalHost!="") { CPrintF(TRANSV(" user forced local address: %s\n"), (const char*)net_strLocalHost); // use that address cm_strName = net_strLocalHost; cm_ulLocalHost = StringToAddress(cm_strName); // if invalid if (cm_ulLocalHost==0 || cm_ulLocalHost==-1) { cm_ulLocalHost=0; // report it CPrintF(TRANSV(" requested local address is invalid\n")); } } // if no valid desired local address CPrintF(TRANSV(" getting local addresses\n")); // get default char hostname[256]; gethostname(hostname, sizeof(hostname)-1); cm_strName = hostname; // lookup the host HOSTENT *phe = gethostbyname(cm_strName); // if succeeded if (phe!=NULL) { // get the addresses cm_strAddress = ""; for(INDEX i=0; phe->h_addr_list[i]!=NULL; i++) { if (i>0) { cm_strAddress += ", "; } cm_strAddress += inet_ntoa(*(const in_addr *)phe->h_addr_list[i]); } } CPrintF(TRANSV(" local addresses: %s (%s)\n"), (const char *) cm_strName, (const char *) cm_strAddress); CPrintF(TRANSV(" port: %d\n"), net_iPort); // try to open master UDP socket try { OpenSocket_t(cm_ulLocalHost, bClient?0:net_iPort); cci_pbMasterInput.pb_ppbsStats = NULL; cci_pbMasterOutput.pb_ppbsStats = NULL; cm_ciBroadcast.SetLocal(NULL); CPrintF(TRANSV(" opened socket: \n")); } catch (char *strError) { CPrintF(TRANSV(" cannot open UDP socket: %s\n"), strError); } } cm_bNetworkInitialized = cci_bWinSockOpen; };
// update master UDP socket and route its messages void CCommunicationInterface::UpdateMasterBuffers() { UBYTE aub[MAX_PACKET_SIZE]; CAddress adrIncomingAddress; SOCKADDR_IN sa; socklen_t size = sizeof(sa); SLONG slSizeReceived; SLONG slSizeSent; BOOL bSomethingDone; CPacket* ppaNewPacket; CTimerValue tvNow; if (cci_bBound) { // read from the socket while there is incoming data do { // initially, nothing is done bSomethingDone = FALSE; slSizeReceived = recvfrom(cci_hSocket,(char*)aub,MAX_PACKET_SIZE,0,(SOCKADDR *)&sa,&size); tvNow = _pTimer->GetHighPrecisionTimer(); adrIncomingAddress.adr_ulAddress = ntohl(sa.sin_addr.s_addr); adrIncomingAddress.adr_uwPort = ntohs(sa.sin_port); //On error, report it to the console (if error is not a no data to read message) if (slSizeReceived == SOCKET_ERROR) { int iResult = WSAGetLastError(); if (!isWouldBlockError(iResult)) { // report it if (iResult!=WSAECONNRESET || net_bReportICMPErrors) { CPrintF(TRANSV("Socket error during UDP receive. %s\n"), (const char*)GetSocketError(iResult)); return; } } // if block received } else { // if there is not at least one byte more in the packet than the header size if (slSizeReceived <= MAX_HEADER_SIZE) { // the packet is in error extern INDEX net_bReportMiscErrors; if (net_bReportMiscErrors) { CPrintF(TRANSV("WARNING: Bad UDP packet from '%s'\n"), (const char *) AddressToString(adrIncomingAddress.adr_ulAddress)); } // there might be more to do bSomethingDone = TRUE; } else if (net_fDropPackets <= 0 || (FLOAT(rand())/RAND_MAX) > net_fDropPackets) { // if no packet drop emulation (or the packet is not dropped), form the packet // and add it to the end of the UDP Master's input buffer ppaNewPacket = new CPacket; ppaNewPacket->WriteToPacketRaw(aub,slSizeReceived); ppaNewPacket->pa_adrAddress.adr_ulAddress = adrIncomingAddress.adr_ulAddress; ppaNewPacket->pa_adrAddress.adr_uwPort = adrIncomingAddress.adr_uwPort; if (net_bReportPackets == TRUE) { CPrintF("%lu: Received sequence: %d from ID: %d, reliable flag: %d\n",(ULONG) tvNow.GetMilliseconds(),ppaNewPacket->pa_ulSequence,ppaNewPacket->pa_adrAddress.adr_uwID,ppaNewPacket->pa_ubReliable); } cci_pbMasterInput.AppendPacket(*ppaNewPacket,FALSE); // there might be more to do bSomethingDone = TRUE; } } } while (bSomethingDone); } // write from the output buffer to the socket while (cci_pbMasterOutput.pb_ulNumOfPackets > 0) { ppaNewPacket = cci_pbMasterOutput.PeekFirstPacket(); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(ppaNewPacket->pa_adrAddress.adr_ulAddress); sa.sin_port = htons(ppaNewPacket->pa_adrAddress.adr_uwPort); slSizeSent = sendto(cci_hSocket, (char*) ppaNewPacket->pa_pubPacketData, (int) ppaNewPacket->pa_slSize, 0, (SOCKADDR *)&sa, sizeof(sa)); cci_bBound = TRUE; // UDP socket that did a send is considered bound tvNow = _pTimer->GetHighPrecisionTimer(); // if some error if (slSizeSent == SOCKET_ERROR) { int iResult = WSAGetLastError(); // if output UDP buffer full, stop sending if (isWouldBlockError(iResult)) { return; // report it } else if (iResult!=WSAECONNRESET || net_bReportICMPErrors) { CPrintF(TRANSV("Socket error during UDP send. %s\n"), (const char*)GetSocketError(iResult)); } return; } else if (slSizeSent < ppaNewPacket->pa_slSize) { STUBBED("LOST OUTGOING PACKET DATA!"); ASSERT(0); // if all sent ok } else { if (net_bReportPackets == TRUE) { CPrintF("%lu: Sent sequence: %d to ID: %d, reliable flag: %d\n",(ULONG)tvNow.GetMilliseconds(),ppaNewPacket->pa_ulSequence,ppaNewPacket->pa_adrAddress.adr_uwID,ppaNewPacket->pa_ubReliable); } cci_pbMasterOutput.RemoveFirstPacket(TRUE); bSomethingDone=TRUE; } } };
BOOL CCommunicationInterface::Client_Update(void) { CTSingleLock slComm(&cm_csComm, TRUE); CPacket *ppaPacket; CPacket *ppaPacketCopy; CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); // update local client's output buffers if (cm_ciLocalClient.UpdateOutputBuffers() == FALSE) { return FALSE; } // if not playing on the server (i.e. connectet to a remote server) if (!cci_bServerInitialized) { // put all pending packets in the master output buffer while (cm_ciLocalClient.ci_pbOutputBuffer.pb_ulNumOfPackets > 0) { ppaPacket = cm_ciLocalClient.ci_pbOutputBuffer.PeekFirstPacket(); if (ppaPacket->pa_tvSendWhen < tvNow) { cm_ciLocalClient.ci_pbOutputBuffer.RemoveFirstPacket(FALSE); if (ppaPacket->pa_ubReliable & UDP_PACKET_RELIABLE) { ppaPacketCopy = new CPacket; *ppaPacketCopy = *ppaPacket; cm_ciLocalClient.ci_pbWaitAckBuffer.AppendPacket(*ppaPacketCopy,FALSE); } cci_pbMasterOutput.AppendPacket(*ppaPacket,FALSE); } else { break; } } // update broadcast output buffers // update its buffers cm_ciBroadcast.UpdateOutputBuffers(); // transfer packets ready to be sent out to the master output buffer while (cm_ciBroadcast.ci_pbOutputBuffer.pb_ulNumOfPackets > 0) { ppaPacket = cm_ciBroadcast.ci_pbOutputBuffer.PeekFirstPacket(); if (ppaPacket->pa_tvSendWhen < tvNow) { cm_ciBroadcast.ci_pbOutputBuffer.RemoveFirstPacket(FALSE); cci_pbMasterOutput.AppendPacket(*ppaPacket,FALSE); } else { break; } } // send/receive packets over the TCP/IP stack UpdateMasterBuffers(); // dispatch all packets from the master input buffer to the clients' input buffers while (cci_pbMasterInput.pb_ulNumOfPackets > 0) { BOOL bClientFound; ppaPacket = cci_pbMasterInput.GetFirstPacket(); bClientFound = FALSE; // if the packet address is broadcast and it's an unreliable transfer, put it in the broadcast buffer if ((ppaPacket->pa_adrAddress.adr_uwID==SLASHSLASH || ppaPacket->pa_adrAddress.adr_uwID==0) && ppaPacket->pa_ubReliable == UDP_PACKET_UNRELIABLE) { cm_ciBroadcast.ci_pbInputBuffer.AppendPacket(*ppaPacket,FALSE); bClientFound = TRUE; // if the packet is for this client, accept it } else if ((ppaPacket->pa_adrAddress.adr_uwID == cm_ciLocalClient.ci_adrAddress.adr_uwID) || ppaPacket->pa_adrAddress.adr_uwID==SLASHSLASH || ppaPacket->pa_adrAddress.adr_uwID==0) { cm_ciLocalClient.ci_pbInputBuffer.AppendPacket(*ppaPacket,FALSE); bClientFound = TRUE; } if (!bClientFound) { // warn about possible attack extern INDEX net_bReportMiscErrors; if (net_bReportMiscErrors) { CPrintF(TRANSV("WARNING: Invalid message from: %s\n"), (const char *) AddressToString(ppaPacket->pa_adrAddress.adr_ulAddress)); } } } } cm_ciLocalClient.UpdateInputBuffers(); cm_ciBroadcast.UpdateInputBuffersBroadcast(); return TRUE; };