Пример #1
0
void CBeamEffectCreator::DrawBeamLightningBolt (CG16bitImage &Dest, SLineDesc &Line, SViewportPaintCtx &Ctx)

//	DrawBeamLightningBolt
//
//	Draws the appropriate beam

	{
	int i;

	//	Compute a set of points for the lightning

	int iPointCount = LIGHTNING_POINT_COUNT;
	CVector *pPoints = new CVector [iPointCount];
	pPoints[0] = CVector(Line.xFrom, Line.yFrom);
	pPoints[iPointCount - 1] = CVector(Line.xTo, Line.yTo);

	ComputeLightningPoints(iPointCount, pPoints, 0.3);

	//	Draw based on intensity

	switch (m_iIntensity)
		{
		//	Draw nothing

		case 0:
			break;

		//	At intensity 1 or 2 just draw a lightning line with the primary color

		case 1:
		case 2:
			{
			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						m_iIntensity,
						m_wPrimaryColor);
				}
			break;
			}

		//	At intensity 3 or 4 draw secondary color around primary.

		case 3:
		case 4:
			{
			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						m_iIntensity,
						m_wSecondaryColor);
				}

			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						m_iIntensity - 2,
						m_wPrimaryColor);
				}
			break;
			}

		//	At intensity 5-10 we draw a glow around the beam

		case 5:
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
			{
			//	Create a polygon for the glow shaped like a wide version of the
			//	lightning bolt.

			CG16bitRegion GlowRegion;
			CreateLightningGlow(Line, iPointCount, pPoints, m_iIntensity, &GlowRegion);

			//	Paint the glow

			GlowRegion.FillTrans(Dest, 0, 0, m_wSecondaryColor, 128);

			//	Paint the main bolt

			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						4,
						m_wSecondaryColor);
				}

			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						2,
						m_wPrimaryColor);
				}

			break;
			}

		//	For even larger beams we do a double glow

		default:
			{
			//	Create a polygon for the glow shaped like a wide version of the
			//	lightning bolt.

			CG16bitRegion GlowRegion1;
			CreateLightningGlow(Line, iPointCount, pPoints, m_iIntensity, &GlowRegion1);

			CG16bitRegion GlowRegion2;
			CreateLightningGlow(Line, iPointCount, pPoints, 10, &GlowRegion2);

			//	Paint the glow

			GlowRegion1.FillTrans(Dest, 0, 0, m_wSecondaryColor, 48);
			GlowRegion2.FillTrans(Dest, 0, 0, m_wSecondaryColor, 96);

			//	Paint the main bolt

			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						4,
						m_wSecondaryColor);
				}

			for (i = 0; i < iPointCount-1; i++)
				{
				const CVector &vFrom = pPoints[i];
				const CVector &vTo = pPoints[i + 1];

				Dest.DrawLine((int)vFrom.GetX(), (int)vFrom.GetY(),
						(int)vTo.GetX(), (int)vTo.GetY(),
						2,
						m_wPrimaryColor);
				}

			break;
			}
		}

	//	Done

	delete [] pPoints;
	}
Пример #2
0
void DrawFilledCircleTrans (CG16bitImage &Dest, int xDest, int yDest, int iRadius, WORD wColor, DWORD byOpacity)

//	DrawFilledCircleTrans
//
//	Draws an transparent filled circle

{
    //	Deal with edge-conditions

    if (iRadius <= 0)
    {
        Dest.DrawPixelTrans(xDest, yDest, wColor, (BYTE)byOpacity);
        return;
    }
    else if (byOpacity == 255)
    {
        DrawFilledCircle(Dest, xDest, yDest, iRadius, wColor);
        return;
    }

    //	Initialize some stuff

    int x = 0;
    int y = iRadius;
    int d = 1 - iRadius;
    int deltaE = 3;
    int deltaSE = -2 * iRadius + 5;

    Dest.FillLineTrans(xDest - iRadius, yDest, 1 + 2 * iRadius, wColor, byOpacity);

    //	Loop

    while (y > x)
    {
        if (d < 0)
        {
            d += deltaE;
            deltaE += 2;
            deltaSE += 2;
        }
        else
        {
            d += deltaSE;
            deltaE += 2;
            deltaSE += 4;

            Dest.FillLineTrans(xDest - x, yDest - y, 1 + 2 * x, wColor, byOpacity);
            Dest.FillLineTrans(xDest - x, yDest + y, 1 + 2 * x, wColor, byOpacity);

            y--;
        }

        x++;

        if (y >= x)
        {
            Dest.FillLineTrans(xDest - y, yDest - x, 1 + 2 * y, wColor, byOpacity);
            Dest.FillLineTrans(xDest - y, yDest + x, 1 + 2 * y, wColor, byOpacity);
        }
    }
}
Пример #3
0
void CBeamEffectCreator::DrawBeamLightning (CG16bitImage &Dest, SLineDesc &Line, SViewportPaintCtx &Ctx)

//	DrawBeamLightning
//
//	Draws the appropriate beam

	{
	//	The central part of the beam is different depending on the
	//	intensity.

	if (m_iIntensity < 4)
		{
		WORD wStart = CG16bitImage::BlendPixel(Ctx.wSpaceColor, m_wPrimaryColor, 128);
		Dest.DrawBiColorLine(Line.xFrom, Line.yFrom,
				Line.xTo, Line.yTo,
				3,
				Ctx.wSpaceColor,
				wStart);

		WORD wEnd = CG16bitImage::BlendPixel(Ctx.wSpaceColor, m_wPrimaryColor, 155);
		Dest.DrawBiColorLine(Line.xFrom, Line.yFrom,
				Line.xTo, Line.yTo,
				1,
				wEnd,
				m_wPrimaryColor);
		}
	else if (m_iIntensity < 10)
		{
		WORD wStart = CG16bitImage::BlendPixel(Ctx.wSpaceColor, m_wSecondaryColor, 155);
		Dest.DrawBiColorLine(Line.xFrom, Line.yFrom,
				Line.xTo, Line.yTo,
				5,
				Ctx.wSpaceColor,
				wStart);

		Dest.DrawBiColorLine(Line.xFrom, Line.yFrom,
				Line.xTo, Line.yTo,
				3,
				Ctx.wSpaceColor,
				m_wSecondaryColor);

		WORD wEnd = CG16bitImage::BlendPixel(Ctx.wSpaceColor, m_wPrimaryColor, 155);
		Dest.DrawBiColorLine(Line.xFrom, Line.yFrom,
				Line.xTo, Line.yTo,
				1,
				wEnd,
				m_wPrimaryColor);
		}
	else
		{
		//	Convert to an angle relative to xTo, yTo

		CVector vVec(Line.xFrom - Line.xTo, Line.yFrom - Line.yTo);
		Metric rRadius;
		int iAngle = VectorToPolar(vVec, &rRadius);
		int iRadius = (int)rRadius;

		//	Can't deal with 0 sized lines

		if (iRadius == 0)
			return;

		CG16bitRegion Region;
		SPoint Poly[8];

		//	Paint the outer-most glow

		WORD wColor = CG16bitImage::BlendPixel(Ctx.wSpaceColor, m_wSecondaryColor, 100);
		CreateBlasterShape(iAngle, iRadius, iRadius / 6, Poly);
		Region.CreateFromConvexPolygon(8, Poly);
		Region.Fill(Dest, Line.xTo, Line.yTo, wColor);

		//	Paint the inner transition

		wColor = CG16bitImage::BlendPixel(m_wSecondaryColor, m_wPrimaryColor, 128);
		wColor = CG16bitImage::BlendPixel(Ctx.wSpaceColor, wColor, 200);
		CreateBlasterShape(iAngle, iRadius * 2 / 3, iRadius / 7, Poly);
		Region.CreateFromConvexPolygon(8, Poly);
		Region.Fill(Dest, Line.xTo, Line.yTo, wColor);

		//	Paint the inner core

		CreateBlasterShape(iAngle, iRadius / 2, iRadius / 8, Poly);
		Region.CreateFromConvexPolygon(8, Poly);
		Region.Fill(Dest, Line.xTo, Line.yTo, m_wPrimaryColor);
		}

	//	Compute the half-way point

	int xHalf = (Line.xFrom + Line.xTo) / 2;
	int yHalf = (Line.yFrom + Line.yTo) / 2;

	//	Draw lightning

	int iCount = m_iIntensity + mathRandom(0, 2);
	for (int j = 0; j < iCount; j++)
		if (mathRandom(1, 2) == 1)
			DrawLightning(Dest, 
					xHalf, 
					yHalf, 
					Line.xTo, 
					Line.yTo, 
					m_wPrimaryColor, 
					LIGHTNING_POINT_COUNT, 
					0.5);
		else
			DrawLightning(Dest, 
					Line.xFrom, 
					Line.yFrom, 
					Line.xTo, 
					Line.yTo, 
					m_wSecondaryColor, 
					LIGHTNING_POINT_COUNT, 
					0.3);
	}
