コード例 #1
0
ファイル: i_system.cpp プロジェクト: vihtinsky/gzdoom
bool I_SetCursor(FTexture *cursorpic)
{
	if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
	{
		// Must be no larger than 32x32.
		if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
		{
			return false;
		}

#ifdef USE_XCURSOR
		if (UseXCursor)
		{
			if (FirstCursor == NULL)
			{
				FirstCursor = SDL_GetCursor();
			}
			X11Cursor = CreateColorCursor(cursorpic);
			if (X11Cursor != NULL)
			{
				SDL_SetCursor(X11Cursor);
				return true;
			}
		}
#endif
		if (cursorSurface == NULL)
			cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));

		SDL_ShowCursor(0);
		SDL_LockSurface(cursorSurface);
		BYTE buffer[32*32*4];
		memset(buffer, 0, 32*32*4);
		FBitmap bmp(buffer, 32*4, 32, 32);
		cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
		memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
		SDL_UnlockSurface(cursorSurface);
	}
	else
	{
		SDL_ShowCursor(1);

		if (cursorSurface != NULL)
		{
			SDL_FreeSurface(cursorSurface);
			cursorSurface = NULL;
		}
#ifdef USE_XCURSOR
		if (X11Cursor != NULL)
		{
			SDL_SetCursor(FirstCursor);
			SDL_FreeCursor(X11Cursor);
			X11Cursor = NULL;
		}
#endif
	}
	return true;
}
コード例 #2
0
ファイル: intermission.cpp プロジェクト: ChillyDoom/zdoom
void DIntermissionScreenFader::Drawer ()
{
	if (!mFlatfill && mBackground.isValid())
	{
		double factor = clamp(double(mTicker) / mDuration, 0., 1.);
		if (mType == FADE_In) factor = 1.0 - factor;
		int color = MAKEARGB(xs_RoundToInt(factor*255), 0,0,0);

		if (screen->Begin2D(false))
		{
			screen->DrawTexture (TexMan[mBackground], 0, 0, DTA_Fullscreen, true, DTA_ColorOverlay, color, TAG_DONE);
			for (unsigned i=0; i < mOverlays.Size(); i++)
			{
				if (CheckOverlay(i))
					screen->DrawTexture (TexMan[mOverlays[i].mPic], mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, DTA_ColorOverlay, color, TAG_DONE);
			}
			screen->FillBorder (NULL);
		}
		else
		{
			V_SetBlend (0,0,0,int(256*factor));
			Super::Drawer();
		}
	}
}
コード例 #3
0
ファイル: i_gui.cpp プロジェクト: Blzut3/gzdoom
bool I_SetCursor(FTexture *cursorpic)
{
	static SDL_Cursor *cursor;
	static SDL_Surface *cursorSurface;

	if (cursorpic != NULL && cursorpic->UseType != ETextureType::Null)
	{
		// Must be no larger than 32x32.
		if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
		{
			return false;
		}

		if (cursorSurface == NULL)
			cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));

		SDL_LockSurface(cursorSurface);
		uint8_t buffer[32*32*4];
		memset(buffer, 0, 32*32*4);
		FBitmap bmp(buffer, 32*4, 32, 32);
		cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
		memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
		SDL_UnlockSurface(cursorSurface);

		if (cursor)
			SDL_FreeCursor (cursor);
		cursor = SDL_CreateColorCursor (cursorSurface, 0, 0);
		SDL_SetCursor (cursor);
	}
	else
	{
		if (cursor)
		{
			SDL_SetCursor (NULL);
			SDL_FreeCursor (cursor);
			cursor = NULL;
		}
		if (cursorSurface != NULL)
		{
			SDL_FreeSurface(cursorSurface);
			cursorSurface = NULL;
		}
	}
	return true;
}
コード例 #4
0
ファイル: r_data.cpp プロジェクト: JohnnyonFlame/odamex
//
// R_InitColormaps
//
void R_InitColormaps (void)
{
	// [RH] Try and convert BOOM colormaps into blending values.
	//		This is a really rough hack, but it's better than
	//		not doing anything with them at all (right?)
	int lastfakecmap = W_CheckNumForName ("C_END");
	firstfakecmap = W_CheckNumForName ("C_START");

	if (firstfakecmap == -1 || lastfakecmap == -1)
		numfakecmaps = 1;
	else
	{
		if(firstfakecmap > lastfakecmap)
			I_Error("no fake cmaps");

		numfakecmaps = lastfakecmap - firstfakecmap;
	}
	
	realcolormaps = (byte *)Z_Malloc (256*(NUMCOLORMAPS+1)*numfakecmaps+255,PU_STATIC,0);
	realcolormaps = (byte *)(((ptrdiff_t)realcolormaps + 255) & ~255);
	fakecmaps = (FakeCmap *)Z_Malloc (sizeof(*fakecmaps) * numfakecmaps, PU_STATIC, 0);

	fakecmaps[0].name[0] = 0;
	R_SetDefaultColormap ("COLORMAP");

	if (numfakecmaps > 1)
	{
		int i;
		size_t j;
		palette_t *pal = GetDefaultPalette ();

		for (i = ++firstfakecmap, j = 1; j < numfakecmaps; i++, j++)
		{
			if (W_LumpLength (i) >= (NUMCOLORMAPS+1)*256)
			{
				int k, r, g, b;
				byte *map = (byte *)W_CacheLumpNum (i, PU_CACHE);

				memcpy (realcolormaps+(NUMCOLORMAPS+1)*256*j,
						map, (NUMCOLORMAPS+1)*256);

				if(pal->basecolors)
				{
					r = RPART(pal->basecolors[*map]);
					g = GPART(pal->basecolors[*map]);
					b = BPART(pal->basecolors[*map]);
	
					W_GetLumpName (fakecmaps[j].name, i);
					for (k = 1; k < 256; k++) {
						r = (r + RPART(pal->basecolors[map[k]])) >> 1;
						g = (g + GPART(pal->basecolors[map[k]])) >> 1;
						b = (b + BPART(pal->basecolors[map[k]])) >> 1;
					}
					fakecmaps[j].blend = MAKEARGB (255, r, g, b);
				}
			}
コード例 #5
0
void FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed)
{
	const char *label = mLabel;
	if (*label == '$') label = GStrings(label+1);

	int overlay = grayed? MAKEARGB(96,48,0,0) : 0;

	int x;
	int w = SmallFont->StringWidth(label) * CleanXfac_1;
	if (!mCentered) x = indent - w;
	else x = (screen->GetWidth() - w) / 2;
	screen->DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
}
コード例 #6
0
ファイル: v_draw.cpp プロジェクト: DaZombieKiller/lxDoom
static int PalFromRGB(uint32 rgb)
{
	if (LastPal >= 0 && LastRGB == rgb)
	{
		return LastPal;
	}
	// Quick check for black and white.
	if (rgb == MAKEARGB(255,0,0,0))
	{
		LastPal = GPalette.BlackIndex;
	}
	else if (rgb == MAKEARGB(255,255,255,255))
	{
		LastPal = GPalette.WhiteIndex;
	}
	else
	{
		LastPal = ColorMatcher.Pick(RPART(rgb), GPART(rgb), BPART(rgb));
	}
	LastRGB = rgb;
	return LastPal;
}
コード例 #7
0
ファイル: colormaps.cpp プロジェクト: ArcticPheenix/gzdoom
uint32_t R_ColormapNumForName (const char *name)
{
	if (strnicmp (name, "COLORMAP", 8))
	{	// COLORMAP always returns 0
		for(int i=fakecmaps.Size()-1; i > 0; i--)
		{
			if (!strnicmp(name, fakecmaps[i].name, 8))
			{
				return i;
			}
		}
				
		if (!strnicmp (name, "WATERMAP", 8))
			return MAKEARGB (128,0,0x4f,0xa5);
	}
	return 0;
}
コード例 #8
0
ファイル: menu.cpp プロジェクト: nano-bot/zdoom
void DMenu::Drawer ()
{
    if (this == DMenu::CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse)
    {
        FTexture *tex = TexMan(gameinfo.mBackButton);
        int w = tex->GetScaledWidth() * CleanXfac;
        int h = tex->GetScaledHeight() * CleanYfac;
        int x = (!(m_show_backbutton&1))? 0:screen->GetWidth() - w;
        int y = (!(m_show_backbutton&2))? 0:screen->GetHeight() - h;
        if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1))
        {
            screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, MAKEARGB(40, 255,255,255), TAG_DONE);
        }
        else
        {
            screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_AlphaF, BackbuttonAlpha, TAG_DONE);
        }
    }
}
コード例 #9
0
bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
{
	bool done;

	BurnTime += ticks;
	ticks *= 2;

	// Make the fire burn
	done = false;
	while (!done && ticks--)
	{
		Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
		done = (Density < 0);
	}

	if (BurnTexture != NULL) delete BurnTexture;
	BurnTexture = new GLTexture(WIDTH, HEIGHT, false, false);

	// Update the burn texture with the new burn data
	BYTE rgb_buffer[WIDTH*HEIGHT*4];

	const BYTE *src = BurnArray;
	DWORD *dest = (DWORD *)rgb_buffer;
	for (int y = HEIGHT; y != 0; --y)
	{
		for (int x = WIDTH; x != 0; --x)
		{
			BYTE s = clamp<int>((*src++)*2, 0, 255);
			*dest++ = MAKEARGB(s,255,255,255);
		}
	}

	// Put the initial screen back to the buffer.
	gl_SetTextureMode(TM_OPAQUE);
	gl.Disable(GL_ALPHA_TEST);
	fb->wipestartscreen->Bind(0, CM_DEFAULT);
	gl.Color4f(1.f, 1.f, 1.f, 1.f);
	gl.Begin(GL_TRIANGLE_STRIP);
	gl.TexCoord2f(0, fb->wipestartscreen->GetVB());
	gl.Vertex2i(0, 0);
	gl.TexCoord2f(0, 0);
	gl.Vertex2i(0, fb->Height);
	gl.TexCoord2f(fb->wipestartscreen->GetUR(), fb->wipestartscreen->GetVB());
	gl.Vertex2i(fb->Width, 0);
	gl.TexCoord2f(fb->wipestartscreen->GetUR(), 0);
	gl.Vertex2i(fb->Width, fb->Height);
	gl.End();

	gl_SetTextureMode(TM_MODULATE);
	gl.ActiveTexture(GL_TEXTURE1);
	gl.Enable(GL_TEXTURE_2D);

	// mask out the alpha channel of the wipeendscreen.
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); 
	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

	gl.ActiveTexture(GL_TEXTURE0);

	// Burn the new screen on top of it.
	gl.Color4f(1.f, 1.f, 1.f, 1.f);
	fb->wipeendscreen->Bind(1, CM_DEFAULT);
	//BurnTexture->Bind(0, CM_DEFAULT);

	BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0, CM_DEFAULT);
	gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


	gl.Begin(GL_TRIANGLE_STRIP);
	gl.MultiTexCoord2f(GL_TEXTURE0, 0, 0);
	gl.MultiTexCoord2f(GL_TEXTURE1, 0, fb->wipestartscreen->GetVB());
	gl.Vertex2i(0, 0);
	gl.MultiTexCoord2f(GL_TEXTURE0, 0, BurnTexture->GetVB());
	gl.MultiTexCoord2f(GL_TEXTURE1, 0, 0);
	gl.Vertex2i(0, fb->Height);
	gl.MultiTexCoord2f(GL_TEXTURE0, BurnTexture->GetUR(), 0);
	gl.MultiTexCoord2f(GL_TEXTURE1, fb->wipestartscreen->GetUR(), fb->wipestartscreen->GetVB());
	gl.Vertex2i(fb->Width, 0);
	gl.MultiTexCoord2f(GL_TEXTURE0, BurnTexture->GetUR(), BurnTexture->GetVB());
	gl.MultiTexCoord2f(GL_TEXTURE1, fb->wipestartscreen->GetUR(), 0);
	gl.Vertex2i(fb->Width, fb->Height);
	gl.End();

	gl.ActiveTexture(GL_TEXTURE1);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	gl.Disable(GL_TEXTURE_2D);
	gl.ActiveTexture(GL_TEXTURE0);

	// The fire may not always stabilize, so the wipe is forced to end
	// after an arbitrary maximum time.
	return done || (BurnTime > 40);
}
コード例 #10
0
ファイル: r_data.cpp プロジェクト: JohnnyonFlame/odamex
//
// R_InitColormaps
//
void R_InitColormaps (void)
{
	// [RH] Try and convert BOOM colormaps into blending values.
	//		This is a really rough hack, but it's better than
	//		not doing anything with them at all (right?)
	int lastfakecmap = W_CheckNumForName ("C_END");
	firstfakecmap = W_CheckNumForName ("C_START");

	if (firstfakecmap == -1 || lastfakecmap == -1)
		numfakecmaps = 1;
	else
	{
		if(firstfakecmap > lastfakecmap)
			I_Error("no fake cmaps");

		numfakecmaps = lastfakecmap - firstfakecmap;
	}

	realcolormaps.colormap = (byte *)Z_Malloc (256*(NUMCOLORMAPS+1)*numfakecmaps,PU_STATIC,0);
	realcolormaps.shademap = (argb_t *)Z_Malloc (256*sizeof(argb_t)*(NUMCOLORMAPS+1)*numfakecmaps,PU_STATIC,0);
	fakecmaps = (FakeCmap *)Z_Malloc (sizeof(*fakecmaps) * numfakecmaps, PU_STATIC, 0);

	fakecmaps[0].name[0] = 0;
	R_ForceDefaultColormap ("COLORMAP");

	if (numfakecmaps > 1)
	{
		int i;
		size_t j;
		palette_t *pal = GetDefaultPalette ();
		shaderef_t defpal = shaderef_t(&pal->maps, 0);

		for (i = ++firstfakecmap, j = 1; j < numfakecmaps; i++, j++)
		{
			if (W_LumpLength (i) >= (NUMCOLORMAPS+1)*256)
			{
				int k, r, g, b;
				byte *map = (byte *)W_CacheLumpNum (i, PU_CACHE);

				byte  *colormap = realcolormaps.colormap+(NUMCOLORMAPS+1)*256*j;
				argb_t *shademap = realcolormaps.shademap+(NUMCOLORMAPS+1)*256*j;

				// Copy colormap data:
				memcpy (colormap, map, (NUMCOLORMAPS+1)*256);

				if(pal->basecolors)
				{
					r = RPART(pal->basecolors[*map]);
					g = GPART(pal->basecolors[*map]);
					b = BPART(pal->basecolors[*map]);

					W_GetLumpName (fakecmaps[j].name, i);
					for (k = 1; k < 256; k++) {
						r = (r + RPART(pal->basecolors[map[k]])) >> 1;
						g = (g + GPART(pal->basecolors[map[k]])) >> 1;
						b = (b + BPART(pal->basecolors[map[k]])) >> 1;
					}
					// NOTE(jsd): This alpha value is used for 32bpp in water areas.
					fakecmaps[j].blend = MAKEARGB (64, r, g, b);

					// Set up shademap for the colormap:
					for (k = 0; k < 256; ++k)
					{
						argb_t c = pal->basecolors[map[0]];
						shademap[k] = alphablend1a(c, MAKERGB(r,g,b), j * (256 / numfakecmaps));
					}
				}
				else
				{
					// Set up shademap for the colormap:
					for (k = 0; k < 256; ++k)
コード例 #11
0
ファイル: a_decals.cpp プロジェクト: WChrisK/Zandronum
void DBaseDecal::SetShade (int r, int g, int b)
{
	AlphaColor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b);
}
コード例 #12
0
	void FromRGB(int r,int g, int b)
	{
		RGB = MAKEARGB(255, r, g, b);
		Index = ColorMatcher.Pick(r, g, b);
	}
コード例 #13
0
FxExpression *ParseParameter(FScanner &sc, PClass *cls, char type, bool constant)
{
	FxExpression *x = NULL;
	int v;

	switch(type)
	{
	case 'S':
	case 's':		// Sound name
		sc.MustGetString();
		x = new FxConstant(FSoundID(sc.String), sc);
		break;

	case 'M':
	case 'm':		// Actor name
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		x = new FxClassTypeCast(RUNTIME_CLASS(AActor), new FxConstant(FName(sc.String), sc));
		break;

	case 'T':
	case 't':		// String
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		x = new FxConstant(sc.String[0]? FName(sc.String) : NAME_None, sc);
		break;

	case 'C':
	case 'c':		// Color
		sc.MustGetString ();
		if (sc.Compare("none"))
		{
			v = -1;
		}
		else if (sc.Compare(""))
		{
			v = 0;
		}
		else
		{
			int c = V_GetColor (NULL, sc.String);
			// 0 needs to be the default so we have to mark the color.
			v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
		}
		{
			ExpVal val;
			val.Type = VAL_Color;
			val.Int = v;
			x = new FxConstant(val, sc);
			break;
		}

	case 'L':
	case 'l':
	{
		// This forces quotation marks around the state name.
		sc.MustGetToken(TK_StringConst);
		if (sc.String[0] == 0 || sc.Compare("None"))
		{
			x = new FxConstant((FState*)NULL, sc);
		}
		else if (sc.Compare("*"))
		{
			if (constant) 
			{
				x = new FxConstant((FState*)(intptr_t)-1, sc);
			}
			else sc.ScriptError("Invalid state name '*'");
		}
		else
		{
			x = new FxMultiNameState(sc.String, sc);
		}
		break;
	}

	case 'X':
	case 'x':
	case 'Y':
	case 'y':
		x = ParseExpression (sc, cls);
		if (constant && !x->isConstant())
		{
			sc.ScriptMessage("Default parameter must be constant.");
			FScriptPosition::ErrorCounter++;
		}
		break;

	default:
		assert(false);
		return NULL;
	}
	return x;
}
コード例 #14
0
	void FromCVar(FColorCVar & cv)
	{
		Index = cv.GetIndex();
		RGB = uint32(cv) | MAKEARGB(255, 0, 0, 0);
	}
コード例 #15
0
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant)
{
	FxExpression *x = NULL;
	int v;

	if (type == TypeSound)
	{
		sc.MustGetString();
		x = new FxConstant(FSoundID(sc.String), sc);
	}
	else if (type == TypeBool || type == TypeSInt32 || type == TypeFloat64)
	{
		x = ParseExpression (sc, cls, constant);
		if (constant && !x->isConstant())
		{
			sc.ScriptMessage("Default parameter must be constant.");
			FScriptPosition::ErrorCounter++;
		}
		// Do automatic coercion between bools, ints and floats.
		if (type == TypeBool)
		{
			x = new FxBoolCast(x);
		}
		else if (type == TypeSInt32)
		{
			x = new FxIntCast(x);
		}
		else
		{
			x = new FxFloatCast(x);
		}
	}
	else if (type == TypeName || type == TypeString)
	{
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		if (type == TypeName)
		{
			x = new FxConstant(sc.String[0] ? FName(sc.String) : NAME_None, sc);
		}
		else
		{
			x = new FxConstant(strbin1(sc.String), sc);
		}
	}
	else if (type == TypeColor)
	{
		sc.MustGetString ();
		if (sc.Compare("none"))
		{
			v = -1;
		}
		else if (sc.Compare(""))
		{
			v = 0;
		}
		else
		{
			int c = V_GetColor (NULL, sc.String);
			// 0 needs to be the default so we have to mark the color.
			v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
		}
		ExpVal val;
		val.Type = TypeColor;
		val.Int = v;
		x = new FxConstant(val, sc);
	}
	else if (type == TypeState)
	{
		// This forces quotation marks around the state name.
		sc.MustGetToken(TK_StringConst);
		if (sc.String[0] == 0 || sc.Compare("None"))
		{
			x = new FxConstant((FState*)NULL, sc);
		}
		else if (sc.Compare("*"))
		{
			if (constant) 
			{
				x = new FxConstant((FState*)(intptr_t)-1, sc);
			}
			else sc.ScriptError("Invalid state name '*'");
		}
		else
		{
			x = new FxMultiNameState(sc.String, sc);
		}
	}
	else if (type->GetClass() == RUNTIME_CLASS(PClassPointer))
	{	// Actor name
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		x = new FxClassTypeCast(static_cast<PClassPointer *>(type)->ClassRestriction, new FxConstant(FName(sc.String), sc));
	}
	else
	{
		assert(false && "Unknown parameter type");
		x = NULL;
	}
	return x;
}
コード例 #16
0
ファイル: font.cpp プロジェクト: coelckers/gzdoom
void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity,
							   const void *ranges, int total_colors, const PalEntry *palette)
{
	int i, j;
	const TranslationParm *parmstart = (const TranslationParm *)ranges;

	FRemapTable remap(total_colors);

	// Create different translations for different color ranges
	Ranges.Clear();
	for (i = 0; i < NumTextColors; i++)
	{
		if (i == CR_UNTRANSLATED)
		{
			if (identity != nullptr)
			{
				memcpy (remap.Remap, identity, ActiveColors);
				if (palette != nullptr)
				{
					memcpy (remap.Palette, palette, ActiveColors*sizeof(PalEntry));
				}
				else
				{
					remap.Palette[0] = GPalette.BaseColors[identity[0]] & MAKEARGB(0,255,255,255);
					for (j = 1; j < ActiveColors; ++j)
					{
						remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255,0,0,0);
					}
				}
			}
			else
			{
				remap = Ranges[0];
			}
			Ranges.Push(remap);
			continue;
		}

		assert(parmstart->RangeStart >= 0);

		remap.Remap[0] = 0;
		remap.Palette[0] = 0;

		for (j = 1; j < ActiveColors; j++)
		{
			int v = int(luminosity[j] * 256.0);

			// Find the color range that this luminosity value lies within.
			const TranslationParm *parms = parmstart - 1;
			do
			{
				parms++;
				if (parms->RangeStart <= v && parms->RangeEnd >= v)
					break;
			}
			while (parms[1].RangeStart > parms[0].RangeEnd);

			// Linearly interpolate to find out which color this luminosity level gets.
			int rangev = ((v - parms->RangeStart) << 8) / (parms->RangeEnd - parms->RangeStart);
			int r = ((parms->Start[0] << 8) + rangev * (parms->End[0] - parms->Start[0])) >> 8; // red
			int g = ((parms->Start[1] << 8) + rangev * (parms->End[1] - parms->Start[1])) >> 8; // green
			int b = ((parms->Start[2] << 8) + rangev * (parms->End[2] - parms->Start[2])) >> 8; // blue
			r = clamp(r, 0, 255);
			g = clamp(g, 0, 255);
			b = clamp(b, 0, 255);
			remap.Remap[j] = ColorMatcher.Pick(r, g, b);
			remap.Palette[j] = PalEntry(255,r,g,b);
		}
		Ranges.Push(remap);

		// Advance to the next color range.
		while (parmstart[1].RangeStart > parmstart[0].RangeEnd)
		{
			parmstart++;
		}
		parmstart++;
	}
}
コード例 #17
0
//==========================================================================
//
// ParseStates
// parses a state block
//
//==========================================================================
int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
{
	FString statestring;
	intptr_t count = 0;
	FState state;
	FState * laststate = NULL;
	intptr_t lastlabel = -1;
	int minrequiredstate = -1;

	SC_MustGetStringName ("{");
	SC_SetEscape(false);	// disable escape sequences in the state parser
	while (!SC_CheckString ("}") && !sc_End)
	{
		memset(&state,0,sizeof(state));
		statestring = ParseStateString();
		if (!statestring.CompareNoCase("GOTO"))
		{
do_goto:	
			statestring = ParseStateString();
			if (SC_CheckString ("+"))
			{
				SC_MustGetNumber ();
				statestring += '+';
				statestring += sc_String;
			}
			// copy the text - this must be resolved later!
			if (laststate != NULL)
			{ // Following a state definition: Modify it.
				laststate->NextState = (FState*)copystring(statestring);	
			}
			else if (lastlabel >= 0)
			{ // Following a label: Retarget it.
				RetargetStates (count+1, statestring);
			}
			else
			{
				SC_ScriptError("GOTO before first state");
			}
		}
		else if (!statestring.CompareNoCase("STOP"))
		{
do_stop:
			if (laststate!=NULL)
			{
				laststate->NextState=(FState*)-1;
			}
			else if (lastlabel >=0)
			{
				RetargetStates (count+1, NULL);
			}
			else
			{
				SC_ScriptError("STOP before first state");
				continue;
			}
		}
		else if (!statestring.CompareNoCase("WAIT") || !statestring.CompareNoCase("FAIL"))
		{
			if (!laststate) 
			{
				SC_ScriptError("%s before first state", sc_String);
				continue;
			}
			laststate->NextState=(FState*)-2;
		}
		else if (!statestring.CompareNoCase("LOOP"))
		{
			if (!laststate) 
			{
				SC_ScriptError("LOOP before first state");
				continue;
			}
			laststate->NextState=(FState*)(lastlabel+1);
		}
		else
		{
			const char * statestrp;

			SC_MustGetString();
			if (SC_Compare (":"))
			{
				laststate = NULL;
				do
				{
					lastlabel = count;
					AddState(statestring, (FState *) (count+1));
					statestring = ParseStateString();
					if (!statestring.CompareNoCase("GOTO"))
					{
						goto do_goto;
					}
					else if (!statestring.CompareNoCase("STOP"))
					{
						goto do_stop;
					}
					SC_MustGetString ();
				} while (SC_Compare (":"));
//				continue;
			}

			SC_UnGet ();

			if (statestring.Len() != 4)
			{
				SC_ScriptError ("Sprite names must be exactly 4 characters\n");
			}

			memcpy(state.sprite.name, statestring, 4);
			state.Misc1=state.Misc2=0;
			state.ParameterIndex=0;
			SC_MustGetString();
			statestring = (sc_String+1);
			statestrp = statestring;
			state.Frame=(*sc_String&223)-'A';
			if ((*sc_String&223)<'A' || (*sc_String&223)>']')
			{
				SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
				state.Frame=0;
			}

			SC_MustGetNumber();
			sc_Number++;
			state.Tics=sc_Number&255;
			state.Misc1=(sc_Number>>8)&255;
			if (state.Misc1) state.Frame|=SF_BIGTIC;

			while (SC_GetString() && !sc_Crossed)
			{
				if (SC_Compare("BRIGHT")) 
				{
					state.Frame|=SF_FULLBRIGHT;
					continue;
				}
				if (SC_Compare("OFFSET"))
				{
					if (state.Frame&SF_BIGTIC)
					{
						SC_ScriptError("You cannot use OFFSET with a state duration larger than 254!");
					}
					// specify a weapon offset
					SC_MustGetStringName("(");
					SC_MustGetNumber();
					state.Misc1=sc_Number;
					SC_MustGetStringName (",");
					SC_MustGetNumber();
					state.Misc2=sc_Number;
					SC_MustGetStringName(")");
					continue;
				}

				// Make the action name lowercase to satisfy the gperf hashers
				strlwr (sc_String);

				int minreq=count;
				if (DoActionSpecials(state, !statestring.IsEmpty(), &minreq, bag))
				{
					if (minreq>minrequiredstate) minrequiredstate=minreq;
					goto endofstate;
				}

				PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true);
				if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
				{
					PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
					state.Action = afd->Function;
					if (!afd->Arguments.IsEmpty())
					{
						const char *params = afd->Arguments.GetChars();
						int numparams = (int)afd->Arguments.Len();
				
						int v;

						if (!islower(*params))
						{
							SC_MustGetStringName("(");
						}
						else
						{
							if (!SC_CheckString("(")) goto endofstate;
						}
						
						int paramindex = PrepareStateParameters(&state, numparams);
						int paramstart = paramindex;
						bool varargs = params[numparams - 1] == '+';

						if (varargs)
						{
							StateParameters[paramindex++] = 0;
						}

						while (*params)
						{
							switch(*params)
							{
							case 'I':
							case 'i':		// Integer
								SC_MustGetNumber();
								v=sc_Number;
								break;

							case 'F':
							case 'f':		// Fixed point
								SC_MustGetFloat();
								v=fixed_t(sc_Float*FRACUNIT);
								break;


							case 'S':
							case 's':		// Sound name
								SC_MustGetString();
								v=S_FindSound(sc_String);
								break;

							case 'M':
							case 'm':		// Actor name
							case 'T':
							case 't':		// String
								SC_SetEscape(true);
								SC_MustGetString();
								SC_SetEscape(false);
								v = (int)(sc_String[0] ? FName(sc_String) : NAME_None);
								break;

							case 'L':
							case 'l':		// Jump label

								if (SC_CheckNumber())
								{
									if (strlen(statestring)>0)
									{
										SC_ScriptError("You cannot use A_Jump commands with a jump index on multistate definitions\n");
									}

									v=sc_Number;
									if (v<1)
									{
										SC_ScriptError("Negative jump offsets are not allowed");
									}

									{
										int minreq=count+v;
										if (minreq>minrequiredstate) minrequiredstate=minreq;
									}
								}
								else
								{
									if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None);

									v = -(int)JumpParameters.Size();
									// This forces quotation marks around the state name.
									SC_MustGetToken(TK_StringConst);
									FString statestring = sc_String; // ParseStateString();
									const PClass *stype=NULL;
									int scope = statestring.IndexOf("::");
									if (scope >= 0)
									{
										FName scopename = FName(statestring, scope, false);
										if (scopename == NAME_Super)
										{
											// Super refers to the direct superclass
											scopename = actor->Class->ParentClass->TypeName;
										}
										JumpParameters.Push(scopename);
										statestring = statestring.Right(statestring.Len()-scope-2);

										stype = PClass::FindClass (scopename);
										if (stype == NULL)
										{
											SC_ScriptError ("%s is an unknown class.", scopename.GetChars());
										}
										if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor)))
										{
											SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
										}
										if (!stype->IsAncestorOf (actor->Class))
										{
											SC_ScriptError ("%s is not derived from %s so cannot access its states.",
												actor->Class->TypeName.GetChars(), stype->TypeName.GetChars());
										}
									}
									else
									{
										// No class name is stored. This allows 'virtual' jumps to
										// labels in subclasses.
										// It also means that the validity of the given state cannot
										// be checked here.
										JumpParameters.Push(NAME_None);
									}
									TArray<FName> names;
									MakeStateNameList(statestring, &names);

									if (stype != NULL)
									{
										if (!stype->ActorInfo->FindState(names.Size(), &names[0]))
										{
											SC_ScriptError("Jump to unknown state '%s' in class '%s'",
												statestring.GetChars(), stype->TypeName.GetChars());
										}
									}
									JumpParameters.Push((ENamedName)names.Size());
									for(unsigned i=0;i<names.Size();i++)
									{
										JumpParameters.Push(names[i]);
									}
									// No offsets here. The point of jumping to labels is to avoid such things!
								}

								break;

							case 'C':
							case 'c':		// Color
								SC_MustGetString ();
								if (SC_Compare("none"))
								{
									v = -1;
								}
								else
								{
									int c = V_GetColor (NULL, sc_String);
									// 0 needs to be the default so we have to mark the color.
									v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
								}
								break;

							case 'X':
							case 'x':
								v = ParseExpression (false, bag.Info->Class);
								break;

							case 'Y':
							case 'y':
								v = ParseExpression (true, bag.Info->Class);
								break;

							default:
								assert(false);
								v = -1;
								break;
							}
							StateParameters[paramindex++] = v;
							params++;
							if (varargs)
							{
								StateParameters[paramstart]++;
							}
							if (*params)
							{
								if (*params == '+')
								{
									if (SC_CheckString(")"))
									{
										goto endofstate;
									}
									params--;
									v = 0;
									StateParameters.Push(v);
								}
								else if ((islower(*params) || *params=='!') && SC_CheckString(")"))
								{
									goto endofstate;
								}
								SC_MustGetStringName (",");
							}
						}
						SC_MustGetStringName(")");
					}
					else 
					{
						SC_MustGetString();
						if (SC_Compare("("))
						{
							SC_ScriptError("You cannot pass parameters to '%s'\n",sc_String);
						}
						SC_UnGet();
					}
					goto endofstate;
				}
				SC_ScriptError("Invalid state parameter %s\n", sc_String);
			}
			SC_UnGet();
