aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r--engines/sci/graphics/celobj32.cpp67
-rw-r--r--engines/sci/graphics/celobj32.h28
-rw-r--r--engines/sci/graphics/controls32.cpp5
-rw-r--r--engines/sci/graphics/text32.cpp25
-rw-r--r--engines/sci/graphics/text32.h200
5 files changed, 220 insertions, 105 deletions
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index b839b44e92..79b1bb6fec 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -27,6 +27,7 @@
#include "sci/graphics/frameout.h"
#include "sci/graphics/palette32.h"
#include "sci/graphics/picture.h"
+#include "sci/graphics/text32.h"
#include "sci/graphics/view.h"
namespace Sci {
@@ -972,67 +973,23 @@ byte *CelObjPic::getResPointer() const {
#pragma mark -
#pragma mark CelObjMem
-void CelObjMem::buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) {
- const uint16 bitmapHeaderSize = getBitmapHeaderSize();
-
- WRITE_SCI11ENDIAN_UINT16(bitmap + 0, width);
- WRITE_SCI11ENDIAN_UINT16(bitmap + 2, height);
- WRITE_SCI11ENDIAN_UINT16(bitmap + 4, (uint16)displaceX);
- WRITE_SCI11ENDIAN_UINT16(bitmap + 6, (uint16)displaceY);
- bitmap[8] = skipColor;
- bitmap[9] = 0;
- WRITE_SCI11ENDIAN_UINT16(bitmap + 10, 0);
-
- if (useRemap) {
- bitmap[10] |= 2;
- }
-
- WRITE_SCI11ENDIAN_UINT32(bitmap + 12, width * height);
- WRITE_SCI11ENDIAN_UINT32(bitmap + 16, 0);
-
- if (hunkPaletteOffset) {
- WRITE_SCI11ENDIAN_UINT32(bitmap + 20, hunkPaletteOffset + bitmapHeaderSize);
- } else {
- WRITE_SCI11ENDIAN_UINT32(bitmap + 20, 0);
- }
-
- WRITE_SCI11ENDIAN_UINT32(bitmap + 24, bitmapHeaderSize);
- WRITE_SCI11ENDIAN_UINT32(bitmap + 28, bitmapHeaderSize);
- WRITE_SCI11ENDIAN_UINT32(bitmap + 32, 0);
-
- if (bitmapHeaderSize >= 40) {
- WRITE_SCI11ENDIAN_UINT16(bitmap + 36, scaledWidth);
- WRITE_SCI11ENDIAN_UINT16(bitmap + 38, scaledHeight);
- }
-}
-
-CelObjMem::CelObjMem(const reg_t bitmap) {
+CelObjMem::CelObjMem(const reg_t bitmapObject) {
_info.type = kCelTypeMem;
- _info.bitmap = bitmap;
+ _info.bitmap = bitmapObject;
_mirrorX = false;
_compressionType = kCelCompressionNone;
_celHeaderOffset = 0;
_transparent = true;
- const uint32 bitmapHeaderSize = getBitmapHeaderSize();
- byte *bitmapData = g_sci->getEngineState()->_segMan->getHunkPointer(bitmap);
- if (bitmapData == nullptr || READ_SCI11ENDIAN_UINT32(bitmapData + 28) != bitmapHeaderSize) {
- error("Invalid Text bitmap %04x:%04x", PRINT_REG(bitmap));
- }
-
- _width = READ_SCI11ENDIAN_UINT16(bitmapData);
- _height = READ_SCI11ENDIAN_UINT16(bitmapData + 2);
- _displace.x = READ_SCI11ENDIAN_UINT16(bitmapData + 4);
- _displace.y = READ_SCI11ENDIAN_UINT16(bitmapData + 6);
- _transparentColor = bitmapData[8];
- if (bitmapHeaderSize >= 40) {
- _scaledWidth = READ_SCI11ENDIAN_UINT16(bitmapData + 36);
- _scaledHeight = READ_SCI11ENDIAN_UINT16(bitmapData + 38);
- } else {
- error("TODO: SCI2 bitmaps not implemented yet!");
- }
- _hunkPaletteOffset = READ_SCI11ENDIAN_UINT16(bitmapData + 20);
- _remap = (READ_SCI11ENDIAN_UINT16(bitmapData + 10) & 2) ? true : false;
+ BitmapResource bitmap(bitmapObject);
+ _width = bitmap.getWidth();
+ _height = bitmap.getHeight();
+ _displace = bitmap.getDisplace();
+ _transparentColor = bitmap.getSkipColor();
+ _scaledWidth = bitmap.getScaledWidth();
+ _scaledHeight = bitmap.getScaledHeight();
+ _hunkPaletteOffset = bitmap.getHunkPaletteOffset();
+ _remap = bitmap.getRemap();
}
CelObjMem *CelObjMem::duplicate() const {
diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h
index 5707333818..1422b76a57 100644
--- a/engines/sci/graphics/celobj32.h
+++ b/engines/sci/graphics/celobj32.h
@@ -547,34 +547,6 @@ public:
*/
class CelObjMem : public CelObj {
public:
- /**
- * Writes a bitmap header to the given data buffer.
- */
- static void buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap);
-
- /**
- * Gets the size of the bitmap header for the current
- * engine version.
- */
- inline static uint32 getBitmapHeaderSize() {
- // TODO: These values are accurate for each engine, but there may be no reason
- // to not simply just always use size 40, since SCI2.1mid does not seem to
- // actually store any data above byte 40, and SCI2 did not allow bitmaps with
- // scaling resolutions other than the default (320x200). Perhaps SCI3 used
- // the extra bytes, or there is some reason why they tried to align the header
- // size with other headers like pic headers?
-// uint32 bitmapHeaderSize;
-// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) {
-// bitmapHeaderSize = 46;
-// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) {
-// bitmapHeaderSize = 40;
-// } else {
-// bitmapHeaderSize = 36;
-// }
-// return bitmapHeaderSize;
- return 46;
- }
-
CelObjMem(reg_t bitmap);
virtual ~CelObjMem() override {};
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
index 8d9f8a708f..a877d8c276 100644
--- a/engines/sci/graphics/controls32.cpp
+++ b/engines/sci/graphics/controls32.cpp
@@ -98,17 +98,16 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
editor.width = width;
if (editor.bitmap.isNull()) {
- reg_t out;
TextAlign alignment = (TextAlign)readSelectorValue(_segMan, controlObject, SELECTOR(mode));
if (titleObject.isNull()) {
bool dimmed = readSelectorValue(_segMan, controlObject, SELECTOR(dimmed));
- editor.bitmap = _gfxText32->createFontBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, dimmed, true, &out);
+ editor.bitmap = _gfxText32->createFontBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, dimmed, true);
} else {
Common::String title = _segMan->getString(titleObject);
int16 titleBackColor = readSelectorValue(_segMan, controlObject, SELECTOR(titleBack));
int16 titleForeColor = readSelectorValue(_segMan, controlObject, SELECTOR(titleFore));
- editor.bitmap = _gfxText32->createTitledBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, title, titleForeColor, titleBackColor, titleFontId, true, &out);
+ editor.bitmap = _gfxText32->createTitledBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, title, titleForeColor, titleBackColor, titleFontId, true);
}
}
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index d980f529de..fa19047a4c 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -59,7 +59,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts) :
_font = _cache->getFont(_defaultFontId);
}
-reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, reg_t *outBitmapObject) {
+reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling) {
_field_22 = 0;
_borderColor = borderColor;
@@ -97,10 +97,8 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
_textRect = Common::Rect();
}
- _bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize());
-
- byte *bitmap = _segMan->getHunkPointer(_bitmap);
- CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
+ BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
+ _bitmap = bitmap.getObject();
erase(bitmapRect, false);
@@ -109,12 +107,10 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
}
drawTextBox();
-
- *outBitmapObject = _bitmap;
return _bitmap;
}
-reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, reg_t *outBitmapObject) {
+reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed) {
_field_22 = 0;
_borderColor = borderColor;
_text = text;
@@ -142,11 +138,9 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
_textRect = Common::Rect();
}
- _bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize());
- byte *bitmap = _segMan->getHunkPointer(_bitmap);
- CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
-
- Buffer buffer(_width, _height, bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28));
+ BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);
+ _bitmap = bitmap.getObject();
+ Buffer buffer(_width, _height, bitmap.getPixels());
// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
// because then it just erased the bitmap using the skip color. So we don't
@@ -174,13 +168,12 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
}
}
- *outBitmapObject = _bitmap;
return _bitmap;
}
-reg_t GfxText32::createTitledBitmap(const int16 width, const int16 height, const Common::Rect &textRect, const Common::String &text, const int16 foreColor, const int16 backColor, const int16 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, Common::String &title, const int16 titleForeColor, const int16 titleBackColor, const GuiResourceId titleFontId, const bool doScaling, reg_t *outBitmapObject) {
+reg_t GfxText32::createTitledBitmap(const int16 width, const int16 height, const Common::Rect &textRect, const Common::String &text, const int16 foreColor, const int16 backColor, const int16 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, Common::String &title, const int16 titleForeColor, const int16 titleBackColor, const GuiResourceId titleFontId, const bool doScaling) {
warning("TODO: createTitledBitmap incomplete !");
- return createFontBitmap(width, height, textRect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, false, doScaling, outBitmapObject);
+ return createFontBitmap(width, height, textRect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, false, doScaling);
}
void GfxText32::setFont(const GuiResourceId fontId) {
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index 9e268e3485..f44035af7e 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -34,6 +34,200 @@ enum TextAlign {
kTextAlignRight = 2
};
+enum BitmapFlags {
+ kBitmapRemap = 2
+};
+
+#define BITMAP_PROPERTY(size, property, offset)\
+inline uint##size get##property() const {\
+ return READ_SCI11ENDIAN_UINT##size(_bitmap + (offset));\
+}\
+inline void set##property(uint##size value) {\
+ WRITE_SCI11ENDIAN_UINT##size(_bitmap + (offset), (value));\
+}
+
+/**
+ * A convenience class for creating and modifying in-memory
+ * bitmaps.
+ */
+class BitmapResource {
+ byte *_bitmap;
+ reg_t _object;
+
+ /**
+ * Gets the size of the bitmap header for the current
+ * engine version.
+ */
+ static inline uint16 getBitmapHeaderSize() {
+ // TODO: These values are accurate for each engine, but there may be no reason
+ // to not simply just always use size 40, since SCI2.1mid does not seem to
+ // actually store any data above byte 40, and SCI2 did not allow bitmaps with
+ // scaling resolutions other than the default (320x200). Perhaps SCI3 used
+ // the extra bytes, or there is some reason why they tried to align the header
+ // size with other headers like pic headers?
+// uint32 bitmapHeaderSize;
+// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) {
+// bitmapHeaderSize = 46;
+// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) {
+// bitmapHeaderSize = 40;
+// } else {
+// bitmapHeaderSize = 36;
+// }
+// return bitmapHeaderSize;
+ return 46;
+ }
+
+ /**
+ * Gets the byte size of a bitmap with the given width
+ * and height.
+ */
+ static inline uint32 getBitmapSize(const uint16 width, const uint16 height) {
+ return width * height + getBitmapHeaderSize();
+ }
+
+public:
+ /**
+ * Create a bitmap resource for an existing bitmap.
+ * Ownership of the bitmap is retained by the caller.
+ */
+ inline BitmapResource(reg_t bitmap) :
+ _bitmap(g_sci->getEngineState()->_segMan->getHunkPointer(bitmap)),
+ _object(bitmap) {
+ if (_bitmap == nullptr || getUncompressedDataOffset() != getBitmapHeaderSize()) {
+ error("Invalid Text bitmap %04x:%04x", PRINT_REG(bitmap));
+ }
+ }
+
+ /**
+ * Allocates and initialises a new bitmap in the given
+ * segment manager.
+ */
+ inline BitmapResource(SegManager *segMan, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool remap) {
+
+ _object = segMan->allocateHunkEntry("Bitmap()", getBitmapSize(width, height));
+ _bitmap = segMan->getHunkPointer(_object);
+
+ const uint16 bitmapHeaderSize = getBitmapHeaderSize();
+
+ setWidth(width);
+ setHeight(height);
+ setDisplace(Common::Point(displaceX, displaceY));
+ setSkipColor(skipColor);
+ _bitmap[9] = 0;
+ WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, 0);
+ setRemap(remap);
+ setDataSize(width * height);
+ WRITE_SCI11ENDIAN_UINT32(_bitmap + 16, 0);
+ setHunkPaletteOffset(hunkPaletteOffset);
+ setDataOffset(bitmapHeaderSize);
+ setUncompressedDataOffset(bitmapHeaderSize);
+ setControlOffset(0);
+ setScaledWidth(scaledWidth);
+ setScaledHeight(scaledHeight);
+ }
+
+ reg_t getObject() const {
+ return _object;
+ }
+
+ BITMAP_PROPERTY(16, Width, 0);
+ BITMAP_PROPERTY(16, Height, 2);
+
+ inline Common::Point getDisplace() const {
+ return Common::Point(
+ (int16)READ_SCI11ENDIAN_UINT16(_bitmap + 4),
+ (int16)READ_SCI11ENDIAN_UINT16(_bitmap + 6)
+ );
+ }
+
+ inline void setDisplace(const Common::Point &displace) {
+ WRITE_SCI11ENDIAN_UINT16(_bitmap + 4, (uint16)displace.x);
+ WRITE_SCI11ENDIAN_UINT16(_bitmap + 6, (uint16)displace.y);
+ }
+
+ inline uint8 getSkipColor() const {
+ return _bitmap[8];
+ }
+
+ inline void setSkipColor(const uint8 skipColor) {
+ _bitmap[8] = skipColor;
+ }
+
+ inline bool getRemap() const {
+ return READ_SCI11ENDIAN_UINT16(_bitmap + 10) & 2;
+ }
+
+ inline void setRemap(const bool remap) {
+ uint16 flags = READ_SCI11ENDIAN_UINT16(_bitmap + 10);
+ if (remap) {
+ flags |= 2;
+ } else {
+ flags &= ~2;
+ }
+ WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, flags);
+ }
+
+ BITMAP_PROPERTY(32, DataSize, 12);
+
+ inline uint32 getHunkPaletteOffset() const {
+ return READ_SCI11ENDIAN_UINT32(_bitmap + 20);
+ }
+
+ void setHunkPaletteOffset(uint32 hunkPaletteOffset) {
+ if (hunkPaletteOffset) {
+ hunkPaletteOffset += getBitmapHeaderSize();
+ }
+
+ WRITE_SCI11ENDIAN_UINT32(_bitmap + 20, hunkPaletteOffset);
+ }
+
+ BITMAP_PROPERTY(32, DataOffset, 24);
+
+ // NOTE: This property is used as a "magic number" for
+ // validating that a block of memory is a valid bitmap,
+ // and so is always set to the size of the header.
+ BITMAP_PROPERTY(32, UncompressedDataOffset, 28);
+
+ // NOTE: This property always seems to be zero
+ BITMAP_PROPERTY(32, ControlOffset, 32);
+
+ inline uint16 getScaledWidth() const {
+ if (getDataOffset() >= 40) {
+ return READ_SCI11ENDIAN_UINT16(_bitmap + 36);
+ }
+
+ // SCI2 bitmaps did not have scaling ability
+ return 320;
+ }
+
+ inline void setScaledWidth(uint16 scaledWidth) {
+ if (getDataOffset() >= 40) {
+ WRITE_SCI11ENDIAN_UINT16(_bitmap + 36, scaledWidth);
+ }
+ }
+
+ inline uint16 getScaledHeight() const {
+ if (getDataOffset() >= 40) {
+ return READ_SCI11ENDIAN_UINT16(_bitmap + 38);
+ }
+
+ // SCI2 bitmaps did not have scaling ability
+ return 200;
+ }
+
+ inline void setScaledHeight(uint16 scaledHeight) {
+ if (getDataOffset() >= 40) {
+ WRITE_SCI11ENDIAN_UINT16(_bitmap + 38, scaledHeight);
+ }
+ }
+
+ inline byte *getPixels() {
+ return _bitmap + getUncompressedDataOffset();
+ }
+};
+
+class GfxFont;
+
/**
* This class handles text calculation and rendering for
* SCI32 games. The text calculation system in SCI32 is
@@ -191,17 +385,17 @@ public:
* Creates a plain font bitmap with a flat color
* background.
*/
- reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling, reg_t *outBitmapObject);
+ reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling);
/**
* Creates a font bitmap with a view background.
*/
- reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, reg_t *outBitmapObject);
+ reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed);
/**
* Creates a font bitmap with a title.
*/
- reg_t createTitledBitmap(const int16 width, const int16 height, const Common::Rect &textRect, const Common::String &text, const int16 foreColor, const int16 backColor, const int16 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, Common::String &title, const int16 titleForeColor, const int16 titleBackColor, const GuiResourceId titleFontId, const bool doScaling, reg_t *outBitmapObject);
+ reg_t createTitledBitmap(const int16 width, const int16 height, const Common::Rect &textRect, const Common::String &text, const int16 foreColor, const int16 backColor, const int16 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, Common::String &title, const int16 titleForeColor, const int16 titleBackColor, const GuiResourceId titleFontId, const bool doScaling);
inline int scaleUpWidth(int value) const {
const int scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;