示例#1
0
void TryRunTics (void)
{
	int runtics;
	int entertime = I_GetTime();

	// Wait for tics to run
	while (1)
	{
#ifdef HAVE_NET
    NetUpdate();
#else
    D_BuildNewTiccmds();
#endif

    runtics = (server ? remotetic : maketic) - gametic;
	
    if (!runtics)
	{
		if (server)
			I_WaitForPacket(ms_to_next_tick);
		else
			I_uSleep(ms_to_next_tick*1000);

		if (I_GetTime() - entertime > 10)
		{
			remotesend--;
			
			if (server)
			{
				char buf[sizeof(packet_header_t) + 1];
				
				packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic);
				buf[sizeof(buf) - 1] = consoleplayer;
				I_SendPacket((packet_header_t *)buf, sizeof buf);
			}
			
			M_Ticker();
			return;
		}
		} else break;
	}

	while (runtics--)
	{
#ifdef HAVE_NET
		if (server) CheckQueuedPackets();
#endif
		if (advancedemo) D_DoAdvanceDemo ();
	
		M_Ticker ();
		G_Ticker ();
	
		gametic++;
	
#ifdef HAVE_NET
		NetUpdate(); // Keep sending our tics to avoid stalling remote nodes
#endif
	}
}
示例#2
0
文件: d_loop.c 项目: mdgunn/doomretro
void TryRunTics(void)
{
    // get real tics
    int entertic = I_GetTime();
    int counts;

    // get available tics
    NetUpdate();

    counts = maketic - gametic;

    if (!counts && !vid_capfps)
        return;

    if (counts < 1)
        counts = 1;

    // wait for new tics if needed
    while (maketic < gametic + counts)
    {
        NetUpdate();

        // Still no tics to run? Sleep until some are available.
        if (maketic < gametic + counts)
        {
            // If we're in a netgame, we might spin forever waiting for
            // new network data to be received. So don't stay in here
            // forever - give the menu a chance to work.
            if (I_GetTime() - entertic >= MAX_NETGAME_STALL_TICS)
                return;

            I_Sleep(1);
        }
    }

    // run the count tics
    while (counts--)
    {
        if (advancetitle)
            D_DoAdvanceTitle();

        G_Ticker();
        gametic++;
        gametime++;

        if (netcmds[0].buttons & BT_SPECIAL)
            netcmds[0].buttons = 0;

        NetUpdate();
    }
}
示例#3
0
void TryRunTics (void)
{
  int runtics;
  int entertime = I_GetTime();

  // Wait for tics to run
  while (1) {
    NetUpdate();
    runtics = (server ? remotetic : maketic) - gametic;
    if (!runtics) {
      if (!movement_smooth) {
        if (server)
          I_WaitForPacket(ms_to_next_tick);
        else
          I_uSleep(ms_to_next_tick*1000);
      }
      if (I_GetTime() - entertime > 10) {
        if (server) {
          char buf[sizeof(packet_header_t)+1];
          remotesend--;
          packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic);
          buf[sizeof(buf)-1] = consoleplayer;
          I_SendPacket((packet_header_t *)buf, sizeof buf);
        }
        M_Ticker(); return;
      }
      {
        WasRenderedInTryRunTics = TRUE;
        if (movement_smooth && gamestate==wipegamestate)
        {
          isExtraDDisplay = TRUE;
          D_Display();
          isExtraDDisplay = FALSE;
        }
      }
    } else break;
  }

  while (runtics--) {
    if (server) CheckQueuedPackets();
    if (advancedemo)
      D_DoAdvanceDemo ();
    M_Ticker ();
    I_GetTime_SaveMS();
    G_Ticker ();
    P_Checksum(gametic);
    gametic++;
    NetUpdate(); // Keep sending our tics to avoid stalling remote nodes
  }
}
示例#4
0
void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked)
{
	if (pl->left >= pl->right)
		return;

	if (r_drawflat)
	{ // [RH] no texture mapping
		ds_color += 4;
		R_MapVisPlane (pl, R_MapColoredPlane);
	}
	else if (pl->picnum == skyflatnum)
	{ // sky flat
		R_DrawSkyPlane (pl);
	}
	else
	{ // regular flat
		FTexture *tex = TexMan(pl->picnum, true);

		if (tex->UseType == FTexture::TEX_Null)
		{
			return;
		}

		if (!masked && !additive)
		{ // If we're not supposed to see through this plane, draw it opaque.
			alpha = OPAQUE;
		}
		else if (!tex->bMasked)
		{ // Don't waste time on a masked texture if it isn't really masked.
			masked = false;
		}
		R_SetupSpanBits(tex);
		double xscale = pl->xform.xScale * tex->Scale.X;
		double yscale = pl->xform.yScale * tex->Scale.Y;
		R_SetSpanSource(tex);

		basecolormap = pl->colormap;
		planeshade = LIGHT2SHADE(pl->lightlevel);

		if (r_drawflat || (!pl->height.isSlope() && !tilt))
		{
			R_DrawNormalPlane(pl, xscale, yscale, alpha, additive, masked);
		}
		else
		{
			R_DrawTiltedPlane(pl, xscale, yscale, alpha, additive, masked);
		}
	}
	NetUpdate ();
}
示例#5
0
void TryRunTics (void)
{
	// get real tics
	static QWORD oldentertics = 0;

	QWORD entertic = I_WaitForTic (oldentertics);
	QWORD realtics = entertic - oldentertics;
	oldentertics = entertic;

	std::string cmd = I_ConsoleInput();
	if (cmd.length())
	{
		AddCommandString (cmd.c_str());
	}
	
	// run the realtics tics
	if(!stepmode)
		TryStepTics(realtics);
	else
	{
		NetUpdate();

		if(nextstep)
		{
			canceltics = 0;
			TryStepTics(nextstep);
			nextstep = 0;

			// debugging output
			extern unsigned char prndindex;
			if(players.size() && players[0].mo)
				Printf(PRINT_HIGH, "level.time %d, prndindex %d, %d %d %d\n", level.time, prndindex, players[0].mo->x, players[0].mo->y, players[0].mo->z);
			else
 				Printf(PRINT_HIGH, "level.time %d, prndindex %d\n", level.time, prndindex);
		}
	}
}
示例#6
0
void TryStepTics(QWORD tics)
{
	DObject::BeginFrame ();
	
	// run the realtics tics
	while (tics--)
	{
		if(canceltics && canceltics--)
			continue;

		NetUpdate ();

		if (advancedemo)
			D_DoAdvanceDemo ();
		
		C_Ticker ();
		M_Ticker ();
		G_Ticker ();
		gametic++;
	}
	
	DObject::EndFrame ();

}
示例#7
0
//
// R_RenderView
//
void R_RenderPlayerView (player_t* player)
{
    R_SetupFrame (player);

    // Clear buffers.
    R_ClearClipSegs ();
    R_ClearDrawSegs ();
    R_ClearPlanes ();
    R_ClearSprites ();

    rendered_segs = rendered_visplanes = 0;
    if (V_GetMode() == VID_MODEGL)
    {
#ifdef GL_DOOM
        // proff 11/99: clear buffers
        gld_InitDrawScene();
        // proff 11/99: switch to perspective mode
        gld_StartDrawScene();
#endif
    } else {
        if (autodetect_hom)
        {   // killough 2/10/98: add flashing red HOM indicators
            int color=(gametic % 20) < 9 ? 0xb0 : 0;
            int h=viewheight;
            for (; h>0; h--)
                memset(screens[0].data+(viewwindowy+h)*screens[0].pitch,color,SCREENWIDTH);
            R_DrawViewBorder();
        }
    }

    // check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    // The head node is the last node output.
    R_RenderBSPNode (numnodes-1);

    // Check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    if (V_GetMode() != VID_MODEGL)
        R_DrawPlanes ();

    // Check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    if (V_GetMode() != VID_MODEGL) {
        R_DrawMasked ();
        R_ResetColumnBuffer();
    }

    // Check for new console commands.
#ifdef HAVE_NET
    NetUpdate ();