void CListSaveFilesTask::CreateFileEntry (CGameFile &GameFile, const CTimeDate &ModifiedTime, int yStart, IAnimatron **retpEntry, int *retcyHeight)

//	CreateFileEntry
//
//	Creates a display entry for the save file

	{
	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &MediumFont = VI.GetFont(fontMedium);
	const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle);

	int x = 0;
	int y = 0;
	int xText = x + ADVENTURE_ICON_WIDTH + ICON_SPACING_HORZ;
	int cxText = m_cxWidth - (ADVENTURE_ICON_WIDTH + 2 * ICON_SPACING_HORZ + SHIP_IMAGE_WIDTH);

	//	Start with a sequencer

	CAniSequencer *pRoot = new CAniSequencer;
	pRoot->SetPropertyVector(PROP_POSITION, CVector(0, yStart));

	//	Add the character name and current star system

	CString sHeading = strPatternSubst(CONSTLIT("%s — %s"), GameFile.GetPlayerName(), GameFile.GetSystemName());

	IAnimatron *pName = new CAniText;
	pName->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pName->SetPropertyVector(PROP_SCALE, CVector(10000, 1000));
	pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pName->SetPropertyFont(PROP_FONT, &SubTitleFont);
	pName->SetPropertyString(PROP_TEXT, sHeading);

	pRoot->AddTrack(pName, 0);
	y += SubTitleFont.GetHeight();

	//	Now add some additional information

	CShipClass *pClass = g_pUniverse->FindShipClass(GameFile.GetPlayerShip());
	CString sShipClass = (pClass ? pClass->GetName() : NULL_STR);
	CString sGenome = strCapitalize(GetGenomeName(GameFile.GetPlayerGenome()));

	CString sState;
	if (GameFile.IsGameResurrect())
		sState = strPatternSubst(CONSTLIT("Resurrect in the %s System"), GameFile.GetSystemName());
	else
		sState = strPatternSubst(CONSTLIT("Continue in the %s System"), GameFile.GetSystemName());

	CString sDesc;
	if (!sGenome.IsBlank() && !sShipClass.IsBlank())
		sDesc = strPatternSubst(CONSTLIT("%s — %s — %s"), sGenome, sShipClass, sState);
	else
		sDesc = sState;

	IAnimatron *pDesc = new CAniText;
	pDesc->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pDesc->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pDesc->SetPropertyFont(PROP_FONT, &MediumFont);
	pDesc->SetPropertyString(PROP_TEXT, sDesc);

	RECT rcLine;
	pDesc->GetSpacingRect(&rcLine);

	pRoot->AddTrack(pDesc, 0);
	y += RectHeight(rcLine);

	//	Adventure info

	CExtension *pAdventure = NULL;
	bool bHasAdventureIcon = false;

	if (g_pUniverse->FindExtension(GameFile.GetAdventure(), 0, &pAdventure))
		{
		//	Adventure icon

		CG16bitImage *pIcon;
		pAdventure->CreateIcon(ADVENTURE_ICON_WIDTH, ADVENTURE_ICON_HEIGHT, &pIcon);

		if (pIcon)
			{
			int xOffset = (ADVENTURE_ICON_WIDTH - pIcon->GetWidth()) / 2;
			IAnimatron *pIconAni = new CAniRect;
			pIconAni->SetPropertyVector(PROP_POSITION, CVector(x + xOffset, 0));
			pIconAni->SetPropertyVector(PROP_SCALE, CVector(pIcon->GetWidth(), pIcon->GetHeight()));
			pIconAni->SetFillMethod(new CAniImageFill(pIcon, true));

			pRoot->AddTrack(pIconAni, 0);

			bHasAdventureIcon = true;
			}

		//	Adventure name

		pName = new CAniText;
		pName->SetPropertyVector(PROP_POSITION, CVector(xText, y));
		pName->SetPropertyVector(PROP_SCALE, CVector(10000, 1000));
		pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
		pName->SetPropertyFont(PROP_FONT, &MediumFont);
		pName->SetPropertyString(PROP_TEXT, pAdventure->GetName());

		pRoot->AddTrack(pName, 0);
		y += MediumFont.GetHeight();
		}

	//	Create an image of the ship class

	if (pClass)
		{
		const CObjectImageArray &ObjImage = pClass->GetImage();
		if (!ObjImage.IsEmpty())
			{
			RECT rcRect = ObjImage.GetImageRect();
			CG16bitImage &Image = ObjImage.GetImage(NULL_STR);
			int cxImage = RectWidth(rcRect);
			int cyImage = RectHeight(rcRect);

			int cxNewWidth = Min(SHIP_IMAGE_WIDTH, cxImage);
			int cyNewHeight = cxNewWidth;

			CG16bitImage *pNewImage = new CG16bitImage;
			pNewImage->CreateFromImageTransformed(Image, 
					rcRect.left, 
					rcRect.top, 
					cxImage,
					cyImage,
					(Metric)cxNewWidth / cxImage,
					(Metric)cyNewHeight / cyImage,
					0.0);

			//	Position

			int xImage = x + m_cxWidth - SHIP_IMAGE_WIDTH + (SHIP_IMAGE_WIDTH - cxNewWidth) / 2;
			int yImage = (SHIP_IMAGE_HEIGHT - cyNewHeight) / 2;

			//	New image frame

			IAnimatron *pImageFrame = new CAniRect;
			pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xImage, yImage));
			pImageFrame->SetPropertyVector(PROP_SCALE, CVector(cxNewWidth, cyNewHeight));
			pImageFrame->SetFillMethod(new CAniImageFill(pNewImage, true));

			pRoot->AddTrack(pImageFrame, 0);
			}
		}

	//	Extra information

	CString sEpitaph = GameFile.GetEpitaph();
	int iScore = GameFile.GetScore();
	CTimeDate LocalTime = ModifiedTime.ToLocalTime();
	CString sModifiedTime = LocalTime.Format("%d %B %Y %I:%M %p");
	CString sFilename = pathGetFilename(GameFile.GetFilespec());

	CString sGameType;
	if (GameFile.IsRegistered())
		sGameType = CONSTLIT("Registered");
	else if (GameFile.IsDebug())
		sGameType = CONSTLIT("Debug");
	else
		sGameType = CONSTLIT("Unregistered");

	CString sExtra;
	if (!sEpitaph.IsBlank())
		sExtra = strPatternSubst(CONSTLIT("Score %d — %s\n%s — %s — %s"), iScore, sEpitaph, sGameType, sModifiedTime, sFilename);
	else if (iScore > 0)
		sExtra = strPatternSubst(CONSTLIT("Score %d\n%s — %s — %s"), iScore, sGameType, sModifiedTime, sFilename);
	else
		sExtra = strPatternSubst(CONSTLIT("%s — %s — %s"), sGameType, sModifiedTime, sFilename);

	pDesc = new CAniText;
	pDesc->SetPropertyVector(PROP_POSITION, CVector(xText, y));
	pDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pDesc->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
	pDesc->SetPropertyFont(PROP_FONT, &MediumFont);
	pDesc->SetPropertyString(PROP_TEXT, sExtra);

	pDesc->GetSpacingRect(&rcLine);

	pRoot->AddTrack(pDesc, 0);
	y += RectHeight(rcLine);

	//	Done

	*retpEntry = pRoot;

	if (retcyHeight)
		*retcyHeight = (bHasAdventureIcon ? Max(ADVENTURE_ICON_HEIGHT, y) : y);
	}
