/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "graphics/cursorman.h" #include "engines/nancy/nancy.h" #include "engines/nancy/cursor.h" #include "engines/nancy/graphics.h" #include "engines/nancy/resource.h" #include "engines/nancy/util.h" #include "engines/nancy/constants.h" namespace Nancy { void CursorManager::init() { Common::SeekableReadStream *chunk = g_nancy->getBootChunkStream("INV"); chunk->seek(0xD6 + g_nancy->getConstants().numCurtainAnimationFrames * 0x20 + 0x1C); Common::String inventoryCursorsImageName = chunk->readString(); chunk = g_nancy->getBootChunkStream("CURS"); chunk->seek(0); uint numCursors = g_nancy->getConstants().numNonItemCursors + g_nancy->getConstants().numItems * 4; _cursors.reserve(numCursors); for (uint i = 0; i < numCursors; ++i) { _cursors.push_back(Cursor()); chunk->seek(i * 16, SEEK_SET); Cursor &cur = _cursors.back(); readRect(*chunk, cur.bounds); chunk->seek(numCursors * 16 + i * 8, SEEK_SET); cur.hotspot.x = chunk->readUint32LE(); cur.hotspot.y = chunk->readUint32LE(); } readRect(*chunk, _primaryVideoInactiveZone); _primaryVideoInitialPos.x = chunk->readUint16LE(); _primaryVideoInitialPos.y = chunk->readUint16LE(); g_nancy->_resource->loadImage(inventoryCursorsImageName, _invCursorsSurface); setCursor(kNormalArrow, -1); showCursor(false); _isInitialized = true; } void CursorManager::setCursor(CursorType type, int16 itemID) { if (!_isInitialized) { return; } if (type == _curCursorType && itemID == _curItemID) { return; } else { _curCursorType = type; _curItemID = itemID; } bool hasItem = false; switch (type) { case kNormalArrow: _curCursorID = 4; break; case kHotspotArrow: _curCursorID = 5; break; case kExit: if (g_nancy->getGameType() != kGameTypeVampire) { _curCursorID = 3; break; } // fall through default: { uint itemsOffset = 0; if (itemID == -1) { // No item held, set to eyeglass itemID = 0; } else { // Item held itemsOffset = g_nancy->getConstants().numNonItemCursors; hasItem = true; } _curCursorID = itemID * 4 + itemsOffset + type; } } Graphics::ManagedSurface *surf; Common::Rect bounds = _cursors[_curCursorID].bounds; Common::Point hotspot = _cursors[_curCursorID].hotspot; if (hasItem) { surf = &_invCursorsSurface; } else { surf = &g_nancy->_graphicsManager->_object0; } // Create a temporary surface to hold the cursor since giving replaceCursor() a pointer // to the original surface results in garbage. This also makes it so we don't have to deal // with TVD's palettes Graphics::ManagedSurface temp; temp.create(bounds.width(), bounds.height(), g_nancy->_graphicsManager->getScreenPixelFormat()); temp.blitFrom(*surf, bounds, Common::Point()); // Convert the trans color from the original format to the screen format uint transColor; if (g_nancy->getGameType() == kGameTypeVampire) { uint8 r, g, b; uint32 input = surf->getPalette()[1]; r = input & 0xFF; g = (input & 0xFF00) >> 8; b = (input & 0xFF0000) >> 16; transColor = temp.format.RGBToColor(r, g, b); } else { uint8 r, g, b; surf->format.colorToRGB(g_nancy->_graphicsManager->getTransColor(), r, g, b); transColor = temp.format.RGBToColor(r, g, b); } CursorMan.replaceCursor(temp.getPixels(), temp.w, temp.h, hotspot.x, hotspot.y, transColor, false, &temp.format); } void CursorManager::setCursorType(CursorType type) { setCursor(type, _curItemID); } void CursorManager::setCursorItemID(int16 itemID) { setCursor(_curCursorType, itemID); } void CursorManager::showCursor(bool shouldShow) { CursorMan.showMouse(shouldShow); } } // End of namespace Nancy