bool MacResExtractor::extractResource(int id, CachedCursor *cc) { // Create the MacResManager if not created already if (_resMgr == NULL) { _resMgr = new Common::MacResManager(); if (!_resMgr->open(_vm->generateFilename(-3))) error("Cannot open file %s", _fileName.c_str()); } Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', id + 1000); if (!dataStream) return false; // If we don't have a cursor palette, force monochrome cursors bool forceMonochrome = !_vm->_system->hasFeature(OSystem::kFeatureCursorPalette); Graphics::MacCursor *macCursor = new Graphics::MacCursor(); if (!macCursor->readFromStream(*dataStream, forceMonochrome)) { delete dataStream; delete macCursor; return false; } cc->bitmap = new byte[macCursor->getWidth() * macCursor->getHeight()]; cc->width = macCursor->getWidth(); cc->height = macCursor->getHeight(); cc->hotspotX = macCursor->getHotspotX(); cc->hotspotY = macCursor->getHotspotY(); if (forceMonochrome) { // Convert to the SCUMM palette const byte *srcBitmap = macCursor->getSurface(); for (int i = 0; i < macCursor->getWidth() * macCursor->getHeight(); i++) { if (srcBitmap[i] == macCursor->getKeyColor()) // Transparent cc->bitmap[i] = 255; else if (srcBitmap[i] == 0) // Black cc->bitmap[i] = 253; else // White cc->bitmap[i] = 254; } } else { // Copy data and palette // Sanity check. This code assumes that the key color is the same assert(macCursor->getKeyColor() == 255); memcpy(cc->bitmap, macCursor->getSurface(), macCursor->getWidth() * macCursor->getHeight()); cc->palette = new byte[256 * 3]; cc->palSize = 256; memcpy(cc->palette, macCursor->getPalette(), 256 * 3); } delete macCursor; delete dataStream; return true; }
void CursorManager::setMacCursor(Common::SeekableReadStream *stream) { assert(stream); Graphics::MacCursor *macCursor = new Graphics::MacCursor(); if (!macCursor->readFromStream(*stream)) error("Could not parse Mac cursor"); CursorMan.replaceCursor(macCursor->getSurface(), macCursor->getWidth(), macCursor->getHeight(), macCursor->getHotspotX(), macCursor->getHotspotY(), macCursor->getKeyColor()); CursorMan.replaceCursorPalette(macCursor->getPalette(), 0, 256); delete macCursor; delete stream; }
void GfxCursor32::setView(const GuiResourceId viewId, const int16 loopNo, const int16 celNo) { hide(); _cursorInfo.resourceId = viewId; _cursorInfo.loopNo = loopNo; _cursorInfo.celNo = celNo; if (_macCursorRemap.empty() && viewId != -1) { CelObjView view(viewId, loopNo, celNo); _hotSpot = view._displace; _width = view._width; _height = view._height; // SSCI never increased the size of cursors, but some of the cursors // in early SCI32 games were designed for low-resolution display mode // and so are kind of hard to pick out when running in high-resolution // mode. // To address this, we make some slight adjustments to cursor display // in these early games: // GK1: All the cursors are increased in size since they all appear to // be designed for low-res display. // PQ4: We only make the cursors bigger if they are above a set // threshold size because inventory items usually have a // high-resolution cursor representation. bool pixelDouble = false; if (g_sci->_gfxFrameout->_isHiRes && (g_sci->getGameId() == GID_GK1 || (g_sci->getGameId() == GID_PQ4 && _width <= 22 && _height <= 22))) { _width *= 2; _height *= 2; _hotSpot.x *= 2; _hotSpot.y *= 2; pixelDouble = true; } _cursor.data = (byte *)realloc(_cursor.data, _width * _height); _cursor.rect = Common::Rect(_width, _height); memset(_cursor.data, 255, _width * _height); _cursor.skipColor = 255; Buffer target(_width, _height, _cursor.data); if (pixelDouble) { view.draw(target, _cursor.rect, Common::Point(0, 0), false, 2, 2); } else { view.draw(target, _cursor.rect, Common::Point(0, 0), false); } } else if (!_macCursorRemap.empty() && viewId != -1) { // Mac cursor handling GuiResourceId viewNum = viewId; // Remap cursor view based on what the scripts have given us. for (uint32 i = 0; i < _macCursorRemap.size(); i++) { if (viewNum == _macCursorRemap[i]) { viewNum = (i + 1) * 0x100 + loopNo * 0x10 + celNo; break; } if (i == _macCursorRemap.size()) error("Unmatched Mac cursor %d", viewNum); } _cursorInfo.resourceId = viewNum; Resource *resource = g_sci->getResMan()->findResource(ResourceId(kResourceTypeCursor, viewNum), false); if (!resource) { // The cursor resources often don't exist, this is normal behavior debug(0, "Mac cursor %d not found", viewNum); return; } Common::MemoryReadStream resStream(resource->data, resource->size); Graphics::MacCursor *macCursor = new Graphics::MacCursor(); if (!macCursor->readFromStream(resStream)) { warning("Failed to load Mac cursor %d", viewNum); delete macCursor; return; } _hotSpot = Common::Point(macCursor->getHotspotX(), macCursor->getHotspotY()); _width = macCursor->getWidth(); _height = macCursor->getHeight(); _cursor.data = (byte *)realloc(_cursor.data, _width * _height); memcpy(_cursor.data, macCursor->getSurface(), _width * _height); _cursor.rect = Common::Rect(_width, _height); _cursor.skipColor = macCursor->getKeyColor(); // The cursor will be drawn on next refresh delete macCursor; } else { _hotSpot = Common::Point(0, 0); _width = _height = 1; _cursor.data = (byte *)realloc(_cursor.data, _width * _height); _cursor.rect = Common::Rect(_width, _height); *_cursor.data = _cursor.skipColor; _cursorBack.rect = _cursor.rect; _cursorBack.rect.clip(_vmapRegion.rect); if (!_cursorBack.rect.isEmpty()) { readVideo(_cursorBack); } } _cursorBack.data = (byte *)realloc(_cursorBack.data, _width * _height); _drawBuff1.data = (byte *)realloc(_drawBuff1.data, _width * _height); _drawBuff2.data = (byte *)realloc(_drawBuff2.data, _width * _height * 4); _savedVmapRegion.data = (byte *)realloc(_savedVmapRegion.data, _width * _height); unhide(); }