Пример #5
0
void DrawAlphaGradientCircle (CG16bitImage &Dest,
                              int xDest,
                              int yDest,
                              int iRadius,
                              WORD wColor)

//	DrawAlphaGradientCircle
//
//	Draws a filled circle of the given color. The circle has an alpha gradient
//	that ranges from fully opaque in the center to fully transparent at the edges.

{
    //	Deal with edge-conditions

    if (iRadius <= 0)
    {
        Dest.DrawPixel(xDest, yDest, wColor);
        return;
    }

    //	Initialize some stuff

    int x = 0;
    int y = iRadius;
    int d = 1 - iRadius;
    int deltaE = 3;
    int deltaSE = -2 * iRadius + 5;

    //	Prepare struct

    SAlphaGradientCircleLineCtx Ctx;
    Ctx.pDest = &Dest;
    Ctx.xDest = xDest;
    Ctx.yDest = yDest;
    Ctx.iRadius = iRadius;
    Ctx.wColor = wColor;

    //	Pre-compute some color info

    DWORD dwColor = wColor;
    Ctx.dwRed = (dwColor >> 11) & 0x1f;
    Ctx.dwGreen = (dwColor >> 5) & 0x3f;
    Ctx.dwBlue = dwColor & 0x1f;

    //	Draw central line

    DrawAlphaGradientCircleLine(Ctx, iRadius, 0);

    //	Draw lines above and below the center

    int iLastDraw = -1;
    while (y > x)
    {
        if (d < 0)
        {
            d += deltaE;
            deltaE += 2;
            deltaSE += 2;
        }
        else
        {
            d += deltaSE;
            deltaE += 2;
            deltaSE += 4;

            //	Draw lines

            DrawAlphaGradientCircleLine(Ctx, x, y);
            iLastDraw = y;

            //	Next

            y--;
        }

        x++;

        //	Draw lines

        if (x != iLastDraw)
            DrawAlphaGradientCircleLine(Ctx, y, x);
    }
}
void CCompositeEntry::GetImage (const CCompositeImageSelector &Selector, CObjectImageArray *retImage)

//	GetImage
//
//	Fills in the image

	{
	int i;

	//	Null case

	if (m_Layers.GetCount() == 0)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Get all the layers

	TArray<CObjectImageArray> Result;
	Result.InsertEmpty(m_Layers.GetCount());
	for (i = 0; i < m_Layers.GetCount(); i++)
		m_Layers[i]->GetImage(Selector, &Result[i]);

	//	Create the composited image
	//
	//	First we need to determine the size of the final image, based
	//	on the size and position of each layer.

	int xMin = 0;
	int xMax = 0;
	int yMin = 0;
	int yMax = 0;

	for (i = 0; i < m_Layers.GetCount(); i++)
		{
		CObjectImageArray &LayerImage = Result[i];
		const RECT &rcRect = LayerImage.GetImageRect();

		int xImageOffset = 0;
		int yImageOffset = 0;

		int xMaxImage = (RectWidth(rcRect) / 2) + xImageOffset;
		int xMinImage = xMaxImage - RectWidth(rcRect);
		int yMaxImage = (RectHeight(rcRect) / 2) + yImageOffset;
		int yMinImage = yMaxImage - RectHeight(rcRect);

		xMin = Min(xMin, xMinImage);
		xMax = Max(xMax, xMaxImage);
		yMin = Min(yMin, yMinImage);
		yMax = Max(yMax, yMaxImage);
		}

	//	Create destination image

	int cxWidth = xMax - xMin;
	int cyHeight = yMax - yMin;
	if (cxWidth <= 0 || cyHeight <= 0)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	CG16bitImage *pComp = new CG16bitImage;
	pComp->CreateBlank(cxWidth, cyHeight, false);
	pComp->SetTransparentColor();

	int xCenter = cxWidth / 2;
	int yCenter = cyHeight / 2;

	//	Blt on the destination

	for (i = 0; i < m_Layers.GetCount(); i++)
		{
		CObjectImageArray &LayerImage = Result[i];
		const RECT &rcRect = LayerImage.GetImageRect();

		//	Paint the image

		LayerImage.PaintImage(*pComp,
				xCenter,
				yCenter,
				0,
				0);
		}

	//	Initialize an image

	RECT rcFinalRect;
	rcFinalRect.left = 0;
	rcFinalRect.top = 0;
	rcFinalRect.right = cxWidth;
	rcFinalRect.bottom = cyHeight;

	CObjectImageArray Comp;
	Comp.Init(pComp, rcFinalRect, 0, 0, true);

	//	Done

	retImage->TakeHandoff(Comp);
	}
