1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 1998-2000, Matthes Bender 5 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 6 * Copyright (c) 2011-2016, The OpenClonk Team and contributors 7 * 8 * Distributed under the terms of the ISC license; see accompanying file 9 * "COPYING" for details. 10 * 11 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 12 * See accompanying file "TRADEMARK" for details. 13 * 14 * To redistribute this file separately, substitute the full license texts 15 * for the above references. 16 */ 17 18 /* A piece of a DirectDraw surface */ 19 20 #ifndef INC_C4Facet 21 #define INC_C4Facet 22 23 #include "graphics/C4BltTransform.h" 24 25 const int32_t C4FCT_None = 0, 26 27 C4FCT_Left = 1, 28 C4FCT_Right = 2, 29 C4FCT_Top = 4, 30 C4FCT_Bottom = 8, 31 C4FCT_Center = 16, 32 33 C4FCT_Alignment = C4FCT_Left | C4FCT_Right | C4FCT_Top | C4FCT_Bottom | C4FCT_Center, 34 35 C4FCT_Half = 32, 36 C4FCT_Double = 64, 37 C4FCT_Triple = 128; 38 39 // tuple of two integers 40 struct C4Vec2D 41 { 42 int32_t x,y; 43 xC4Vec2D44 C4Vec2D(int32_t x=0, int32_t y=0) : x(x), y(y) {} 45 }; 46 47 class C4DrawTransform : public C4BltTransform 48 { 49 public: 50 int32_t FlipDir; // +1 or -1; multiplied as x-flip 51 C4DrawTransform(C4DrawTransform & rCopy,float iOffX,float iOffY)52 C4DrawTransform(C4DrawTransform &rCopy, float iOffX, float iOffY) // ctor doing transform at given offset - doesn't init FlipDir (for temp use only) 53 { 54 SetTransformAt(rCopy, iOffX, iOffY); 55 } 56 C4DrawTransform()57 C4DrawTransform() 58 { 59 // ctor without matrix initialization 60 FlipDir = 1; 61 } 62 C4DrawTransform(int32_t iFlipDir)63 C4DrawTransform(int32_t iFlipDir) 64 { 65 // ctor setting flipdir only 66 FlipDir = iFlipDir; 67 // set identity 68 Set(1,0,0,0,1,0,0,0,1); 69 } 70 71 ~C4DrawTransform() = default; 72 73 // do transform at given offset - doesn't init FlipDir (for temp use only) 74 void SetTransformAt(C4DrawTransform &rCopy, float iOffX, float iOffY); 75 Set(float fA,float fB,float fC,float fD,float fE,float fF,float fG,float fH,float fI)76 void Set(float fA, float fB, float fC, float fD, float fE, float fF, float fG, float fH, float fI) 77 { 78 // set values; apply flipdir 79 C4BltTransform::Set(fA*FlipDir, fB, fC, fD, fE, fF, fG, fH, fI); 80 } 81 SetFlipDir(int32_t iNewFlipDir)82 void SetFlipDir(int32_t iNewFlipDir) 83 { 84 // no change? 85 if (iNewFlipDir == FlipDir) return; 86 // set and apply in matrix 87 FlipDir = iNewFlipDir; mat[0] = -mat[0]; 88 } 89 IsIdentity()90 bool IsIdentity() const 91 { 92 return (mat[0]==1.0f) && (mat[1]==0.0f) && (mat[2]==0.0f) 93 && (mat[3]==0.0f) && (mat[4]==1.0f) && (mat[5]==0.0f) 94 && (mat[6]==0.0f) && (mat[7]==0.0f) && (mat[8]==1.0f) 95 && (FlipDir==1); // flipdir must be 1, because otherwise matrices flipped by action+script would be removed 96 } 97 98 // default comparison op won't work :( 99 bool operator == (const C4DrawTransform &rCmp) const 100 { 101 return (mat[0]==rCmp.mat[0]) && (mat[1]==rCmp.mat[1]) && (mat[2]==rCmp.mat[2]) 102 && (mat[3]==rCmp.mat[3]) && (mat[4]==rCmp.mat[4]) && (mat[5]==rCmp.mat[5]) 103 && (mat[6]==rCmp.mat[6]) && (mat[7]==rCmp.mat[7]) && (mat[8]==rCmp.mat[8]) && (FlipDir == rCmp.FlipDir); 104 } 105 C4DrawTransform * operator&() { return this; } 106 void CompileFunc(StdCompiler *pComp); 107 108 // rounded pixel offsets generated by this transformation GetXOffset()109 int32_t GetXOffset() const { return static_cast<int32_t>(mat[2]); } GetYOffset()110 int32_t GetYOffset() const { return static_cast<int32_t>(mat[5]); } 111 112 }; 113 114 class C4Facet 115 { 116 public: 117 C4Surface * Surface; 118 float X,Y,Wdt,Hgt; 119 public: 120 C4Facet(); C4Facet(C4Surface * pSfc,float iX,float iY,float iWdt,float iHgt)121 C4Facet(C4Surface * pSfc, float iX, float iY, float iWdt, float iHgt) 122 : Surface(pSfc), X(iX), Y(iY), Wdt(iWdt), Hgt(iHgt) { } 123 public: 124 void Default(); 125 void Set(C4Surface &rSfc); 126 void Set(C4Surface * nsfc, float nx, float ny, float nwdt, float nhgt); Set(const C4Facet & cpy)127 void Set(const C4Facet &cpy) { *this=cpy; } 128 void Expand(int32_t iLeft=0, int32_t iRight=0, int32_t iTop=0, int32_t iBottom=0); 129 void DrawEnergyLevelEx(int32_t iLevel, int32_t iRange, const C4Facet &gfx, int32_t bar_idx); // draw energy level using graphics 130 void DrawX(C4Surface * sfcTarget, float iX, float iY, float iWdt, float iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0) const; 131 void DrawXFloat(C4Surface * sfcTarget, float fX, float fY, float fWdt, float fHgt) const; 132 void DrawValue(C4Facet &cgo, int32_t iValue, int32_t iPhaseX=0, int32_t iPhaseY=0, int32_t iAlign=C4FCT_Center); 133 void DrawValue2(C4Facet &cgo, int32_t iValue1, int32_t iValue2, int32_t iPhaseX=0, int32_t iPhaseY=0, int32_t iAlign=C4FCT_Center, int32_t *piUsedWidth=nullptr); 134 void Draw(C4Facet &cgo, bool fAspect=true, int32_t iPhaseX=0, int32_t iPhaseY=0, bool fTransparent=true); 135 void DrawFullScreen(C4Facet &cgo); 136 void DrawT(C4Surface * sfcTarget, float iX, float iY, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform); // draw with transformation (if pTransform is assigned) 137 void DrawT(C4Facet &cgo, bool fAspect, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform); 138 void DrawTUnscaled(C4Surface * sfcTarget, float iX, float iY, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform); // interpret source coordinates as unscaled 139 void DrawTUnscaled(C4Facet &cgo, bool fAspect, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform); 140 void DrawXT(C4Surface * sfcTarget, float iX, float iY, int32_t iWdt, int32_t iHgt, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform); 141 void DrawClr(C4Facet &cgo, bool fAspect=true, DWORD dwClr=0); // set surface color and draw 142 void DrawXClr(C4Surface * sfcTarget, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, DWORD dwClr); // set surface color and draw 143 void DrawValue2Clr(C4Facet &cgo, int32_t iValue1, int32_t iValue2, DWORD dwClr); // set surface color and draw 144 void DrawXR(C4Surface * sfcTarget, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0, int32_t r=0); // draw rotated 145 void Draw(C4Surface * sfcTarget, float iX, float iY, int32_t iPhaseX=0, int32_t iPhaseY=0); 146 bool GetPhaseNum(int32_t &rX, int32_t &rY); // return number of phases in this graphic 147 C4Facet GetSection(int32_t iSection); 148 C4Facet GetPhase(int iPhaseX=0, int iPhaseY=0); 149 C4Facet GetFraction(int32_t percentWdt, int32_t percentHgt=0, int32_t alignX=C4FCT_Left, int32_t alignY=C4FCT_Top); 150 C4Facet TruncateSection(int32_t iAlign=C4FCT_Left); 151 C4Facet Truncate(int32_t iAlign, int32_t iSize); 152 int32_t GetSectionCount(); GetWidthByHeight(int32_t iHeight)153 int32_t GetWidthByHeight(int32_t iHeight) // calc width so it matches facet aspect to height 154 { return iHeight * Wdt / (Hgt ? Hgt : 1); } GetHeightByWidth(int32_t iWidth)155 int32_t GetHeightByWidth(int32_t iWidth) // calc height so it matches facet aspect to width 156 { return iWidth * Hgt / (Wdt ? Wdt : 1); } 157 }; 158 159 class C4TargetFacet: public C4Facet 160 { 161 public: C4TargetFacet()162 C4TargetFacet() { Default(); } 163 ~C4TargetFacet() = default; 164 public: 165 float TargetX,TargetY,Zoom; 166 167 // Reference values for parallax computations. This is similar to 168 // a scrolling position. In most cases these are the same as TargetX 169 // and TargetY, however for full map screenshots, which are composed 170 // of several individual screenshots, these are kept fixed while 171 // TargetX/TargetY are varied to cover the full map. This prevents 172 // duplicate parallax objects in fullscreen map screenshots. If 173 // TargetX/TargetY are different from ParRefX/ParRefY it can be thought 174 // of as drawing only a part of a window/viewport at a given fixed 175 // scroll position. 176 // See bug #1042. 177 float ParRefX, ParRefY; 178 public: Default()179 void Default() { TargetX=TargetY=0; Zoom=1; ParRefX=ParRefY=0; C4Facet::Default(); } Clear()180 void Clear() { Surface=nullptr; } 181 Set(const C4Facet & cpy)182 void Set(const C4Facet &cpy) { TargetX=TargetY=0; Zoom=1; ParRefX=ParRefY=0; C4Facet::Set(cpy); } Set(const C4TargetFacet & cpy)183 void Set(const C4TargetFacet &cpy) { *this = cpy; } 184 void Set(class C4Surface *nsfc, float nx, float ny, float nwdt, float nhgt, float ntx=0, float nty=0, float Zoom=1); 185 void Set(class C4Surface *nsfc, const C4Rect & r, float ntx=0, float nty=0, float Zoom=1); 186 void Set(class C4Surface *nsfc, float nx, float ny, float nwdt, float nhgt, float ntx, float nty, float Zoom, float prx, float pry); 187 188 public: 189 C4TargetFacet &operator = (const C4Facet& rhs) 190 { 191 Set(rhs.Surface,rhs.X,rhs.Y,rhs.Wdt,rhs.Hgt); 192 return *this; 193 } 194 void SetRect(C4TargetRect &rSrc); 195 }; 196 197 #endif // INC_C4Facet 198