// 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;
    }

	}




};
예제 #2
0
void CDlgSelectMode::OnTestButton()
{
  CWnd wndTestWindowedMode;

  UpdateData( TRUE);

  // apply wanted display mode settings
  CDisplayMode dm;
  enum GfxAPIType gfxAPI;
  ApplySettings( &dm, &gfxAPI);

  // try to set wanted display mode
  PIX pixSizeI    = dm.dm_pixSizeI;
  PIX pixSizeJ    = dm.dm_pixSizeJ;

  BOOL bDisplayModeSet = _pGfx->SetDisplayMode( GAT_OGL, 0, pixSizeI, pixSizeJ, dm.dm_ddDepth);
  if( !bDisplayModeSet) {
    AfxMessageBox( L"Unable to setup full screen display. Test mode failed.");
    return;
  }

  //--------------------------- Open window for testing windowed display mode

  // draw ports and viewports needed for printing message
  CDrawPort *pDrawPort;
  CViewPort *pViewPort;

  // get the windows dimensions for this display
	int iScreenX = ::GetSystemMetrics(SM_CXSCREEN);	// screen size
	int iScreenY = ::GetSystemMetrics(SM_CYSCREEN);

  // open window of display mode size
  const wchar_t *strWindowClass = AfxRegisterWndClass( CS_OWNDC|CS_NOCLOSE);
  wndTestWindowedMode.CreateEx( WS_EX_TOPMOST, strWindowClass, L"Test mode",
                                WS_POPUP|WS_VISIBLE, 0,0, iScreenX,iScreenY, m_hWnd, 0);
  // create window canvas
  _pGfx->CreateWindowCanvas( wndTestWindowedMode.m_hWnd, &pViewPort, &pDrawPort);

  // if screen or window opening was not successful
  if( pViewPort == NULL) {
    AfxMessageBox( L"Unable to setup full screen display. Test mode failed.");
    return;
  }

  // show test mode screen
  ShowTestModeScreen( pDrawPort, pViewPort);
    
  // get starting time
  CTimerValue tvStart = _pTimer->GetHighPrecisionTimer();
  // loop forever
  FOREVER {
    // get current time
    CTimerValue tvCurrent = _pTimer->GetHighPrecisionTimer();
    // get time difference in seconds
    CTimerValue tvElapsed = tvCurrent - tvStart;
    // three seconds passed?
    if( tvElapsed.GetSeconds() > 5.0f) break;
  }
  
	// destroy windowed canvas
  _pGfx->DestroyWindowCanvas( pViewPort);
  pViewPort = NULL;
  // destroy window
  wndTestWindowedMode.DestroyWindow();

  // restore old mode
  _pGfx->ResetDisplayMode();

  if( AfxMessageBox( L"Did You see displayed message correctly?", MB_YESNO) == IDYES) {
    GetDlgItem( IDOK)->SetFocus(); // set focus to apply button
  } else {
    AfxMessageBox( L"Mode is not valid and it is rejected. Choose another one.");
  }

  Invalidate( FALSE);
}
예제 #3
0
void CProfileForm::CalibrateProfilingTimers(void)
{
  enum Epsilons {
    ETI_TOTAL,
    ETI_STARTSTOP,
    ETI_START,
    ETI_STOP,
    ETI_DUMMY,
    ETI_COUNT
  };

  CProfileForm pfCalibration("", "", 0, ETI_COUNT);
  // set all epsilons to zero, so that they don't interfere with the measuring
  _tvStartEpsilon.Clear();
  _tvStopEpsilon.Clear();
  _tvStartStopEpsilon.Clear();
  _tvCurrentProfilingEpsilon.Clear();

  /* NOTE: we must use one more counter (ETI_TOTAL), so that we don't overestimate
   * time spent in StartTimer(), StopTimer() if it is the first timer started.
   */

#define REPEATCOUNT 10000
  // measure how much it takes to start and stop timer
  __int64 llMinStartStopTime(0x7fffffffffffffff);
  {for (INDEX i=0; i<REPEATCOUNT; i++) {
    pfCalibration.Reset();
    pfCalibration.StartTimer(ETI_TOTAL);
    pfCalibration.StartTimer(ETI_STARTSTOP);
    pfCalibration.StopTimer(ETI_STARTSTOP);
    pfCalibration.StopTimer(ETI_TOTAL);
    __int64 llThisStartStopTime = pfCalibration.pf_aptTimers[ETI_STARTSTOP].
      pt_tvElapsed.tv_llValue;
    if (llThisStartStopTime<llMinStartStopTime) {
      llMinStartStopTime = llThisStartStopTime;
    }
  }}
  _tvStartStopEpsilon = llMinStartStopTime;

  // measure how much it takes to start timer
  __int64 llMinStartTime(0x7fffffffffffffff);
  {for (INDEX i=0; i<REPEATCOUNT; i++) {
    pfCalibration.Reset();
    pfCalibration.StartTimer(ETI_TOTAL);
    pfCalibration.StartTimer(ETI_START);
    pfCalibration.StartTimer(ETI_DUMMY);
    pfCalibration.StopTimer(ETI_START);
    pfCalibration.StopTimer(ETI_TOTAL);
    pfCalibration.StopTimer(ETI_DUMMY);
    __int64 llThisStartTime = pfCalibration.pf_aptTimers[ETI_START].
      pt_tvElapsed.tv_llValue;
    if (llThisStartTime<llMinStartTime) {
      llMinStartTime = llThisStartTime;
    }
  }}
  _tvStartEpsilon = llMinStartTime;

  // measure how much it takes to stop timer
  __int64 llMinStopTime(0x7fffffffffffffff);
  {for (INDEX i=0; i<REPEATCOUNT; i++) {
    pfCalibration.Reset();
    pfCalibration.StartTimer(ETI_TOTAL);
    pfCalibration.StartTimer(ETI_DUMMY);
    pfCalibration.StartTimer(ETI_STOP);
    pfCalibration.StopTimer(ETI_DUMMY);
    pfCalibration.StopTimer(ETI_STOP);
    pfCalibration.StopTimer(ETI_TOTAL);
    __int64 llThisStopTime = pfCalibration.pf_aptTimers[ETI_STOP].
      pt_tvElapsed.tv_llValue;
    if (llThisStopTime<llMinStopTime) {
      llMinStopTime = llThisStopTime;
    }
  }}
  _tvStopEpsilon = llMinStopTime;

  pfCalibration.Reset();
  pfCalibration.StartTimer(ETI_TOTAL);
  pfCalibration.StartTimer(ETI_STARTSTOP);
  pfCalibration.StopTimer(ETI_STARTSTOP);
  pfCalibration.StopTimer(ETI_TOTAL);
  _tvTest = pfCalibration.pf_aptTimers[ETI_STARTSTOP].pt_tvElapsed;

}
예제 #4
0
void CGame::ComputerRender(CDrawPort *pdp)
{
  // if playing a demo
  if (_pNetwork->IsPlayingDemo()) {
    // never call computer
    cmp_ppenPlayer = NULL;
  }

  // disable netricsa for non-local players
  if (cmp_ppenPlayer!=NULL && !_pNetwork->IsPlayerLocal(cmp_ppenPlayer)) {
    cmp_ppenPlayer = NULL;
  }
  if (cmp_ppenDHPlayer!=NULL && !_pNetwork->IsPlayerLocal(cmp_ppenDHPlayer)) {
    cmp_ppenDHPlayer = NULL;
  }
  if (cmp_ppenDHPlayer!=NULL && !pdp->IsDualHead()) {
    cmp_ppenDHPlayer = NULL;
  }

  // initially - no player
  _ppenPlayer=NULL;

  // if player calls computer
  if (cmp_ppenPlayer!=NULL) {
    // use that player
    _ppenPlayer = cmp_ppenPlayer;
    // if computer is on in background
    if (_pGame->gm_csComputerState==CS_ONINBACKGROUND) {
      // just toggle to on
      _pGame->gm_csComputerState=CS_ON;
      // find group with some unread messages
      FindGroupWithUnread();
      // force reinit
      _cmtCurrentType = (enum CompMsgType)-1;
    }
  // if using dualhead to render computer on second display
  } else if (cmp_ppenDHPlayer!=NULL) {
    // use that player
    _ppenPlayer = cmp_ppenDHPlayer;
    // clear dualhead request - it has to be reinitialized every frame
    cmp_ppenDHPlayer = NULL;

    // if viewing statistics
    if (_cmtWantedType == CMT_STATISTICS) {
      // fill in fresh player statistics
      _ppenPlayer->GetStats(_strStatsDetails, CST_DETAIL, _ctTextCharsPerRow);
      // force updating
      UpdateType(TRUE);
    }

    // if computer is not on or on in background
    if (_pGame->gm_csComputerState!=CS_ON && _pGame->gm_csComputerState!=CS_ONINBACKGROUND) {
      // switch on fast
      ComputerOn();
      fComputerFadeValue = 1.0f;
      _pGame->gm_csComputerState = CS_ONINBACKGROUND;
      cmp_bInitialStart = FALSE; // end of eventual initial start
    }

    // if should update to new message
    if (cmp_bUpdateInBackground) {
      cmp_bUpdateInBackground = FALSE;
      FindGroupWithUnread();
      // force reinit
      _cmtCurrentType = (enum CompMsgType)-1;
    }
  }

  // if no player
  if (_ppenPlayer==NULL) {
    // make sure computer is off
    _pGame->gm_csComputerState=CS_OFF;
    // do nothing more
    return;
  }

  // if computer is not active
  if (_pGame->gm_csComputerState==CS_OFF) {
    // just remember time
    tvComputerLast = _pTimer->GetHighPrecisionTimer();
    // if a player wants computer
    if (_ppenPlayer!=NULL) {
      // start turning on
      _pGame->gm_csComputerState=CS_TURNINGON;
      ComputerOn();
    } else {
      return;
    }
  }
 
  // calculate up-down speed to be independent of refresh speed
  CTimerValue tvNow   = _pTimer->GetHighPrecisionTimer();
  CTimerValue tvDelta = tvNow - tvComputerLast;
  tvComputerLast      = tvNow;
  FLOAT fFadeSpeed    = (FLOAT)(tvDelta.GetSeconds() / tmComputerFade);

  // if computer is dropping down
  if( _pGame->gm_csComputerState==CS_TURNINGON) {
    // move it down
    fComputerFadeValue += fFadeSpeed;
    // if finished moving
    if( fComputerFadeValue>1.0f) {
      // stop
      fComputerFadeValue = 1.0f;
      _pGame->gm_csComputerState   = CS_ON;
      cmp_bInitialStart  = FALSE; // end of eventual initial start
    }
  }
  // if computer is pulling up
  if( _pGame->gm_csComputerState==CS_TURNINGOFF) {
    // move it up
    fComputerFadeValue -= fFadeSpeed;
    // if finished moving
    if( fComputerFadeValue<0.0f) {
      // stop
      fComputerFadeValue = 0.0f;
      _pGame->gm_csComputerState   = CS_OFF;
      ComputerOff();
      cmp_ppenPlayer = NULL;
      // exit computer
      return;
    }
  }

  // safety check -> do not proceed if no player
  if (_ppenPlayer==NULL) {
    return;
  }

  // lock drawport
  CDrawPort dpComp(pdp, FALSE);
  if(!dpComp.Lock()) {
    // do nothing
    return;
  }

  // if in fullscreen
  CDisplayMode dmCurrent;
  _pGfx->GetCurrentDisplayMode(dmCurrent);
  if (dmCurrent.IsFullScreen() && dmCurrent.IsDualHead()) {
    // clamp mouse pointer
    _vpixMouse(1) = Clamp(_vpixMouse(1), 0L, dpComp.GetWidth());
    _vpixMouse(2) = Clamp(_vpixMouse(2), 0L, dpComp.GetHeight());
  // if in window
  } else {
    // use same mouse pointer as windows
    _vpixMouse = _vpixExternMouse;
    // if dualhead
    if (dpComp.dp_MinI>0) {
      // offset by half screen
      _vpixMouse(1) -= dpComp.GetWidth();
    }
    // if widescreen
    if (dpComp.dp_MinJ>0) {
      // offset by screen top
      _vpixMouse(2) -= dpComp.dp_MinJ;
    }
  }

  TIME tmOld     = _pTimer->CurrentTick();
  FLOAT fLerpOld = _pTimer->GetLerpFactor();

  FLOAT fSec = tvNow.GetSeconds();
  TIME tmTick = floor(fSec/_pTimer->TickQuantum)*_pTimer->TickQuantum;
  FLOAT fLerp = (fSec-tmTick)/_pTimer->TickQuantum;
  _pTimer->SetCurrentTick(tmTick);
  _pTimer->SetLerp(fLerp);

  LCDPrepare(1.0f);//ClampUp(fComputerFadeValue*10,1.0f));
  LCDSetDrawport(&dpComp);
  // if initial start
  if (cmp_bInitialStart) {
    // do not allow game to show through
    dpComp.Fill(C_BLACK|255);
  // if normal start
  } else {
    // fade over game view
    dpComp.Fill(LCDFadedColor(C_BLACK|255));
  }
  dpComp.FillZBuffer(1.0f);

  // update screen geometry
  UpdateSize(&dpComp);
  // update scroll positions
  UpdateType();
  UpdateFirstOnScreen();
  // check for message change
  UpdateMessageAppearing();
  // mark current message as read
  MarkCurrentRead();

  // get current time and alpha value
  FLOAT tmNow = (FLOAT)tvNow.GetSeconds();
  ULONG ulA   = NormFloatToByte(fComputerFadeValue);

  _colLight  = LCDFadedColor(C_WHITE|255);
  _colMedium = LCDFadedColor(SE_COL_BLUE_LIGHT|255);
  _colDark   = LCDFadedColor(LerpColor(SE_COL_BLUE_DARK, SE_COL_BLUE_LIGHT, 0.5f)|255);
  _colBoxes  = LCDFadedColor(LerpColor(SE_COL_BLUE_DARK, SE_COL_BLUE_LIGHT, 0.5f)|255);

  // background
  LCDRenderCloudsForComp();
//  dpComp.DrawLine( 0, pixSizeJ-1, pixSizeI, pixSizeJ-1, C_GREEN|ulA);

  // all done
  dpComp.Unlock();

  // print title
  CDrawPort dpTitle(&dpComp, _boxTitle);
  if (dpTitle.Lock()) {
    LCDSetDrawport(&dpTitle);
    LCDRenderCompGrid();
    LCDRenderClouds2();
    LCDScreenBoxOpenLeft(_colBoxes);
    PrintTitle(&dpTitle);
    dpTitle.Unlock();
  }

  // print exit button
  CDrawPort dpExit(&dpComp, _boxExit);
  if (dpExit.Lock()) {
    LCDSetDrawport(&dpExit);
    LCDRenderCompGrid();
    LCDRenderClouds2();
    LCDScreenBoxOpenRight(_colBoxes);
    PrintExit(&dpExit);
    dpExit.Unlock();
  }

  // print buttons
  for (INDEX i=0; i<CMT_COUNT; i++) {
    PrintButton(&dpComp, i);
  }
  // print list of messages
  CDrawPort dpMsgList(&dpComp, _boxMsgList);
  if (dpMsgList.Lock()) {
    LCDSetDrawport(&dpMsgList);
    LCDRenderCompGrid();
    LCDRenderClouds2();
    LCDScreenBox(_colBoxes);
    PrintMessageList(&dpMsgList);
    dpMsgList.Unlock();
  }
  // print text of current message
  CDrawPort dpMsgText(&dpComp, _boxMsgText);
  if (dpMsgText.Lock()) {
    LCDSetDrawport(&dpMsgText);
    LCDRenderCompGrid();
    LCDRenderClouds2();
    LCDScreenBox(_colBoxes);
    PrintMessageText(&dpMsgText);
    dpMsgText.Unlock();
  }
  // draw image of current message
  CDrawPort dpMsgImage(&dpComp, _boxMsgImage);
  if (dpMsgImage.Lock()) {
    LCDSetDrawport(&dpMsgImage);
    RenderMessageImage(&dpMsgImage);
    dpMsgImage.Unlock();
  }

  // render mouse pointer on top of everything else
  if (_pGame->gm_csComputerState != CS_ONINBACKGROUND) {
    if (dpComp.Lock()) {
      LCDSetDrawport(&dpComp);
      LCDDrawPointer(_vpixMouse(1), _vpixMouse(2));
      dpComp.Unlock();
    }
  }

  _pTimer->SetCurrentTick(tmOld);
  _pTimer->SetLerp(fLerpOld);
}