Пример #7
0
void GenerateTopologyMap (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i, j;

	STopologyMapCtx Ctx;

	//	Initialize the output

	COutputChart Output;
	Output.SetStyleFont(STYLE_NAME, pCmdLine->GetAttribute(CONSTLIT("font")));
	Output.SetStyleColor(STYLE_NAME, CG16bitImage::RGBValue(0xFF, 0xFF, 0xFF));

	Output.SetOutputFilespec(pCmdLine->GetAttribute(CONSTLIT("output")));

	//	Get the topology node

	CTopologyNode *pFirstNode = Universe.GetFirstTopologyNode();
	if (pFirstNode == NULL)
		{
		printf("ERROR: Unable to find topology node.\n");
		return;
		}

	//	Get the system map for the node

	Ctx.pMap = pFirstNode->GetDisplayPos();
	if (Ctx.pMap == NULL)
		{
		printf("ERROR: No system map for node %s.\n", pFirstNode->GetID().GetASCIIZPointer());
		return;
		}

	//	Create a background image

	CG16bitImage *pImage = Ctx.pMap->CreateBackgroundImage();

	//	Create the output

	Output.SetContentSize((pImage ? pImage->GetWidth() : 1024), (pImage ? pImage->GetHeight() : 1024));
	CG16bitImage &Dest = Output.GetOutputImage();

	//	Blt

	if (pImage)
		Dest.Blt(0, 0, pImage->GetWidth(), pImage->GetHeight(), *pImage, 0, 0);

	//	Done with background image

	delete pImage;
	pImage = NULL;

	//	Compute the size of the map (in pixels)

	Ctx.cxMap = Dest.GetWidth();
	Ctx.cyMap = Dest.GetHeight();
	Ctx.xCenter = Ctx.cxMap / 2;
	Ctx.yCenter = Ctx.cyMap / 2;

	//	Loop over all nodes and clear marks on the ones that we need to draw

	for (i = 0; i < Universe.GetTopologyNodeCount(); i++)
		{
		CTopologyNode *pNode = Universe.GetTopologyNode(i);
			
		int xPos, yPos;
		pNode->SetMarked(pNode->GetDisplayPos(&xPos, &yPos) != Ctx.pMap 
				|| pNode->IsEndGame());
		}

	//	Paint the nodes

	for (i = 0; i < Universe.GetTopologyNodeCount(); i++)
		{
		CTopologyNode *pNode = Universe.GetTopologyNode(i);
		if (!pNode->IsMarked())
			{
			int xPos, yPos;
			pNode->GetDisplayPos(&xPos, &yPos);

			//	Convert to view coordinates

			int x = Ctx.xCenter + xPos;
			int y = Ctx.yCenter - yPos;

			//	Draw gate connections

			for (j = 0; j < pNode->GetStargateCount(); j++)
				{
				CTopologyNode *pDestNode = pNode->GetStargateDest(j);
				if (pDestNode && !pDestNode->IsMarked())
					{
					int xPos, yPos;
					pDestNode->GetDisplayPos(&xPos, &yPos);

					int xDest = Ctx.xCenter + xPos;
					int yDest = Ctx.yCenter - yPos;

					Dest.DrawLine(x, y, xDest, yDest, STARGATE_LINE_WIDTH, STARGATE_LINE_COLOR);
					}
				}

			//	Draw star system

			DrawNode(Ctx, Output, pNode, x, y);

			pNode->SetMarked();
			}
		}

	//	Done

	Output.Output();
	}
Пример #8
0
void CUIHelper::CreateClassInfoSpecialItem (CItemType *pItemIcon, const CString &sText, int x, int y, int cxWidth, DWORD dwOptions, int *retcyHeight, IAnimatron **retpInfo) const

//	CreateClassInfoSpecialItem
//
//	Creates a special item info animation

	{
	const CVisualPalette &VI = m_HI.GetVisuals();

	//	Figure out some dimensions and metrics. Everything is relative to x, y.

	bool bRightAlign = ((dwOptions & OPTION_ITEM_RIGHT_ALIGN) ? true : false);
	int cxIcon = SMALL_ICON_WIDTH;
	int cyIcon = SMALL_ICON_HEIGHT;
	int xIcon = (bRightAlign ? -cxIcon : 0);
	int yIcon = 0;

	int cxText = cxWidth - (cxIcon + ITEM_INFO_SPACING_HORZ);
	int xText = (bRightAlign ? -cxWidth : cxIcon + ITEM_INFO_SPACING_HORZ);
	int yText = 0;

	//	Create a sequencer to hold all the controls

	CAniSequencer *pRoot;
	CAniSequencer::Create(CVector(x, y), &pRoot);

	//	Create a small item icon

	if (pItemIcon)
		{
		const CObjectImageArray &Image = pItemIcon->GetImage();
		RECT rcImage = Image.GetImageRect();
		if (!Image.IsEmpty())
			{
			CG16bitImage *pIcon = new CG16bitImage;
			pIcon->CreateFromImageTransformed(Image.GetImage(), 
					rcImage.left, 
					rcImage.top, 
					RectWidth(rcImage), 
					RectHeight(rcImage), 
					(Metric)SMALL_ICON_WIDTH / RectWidth(rcImage),
					(Metric)SMALL_ICON_HEIGHT / RectHeight(rcImage),
					0.0);

			IAnimatron *pImageFrame = new CAniRect;
			pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xIcon, yIcon));
			pImageFrame->SetPropertyVector(PROP_SCALE, CVector(SMALL_ICON_WIDTH, SMALL_ICON_HEIGHT));
			pImageFrame->SetFillMethod(new CAniImageFill(pIcon, true));

			pRoot->AddTrack(pImageFrame, 0);
			}
		}

	//	Create some text

	int cyText = 0;

	IAnimatron *pRef = new CAniRichText(VI);
	pRef->SetPropertyVector(PROP_POSITION, CVector(xText, yText + cyText));
	pRef->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pRef->SetPropertyString(PROP_TEXT, sText);
	if (bRightAlign)
		pRef->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_RIGHT);

	pRoot->AddTrack(pRef, 0);

	RECT rcRef;
	pRef->GetSpacingRect(&rcRef);
	cyText += RectHeight(rcRef);

	//	Done

	if (retcyHeight)
		*retcyHeight = Max(cyText, SMALL_ICON_HEIGHT);

	*retpInfo = pRoot;
	}
Пример #9
0
void DrawNebulosity8bit (CG16bitImage &Dest, int x, int y, int cxWidth, int cyHeight, int iScale, BYTE byMin, BYTE byMax)

