void CGame::ComputerMouseMove(PIX pixX, PIX pixY) { _vpixMouse(1) += pixX-_vpixExternMouse(1); _vpixMouse(2) += pixY-_vpixExternMouse(2); _vpixExternMouse(1) = pixX; _vpixExternMouse(2) = pixY; // if dragging if (_pixSliderDragJ>=0) { PIX pixDelta = _vpixMouse(2)-_pixSliderDragJ; if (_bSliderDragText) { if (_iActiveMessage<_acmMessages.Count()) { INDEX ctTextLines = _acmMessages[_iActiveMessage].cm_ctFormattedLines; INDEX iWantedLine = _iSliderDragLine+ SliderPixToIndex(pixDelta, _ctTextLinesOnScreen, ctTextLines, GetTextSliderSpace()); MessageTextUpDn(iWantedLine-_iTextLineOnScreen); } } else { INDEX ctLines = _acmMessages.Count(); INDEX iWantedLine = _iSliderDragLine+ SliderPixToIndex(pixDelta, _ctMessagesOnScreen, ctLines, GetMsgSliderSpace()); MessagesUpDn(iWantedLine-_iFirstMessageOnScreen); } } }
// update scroll position for message list static void UpdateFirstOnScreen(void) { if (_iFirstMessageOnScreen==_iWantedFirstMessageOnScreen) { return; } _iFirstMessageOnScreen=_iWantedFirstMessageOnScreen; ASSERT( _iFirstMessageOnScreen>=0&& _iFirstMessageOnScreen<=_acmMessages.Count()); _iFirstMessageOnScreen = Clamp(_iFirstMessageOnScreen, INDEX(0), _acmMessages.Count()); // for each message for(INDEX i=0; i<_acmMessages.Count(); i++) { CCompMessage &cm = _acmMessages[i]; // if on screen if (i>=_iWantedFirstMessageOnScreen &&i<_iWantedFirstMessageOnScreen+_ctMessagesOnScreen) { // load cm.PrepareMessage(_ctTextCharsPerRow); // if not on screen } else { // unload cm.UnprepareMessage(); } } }
// Draw all tiles that are in lowest lod static void RenderBatchedTiles(void) { // Set texture wrapping gfxSetTextureWrapping(GFX_CLAMP,GFX_CLAMP); // Use terrains global top map as texture _ptrTerrain->tr_tdTopMap.SetAsCurrent(); GFXVertex4 *pavVertices = &_avDelayedVertices[0]; GFXTexCoord *pauvTexCoords = &_auvDelayedTexCoords[0]; GFXTexCoord *pauvShadowMapTC = &_auvDelayedShadowMapTC[0]; INDEX *paiIndices = &_aiDelayedIndices[0]; INDEX ctVertices = _avDelayedVertices.Count(); INDEX ctIndices = _aiDelayedIndices.Count(); // Prepare white color array FillConstColorArray(ctVertices); GFXColor *pacolColors = &_acolVtxConstColors[0]; gfxEnableAlphaTest(); gfxDisableBlend(); gfxSetVertexArray(pavVertices,ctVertices); gfxSetTexCoordArray(pauvTexCoords, FALSE); gfxSetColorArray(pacolColors); gfxLockArrays(); gfxDrawElements(ctIndices,paiIndices); gfxDisableAlphaTest(); _ctTris +=ctIndices/2; // if shadows are visible if(_wrpWorldRenderPrefs.wrp_shtShadows!=CWorldRenderPrefs::SHT_NONE) { gfxDepthFunc(GFX_EQUAL); gfxBlendFunc(GFX_DST_COLOR,GFX_SRC_COLOR); gfxEnableBlend(); gfxSetTexCoordArray(pauvShadowMapTC, FALSE); _ptrTerrain->tr_tdShadowMap.SetAsCurrent(); gfxDrawElements(ctIndices,paiIndices); gfxDepthFunc(GFX_LESS_EQUAL); } if(_ptrTerrain->GetFlags()&TR_HAS_FOG) { RenderFogLayer(-1); } if(_ptrTerrain->GetFlags()&TR_HAS_HAZE) { RenderHazeLayer(-1); } gfxUnlockArrays(); // Popall delayed arrays _avDelayedVertices.PopAll(); _auvDelayedTexCoords.PopAll(); _auvDelayedShadowMapTC.PopAll(); _aiDelayedIndices.PopAll(); }
void NextMessage(void) { if (_iActiveMessage<_acmMessages.Count()==0) { return; } _iActiveMessage++; if (_iActiveMessage>=_acmMessages.Count()) { _iActiveMessage = _acmMessages.Count()-1; } SyncScrollWithActive(); }
static void RenderHazeLayer(INDEX itt) { FLOAT3D vObjPosition = _ptrTerrain->tr_penEntity->en_plPlacement.pl_PositionVector; _fHazeAdd = -_haze_hp.hp_fNear; _fHazeAdd += _vViewer(1) * (vObjPosition(1) - _aprProjection->pr_vViewerPosition(1)); _fHazeAdd += _vViewer(2) * (vObjPosition(2) - _aprProjection->pr_vViewerPosition(2)); _fHazeAdd += _vViewer(3) * (vObjPosition(3) - _aprProjection->pr_vViewerPosition(3)); GFXVertex *pvVtx; INDEX *piIndices; INDEX ctVertices; INDEX ctIndices; // if this is tile if(itt>=0) { CTerrainTile &tt = _ptrTerrain->tr_attTiles[itt]; pvVtx = &tt.GetVertices()[0]; piIndices = &tt.GetIndices()[0]; ctVertices = tt.GetVertices().Count(); ctIndices = tt.GetIndices().Count(); // else this are batched tiles } else { pvVtx = &_avDelayedVertices[0]; piIndices = &_aiDelayedIndices[0]; ctVertices = _avDelayedVertices.Count(); ctIndices = _aiDelayedIndices.Count(); } GFXTexCoord *pfHazeTC = _atcHaze.Push(ctVertices); GFXColor *pcolHaze = _acolHaze.Push(ctVertices); const COLOR colH = AdjustColor( _haze_hp.hp_colColor, _slTexHueShift, _slTexSaturation); GFXColor colHaze(colH); // for each vertex in tile for(INDEX ivx=0;ivx<ctVertices;ivx++) { GetHazeMapInVertex(pvVtx[ivx],pfHazeTC[ivx]); pcolHaze[ivx] = colHaze; } // render haze layer gfxDepthFunc(GFX_EQUAL); gfxSetTextureWrapping( GFX_CLAMP, GFX_CLAMP); gfxSetTexture( _haze_ulTexture, _haze_tpLocal); gfxSetTexCoordArray(pfHazeTC, FALSE); gfxSetColorArray(pcolHaze); gfxBlendFunc( GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA); gfxEnableBlend(); gfxDrawElements(ctIndices,piIndices); gfxDepthFunc(GFX_LESS_EQUAL); _atcHaze.PopAll(); _acolHaze.PopAll(); }
void SelectMessage(INDEX i) { if (_acmMessages.Count()==0) { return; } _iActiveMessage = i; if (_iActiveMessage<0) { _iActiveMessage = 0; } if (_iActiveMessage>=_acmMessages.Count()) { _iActiveMessage = _acmMessages.Count()-1; } SyncScrollWithActive(); }
// select last unread message, or last message if all read void LastUnreadMessage(void) { BOOL bFound = FALSE; for(_iActiveMessage=_acmMessages.Count()-1; _iActiveMessage>=0; _iActiveMessage--) { if (!_acmMessages[_iActiveMessage].cm_bRead) { bFound = TRUE; break; } } if (!bFound) { _iActiveMessage = ClampDn(_acmMessages.Count()-1, 0); } SyncScrollWithActive(); }
// check all delayed depth points extern void CheckDelayedDepthPoints( const CDrawPort *pdp, INDEX iMirrorLevel/*=0*/) { // skip if not delayed or mirror level is to high gap_iOptimizeDepthReads = Clamp( gap_iOptimizeDepthReads, 0L, 2L); if( gap_iOptimizeDepthReads==0 || iMirrorLevel>7) return; ASSERT( pdp!=NULL && iMirrorLevel>=0); // check only if time lapse allows const CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); const TIME tmDelta = (tvNow-_tvLast[iMirrorLevel]).GetSeconds(); ASSERT( tmDelta>=0); if( gap_iOptimizeDepthReads==2 && tmDelta<0.1f) return; // prepare _tvLast[iMirrorLevel] = tvNow; INDEX ctPoints = _adiDelayed.Count(); if( ctPoints==0) return; // done if no points in queue // for each point INDEX iPoint = 0; while( iPoint<ctPoints) { DepthInfo &di = _adiDelayed[iPoint]; // if the point is not active any more if( iMirrorLevel==di.di_iMirrorLevel && di.di_iSwapLastRequest<_iCheckIteration-KEEP_BEHIND) { // delete it by moving the last one on its place di = _adiDelayed[ctPoints-1]; ctPoints--; // if the point is still active } else { // go to next point iPoint++; } } // remove unused points at the end if( ctPoints==0) _adiDelayed.PopAll(); else _adiDelayed.PopUntil(ctPoints-1); // ignore stalls if( tmDelta>1.0f) return; // check and update visibility of what has left ASSERT( ctPoints == _adiDelayed.Count()); if( ctPoints>0) UpdateDepthPointsVisibility( pdp, iMirrorLevel, &_adiDelayed[0], ctPoints); // mark checking _iCheckIteration++; }
// draw image of current message void RenderMessageImage(CDrawPort *pdp) { if (!GetSP()->sp_bCooperative) { return; } // if no message if (_acmMessages.Count()==0 || fComputerFadeValue<0.99f) { // render empty LCDRenderClouds2(); LCDScreenBox(_colBoxes); return; } CCompMessage &cm = _acmMessages[_iActiveMessage]; if (cm.cm_itImage == CCompMessage::IT_STATISTICS) { _pGame->LCDRenderCompGrid(); } LCDRenderClouds2(); LCDScreenBox(_colBoxes); // if no image if (cm.cm_itImage == CCompMessage::IT_NONE) { // do nothing return; } else if (cm.cm_itImage == CCompMessage::IT_PICTURE) { RenderMessagePicture(pdp); } else if (cm.cm_itImage == CCompMessage::IT_STATISTICS) { RenderMessageStats(pdp); } else if (cm.cm_itImage == CCompMessage::IT_MODEL) { RenderMessageModel(pdp, cm.cm_strModel); } else { ASSERT(FALSE); } }
static void BatchTile(INDEX itt) { CTerrainTile &tt = _ptrTerrain->tr_attTiles[itt]; ASSERT(tt.GetVertices().Count()==9); ASSERT(tt.GetIndices().Count()==24); INDEX ctDelayedVertices = _avDelayedVertices.Count(); GFXVertex4 *pavVertices = &tt.GetVertices()[0]; GFXTexCoord *pauvTexCoords = &tt.GetTexCoords()[0]; GFXTexCoord *pauvShadowMapTC = &tt.GetShadowMapTC()[0]; INDEX *paiIndices = &tt.GetIndices()[0]; GFXVertex4 *pavDelVertices = _avDelayedVertices.Push(9); GFXTexCoord *pauvDelTexCoords = _auvDelayedTexCoords.Push(9); GFXTexCoord *pauvDelShadowMapTC = _auvDelayedShadowMapTC.Push(9); INDEX *paiDelIndices = _aiDelayedIndices.Push(24); // for each vertex in tile for(INDEX ivx=0;ivx<9;ivx++) { // copy vertex, texcoord & shadow map texcoord to delayed array pavDelVertices[ivx] = pavVertices[ivx]; pauvDelTexCoords[ivx] = pauvTexCoords[ivx]; pauvDelShadowMapTC[ivx] = pauvShadowMapTC[ivx]; } // for each index in tile for(INDEX iind=0;iind<24;iind++) { // reindex indice for new arrays paiDelIndices[iind] = paiIndices[iind] + ctDelayedVertices; } _ctDelayedNodes++; }
static PIXaabbox2D GetMsgSliderBox(void) { INDEX ctLines = _acmMessages.Count(); PIX pixSizeI = _boxMsgList.Size()(1); PIX pixSizeJ = _boxMsgList.Size()(2); return GetSliderBox( _iFirstMessageOnScreen, _ctMessagesOnScreen, ctLines, GetMsgSliderSpace()); }
void CCastRay::ClearSectorList(void) { // for each active sector for(INDEX ias=0; ias<_aas.Count(); ias++) { // mark it as inactive _aas[ias].as_pbsc->bsc_ulFlags&=~BSCF_RAYTESTED; } _aas.PopAll(); }
static void FillConstColorArray(INDEX ctVertices) { INDEX ctColors=_acolVtxConstColors.Count(); _acolVtxConstColors.PopAll(); _acolVtxConstColors.Push(ctVertices); // if requested array is larger then existing one if(ctVertices>ctColors) { memset(&_acolVtxConstColors[ctColors],255,(ctVertices-ctColors)*sizeof(GFXColor)); } }
void MessagesUpDn(INDEX ctLines) { INDEX ctMessages = _acmMessages.Count(); _iWantedFirstMessageOnScreen += ctLines; INDEX iMaxFirst = ClampDn(0L, ctMessages-_ctMessagesOnScreen); _iWantedFirstMessageOnScreen = Clamp(_iWantedFirstMessageOnScreen, 0L, iMaxFirst); _iActiveMessage = Clamp(_iActiveMessage, _iWantedFirstMessageOnScreen, _iWantedFirstMessageOnScreen+_ctMessagesOnScreen-1L); }
// go to next/previous message void PrevMessage(void) { if (_iActiveMessage<_acmMessages.Count()==0) { return; } _iActiveMessage--; if (_iActiveMessage<0) { _iActiveMessage = 0; } SyncScrollWithActive(); }
static PIXaabbox2D GetTextSliderBox(void) { if (_iActiveMessage>=_acmMessages.Count()) { return PIXaabbox2D(); } INDEX ctTextLines = _acmMessages[_iActiveMessage].cm_ctFormattedLines; PIX pixSizeI = _boxMsgText.Size()(1); PIX pixSizeJ = _boxMsgText.Size()(2); return GetSliderBox( _iTextLineOnScreen, _ctTextLinesOnScreen, ctTextLines, GetTextSliderSpace()); }
// render credits to given drawport FLOAT Credits_Render(CDrawPort *pdp) { if (!_bCreditsOn) { return 0; } CDrawPort dpWide; pdp->MakeWideScreen(&dpWide); pdp->Unlock(); dpWide.Lock(); FLOAT fTime = GetTime(); pixW = dpWide.GetWidth(); pixH = dpWide.GetHeight(); fResolutionScaling = (FLOAT)pixW / 640.0f; dpWide.SetFont( _pfdDisplayFont); pixLineHeight = floor(20*fResolutionScaling); const FLOAT fLinesPerSecond = _fSpeed; FLOAT fOffset = fTime*fLinesPerSecond; INDEX ctLinesOnScreen = pixH/pixLineHeight; INDEX iLine1 = fOffset; pixJ = iLine1*pixLineHeight-fOffset*pixLineHeight; iLine1-=ctLinesOnScreen; INDEX ctLines = _astrCredits.Count(); BOOL bOver = TRUE; for (INDEX i = iLine1; i<iLine1+ctLinesOnScreen+1; i++) { CTString *pstr = &strEmpty; INDEX iLine = i; if (iLine>=0 && iLine<ctLines) { pstr = &_astrCredits[iLine]; bOver = FALSE; } PrintOneLine(&dpWide, *pstr); } dpWide.Unlock(); pdp->Lock(); if (bOver) { return 0; } else if (ctLines-iLine1<ctLinesOnScreen) { return FLOAT(ctLines-iLine1)/ctLinesOnScreen; } else { return 1; } }
// check point against depth buffer extern BOOL CheckDepthPoint( const CDrawPort *pdp, PIX pixI, PIX pixJ, FLOAT f**K, INDEX iID, INDEX iMirrorLevel/*=0*/) { // no raster? const CRaster *pra = pdp->dp_Raster; if( pra==NULL) return FALSE; // almoust out of raster? pixI += pdp->dp_MinI; pixJ += pdp->dp_MinJ; if( pixI<1 || pixJ<1 || pixI>pra->ra_Width-2 || pixJ>pra->ra_Height-2) return FALSE; // if shouldn't delay if( gap_iOptimizeDepthReads==0) { // just check immediately DepthInfo di = { iID, pixI, pixJ, f**K, _iCheckIteration, iMirrorLevel, FALSE }; UpdateDepthPointsVisibility( pdp, iMirrorLevel, &di, 1); return di.di_bVisible; } // for each stored point for( INDEX idi=0; idi<_adiDelayed.Count(); idi++) { DepthInfo &di = _adiDelayed[idi]; // if same id if( di.di_iID == iID) { // remember parameters di.di_pixI = pixI; di.di_pixJ = pixJ; di.di_fOoK = f**K; di.di_iSwapLastRequest = _iCheckIteration; // return visibility return di.di_bVisible; } } // if not found... // create new one DepthInfo &di = _adiDelayed.Push(); // remember parameters di.di_iID = iID; di.di_pixI = pixI; di.di_pixJ = pixJ; di.di_fOoK = f**K; di.di_iSwapLastRequest = _iCheckIteration; di.di_iMirrorLevel = iMirrorLevel; di.di_bVisible = FALSE; // not visible by default return FALSE; }
// select next unread message static void NextUnreadMessage(void) { INDEX i=_iActiveMessage; FOREVER { i++; if (i>=_acmMessages.Count()) { i = 0; } if (i==_iActiveMessage) { return; } if (!_acmMessages[i].cm_bRead) { _iActiveMessage = i; SyncScrollWithActive(); return; } } }
void MessageTextDn(INDEX ctLines) { // if no message do nothing if (_iActiveMessage<_acmMessages.Count()==0) { return; } // find text lines count _acmMessages[_iActiveMessage].PrepareMessage(_ctTextCharsPerRow); INDEX ctTextLines = _acmMessages[_iActiveMessage].cm_ctFormattedLines; // calculate maximum value for first visible line INDEX iFirstLine = ctTextLines-_ctTextLinesOnScreen; if (iFirstLine<0) { iFirstLine = 0; } // increment _iTextLineOnScreen+=ctLines; if (_iTextLineOnScreen>iFirstLine) { _iTextLineOnScreen = iFirstLine; } }
static FLOATaabbox3D AddAllVerticesToBBox(CModelInstance &mi) { FLOATmatrix3D mat; FLOAT3D vPos = FLOAT3D(0,0,0); mat.Diagonal(1); CStaticStackArray<FLOAT3D> avVertices; mi.GetModelVertices(avVertices,mat,vPos,0,0); INDEX ctvtx = avVertices.Count(); // if at least one vertex exists FLOATaabbox3D bbox; if(ctvtx>0) { bbox = FLOATaabbox3D(avVertices[0]); // for each vertex after first one for(INDEX ivx=1;ivx<ctvtx;ivx++) { // add this vertex position to all frames bbox bbox |= FLOATaabbox3D(avVertices[ivx]); } } return bbox; }
// print list of messages void PrintMessageList(CDrawPort *pdp) { PIX pixTextX = _pixMarginI; PIX pixYLine = _pixMarginJ; SetFont1(pdp); INDEX iFirst = _iFirstMessageOnScreen; INDEX iLast = Min(INDEX(_iFirstMessageOnScreen+_ctMessagesOnScreen), _acmMessages.Count())-1; if (iFirst>iLast) { pdp->PutText( TRANS("no messages"), pixTextX, pixYLine, _colDark); } for(INDEX i=iFirst; i<=iLast; i++) { COLOR col = _colMedium; if (_acmMessages[i].cm_bRead) { col = _colDark; } if (i==_iActiveMessage) { col = _colLight; } if (GetMsgListBox(i-_iFirstMessageOnScreen)>=_vpixMouse) { col = LCDBlinkingColor(_colLight, _colMedium); } pdp->PutText( _acmMessages[i].cm_strSubject, pixTextX, pixYLine, col); pixYLine+=_pixCharSizeJ; } PIXaabbox2D boxSliderSpace = GetMsgSliderSpace(); LCDDrawBox(0,0,boxSliderSpace, _colBoxes); PIXaabbox2D boxSlider = GetMsgSliderBox(); COLOR col = _colBoxes; PIXaabbox2D boxSliderTrans = boxSlider; boxSliderTrans+=_boxMsgList.Min(); if (boxSliderTrans>=_vpixMouse) { col = LCDBlinkingColor(_colLight, _colDark); } pdp->Fill( boxSlider.Min()(1)+2, boxSlider.Min()(2)+2, boxSlider.Size()(1)-4, boxSlider.Size()(2)-4, col); }
// mark current message as read void MarkCurrentRead(void) { if (_iActiveMessage>=_acmMessages.Count()) { return; } // if running in background if (_pGame->gm_csComputerState == CS_ONINBACKGROUND) { // do nothing return; } ASSERT(_ppenPlayer!=NULL); if (_ppenPlayer==NULL) { return; } // if already read if (_acmMessages[_iActiveMessage].cm_bRead) { // do nothing return; } // mark as read _ppenPlayer->m_ctUnreadMessages--; _acmMessages[_iActiveMessage].MarkRead(); }
static DOUBLE TrisTroughputPass(INDEX ct) { if( !_pdp->Lock()) { ASSERT(FALSE); return 0.0; } StartTimer(); gfxSetFrustum( -0.5f, +0.5f, -0.5f, +0.5f, 0.5f, 2.0f); gfxSetViewMatrix(NULL); gfxCullFace(GFX_NONE); _pdp->Fill(C_GRAY|255); _pdp->FillZBuffer(1.0f); if(_bTexture) { gfxEnableTexture(); } else { gfxDisableTexture(); } if(_bBlend) { gfxEnableBlend(); gfxBlendFunc( GFX_ONE, GFX_ONE); } else { gfxDisableBlend(); } if(_bDepth) { gfxEnableDepthTest(); gfxEnableDepthWrite(); } else { gfxDisableDepthTest(); gfxDisableDepthWrite(); } gfxDisableAlphaTest(); gfxSetVertexArray( &_avtx[0], _avtx.Count()); gfxLockArrays(); gfxSetTexCoordArray( &_atex[0], FALSE); gfxSetColorArray( &_acol[0]); if(_bMultiTexture) { gfxSetTextureUnit(1); gfxEnableTexture(); gfxSetTexture( _ulTexObject, _tpLocal); gfxSetTexCoordArray( &_atex[0], FALSE); gfxSetTextureUnit(0); } for( INDEX i=0; i<ct; i++) gfxDrawElements( _aiElements.Count(), &_aiElements[0]); gfxUnlockArrays(); if(_bMultiTexture) { gfxSetTextureUnit(1); gfxDisableTexture(); gfxSetTextureUnit(0); } _pdp->Unlock(); gfxFinish(); _pvp->SwapBuffers(); return StopTimer(); }
void MakeDiff_t(void) { // write header with size of files (*_pstrmOut).WriteID_t("DIFF"); (*_pstrmOut)<<_slSizeOld<<_slSizeNew<<_ulCRC; // find first entities in blocks UBYTE *pubOldEnts = FindFirstEntity(_pubOld, _slSizeOld); UBYTE *pubNewEnts = FindFirstEntity(_pubNew, _slSizeNew); if (pubOldEnts==NULL || pubNewEnts==NULL) { ThrowF_t(TRANS("Invalid stream for Diff!")); } // make arrays of entity offsets UBYTE *pubEntEndOld; MakeInfos(_aebiOld, _pubOld, _slSizeOld, pubOldEnts, pubEntEndOld); UBYTE *pubEntEndNew; MakeInfos(_aebiNew, _pubNew, _slSizeNew, pubNewEnts, pubEntEndNew); // emit chunk before entities by xor EmitXor_t(0, pubOldEnts-_pubOld, 0, pubNewEnts-_pubNew); // for each entity in new for(INDEX ieibNew = 0; ieibNew<_aebiNew.Count(); ieibNew++) { EntityBlockInfo &ebiNew = _aebiNew[ieibNew]; // find same in old file INDEX ieibOld = -1; for(INDEX i=0; i<_aebiOld.Count(); i++) { if (_aebiOld[i].ebi_ulID==ebiNew.ebi_ulID) { ieibOld = i; break; } } BOOL bDone = FALSE; // if found if (ieibOld>=0) { EntityBlockInfo &ebiOld = _aebiOld[ieibOld]; // if same if ( ebiOld.ebi_slSize==ebiNew.ebi_slSize) { if (memcmp(_pubOld+ebiOld.ebi_slOffset, _pubNew+ebiNew.ebi_slOffset, ebiNew.ebi_slSize)==0) { //CPrintF("Same blocks\n"); // emit copy from old EmitOld_t(ebiOld.ebi_slOffset, ebiOld.ebi_slSize); bDone = TRUE; } else { //CPrintF("Different blocks\n"); } } else { //CPrintF("Different sizes\n"); } if (!bDone) { // emit xor EmitXor_t( ebiOld.ebi_slOffset, ebiOld.ebi_slSize, ebiNew.ebi_slOffset, ebiNew.ebi_slSize); bDone = TRUE; } } else { //CPrintF("Not found\n"); } if (!bDone) { // emit from new EmitNew_t(ebiNew.ebi_slOffset, ebiNew.ebi_slSize); bDone = TRUE; } } // emit chunk after entities by xor EmitXor_t( pubEntEndOld-_pubOld, _pubOld+_slSizeOld-pubEntEndOld, pubEntEndNew-_pubNew, _pubNew+_slSizeNew-pubEntEndNew); }
static void RenderFogLayer(INDEX itt) { FLOATmatrix3D &mViewer = _aprProjection->pr_ViewerRotationMatrix; FLOAT3D vObjPosition = _ptrTerrain->tr_penEntity->en_plPlacement.pl_PositionVector; // get viewer -z in object space _vFViewerObj = FLOAT3D(0,0,-1) * !_mObjectToView; // get fog direction in object space _vHDirObj = _fog_vHDirAbs * !(!mViewer*_mObjectToView); // get viewer offset _fFogAddZ = _vViewer(1) * (vObjPosition(1) - _aprProjection->pr_vViewerPosition(1)); _fFogAddZ += _vViewer(2) * (vObjPosition(2) - _aprProjection->pr_vViewerPosition(2)); _fFogAddZ += _vViewer(3) * (vObjPosition(3) - _aprProjection->pr_vViewerPosition(3)); // get fog offset _fFogAddH = (_fog_vHDirAbs % vObjPosition) + _fog_fp.fp_fH3; GFXVertex *pvVtx; INDEX *piIndices; INDEX ctVertices; INDEX ctIndices; // if this is tile if(itt>=0) { CTerrainTile &tt = _ptrTerrain->tr_attTiles[itt]; pvVtx = &tt.GetVertices()[0]; piIndices = &tt.GetIndices()[0]; ctVertices = tt.GetVertices().Count(); ctIndices = tt.GetIndices().Count(); // else this are batched tiles } else { pvVtx = &_avDelayedVertices[0]; piIndices = &_aiDelayedIndices[0]; ctVertices = _avDelayedVertices.Count(); ctIndices = _aiDelayedIndices.Count(); } GFXTexCoord *pfFogTC = _atcHaze.Push(ctVertices); GFXColor *pcolFog = _acolHaze.Push(ctVertices); const COLOR colF = AdjustColor( _fog_fp.fp_colColor, _slTexHueShift, _slTexSaturation); GFXColor colFog(colF); // for each vertex in tile for(INDEX ivx=0;ivx<ctVertices;ivx++) { GetFogMapInVertex(pvVtx[ivx],pfFogTC[ivx]); pcolFog[ivx] = colFog; } // render fog layer gfxDepthFunc(GFX_EQUAL); gfxSetTextureWrapping( GFX_CLAMP, GFX_CLAMP); gfxSetTexture( _fog_ulTexture, _fog_tpLocal); gfxSetTexCoordArray(pfFogTC, FALSE); gfxSetColorArray(pcolFog); gfxBlendFunc( GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA); gfxEnableBlend(); gfxDisableAlphaTest(); gfxDrawElements(ctIndices,piIndices); gfxDepthFunc(GFX_LESS_EQUAL); _atcHaze.PopAll(); _acolHaze.PopAll(); }
// fill remap array with indices of vertices in order how they appear per polygons FOREACHINDYNAMICCONTAINER(acmMaterials, ConversionMaterial, itcm) { // fill remap array with -1 for( INDEX iRemap=0; iRemap<ctVertices; iRemap++) { aiRemap[iRemap] = -1; } // reset 'vertex in surface' counter INDEX ctvx = 0; // for each polygon in surface {FOREACHINDYNAMICCONTAINER(itcm->ms_Polygons, INDEX, itipol) { INDEX idxPol = *itipol; // for each vertex in polygon for(INDEX iVtx=0; iVtx<3; iVtx++) { // get vertex's index INDEX idxVtx = actTriangles[idxPol].ct_iVtx[iVtx]; if( aiRemap[idxVtx] == -1) { aiRemap[idxVtx] = ctvx; ctvx++; } } }} INDEX ctOld = avDst.Count(); // allocate new block of vertices used in this surface FLOAT3D *pavDst = avDst.Push( ctvx); // for each polygon in surface {FOREACHINDYNAMICCONTAINER(itcm->ms_Polygons, INDEX, itipol) { INDEX iPol=*itipol; // for each vertex in polygon for(INDEX iVtx=0; iVtx<3; iVtx++) { // get vertex's index INDEX idxVtx = actTriangles[iPol].ct_iVtx[iVtx]; // get remapped index INDEX iRemap = aiRemap[idxVtx]; // if cutting object if( bAsOpened) { // copy vertex coordinate pavDst[ iRemap] = avVertices[idxVtx]; } // if creating unwrapped mapping else { // copy texture coordinate FLOAT3D vMap; vMap(1) = avTextureVertices[actTriangles[iPol].ct_iTVtx[iVtx]](1); vMap(2) = -avTextureVertices[actTriangles[iPol].ct_iTVtx[iVtx]](2); vMap(3) = 0; pavDst[ iRemap] = vMap; } // remap index of polygon vertex actTriangles[iPol].ct_iVtx[iVtx] = iRemap+ctOld; } }} }
// print text of current message void PrintMessageText(CDrawPort *pdp) { if (_acmMessages.Count()==0 || _iActiveMessage>=_acmMessages.Count()|| fComputerFadeValue<0.99f) { return; } SetFont2(pdp); // print subject CTString strSubject0; CTString strSubject1; CTString strSubject2; //strSubject.PrintF("%g", _fMsgAppearFade); const char *strSubject = _acmMessages[_iActiveMessage].cm_strSubject; INDEX ctSubjectLen = strlen(strSubject); INDEX ctToPrint = int(_fMsgAppearDelta*20.0f); for (INDEX iChar=0; iChar<ctSubjectLen; iChar++) { char strChar[2]; strChar[0] = strSubject[iChar]; strChar[1] = 0; if (iChar>ctToPrint) { NOTHING; } else if (iChar==ctToPrint) { strSubject2+=strChar; } else if (iChar==ctToPrint-1) { strSubject1+=strChar; } else { strSubject0+=strChar; } } PIX pixWidth0 = pdp->GetTextWidth(strSubject0); PIX pixWidth1 = pdp->GetTextWidth(strSubject1); pdp->PutText(strSubject0, _pixMarginI, _pixMarginJ-1, _colMedium); pdp->PutText(strSubject1, _pixMarginI+pixWidth0, _pixMarginJ-1, LerpColor( _colLight, _colMedium, 0.5f)); pdp->PutText(strSubject2, _pixMarginI+pixWidth0+pixWidth1, _pixMarginJ-1, _colLight); pdp->DrawLine(0, PIX(_pixMarginJ*4), _boxMsgText.Size()(1), PIX(_pixMarginJ*4), _colBoxes); // fill in fresh player statistics if (strncmp(_acmMessages[_iActiveMessage].cm_strText, "$STAT", 5)==0) { _ppenPlayer->GetStats(_strStatsDetails, CST_DETAIL, _ctTextCharsPerRow); _acmMessages[_iActiveMessage].cm_ctFormattedWidth = 0; } // format text _acmMessages[_iActiveMessage].PrepareMessage(_ctTextCharsPerRow); SetFont1(pdp); INDEX ctLineToPrint = int(_fMsgAppearDelta*20.0f); // print it PIX pixJ = _pixMarginJ*4; for (INDEX iLine = _iTextLineOnScreen; iLine<_iTextLineOnScreen+_ctTextLinesOnScreen; iLine++) { INDEX iPrintLine = iLine-_iTextLineOnScreen; if (iPrintLine>ctLineToPrint) { continue; } COLOR col = LerpColor( _colLight, _colMedium, Clamp( FLOAT(ctLineToPrint-iPrintLine)/3, 0.0f, 1.0f)); pdp->PutText(_acmMessages[_iActiveMessage].GetLine(iLine), _pixMarginI, pixJ, col); pixJ+=_pixCharSizeJ; } PIXaabbox2D boxSliderSpace = GetTextSliderSpace(); LCDDrawBox(0,0,boxSliderSpace, _colBoxes); PIXaabbox2D boxSlider = GetTextSliderBox(); COLOR col = _colBoxes; PIXaabbox2D boxSliderTrans = boxSlider; boxSliderTrans+=_boxMsgText.Min(); if (boxSliderTrans>=_vpixMouse) { col = LCDBlinkingColor(_colLight, _colDark); } pdp->Fill( boxSlider.Min()(1)+2, boxSlider.Min()(2)+2, boxSlider.Size()(1)-4, boxSlider.Size()(2)-4, col); }
FLOAT3D vMap; vMap(1) = avTextureVertices[actTriangles[iPol].ct_iTVtx[iVtx]](1); vMap(2) = -avTextureVertices[actTriangles[iPol].ct_iTVtx[iVtx]](2); vMap(3) = 0; pavDst[ iRemap] = vMap; } // remap index of polygon vertex actTriangles[iPol].ct_iVtx[iVtx] = iRemap+ctOld; } }} } aiRemap.Clear(); // replace remapped array of vertices over original one avVertices.Clear(); avVertices.New(avDst.Count()); for( INDEX iVtxNew=0; iVtxNew<avDst.Count(); iVtxNew++) { avVertices[iVtxNew] = avDst[iVtxNew]; } avDst.PopAll(); {INDEX ctSurf = 0; // fill remap array with indices of vertices in order how they appear per polygons {FOREACHINDYNAMICCONTAINER(acmMaterials, ConversionMaterial, itcm) { _RPT1(_CRT_WARN, "Indices of polygons in surface %d:", ctSurf); // for each polygon in surface {FOREACHINDYNAMICCONTAINER(itcm->ms_Polygons, INDEX, itipol) { _RPT1(_CRT_WARN, " %d,", *itipol);