diff options
-rw-r--r-- | engines/sci/console.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/gc.cpp | 29 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics32.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 3 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 4 | ||||
-rw-r--r-- | engines/sci/engine/segment.h | 1 | ||||
-rw-r--r-- | engines/sci/graphics/controls32.cpp | 19 | ||||
-rw-r--r-- | engines/sci/graphics/controls32.h | 7 | ||||
-rw-r--r-- | engines/sci/graphics/paint16.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/paint32.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/palette.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/text32.cpp | 8 | ||||
-rw-r--r-- | engines/sci/graphics/text32.h | 10 | ||||
-rw-r--r-- | engines/sci/graphics/video32.cpp | 3 |
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); |