//	DrawNebulosity8bit
//
//	Draws 8-bit clouds.

	{
	int i;

	ASSERT(iScale > 0);

	NoiseInit();

	//	Make sure we're in bounds

	if (!Dest.HasAlpha() || !Dest.AdjustCoords(NULL, NULL, 0, 0, 
			&x, &y, 
			&cxWidth, &cyHeight))
		return;

	//	We need noise generators for each frequency

	struct SFreq
		{
		int iFreq;
		float Amplitude;
		CNoiseGenerator *pNoise;
		SNoisePos x;
		SNoisePos y;
		};

	TArray<SFreq> FreqList;

	//	At iMinFreq = 1 we create detail all the way to the pixel level.

	int iMinFreq = 1;//Max(iScale / 256, 1);

	//	In theory, the noise function returns values from -1.0 to 1.0, but
	//	in practice the values are clutered between -0.5 to 0.5. We multiply
	//	the result by this amplitude adjustment so that we get a greater
	//	dynamic range.

	float rAmplitudeAdj = 2.0f;

	//	As we get to smaller and smaller detail, the amplitude decreases
	//	(by half for each frequency). But if there are too many levels of
	//	detail, the amplitude decreases so much that it is invisible.
	//	Thus we have a minimum amplitude.

	float rMinAmplitude = (float)iScale / 32.0f;

	//	Create noise generators are each frequency.

	float rMaxValue = 0.0;
	int iFreq = iScale;
	while (iFreq >= iMinFreq)
		{
		SFreq *pFreq = FreqList.Insert();

		pFreq->iFreq = iFreq;
		pFreq->pNoise = new CNoiseGenerator(iFreq);
		pFreq->Amplitude = rAmplitudeAdj * Max((float)iFreq, rMinAmplitude);

		rMaxValue += (pFreq->Amplitude / rAmplitudeAdj);

		iFreq = iFreq / 2;
		};

	//	Compute the factor to adjust the pixel value

	float rRange = (float)(byMax - byMin) + 0.99999f;
	float rFactor = rRange / (2.0f * rMaxValue);

	int iFreqCount = FreqList.GetCount();

	//	Fill

	for (i = 0; i < iFreqCount; i++)
		FreqList[i].pNoise->Reset(FreqList[i].y, y);

	BYTE *pRow = Dest.GetAlphaRow(y);
	BYTE *pRowEnd = Dest.GetAlphaRow(y + cyHeight);
	while (pRow < pRowEnd)
		{
		for (i = 0; i < iFreqCount; i++)
			FreqList[i].pNoise->Reset(FreqList[i].x, x);

		BYTE *pPos = pRow;
		BYTE *pPosEnd = pRow + cxWidth;
		while (pPos < pPosEnd)
			{
			float rValue = rMaxValue;
			for (i = 0; i < iFreqCount; i++)
				{
				SFreq *pFreq = &FreqList[i];
				rValue += pFreq->pNoise->GetAt(pFreq->x, pFreq->y) * pFreq->Amplitude;

				pFreq->pNoise->Next(pFreq->x);
				}

			*pPos = (BYTE)Clamp((DWORD)byMin + (DWORD)(rFactor * rValue), (DWORD)byMin, (DWORD)byMax);

			//	Next pixel

			pPos++;
			}

		//	Next row

		pRow = Dest.NextAlphaRow(pRow);
		for (i = 0; i < iFreqCount; i++)
			FreqList[i].pNoise->Next(FreqList[i].y);
		}

	//	Free the noise generators

	for (i = 0; i < iFreqCount; i++)
		delete FreqList[i].pNoise;
	}
Пример #10
0
void GenerateShipImageChart (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i;

	enum OrderTypes
		{
		orderSmallest = 1,
		orderLargest = 2,
		orderName = 3,
		};

	//	Options

	bool bTextBoxesOnly = pCmdLine->GetAttributeBool(CONSTLIT("textBoxesOnly"));

	//	Figure out what order we want

	CString sOrder = pCmdLine->GetAttribute(CONSTLIT("sort"));
	int iOrder;
	if (strEquals(sOrder, CONSTLIT("smallest")))
		iOrder = orderSmallest;
	else if (strEquals(sOrder, CONSTLIT("largest")))
		iOrder = orderLargest;
	else
		iOrder = orderName;

	//	Image size

	int cxDesiredWidth;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("width"), &cxDesiredWidth))
		cxDesiredWidth = Max(512, cxDesiredWidth);
	else
		cxDesiredWidth = 1280;

	//	Spacing

	int cxSpacing = pCmdLine->GetAttributeInteger(CONSTLIT("xSpacing"));
	int cxExtraMargin = pCmdLine->GetAttributeInteger(CONSTLIT("xMargin"));

	//	Rotation

	int iRotation = pCmdLine->GetAttributeInteger(CONSTLIT("rotation"));

	//	Font for text

	CString sTypeface;
	int iSize;
	bool bBold;
	bool bItalic;

	if (!CG16bitFont::ParseFontDesc(pCmdLine->GetAttribute(CONSTLIT("font")),
			&sTypeface,
			&iSize,
			&bBold,
			&bItalic))
		{
		sTypeface = CONSTLIT("Arial");
		iSize = 10;
		bBold = false;
		bItalic = false;
		}

	CG16bitFont NameFont;
	NameFont.Create(sTypeface, -PointsToPixels(iSize), bBold, bItalic);
	WORD wNameColor = CG16bitImage::RGBValue(255, 255, 255);

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

	//	Generate a table of ships

	CSymbolTable Table(FALSE, TRUE);
	for (i = 0; i < Universe.GetShipClassCount(); i++)
		{
		CShipClass *pClass = Universe.GetShipClass(i);

		//	Skip player ship classes

		if (pClass->GetPlayerSettings())
			continue;

		//	Skip non-generic classes

		if (!pClass->HasAttribute(CONSTLIT("genericClass")))
			continue;

		//	Compute the sort key

		char szBuffer[1024];
		switch (iOrder)
			{
			case orderLargest:
				wsprintf(szBuffer, "%04d%s%x",
						2048 - RectWidth(pClass->GetImage().GetImageRect()),
						pClass->GetName().GetASCIIZPointer(),
						pClass);
				break;

			case orderSmallest:
				wsprintf(szBuffer, "%04d%s%x",
						RectWidth(pClass->GetImage().GetImageRect()),
						pClass->GetName().GetASCIIZPointer(),
						pClass);
				break;

			default:
				wsprintf(szBuffer, "%s%x", pClass->GetName().GetASCIIZPointer(), pClass);
				break;
			}

		//	Add to list

		Table.AddEntry(CString(szBuffer), (CObject *)pClass);
		}

	//	Allocate a map that tracks where to paint each ship

	CPaintMap Map(Table.GetCount());

	//	Arrange the ships

	SArrangeDesc Desc;
	Desc.cxDesiredWidth = Max(512, cxDesiredWidth - (2 * (cxSpacing + cxExtraMargin)));
	Desc.cxSpacing = cxSpacing;
	Desc.cxExtraMargin = cxExtraMargin;
	Desc.pHeader = &NameFont;

	ArrangeByRow(Table, Desc, Map);
	//ArrangeByCell(Table, cxDesiredWidth, Map);

	//	Create a large image

	CG16bitImage Output;
	int cxWidth = Max(cxDesiredWidth, Map.GetWidth());
	int cyHeight = Map.GetHeight();
	Output.CreateBlank(cxWidth, cyHeight, false);
	printf("Creating %dx%d image.\n", cxWidth, cyHeight);

	//	Paint the images

	for (i = 0; i < Table.GetCount(); i++)
		{
		CShipClass *pClass = (CShipClass *)Table.GetValue(i);

		int x = Map.GetX(i);
		int y = Map.GetY(i);
		if (x != -1)
			{
			if (!bTextBoxesOnly)
				pClass->GetImage().PaintImageUL(Output,
						x,
						y,
						0,
						Angle2Direction(iRotation));

			//	Paint name

			int xText = Map.GetTextX(i);
			int yText = Map.GetTextY(i);
			if (xText != -1)
				{
				if (bTextBoxesOnly)
					Output.Fill(xText, yText, Map.GetTextWidth(i), Map.GetTextHeight(i), 0xffff);

				if (!bTextBoxesOnly)
					{
					Output.FillColumn(x + (Map.GetWidth(i) / 2),
							y + Map.GetHeight(i),
							yText - (y + Map.GetHeight(i)),
							wNameColor);

					NameFont.DrawText(Output,
							xText,
							yText,
							wNameColor,
							255,
							pClass->GetNounPhrase(0));
					}
				}
			}
		}

	//	Write to file or clipboard

	OutputImage(Output, sFilespec);
	}
