File: allegro_bitmap.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (277 lines) | stat: -rw-r--r-- 11,178 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// Allegro lib based bitmap
//
// TODO: probably should be moved to the Engine; check again when (if) it is
// clear that AGS.Native does not need allegro for drawing.
//
//=============================================================================

#ifndef AGS_SHARED_GFX_ALLEGRO_BITMAP_H
#define AGS_SHARED_GFX_ALLEGRO_BITMAP_H

#include "graphics/screen.h"
#include "ags/lib/allegro.h" // BITMAP
#include "ags/shared/core/types.h"
#include "ags/shared/gfx/bitmap.h"
#include "ags/shared/util/string.h"

namespace AGS3 {
namespace AGS {
namespace Shared {

class Bitmap {
public:
	Bitmap();
	Bitmap(int width, int height, int color_depth = 0);
	Bitmap(Bitmap *src, const Rect &rc);
	Bitmap(BITMAP *al_bmp, bool shared_data);
	~Bitmap();

	// Allocate new bitmap.
	// NOTE: color_depth is in BITS per pixel (i.e. 8, 16, 24, 32...).
	// NOTE: in all of these color_depth may be passed as 0 in which case a default
	// color depth will be used (as previously set for the system).
	// TODO: color_depth = 0 is used to call Allegro's create_bitmap, which uses
	// some global color depth setting; not sure if this is OK to use for generic class,
	// revise this in future
	bool    Create(int width, int height, int color_depth = 0);
	// Create Bitmap and clear to transparent color
	bool    CreateTransparent(int width, int height, int color_depth = 0);
	// Creates a sub-bitmap of the given bitmap; the sub-bitmap is a reference to
	// particular region inside a parent.
	// WARNING: the parent bitmap MUST be kept in memory for as long as sub-bitmap exists!
	bool    CreateSubBitmap(Bitmap *src, const Rect &rc);
	// Resizes existing sub-bitmap within the borders of its parent
	bool    ResizeSubBitmap(int width, int height);
	// Creates a plain copy of the given bitmap, optionally converting to a different color depth;
	// pass color depth 0 to keep the original one.
	bool    CreateCopy(Bitmap *src, int color_depth = 0);
	// TODO: this is a temporary solution for plugin support
	// Wraps a raw allegro BITMAP object, optionally owns it (will delete on disposal)
	bool    WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data);
	// Deallocate bitmap
	void    Destroy();

	bool    LoadFromFile(const String &filename) {
		return LoadFromFile(filename.GetCStr());
	}
	bool    LoadFromFile(const char *filename);
	bool    LoadFromFile(PACKFILE *pf);
	bool    SaveToFile(const String &filename, const void *palette) {
		return SaveToFile(filename.GetCStr(), palette);
	}
	bool    SaveToFile(Common::WriteStream &out, const void *palette);
	bool    SaveToFile(const char *filename, const void *palette);

	// TODO: This is temporary solution for cases when we cannot replace
	// use of raw BITMAP struct with Bitmap
	inline BITMAP *GetAllegroBitmap() {
		return _alBitmap;
	}

	// Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing
	inline bool IsMemoryBitmap() const {
		return true;
	}
	// Is this a video bitmap
	inline bool IsVideoBitmap() const {
		return dynamic_cast<Graphics::Screen *>(_alBitmap) != nullptr;
	}
	// Is this a linear bitmap, the one that can be accessed linearly within each scanline
	inline bool IsLinearBitmap() const {
		return true;
	}

	// Is this a subbitmap, referencing a part of another, bigger one?
	inline bool isSubBitmap() const {
		return _alBitmap->isSubBitmap();
	}

	// Do both bitmaps share same data (usually: subbitmaps, or parent/subbitmap)
	inline bool IsSameBitmap(Bitmap *other) const {
		return is_same_bitmap(_alBitmap, other->_alBitmap) != 0;
	}

	// Checks if bitmap cannot be used
	inline bool IsNull() const {
		return !_alBitmap;
	}
	// Checks if bitmap has zero size: either width or height (or both) is zero
	inline bool IsEmpty() const {
		return GetWidth() == 0 || GetHeight() == 0;
	}
	inline int  GetWidth() const {
		return _alBitmap->w;
	}
	inline int  GetHeight() const {
		return _alBitmap->h;
	}
	inline Size GetSize() const {
		return Size(_alBitmap->w, _alBitmap->h);
	}
	// Get sub-bitmap's offset position within its parent
	inline Point GetSubOffset() const {
		Common::Point pt = _alBitmap->getOffsetFromOwner();
		return Point(pt.x, pt.y);
	}
	inline int  GetColorDepth() const {
		return bitmap_color_depth(_alBitmap);
	}
	// BPP: bytes per pixel
	inline int  GetBPP() const {
		return (GetColorDepth() + 7) / 8;
	}