#endif

    if (V_GetMode() == VID_MODEGL) {
#ifdef GL_DOOM
        // proff 11/99: draw the scene
        gld_DrawScene(player);
        // proff 11/99: finishing off
        gld_EndDrawScene();
#endif
    }

    if (rendering_stats) R_ShowStats();

    R_RestoreInterpolations();
}
示例#8
0
void D_Display (void)
{
  static boolean inhelpscreensstate   = false;
  static boolean isborderstate        = false;
  static boolean borderwillneedredraw = false;
  static gamestate_t oldgamestate = -1;
  boolean wipe;
  boolean viewactive = false, isborder = false;

  if (nodrawers)                    // for comparative timing / profiling
    return;

  if (!I_StartDisplay())
    return;

  // save the current screen if about to wipe
  if ((wipe = gamestate != wipegamestate) && (V_GetMode() != VID_MODEGL))
    wipe_StartScreen();

  if (gamestate != GS_LEVEL) { // Not a level
    switch (oldgamestate) {
    case -1:
    case GS_LEVEL:
      V_SetPalette(0); // cph - use default (basic) palette
    default:
      break;
    }

    switch (gamestate) {
    case GS_INTERMISSION:
      WI_Drawer();
      break;
    case GS_FINALE:
      F_Drawer();
      break;
    case GS_DEMOSCREEN:
      D_PageDrawer();
      break;
    default:
      break;
    }
  } else if (gametic != basetic) { // In a level
    boolean redrawborderstuff;

    HU_Erase();

    if (setsizeneeded) {               // change the view size if needed
      R_ExecuteSetViewSize();
      oldgamestate = -1;            // force background redraw
    }

    // Work out if the player view is visible, and if there is a border
    viewactive = (!(automapmode & am_active) || (automapmode & am_overlay)) && !inhelpscreens;
    isborder = viewactive ? (viewheight != SCREENHEIGHT) : (!inhelpscreens && (automapmode & am_active));

    if (oldgamestate != GS_LEVEL) {
      R_FillBackScreen ();    // draw the pattern into the back screen
      redrawborderstuff = isborder;
    } else {
      // CPhipps -
      // If there is a border, and either there was no border last time,
      // or the border might need refreshing, then redraw it.
      redrawborderstuff = isborder && (!isborderstate || borderwillneedredraw);
      // The border may need redrawing next time if the border surrounds the screen,
      // and there is a menu being displayed
      borderwillneedredraw = menuactive && isborder && viewactive && (viewwidth != SCREENWIDTH);
    }
    if (redrawborderstuff || (V_GetMode() == VID_MODEGL))
      R_DrawViewBorder();

    // Now do the drawing
    if (viewactive)
      R_RenderPlayerView (&players[displayplayer]);
    if (automapmode & am_active)
      AM_Drawer();
    ST_Drawer((viewheight != SCREENHEIGHT) || ((automapmode & am_active) && !(automapmode & am_overlay)), redrawborderstuff);
    if (V_GetMode() != VID_MODEGL)
      R_DrawViewBorder();
    HU_Drawer();
  }

  inhelpscreensstate = inhelpscreens;
  isborderstate      = isborder;
  oldgamestate = wipegamestate = gamestate;

  // draw pause pic
  if (paused) {
    // Simplified the "logic" here and no need for x-coord caching - POPE
    V_DrawNamePatch((320 - V_NamePatchWidth("M_PAUSE"))/2, 4,
                    0, "M_PAUSE", CR_DEFAULT, VPT_STRETCH);
  }

  // menus go directly to the screen
  M_Drawer();          // menu is drawn even on top of everything
#ifdef HAVE_NET
  NetUpdate();         // send out any new accumulation
#else
  D_BuildNewTiccmds();
#endif

  // normal update
  if (!wipe || (V_GetMode() == VID_MODEGL))
    I_FinishUpdate ();              // page flip or blit buffer
  else {
    // wipe update
    wipe_EndScreen();
    D_Wipe();
  }

  I_EndDisplay();

  //e6y: don't thrash cpu during pausing
  if (paused) {
    I_uSleep(1000);
  }
}
示例#9
0
static void D_Display(void)
{
	static boolean menuactivestate = false;
	static gamestate_t oldgamestate = -1;
	boolean redrawsbar = false;
	static boolean wipe = false;

	if (dedicated)
		return;

	if (nodrawers)
		return; // for comparative timing/profiling

	// check for change of screen size (video mode)
	if (setmodeneeded && !wipe)
		SCR_SetMode(); // change video mode

	if (vid.recalc)
		SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()

	// change the view size if needed
	if (setsizeneeded)
	{
		R_ExecuteSetViewSize();
		oldgamestate = -1; // force background redraw
		redrawsbar = true;
	}

	// save the current screen if about to wipe
	if (gamestate != wipegamestate)
	{
		wipe = true;

#ifndef SHUFFLE
		if (rendermode == render_soft)
#endif
			F_WipeStartScreen();
	}
	else
		wipe = false;

	// Hardware mode does not fade wipe.
	// Thus, don't delay it unless needed for synchronisity.
#ifndef SHUFFLE
	if (rendermode != render_soft /*&& !netgame*/)
	{
		if (gamestate != GS_INTRO
		&& gamestate != GS_INTRO2
		&& gamestate != GS_CUTSCENE)
			wipe = false;
	}
#endif
	// draw buffered stuff to screen
	// Used only by linux GGI version
	I_UpdateNoBlit();

	// Fade to black first
	if (rendermode != render_none)
	{
		if (wipe)
		{
			if (!(mapheaderinfo[gamemap-1]->interscreen[0] == '#'
				&& gamestate == GS_INTERMISSION))
			{
				V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
#if defined (SHUFFLE) && defined (HWRENDER)
				if(rendermode != render_soft)
				{
					HWR_PrepFadeToBlack();
				}
#endif
			}
			F_WipeEndScreen(0, 0, vid.width, vid.height);

			F_RunWipe(2*TICRATE, gamestate != GS_TIMEATTACK);

			WipeInAction = false;
		}
		F_WipeStartScreen();
	}

	// do buffered drawing
	switch (gamestate)
	{
		case GS_LEVEL:
			if (!gametic)
				break;
			HU_Erase();
			if (automapactive)
				AM_Drawer();
			if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc)
				redrawsbar = true;
			break;

		case GS_INTERMISSION:
			Y_IntermissionDrawer();
			HU_Erase();
			HU_Drawer();
			break;

		case GS_TIMEATTACK:
			break;

		case GS_INTRO:
		case GS_INTRO2:
			F_IntroDrawer();
			break;

		case GS_CUTSCENE:
			F_CutsceneDrawer();
			HU_Erase();
			HU_Drawer();
			break;

		case GS_GAMEEND:
			F_GameEndDrawer();
			break;

		case GS_EVALUATION:
			F_GameEvaluationDrawer();
			break;

		case GS_CREDITS:
			F_CreditDrawer();
			HU_Erase();
			HU_Drawer();
			break;

		case GS_TITLESCREEN:
			F_TitleScreenDrawer();
			break;

		case GS_DEMOSCREEN:
			D_PageDrawer(pagename);
		case GS_DEDICATEDSERVER:
		case GS_WAITINGPLAYERS:
		case GS_NULL:
			break;
	}

	// Transitions for Introduction
	if (gamestate == GS_INTRO && oldgamestate == GS_INTRO2)
		wipe = true;
	else if (gamestate == GS_INTRO2 && oldgamestate == GS_INTRO)
		wipe = true;

	// clean up border stuff
	// see if the border needs to be initially drawn
	if (gamestate == GS_LEVEL)
	{
		if (oldgamestate != GS_LEVEL)
		{
#if 0
			R_FillBackScreen(); // draw the pattern into the back screen
#endif
		}

		// draw the view directly
		if (!automapactive && !dedicated && cv_renderview.value)
		{
			if (players[displayplayer].mo)
			{
				topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
#ifdef HWRENDER
				if (rendermode != render_soft)
					HWR_RenderPlayerView(0, &players[displayplayer]);
				else
#endif
				if (rendermode != render_none)
					R_RenderPlayerView(&players[displayplayer]);
			}

			// render the second screen
			if (secondarydisplayplayer != consoleplayer && players[secondarydisplayplayer].mo)
			{
#ifdef HWRENDER
				if (rendermode != render_soft)
					HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
				else
#endif
				if (rendermode != render_none)
				{
					viewwindowy = vid.height / 2;
					M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));

					topleft = screens[0] + viewwindowy*vid.width + viewwindowx;

					R_RenderPlayerView(&players[secondarydisplayplayer]);

					viewwindowy = 0;
					M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
				}
			}

			// Image postprocessing effect
			if (postimgtype)
				V_DoPostProcessor(0, postimgtype, postimgparam);
			if (postimgtype2)
				V_DoPostProcessor(1, postimgtype2, postimgparam2);
		}

		if (lastdraw)
		{
			if (rendermode == render_soft)
				VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
			lastdraw = false;
		}

		ST_Drawer(redrawsbar);

		HU_Drawer();
	}

	// change gamma if needed
	if (gamestate != oldgamestate && gamestate != GS_LEVEL)
		V_SetPalette(0);

	menuactivestate = menuactive;
	oldgamestate = wipegamestate = gamestate;

	// draw pause pic
	if (paused && (!menuactive || netgame))
	{
		INT32 py;
		patch_t *patch;
		if (automapactive)
			py = 4;
		else
			py = viewwindowy + 4;
		patch = W_CachePatchName("M_PAUSE", PU_CACHE);
		V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch);
	}

	// vid size change is now finished if it was on...
	vid.recalc = 0;

	// FIXME: draw either console or menu, not the two
	if (gamestate != GS_TIMEATTACK)
		CON_Drawer();

	M_Drawer(); // menu is drawn even on top of everything
	NetUpdate(); // send out any new accumulation

	// It's safe to end the game now.
	if (G_GetExitGameFlag())
	{
		Command_ExitGame_f();
		G_ClearExitGameFlag();
	}

	//
	// normal update
	//
	if (!wipe)
	{
		if (cv_netstat.value)
		{
			char s[50];
			Net_GetNetStat();

			s[sizeof s - 1] = '\0';

			snprintf(s, sizeof s - 1, "get %d b/s", getbps);
			V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s);
			snprintf(s, sizeof s - 1, "send %d b/s", sendbps);
			V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s);
			snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent);
			V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s);
			snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
			V_DrawString(BASEVIDWIDTH - V_StringWidth(s), BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
		}

		I_FinishUpdate(); // page flip or blit buffer

		if (takescreenshot) // Only take screenshots after drawing.
			M_DoScreenShot();

		return;
	}

	//
	// wipe update
	//

	if (rendermode != render_none)
	{
		F_WipeEndScreen(0, 0, vid.width, vid.height);

		F_RunWipe(2*TICRATE, gamestate != GS_TIMEATTACK);

		WipeInAction = false;
	}
}
示例#10
0
	void RenderPortal::RenderLinePortal(PortalDrawseg* pds, int depth)
	{
		auto viewport = Thread->Viewport.get();
		auto &viewpoint = viewport->viewpoint;
		
		// [ZZ] check depth. fill portal with black if it's exceeding the visual recursion limit, and continue like nothing happened.
		if (depth >= r_portal_recursions)
		{
			uint8_t color = (uint8_t)BestColor((uint32_t *)GPalette.BaseColors, 0, 0, 0, 0, 255);
			int spacing = viewport->RenderTarget->GetPitch();
			for (int x = pds->x1; x < pds->x2; x++)
			{
				if (x < 0 || x >= viewport->RenderTarget->GetWidth())
					continue;

				int Ytop = pds->ceilingclip[x - pds->x1];
				int Ybottom = pds->floorclip[x - pds->x1];

				if (viewport->RenderTarget->IsBgra())
				{
					uint32_t *dest = (uint32_t*)viewport->RenderTarget->GetBuffer() + x + Ytop * spacing;

					uint32_t c = GPalette.BaseColors[color].d;
					for (int y = Ytop; y <= Ybottom; y++)
					{
						*dest = c;
						dest += spacing;
					}
				}
				else
				{
					uint8_t *dest = viewport->RenderTarget->GetBuffer() + x + Ytop * spacing;

					for (int y = Ytop; y <= Ybottom; y++)
					{
						*dest = color;
						dest += spacing;
					}
				}
			}

			if (r_highlight_portals)
				RenderLinePortalHighlight(pds);

			return;
		}

		DAngle startang = viewpoint.Angles.Yaw;
		DVector3 startpos = viewpoint.Pos;
		DVector3 savedpath[2] = { viewpoint.Path[0], viewpoint.Path[1] };
		ActorRenderFlags savedvisibility = viewpoint.camera ? viewpoint.camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0);
		
		viewpoint.camera->renderflags &= ~RF_INVISIBLE;

		CurrentPortalUniq++;

		unsigned int portalsAtStart = WallPortals.Size();

		if (pds->mirror)
		{
			//vertex_t *v1 = ds->curline->v1;
			vertex_t *v1 = pds->src->v1;

			// Reflect the current view behind the mirror.
			if (pds->src->Delta().X == 0)
			{ // vertical mirror
				viewpoint.Pos.X = v1->fX() - startpos.X + v1->fX();
			}
			else if (pds->src->Delta().Y == 0)
			{ // horizontal mirror
				viewpoint.Pos.Y = v1->fY() - startpos.Y + v1->fY();
			}
			else
			{ // any mirror
				vertex_t *v2 = pds->src->v2;

				double dx = v2->fX() - v1->fX();
				double dy = v2->fY() - v1->fY();
				double x1 = v1->fX();
				double y1 = v1->fY();
				double x = startpos.X;
				double y = startpos.Y;

				// the above two cases catch len == 0
				double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy);

				viewpoint.Pos.X = (x1 + r * dx) * 2 - x;
				viewpoint.Pos.Y = (y1 + r * dy) * 2 - y;
			}
			viewpoint.Angles.Yaw = pds->src->Delta().Angle() * 2 - startang;
		}
		else
		{
			P_TranslatePortalXY(pds->src, viewpoint.Pos.X, viewpoint.Pos.Y);
			P_TranslatePortalZ(pds->src, viewpoint.Pos.Z);
			P_TranslatePortalAngle(pds->src, viewpoint.Angles.Yaw);
			P_TranslatePortalXY(pds->src, viewpoint.Path[0].X, viewpoint.Path[0].Y);
			P_TranslatePortalXY(pds->src, viewpoint.Path[1].X, viewpoint.Path[1].Y);

			if (!viewpoint.showviewer && viewpoint.camera && P_PointOnLineSidePrecise(viewpoint.Path[0], pds->dst) != P_PointOnLineSidePrecise(viewpoint.Path[1], pds->dst))
			{
				double distp = (viewpoint.Path[0] - viewpoint.Path[1]).Length();
				if (distp > EQUAL_EPSILON)
				{
					double dist1 = (viewpoint.Pos - viewpoint.Path[0]).Length();
					double dist2 = (viewpoint.Pos - viewpoint.Path[1]).Length();

					if (dist1 + dist2 < distp + 1)
					{
						viewpoint.camera->renderflags |= RF_INVISIBLE;
					}
				}
			}
		}

		viewpoint.Sin = viewpoint.Angles.Yaw.Sin();
		viewpoint.Cos = viewpoint.Angles.Yaw.Cos();

		viewpoint.TanSin = Thread->Viewport->viewwindow.FocalTangent * viewpoint.Sin;
		viewpoint.TanCos = Thread->Viewport->viewwindow.FocalTangent * viewpoint.Cos;

		CopyStackedViewParameters();

		validcount++;
		PortalDrawseg* prevpds = CurrentPortal;
		CurrentPortal = pds;

		Thread->PlaneList->ClearKeepFakePlanes();
		Thread->ClipSegments->Clear(pds->x1, pds->x2);

		WindowLeft = pds->x1;
		WindowRight = pds->x2;

		// RF_XFLIP should be removed before calling the root function
		int prevmf = MirrorFlags;
		if (pds->mirror)
		{
			if (MirrorFlags & RF_XFLIP)
				MirrorFlags &= ~RF_XFLIP;
			else MirrorFlags |= RF_XFLIP;
		}

		// some portals have height differences, account for this here
		Thread->Clip3D->EnterSkybox(); // push 3D floor height map
		CurrentPortalInSkybox = false; // first portal in a skybox should set this variable to false for proper clipping in skyboxes.

		// first pass, set clipping
		auto ceilingclip = Thread->OpaquePass->ceilingclip;
		auto floorclip = Thread->OpaquePass->floorclip;
		memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip));
		memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip));

		Thread->OpaquePass->RenderScene();
		Thread->Clip3D->ResetClip(); // reset clips (floor/ceiling)
		if (!savedvisibility && viewpoint.camera) viewpoint.camera->renderflags &= ~RF_INVISIBLE;

		Thread->PlaneList->Render();
		RenderPlanePortals();

		double vzp = viewpoint.Pos.Z;

		int prevuniq = CurrentPortalUniq;
		// depth check is in another place right now
		unsigned int portalsAtEnd = WallPortals.Size();
		for (; portalsAtStart < portalsAtEnd; portalsAtStart++)
		{
			RenderLinePortal(WallPortals[portalsAtStart], depth + 1);
		}
		int prevuniq2 = CurrentPortalUniq;
		CurrentPortalUniq = prevuniq;

		if (Thread->MainThread)
			NetUpdate();

		Thread->TranslucentPass->Render();	  //      this is required since with portals there often will be cases when more than 80% of the view is inside a portal.

		if (Thread->MainThread)
			NetUpdate();

		Thread->Clip3D->LeaveSkybox(); // pop 3D floor height map
		CurrentPortalUniq = prevuniq2;

		// draw a red line around a portal if it's being highlighted
		if (r_highlight_portals)
			RenderLinePortalHighlight(pds);

		CurrentPortal = prevpds;
		MirrorFlags = prevmf;
		viewpoint.Angles.Yaw = startang;
		viewpoint.Pos = startpos;
		viewpoint.Path[0] = savedpath[0];
		viewpoint.Path[1] = savedpath[1];
	}