Пример #11
0
void CUIHelper::CreateClassInfoItem (const CItem &Item, int x, int y, int cxWidth, DWORD dwOptions, const CString &sExtraDesc, int *retcyHeight, IAnimatron **retpInfo) const

//	CreateClassInfoItem
//
//	Creates an item info animation

	{
	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &MediumFont = VI.GetFont(fontMedium);
	const CG16bitFont &MediumBoldFont = VI.GetFont(fontMediumBold);
	const CG16bitFont &SubTitleFont = VI.GetFont(fontSubTitle);

	//	Handle some edge conditions

	CItemType *pType = Item.GetType();
	if (pType == NULL)
		{
		if (retcyHeight)
			*retcyHeight = 0;

		CAniSequencer::Create(CVector(x, y), (CAniSequencer **)retpInfo);
		return;
		}

	//	Figure out some dimensions and metrics. Everything is relative to x, y.

	bool bRightAlign = ((dwOptions & OPTION_ITEM_RIGHT_ALIGN) ? true : false);
	int cxIcon = SMALL_ICON_WIDTH;
	int cyIcon = SMALL_ICON_HEIGHT;
	int xIcon = (bRightAlign ? -cxIcon : 0);
	int yIcon = 0;

	int cxText = cxWidth - (cxIcon + ITEM_INFO_SPACING_HORZ);
	int xText = (bRightAlign ? -cxWidth : cxIcon + ITEM_INFO_SPACING_HORZ);
	int yText = 0;

	//	Create a sequencer to hold all the controls

	CAniSequencer *pRoot;
	CAniSequencer::Create(CVector(x, y), &pRoot);

	//	Create a small item icon

	const CObjectImageArray &Image = pType->GetImage();
	RECT rcImage = Image.GetImageRect();
	if (!Image.IsEmpty())
		{
		CG16bitImage *pIcon = new CG16bitImage;
		pIcon->CreateFromImageTransformed(Image.GetImage(), 
				rcImage.left, 
				rcImage.top, 
				RectWidth(rcImage), 
				RectHeight(rcImage), 
				(Metric)SMALL_ICON_WIDTH / RectWidth(rcImage),
				(Metric)SMALL_ICON_HEIGHT / RectHeight(rcImage),
				0.0);

		IAnimatron *pImageFrame = new CAniRect;
		pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xIcon, yIcon));
		pImageFrame->SetPropertyVector(PROP_SCALE, CVector(SMALL_ICON_WIDTH, SMALL_ICON_HEIGHT));
		pImageFrame->SetFillMethod(new CAniImageFill(pIcon, true));

		pRoot->AddTrack(pImageFrame, 0);
		}

	//	Create text

	int cyText = 0;

	IAnimatron *pName = new CAniText;
	pName->SetPropertyVector(PROP_POSITION, CVector(xText, yText + cyText));
	pName->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pName->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogInput));
	pName->SetPropertyFont(PROP_FONT, &MediumBoldFont);
	pName->SetPropertyString(PROP_TEXT, pType->GetNounPhrase(nounActual));
	if (bRightAlign)
		pName->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_RIGHT);

	pRoot->AddTrack(pName, 0);
	cyText += MediumBoldFont.GetHeight();

	//	Add the damage type adjustment

	CItemDataAnimatron *pDamageDesc = new CItemDataAnimatron(VI, Item);
	if (!pDamageDesc->IsEmpty())
		{
		pDamageDesc->SetPropertyVector(PROP_POSITION, CVector(xText, yText + cyText));
		pDamageDesc->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
		if (bRightAlign)
			pDamageDesc->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_RIGHT);

		pRoot->AddTrack(pDamageDesc, 0);

		RECT rcRect;
		pDamageDesc->GetSpacingRect(&rcRect);
		cyText += RectHeight(rcRect);
		}
	else
		delete pDamageDesc;

	//	Add the reference text

	CItemCtx ItemCtx;
	CString sRef = pType->GetReference(ItemCtx, -1, CItemType::FLAG_ACTUAL_ITEM);
	if (sRef.IsBlank())
		sRef = strPatternSubst(CONSTLIT("Level %s%s"), strLevel(pType->GetLevel()), sExtraDesc);
	else
		sRef = strPatternSubst(CONSTLIT("Level %s — %s%s"), strLevel(pType->GetLevel()), sRef, sExtraDesc);

	IAnimatron *pRef = new CAniText;
	pRef->SetPropertyVector(PROP_POSITION, CVector(xText, yText + cyText));
	pRef->SetPropertyVector(PROP_SCALE, CVector(cxText, 1000));
	pRef->SetPropertyColor(PROP_COLOR, VI.GetColor(colorTextDialogLabel));
	pRef->SetPropertyFont(PROP_FONT, &MediumFont);
	pRef->SetPropertyString(PROP_TEXT, sRef);
	if (bRightAlign)
		pRef->SetPropertyString(PROP_TEXT_ALIGN_HORZ, ALIGN_RIGHT);

	pRoot->AddTrack(pRef, 0);

	RECT rcRef;
	pRef->GetSpacingRect(&rcRef);
	cyText += RectHeight(rcRef);

	//	Done

	if (retcyHeight)
		*retcyHeight = Max(cyText, SMALL_ICON_HEIGHT);

	*retpInfo = pRoot;
	}
Пример #12
0
void CNewGameSession::SetShipClassImage (CShipClass *pClass, int x, int y, int cxWidth)

//	SetShipClassImage
//
//	Sets the current ship class image

	{
	const CPlayerSettings *pPlayerSettings = pClass->GetPlayerSettings();
	const CG16bitImage *pImage = g_pUniverse->GetLibraryBitmap(pPlayerSettings->GetLargeImage());

	//	Delete the previous one

	DeleteElement(ID_SHIP_CLASS_IMAGE);

	//	Add the new one, if we've got one.

	const CG16bitImage *pImageToUse = NULL;
	bool bFree = false;

	if (pImage && !pImage->IsEmpty())
		{
		//	If this image is not the right size, then create a resized version
		//	that is.

		if (pImage->GetWidth() != SHIP_IMAGE_WIDTH || pImage->GetHeight() != SHIP_IMAGE_HEIGHT)
			{
			int cxNewWidth = SHIP_IMAGE_WIDTH;
			int cyNewHeight = cxNewWidth * pImage->GetHeight() / pImage->GetWidth();
			if (cyNewHeight > SHIP_IMAGE_HEIGHT)
				{
				cyNewHeight = SHIP_IMAGE_HEIGHT;
				cxNewWidth = cyNewHeight * pImage->GetWidth() / pImage->GetHeight();
				}

			CG16bitImage *pNewImage = new CG16bitImage;
			pNewImage->CreateFromImageTransformed(*pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight(), (Metric)cxNewWidth / pImage->GetWidth(), (Metric)cyNewHeight / pImage->GetHeight(), 0.0);

			pImageToUse = pNewImage;
			bFree = true;
			}
		else
			{
			pImageToUse = pImage;
			bFree = false;
			}
		}

	//	If we don't have an image then ask the class to paint it

	else
		{
		CG16bitImage *pNewImage = new CG16bitImage;
		pNewImage->CreateBlank(SHIP_IMAGE_WIDTH, SHIP_IMAGE_HEIGHT, false);


		ViewportTransform Trans;
		pClass->Paint(*pNewImage, 
				SHIP_IMAGE_WIDTH / 2, 
				SHIP_IMAGE_HEIGHT / 2, 
				Trans, 
				0, 
				0,
				false,
				false
				);

		pImageToUse = pNewImage;
		bFree = true;
		}

	//	Position

	int xImage = x + (cxWidth - pImageToUse->GetWidth()) / 2;
	int yImage = y + (SHIP_IMAGE_HEIGHT - pImageToUse->GetHeight()) / 2;

	//	New image frame

	IAnimatron *pImageFrame = new CAniRect;
	pImageFrame->SetID(ID_SHIP_CLASS_IMAGE);
	pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xImage, yImage));
	pImageFrame->SetPropertyVector(PROP_SCALE, CVector(pImageToUse->GetWidth(), pImageToUse->GetHeight()));
	pImageFrame->SetFillMethod(new CAniImageFill(pImageToUse, bFree));

	m_pRoot->AddLine(pImageFrame);
	}
