aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/console.cpp2
-rw-r--r--engines/sci/engine/gc.cpp29
-rw-r--r--engines/sci/engine/kgraphics32.cpp8
-rw-r--r--engines/sci/engine/kscripts.cpp2
-rw-r--r--engines/sci/engine/seg_manager.cpp3
-rw-r--r--engines/sci/engine/seg_manager.h4
-rw-r--r--engines/sci/engine/segment.h1
-rw-r--r--engines/sci/graphics/controls32.cpp19
-rw-r--r--engines/sci/graphics/controls32.h7
-rw-r--r--engines/sci/graphics/paint16.cpp2
-rw-r--r--engines/sci/graphics/paint32.cpp2
-rw-r--r--engines/sci/graphics/palette.cpp2
-rw-r--r--engines/sci/graphics/text32.cpp8
-rw-r--r--engines/sci/graphics/text32.h10
-rw-r--r--engines/sci/graphics/video32.cpp3
15 files changed, 50 insertions, 52 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 6898745858..6acb467b50 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);
+ reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize, true);
byte* bakMemory = segman->getHunkPointer(bakScreen);
assert(bakMemory);
_engine->_gfxScreen->bitsSave(rect, bakMask, bakMemory);
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index b229490570..e0467e9461 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -143,23 +143,30 @@ AddrSet *findAllActiveReferences(EngineState *s) {
const Common::Array<SegmentObj *> &heap = s->_segMan->getSegments();
uint heapSize = heap.size();
- // Init: Explicitly loaded scripts
for (uint i = 1; i < heapSize; i++) {
- if (heap[i] && heap[i]->getType() == SEG_TYPE_SCRIPT) {
- Script *script = (Script *)heap[i];
+ if (heap[i]) {
+ // Init: Explicitly loaded scripts
+ if (heap[i]->getType() == SEG_TYPE_SCRIPT) {
+ Script *script = (Script *)heap[i];
- if (script->getLockers()) { // Explicitly loaded?
- wm.pushArray(script->listObjectReferences());
+ if (script->getLockers()) { // Explicitly loaded?
+ wm.pushArray(script->listObjectReferences());
+ }
+ }
+
+ // Init: Explicitly opted-out hunks
+ else if (heap[i]->getType() == SEG_TYPE_HUNK) {
+ HunkTable *ht = static_cast<HunkTable *>(heap[i]);
+
+ for (uint j = 0; j < ht->_table.size(); j++) {
+ if (!ht->_table[j].data.gc) {
+ wm.push(make_reg(i, j));
+ }
+ }
}
}
}
-#ifdef ENABLE_SCI32
- // Init: ScrollWindows
- if (g_sci->_gfxControls32)
- wm.pushArray(g_sci->_gfxControls32->listObjectReferences());
-#endif
-
debugC(kDebugLevelGC, "[GC] -- Finished explicitly loaded scripts, done with root set");
processWorkList(s->_segMan, wm, heap);
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 9cfe53255b..b8682b3f47 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -195,14 +195,14 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
if (subop == 0) {
TextAlign alignment = (TextAlign)readSelectorValue(segMan, object, SELECTOR(mode));
- return g_sci->_gfxText32->createFontBitmap(width, height, rect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, true);
+ return g_sci->_gfxText32->createFontBitmap(width, height, rect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, true, true);
} else {
CelInfo32 celInfo;
celInfo.type = kCelTypeView;
celInfo.resourceId = readSelectorValue(segMan, object, SELECTOR(view));
celInfo.loopNo = readSelectorValue(segMan, object, SELECTOR(loop));
celInfo.celNo = readSelectorValue(segMan, object, SELECTOR(cel));
- return g_sci->_gfxText32->createFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed);
+ return g_sci->_gfxText32->createFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed, true);
}
}
@@ -534,7 +534,7 @@ 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);
+ BitmapResource bitmap(s->_segMan, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap, true);
memset(bitmap.getPixels(), backColor, width * height);
return bitmap.getObject();
}
@@ -604,7 +604,7 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
// Then clips. But this seems stupid.
textRect.clip(Common::Rect(bitmap.getWidth(), bitmap.getHeight()));
- 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);
+ 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);
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 6fd130bceb..42e7a2028f 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);
+ return s->_segMan->allocateHunkEntry("kLoad()", resnr, true);
return make_reg(0, ((restype << 11) | resnr)); // Return the resource identifier as handle
}
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 95e3cd15f9..e6692060b6 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -393,7 +393,7 @@ void SegManager::freeHunkEntry(reg_t addr) {
ht->freeEntryContents(addr.getOffset());
}
-reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
+reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size, bool gc) {
HunkTable *table;
int offset;
@@ -412,6 +412,7 @@ reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
h->mem = malloc(size);
h->size = size;
h->type = hunk_type;
+ h->gc = gc;
return addr;
}
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 9da7e58770..ba2ba33a6a 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -225,9 +225,11 @@ 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);
+ reg_t allocateHunkEntry(const char *hunk_type, int size, bool gc);
/**
* Deallocates a hunk entry
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 50c77d0538..6c94c24ff9 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -205,6 +205,7 @@ struct Hunk {
void *mem;
uint32 size;
const char *type;
+ bool gc;
};
template<typename T>
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
index f4e9d26df4..639a35c1a6 100644
--- a/engines/sci/graphics/controls32.cpp
+++ b/engines/sci/graphics/controls32.cpp
@@ -54,18 +54,6 @@ GfxControls32::~GfxControls32() {
}
#pragma mark -
-#pragma mark Garbage collection
-
-Common::Array<reg_t> GfxControls32::listObjectReferences() {
- Common::Array<reg_t> ret;
- ScrollWindowMap::const_iterator it;
- for (it = _scrollWindows.begin(); it != _scrollWindows.end(); ++it)
- ret.push_back(it->_value->getBitmap());
-
- return ret;
-}
-
-#pragma mark -
#pragma mark Text input control
reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
@@ -130,7 +118,7 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
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);
+ editor.bitmap = _gfxText32->createFontBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, dimmed, true, false);
} else {
error("Titled bitmaps are not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!");
}
@@ -383,6 +371,7 @@ void GfxControls32::flashCursor(TextEditor &editor) {
#pragma mark Scrollable window control
ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, const Common::Point &position, const reg_t plane, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries) :
+ _segMan(segMan),
_gfxText32(segMan, g_sci->_gfxCache),
_maxNumEntries(maxNumEntries),
_firstVisibleChar(0),
@@ -424,13 +413,13 @@ ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, con
}
assert(bitmapRect.width() > 0 && bitmapRect.height() > 0);
- _bitmap = _gfxText32.createFontBitmap(bitmapRect.width(), bitmapRect.height(), _textRect, "", _foreColor, _backColor, skipColor, _fontId, _alignment, _borderColor, false, false);
+ _bitmap = _gfxText32.createFontBitmap(bitmapRect.width(), bitmapRect.height(), _textRect, "", _foreColor, _backColor, skipColor, _fontId, _alignment, _borderColor, false, false, false);
debugC(1, kDebugLevelGraphics, "New ScrollWindow: textRect size: %d x %d, bitmap: %04x:%04x", _textRect.width(), _textRect.height(), PRINT_REG(_bitmap));
}
ScrollWindow::~ScrollWindow() {
- // _gfxText32._bitmap will get GCed once ScrollWindow is gone.
+ _segMan->freeHunkEntry(_bitmap);
// _screenItem will be deleted by GfxFrameout
}
diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h
index 460b0b5625..680c70d2d6 100644
--- a/engines/sci/graphics/controls32.h
+++ b/engines/sci/graphics/controls32.h
@@ -227,6 +227,8 @@ public:
const reg_t getBitmap() const { return _bitmap; }
private:
+ SegManager *_segMan;
+
typedef Common::Array<ScrollWindowEntry> EntriesList;
/**
@@ -418,11 +420,6 @@ private:
GfxText32 *_gfxText32;
#pragma mark -
-#pragma mark Garbage collection
-public:
- Common::Array<reg_t> listObjectReferences();
-
-#pragma mark -
#pragma mark Text input control
public:
reg_t kernelEditText(const reg_t controlObject);
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index 6004e9ce7a..4517659283 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);
+ memoryId = _segMan->allocateHunkEntry("SaveBits()", size, true);
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 7773b9f4e1..8a9d9b9657 100644
--- a/engines/sci/graphics/paint32.cpp
+++ b/engines/sci/graphics/paint32.cpp
@@ -128,7 +128,7 @@ 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);
+ BitmapResource bitmap(_segMan, 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());
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 1514ad838f..a26c92c364 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);
+ reg_t memoryId = segMan->allocateHunkEntry("kPalette(save)", 1024, true);
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 277e6e93d0..d612ddbfa3 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -59,7 +59,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts) :
}
}
-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 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, const bool gc) {
_borderColor = borderColor;
_text = text;
@@ -96,7 +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);
+ BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
_bitmap = bitmap.getObject();
erase(bitmapRect, false);
@@ -109,7 +109,7 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
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 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, const bool gc) {
_borderColor = borderColor;
_text = text;
_textRect = rect;
@@ -135,7 +135,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);
+ BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
_bitmap = bitmap.getObject();
// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index f57433f42d..40921563d0 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -117,8 +117,8 @@ public:
* 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));
+ 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();
@@ -132,7 +132,7 @@ public:
setRemap(remap);
setDataSize(width * height);
WRITE_SCI11ENDIAN_UINT32(_bitmap + 16, 0);
- setHunkPaletteOffset(hunkPaletteOffset);
+ setHunkPaletteOffset(paletteSize > 0 ? (width * height) : 0);
setDataOffset(bitmapHeaderSize);
setUncompressedDataOffset(bitmapHeaderSize);
setControlOffset(0);
@@ -394,12 +394,12 @@ 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 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, const bool gc);
/**
* 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 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, const bool gc);
inline int scaleUpWidth(int value) const {
const int scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp
index dd841f5b4c..46607066f6 100644
--- a/engines/sci/graphics/video32.cpp
+++ b/engines/sci/graphics/video32.cpp
@@ -117,6 +117,7 @@ VMDPlayer::IOStatus VMDPlayer::close() {
if (!_planeIsOwned && _screenItem != nullptr) {
g_sci->_gfxFrameout->deleteScreenItem(*_screenItem);
+ g_sci->getEngineState()->_segMan->freeHunkEntry(_screenItem->_celInfo.bitmap);
_screenItem = nullptr;
} else if (_plane != nullptr) {
g_sci->_gfxFrameout->deletePlane(*_plane);
@@ -231,7 +232,7 @@ 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);
+ BitmapResource vmdBitmap(_segMan, 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);