示例#11
0
void TryRunTics (void)
{
    int	i;
    int	lowtic;
    int	entertic;
    static int oldentertics;
    int realtics;
    int	availabletics;
    int	counts;

    // get real tics
    entertic = I_GetTime() / ticdup;
    realtics = entertic - oldentertics;
    oldentertics = entertic;

    // in singletics mode, run a single tic every time this function
    // is called.

    if (singletics)
    {
        BuildNewTic();
    }
    else
    {
        NetUpdate ();
    }

    lowtic = GetLowTic();

    availabletics = lowtic - gametic/ticdup;

    // decide how many tics to run

    if (new_sync)
    {
	counts = availabletics;
    }
    else
    {
        // decide how many tics to run
        if (realtics < availabletics-1)
            counts = realtics+1;
        else if (realtics < availabletics)
            counts = realtics;
        else
            counts = availabletics;

        if (counts < 1)
            counts = 1;

        if (net_client_connected)
        {
            OldNetSync();
        }
    }

    if (counts < 1)
	counts = 1;

    // wait for new tics if needed

    while (!PlayersInGame() || lowtic < gametic/ticdup + counts)
    {
	NetUpdate ();

        lowtic = GetLowTic();

	if (lowtic < gametic/ticdup)
	    I_Error ("TryRunTics: lowtic < gametic");

        // Don't stay in this loop forever.  The menu is still running,
        // so return to update the screen

	if (I_GetTime() / ticdup - entertic > 0)
	{
	    return;
	}

        I_Sleep(1);
    }

    // run the count * ticdup dics
    while (counts--)
    {
        ticcmd_set_t *set;

        if (!PlayersInGame())
        {
            return;
        }

        set = &ticdata[(gametic / ticdup) % BACKUPTICS];

        if (!net_client_connected)
        {
            SinglePlayerClear(set);
        }

	for (i=0 ; i<ticdup ; i++)
	{
            if (gametic/ticdup > lowtic)
                I_Error ("gametic>lowtic");

            memcpy(local_playeringame, set->ingame, sizeof(local_playeringame));

            loop_interface->RunTic(set->cmds, set->ingame);
	    gametic++;

	    // modify command for duplicated tics

            TicdupSquash(set);
	}

	NetUpdate ();	// check for new console commands
    }
}
示例#12
0
文件: d_net.c 项目: jdbcdev/doomretro
void TryRunTics(void)
{
    int         i;
    int         lowtic;
    int         entertic;
    static int  oldentertics;
    int         realtics;
    int         availabletics;
    int         counts;

    // get real tics
    entertic = I_GetTime() / ticdup;
    realtics = entertic - oldentertics;
    oldentertics = entertic;

    lowtic = maketic;

    availabletics = lowtic - gametic / ticdup;

    // decide how many tics to run
    if (realtics < availabletics - 1)
        counts = realtics + 1;
    else if (realtics < availabletics)
        counts = realtics;
    else
        counts = availabletics;

    if (counts < 1)
        counts = 1;

    // wait for new tics if needed
    while (lowtic < gametic / ticdup + counts)
    {
        NetUpdate();

        lowtic = maketic;

        // Don't stay in this loop forever.  The menu is still running,
        // so return to update the screen
        if (I_GetTime() / ticdup - entertic > 0)
            return;

        I_Sleep(1);
    }

    // run the count * ticdup dics
    while (counts--)
    {
        for (i = 0; i < ticdup; i++)
        {
            if (advancetitle)
                D_DoAdvanceTitle();

            G_Ticker();
            gametic++;

            // modify command for duplicated tics
            if (i != ticdup - 1)
            {
                int     buf = (gametic / ticdup) % BACKUPTICS;
                int     j;

                for (j = 0; j < MAXPLAYERS; j++)
                {
                    ticcmd_t    *cmd = &netcmds[j][buf];

                    if (cmd->buttons & BT_SPECIAL)
                        cmd->buttons = 0;
                }
            }
        }
    }
}
示例#13
0
static void D_Display(void)
{
    static boolean menuactivestate = false;
    static gamestate_t oldgamestate = -1;
    boolean redrawsbar = false;

    static boolean wipe = false;
    INT32 wipedefindex = 0;

    if (dedicated)
        return;

    if (nodrawers)
        return; // for comparative timing/profiling

    // check for change of screen size (video mode)
    if (setmodeneeded && !wipe)
        SCR_SetMode(); // change video mode

    if (vid.recalc)
        SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()

    // change the view size if needed
    if (setsizeneeded)
    {
        R_ExecuteSetViewSize();
        oldgamestate = -1; // force background redraw
        redrawsbar = true;
    }

    // save the current screen if about to wipe
    if (gamestate != wipegamestate)
    {
        wipe = true;
        F_WipeStartScreen();
    }
    else
        wipe = false;

    // draw buffered stuff to screen
    // Used only by linux GGI version
    I_UpdateNoBlit();

    if (wipe)
    {
        // set for all later
        wipedefindex = gamestate; // wipe_xxx_toblack
        if (gamestate == GS_INTERMISSION)
        {
            if (intertype == int_spec) // Special Stage
                wipedefindex = wipe_specinter_toblack;
            else if (intertype != int_coop) // Multiplayer
                wipedefindex = wipe_multinter_toblack;
        }

        if (rendermode != render_none)
        {
            // Fade to black first
            if (gamestate != GS_LEVEL // fades to black on its own timing, always
                    && wipedefs[wipedefindex] != UINT8_MAX)
            {
                V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
#ifdef HWRENDER
                if(rendermode != render_soft)
                    HWR_PrepFadeToBlack();
#endif
                F_WipeEndScreen();
                F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
            }

            F_WipeStartScreen();
        }
    }

    // do buffered drawing
    switch (gamestate)
    {
    case GS_LEVEL:
        if (!gametic)
            break;
        HU_Erase();
        if (automapactive)
            AM_Drawer();
        if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc)
            redrawsbar = true;
        break;

    case GS_INTERMISSION:
        Y_IntermissionDrawer();
        HU_Erase();
        HU_Drawer();
        break;

    case GS_TIMEATTACK:
        break;

    case GS_INTRO:
        F_IntroDrawer();
        if (wipegamestate == (gamestate_t)-1)
            wipe = true;
        break;

    case GS_CUTSCENE:
        F_CutsceneDrawer();
        HU_Erase();
        HU_Drawer();
        break;

    case GS_GAMEEND:
        F_GameEndDrawer();
        break;

    case GS_EVALUATION:
        F_GameEvaluationDrawer();
        HU_Drawer();
        break;

    case GS_CONTINUING:
        F_ContinueDrawer();
        break;

    case GS_CREDITS:
        F_CreditDrawer();
        HU_Erase();
        HU_Drawer();
        break;

    case GS_TITLESCREEN:
        F_TitleScreenDrawer();
        break;

    case GS_WAITINGPLAYERS:
    // The clientconnect drawer is independent...
    case GS_DEDICATEDSERVER:
    case GS_NULL:
        break;
    }

    // clean up border stuff
    // see if the border needs to be initially drawn
    if (gamestate == GS_LEVEL)
    {
#if 0
        if (oldgamestate != GS_LEVEL)
            R_FillBackScreen(); // draw the pattern into the back screen
#endif

        // draw the view directly
        if (!automapactive && !dedicated && cv_renderview.value)
        {
            if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
            {
                topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
                objectsdrawn = 0;
#ifdef HWRENDER
                if (rendermode != render_soft)
                    HWR_RenderPlayerView(0, &players[displayplayer]);
                else
#endif
                    if (rendermode != render_none)
                        R_RenderPlayerView(&players[displayplayer]);
            }

            // render the second screen
            if (splitscreen && players[secondarydisplayplayer].mo)
            {
#ifdef HWRENDER
                if (rendermode != render_soft)
                    HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
                else
#endif
                    if (rendermode != render_none)
                    {
                        viewwindowy = vid.height / 2;
                        M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));

                        topleft = screens[0] + viewwindowy*vid.width + viewwindowx;

                        R_RenderPlayerView(&players[secondarydisplayplayer]);

                        viewwindowy = 0;
                        M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
                    }
            }

            // Image postprocessing effect
            if (postimgtype)
                V_DoPostProcessor(0, postimgtype, postimgparam);
            if (postimgtype2)
                V_DoPostProcessor(1, postimgtype2, postimgparam2);
        }

        if (lastdraw)
        {
            if (rendermode == render_soft)
                VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
            lastdraw = false;
        }

        ST_Drawer(redrawsbar);

        HU_Drawer();
    }

    // change gamma if needed
    if (gamestate != oldgamestate && gamestate != GS_LEVEL)
        V_SetPalette(0);

    menuactivestate = menuactive;
    oldgamestate = wipegamestate = gamestate;

    // draw pause pic
    if (paused && cv_showhud.value && (!menuactive || netgame))
    {
        INT32 py;
        patch_t *patch;
        if (automapactive)
            py = 4;
        else
            py = viewwindowy + 4;
        patch = W_CachePatchName("M_PAUSE", PU_CACHE);
        V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch);
    }

    // vid size change is now finished if it was on...
    vid.recalc = 0;

    // FIXME: draw either console or menu, not the two
    if (gamestate != GS_TIMEATTACK)
        CON_Drawer();

    M_Drawer(); // menu is drawn even on top of everything
    NetUpdate(); // send out any new accumulation

    // It's safe to end the game now.
    if (G_GetExitGameFlag())
    {
        Command_ExitGame_f();
        G_ClearExitGameFlag();
    }

    //
    // normal update
    //
    if (!wipe)
    {
        if (cv_netstat.value)
        {
            char s[50];
            Net_GetNetStat();

            s[sizeof s - 1] = '\0';

            snprintf(s, sizeof s - 1, "get %d b/s", getbps);
            V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s);
            snprintf(s, sizeof s - 1, "send %d b/s", sendbps);
            V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s);
            snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent);
            V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s);
            snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
            V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
        }

        I_FinishUpdate(); // page flip or blit buffer
        return;
    }

    //
    // wipe update
    //
    wipedefindex += WIPEFINALSHIFT;

    if (rendermode != render_none)
    {
        F_WipeEndScreen();
        F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
    }
}
示例#14
0
static void DrawAndBlit(void)
{
    // Change the view size if needed
    if (setsizeneeded)
    {
        R_ExecuteSetViewSize();
    }

    // Do buffered drawing
    switch (gamestate)
    {
        case GS_LEVEL:
            if (!gametic)
            {
                break;
            }
            if (automapactive)
            {
                AM_Drawer();
            }
            else
            {
                R_RenderPlayerView(&players[displayplayer]);
            }
            CT_Drawer();
            UpdateState |= I_FULLVIEW;
            SB_Drawer();
            break;
        case GS_INTERMISSION:
            IN_Drawer();
            break;
        case GS_FINALE:
            F_Drawer();
            break;
        case GS_DEMOSCREEN:
            PageDrawer();
            break;
    }

    if (testcontrols)
    {
        V_DrawMouseSpeedBox(testcontrols_mousespeed);
    }

    if (paused && !MenuActive && !askforquit)
    {
        if (!netgame)
        {
            V_DrawPatch(160, viewwindowy + 5, W_CacheLumpName("PAUSED",
                                                              PU_CACHE));
        }
        else
        {
            V_DrawPatch(160, 70, W_CacheLumpName("PAUSED", PU_CACHE));
        }
    }

    // Draw current message
    DrawMessage();

    // Draw Menu
    MN_Drawer();

    // Send out any new accumulation
    NetUpdate();

    // Flush buffered stuff to screen
    I_FinishUpdate();
}
示例#15
0
void TryRunTics (void)
{
    int	i;
    int	lowtic;
    int	entertic;
    static int oldentertics;
    int realtics;
    int	availabletics;
    int	counts;

    // get real tics
    entertic = I_GetTime() / ticdup;
    realtics = entertic - oldentertics;
    oldentertics = entertic;

    // in singletics mode, run a single tic every time this function
    // is called.

    if (singletics)
    {
        BuildNewTic();
    }
    else
    {
        NetUpdate ();
    }

    lowtic = GetLowTic();

    availabletics = lowtic - gametic/ticdup;

    // decide how many tics to run

    if (new_sync)
    {
	counts = availabletics;
    }
    else
    {
        // decide how many tics to run
        if (realtics < availabletics-1)
            counts = realtics+1;
        else if (realtics < availabletics)
            counts = realtics;
        else
            counts = availabletics;

        if (counts < 1)
            counts = 1;

        if (net_client_connected)
        {
            OldNetSync();
        }
    }

    if (counts < 1)
	counts = 1;

    // wait for new tics if needed
    while (!PlayersInGame() || lowtic < gametic/ticdup + counts)
    {
	NetUpdate ();

        lowtic = GetLowTic();

	if (lowtic < gametic/ticdup)
	    I_Error ("TryRunTics: lowtic < gametic");

        // Still no tics to run? Sleep until some are available.
        if (lowtic < gametic/ticdup + counts)
        {
            // If we're in a netgame, we might spin forever waiting for
            // new network data to be received. So don't stay in here
            // forever - give the menu a chance to work.
            if (I_GetTime() / ticdup - entertic >= MAX_NETGAME_STALL_TICS)
            {
                return;
            }

            I_Sleep(1);
        }
    }

    // run the count * ticdup dics
    while (counts--)
    {
        ticcmd_set_t *set;

        if (!PlayersInGame())
        {
            return;
        }

        set = &ticdata[(gametic / ticdup) % BACKUPTICS];

        if (!net_client_connected)
        {
            SinglePlayerClear(set);
        }

	for (i=0 ; i<ticdup ; i++)
	{
            if (gametic/ticdup > lowtic)
                I_Error ("gametic>lowtic");

            memcpy(local_playeringame, set->ingame, sizeof(local_playeringame));

            loop_interface->RunTic(set->cmds, set->ingame);
	    gametic++;

	    // modify command for duplicated tics

            TicdupSquash(set);
	}

	NetUpdate ();	// check for new console commands
    }
}
示例#16
0
void D_Display (void)
{
    static  boolean             viewactivestate = false;
    static  boolean             menuactivestate = false;
    static  boolean             inhelpscreensstate = false;
    static  boolean             popupactivestate = false; // [STRIFE]
    static  boolean             fullscreen = false;
    static  gamestate_t         oldgamestate = -1;
    static  int                 borderdrawcount;
    int                         nowtime;
    int                         tics;
    int                         wipestart;
    int                         y;
    boolean                     done;
    boolean                     wipe;
    boolean                     redrawsbar;

    if (nodrawers)
        return;                    // for comparative timing / profiling

    redrawsbar = false;
    
    // change the view size if needed
    if (setsizeneeded)
    {
        R_ExecuteSetViewSize ();
        oldgamestate = -1;                      // force background redraw
        borderdrawcount = 3;
    }

    // save the current screen if about to wipe
    if (gamestate != wipegamestate)
    {
        wipe = true;
        wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
    }
    else
        wipe = false;

    if (gamestate == GS_LEVEL && gametic)
        HU_Erase();

    // do buffered drawing
    switch (gamestate)
    {
    case GS_LEVEL:
        if (!gametic)
            break;
        if (automapactive)
            AM_Drawer ();
        if (wipe || (viewheight != 200 && fullscreen) )
            redrawsbar = true;
        // haleyjd 08/29/10: [STRIFE] Always redraw sbar if menu is/was active
        if (menuactivestate || (inhelpscreensstate && !inhelpscreens))
            redrawsbar = true;              // just put away the help screen
        ST_Drawer (viewheight == 200, redrawsbar );
        fullscreen = viewheight == 200;
        break;
      
     // haleyjd 08/23/2010: [STRIFE] No intermission
     /*
     case GS_INTERMISSION:
         WI_Drawer ();
         break;
     */

    case GS_FINALE:
        F_Drawer ();
        break;

    case GS_DEMOSCREEN:
        D_PageDrawer ();
        break;
    
    default:
        break;
    }
    
    // draw buffered stuff to screen
    I_UpdateNoBlit ();

    // draw the view directly
    if (gamestate == GS_LEVEL && !automapactive && gametic)
        R_RenderPlayerView (&players[displayplayer]);

    // clean up border stuff
    if (gamestate != oldgamestate && gamestate != GS_LEVEL)
        I_SetPalette (W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE));

    // see if the border needs to be initially drawn
    if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL)
    {
        viewactivestate = false;        // view was not active
        R_FillBackScreen ();    // draw the pattern into the back screen
    }

    // see if the border needs to be updated to the screen
    if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320)
    {
        if (menuactive || menuactivestate || !viewactivestate)
        {
            borderdrawcount = 3;
            popupactivestate = false;
        }
        if (borderdrawcount)
        {
            R_DrawViewBorder ();    // erase old menu stuff
            borderdrawcount--;
        }

    }

    if (testcontrols)
    {
        // Box showing current mouse speed

        V_DrawMouseSpeedBox(testcontrols_mousespeed);
    }

    menuactivestate = menuactive;
    viewactivestate = viewactive;
    inhelpscreensstate = inhelpscreens;
    oldgamestate = wipegamestate = gamestate;

    // haleyjd 20120208: [STRIFE] Rogue moved this down to below border drawing
    if (gamestate == GS_LEVEL && gametic)
    {
        HU_Drawer ();
        if(ST_DrawExternal()) 
            popupactivestate = true;
        else if(popupactivestate)
        {
            popupactivestate = false;
            menuactivestate = 1;
        }
    }

    // draw pause pic
    if (paused)
    {
        if (automapactive)
            y = 4;
        else
            y = viewwindowy+4;
        V_DrawPatchDirect(viewwindowx + (scaledviewwidth - 68) / 2, y,
                          W_CacheLumpName (DEH_String("M_PAUSE"), PU_CACHE));
    }


    // menus go directly to the screen
    M_Drawer ();          // menu is drawn even on top of everything
    NetUpdate ();         // send out any new accumulation


    // normal update
    if (!wipe)
    {
        I_FinishUpdate ();              // page flip or blit buffer
        return;
    }
    
    // wipe update
    wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);

    wipestart = I_GetTime () - 1;

    do
    {
        do
        {
            nowtime = I_GetTime ();
            tics = nowtime - wipestart;
            I_Sleep(1);
        } while (tics < 3); // haleyjd 08/23/2010: [STRIFE] Changed from == 0 to < 3

        // haleyjd 08/26/10: [STRIFE] Changed to use ColorXForm wipe.
        wipestart = nowtime;
        done = wipe_ScreenWipe(wipe_ColorXForm
                               , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics);
        I_UpdateNoBlit ();
        M_Drawer ();                            // menu is drawn even on top of wipes
        I_FinishUpdate ();                      // page flip or blit buffer
    } while (!done);
}
示例#17
0
void TryRunTics(void)
{
    int         i;
    int         entertic;
    static int  oldentertics;
    int         realtics;
    int         availabletics;
    int         counts;

    // get real tics
    entertic = I_GetTime() / ticdup;
    realtics = entertic - oldentertics;
    oldentertics = entertic;

    // get available tics
    NetUpdate();

    availabletics = maketic - gametic / ticdup;

    // decide how many tics to run
    if (realtics < availabletics - 1)
        counts = realtics + 1;
    else if (realtics < availabletics)
        counts = realtics;
    else
        counts = availabletics;

    if (!counts && !vid_capfps)
        return;

    if (counts < 1)
        counts = 1;

    // wait for new tics if needed
    while (maketic < gametic / ticdup + counts)
    {
        NetUpdate();

        // Still no tics to run? Sleep until some are available.
        if (maketic < gametic/ticdup + counts)
        {
            // If we're in a netgame, we might spin forever waiting for
            // new network data to be received. So don't stay in here
            // forever - give the menu a chance to work.
            if (I_GetTime() / ticdup - entertic >= MAX_NETGAME_STALL_TICS)
                return;

            I_Sleep(1);
        }
    }

    // run the count * ticdup dics
    while (counts--)
    {
        for (i = 0; i < ticdup; i++)
        {
            if (advancetitle)
                D_DoAdvanceTitle();

            G_Ticker();
            gametic++;
            gametime++;

            // modify command for duplicated tics
            if (i != ticdup - 1)
            {
                ticcmd_t    *cmd = &netcmds[(gametic / ticdup) % BACKUPTICS];

                if (cmd->buttons & BT_SPECIAL)
                    cmd->buttons = 0;
            }
        }
        NetUpdate();
    }
}
示例#18
0
void TryRunTics(void)
{
    int i;
    int lowtic;
    int entertic;
    static int oldentertics;
    int realtics;
    int availabletics;
    int counts;

    // get real tics
    entertic = I_GetTime() / ticdup;
    realtics = entertic - oldentertics;
    oldentertics = entertic;

    // get available tics
    NetUpdate();

    lowtic = GetLowTic();

    availabletics = lowtic - gametic / ticdup;

    // decide how many tics to run

    if (net_cl_new_sync)
    {
        counts = availabletics;
    }
    else
    {
        // decide how many tics to run
        if (realtics < availabletics - 1)
            counts = realtics + 1;
        else if (realtics < availabletics)
            counts = realtics;
        else
            counts = availabletics;

        if (counts < 1)
            counts = 1;

        frameon++;

        if (!demoplayback)
        {
            int keyplayer = -1;

            // ideally maketic should be 1 - 3 tics above lowtic
            // if we are consistantly slower, speed up time

            for (i = 0; i < MAXPLAYERS; i++)
            {
                if (playeringame[i])
                {
                    keyplayer = i;
                    break;
                }
            }

            if (keyplayer < 0)
            {
                // If there are no players, we can never advance anyway

                return;
            }

            if (consoleplayer == keyplayer)
            {
                // the key player does not adapt
            }
            else
            {
                if (maketic <= nettics[keyplayer])
                {
                    lasttime--;
                }

                frameskip[frameon & 3] = (oldnettics > nettics[keyplayer]);
                oldnettics = maketic;

                if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
                {
                    skiptics = 1;
                }
            }
        }
    }

    if (counts < 1)
        counts = 1;

    // wait for new tics if needed

    while (!PlayersInGame() || lowtic < gametic / ticdup + counts)
    {
        NetUpdate();

        lowtic = GetLowTic();

        // Don't stay in this loop forever.  The menu is still running,
        // so return to update the screen

        if (I_GetTime() / ticdup - entertic > 0)
        {
            return;
        }

        I_Sleep(1);
    }

    // run the count * ticdup dics
    while (counts--)
    {
        for (i = 0; i < ticdup; i++)
        {
            // check that there are players in the game.  if not, we cannot
            // run a tic.

            if (!PlayersInGame())
            {
                return;
            }

            if (advancedemo)
                D_DoAdvanceDemo();

            G_Ticker();
            gametic++;

            // modify command for duplicated tics
            if (i != ticdup - 1)
            {
                ticcmd_t        *cmd;
                int             buf;
                int             j;

                buf = (gametic / ticdup) % BACKUPTICS;
                for (j = 0; j < MAXPLAYERS; j++)
                {
                    cmd = &netcmds[j][buf];
                    if (cmd->buttons & BT_SPECIAL)
                        cmd->buttons = 0;
                }
            }
        }
        NetUpdate();   // check for new console commands
    }
}
示例#19
0
文件: d_client.c 项目: DrBeef/DVR
void TryRunTics ()
{
  int runtics;
  int entertime = I_GetTime();

  // Wait for tics to run
  while (1) {
#ifdef HAVE_NET
    NetUpdate();
#else

    D_BuildNewTiccmds();

#endif
    runtics = (server ? remotetic : maketic) - gametic;

    if (!runtics) {
      if (!movement_smooth) {
#ifdef HAVE_NET
        if (server)
          I_WaitForPacket(ms_to_next_tick);
        else
#endif
          I_uSleep(ms_to_next_tick*1000);
      }

      if (I_GetTime() - entertime > 10) {
#ifdef HAVE_NET
        if (server) {
          char buf[sizeof(packet_header_t)+1];
          remotesend--;
          packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic);
          buf[sizeof(buf)-1] = consoleplayer;
          I_SendPacket((packet_header_t *)buf, sizeof buf);
        }
#endif

        M_Ticker(); return;
      }
      //if ((displaytime) < (tic_vars.next-SDL_GetTicks()))
      {
        WasRenderedInTryRunTics = true;
        if (V_GetMode() == VID_MODEGL ? 
            movement_smooth : 
            movement_smooth && gamestate==wipegamestate)
        {
          isExtraDDisplay = true;
          D_Display(0);
          D_Display(1);
          isExtraDDisplay = false;
        }
      }
    } else break;
  }

  while (runtics--) {
#ifdef HAVE_NET
    if (server) CheckQueuedPackets();
#endif


    if (advancedemo)
      D_DoAdvanceDemo ();


    M_Ticker ();
    I_GetTime_SaveMS();
    G_Ticker ();
    P_Checksum(gametic);
    gametic++;
#ifdef HAVE_NET
    NetUpdate(); // Keep sending our tics to avoid stalling remote nodes
#endif
  }
}
示例#20
0
//
// R_RenderView
//
void R_RenderPlayerView (player_t* player)
{       
  R_SetupFrame (player);

  // Clear buffers.
  R_ClearClipSegs ();
  R_ClearDrawSegs ();
  R_ClearPlanes ();
  R_ClearSprites ();
    
  rendered_segs = rendered_visplanes = 0;
  if (autodetect_hom)
    { // killough 2/10/98: add flashing red HOM indicators
      char c[47*47];
      extern int lastshottic;
      int i,color=(gametic % 20) < 9 ? 0xb0 : 0;
      memset(*screens+viewwindowy*SCREENWIDTH,color,viewheight*SCREENWIDTH);
      for (i=0;i<47*47;i++)
        {
          char t =
"/////////////////////////////////////////////////////////////////////////////"
"/////////////////////////////////////////////////////////////////////////////"
"///////jkkkkklk////////////////////////////////////hkllklklkklkj/////////////"
"///////////////////jkkkkklklklkkkll//////////////////////////////kkkkkklklklk"
"lkkkklk//////////////////////////jllkkkkklklklklklkkklk//////////////////////"
"//klkkllklklklkllklklkkklh//////////////////////kkkkkjkjjkkj\3\205\214\3lllkk"
"lkllh////////////////////kllkige\211\210\207\206\205\204\203\203\203\205`\206"
"\234\234\234\234kkllg//////////////////klkkjhfe\210\206\203\203\203\202\202"
"\202\202\202\202\203\205`\207\211eikkk//////////////////kkkk\3g\211\207\206"
"\204\203\202\201\201\200\200\200\200\200\201\201\202\204b\210\211\3lkh///////"
"//////////lklki\213\210b\206\203\201\201\200\200\200\200\200Z\200\200\200\202"
"\203\204\205\210\211jll/////////////////lkkk\3\212\210b\205\202\201\200\200"
"\200XW\200\200\200\200\200\200\202\203\204\206\207eklj////////////////lkkjg"
"\211b\206\204\202\200\200\200YWWX\200Z\200\200\200\202\203\203\205bdjkk//////"
"//////////llkig\211a\205\203\202\200\200\200YXWX\200\200\200\200\200\201\202"
"\203\203\206\207ekk////////////////lkki\3\211\206\204\202\201\200\200XXWWWXX"
"\200\200\200\200\202\202\204\206\207ekk////////////////lkkj\3e\206\206\204\\"
"\200\200XWVVWWWXX\200\200\200\\\203\205\207\231kk////////////////lkkjjgcccfd"
"\207\203WVUVW\200\200\202\202\204\204\205\204\206\210gkk////////////////kkkkj"
"e``\210hjjgb\200W\200\205\206fhghcbdcdfkk////////////////jkkj\3\207ab\211e"
"\213j\3g\204XX\207\213jii\212\207\203\204\210gfkj///////////////j\211lkjf\210"
"\214\3\3kj\213\213\211\205X\200\205\212\210\213\213\213\211\210\203\205gelj//"
"////////////hf\211\213kh\212\212i\212gkh\202\203\210\210\202\201\206\207\206"
"\\kkhf\210aabkk//////////////je\210\210\3g\210\207\210e\210c\205\204\202\210"
"\207\203\202\210\205\203\203fjbe\213\210bbieW/////////////ke\207\206ie\206"
"\203\203\203\205\205\204\203\210\211\207\202\202\206\210\203\204\206\207\210"
"\211\231\206\206`\206\206]/////////////kf\\\202ig\204\203\202\201\\\202\202"
"\205\207\210\207\203\202\206\206\206\205\203\203\203\202\202\203\204b\206\204"
"Z/////////////i\3\\\204j\212\204\202\201\200\202\202\202\203\206\211\210\203"
"\203c\205\202\201\201\201\200\200\201\202\204a\204\201W/////////////j\3\207"
"\210jh\206\202\200\200\200\200\200\202\206\211\205\202\202bb\201\200\200\200"
"\200\200\200\202\203b\\WW/////////////jke\206jic\203\201\200\200\200\200\202"
"\211\211\201\200\200\204\210\201\200\200W\200\200\200\201\204c\\\200]////////"
"//////kd\210\3\3e\205\202\200\200W\200\202\211\210\210\201\202\207\210\203"
"\200WWW\200\200\202\205d\\\202///////////////kkdhigb\203\201\200\200\200\202"
"\206\210\210\205\210\211\206\203\200WWW\200\201\203ce\203\205////////////////"
"ijkig\211\203\201\200\200\202\206\207\207\205\206\207\210\206\203\200\200WW"
"\200\203\206ce\202_//////////////////jig\210\203\202\200\201\206\210\210\205"
"\204\204\205\206\206\204\202\200\200\200\200\203bcd////////////////////hjgc"
"\205\202\201\203\206\210\206\204\204\202\202\204\205\206\204\200\200\200\201"
"\206\207c//////////////////////j\3\207\204\203\202\202\211c\204\201W\200\200"
"\203\205\206\203\200\200\200\203\206b///////////////////////ihd\204\203\202"
"\201\207f\205VTVTW\202\210\206Z\200\200\203aa////////////////////////jg\204"
"\204\203\201\202\210\211\211c\206\205\210d\210\200\200\200\202\204ac/////////"
"///////////////j\3b\203\203\202\202\205\207\206\205\207\207\206\206\202\200"
"\201\202\203ac/////////////////////////iid\206\204\203\202\204\205\377\205"
"\204\205\204\203\201\200\202\203\203bc//////////////////////////ej\207\205"
"\203\201\202\202\203\207\204\203\202\202\201\201\203\203bd///////////////////"
"////////ee\3a\204\201\200\201\202\205\203\201\200\200\201\202\204\205cc//////"
"//////////////////////c\3ec\203\201\200\200\201\202\201\200\200\202\203\206cc"
"//////////////////////////////c\3f\206\203\201\200\200\200\200\200\201\203bdc"
"////////////////////////////////g\3\211\206\202\\\201\200\201\202\203dde/////"
"/////////////////////////////\234\3db\203\203\203\203adec////////////////////"
"/////////////////hffed\211de////////////////////"[i];
          c[i] = t=='/' ? color : t;
        }
      if (gametic-lastshottic < TICRATE*2 && gametic-lastshottic > TICRATE/8)
        V_DrawBlock(viewwindowx +  viewwidth/2 - 24,
                    viewwindowy + viewheight/2 - 24, 0, 47, 47, c, VPT_NONE);
      R_DrawViewBorder();
    }

  // check for new console commands.
  NetUpdate ();

  // The head node is the last node output.
  R_RenderBSPNode (numnodes-1);
    
  // Check for new console commands.
  NetUpdate ();
    
  R_DrawPlanes ();
    
  // Check for new console commands.
  NetUpdate ();
    
  R_DrawMasked ();

  // Check for new console commands.
  NetUpdate ();

  if (rendering_stats) R_ShowStats();
}
示例#21
0
文件: d_main.c 项目: jm--/seL4Doom
void D_Display (void)
{
    static  boolean		viewactivestate = false;
    static  boolean		menuactivestate = false;
    static  boolean		inhelpscreensstate = false;
    static  boolean		fullscreen = false;
    static  gamestate_t		oldgamestate = -1;
    static  int			borderdrawcount;
    int				nowtime;
    int				tics;
    int				wipestart;
    int				y;
    boolean			done;
    boolean			wipe;
    boolean			redrawsbar;

    if (nodrawers)
	return;                    // for comparative timing / profiling
		
    redrawsbar = false;
    
    // change the view size if needed
    if (setsizeneeded)
    {
	R_ExecuteSetViewSize ();
	oldgamestate = -1;                      // force background redraw
	borderdrawcount = 3;
    }

    // save the current screen if about to wipe
    if (gamestate != wipegamestate)
    {
	wipe = true;
	wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
    }
    else
	wipe = false;

    if (gamestate == GS_LEVEL && gametic)
	HU_Erase();
    
    // do buffered drawing
    switch (gamestate)
    {
      case GS_LEVEL:
	if (!gametic)
	    break;
	if (automapactive)
	    AM_Drawer ();
	if (wipe || (viewheight != 200 && fullscreen) )
	    redrawsbar = true;
	if (inhelpscreensstate && !inhelpscreens)
	    redrawsbar = true;              // just put away the help screen
	ST_Drawer (viewheight == 200, redrawsbar );
	fullscreen = viewheight == 200;
	break;

      case GS_INTERMISSION:
	WI_Drawer ();
	break;

      case GS_FINALE:
	F_Drawer ();
	break;

      case GS_DEMOSCREEN:
	D_PageDrawer ();
	break;
    }
    
    // draw buffered stuff to screen
    I_UpdateNoBlit ();
    
    // draw the view directly
    if (gamestate == GS_LEVEL && !automapactive && gametic)
	R_RenderPlayerView (&players[displayplayer]);

    if (gamestate == GS_LEVEL && gametic)
	HU_Drawer ();
    
    // clean up border stuff
    if (gamestate != oldgamestate && gamestate != GS_LEVEL)
	I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE));

    // see if the border needs to be initially drawn
    if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL)
    {
	viewactivestate = false;        // view was not active
	R_FillBackScreen ();    // draw the pattern into the back screen
    }

    // see if the border needs to be updated to the screen
    if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320)
    {
	if (menuactive || menuactivestate || !viewactivestate)
	    borderdrawcount = 3;
	if (borderdrawcount)
	{
	    R_DrawViewBorder ();    // erase old menu stuff
	    borderdrawcount--;
	}

    }

    menuactivestate = menuactive;
    viewactivestate = viewactive;
    inhelpscreensstate = inhelpscreens;
    oldgamestate = wipegamestate = gamestate;
    
    // draw pause pic
    if (paused)
    {
	if (automapactive)
	    y = 4;
	else
	    y = viewwindowy+4;
	V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2,
			  y,0,W_CacheLumpName ("M_PAUSE", PU_CACHE));
    }


    // menus go directly to the screen
    M_Drawer ();          // menu is drawn even on top of everything
    NetUpdate ();         // send out any new accumulation


    // normal update
    if (!wipe)
    {
	I_FinishUpdate ();              // page flip or blit buffer
	return;
    }
    
    // wipe update
    wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);

    wipestart = I_GetTime () - 1;

    do
    {
	do
	{
	    nowtime = I_GetTime ();
	    tics = nowtime - wipestart;
	} while (!tics);
	wipestart = nowtime;
	done = wipe_ScreenWipe(wipe_Melt
			       , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics);
	I_UpdateNoBlit ();
	M_Drawer ();                            // menu is drawn even on top of wipes
	I_FinishUpdate ();                      // page flip or blit buffer
    } while (!done);
}
示例#22
0
void D_Display (void)
{
  boolean wipe, viewactive, isborder;
  static boolean isborderstate        = FALSE;
  static boolean borderwillneedredraw = FALSE;
  static gamestate_t oldgamestate = -1;

  // Reentrancy.
  if (in_d_wipe)
  {
     D_Wipe();
     return;
  }

  if (!I_StartDisplay())
    return;

  // save the current screen if about to wipe
  if ((wipe = gamestate != wipegamestate))
    wipe_StartScreen();

  if (gamestate != GS_LEVEL) { // Not a level
    switch (oldgamestate) {
    case -1:
    case GS_LEVEL:
      V_SetPalette(0); // cph - use default (basic) palette
    default:
      break;
    }

    switch (gamestate) {
    case GS_INTERMISSION:
      WI_Drawer();
      break;
    case GS_FINALE:
      F_Drawer();
      break;
    case GS_DEMOSCREEN:
      D_PageDrawer();
      break;
    default:
      break;
    }
  } else if (gametic != basetic) { // In a level
    boolean redrawborderstuff;

    HU_Erase();

    if (setsizeneeded) {               // change the view size if needed
      R_ExecuteSetViewSize();
      oldgamestate = -1;            // force background redraw
    }

    // Work out if the player view is visible, and if there is a border
    viewactive = (!(automapmode & am_active) || (automapmode & am_overlay)) && !inhelpscreens;
    isborder = viewactive ? (viewheight != SCREENHEIGHT) : (!inhelpscreens && (automapmode & am_active));

    if (oldgamestate != GS_LEVEL) {
      redrawborderstuff = isborder;
    } else {
      // CPhipps -
      // If there is a border, and either there was no border last time,
      // or the border might need refreshing, then redraw it.
      redrawborderstuff = isborder && (!isborderstate || borderwillneedredraw);
      // The border may need redrawing next time if the border surrounds the screen,
      // and there is a menu being displayed
      borderwillneedredraw = viewactive
        ? (menuactive && isborder)
        : (!inhelpscreens && menuactive == mnact_full);
    }

    // Now do the drawing
    if (viewactive)
      R_RenderPlayerView (&players[displayplayer]);
    if (automapmode & am_active)
      AM_Drawer();
    ST_Drawer(
        ((viewheight != SCREENHEIGHT)
         || ((automapmode & am_active) && !(automapmode & am_overlay))),
        redrawborderstuff,
        (menuactive == mnact_full));
    HU_Drawer();
  }

  isborderstate      = isborder;
  oldgamestate = wipegamestate = gamestate;

  // draw pause pic
  if (paused && (menuactive != mnact_full)) {
    // Simplified the "logic" here and no need for x-coord caching - POPE
    V_DrawNamePatch((320 - V_NamePatchWidth("M_PAUSE"))/2, 4,
                    0, "M_PAUSE", CR_DEFAULT, VPT_NONE);
  }

  // menus go directly to the screen
  M_Drawer();          // menu is drawn even on top of everything
#ifdef HAVE_NET
  NetUpdate();         // send out any new accumulation
#else
  D_BuildNewTiccmds();
#endif

  // normal update
  if (!wipe)
    I_FinishUpdate ();              // page flip or blit buffer
  else {
    // wipe update
    wipe_EndScreen();
    D_Wipe();
  }

  I_EndDisplay();
}