Пример #13
0
void AGScreen::Paint (CG16bitImage &Dest)

//	Paint
//
//	Paint the whole screen.
//
//	Dest is the entire display area; its origin is 0,0.

	{
	if (!IsRectEmpty(&m_rcInvalid))
		{
		int i;

		//	Convert to Window coordinates

		RECT rcUpdate = m_rcInvalid;
		OffsetRect(&rcUpdate, m_rcRect.left, m_rcRect.top);

		//	Clip appropriately. Note that Dest is always in
		//	window coordinates.

		Dest.SetClipRect(rcUpdate);

		//	Blank the screen

		Dest.Fill(rcUpdate.left, rcUpdate.top, RectWidth(rcUpdate), RectHeight(rcUpdate), CG16bitImage::RGBValue(0,0,0));

		//	Let each area paint

		for (i = 0; i < GetAreaCount(); i++)
			{
			AGArea *pArea = GetArea(i);

			//	m_rcInvalid is in Screen coordinates, and so is the rect
			//	for each area. The intersection is the portion of the
			//	area's rect that is invalid.

			RECT rcIntersect;
			if (pArea->IsVisible()
					&& ::IntersectRect(&rcIntersect, &m_rcInvalid, &pArea->GetRect()))
				{
				//	Calculate the rect of the area relative to the Window

				RECT rcArea = pArea->GetRect();
				OffsetRect(&rcArea, m_rcRect.left, m_rcRect.top);

				//	Clip appropriately

				OffsetRect(&rcIntersect, m_rcRect.left, m_rcRect.top);
				Dest.SetClipRect(rcIntersect);

				//	Paint

				pArea->Paint(Dest, rcArea);
				}
			}

		//	Reset the invalid rect

		memset(&m_rcInvalid, 0, sizeof(m_rcInvalid));
		Dest.ResetClipRect();
		}
	}
void CFilterColorizeEntry::GetImage (const CCompositeImageSelector &Selector, CObjectImageArray *retImage)

//	GetImage
//
//	Fills in the image

	{
	//	Null case

	if (m_pSource == NULL)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Get the source image (which we want to colorize)

	CObjectImageArray Source;
	m_pSource->GetImage(Selector, &Source);
	const RECT &rcSource = Source.GetImageRect();
	CG16bitImage &SourceImage = Source.GetImage(NULL_STR);
	int cxWidth = RectWidth(rcSource);
	int cyHeight = RectHeight(rcSource);
	if (Source.IsEmpty() || cxWidth == 0 || cyHeight == 0)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Create the destination image

	CG16bitImage *pDest = new CG16bitImage;
	pDest->CreateBlank(cxWidth, cyHeight, SourceImage.HasAlpha());
	if (!SourceImage.HasAlpha())
		pDest->SetTransparentColor();

	//	Blt the to the destination with colorization

	CopyBltColorize(*pDest,
			0,
			0,
			cxWidth,
			cyHeight,
			SourceImage,
			rcSource.left,
			rcSource.top,
			m_dwHue,
			m_dwSaturation);

	//	Initialize an image

	RECT rcFinalRect;
	rcFinalRect.left = 0;
	rcFinalRect.top = 0;
	rcFinalRect.right = cxWidth;
	rcFinalRect.bottom = cyHeight;

	CObjectImageArray Comp;
	Comp.Init(pDest, rcFinalRect, 0, 0, true);

	//	Done

	retImage->TakeHandoff(Comp);
	}
Пример #15
0
void CParticleEffect::PaintSmokeParticles (SParticleArray *pGroup, CG16bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx)

//	PaintSmokeParticles
//
//	Paint particles as smoke

	{
	SParticleType *pType = pGroup->pType;
	SParticle *pParticle = pGroup->pParticles;
	SParticle *pEnd = pParticle + pGroup->iCount;
	while (pParticle < pEnd)
		{
		if (pParticle->IsValid())
			{
			//	Compute color

			int iColor = 64 + (pParticle->iDestiny % 192);
			WORD wColor = CG16bitImage::RGBValue(iColor, iColor, iColor);

			//	Compute how much to fade out the smoke

			int iFade = 0;
			int iSize = 0;
			if (pType->iLifespan)
				{
				iFade = 255 * pParticle->iLifeLeft / pType->iLifespan;
				iSize = 5 - (5 * pParticle->iLifeLeft /  pType->iLifespan);
				}

			int iFade2 = iFade / 2;

			//	Compute the position

			int x, y;
			Ctx.XForm.Transform(GetPos() + pParticle->vPos, &x, &y);

			//	Paint

			switch (iSize)
				{
				case 0:
					Dest.DrawPixelTrans(x, y, wColor, iFade);
					break;

				case 1:
					Dest.DrawPixelTrans(x, y, wColor, iFade);
					Dest.DrawPixelTrans(x + 1, y, wColor, iFade2);
					Dest.DrawPixelTrans(x, y + 1, wColor, iFade2);
					break;

				case 2:
					Dest.DrawPixelTrans(x, y, wColor, iFade);
					Dest.DrawPixelTrans(x + 1, y, wColor, iFade2);
					Dest.DrawPixelTrans(x, y + 1, wColor, iFade2);
					Dest.DrawPixelTrans(x - 1, y, wColor, iFade2);
					Dest.DrawPixelTrans(x, y - 1, wColor, iFade2);
					break;

				case 3:
					Dest.DrawPixelTrans(x, y, wColor, iFade);
					Dest.DrawPixelTrans(x + 1, y, wColor, iFade);
					Dest.DrawPixelTrans(x, y + 1, wColor, iFade);
					Dest.DrawPixelTrans(x - 1, y, wColor, iFade);
					Dest.DrawPixelTrans(x, y - 1, wColor, iFade);
					Dest.DrawPixelTrans(x + 1, y + 1, wColor, iFade2);
					Dest.DrawPixelTrans(x + 1, y - 1, wColor, iFade2);
					Dest.DrawPixelTrans(x - 1, y + 1, wColor, iFade2);
					Dest.DrawPixelTrans(x - 1, y - 1, wColor, iFade2);
					break;

				case 4:
				default:
					{
					Dest.FillTransRGB(x - 1,
							y - 1,
							3,
							3,
							RGB(192, 192, 192),
							iFade);

					Dest.DrawPixelTrans(x + 2, y, wColor, iFade2);
					Dest.DrawPixelTrans(x, y + 2, wColor, iFade2);
					Dest.DrawPixelTrans(x - 2, y, wColor, iFade2);
					Dest.DrawPixelTrans(x, y - 2, wColor, iFade2);
					}
				}
			}

		pParticle++;
		}
	}
