示例#1
0
void BuildPalmap( void ){
#ifdef TABLECOLORS
	int r, g, b;
	int bestcolor;

	if ( palmap_built ) {
		return;
	}
	palmap_built = qtrue;

	for ( r = 4 ; r < 256 ; r += 8 )
	{
		for ( g = 4 ; g < 256 ; g += 8 )
		{
			for ( b = 4 ; b < 256 ; b += 8 )
			{
				bestcolor = BestColor( r, g, b, 1, 254 );
				palmap[r >> 3][g >> 3][b >> 3] = bestcolor;
			}
		}
	}
#endif

	if ( !colormap_issued ) {
		Error( "You must issue a $colormap command first" );
	}

}
示例#2
0
BYTE FColorMatcher::Pick (int r, int g, int b)
{
	if (Pal == NULL)
		return 1;

	return (BYTE)BestColor ((uint32 *)Pal, r, g, b);
}
示例#3
0
/*
   =============
   FindColor
   =============
 */
int FindColor( int r, int g, int b ){
	int bestcolor;

	if ( r > 255 ) {
		r = 255;
	}
	if ( r < 0 ) {
		r = 0;
	}
	if ( g > 255 ) {
		g = 255;
	}
	if ( g < 0 ) {
		g = 0;
	}
	if ( b > 255 ) {
		b = 255;
	}
	if ( b < 0 ) {
		b = 0;
	}
#ifndef TABLECOLORS
	bestcolor = BestColor( r, g, b, 0, 254 );
#else
	bestcolor = palmap[r >> 3][g >> 3][b >> 3];
#endif

	return bestcolor;
}
示例#4
0
// Draw a list of player colors on a team.  Lines up with player names.
void EATeamPlayerColors(int x, int y,
                        const unsigned short w, const unsigned short h,
                        const float scale,
                        const x_align_t x_align, const y_align_t y_align,
                        const x_align_t x_origin, const y_align_t y_origin,
                        const short padding, const short limit,
                        const byte team) {
	byte drawn = 0;
	for (size_t i = 0;i < sortedPlayers().size();i++) {
		// Make sure we're not overrunning our limit.
		if (limit != 0 && drawn >= limit) {
			break;
		}

		player_t* player = sortedPlayers()[i];
		if (inTeamPlayer(player, team)) {
			int playercolor = CL_GetPlayerColor(player);
			int color = BestColor(GetDefaultPalette()->basecolors,
			                      RPART(playercolor),
			                      GPART(playercolor),
			                      BPART(playercolor),
			                      GetDefaultPalette()->numcolors);

			hud::Clear(x, y, w, h, scale, x_align, y_align, x_origin, y_origin, color);
			y += h + padding;
			drawn += 1;
		}
	}
}
示例#5
0
	void RenderPortal::RenderLinePortalHighlight(PortalDrawseg* pds)
	{
		// [ZZ] NO OVERFLOW CHECKS HERE
		//      I believe it won't break. if it does, blame me. :(

		auto viewport = Thread->Viewport.get();

		if (viewport->RenderTarget->IsBgra()) // Assuming this is just a debug function
			return;

		uint8_t color = (uint8_t)BestColor((uint32_t *)GPalette.BaseColors, 255, 0, 0, 0, 255);

		uint8_t* pixels = viewport->RenderTarget->GetBuffer();
		// top edge
		for (int x = pds->x1; x < pds->x2; x++)
		{
			if (x < 0 || x >= viewport->RenderTarget->GetWidth())
				continue;

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

			if (x == pds->x1 || x == pds->x2 - 1)
			{
				viewport->RenderTarget->DrawLine(x, Ytop, x, Ybottom + 1, color, 0);
				continue;
			}

			int YtopPrev = pds->ceilingclip[p - 1];
			int YbottomPrev = pds->floorclip[p - 1];

			if (abs(Ytop - YtopPrev) > 1)
				viewport->RenderTarget->DrawLine(x, YtopPrev, x, Ytop, color, 0);
			else *(pixels + Ytop * viewport->RenderTarget->GetPitch() + x) = color;

			if (abs(Ybottom - YbottomPrev) > 1)
				viewport->RenderTarget->DrawLine(x, YbottomPrev, x, Ybottom, color, 0);
			else *(pixels + Ybottom * viewport->RenderTarget->GetPitch() + x) = color;
		}
	}