	// CHECKME: probably should not be exposed, see comment to GetData()
	inline int  GetDataSize() const {
		return GetWidth() * GetHeight() * GetBPP();
	}
	// Gets scanline length in bytes (is the same for any scanline)
	inline int  GetLineLength() const {
		return GetWidth() * GetBPP();
	}

	// TODO: replace with byte *
	// Gets a pointer to underlying graphic data
	// FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential
	inline const unsigned char *GetData() const {
		return _alBitmap->getPixels();
	}

	// Get scanline for direct reading
	inline const unsigned char *GetScanLine(int index) const {
		assert(index >= 0 && index < GetHeight());
		return _alBitmap->getBasePtr(0, index);
	}
	inline unsigned char *GetScanLine(int index) {
		assert(index >= 0 && index < GetHeight());
		return (unsigned char *)_alBitmap->getBasePtr(0, index);
	}

	// Get bitmap's mask color (transparent color)
	inline color_t GetMaskColor() const {
		return bitmap_mask_color(_alBitmap);
	}

	// Converts AGS color-index into RGB color according to the bitmap format.
	// TODO: this method was added to the Bitmap class during large refactoring,
	// but that's a mistake, because in retrospect is has nothing to do with
	// bitmap itself and should rather be a part of the game data logic.
	color_t GetCompatibleColor(color_t color);

	//=========================================================================
	// Clipping
	// TODO: consider implementing push-pop clipping stack logic.
	//=========================================================================
	void    SetClip(const Rect &rc);
	void    ResetClip();
	Rect    GetClip() const;

	//=========================================================================
	// Blitting operations (drawing one bitmap over another)
	//=========================================================================
	// Draw other bitmap over current one
	void    Blit(Bitmap *src, int dst_x = 0, int dst_y = 0, BitmapMaskOption mask = kBitmap_Copy);
	void    Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask = kBitmap_Copy);
	// Draw other bitmap in a masked mode (kBitmap_Transparency)
	void    MaskedBlit(Bitmap *src, int dst_x, int dst_y);
	// Draw other bitmap, stretching or shrinking its size to given values
	void    StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
	void    StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
	// Antia-aliased stretch-blit
	void    AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
	void    AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy);
	// TODO: find more general way to call these operations, probably require pointer to Blending data struct?
	// Draw bitmap using translucency preset
	void    TransBlendBlt(Bitmap *src, int dst_x, int dst_y);
	// Draw bitmap using lighting preset
	void    LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount);
	// TODO: generic "draw transformed" function? What about mask option?
	void    FlipBlt(Bitmap *src, int dst_x, int dst_y, GraphicFlip flip);
	void    RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle);
	void    RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle);

	//=========================================================================
	// Pixel operations
	//=========================================================================
	// Fills the whole bitmap with given color (black by default)
	void    Clear(color_t color = 0);
	void    ClearTransparent();
	// The PutPixel and GetPixel are supposed to be safe and therefore
	// relatively slow operations. They should not be used for changing large
	// blocks of bitmap memory - reading/writing from/to scan lines should be
	// done in such cases.
	void    PutPixel(int x, int y, color_t color);
	int     GetPixel(int x, int y) const;

	//=========================================================================
	// Vector drawing operations
	//=========================================================================
	void    DrawLine(const Line &ln, color_t color);
	void    DrawTriangle(const Triangle &tr, color_t color);
	void    DrawRect(const Rect &rc, color_t color);
	void    FillRect(const Rect &rc, color_t color);
	void    FillCircle(const Circle &circle, color_t color);
	// Fills the whole bitmap with given color
	void    Fill(color_t color);
	void    FillTransparent();
	// Floodfills an enclosed area, starting at point
	void    FloodFill(int x, int y, color_t color);

	//=========================================================================
	// Direct access operations
	//=========================================================================
	// TODO: think how to increase safety over this (some fixed memory buffer class with iterator?)
	// Gets scanline for directly writing into it
	inline unsigned char *GetScanLineForWriting(int index) {
		assert(index >= 0 && index < GetHeight());
		return _alBitmap->line[index];
	}
	inline unsigned char *GetDataForWriting() {
		return _alBitmap->line[0];
	}
	// Copies buffer contents into scanline
	void    SetScanLine(int index, unsigned char *data, int data_size = -1);

private:
	BITMAP *_alBitmap;
	bool _isDataOwner;
};



namespace BitmapHelper {
// TODO: revise those functions later (currently needed in a few very specific cases)
// NOTE: the resulting object __owns__ bitmap data from now on
Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp);
// NOTE: the resulting object __does not own__ bitmap data
Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp);
} // namespace BitmapHelper

} // namespace Shared
} // namespace AGS
} // namespace AGS3

#endif