1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14 //
15 // Allegro lib based bitmap
16 //
17 // TODO: probably should be moved to the Engine; check again when (if) it is
18 // clear that AGS.Native does not need allegro for drawing.
19 //
20 //=============================================================================
21 #ifndef __AGS_CN_GFX__ALLEGROBITMAP_H
22 #define __AGS_CN_GFX__ALLEGROBITMAP_H
23 
24 #include <allegro.h>
25 #include "core/types.h"
26 #include "gfx/bitmap.h"
27 
28 namespace AGS
29 {
30 namespace Common
31 {
32 
33 class Bitmap
34 {
35 public:
36     Bitmap();
37     Bitmap(int width, int height, int color_depth = 0);
38     Bitmap(Bitmap *src, const Rect &rc);
39     Bitmap(BITMAP *al_bmp, bool shared_data);
40     ~Bitmap();
41 
42     // Allocate new bitmap
43     // CHECKME: color_depth = 0 is used to call Allegro's create_bitmap, which uses
44     // some global color depth setting; not sure if this is OK to use for generic class,
45     // revise this in future
46     bool    Create(int width, int height, int color_depth = 0);
47     bool    CreateTransparent(int width, int height, int color_depth = 0);
48     // Allow this object to share existing bitmap data
49     bool    CreateSubBitmap(Bitmap *src, const Rect &rc);
50     // Create a copy of given bitmap
51     bool	CreateCopy(Bitmap *src, int color_depth = 0);
52     // TODO: a temporary solution for plugin support
53     bool    WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data);
54     // Deallocate bitmap
55     void	Destroy();
56 
57     bool    LoadFromFile(const char *filename);
58     bool    SaveToFile(const char *filename, const void *palette);
59 
60     // TODO: This is temporary solution for cases when we cannot replace
61 	// use of raw BITMAP struct with Bitmap
GetAllegroBitmap()62     inline BITMAP *GetAllegroBitmap()
63     {
64         return _alBitmap;
65     }
66 
67     // TODO: also add generic GetBitmapType returning combination of flags
68 	// Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing
IsMemoryBitmap()69     inline bool IsMemoryBitmap() const
70     {
71         return is_memory_bitmap(_alBitmap) != 0;
72     }
73     // Is this a linear bitmap, the one that can be accessed linearly within each scanline
IsLinearBitmap()74 	inline bool IsLinearBitmap() const
75     {
76         return is_linear_bitmap(_alBitmap) != 0;
77     }
78 
79     // Checks if bitmap cannot be used
IsNull()80     inline bool IsNull() const
81     {
82         return !_alBitmap;
83     }
84     // Checks if bitmap has zero size: either width or height (or both) is zero
IsEmpty()85     inline bool IsEmpty() const
86     {
87         return GetWidth() == 0 || GetHeight() == 0;
88     }
GetWidth()89     inline int  GetWidth() const
90     {
91         return _alBitmap->w;
92     }
GetHeight()93     inline int  GetHeight() const
94     {
95         return _alBitmap->h;
96     }
GetSize()97     inline Size GetSize() const
98     {
99         return Size(_alBitmap->w, _alBitmap->h);
100     }
GetColorDepth()101     inline int  GetColorDepth() const
102     {
103         return bitmap_color_depth(_alBitmap);
104     }
105     // BPP: bytes per pixel
GetBPP()106     inline int  GetBPP() const
107     {
108         return (GetColorDepth() + 7) / 8;
109     }
110 
111     // CHECKME: probably should not be exposed, see comment to GetData()
GetDataSize()112 	inline int  GetDataSize() const
113     {
114         return GetWidth() * GetHeight() * GetBPP();
115     }
116     // Gets scanline length in bytes (is the same for any scanline)
GetLineLength()117 	inline int  GetLineLength() const
118     {
119         return GetWidth() * GetBPP();
120     }
121 
122 	// TODO: replace with byte *
123 	// Gets a pointer to underlying graphic data
124 	// FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential
GetData()125     inline const unsigned char *GetData() const
126     {
127         return _alBitmap->line[0];
128     }
129 
130     // Get scanline for direct reading
GetScanLine(int index)131 	inline const unsigned char *GetScanLine(int index) const
132     {
133         return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : NULL;
134     }
135 
136     void    SetMaskColor(color_t color);
GetMaskColor()137 	inline color_t GetMaskColor() const
138     {
139         return bitmap_mask_color(_alBitmap);
140     }
141 
142     // FIXME: allegro manual states these should not be used externally;
143 	// should hide or totally remove those later
144     void    Acquire();
145 	void	Release();
146 
147     color_t GetCompatibleColor(color_t color);
148 
149     //=========================================================================
150     // Clipping
151     //=========================================================================
152     void    SetClip(const Rect &rc);
153     Rect    GetClip() const;
154 
155     //=========================================================================
156     // Blitting operations (drawing one bitmap over another)
157     //=========================================================================
158     // Draw other bitmap over current one
159     void    Blit(Bitmap *src, int dst_x = 0, int dst_y = 0, BitmapMaskOption mask = kBitmap_Copy);
160     void    Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask = kBitmap_Copy);
161     // Copy other bitmap, stretching or shrinking its size to given values
162     void    StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
163     void    StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
164     // Antia-aliased stretch-blit
165     void    AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
166     void    AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
167     // TODO: find more general way to call these operations, probably require pointer to Blending data struct?
168     // Draw bitmap using translucency preset
169     void    TransBlendBlt(Bitmap *src, int dst_x, int dst_y);
170     // Draw bitmap using lighting preset
171     void    LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount);
172     // TODO: generic "draw transformed" function? What about mask option?
173     void    FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip);
174     void    RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle);
175     void    RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle);
176 
177     //=========================================================================
178     // Pixel operations
179     //=========================================================================
180     // Fills the whole bitmap with given color (black by default)
181     void	Clear(color_t color = 0);
182     void    ClearTransparent();
183     // The PutPixel and GetPixel are supposed to be safe and therefore
184     // relatively slow operations. They should not be used for changing large
185     // blocks of bitmap memory - reading/writing from/to scan lines should be
186     // done in such cases.
187     void	PutPixel(int x, int y, color_t color);
188     int		GetPixel(int x, int y) const;
189 
190     //=========================================================================
191     // Vector drawing operations
192     //=========================================================================
193     void    DrawLine(const Line &ln, color_t color);
194     void    DrawTriangle(const Triangle &tr, color_t color);
195     void    DrawRect(const Rect &rc, color_t color);
196     void    FillRect(const Rect &rc, color_t color);
197     void    FillCircle(const Circle &circle, color_t color);
198     // Fills the whole bitmap with given color
199     void    Fill(color_t color);
200     void    FillTransparent();
201     // Floodfills an enclosed area, starting at point
202     void    FloodFill(int x, int y, color_t color);
203 
204 	//=========================================================================
205 	// Direct access operations
206 	//=========================================================================
207     // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?)
208 	// Gets scanline for directly writing into it
GetScanLineForWriting(int index)209     inline unsigned char *GetScanLineForWriting(int index)
210     {
211         return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : NULL;
212     }
GetDataForWriting()213     inline unsigned char *GetDataForWriting()
214     {
215         return _alBitmap->line[0];
216     }
217     // Copies buffer contents into scanline
218     void    SetScanLine(int index, unsigned char *data, int data_size = -1);
219 
220 private:
221 	BITMAP			*_alBitmap;
222 	bool			_isDataOwner;
223 };
224 
225 
226 
227 namespace BitmapHelper
228 {
229     // TODO: revise those functions later (currently needed in a few very specific cases)
230 	// NOTE: the resulting object __owns__ bitmap data from now on
231 	Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp);
232 	// NOTE: the resulting object __does not own__ bitmap data
233 	Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp);
234 } // namespace BitmapHelper
235 
236 } // namespace Common
237 } // namespace AGS
238 
239 #endif // __AGS_CN_GFX__ALLEGROBITMAP_H
240