OpenClonk
CSurface8.cpp
Go to the documentation of this file.
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) 2009-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 // a wrapper class to DirectDraw surfaces
18 
19 #include "C4Include.h"
20 #include "graphics/CSurface8.h"
21 
22 #include "graphics/Bitmap256.h"
23 #include "c4group/CStdFile.h"
24 #include "lib/StdColors.h"
25 
27 {
28  Wdt=Hgt=Pitch=0;
30  Bits=nullptr;
31  pPal=nullptr;
32 }
33 
34 CSurface8::CSurface8(int iWdt, int iHgt)
35 {
36  Wdt=Hgt=Pitch=0;
38  Bits=nullptr;
39  pPal=nullptr;
40  Create(iWdt, iHgt);
41 }
42 
44 {
45  Clear();
46 }
47 
49 {
50  // clear bitmap-copy
51  delete [] Bits; Bits=nullptr;
52  // clear pal
53  delete pPal;
54  pPal=nullptr;
55 }
56 
57 void CSurface8::Box(int iX, int iY, int iX2, int iY2, int iCol)
58 {
59  for (int cy=iY; cy<=iY2; cy++) HLine(iX,iX2,cy,iCol);
60 }
61 
63 {
64  ClipX=0; ClipY=0; ClipX2=Wdt-1; ClipY2=Hgt-1;
65 }
66 
67 void CSurface8::Clip(int iX, int iY, int iX2, int iY2)
68 {
69  ClipX=Clamp(iX,0,Wdt-1); ClipY=Clamp(iY,0,Hgt-1);
70  ClipX2=Clamp(iX2,0,Wdt-1); ClipY2=Clamp(iY2,0,Hgt-1);
71 }
72 
73 void CSurface8::HLine(int iX, int iX2, int iY, int iCol)
74 {
75  for (int cx=iX; cx<=iX2; cx++) SetPix(cx,iY,iCol);
76 }
77 
78 bool CSurface8::Create(int iWdt, int iHgt)
79 {
80  Clear();
81  // check size
82  if (!iWdt || !iHgt) return false;
83  Wdt=iWdt; Hgt=iHgt;
84 
85  // create pal
86  pPal = new CStdPalette;
87  if (!pPal) return false;
88  memset(pPal->Colors, 0, sizeof(pPal->Colors));
89 
90  Bits=new BYTE[Wdt*Hgt];
91  if (!Bits) return false;
92  memset(Bits, 0, Wdt*Hgt);
93  Pitch=Wdt;
94  // update clipping
95  NoClip();
96  return true;
97 }
98 
100 {
101  int cnt,lcnt;
102  C4BMP256Info BitmapInfo;
103  // read bmpinfo-header
104  if (!hGroup.Read(&BitmapInfo,sizeof(C4BMPInfo))) return false;
105  // is it 8bpp?
106  if (BitmapInfo.Info.biBitCount == 8)
107  {
108  if (!hGroup.Read(((BYTE *) &BitmapInfo)+sizeof(C4BMPInfo),sizeof(BitmapInfo)-sizeof(C4BMPInfo))) return false;
109  if (!hGroup.Advance(BitmapInfo.FileBitsOffset())) return false;
110  }
111  else
112  {
113  // read 24bpp
114  if (BitmapInfo.Info.biBitCount != 24) return false;
115  if (!hGroup.Advance(((C4BMPInfo) BitmapInfo).FileBitsOffset())) return false;
116  }
117 
118  // Create and lock surface
119  if (!Create(BitmapInfo.Info.biWidth,BitmapInfo.Info.biHeight)) return false;
120 
121  if (BitmapInfo.Info.biBitCount == 8)
122  {
123  // Copy palette
124  for (cnt=0; cnt<256; cnt++)
125  {
126  pPal->Colors[cnt] = C4RGB(BitmapInfo.Colors[cnt].rgbRed,
127  BitmapInfo.Colors[cnt].rgbGreen,
128  BitmapInfo.Colors[cnt].rgbBlue);
129  }
130  }
131 
132  // create line buffer
133  int iBufSize=DWordAligned(BitmapInfo.Info.biWidth*BitmapInfo.Info.biBitCount/8);
134  BYTE *pBuf = new BYTE[iBufSize];
135  // Read lines
136  for (lcnt=Hgt-1; lcnt>=0; lcnt--)
137  {
138  if (!hGroup.Read(pBuf, iBufSize))
139  { Clear(); delete [] pBuf; return false; }
140  BYTE *pPix=pBuf;
141  for (int x=0; x<BitmapInfo.Info.biWidth; ++x)
142  switch (BitmapInfo.Info.biBitCount)
143  {
144  case 8:
145  SetPix(x, lcnt, *pPix++);
146  break;
147  case 24:
148  return false;
149  break;
150  }
151  }
152  // free buffer again
153  delete [] pBuf;
154 
155  return true;
156 }
157 
158 bool CSurface8::Save(const char *szFilename, CStdPalette *bpPalette)
159 {
160  C4BMP256Info BitmapInfo;
161  BitmapInfo.Set(Wdt,Hgt, bpPalette ? bpPalette : pPal);
162 
163  // Create file & write info
164  CStdFile hFile;
165 
166  if ( !hFile.Create(szFilename)
167  || !hFile.Write(&BitmapInfo,sizeof(BitmapInfo)) )
168  { return false; }
169 
170  // Write lines
171  char bpEmpty[4]; ZeroMem(bpEmpty, 4);
172  const int iEmpty = DWordAligned(Wdt)-Wdt;
173  for (int cnt=Hgt-1; cnt>=0; cnt--)
174  {
175  if (!hFile.Write(Bits+(Pitch*cnt),Wdt))
176  { return false; }
177  if (iEmpty)
178  if (!hFile.Write(bpEmpty,iEmpty))
179  { return false; }
180  }
181 
182  // Close file
183  hFile.Close();
184 
185  // Success
186  return true;
187 }
188 
190 {
191  if (!bpMap) return;
192  for (int cnt=0; cnt<Wdt*Hgt; cnt++) SetPix(cnt%Wdt, cnt/Wdt, bpMap[GetPix(cnt%Wdt, cnt/Wdt)]);
193 }
194 
195 void CSurface8::GetSurfaceSize(int &irX, int &irY) const
196 {
197  // simply assign stored values
198  irX=Wdt;
199  irY=Hgt;
200 }
201 
202 void CSurface8::ClearBox8Only(int iX, int iY, int iWdt, int iHgt)
203 {
204  // clear rect; assume clip already
205  for (int y=iY; y<iY+iHgt; ++y)
206  for (int x=iX; x<iX+iWdt; ++x)
207  Bits[y*Pitch+x] = 0;
208  // done
209 }
210 
211 
212 void CSurface8::Circle(int x, int y, int r, BYTE col)
213 {
214  for (int ycnt=-r; ycnt<r; ycnt++)
215  {
216  int lwdt = (int) sqrt(float(r*r-ycnt*ycnt));
217  for (int xcnt = 2 * lwdt - 1; xcnt >= 0; xcnt--)
218  SetPix(x - lwdt + xcnt, y + ycnt, col);
219  }
220 }
221 
222 void CSurface8::AllowColor(BYTE iRngLo, BYTE iRngHi, bool fAllowZero)
223 {
224  // change colors
225  int xcnt,ycnt;
226  if (iRngHi<iRngLo) return;
227  for (ycnt=0; ycnt<Hgt; ycnt++)
228  {
229  for (xcnt=0; xcnt<Wdt; xcnt++)
230  {
231  BYTE px=GetPix(xcnt,ycnt);
232  if (px || !fAllowZero)
233  if ((px<iRngLo) || (px>iRngHi))
234  SetPix(xcnt, ycnt, iRngLo + px % (iRngHi-iRngLo+1));
235  }
236  }
237 }
238 
239 void CSurface8::SetBuffer(BYTE *pbyToBuf, int Wdt, int Hgt, int Pitch)
240 {
241  // release old
242  Clear();
243  // set new
244  this->Wdt=Wdt;
245  this->Hgt=Hgt;
246  this->Pitch=Pitch;
247  this->Bits = pbyToBuf;
248  NoClip();
249 }
250 
252 {
253  this->Bits = nullptr;
254  Clear();
255 }
BYTE rgbGreen
Definition: Bitmap256.h:53
BYTE rgbRed
Definition: Bitmap256.h:54
BYTE rgbBlue
Definition: Bitmap256.h:52
uint8_t BYTE
int DWordAligned(int val)
Definition: Standard.h:47
std::enable_if< std::is_pod< T >::value >::type ZeroMem(T *lpMem, size_t dwSize)
Definition: Standard.h:60
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
#define C4RGB(r, g, b)
Definition: StdColors.h:26
void Set(int iWdt, int iHgt, CStdPalette *)
Definition: Bitmap256.cpp:65
RGBQUAD Colors[256]
Definition: Bitmap256.h:76
BITMAPINFOHEADER Info
Definition: Bitmap256.h:67
bool Close(StdBuf **ppMemory=nullptr)
Definition: CStdFile.cpp:151
bool Create(const char *szFileName, bool fCompressed=false, bool fExecutable=false, bool fMemory=false)
Definition: CStdFile.cpp:49
bool Write(const void *pBuffer, int iSize)
Definition: CStdFile.cpp:240
virtual bool Read(void *pBuffer, size_t iSize)=0
virtual bool Advance(int iOffset)=0
void ClearBox8Only(int iX, int iY, int iWdt, int iHgt)
Definition: CSurface8.cpp:202
int ClipY
Definition: CSurface8.h:29
void Clip(int iX, int iY, int iX2, int iY2)
Definition: CSurface8.cpp:67
bool Save(const char *szFilename, CStdPalette *=nullptr)
Definition: CSurface8.cpp:158
CStdPalette * pPal
Definition: CSurface8.h:31
BYTE GetPix(int iX, int iY) const
Definition: CSurface8.h:49
void HLine(int iX, int iX2, int iY, int iCol)
Definition: CSurface8.cpp:73
int Pitch
Definition: CSurface8.h:28
bool Create(int iWdt, int iHgt)
Definition: CSurface8.cpp:78
void AllowColor(BYTE iRngLo, BYTE iRngHi, bool fAllowZero=false)
Definition: CSurface8.cpp:222
void Circle(int x, int y, int r, BYTE col)
Definition: CSurface8.cpp:212
int ClipY2
Definition: CSurface8.h:29
void GetSurfaceSize(int &irX, int &irY) const
Definition: CSurface8.cpp:195
void Box(int iX, int iY, int iX2, int iY2, int iCol)
Definition: CSurface8.cpp:57
void Clear()
Definition: CSurface8.cpp:48
void MapBytes(BYTE *bpMap)
Definition: CSurface8.cpp:189
void NoClip()
Definition: CSurface8.cpp:62
void SetPix(int iX, int iY, BYTE byCol)
Definition: CSurface8.h:37
int ClipX
Definition: CSurface8.h:29
BYTE * Bits
Definition: CSurface8.h:30
void ReleaseBuffer()
Definition: CSurface8.cpp:251
int Wdt
Definition: CSurface8.h:28
bool Read(class CStdStream &hGroup)
Definition: CSurface8.cpp:99
int ClipX2
Definition: CSurface8.h:29
int Hgt
Definition: CSurface8.h:28
void SetBuffer(BYTE *pbyToBuf, int Wdt, int Hgt, int Pitch)
Definition: CSurface8.cpp:239
DWORD Colors[256]
Definition: StdColors.h:186