1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 //============================================================================= 24 // 25 // Allegro lib based bitmap 26 // 27 // TODO: probably should be moved to the Engine; check again when (if) it is 28 // clear that AGS.Native does not need allegro for drawing. 29 // 30 //============================================================================= 31 32 #ifndef AGS_SHARED_GFX_ALLEGRO_BITMAP_H 33 #define AGS_SHARED_GFX_ALLEGRO_BITMAP_H 34 35 #include "graphics/screen.h" 36 #include "ags/lib/allegro.h" // BITMAP 37 #include "ags/shared/core/types.h" 38 #include "ags/shared/gfx/bitmap.h" 39 #include "ags/shared/util/string.h" 40 41 namespace AGS3 { 42 namespace AGS { 43 namespace Shared { 44 45 class Bitmap { 46 public: 47 Bitmap(); 48 Bitmap(int width, int height, int color_depth = 0); 49 Bitmap(Bitmap *src, const Rect &rc); 50 Bitmap(BITMAP *al_bmp, bool shared_data); 51 ~Bitmap(); 52 53 // Allocate new bitmap 54 // CHECKME: color_depth = 0 is used to call Allegro's create_bitmap, which uses 55 // some global color depth setting; not sure if this is OK to use for generic class, 56 // revise this in future 57 bool Create(int width, int height, int color_depth = 0); 58 bool CreateTransparent(int width, int height, int color_depth = 0); 59 // Allow this object to share existing bitmap data 60 bool CreateSubBitmap(Bitmap *src, const Rect &rc); 61 // Create a copy of given bitmap 62 bool CreateCopy(Bitmap *src, int color_depth = 0); 63 // TODO: a temporary solution for plugin support 64 bool WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data); 65 // Deallocate bitmap 66 void Destroy(); 67 LoadFromFile(const String & filename)68 bool LoadFromFile(const String &filename) { 69 return LoadFromFile(filename.GetCStr()); 70 } 71 bool LoadFromFile(const char *filename); SaveToFile(const String & filename,const void * palette)72 bool SaveToFile(const String &filename, const void *palette) { 73 return SaveToFile(filename.GetCStr(), palette); 74 } 75 bool SaveToFile(Common::WriteStream &out, const void *palette); 76 bool SaveToFile(const char *filename, const void *palette); 77 78 // TODO: This is temporary solution for cases when we cannot replace 79 // use of raw BITMAP struct with Bitmap GetAllegroBitmap()80 inline BITMAP *GetAllegroBitmap() { 81 return _alBitmap; 82 } 83 84 // Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing IsMemoryBitmap()85 inline bool IsMemoryBitmap() const { 86 return true; 87 } 88 // Is this a video bitmap IsVideoBitmap()89 inline bool IsVideoBitmap() const { 90 return dynamic_cast<Graphics::Screen *>(_alBitmap) != nullptr; 91 } 92 // Is this a linear bitmap, the one that can be accessed linearly within each scanline IsLinearBitmap()93 inline bool IsLinearBitmap() const { 94 return true; 95 } 96 97 // Is this a subbitmap, referencing a part of another, bigger one? isSubBitmap()98 inline bool isSubBitmap() const { 99 return _alBitmap->isSubBitmap(); 100 } 101 102 // Checks if bitmap cannot be used IsNull()103 inline bool IsNull() const { 104 return !_alBitmap; 105 } 106 // Checks if bitmap has zero size: either width or height (or both) is zero IsEmpty()107 inline bool IsEmpty() const { 108 return GetWidth() == 0 || GetHeight() == 0; 109 } GetWidth()110 inline int GetWidth() const { 111 return _alBitmap->w; 112 } GetHeight()113 inline int GetHeight() const { 114 return _alBitmap->h; 115 } GetSize()116 inline Size GetSize() const { 117 return Size(_alBitmap->w, _alBitmap->h); 118 } 119 // Get sub-bitmap's offset position within its parent GetSubOffset()120 inline Point GetSubOffset() const { 121 Common::Point pt = _alBitmap->getOffsetFromOwner(); 122 return Point(pt.x, pt.y); 123 } GetColorDepth()124 inline int GetColorDepth() const { 125 return bitmap_color_depth(_alBitmap); 126 } 127 // BPP: bytes per pixel GetBPP()128 inline int GetBPP() const { 129 return (GetColorDepth() + 7) / 8; 130 } 131 132 // CHECKME: probably should not be exposed, see comment to GetData() GetDataSize()133 inline int GetDataSize() const { 134 return GetWidth() * GetHeight() * GetBPP(); 135 } 136 // Gets scanline length in bytes (is the same for any scanline) GetLineLength()137 inline int GetLineLength() const { 138 return GetWidth() * GetBPP(); 139 } 140 141 // TODO: replace with byte * 142 // Gets a pointer to underlying graphic data 143 // FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential GetData()144 inline const unsigned char *GetData() const { 145 return _alBitmap->getPixels(); 146 } 147 148 // Get scanline for direct reading GetScanLine(int index)149 inline const unsigned char *GetScanLine(int index) const { 150 return (index >= 0 && index < GetHeight()) ? _alBitmap->getBasePtr(0, index) : nullptr; 151 } GetScanLine(int index)152 inline unsigned char *GetScanLine(int index) { 153 return (index >= 0 && index < GetHeight()) ? (unsigned char *)_alBitmap->getBasePtr(0, index) : nullptr; 154 } 155 156 void SetMaskColor(color_t color); GetMaskColor()157 inline color_t GetMaskColor() const { 158 return bitmap_mask_color(_alBitmap); 159 } 160 161 // Converts AGS color-index into RGB color according to the bitmap format. 162 // TODO: this method was added to the Bitmap class during large refactoring, 163 // but that's a mistake, because in retrospect is has nothing to do with 164 // bitmap itself and should rather be a part of the game data logic. 165 color_t GetCompatibleColor(color_t color); 166 167 //========================================================================= 168 // Clipping 169 //========================================================================= 170 void SetClip(const Rect &rc); 171 void ResetClip(); 172 Rect GetClip() const; 173 174 //========================================================================= 175 // Blitting operations (drawing one bitmap over another) 176 //========================================================================= 177 // Draw other bitmap over current one 178 void Blit(Bitmap *src, int dst_x = 0, int dst_y = 0, BitmapMaskOption mask = kBitmap_Copy); 179 void Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask = kBitmap_Copy); 180 // Copy other bitmap, stretching or shrinking its size to given values 181 void StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); 182 void StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); 183 // Antia-aliased stretch-blit 184 void AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); 185 void AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); 186 // TODO: find more general way to call these operations, probably require pointer to Blending data struct? 187 // Draw bitmap using translucency preset 188 void TransBlendBlt(Bitmap *src, int dst_x, int dst_y); 189 // Draw bitmap using lighting preset 190 void LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount); 191 // TODO: generic "draw transformed" function? What about mask option? 192 void FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip); 193 void RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle); 194 void RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle); 195 196 //========================================================================= 197 // Pixel operations 198 //========================================================================= 199 // Fills the whole bitmap with given color (black by default) 200 void Clear(color_t color = 0); 201 void ClearTransparent(); 202 // The PutPixel and GetPixel are supposed to be safe and therefore 203 // relatively slow operations. They should not be used for changing large 204 // blocks of bitmap memory - reading/writing from/to scan lines should be 205 // done in such cases. 206 void PutPixel(int x, int y, color_t color); 207 int GetPixel(int x, int y) const; 208 209 //========================================================================= 210 // Vector drawing operations 211 //========================================================================= 212 void DrawLine(const Line &ln, color_t color); 213 void DrawTriangle(const Triangle &tr, color_t color); 214 void DrawRect(const Rect &rc, color_t color); 215 void FillRect(const Rect &rc, color_t color); 216 void FillCircle(const Circle &circle, color_t color); 217 // Fills the whole bitmap with given color 218 void Fill(color_t color); 219 void FillTransparent(); 220 // Floodfills an enclosed area, starting at point 221 void FloodFill(int x, int y, color_t color); 222 223 //========================================================================= 224 // Direct access operations 225 //========================================================================= 226 // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?) 227 // Gets scanline for directly writing into it GetScanLineForWriting(int index)228 inline unsigned char *GetScanLineForWriting(int index) { 229 return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; 230 } GetDataForWriting()231 inline unsigned char *GetDataForWriting() { 232 return _alBitmap->line[0]; 233 } 234 // Copies buffer contents into scanline 235 void SetScanLine(int index, unsigned char *data, int data_size = -1); 236 237 private: 238 BITMAP *_alBitmap; 239 bool _isDataOwner; 240 }; 241 242 243 244 namespace BitmapHelper { 245 // TODO: revise those functions later (currently needed in a few very specific cases) 246 // NOTE: the resulting object __owns__ bitmap data from now on 247 Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp); 248 // NOTE: the resulting object __does not own__ bitmap data 249 Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp); 250 } // namespace BitmapHelper 251 252 } // namespace Shared 253 } // namespace AGS 254 } // namespace AGS3 255 256 #endif 257