Пример #1
0
bool C4GraphicsSystem::ToggleShowHelp()
	{
	Toggle(ShowHelp);
	// Turned off? Invalidate background.
	if (!ShowHelp) InvalidateBg();
	return true;
	}
Пример #2
0
void C4GraphicsSystem::DrawFlashMessage()
	{
	if (!FlashMessageTime) return;
	if (!Application.isFullScreen) return;
	Application.DDraw->TextOut(FlashMessageText, Game.GraphicsResource.FontRegular, 1.0, Application.DDraw->lpBack,
											 (FlashMessageX==-1) ? Config.Graphics.ResX/2 : FlashMessageX,
											 (FlashMessageY==-1) ? Config.Graphics.ResY/2 : FlashMessageY,
											 CStdDDraw::DEFAULT_MESSAGE_COLOR,
											 (FlashMessageX==-1) ? ACenter : ALeft);
	FlashMessageTime--;
	// Flash message timed out: redraw background
	if (!FlashMessageTime) InvalidateBg();
	}
void C4GraphicsSystem::DrawFlashMessage()
{
	if (!FlashMessageTime) return;
	if (Application.isEditor) return;
	pDraw->TextOut(FlashMessageText, ::GraphicsResource.FontRegular, 1.0, FullScreen.pSurface,
	                           (FlashMessageX==-1) ? C4GUI::GetScreenWdt()/2 : FlashMessageX,
	                           (FlashMessageY==-1) ? C4GUI::GetScreenHgt()/2 : FlashMessageY,
	                           C4Draw::DEFAULT_MESSAGE_COLOR,
	                           (FlashMessageX==-1) ? ACenter : ALeft);
	FlashMessageTime--;
	// Flash message timed out: redraw background
	if (!FlashMessageTime) InvalidateBg();
}
Пример #4
0
void C4GraphicsSystem::FlashMessage(const char *szMessage)
	{
	// Store message
	SCopy(szMessage, FlashMessageText, C4MaxTitle);
	// Calculate message time
	FlashMessageTime = SLen(FlashMessageText) * 2;
	// Initial position
	FlashMessageX = -1; 
	FlashMessageY = 10;
	// Upper board active: stay below upper board
	if (Config.Graphics.UpperBoard)
		FlashMessageY += C4UpperBoardHeight;
	// More than one viewport: try to stay below portraits etc.
	if (GetViewportCount() > 1)
		FlashMessageY += 64;
	// New flash message: redraw background (might be drawing one message on top of another)
	InvalidateBg();
	}
void C4GraphicsSystem::Default()
{
	MessageBoard.reset(new C4MessageBoard);
	InvalidateBg();
	ShowVertices=false;
	ShowAction=false;
	ShowCommand=false;
	ShowEntrance=false;
	ShowPathfinder=false;
	ShowNetstatus=false;
	Show8BitSurface=0;
	ShowLights=false;
	ShowMenuInfo=false;
	ShowHelp=false;
	FlashMessageText[0]=0;
	FlashMessageTime=0; FlashMessageX=FlashMessageY=0;
	pLoaderScreen=NULL;
}
Пример #6
0
void C4GraphicsSystem::Default()
	{
	UpperBoard.Default();
	MessageBoard.Default();
	FirstViewport=NULL;
	InvalidateBg();
	ViewportArea.Default();
	ShowVertices=FALSE;
	ShowAction=FALSE;
	ShowCommand=FALSE;
	ShowEntrance=FALSE;
	ShowPathfinder=FALSE;
	ShowNetstatus=FALSE;
	ShowSolidMask=FALSE;
	ShowHelp=FALSE;
	FlashMessageText[0]=0;
	FlashMessageTime=0; FlashMessageX=FlashMessageY=0;
	fSetPalette=FALSE;
	Video.Default();
	for (int32_t iRamp=0; iRamp<3*C4MaxGammaRamps; iRamp+=3)
		{ dwGamma[iRamp+0]=0; dwGamma[iRamp+1]=0x808080; dwGamma[iRamp+2]=0xffffff; }
	fSetGamma=FALSE;
	pLoaderScreen=NULL;
	}