endofstate:
			StateArray.Push(state);
			while (*statestrp)
			{
				int frame=((*statestrp++)&223)-'A';

				if (frame<0 || frame>28)
				{
					SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
					frame=0;
				}

				state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC))|frame;
				StateArray.Push(state);
				count++;
			}
			laststate=&StateArray[count];
			count++;
		}
	}
	if (count<=minrequiredstate)
	{
		SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars());
	}
	SC_SetEscape(true);	// re-enable escape sequences
	return count;
}
コード例 #18
0
ファイル: r_translate.cpp プロジェクト: Accusedbold/zdoom
void R_InitTranslationTables ()
{
	int i;

	// Each player gets two translations. Doom and Strife don't use the
	// extra ones, but Heretic and Hexen do. These are set up during
	// netgame arbitration and as-needed, so they just get to be identity
	// maps until then so they won't be invalid.
	for (i = 0; i < MAXPLAYERS; ++i)
	{
		PushIdentityTable(TRANSLATION_Players);
		PushIdentityTable(TRANSLATION_PlayersExtra);
		PushIdentityTable(TRANSLATION_RainPillar);
	}
	// The menu player also gets a separate translation table
	PushIdentityTable(TRANSLATION_Players);

	// The three standard translations from Doom or Heretic (seven for Strife),
	// plus the generic ice translation.
	for (i = 0; i < 8; ++i)
	{
		PushIdentityTable(TRANSLATION_Standard);
	}

	// Each player corpse has its own translation so they won't change
	// color if the player who created them changes theirs.
	for (i = 0; i < BODYQUESIZE; ++i)
	{
		PushIdentityTable(TRANSLATION_PlayerCorpses);
	}

	// Create the standard translation tables
	if (gameinfo.gametype & GAME_DoomChex)
	{
		for (i = 0x70; i < 0x80; i++)
		{ // map green ramp to gray, brown, red
			translationtables[TRANSLATION_Standard][0]->Remap[i] = 0x60 + (i&0xf);
			translationtables[TRANSLATION_Standard][1]->Remap[i] = 0x40 + (i&0xf);
			translationtables[TRANSLATION_Standard][2]->Remap[i] = 0x20 + (i&0xf);

			translationtables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[0x60 + (i&0xf)] | MAKEARGB(255,0,0,0);
			translationtables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[0x40 + (i&0xf)] | MAKEARGB(255,0,0,0);
			translationtables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[0x20 + (i&0xf)] | MAKEARGB(255,0,0,0);
		}
	}
	else if (gameinfo.gametype == GAME_Heretic)
	{
		for (i = 225; i <= 240; i++)
		{
			translationtables[TRANSLATION_Standard][0]->Remap[i] = 114+(i-225); // yellow
			translationtables[TRANSLATION_Standard][1]->Remap[i] = 145+(i-225); // red
			translationtables[TRANSLATION_Standard][2]->Remap[i] = 190+(i-225); // blue
			
			translationtables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[114+(i-225)] | MAKEARGB(255,0,0,0);
			translationtables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[145+(i-225)] | MAKEARGB(255,0,0,0);
			translationtables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[190+(i-225)] | MAKEARGB(255,0,0,0);
		}
	}
	else if (gameinfo.gametype == GAME_Strife)
	{
		for (i = 0x20; i <= 0x3F; ++i)
		{
			translationtables[TRANSLATION_Standard][0]->Remap[i] = i - 0x20;
			translationtables[TRANSLATION_Standard][1]->Remap[i] = i - 0x20;
			translationtables[TRANSLATION_Standard][2]->Remap[i] = 0xD0 + (i&0xf);
			translationtables[TRANSLATION_Standard][3]->Remap[i] = 0xD0 + (i&0xf);
			translationtables[TRANSLATION_Standard][4]->Remap[i] = i - 0x20;
			translationtables[TRANSLATION_Standard][5]->Remap[i] = i - 0x20;
			translationtables[TRANSLATION_Standard][6]->Remap[i] = i - 0x20;
		}
		for (i = 0x50; i <= 0x5F; ++i)
		{
			// Merchant hair
			translationtables[TRANSLATION_Standard][4]->Remap[i] = 0x80 + (i&0xf);
			translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x10 + (i&0xf);
			translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x40 + (i&0xf);
		}
		for (i = 0x80; i <= 0x8F; ++i)
		{
			translationtables[TRANSLATION_Standard][0]->Remap[i] = 0x40 + (i&0xf); // red
			translationtables[TRANSLATION_Standard][1]->Remap[i] = 0xB0 + (i&0xf); // rust
			translationtables[TRANSLATION_Standard][2]->Remap[i] = 0x10 + (i&0xf); // gray
			translationtables[TRANSLATION_Standard][3]->Remap[i] = 0x30 + (i&0xf); // dark green
			translationtables[TRANSLATION_Standard][4]->Remap[i] = 0x50 + (i&0xf); // gold
			translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x60 + (i&0xf); // bright green
			translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x90 + (i&0xf); // blue
		}
		for (i = 0xC0; i <= 0xCF; ++i)
		{
			translationtables[TRANSLATION_Standard][4]->Remap[i] = 0xA0 + (i&0xf);
			translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x20 + (i&0xf);
			translationtables[TRANSLATION_Standard][6]->Remap[i] = (i&0xf);
		}
		translationtables[TRANSLATION_Standard][6]->Remap[0xC0] = 1;
		for (i = 0xD0; i <= 0xDF; ++i)
		{
			translationtables[TRANSLATION_Standard][4]->Remap[i] = 0xB0 + (i&0xf);
			translationtables[TRANSLATION_Standard][5]->Remap[i] = 0x30 + (i&0xf);
			translationtables[TRANSLATION_Standard][6]->Remap[i] = 0x10 + (i&0xf);
		}
		for (i = 0xF1; i <= 0xF6; ++i)
		{
			translationtables[TRANSLATION_Standard][0]->Remap[i] = 0xDF + (i&0xf);
		}
		for (i = 0xF7; i <= 0xFB; ++i)
		{
			translationtables[TRANSLATION_Standard][0]->Remap[i] = i - 6;
		}
		for (i = 0; i < 7; ++i)
		{
			for (int j = 0x20; j <= 0xFB; ++j)
			{
				translationtables[TRANSLATION_Standard][i]->Palette[j] =
					GPalette.BaseColors[translationtables[TRANSLATION_Standard][i]->Remap[j]] | MAKEARGB(255,0,0,0);
			}
		}
	}

	// Create the ice translation table, based on Hexen's. Alas, the standard
	// Doom palette has no good substitutes for these bluish-tinted grays, so
	// they will just look gray unless you use a different PLAYPAL with Doom.

	BYTE IcePaletteRemap[16];
	for (i = 0; i < 16; ++i)
	{
		IcePaletteRemap[i] = ColorMatcher.Pick (IcePalette[i][0], IcePalette[i][1], IcePalette[i][2]);
	}
	FRemapTable *remap = translationtables[TRANSLATION_Standard][7];
	for (i = 0; i < 256; ++i)
	{
		int r = GPalette.BaseColors[i].r;
		int g = GPalette.BaseColors[i].g;
		int b = GPalette.BaseColors[i].b;
		int v = (r*77 + g*143 + b*37) >> 12;
		remap->Remap[i] = IcePaletteRemap[v];
		remap->Palette[i] = PalEntry(255, IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]);
	}

	// The alphatexture translation. Since alphatextures use the red channel this is just a standard grayscale mapping.
	PushIdentityTable(TRANSLATION_Standard);
	remap = translationtables[TRANSLATION_Standard][8];
	for (i = 0; i < 256; i++)
	{
		remap->Remap[i] = i;
		remap->Palette[i] = PalEntry(255, i, i, i);
	}
}
コード例 #19
0
ファイル: gl_wipe.cpp プロジェクト: loismustdie555/GZDoom-GPL
bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
{
    bool done;

    BurnTime += ticks;
    ticks *= 2;

    // Make the fire burn
    done = false;
    while (!done && ticks--)
    {
        Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
        done = (Density < 0);
    }

    if (BurnTexture != NULL) delete BurnTexture;
    BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, true);

    // Update the burn texture with the new burn data
    BYTE rgb_buffer[WIDTH*HEIGHT*4];

    const BYTE *src = BurnArray;
    DWORD *dest = (DWORD *)rgb_buffer;
    for (int y = HEIGHT; y != 0; --y)
    {
        for (int x = WIDTH; x != 0; --x)
        {
            BYTE s = clamp<int>((*src++)*2, 0, 255);
            *dest++ = MAKEARGB(s,255,255,255);
        }
    }

    float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
    float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());


    // Put the initial screen back to the buffer.
    gl_RenderState.SetTextureMode(TM_OPAQUE);
    gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
    gl_RenderState.ResetColor();
    gl_RenderState.Apply();
    fb->wipestartscreen->Bind(0, 0, false);
    FFlatVertex *ptr;
    unsigned int offset, count;
    ptr = GLRenderer->mVBO->GetBuffer();
    ptr->Set(0, 0, 0, 0, vb);
    ptr++;
    ptr->Set(0, fb->Height, 0, 0, 0);
    ptr++;
    ptr->Set(fb->Width, 0, 0, ur, vb);
    ptr++;
    ptr->Set(fb->Width, fb->Height, 0, ur, 0);
    ptr++;
    GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);

    gl_RenderState.SetTextureMode(TM_MODULATE);
    gl_RenderState.SetEffect(EFF_BURN);
    gl_RenderState.ResetColor();
    gl_RenderState.Apply();

    // Burn the new screen on top of it.
    fb->wipeendscreen->Bind(0, 0, false);

    BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0);

    GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
    gl_RenderState.SetEffect(EFF_NONE);

    // The fire may not always stabilize, so the wipe is forced to end
    // after an arbitrary maximum time.
    return done || (BurnTime > 40);
}
コード例 #20
0
	void Drawer()
	{
		Super::Drawer();

		if (mCVar == NULL) return;
		int y = (-mDesc->mPosition + BigFont->GetHeight() + mDesc->mItems.Size() * OptionSettings.mLinespacing) * CleanYfac_1;
		int h = (screen->GetHeight() - y) / 16;
		int fh = OptionSettings.mLinespacing * CleanYfac_1;
		int w = fh;
		int yy = y;

		if (h > fh) h = fh;
		else if (h < 4) return;	// no space to draw it.
		
		int indent = (screen->GetWidth() / 2);
		int p = 0;

		for(int i = 0; i < 16; i++, y += h)
		{
			int box_x, box_y;
			int x1;

			box_y = y - 2 * CleanYfac_1;
			box_x = indent - 16*w;
			for (x1 = 0; x1 < 16; ++x1, p++)
			{
				screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0);
				if ((mDesc->mSelectedItem == mStartItem+7) && 
					(/*p == CurrColorIndex ||*/ (i == mGridPosY && x1 == mGridPosX)))
				{
					int r, g, b;
					DWORD col;
					double blinky;
					if (i == mGridPosY && x1 == mGridPosX)
					{
						r = 255, g = 128, b = 0;
					}
					else
					{
						r = 200, g = 200, b = 255;
					}
					// Make sure the cursors stand out against similar colors
					// by pulsing them.
					blinky = fabs(sin(I_MSTime()/1000.0)) * 0.5 + 0.5;
					col = MAKEARGB(255,int(r*blinky),int(g*blinky),int(b*blinky));

					screen->Clear (box_x, box_y, box_x + w, box_y + 1, -1, col);
					screen->Clear (box_x, box_y + h-1, box_x + w, box_y + h, -1, col);
					screen->Clear (box_x, box_y, box_x + 1, box_y + h, -1, col);
					screen->Clear (box_x + w - 1, box_y, box_x + w, box_y + h, -1, col);
				}
				box_x += w;
			}
		}
		y = yy;
		DWORD newColor = MAKEARGB(255, int(mRed), int(mGreen), int(mBlue));
		DWORD oldColor = DWORD(*mCVar) | 0xFF000000;

		int x = screen->GetWidth()*2/3;

		screen->Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, -1, oldColor);
		screen->Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, -1, newColor);

		y += 49*CleanYfac_1;
		screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac_1, y,
			"Old", DTA_CleanNoMove_1, true, TAG_DONE);
		screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac_1, y,
			"New", DTA_CleanNoMove_1, true, TAG_DONE);
	}