Beispiel #1
0
bool C4Surface::ReadBMP(CStdStream &hGroup, int iFlags)
{
	int lcnt;
	C4BMP256Info BitmapInfo;
	// read bmpinfo-header
	if (!hGroup.Read(&BitmapInfo,sizeof(C4BMPInfo))) return false;
	// is it 8bpp?
	if (BitmapInfo.Info.biBitCount == 8)
	{
		if (!hGroup.Read(((BYTE *) &BitmapInfo)+sizeof(C4BMPInfo),
		                 std::min(sizeof(BitmapInfo)-sizeof(C4BMPInfo),sizeof(BitmapInfo)-sizeof(C4BMPInfo)+BitmapInfo.FileBitsOffset())))
			return false;
		if (!hGroup.Advance(BitmapInfo.FileBitsOffset())) return false;
	}
	else
	{
		// read 24bpp
		if (BitmapInfo.Info.biBitCount != 24) return false;
		if (!hGroup.Advance(((C4BMPInfo) BitmapInfo).FileBitsOffset())) return false;
	}

	// Create and lock surface
	if (!Create(BitmapInfo.Info.biWidth,BitmapInfo.Info.biHeight, iFlags)) return false;
	if (!Lock()) { Clear(); return false; }

	// create line buffer
	int iBufSize=DWordAligned(BitmapInfo.Info.biWidth*BitmapInfo.Info.biBitCount/8);
	BYTE *pBuf = new BYTE[iBufSize];
	// Read lines
	for (lcnt=Hgt-1; lcnt>=0; lcnt--)
	{
		if (!hGroup.Read(pBuf, iBufSize))
			{ Clear(); delete [] pBuf; return false; }
		BYTE *pPix=pBuf;
		for (int x=0; x<BitmapInfo.Info.biWidth; ++x)
			switch (BitmapInfo.Info.biBitCount)
			{
			case 8:
				SetPixDw(x, lcnt, C4RGB(
				         BitmapInfo.Colors[*pPix].rgbRed,
				         BitmapInfo.Colors[*pPix].rgbGreen,
				         BitmapInfo.Colors[*pPix].rgbBlue));
				++pPix;
				break;
			case 24:
				SetPixDw(x, lcnt, C4RGB(pPix[0], pPix[1], pPix[2]));
				pPix+=3;
				break;
			}
	}
	// free buffer again
	delete [] pBuf;

	Unlock();

	return true;
}
Beispiel #2
0
void C4Sky::SetFadePalette(int32_t *ipColors)
{
	// If colors all zero, use game palette default blue
	if (ipColors[0]+ipColors[1]+ipColors[2]+ipColors[3]+ipColors[4]+ipColors[5]==0)
	{
		FadeClr1=C4RGB(0x1c, 0x40, 0x99);
		FadeClr2=C4RGB(0xc2, 0xc6, 0xff);
	}
	else
	{
		// set colors
		FadeClr1=C4RGB(ipColors[0], ipColors[1], ipColors[2]);
		FadeClr2=C4RGB(ipColors[3], ipColors[4], ipColors[5]);
	}
}
bool CSurface8::Read(CStdStream &hGroup)
{
	int cnt,lcnt;
	C4BMP256Info BitmapInfo;
	// read bmpinfo-header
	if (!hGroup.Read(&BitmapInfo,sizeof(C4BMPInfo))) return false;
	// is it 8bpp?
	if (BitmapInfo.Info.biBitCount == 8)
	{
		if (!hGroup.Read(((BYTE *) &BitmapInfo)+sizeof(C4BMPInfo),sizeof(BitmapInfo)-sizeof(C4BMPInfo))) return false;
		if (!hGroup.Advance(BitmapInfo.FileBitsOffset())) return false;
	}
	else
	{
		// read 24bpp
		if (BitmapInfo.Info.biBitCount != 24) return false;
		if (!hGroup.Advance(((C4BMPInfo) BitmapInfo).FileBitsOffset())) return false;
	}

	// Create and lock surface
	if (!Create(BitmapInfo.Info.biWidth,BitmapInfo.Info.biHeight)) return false;

	if (BitmapInfo.Info.biBitCount == 8)
	{
		// Copy palette
		for (cnt=0; cnt<256; cnt++)
		{
			pPal->Colors[cnt] = C4RGB(BitmapInfo.Colors[cnt].rgbRed,
			                          BitmapInfo.Colors[cnt].rgbGreen,
			                          BitmapInfo.Colors[cnt].rgbBlue);
		}
	}

	// create line buffer
	int iBufSize=DWordAligned(BitmapInfo.Info.biWidth*BitmapInfo.Info.biBitCount/8);
	BYTE *pBuf = new BYTE[iBufSize];
	// Read lines
	for (lcnt=Hgt-1; lcnt>=0; lcnt--)
	{
		if (!hGroup.Read(pBuf, iBufSize))
			{ Clear(); delete [] pBuf; return false; }
		BYTE *pPix=pBuf;
		for (int x=0; x<BitmapInfo.Info.biWidth; ++x)
			switch (BitmapInfo.Info.biBitCount)
			{
			case 8:
				SetPix(x, lcnt, *pPix++);
				break;
			case 24:
				return false;
				break;
			}
	}
	// free buffer again
	delete [] pBuf;

	return true;
}
Beispiel #4
0
DWORD CPNGFile::GetPix(int iX, int iY)
{
	// image loaded?
	if (!pImageData) return 0;
	// return pixel value
	unsigned char *pPix=pImageData+iY*iRowSize+iX*iPixSize;
	switch (iClrType)
	{
	case PNG_COLOR_TYPE_RGB:
		return C4RGB(pPix[2], pPix[1], pPix[0]);
	case PNG_COLOR_TYPE_RGB_ALPHA:
		return RGBA(pPix[2], pPix[1], pPix[0], pPix[3]);
	}
	return 0;
}
void C4GraphicsSystem::ApplyGamma()
	{
	// No gamma effects
	if (Config.Graphics.DisableGamma) return;
	//  calculate color channels by adding the difference between the gamma ramps to their normals
	int32_t ChanOff[3];
	DWORD Gamma[3];
	const int32_t DefChanVal[3] = { 0x00, 0x80, 0xff };
	// calc offset for curve points
	for (int32_t iCurve=0; iCurve<3; ++iCurve)
		{
		ZeroMemory(ChanOff, sizeof(int32_t)*3);
		// ...channels...
		for (int32_t iChan=0; iChan<3; ++iChan)
			// ...ramps...
			for (int32_t iRamp=0; iRamp<C4MaxGammaRamps; ++iRamp)
				// add offset
				ChanOff[iChan]+=(int32_t) BYTE(dwGamma[iRamp*3+iCurve]>>(16-iChan*8)) - DefChanVal[iCurve];
		// calc curve point
		Gamma[iCurve]=C4RGB(BoundBy<int32_t>(DefChanVal[iCurve]+ChanOff[0], 0, 255), BoundBy<int32_t>(DefChanVal[iCurve]+ChanOff[1], 0, 255), BoundBy<int32_t>(DefChanVal[iCurve]+ChanOff[2], 0, 255));
		}
	// set gamma
	Application.DDraw->SetGamma(Gamma[0], Gamma[1], Gamma[2]);
	}