Пример #7
0
BOOL C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename)
	{
	// Fullscreen only
	if (!Application.isFullScreen) return FALSE;
	// back surface must be present
	if (!Application.DDraw->lpBack) return FALSE;

	// save landscape
	if (fSaveAll)
		{
		// get viewport to draw in
		C4Viewport *pVP=GetFirstViewport(); if (!pVP) return FALSE;
		// create image large enough to hold the landcape
		CPNGFile png; int32_t lWdt=GBackWdt,lHgt=GBackHgt;
		if (!png.Create(lWdt, lHgt, false)) return FALSE;
		// get backbuffer size
		int32_t bkWdt=Config.Graphics.ResX,bkHgt=Config.Graphics.ResY;
		if (!bkWdt || !bkHgt) return FALSE;
		// facet for blitting
		C4FacetEx bkFct;
		// mark background to be redrawn
		InvalidateBg();
		// backup and clear sky parallaxity
		int32_t iParX=Game.Landscape.Sky.ParX; Game.Landscape.Sky.ParX=10;
		int32_t iParY=Game.Landscape.Sky.ParY; Game.Landscape.Sky.ParY=10;
		// temporarily change viewport player
		int32_t iVpPlr=pVP->Player; pVP->Player=NO_OWNER;
		// blit all tiles needed
		for (int32_t iY=0; iY<lHgt; iY+=bkHgt) for (int32_t iX=0; iX<lWdt; iX+=bkWdt)
			{
			// get max width/height
			int32_t bkWdt2=bkWdt,bkHgt2=bkHgt;
			if (iX+bkWdt2>lWdt) bkWdt2-=iX+bkWdt2-lWdt;
			if (iY+bkHgt2>lHgt) bkHgt2-=iY+bkHgt2-lHgt;
			// update facet
			bkFct.Set(Application.DDraw->lpBack, 0, 0, bkWdt2, bkHgt2, iX, iY);
			// draw there
			pVP->Draw(bkFct, false);
			// render
			Application.DDraw->PageFlip(); Application.DDraw->PageFlip();
			// get output (locking primary!)
			if (Application.DDraw->lpBack->Lock())
				{
				// transfer each pixel - slooow...
				for (int32_t iY2=0; iY2<bkHgt2; ++iY2)
					for (int32_t iX2=0; iX2<bkWdt2; ++iX2)
						png.SetPix(iX+iX2, iY+iY2, Application.DDraw->ApplyGammaTo(Application.DDraw->lpBack->GetPixDw(iX2, iY2, false)));
				// done; unlock
				Application.DDraw->lpBack->Unlock();
				}
			}
		// restore viewport player
		pVP->Player=iVpPlr;
		// restore parallaxity
		Game.Landscape.Sky.ParX=iParX;
		Game.Landscape.Sky.ParY=iParY;
		// save!
		return png.Save(szFilename);
		}
	// Save primary surface
	return Application.DDraw->lpBack->SavePNG(szFilename, false, true, false);
	}