Пример #16
0
CG16bitImage *CSystemMap::CreateBackgroundImage (void)

//	CreateBackgroundImage
//
//	Creates an image containing the map.
//	Caller is responsible for freeing the returned image.

	{
	int i;

	CG16bitImage *pImage = g_pUniverse->GetLibraryBitmapCopy(m_dwBackgroundImage);
	if (pImage == NULL)
		return NULL;

	int xCenter = pImage->GetWidth() / 2;
	int yCenter = pImage->GetHeight() / 2;

	//	Paint all annotations

	if (m_Annotations.GetCount() > 0)
		{
		SViewportPaintCtx Ctx;

		for (i = 0; i < m_Annotations.GetCount(); i++)
			{
			SMapAnnotation *pAnnotation = &m_Annotations[i];

			Ctx.iTick = pAnnotation->iTick;
			Ctx.iRotation = pAnnotation->iRotation;

			pAnnotation->pPainter->Paint(*pImage, xCenter + pAnnotation->xOffset, yCenter - pAnnotation->yOffset, Ctx);
			}
		}

#ifdef DEBUG
#if 0
	//	Test noise function
	CG16bitImage Alpha;
	Alpha.CreateBlankAlpha(pImage->GetWidth(), pImage->GetHeight());
	DrawNebulosity8bit(Alpha, 0, 0, pImage->GetWidth(), pImage->GetHeight(), 256, 0, 255);

	pImage->Fill(0, 0, pImage->GetWidth(), pImage->GetHeight(), 0);
	pImage->FillMask(0, 0, pImage->GetWidth(), pImage->GetHeight(), Alpha, CG16bitImage::RGBValue(255, 255, 255), 0, 0);
#endif
#endif

	return pImage;
	}
Пример #17
0
void CParticleEffect::OnPaint (CG16bitImage &Dest, int x, int y, SViewportPaintCtx &Ctx)

//	OnPaint
//
//	Paint the effect

	{
	SParticleArray *pGroup = m_pFirstGroup;
	while (pGroup)
		{
		SParticleType *pType = pGroup->pType;

		//	Paint image

		switch (pType->iPaintStyle)
			{
			case paintFlame:
				PaintFlameParticles(pGroup, Dest, x, y, Ctx);
				break;

			case paintImage:
				{
				int iTick = GetSystem()->GetTick();

				SParticle *pParticle = pGroup->pParticles;
				SParticle *pEnd = pParticle + pGroup->iCount;
				while (pParticle < pEnd)
					{
					if (pParticle->IsValid())
						{
						int x, y;

						Ctx.XForm.Transform(GetPos() + pParticle->vPos, &x, &y);
						pType->Image.PaintImage(Dest, x, y, iTick + pParticle->iDestiny, 0);
						}

					pParticle++;
					}
				break;
				}

			case paintSmoke:
				PaintSmokeParticles(pGroup, Dest, x, y, Ctx);
				break;

			default:
				{
				WORD wColor = CG16bitImage::RGBValue(0, 255, 0);

				SParticle *pParticle = pGroup->pParticles;
				SParticle *pEnd = pParticle + pGroup->iCount;
				while (pParticle < pEnd)
					{
					if (pParticle->IsValid())
						{
						int x, y;

						Ctx.XForm.Transform(GetPos() + pParticle->vPos, &x, &y);
						Dest.DrawDot(x, y, wColor, CG16bitImage::markerSmallRound);
						}

					pParticle++;
					}
				}
			}

		pGroup = pGroup->pNext;
		}
	}
Пример #18
0
void COrbit::Paint (CG16bitImage &Dest, const ViewportTransform &Trans, COLORREF rgbColor)

//	Paint
//
//	Paint the orbit

	{
	DWORD redValue = GetRValue(rgbColor);
	DWORD greenValue = GetGValue(rgbColor);
	DWORD blueValue = GetBValue(rgbColor);

	//	Paint circular orbits in a single color; eccentric orbits change color
	//	since they are not equidistant from the sun

	if (m_rEccentricity == 0.0)
		{
		Metric rAngle;
		const Metric rIncrement = g_Pi / 90.0;
		int xPrev, yPrev;
		WORD wColor;

		//	The orbit color fades depending on the distance from the sun

		Metric rFade = 0.25 + (LIGHT_SECOND * 180.0 / m_rSemiMajorAxis);
		if (rFade < 1.0)
			wColor = CG16bitImage::RGBValue((int)(redValue * rFade), (int)(greenValue * rFade), (int)(blueValue * rFade));
		else
			wColor = CG16bitImage::RGBValue((WORD)redValue, (WORD)greenValue, (WORD)blueValue);

		//	Compute the position of the starting point

		Trans.Transform(GetPointCircular(0.0), &xPrev, &yPrev);

		//	Paint the orbit in multiple segments

		for (rAngle = rIncrement; rAngle < g_Pi * 2.0; rAngle += rIncrement)
			{
			//	Compute the end point

			int x, y;
			Trans.Transform(GetPointCircular(rAngle), &x, &y);

			//	Draw a line segment

			Dest.DrawLine(xPrev, yPrev, x, y, 1, wColor);

			//	Next point

			xPrev = x;
			yPrev = y;
			}
		}
	else
		{
		Metric rAngle;
		const Metric rIncrement = g_Pi / 90.0;
		int xPrev, yPrev;

		//	Compute the position of the starting point

		Trans.Transform(GetPoint(0.0), &xPrev, &yPrev);

		//	Paint the orbit in multiple segments

		for (rAngle = rIncrement; rAngle < g_Pi * 2.0; rAngle += rIncrement)
			{
			Metric rRadius;
			CVector vPos = GetPointAndRadius(rAngle, &rRadius);
			WORD wColor;

			//	Compute the end point

			int x, y;
			Trans.Transform(vPos, &x, &y);

			//	The orbit color fades depending on the distance from the sun

			Metric rFade = 0.25 + (LIGHT_SECOND * 180.0 / rRadius);
			if (rFade < 1.0)
				wColor = CG16bitImage::RGBValue((int)(redValue * rFade), (int)(greenValue * rFade), (int)(blueValue * rFade));
			else
				wColor = CG16bitImage::RGBValue((WORD)redValue, (WORD)greenValue, (WORD)blueValue);

			//	Draw a line segment

			Dest.DrawLine(xPrev, yPrev, x, y, 1, wColor);

			//	Next point

			xPrev = x;
			yPrev = y;
			}
		}
	}