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
|