Пример #8
0
void C4GraphicsSystem::RecalculateViewports()
	{

	// Fullscreen only
	if (!Application.isFullScreen) return;

	// Sort viewports
	SortViewportsByPlayerControl();

	// Viewport area
	int32_t iBorderTop = 0, iBorderBottom = 0;
	if (Config.Graphics.UpperBoard) 
		iBorderTop = C4UpperBoardHeight;
	iBorderBottom = MessageBoard.Output.Hgt;
	ViewportArea.Set(Application.DDraw->lpBack,0,iBorderTop, Config.Graphics.ResX, Config.Graphics.ResY-iBorderTop-iBorderBottom);

	// Redraw flag
	InvalidateBg();
#ifdef _WIN32
	// reset mouse clipping
	ClipCursor(NULL);
#else
	// StdWindow handles this.
#endif
	// reset GUI dlg pos
	if (Game.pGUI)
		Game.pGUI->SetPreferredDlgRect(C4Rect(ViewportArea.X, ViewportArea.Y, ViewportArea.Wdt, ViewportArea.Hgt));

	// fullscreen background: First, cover all of screen
	BackgroundAreas.Clear();
	BackgroundAreas.AddRect(C4Rect(ViewportArea.X, ViewportArea.Y, ViewportArea.Wdt, ViewportArea.Hgt));

	// Viewports
	C4Viewport *cvp;
	int32_t iViews = 0;
	for (cvp=FirstViewport; cvp; cvp=cvp->Next) iViews++;
	if (!iViews) return;
	int32_t iViewsH = (int32_t) sqrt(float(iViews));
	int32_t iViewsX = iViews / iViewsH;
	int32_t iViewsL = iViews % iViewsH;
	int32_t cViewH,cViewX,ciViewsX;
	int32_t cViewWdt,cViewHgt,cOffWdt,cOffHgt,cOffX,cOffY;
	cvp=FirstViewport;
	for (cViewH=0; cViewH<iViewsH; cViewH++)
		{
		ciViewsX = iViewsX;	if (cViewH<iViewsL) ciViewsX++;
		for (cViewX=0; cViewX<ciViewsX; cViewX++)
			{
			cViewWdt = ViewportArea.Wdt/ciViewsX;
			cViewHgt = ViewportArea.Hgt/iViewsH;
			cOffX = ViewportArea.X;
			cOffY = ViewportArea.Y;
			cOffWdt=cOffHgt=0;
			int32_t ViewportScrollBorder = Application.isFullScreen ? C4ViewportScrollBorder : 0;
			if (ciViewsX*Min<int32_t>(cViewWdt, GBackWdt+2*ViewportScrollBorder)<ViewportArea.Wdt)
				cOffX=(ViewportArea.Wdt-ciViewsX*Min<int32_t>(cViewWdt, GBackWdt+2*ViewportScrollBorder))/2;
			if (iViewsH*Min<int32_t>(cViewHgt, GBackHgt+2*ViewportScrollBorder)<ViewportArea.Hgt)
				cOffY=(ViewportArea.Hgt-iViewsH*Min<int32_t>(cViewHgt, GBackHgt+2*ViewportScrollBorder))/2 + ViewportArea.Y;
			if (Config.Graphics.SplitscreenDividers) 
				{
				if (cViewX<ciViewsX-1) cOffWdt=4;
				if (cViewH<iViewsH-1) cOffHgt=4;
				}
			int32_t coViewWdt=cViewWdt-cOffWdt; if (coViewWdt>GBackWdt+2*ViewportScrollBorder) { coViewWdt=GBackWdt+2*ViewportScrollBorder; }
			int32_t coViewHgt=cViewHgt-cOffHgt; if (coViewHgt>GBackHgt+2*ViewportScrollBorder) { coViewHgt=GBackHgt+2*ViewportScrollBorder; }
			C4Rect rcOut(cOffX+cViewX*cViewWdt, cOffY+cViewH*cViewHgt, coViewWdt, coViewHgt);
			cvp->SetOutputSize(rcOut.x,rcOut.y,rcOut.x,rcOut.y,rcOut.Wdt,rcOut.Hgt);
			cvp=cvp->Next;
			// clip down area avaiable for background drawing
			BackgroundAreas.ClipByRect(rcOut);
			}
		}
	}
bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename, float fSaveAllZoom)
{
	// Fullscreen only
	if (Application.isEditor) return false;
	// back surface must be present
	if (!FullScreen.pSurface) return false;

	// save landscape
	if (fSaveAll)
	{
		// Create full map screenshots at zoom 2x. Fractional zooms (like 1.7x) should work but might cause some trouble at screen borders.
		float zoom = fSaveAllZoom;
		// get viewport to draw in
		C4Viewport *pVP=::Viewports.GetFirstViewport(); if (!pVP) return false;
		// create image large enough to hold the landscape
		std::unique_ptr<CPNGFile> png(new CPNGFile());
		int32_t lWdt = GBackWdt * zoom, lHgt = GBackHgt * zoom;
		if (!png->Create(lWdt, lHgt, false)) return false;
		// get backbuffer size
		int32_t bkWdt=C4GUI::GetScreenWdt(), bkHgt=C4GUI::GetScreenHgt();
		if (!bkWdt || !bkHgt) return false;
		// facet for blitting
		C4TargetFacet bkFct;
		// mark background to be redrawn
		InvalidateBg();
		// draw on one big viewport
		pVP->SetOutputSize(0,0,0,0, bkWdt, bkHgt);
		// backup and clear sky parallaxity
		int32_t iParX=::Landscape.Sky.ParX; ::Landscape.Sky.ParX=10;
		int32_t iParY=::Landscape.Sky.ParY; ::Landscape.Sky.ParY=10;
		// backup and clear viewport borders
		FLOAT_RECT vp_borders = { pVP->BorderLeft, pVP->BorderRight, pVP->BorderTop, pVP->BorderBottom };
		pVP->BorderLeft = pVP->BorderRight = pVP->BorderTop = pVP->BorderBottom = 0.0f;
		// temporarily change viewport player
		int32_t iVpPlr=pVP->Player; pVP->Player=NO_OWNER;
		// blit all tiles needed
		for (int32_t iY=0; iY<lHgt; iY+=bkHgt) for (int32_t iX=0; iX<lWdt; iX+=bkWdt)
			{
				// get max width/height
				int32_t bkWdt2=bkWdt,bkHgt2=bkHgt;
				if (iX+bkWdt2>lWdt) bkWdt2-=iX+bkWdt2-lWdt;
				if (iY+bkHgt2>lHgt) bkHgt2-=iY+bkHgt2-lHgt;
				// update facet
				bkFct.Set(FullScreen.pSurface, 0, 0, ceil(float(bkWdt2)/zoom), ceil(float(bkHgt2)/zoom), iX/zoom, iY/zoom, zoom, 0, 0);
				// draw there
				pVP->Draw(bkFct, true, false);
				// render
				FullScreen.pSurface->PageFlip(); FullScreen.pSurface->PageFlip();
				// get output (locking primary!)
				if (FullScreen.pSurface->Lock())
				{
					// transfer each pixel - slooow...
					for (int32_t iY2 = 0; iY2 < bkHgt2; ++iY2)
#ifndef USE_CONSOLE
						glReadPixels(0, FullScreen.pSurface->Hgt - iY2 - 1, bkWdt2, 1, GL_BGR, GL_UNSIGNED_BYTE, reinterpret_cast<BYTE *>(png->GetRow(iY + iY2)) + iX * 3);
#else
						for (int32_t iX2=0; iX2<bkWdt2; ++iX2)
							png->SetPix(iX+iX2, iY+iY2, FullScreen.pSurface->GetPixDw(iX2, iY2, false));
#endif
					// done; unlock
					FullScreen.pSurface->Unlock();
					// This can take a long time and we would like to pump messages
					// However, we're currently hogging the primary surface and horrible things might happen if we do that, including initiation of another screenshot
					// The only thing that can be safely run is music (sound could play but that would just make them out of sync of the game)
					::Application.MusicSystem.Execute(true);
				}
			}
		// restore viewport player
		pVP->Player=iVpPlr;
		// restore viewport borders
		pVP->BorderLeft = vp_borders.left;
		pVP->BorderTop = vp_borders.top;
		pVP->BorderRight = vp_borders.right;
		pVP->BorderBottom = vp_borders.bottom;
		// restore parallaxity
		::Landscape.Sky.ParX=iParX;
		::Landscape.Sky.ParY=iParY;
		// restore viewport size
		::Viewports.RecalculateViewports();
		// save!
		CPNGFile::ScheduleSaving(png.release(), szFilename);
		return true;
	}
	// Save primary surface in background thread
	return FullScreen.pSurface->SavePNG(szFilename, false, false, true);
}