aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorColin Snover2016-07-29 15:48:14 -0500
committerColin Snover2016-08-01 10:37:14 -0500
commit2071196f4235c75ff020605f53b3d397532e841a (patch)
treeaaae025e3e221e29e7d0c2f2b9c48f4e760caf6e /engines
parent4e31c9aaf4aa36b6fea039d1779317e6a943e68b (diff)
downloadscummvm-rg350-2071196f4235c75ff020605f53b3d397532e841a.tar.gz
scummvm-rg350-2071196f4235c75ff020605f53b3d397532e841a.tar.bz2
scummvm-rg350-2071196f4235c75ff020605f53b3d397532e841a.zip
SCI32: Add bitmap segment and remove GC option from hunk segment
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/console.cpp15
-rw-r--r--engines/sci/engine/gc.cpp12
-rw-r--r--engines/sci/engine/kernel.cpp1
-rw-r--r--engines/sci/engine/kgraphics32.cpp17
-rw-r--r--engines/sci/engine/kscripts.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp22
-rw-r--r--engines/sci/engine/savegame.h3
-rw-r--r--engines/sci/engine/seg_manager.cpp59
-rw-r--r--engines/sci/engine/seg_manager.h14
-rw-r--r--engines/sci/engine/segment.cpp14
-rw-r--r--engines/sci/engine/segment.h240
-rw-r--r--engines/sci/graphics/celobj32.cpp4
-rw-r--r--engines/sci/graphics/controls32.cpp4
-rw-r--r--engines/sci/graphics/paint16.cpp2
-rw-r--r--engines/sci/graphics/paint32.cpp20
-rw-r--r--engines/sci/graphics/paint32.h6
-rw-r--r--engines/sci/graphics/palette.cpp2
-rw-r--r--engines/sci/graphics/text32.cpp26
-rw-r--r--engines/sci/graphics/text32.h204
-rw-r--r--engines/sci/graphics/transitions32.cpp11
-rw-r--r--engines/sci/graphics/video32.cpp7
21 files changed, 419 insertions, 266 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 6acb467b50..3e67a1819a 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -1984,7 +1984,7 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
byte bakMask = GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY | GFX_SCREEN_MASK_CONTROL;
int bakSize = _engine->_gfxScreen->bitsGetDataSize(rect, bakMask);
- reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize, true);
+ reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize);
byte* bakMemory = segman->getHunkPointer(bakScreen);
assert(bakMemory);
_engine->_gfxScreen->bitsSave(rect, bakMask, bakMemory);
@@ -2080,6 +2080,10 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
case SEG_TYPE_STRING:
debugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used);
break;
+
+ case SEG_TYPE_BITMAP:
+ debugPrintf("T SCI32 bitmaps (%d)", (*(BitmapTable *)mobj).entries_used);
+ break;
#endif
default:
@@ -2214,6 +2218,9 @@ bool Console::segmentInfo(int nr) {
case SEG_TYPE_ARRAY:
debugPrintf("SCI32 arrays\n");
break;
+ case SEG_TYPE_BITMAP:
+ debugPrintf("SCI32 bitmaps\n");
+ break;
#endif
default :
@@ -2815,6 +2822,12 @@ bool Console::cmdViewReference(int argc, const char **argv) {
hexDumpReg(array->getRawData(), array->getSize(), 4, 0, true);
break;
}
+ case SEG_TYPE_BITMAP: {
+ debugPrintf("SCI32 bitmap:\n");
+ const SciBitmap *bitmap = _engine->_gamestate->_segMan->lookupBitmap(reg);
+ Common::hexdump((const byte *) bitmap->getRawData(), bitmap->getRawSize(), 16, 0);
+ break;
+ }
#endif
default: {
const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg);
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index e0467e9461..ad4fd19405 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -154,16 +154,18 @@ AddrSet *findAllActiveReferences(EngineState *s) {
}
}
- // Init: Explicitly opted-out hunks
- else if (heap[i]->getType() == SEG_TYPE_HUNK) {
- HunkTable *ht = static_cast<HunkTable *>(heap[i]);
+#ifdef ENABLE_SCI32
+ // Init: Explicitly opted-out bitmaps
+ else if (heap[i]->getType() == SEG_TYPE_BITMAP) {
+ BitmapTable *bt = static_cast<BitmapTable *>(heap[i]);
- for (uint j = 0; j < ht->_table.size(); j++) {
- if (!ht->_table[j].data.gc) {
+ for (uint j = 0; j < bt->_table.size(); j++) {
+ if (!bt->_table[j].data.getShouldGC()) {
wm.push(make_reg(i, j));
}
}
}
+#endif
}
}
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 2afb8b73d1..d764a88a0a 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -408,6 +408,7 @@ uint16 Kernel::findRegType(reg_t reg) {
#ifdef ENABLE_SCI32
case SEG_TYPE_ARRAY:
case SEG_TYPE_STRING:
+ case SEG_TYPE_BITMAP:
#endif
result |= SIG_TYPE_REFERENCE;
break;
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 44085da6e7..e458109cc2 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -536,13 +536,14 @@ reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) {
int16 scaledHeight = argc > 5 ? argv[5].toSint16() : g_sci->_gfxText32->_scaledHeight;
bool useRemap = argc > 6 ? argv[6].toSint16() : false;
- BitmapResource bitmap(s->_segMan, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap, true);
+ reg_t bitmapId;
+ SciBitmap &bitmap = *s->_segMan->allocateBitmap(&bitmapId, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap, true);
memset(bitmap.getPixels(), backColor, width * height);
- return bitmap.getObject();
+ return bitmapId;
}
reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) {
- s->_segMan->freeHunkEntry(argv[0]);
+ s->_segMan->freeBitmap(argv[0]);
return s->r_acc;
}
@@ -552,7 +553,7 @@ reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv) {
}
reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) {
- BitmapResource bitmap(argv[0]);
+ SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
CelObjView view(argv[1].toUint16(), argv[2].toSint16(), argv[3].toSint16());
const int16 x = argc > 4 ? argv[4].toSint16() : 0;
@@ -582,7 +583,7 @@ reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) {
reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
// called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894
- BitmapResource bitmap(argv[0]);
+ SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
Common::String text = s->_segMan->getString(argv[1]);
Common::Rect textRect(
argv[2].toSint16(),
@@ -609,7 +610,7 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
reg_t textBitmapObject = g_sci->_gfxText32->createFontBitmap(textRect.width(), textRect.height(), Common::Rect(textRect.width(), textRect.height()), text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, false, false);
CelObjMem textCel(textBitmapObject);
textCel.draw(bitmap.getBuffer(), textRect, Common::Point(textRect.left, textRect.top), false);
- s->_segMan->freeHunkEntry(textBitmapObject);
+ s->_segMan->freeBitmap(textBitmapObject);
return s->r_acc;
}
@@ -617,7 +618,7 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) {
// called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890
- BitmapResource bitmap(argv[0]);
+ SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
Common::Rect fillRect(
argv[1].toSint16(),
argv[2].toSint16(),
@@ -642,7 +643,7 @@ reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv) {
}
reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv) {
- BitmapResource bitmap(argv[0]);
+ SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
bitmap.setDisplace(Common::Point(argv[1].toSint16(), argv[2].toSint16()));
return s->r_acc;
}
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 42e7a2028f..6fd130bceb 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -40,7 +40,7 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) {
// Request to dynamically allocate hunk memory for later use
if (restype == kResourceTypeMemory)
- return s->_segMan->allocateHunkEntry("kLoad()", resnr, true);
+ return s->_segMan->allocateHunkEntry("kLoad()", resnr);
return make_reg(0, ((restype << 11) | resnr)); // Return the resource identifier as handle
}
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 31fb848a2c..f49853de2f 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -158,6 +158,18 @@ void syncWithSerializer(Common::Serializer &s, SciString &obj) {
obj.setValue(i, value);
}
}
+
+void syncWithSerializer(Common::Serializer &s, SciBitmap &obj) {
+ debug("TODO: Sync bitmap");
+
+// if (s.isSaving()) {
+// size = obj.getSize();
+// s.syncAsUint32LE(size);
+// } else {
+// s.syncAsUint32LE(size);
+// obj.setSize(size);
+// }
+}
#endif
#pragma mark -
@@ -273,6 +285,8 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
} else if (type == SEG_TYPE_STRING) {
// Set the correct segment for SCI32 strings
_stringSegId = i;
+ } else if (s.getVersion() >= 36 && type == SEG_TYPE_BITMAP) {
+ _bitmapSegId = i;
#endif
}
@@ -687,6 +701,14 @@ void StringTable::saveLoadWithSerializer(Common::Serializer &ser) {
sync_Table<StringTable>(ser, *this);
}
+
+void BitmapTable::saveLoadWithSerializer(Common::Serializer &ser) {
+ if (ser.getVersion() < 36)
+ return;
+
+ // TODO: Should only include bitmaps with gc = true
+ sync_Table(ser, *this);
+}
#endif
void GfxPalette::palVarySaveLoadPalette(Common::Serializer &s, Palette *palette) {
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 43909accf2..c5c2bcef08 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 36 - SCI32 bitmap segment
* 35 - SCI32 remap
* 34 - SCI32 palettes, and store play time in ticks
* 33 - new overridePriority flag in MusicEntry
@@ -60,7 +61,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 35,
+ CURRENT_SAVEGAME_VERSION = 36,
MINIMUM_SAVEGAME_VERSION = 14
};
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index e6692060b6..67da4c847d 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -43,6 +43,7 @@ SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher)
#ifdef ENABLE_SCI32
_arraysSegId = 0;
_stringSegId = 0;
+ _bitmapSegId = 0;
#endif
createClassTable();
@@ -72,6 +73,7 @@ void SegManager::resetSegMan() {
#ifdef ENABLE_SCI32
_arraysSegId = 0;
_stringSegId = 0;
+ _bitmapSegId = 0;
#endif
// Reinitialize class table
@@ -393,7 +395,7 @@ void SegManager::freeHunkEntry(reg_t addr) {
ht->freeEntryContents(addr.getOffset());
}
-reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size, bool gc) {
+reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
HunkTable *table;
int offset;
@@ -412,7 +414,6 @@ reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size, bool gc) {
h->mem = malloc(size);
h->size = size;
h->type = hunk_type;
- h->gc = gc;
return addr;
}
@@ -942,6 +943,60 @@ void SegManager::freeString(reg_t addr) {
stringTable.freeEntry(addr.getOffset());
}
+#pragma mark -
+#pragma mark Bitmaps
+
+SciBitmap *SegManager::allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) {
+ BitmapTable *table;
+ int offset;
+
+ if (!_bitmapSegId) {
+ table = (BitmapTable *)allocSegment(new BitmapTable(), &(_bitmapSegId));
+ } else {
+ table = (BitmapTable *)_heap[_bitmapSegId];
+ }
+
+ offset = table->allocEntry();
+
+ *addr = make_reg(_bitmapSegId, offset);
+ SciBitmap *bitmap = &table->at(offset);
+
+ if (bitmap == nullptr) {
+ *addr = NULL_REG;
+ }
+
+ bitmap->create(width, height, skipColor, displaceX, displaceY, scaledWidth, scaledHeight, paletteSize, remap, gc);
+
+ return bitmap;
+}
+
+SciBitmap *SegManager::lookupBitmap(const reg_t addr) {
+ if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP)
+ error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
+
+ BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()];
+
+ if (!bitmapTable.isValidEntry(addr.getOffset()))
+ error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
+
+ return &(bitmapTable.at(addr.getOffset()));
+}
+
+void SegManager::freeBitmap(const reg_t addr) {
+ if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP)
+ error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
+
+ BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()];
+
+ if (!bitmapTable.isValidEntry(addr.getOffset()))
+ error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
+
+ bitmapTable.at(addr.getOffset()).destroy();
+ bitmapTable.freeEntry(addr.getOffset());
+}
+
+#pragma mark -
+
#endif
void SegManager::createClassTable() {
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index ba2ba33a6a..acebecea97 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -29,6 +29,10 @@
#include "sci/engine/vm.h"
#include "sci/engine/vm_types.h"
#include "sci/engine/segment.h"
+#ifdef ENABLE_SCI32
+// TODO: Baaaad?
+#include "sci/graphics/celobj32.h"
+#endif
namespace Sci {
@@ -225,11 +229,9 @@ public:
* @param[in] size Number of bytes to allocate for the hunk entry
* @param[in] hunk_type A descriptive string for the hunk entry, for
* debugging purposes
- * @param[in] gc Whether to make the hunk eligible for garbage
- * collection
* @return The offset of the freshly allocated hunk entry
*/
- reg_t allocateHunkEntry(const char *hunk_type, int size, bool gc);
+ reg_t allocateHunkEntry(const char *hunk_type, int size);
/**
* Deallocates a hunk entry
@@ -435,10 +437,15 @@ public:
SciArray<reg_t> *allocateArray(reg_t *addr);
SciArray<reg_t> *lookupArray(reg_t addr);
void freeArray(reg_t addr);
+
SciString *allocateString(reg_t *addr);
SciString *lookupString(reg_t addr);
void freeString(reg_t addr);
SegmentId getStringSegmentId() { return _stringSegId; }
+
+ SciBitmap *allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor = kDefaultSkipColor, const int16 displaceX = 0, const int16 displaceY = 0, const int16 scaledWidth = kLowResX, const int16 scaledHeight = kLowResY, const uint32 paletteSize = 0, const bool remap = false, const bool gc = true);
+ SciBitmap *lookupBitmap(reg_t addr);
+ void freeBitmap(reg_t addr);
#endif
const Common::Array<SegmentObj *> &getSegments() const { return _heap; }
@@ -464,6 +471,7 @@ private:
#ifdef ENABLE_SCI32
SegmentId _arraysSegId;
SegmentId _stringSegId;
+ SegmentId _bitmapSegId;
#endif
public:
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 2cff799f4b..7f690cb7c4 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -70,6 +70,9 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) {
case SEG_TYPE_STRING:
mem = new StringTable();
break;
+ case SEG_TYPE_BITMAP:
+ mem = new BitmapTable();
+ break;
#endif
default:
error("Unknown SegmentObj type %d", type);
@@ -310,6 +313,17 @@ SegmentRef StringTable::dereference(reg_t pointer) {
return ret;
}
+#pragma mark -
+#pragma mark Bitmaps
+
+SegmentRef BitmapTable::dereference(reg_t pointer) {
+ SegmentRef ret;
+ ret.isRaw = true;
+ ret.maxSize = at(pointer.getOffset()).getRawSize();
+ ret.raw = at(pointer.getOffset()).getRawData();
+ return ret;
+}
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 6c94c24ff9..c25ede1d6a 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -71,6 +71,7 @@ enum SegmentType {
#ifdef ENABLE_SCI32
SEG_TYPE_ARRAY = 11,
SEG_TYPE_STRING = 12,
+ SEG_TYPE_BITMAP = 13,
#endif
SEG_TYPE_MAX // For sanity checking
@@ -205,7 +206,6 @@ struct Hunk {
void *mem;
uint32 size;
const char *type;
- bool gc;
};
template<typename T>
@@ -520,6 +520,244 @@ struct StringTable : public SegmentObjTable<SciString> {
SegmentRef dereference(reg_t pointer);
};
+#pragma mark -
+#pragma mark Bitmaps
+
+enum {
+ kDefaultSkipColor = 250
+};
+
+#define BITMAP_PROPERTY(size, property, offset)\
+inline uint##size get##property() const {\
+ return READ_SCI11ENDIAN_UINT##size(_data + (offset));\
+}\
+inline void set##property(uint##size value) {\
+ WRITE_SCI11ENDIAN_UINT##size(_data + (offset), (value));\
+}
+
+/**
+ * A convenience class for creating and modifying in-memory
+ * bitmaps.
+ */
+class SciBitmap {
+ byte *_data;
+ int _dataSize;
+ Buffer _buffer;
+ bool _gc;
+
+public:
+ enum BitmapFlags {
+ kBitmapRemap = 2
+ };
+
+ /**
+ * 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();
+ }
+
+ inline SciBitmap() : _data(nullptr), _dataSize(0), _gc(true) {}
+
+ /**
+ * Allocates and initialises a new bitmap.
+ */
+ inline void create(const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) {
+
+ _dataSize = getBitmapSize(width, height) + paletteSize;
+ _data = (byte *)realloc(_data, _dataSize);
+ _gc = gc;
+
+ const uint16 bitmapHeaderSize = getBitmapHeaderSize();
+
+ setWidth(width);
+ setHeight(height);
+ setDisplace(Common::Point(displaceX, displaceY));
+ setSkipColor(skipColor);
+ _data[9] = 0;
+ WRITE_SCI11ENDIAN_UINT16(_data + 10, 0);
+ setRemap(remap);
+ setDataSize(width * height);
+ WRITE_SCI11ENDIAN_UINT32(_data + 16, 0);
+ setHunkPaletteOffset(paletteSize > 0 ? (width * height) : 0);
+ setDataOffset(bitmapHeaderSize);
+ setUncompressedDataOffset(bitmapHeaderSize);
+ setControlOffset(0);
+ setScaledWidth(scaledWidth);
+ setScaledHeight(scaledHeight);
+
+ _buffer = Buffer(getWidth(), getHeight(), getPixels());
+ }
+
+ inline void destroy() {
+ free(_data);
+ _data = nullptr;
+ _dataSize = 0;
+ }
+
+ inline int getRawSize() const {
+ return _dataSize;
+ }
+
+ inline byte *getRawData() const {
+ return _data;
+ }
+
+ inline Buffer &getBuffer() {
+ return _buffer;
+ }
+
+ inline bool getShouldGC() const {
+ return _gc;
+ }
+
+ inline void enableGC() {
+ _gc = true;
+ }
+
+ inline void disableGC() {
+ _gc = false;
+ }
+
+ BITMAP_PROPERTY(16, Width, 0);
+ BITMAP_PROPERTY(16, Height, 2);
+
+ inline Common::Point getDisplace() const {
+ return Common::Point(
+ (int16)READ_SCI11ENDIAN_UINT16(_data + 4),
+ (int16)READ_SCI11ENDIAN_UINT16(_data + 6)
+ );
+ }
+
+ inline void setDisplace(const Common::Point &displace) {
+ WRITE_SCI11ENDIAN_UINT16(_data + 4, (uint16)displace.x);
+ WRITE_SCI11ENDIAN_UINT16(_data + 6, (uint16)displace.y);
+ }
+
+ inline uint8 getSkipColor() const {
+ return _data[8];
+ }
+
+ inline void setSkipColor(const uint8 skipColor) {
+ _data[8] = skipColor;
+ }
+
+ inline bool getRemap() const {
+ return READ_SCI11ENDIAN_UINT16(_data + 10) & kBitmapRemap;
+ }
+
+ inline void setRemap(const bool remap) {
+ uint16 flags = READ_SCI11ENDIAN_UINT16(_data + 10);
+ if (remap) {
+ flags |= kBitmapRemap;
+ } else {
+ flags &= ~kBitmapRemap;
+ }
+ WRITE_SCI11ENDIAN_UINT16(_data + 10, flags);
+ }
+
+ BITMAP_PROPERTY(32, DataSize, 12);
+
+ inline uint32 getHunkPaletteOffset() const {
+ return READ_SCI11ENDIAN_UINT32(_data + 20);
+ }
+
+ inline void setHunkPaletteOffset(uint32 hunkPaletteOffset) {
+ if (hunkPaletteOffset) {
+ hunkPaletteOffset += getBitmapHeaderSize();
+ }
+
+ WRITE_SCI11ENDIAN_UINT32(_data + 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(_data + 36);
+ }
+
+ // SCI2 bitmaps did not have scaling ability
+ return 320;
+ }
+
+ inline void setScaledWidth(uint16 scaledWidth) {
+ if (getDataOffset() >= 40) {
+ WRITE_SCI11ENDIAN_UINT16(_data + 36, scaledWidth);
+ }
+ }
+
+ inline uint16 getScaledHeight() const {
+ if (getDataOffset() >= 40) {
+ return READ_SCI11ENDIAN_UINT16(_data + 38);
+ }
+
+ // SCI2 bitmaps did not have scaling ability
+ return 200;
+ }
+
+ inline void setScaledHeight(uint16 scaledHeight) {
+ if (getDataOffset() >= 40) {
+ WRITE_SCI11ENDIAN_UINT16(_data + 38, scaledHeight);
+ }
+ }
+
+ inline byte *getPixels() {
+ return _data + getUncompressedDataOffset();
+ }
+
+ inline byte *getHunkPalette() {
+ if (getHunkPaletteOffset() == 0) {
+ return nullptr;
+ }
+ return _data + getHunkPaletteOffset();
+ }
+};
+
+struct BitmapTable : public SegmentObjTable<SciBitmap> {
+ BitmapTable() : SegmentObjTable<SciBitmap>(SEG_TYPE_BITMAP) {}
+
+ virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
+ at(sub_addr.getOffset()).destroy();
+ freeEntry(sub_addr.getOffset());
+ }
+
+ void saveLoadWithSerializer(Common::Serializer &ser);
+ SegmentRef dereference(reg_t pointer);
+};
+
#endif
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index a3dcbbbab6..311684d595 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -1088,7 +1088,7 @@ CelObjMem::CelObjMem(const reg_t bitmapObject) {
_celHeaderOffset = 0;
_transparent = true;
- BitmapResource bitmap(bitmapObject);
+ SciBitmap &bitmap = *g_sci->getEngineState()->_segMan->lookupBitmap(bitmapObject);
_width = bitmap.getWidth();
_height = bitmap.getHeight();
_displace = bitmap.getDisplace();
@@ -1104,7 +1104,7 @@ CelObjMem *CelObjMem::duplicate() const {
}
byte *CelObjMem::getResPointer() const {
- return g_sci->getEngineState()->_segMan->getHunkPointer(_info.bitmap);
+ return g_sci->getEngineState()->_segMan->lookupBitmap(_info.bitmap)->getRawData();
}
#pragma mark -
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
index 639a35c1a6..7689655d1d 100644
--- a/engines/sci/graphics/controls32.cpp
+++ b/engines/sci/graphics/controls32.cpp
@@ -309,7 +309,7 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
g_sci->_gfxFrameout->frameOut(true);
}
- _segMan->freeHunkEntry(editor.bitmap);
+ _segMan->freeBitmap(editor.bitmap);
if (textChanged) {
editor.text.trim();
@@ -419,7 +419,7 @@ ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, con
}
ScrollWindow::~ScrollWindow() {
- _segMan->freeHunkEntry(_bitmap);
+ _segMan->freeBitmap(_bitmap);
// _screenItem will be deleted by GfxFrameout
}
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index 4517659283..6004e9ce7a 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -334,7 +334,7 @@ reg_t GfxPaint16::bitsSave(const Common::Rect &rect, byte screenMask) {
// now actually ask _screen how much space it will need for saving
size = _screen->bitsGetDataSize(workerRect, screenMask);
- memoryId = _segMan->allocateHunkEntry("SaveBits()", size, true);
+ memoryId = _segMan->allocateHunkEntry("SaveBits()", size);
memoryPtr = _segMan->getHunkPointer(memoryId);
if (memoryPtr)
_screen->bitsSave(workerRect, screenMask, memoryPtr);
diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp
index 8a9d9b9657..338b70901e 100644
--- a/engines/sci/graphics/paint32.cpp
+++ b/engines/sci/graphics/paint32.cpp
@@ -37,11 +37,12 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st
}
Common::Rect gameRect;
- BitmapResource bitmap = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
+ reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
+ SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId);
CelInfo32 celInfo;
celInfo.type = kCelTypeMem;
- celInfo.bitmap = bitmap.getObject();
+ celInfo.bitmap = bitmapId;
// SSCI stores the line color on `celInfo`, even though
// this is not a `kCelTypeColor`, as a hack so that
// `kUpdateLine` can get the originally used color
@@ -59,10 +60,10 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st
void GfxPaint32::kernelUpdateLine(ScreenItem *screenItem, Plane *plane, const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness) {
Common::Rect gameRect;
- BitmapResource bitmap = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
+ reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
- _segMan->freeHunkEntry(screenItem->_celInfo.bitmap);
- screenItem->_celInfo.bitmap = bitmap.getObject();
+ _segMan->freeBitmap(screenItem->_celInfo.bitmap);
+ screenItem->_celInfo.bitmap = bitmapId;
screenItem->_celInfo.color = color;
screenItem->_position = startPoint;
screenItem->_priority = priority;
@@ -80,7 +81,7 @@ void GfxPaint32::kernelDeleteLine(const reg_t screenItemObject, const reg_t plan
return;
}
- _segMan->freeHunkEntry(screenItem->_celInfo.bitmap);
+ _segMan->freeBitmap(screenItem->_celInfo.bitmap);
g_sci->_gfxFrameout->deleteScreenItem(*screenItem, *plane);
}
@@ -116,7 +117,7 @@ void GfxPaint32::plotter(int x, int y, int color, void *data) {
}
}
-BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
+reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
const uint8 skipColor = color != kDefaultSkipColor ? kDefaultSkipColor : 0;
// Thickness is expected to be 2n+1
@@ -128,7 +129,8 @@ BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const
outRect.right = (startPoint.x > endPoint.x ? startPoint.x : endPoint.x) + halfThickness + 1;
outRect.bottom = (startPoint.y > endPoint.y ? startPoint.y : endPoint.y) + halfThickness + 1;
- BitmapResource bitmap(_segMan, outRect.width(), outRect.height(), skipColor, 0, 0, g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, 0, false, true);
+ reg_t bitmapId;
+ SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, outRect.width(), outRect.height(), skipColor, 0, 0, g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, 0, false, true);
byte *pixels = bitmap.getPixels();
memset(pixels, skipColor, bitmap.getWidth() * bitmap.getHeight());
@@ -174,7 +176,7 @@ BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const
Graphics::drawThickLine2(drawRect.left, drawRect.top, drawRect.right, drawRect.bottom, thickness, color, plotter, &properties);
}
- return bitmap;
+ return bitmapId;
}
diff --git a/engines/sci/graphics/paint32.h b/engines/sci/graphics/paint32.h
index 6d5a957fcd..3c3b7b4343 100644
--- a/engines/sci/graphics/paint32.h
+++ b/engines/sci/graphics/paint32.h
@@ -24,8 +24,8 @@
#define SCI_GRAPHICS_PAINT32_H
namespace Sci {
-class BitmapResource;
class Plane;
+class SciBitmap;
class ScreenItem;
class SegManager;
@@ -54,7 +54,7 @@ public:
private:
typedef struct {
- BitmapResource *bitmap;
+ SciBitmap *bitmap;
bool pattern[16];
uint8 patternIndex;
bool solid;
@@ -64,7 +64,7 @@ private:
static void plotter(int x, int y, int color, void *data);
- BitmapResource makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness, Common::Rect &outRect);
+ reg_t makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness, Common::Rect &outRect);
};
} // End of namespace Sci
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index a26c92c364..1514ad838f 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -626,7 +626,7 @@ void GfxPalette::kernelAnimateSet() {
reg_t GfxPalette::kernelSave() {
SegManager *segMan = g_sci->getEngineState()->_segMan;
- reg_t memoryId = segMan->allocateHunkEntry("kPalette(save)", 1024, true);
+ reg_t memoryId = segMan->allocateHunkEntry("kPalette(save)", 1024);
byte *memoryPtr = segMan->getHunkPointer(memoryId);
if (memoryPtr) {
for (int colorNr = 0; colorNr < 256; colorNr++) {
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index d612ddbfa3..f81d50946b 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -96,8 +96,7 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
_textRect = Common::Rect();
}
- BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
- _bitmap = bitmap.getObject();
+ _segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
erase(bitmapRect, false);
@@ -135,8 +134,7 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
_textRect = Common::Rect();
}
- BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
- _bitmap = bitmap.getObject();
+ SciBitmap &bitmap = *_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
// 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
@@ -180,8 +178,8 @@ void GfxText32::setFont(const GuiResourceId fontId) {
void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling) {
Common::Rect targetRect = doScaling ? scaleRect(rect) : rect;
- byte *bitmap = _segMan->getHunkPointer(_bitmap);
- byte *pixels = bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28) + rect.top * _width + rect.left;
+ SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
+ byte *pixels = bitmap.getPixels() + rect.top * _width + rect.left;
// NOTE: Not fully disassembled, but this should be right
int16 rectWidth = targetRect.width();
@@ -210,8 +208,8 @@ void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint
}
void GfxText32::drawChar(const char charIndex) {
- byte *bitmap = _segMan->getHunkPointer(_bitmap);
- byte *pixels = bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28);
+ SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
+ byte *pixels = bitmap.getPixels();
_font->drawToBuffer(charIndex, _drawPosition.y, _drawPosition.x, _foreColor, _dimmed, pixels, _width, _height);
_drawPosition.x += _font->getCharWidth(charIndex);
@@ -328,14 +326,14 @@ void GfxText32::drawText(const uint index, uint length) {
}
}
-void GfxText32::invertRect(const reg_t bitmap, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) {
+void GfxText32::invertRect(const reg_t bitmapId, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) {
Common::Rect targetRect = rect;
if (doScaling) {
bitmapStride = bitmapStride * _scaledWidth / g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
targetRect = scaleRect(rect);
}
- byte *bitmapData = _segMan->getHunkPointer(bitmap);
+ SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId);
// NOTE: SCI code is super weird here; it seems to be trying to look at the
// entire size of the bitmap including the header, instead of just the pixel
@@ -345,14 +343,14 @@ void GfxText32::invertRect(const reg_t bitmap, int16 bitmapStride, const Common:
// function was never updated to match? Or maybe they exploit the
// configurable stride length somewhere else to do stair stepping inverts...
uint32 invertSize = targetRect.height() * bitmapStride + targetRect.width();
- uint32 bitmapSize = READ_SCI11ENDIAN_UINT32(bitmapData + 12);
+ uint32 bitmapSize = bitmap.getDataSize();
if (invertSize >= bitmapSize) {
error("InvertRect too big: %u >= %u", invertSize, bitmapSize);
}
// NOTE: Actual engine just added the bitmap header size hardcoded here
- byte *pixel = bitmapData + READ_SCI11ENDIAN_UINT32(bitmapData + 28) + bitmapStride * targetRect.top + targetRect.left;
+ byte *pixel = bitmap.getPixels() + bitmapStride * targetRect.top + targetRect.left;
int16 stride = bitmapStride - targetRect.width();
int16 targetHeight = targetRect.height();
@@ -615,7 +613,7 @@ Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth,
void GfxText32::erase(const Common::Rect &rect, const bool doScaling) {
Common::Rect targetRect = doScaling ? scaleRect(rect) : rect;
- BitmapResource bitmap(_bitmap);
+ SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
bitmap.getBuffer().fillRect(targetRect, _backColor);
}
@@ -652,7 +650,7 @@ int16 GfxText32::getTextCount(const Common::String &text, const uint index, cons
}
void GfxText32::scrollLine(const Common::String &lineText, int numLines, uint8 color, TextAlign align, GuiResourceId fontId, ScrollDirection dir) {
- BitmapResource bmr(_bitmap);
+ SciBitmap &bmr = *_segMan->lookupBitmap(_bitmap);
byte *pixels = bmr.getPixels();
int h = _font->getHeight();
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index 40921563d0..44bd48afd5 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -42,210 +42,6 @@ enum ScrollDirection {
kScrollDown
};
-enum BitmapFlags {
- kBitmapRemap = 2
-};
-
-enum {
- kDefaultSkipColor = 250
-};
-
-#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;
- Buffer _buffer;
-
- /**
- * 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));
- }
-
- _buffer = Buffer(getWidth(), getHeight(), getPixels());
- }
-
- /**
- * 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 paletteSize, const bool remap, const bool gc) {
- _object = segMan->allocateHunkEntry("Bitmap()", getBitmapSize(width, height) + paletteSize, gc);
- _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(paletteSize > 0 ? (width * height) : 0);
- setDataOffset(bitmapHeaderSize);
- setUncompressedDataOffset(bitmapHeaderSize);
- setControlOffset(0);
- setScaledWidth(scaledWidth);
- setScaledHeight(scaledHeight);
-
- _buffer = Buffer(getWidth(), getHeight(), getPixels());
- }
-
- inline reg_t getObject() const {
- return _object;
- }
-
- inline Buffer &getBuffer() {
- return _buffer;
- }
-
- 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) & kBitmapRemap;
- }
-
- inline void setRemap(const bool remap) {
- uint16 flags = READ_SCI11ENDIAN_UINT16(_bitmap + 10);
- if (remap) {
- flags |= kBitmapRemap;
- } else {
- flags &= ~kBitmapRemap;
- }
- WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, flags);
- }
-
- BITMAP_PROPERTY(32, DataSize, 12);
-
- inline uint32 getHunkPaletteOffset() const {
- return READ_SCI11ENDIAN_UINT32(_bitmap + 20);
- }
-
- inline 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;
/**
diff --git a/engines/sci/graphics/transitions32.cpp b/engines/sci/graphics/transitions32.cpp
index 01956e6a2f..251e439cf5 100644
--- a/engines/sci/graphics/transitions32.cpp
+++ b/engines/sci/graphics/transitions32.cpp
@@ -362,7 +362,7 @@ ShowStyleList::iterator GfxTransitions32::deleteShowStyle(const ShowStyleList::i
case kShowStyleDissolveNoMorph:
case kShowStyleDissolve:
if (getSciVersion() <= SCI_VERSION_2_1_EARLY) {
- _segMan->freeHunkEntry(showStyle->bitmap);
+ _segMan->freeBitmap(showStyle->bitmap);
g_sci->_gfxFrameout->deleteScreenItem(*showStyle->bitmapScreenItem);
}
break;
@@ -459,9 +459,10 @@ void GfxTransitions32::configure21EarlyIris(PlaneShowStyle &showStyle, const int
void GfxTransitions32::configure21EarlyDissolve(PlaneShowStyle &showStyle, const int16 priority, const Common::Rect &gameRect) {
- BitmapResource bitmap(_segMan, showStyle.width, showStyle.height, kDefaultSkipColor, 0, 0, kLowResX, kLowResY, 0, false, false);
+ reg_t bitmapId;
+ SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, showStyle.width, showStyle.height, kDefaultSkipColor, 0, 0, kLowResX, kLowResY, 0, false, false);
- showStyle.bitmap = bitmap.getObject();
+ showStyle.bitmap = bitmapId;
const Buffer &source = g_sci->_gfxFrameout->getCurrentBuffer();
Buffer target(showStyle.width, showStyle.height, bitmap.getPixels());
@@ -471,7 +472,7 @@ void GfxTransitions32::configure21EarlyDissolve(PlaneShowStyle &showStyle, const
CelInfo32 celInfo;
celInfo.type = kCelTypeMem;
- celInfo.bitmap = bitmap.getObject();
+ celInfo.bitmap = bitmapId;
showStyle.bitmapScreenItem = new ScreenItem(showStyle.plane, celInfo, Common::Point(0, 0), ScaleInfo());
showStyle.bitmapScreenItem->_priority = priority;
@@ -608,7 +609,7 @@ bool GfxTransitions32::processPixelDissolve(PlaneShowStyle &showStyle) {
bool GfxTransitions32::processPixelDissolve21Early(PlaneShowStyle &showStyle) {
bool unchanged = true;
- BitmapResource bitmap(showStyle.bitmap);
+ SciBitmap &bitmap = *_segMan->lookupBitmap(showStyle.bitmap);
Buffer buffer(showStyle.width, showStyle.height, bitmap.getPixels());
uint32 numPixels = showStyle.width * showStyle.height;
diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp
index 46607066f6..dc2641c92a 100644
--- a/engines/sci/graphics/video32.cpp
+++ b/engines/sci/graphics/video32.cpp
@@ -117,7 +117,7 @@ VMDPlayer::IOStatus VMDPlayer::close() {
if (!_planeIsOwned && _screenItem != nullptr) {
g_sci->_gfxFrameout->deleteScreenItem(*_screenItem);
- g_sci->getEngineState()->_segMan->freeHunkEntry(_screenItem->_celInfo.bitmap);
+ g_sci->getEngineState()->_segMan->freeBitmap(_screenItem->_celInfo.bitmap);
_screenItem = nullptr;
} else if (_plane != nullptr) {
g_sci->_gfxFrameout->deletePlane(*_plane);
@@ -232,14 +232,15 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) {
const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
- BitmapResource vmdBitmap(_segMan, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false);
+ reg_t bitmapId;
+ SciBitmap &vmdBitmap = *_segMan->allocateBitmap(&bitmapId, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false);
if (screenWidth != scriptWidth || screenHeight != scriptHeight) {
mulru(vmdRect, Ratio(scriptWidth, screenWidth), Ratio(scriptHeight, screenHeight), 1);
}
CelInfo32 vmdCelInfo;
- vmdCelInfo.bitmap = vmdBitmap.getObject();
+ vmdCelInfo.bitmap = bitmapId;
_decoder->setSurfaceMemory(vmdBitmap.getPixels(), vmdBitmap.getWidth(), vmdBitmap.getHeight(), 1);
if (_planeIsOwned) {