278 lines
11 KiB
C++
278 lines
11 KiB
C++
/* 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
|