From 70fd6d20bf7cc1cbd1dc2823a3cc485ded852957 Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Sat, 17 Oct 2015 17:35:33 -0400 Subject: [PATCH] Keep parallax objects fixed on full map screenshots (#1042) --- src/game/C4GraphicsSystem.cpp | 2 +- src/graphics/C4FacetEx.cpp | 12 ++++++++++-- src/graphics/C4FacetEx.h | 17 +++++++++++++++-- src/object/C4Object.cpp | 4 ++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/game/C4GraphicsSystem.cpp b/src/game/C4GraphicsSystem.cpp index 126c130ee..33cae7c73 100644 --- a/src/game/C4GraphicsSystem.cpp +++ b/src/game/C4GraphicsSystem.cpp @@ -265,7 +265,7 @@ bool C4GraphicsSystem::DoSaveScreenshot(bool fSaveAll, const char *szFilename, f 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); + 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, false); // render diff --git a/src/graphics/C4FacetEx.cpp b/src/graphics/C4FacetEx.cpp index 319efcdf2..73d998e6e 100644 --- a/src/graphics/C4FacetEx.cpp +++ b/src/graphics/C4FacetEx.cpp @@ -23,20 +23,28 @@ #include #include - void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom) +{ + Set(nsfc, nx, ny, nwdt, nhgt, ntx, nty, Zoom, ntx, nty); +} + +void C4TargetFacet::Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom, float prx, float pry) { C4Facet::Set(nsfc, nx, ny, nwdt, nhgt); TargetX = ntx; TargetY = nty; this->Zoom = Zoom; + ParRefX = prx; ParRefY = pry; } void C4TargetFacet::Set(C4Surface * nsfc, const C4Rect & r, float ntx, float nty, float Zoom) { Set(nsfc, r.x, r.y, r.Wdt, r.Hgt, ntx, nty, Zoom); } + void C4TargetFacet::SetRect(C4TargetRect &rSrc) { - X=rSrc.x; Y=rSrc.y; Wdt=rSrc.Wdt; Hgt=rSrc.Hgt; TargetX=rSrc.tx; TargetY=rSrc.ty; + X=rSrc.x; Y=rSrc.y; Wdt=rSrc.Wdt; Hgt=rSrc.Hgt; + TargetX=rSrc.tx; TargetY=rSrc.ty; + ParRefX=rSrc.tx; TargetY=rSrc.ty; } // ------------------------ diff --git a/src/graphics/C4FacetEx.h b/src/graphics/C4FacetEx.h index 2868436ab..4fac07000 100644 --- a/src/graphics/C4FacetEx.h +++ b/src/graphics/C4FacetEx.h @@ -34,14 +34,27 @@ public: ~C4TargetFacet() { } public: float TargetX,TargetY,Zoom; + + // Reference values for parallax computations. This is similar to + // a scrolling position. In most cases these are the same as TargetX + // and TargetY, however for full map screenshots, which are composed + // of several individual screenshots, these are kept fixed while + // TargetX/TargetY are varied to cover the full map. This prevents + // duplicate parallax objects in fullscreen map screenshots. If + // TargetX/TargetY are different from ParRefX/ParRefY it can be thought + // of as drawing only a part of a window/viewport at a given fixed + // scroll position. + // See bug #1042. + float ParRefX, ParRefY; public: - void Default() { TargetX=TargetY=0; Zoom=1; C4Facet::Default(); } + void Default() { TargetX=TargetY=0; Zoom=1; ParRefX=ParRefY=0; C4Facet::Default(); } void Clear() { Surface=NULL; } - void Set(const C4Facet &cpy) { TargetX=TargetY=0; Zoom=1; C4Facet::Set(cpy); } + void Set(const C4Facet &cpy) { TargetX=TargetY=0; Zoom=1; ParRefX=ParRefY=0; C4Facet::Set(cpy); } void Set(const C4TargetFacet &cpy) { *this = cpy; } void Set(class C4Surface *nsfc, float nx, float ny, float nwdt, float nhgt, float ntx=0, float nty=0, float Zoom=1); void Set(class C4Surface *nsfc, const C4Rect & r, float ntx=0, float nty=0, float Zoom=1); + void Set(class C4Surface *nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom, float prx, float pry); public: C4TargetFacet &operator = (const C4Facet& rhs) diff --git a/src/object/C4Object.cpp b/src/object/C4Object.cpp index ed82a2b14..04105f78f 100644 --- a/src/object/C4Object.cpp +++ b/src/object/C4Object.cpp @@ -4478,8 +4478,8 @@ bool C4Object::GetDrawPosition(const C4TargetFacet & cgo, float objx, float objy if (resultzoom <= 0 || resultzoom > 100) // FIXME: optimize treshhold return false; - float rx = ((1 - parx) * targetx) * resultzoom + objx / (parx + zoom - parx * zoom); - float ry = ((1 - pary) * targety) * resultzoom + objy / (pary + zoom - pary * zoom); + float rx = ((1 - parx) * cgo.ParRefX) * resultzoom + objx / (parx + zoom - parx * zoom); + float ry = ((1 - pary) * cgo.ParRefY) * resultzoom + objy / (pary + zoom - pary * zoom); // Step 2: convert to screen coordinates if(parx == 0 && fix_x < 0)