void C4Menu::DrawFrame(C4Surface * sfcSurface, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt)
{
	pDraw->DrawFrameDw(sfcSurface, iX+1, iY+1, iX+iWdt-1,iY+iHgt-1, C4RGB(0x44, 0, 0));
}
void C4MenuItem::DrawElement(C4TargetFacet &cgo)
{
	// get target pos
	C4Facet cgoOut(cgo.Surface, cgo.TargetX + rcBounds.x, cgo.TargetY + rcBounds.y, rcBounds.Wdt, rcBounds.Hgt);
	// Select mark
	if (iStyle!=C4MN_Style_Info)
		if (fSelected && TextDisplayProgress)
			pDraw->DrawBoxDw(cgo.Surface, cgoOut.X, cgoOut.Y, cgoOut.X + cgoOut.Wdt - 1, cgoOut.Y + cgoOut.Hgt - 1, C4RGB(0xca, 0, 0));
	// Symbol/text areas
	C4Facet cgoItemSymbol,cgoItemText;
	cgoItemSymbol=cgoItemText=cgoOut;
	int32_t iSymWidth;
	if ((iSymWidth = GetSymbolWidth(cgoItemText.Hgt)))
	{
		// get symbol area
		cgoItemSymbol=cgoItemText.Truncate(C4FCT_Left, iSymWidth);
	}
	// cgoItemSymbol.Hgt is 0. This means rcBounds.Hgt is 0. That
	// makes no sense at this point, so let's just draw in a
	// square area at item y.
	C4Facet cgoSymbolOut(cgoItemSymbol.Surface, cgoItemSymbol.X, cgoItemSymbol.Y, cgoItemSymbol.Wdt, cgoItemSymbol.Wdt);

	// Draw item symbol:
	// Draw if there is no text progression at all (TextDisplayProgress==-1, or if it's progressed far enough already (TextDisplayProgress>0)
	if(pSymbolObj && TextDisplayProgress)
	{
		pSymbolObj->DrawPicture(cgoSymbolOut, false, NULL);
	}
	else if (pSymbolGraphics && TextDisplayProgress)
	{
		pSymbolGraphics->Draw(cgoSymbolOut, dwSymbolClr ? dwSymbolClr : 0xffffffff, NULL, 0, 0, NULL);
	}
	else if (Symbol.Surface && TextDisplayProgress)
		Symbol.DrawClr(cgoItemSymbol, true, dwSymbolClr);

	// Draw item text
	pDraw->StorePrimaryClipper(); pDraw->SubPrimaryClipper(cgoItemText.X, cgoItemText.Y, cgoItemText.X+cgoItemText.Wdt-1, cgoItemText.Y+cgoItemText.Hgt-1);
	switch (iStyle)
	{
	case C4MN_Style_Context:
		pDraw->TextOut(Caption,::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X,cgoItemText.Y,C4Draw::DEFAULT_MESSAGE_COLOR,ALeft);
		break;
	case C4MN_Style_Info:
	{
		StdStrBuf sText;
		::GraphicsResource.FontRegular.BreakMessage(InfoCaption, cgoItemText.Wdt, &sText, true);
		pDraw->TextOut(sText.getData(), ::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X,cgoItemText.Y);
		break;
	}
	case C4MN_Style_Dialog:
	{
		// cut buffer at text display pos
		char cXChg='\0'; int iStopPos = 0;
		if (TextDisplayProgress>-1)
		{
			iStopPos = std::min<int>(TextDisplayProgress, strlen(Caption));
			cXChg = Caption[iStopPos];
			Caption[iStopPos] = '\0';
		}
		// display broken text
		StdStrBuf sText;
		::GraphicsResource.FontRegular.BreakMessage(Caption, cgoItemText.Wdt, &sText, true);
		pDraw->TextOut(sText.getData(),::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X,cgoItemText.Y);
		// restore complete text
		if (cXChg) Caption[iStopPos] = cXChg;
		break;
	}
	}
	pDraw->RestorePrimaryClipper();
	// Draw count
	if (Count!=C4MN_Item_NoCount)
	{
		char szCount[10+1];
		sprintf(szCount,"%ix",Count);
		pDraw->TextOut(szCount, ::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface, cgoItemText.X+cgoItemText.Wdt-1, cgoItemText.Y+cgoItemText.Hgt-1-::GraphicsResource.FontRegular.GetLineHeight(), C4Draw::DEFAULT_MESSAGE_COLOR, ARight);
	}
}
DWORD GenerateRandomPlayerColor(int32_t iTry) // generate a random player color for the iTry'th try
{
	// generate a random one biased towards max channel luminance
	// (for greater color difference and less gray-ish colors)
	return C4RGB(std::min<int>(UnsyncedRandom(302), 256), std::min<int>(UnsyncedRandom(302), 256), std::min<int>(UnsyncedRandom(302), 256));
}
Beispiel #9
0
void C4Def::Draw(C4Facet &cgo, bool fSelected, DWORD iColor, C4Object *pObj, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform* trans, const char *graphicsName)
{
	if(fSelected)
		pDraw->DrawBoxDw(cgo.Surface, cgo.X, cgo.Y, cgo.X + cgo.Wdt - 1, cgo.Y + cgo.Hgt - 1, C4RGB(0xca, 0, 0));

	C4DefGraphics* graphics = pObj ? pObj->GetGraphics() : &Graphics;
	if (graphicsName)
	{
		C4DefGraphics *other = graphics->Get(graphicsName);
		if (other) graphics = other;
	}
	graphics->Draw(cgo, iColor, pObj, iPhaseX, iPhaseY, trans);
}
void C4Chart::DrawElement(C4TargetFacet &cgo)
{
	typedef C4Graph::ValueType ValueType;
	typedef C4Graph::TimeType TimeType;
	// transparent w/o graph
	if (!pDisplayGraph) return;
	int iSeriesCount = pDisplayGraph->GetSeriesCount();
	if (!iSeriesCount) return;
	assert(iSeriesCount>0);
	StdStrBuf sbuf;
	pDisplayGraph->Update(); // update averages, etc.
	// calc metrics
	CStdFont &rFont = ::GraphicsResource.MiniFont;
	int       YAxisWdt       = 5,
	          XAxisHgt       = 15;
			  
	const int AxisArrowLen   = 6,
	          AxisMarkerLen  = 5,
	          AxisArrowThickness = 3,
	          AxisArrowIndent=  2; // margin between axis arrow and last value
	int32_t       YAxisMinStepHgt, XAxisMinStepWdt;
	// get value range
	int iMinTime = pDisplayGraph->GetStartTime();
	int iMaxTime = pDisplayGraph->GetEndTime() - 1;
	if (iMinTime >= iMaxTime) return;
	ValueType iMinVal = pDisplayGraph->GetMinValue();
	ValueType iMaxVal = pDisplayGraph->GetMaxValue();
	if (iMinVal == iMaxVal) ++iMaxVal;
	if (iMinVal > 0 && iMaxVal/iMinVal >= 2) iMinVal = 0; // go zero-based if this creates less than 50% unused space
	else if (iMaxVal < 0 && iMinVal/iMaxVal >= 2) iMaxVal = 0;
	int ddv;
	if (iMaxVal>0 && (ddv=GetValueDecade(int(iMaxVal))/50))
		iMaxVal = ((iMaxVal-(iMaxVal>0))/ddv+(iMaxVal>0))*ddv;
	if (iMinVal && (ddv=GetValueDecade(int(iMinVal))/50))
		iMinVal = ((iMinVal-(iMinVal<0))/ddv+(iMinVal<0))*ddv;
	ValueType dv=iMaxVal-iMinVal; TimeType dt=iMaxTime-iMinTime;
	// axis calculations
	sbuf.Format("-%d", (int) std::max(Abs(iMaxVal), Abs(iMinVal)));
	rFont.GetTextExtent(sbuf.getData(), XAxisMinStepWdt, YAxisMinStepHgt, false);
	YAxisWdt += XAxisMinStepWdt; XAxisHgt += YAxisMinStepHgt;
	XAxisMinStepWdt += 2; YAxisMinStepHgt += 2;
	int tw = rcBounds.Wdt - YAxisWdt;
	int th = rcBounds.Hgt - XAxisHgt;
	int tx = rcBounds.x + int(cgo.TargetX) + YAxisWdt;
	int ty = rcBounds.y + int(cgo.TargetY);
	// show a legend, if more than one graph is shown
	if (iSeriesCount > 1)
	{
		int iSeries = 0; const C4Graph *pSeries;
		int32_t iLegendWdt = 0, Q,W;
		while ((pSeries = pDisplayGraph->GetSeries(iSeries++)))
		{
			rFont.GetTextExtent(pSeries->GetTitle(), W, Q, true);
			iLegendWdt = std::max(iLegendWdt, W);
		}
		tw -= iLegendWdt+1;
		iSeries = 0;
		int iYLegendDraw = (th - iSeriesCount*Q)/2 + ty;
		while ((pSeries = pDisplayGraph->GetSeries(iSeries++)))
		{
			pDraw->TextOut(pSeries->GetTitle(), rFont, 1.0f, cgo.Surface, tx+tw, iYLegendDraw, pSeries->GetColorDw() | 0xff000000, ALeft, true);
			iYLegendDraw += Q;
		}
	}
	// safety: too small?
	if (tw < 10 || th < 10) return;
	// draw axis
	pDraw->DrawLineDw(cgo.Surface, tx, ty+th, tx+tw-1, ty+th, C4RGB(0x91, 0x91, 0x91));
	pDraw->DrawLineDw(cgo.Surface, tx+tw-1, ty+th, tx+tw-1-AxisArrowLen, ty+th-AxisArrowThickness, C4RGB(0x91, 0x91, 0x91));
	pDraw->DrawLineDw(cgo.Surface, tx+tw-1, ty+th, tx+tw-1-AxisArrowLen, ty+th+AxisArrowThickness, C4RGB(0x91, 0x91, 0x91));
	pDraw->DrawLineDw(cgo.Surface, tx, ty, tx, ty+th, C4RGB(0x91, 0x91, 0x91));
	pDraw->DrawLineDw(cgo.Surface, tx, ty, tx-AxisArrowThickness, ty+AxisArrowLen, C4RGB(0x91, 0x91, 0x91));
	pDraw->DrawLineDw(cgo.Surface, tx, ty, tx+AxisArrowThickness, ty+AxisArrowLen, C4RGB(0x91, 0x91, 0x91));
	tw -= AxisArrowLen + AxisArrowIndent;
	th -= AxisArrowLen + AxisArrowIndent; ty += AxisArrowLen + AxisArrowIndent;
	// do axis numbering
	int iXAxisSteps = GetAxisStepRange(dt, tw / XAxisMinStepWdt),
	                  iYAxisSteps = GetAxisStepRange(int(dv), th / YAxisMinStepHgt);
	int iX, iY, iTime, iVal;
	iY = 0;
	iTime = ((iMinTime-(iMinTime>0))/iXAxisSteps+(iMinTime>0))*iXAxisSteps;
	for (; iTime <= iMaxTime; iTime += iXAxisSteps)
	{
		iX = tx + tw * (iTime-iMinTime) / dt;
		pDraw->DrawLineDw(cgo.Surface, iX, ty+th+1, iX, ty+th+AxisMarkerLen, C4RGB(0x91, 0x91, 0x91));
		sbuf.Format("%d", (int) iTime);
		pDraw->TextOut(sbuf.getData(), rFont, 1.0f, cgo.Surface, iX, ty+th+AxisMarkerLen, 0xff7f7f7f, ACenter, false);
	}
	iVal = int( ((iMinVal-(iMinVal>0))/iYAxisSteps+(iMinVal>0))*iYAxisSteps );
	for (; iVal <= iMaxVal; iVal += iYAxisSteps)
	{
		iY = ty+th - int((iVal-iMinVal) / dv * th);
		pDraw->DrawLineDw(cgo.Surface, tx-AxisMarkerLen, iY, tx-1, iY, C4RGB(0x91, 0x91, 0x91));
		sbuf.Format("%d", (int) iVal);
		pDraw->TextOut(sbuf.getData(), rFont, 1.0f, cgo.Surface, tx-AxisMarkerLen, iY-rFont.GetLineHeight()/2, 0xff7f7f7f, ARight, false);
	}
	// draw graph series(es)
	int iSeries = 0;
	while (const C4Graph *pSeries = pDisplayGraph->GetSeries(iSeries++))
	{
		int iThisMinTime = std::max(iMinTime, pSeries->GetStartTime());
		int iThisMaxTime = std::min(iMaxTime, pSeries->GetEndTime());
		bool fAnyVal = false;
		for (iX = 0; iX<tw; ++iX)
		{
			iTime = iMinTime + dt*iX/tw;
			if (!Inside(iTime, iThisMinTime, iThisMaxTime)) continue;
			int iY2 = int((-pSeries->GetValue(iTime) + iMinVal) * th / dv) + ty+th;
			if (fAnyVal) pDraw->DrawLineDw(cgo.Surface, (float) (tx+iX-1), (float) iY, (float) (tx+iX), (float) iY2, pSeries->GetColorDw() | 0xff000000);
			iY = iY2;
			fAnyVal = true;
		}
	}
}
void C4Network2ClientListBox::ClientListItem::Update()
{
	// update wait label
	if (pPing)
	{
		int iWait = ::Control.Network.ClientPerfStat(iClientID);
		pPing->SetText(FormatString("%d ms", iWait).getData());
		pPing->SetColor(C4RGB(
		                  Clamp(255-Abs(iWait)*5, 0, 255),
		                  Clamp(255-iWait*5, 0, 255),
		                  Clamp(255+iWait*5, 0, 255)));
	}
	// update activation status
	const C4Client *pClient = GetClient(); if (!pClient) return;
	bool fIsActive = pClient->isActivated();
	if (fIsActive != fShownActive)
	{
		fShownActive = fIsActive;
		if (!pClient->isHost()) pStatusIcon->SetIcon(fIsActive ? C4GUI::Ico_Client : C4GUI::Ico_ObserverClient);
		if (pActivateBtn)
		{
			pActivateBtn->SetIcon(fIsActive ? C4GUI::Ico_Active : C4GUI::Ico_Inactive);
			pActivateBtn->SetToolTip(LoadResStrNoAmp(fIsActive ? "IDS_NET_DEACTIVATECLIENT" : "IDS_NET_ACTIVATECLIENT"));
		}
	}
	// update players in tooltip
	StdStrBuf sCltPlrs(Game.PlayerInfos.GetActivePlayerNames(false, iClientID));
	pName->SetToolTip(sCltPlrs.getData());
	// update icon: Network status
	C4GUI::Icons icoStatus = C4GUI::Ico_UnknownClient;
	C4Network2Client *pClt = pClient->getNetClient();
	if (pClt)
	{
		switch (pClt->getStatus())
		{
		case NCS_Joining: // waiting for join data
		case NCS_Chasing: // client is behind (status not acknowledged, isn't waited for)
		case NCS_NotReady: // client is behind (status not acknowledged)
			icoStatus = C4GUI::Ico_Loading;
			break;

		case NCS_Ready: // client acknowledged network status
			icoStatus = C4GUI::Ico_Ready;
			break;

		case NCS_Remove: // client is to be removed
			icoStatus = C4GUI::Ico_Kick;
			break;

		default: // whatever
			assert(false);
			icoStatus = C4GUI::Ico_Loading;
			break;
		}
	}
	// sound icon?
	if (last_sound_time)
	{
		time_t dt = time(nullptr) - last_sound_time;
		if (dt >= SoundIconShowTime)
		{
			// stop showing sound icon
			last_sound_time = 0;
		}
		else
		{
			// time not up yet: show sound icon
			icoStatus = C4GUI::Ico_Sound;
		}
	}
	// network OK - control ready?
	if (!pForDlg->IsStartup() && (icoStatus == C4GUI::Ico_Ready))
	{
		if (!::Control.Network.ClientReady(iClientID, ::Control.ControlTick))
		{
			// control not ready
			icoStatus = C4GUI::Ico_NetWait;
		}
	}
	// set new icon
	pStatusIcon->SetIcon(icoStatus);
}