示例#6
0
byte FColorMatcher::Pick (int r, int g, int b)
{
	if (Pal == NULL)
		return 0;

#ifdef BEFAST
	byte bestcolor;
	int bestdist;

	byte color = FirstColor[(r+CLOSIZE/2)>>CLOBITS][(g+CLOSIZE/2)>>CLOBITS][(b+CLOSIZE/2)>>CLOBITS];
	if (NextColor[color] == 0)
		return color;

	bestcolor = 0;
	bestdist = 257*257+257*257+257*257;

	do
	{
		int dist = (r-Pal[color].r)*(r-Pal[color].r)+
				   (g-Pal[color].g)*(g-Pal[color].g)+
				   (b-Pal[color].b)*(b-Pal[color].b);
		if (dist < bestdist)
		{
			if (dist == 0)
				return color;

			bestdist = dist;
			bestcolor = color;
		}
		color = NextColor[color];
	} while (color != 0);
	return bestcolor;
#else
	return BestColor ((DWORD *)Pal, r, g, b);
#endif
}
示例#7
0
/*
   ==============
   Cmd_Colormap

   $colormap filename

   the brightes colormap is first in the table (FIXME: reverse this now?)

   64 rows of 256 : lightmaps
   256 rows of 256 : translucency table
   ==============
 */
void Cmd_Colormap( void ){
	int levels, brights;
	int l, c;
	float frac, red, green, blue;
	float range;
	byte    *cropped, *lump_p;
	char savename[1024];
	char dest[1024];

	colormap_issued = qtrue;
	if ( !g_release ) {
		memcpy( colormap_palette, lbmpalette, 768 );
	}

	if ( !TokenAvailable() ) { // just setting colormap_issued
		return;
	}

	GetToken( qfalse );
	sprintf( savename, "%spics/%s.pcx", writedir, token );

	if ( g_release ) {
		sprintf( dest, "pics/%s.pcx", token );
		ReleaseFile( dest );
		return;
	}

	range = 2;
	levels = 64;
	brights = 1;    // ignore 255 (transparent)

	cropped = malloc( ( levels + 256 ) * 256 );
	lump_p = cropped;

// shaded levels
	for ( l = 0; l < levels; l++ )
	{
		frac = range - range * (float)l / ( levels - 1 );
		for ( c = 0 ; c < 256 - brights ; c++ )
		{
			red = lbmpalette[c * 3];
			green = lbmpalette[c * 3 + 1];
			blue = lbmpalette[c * 3 + 2];

			red = (int)( red * frac + 0.5 );
			green = (int)( green * frac + 0.5 );
			blue = (int)( blue * frac + 0.5 );

//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
// don't use color 0, because NT can't remap that (or 255)
//
			*lump_p++ = BestColor( red,green,blue, 1, 254 );
		}

		// fullbrights allways stay the same
		for ( ; c < 256 ; c++ )
			*lump_p++ = c;
	}

// 66% transparancy table
	for ( l = 0; l < 255; l++ )
	{
		for ( c = 0 ; c < 255 ; c++ )
		{
			red = lbmpalette[c * 3] * 0.33 + lbmpalette[l * 3] * 0.66;
			green = lbmpalette[c * 3 + 1] * 0.33 + lbmpalette[l * 3 + 1] * 0.66;
			blue = lbmpalette[c * 3 + 2] * 0.33 + lbmpalette[l * 3 + 2] * 0.66;

			*lump_p++ = BestColor( red,green,blue, 1, 254 );
		}
		*lump_p++ = 255;
	}
	for ( c = 0 ; c < 256 ; c++ )
		*lump_p++ = 255;

	// save off the new image
	printf( "saving %s\n", savename );
	CreatePath( savename );
	WritePCXfile( savename, cropped, 256, levels + 256, lbmpalette );

	free( cropped );
}
示例#8
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];
	}