/* 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 2 * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "neverhood/mouse.h" #include "graphics/cursorman.h" namespace Neverhood { Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, const NRect &mouseRect) : StaticSprite(vm, 2000), _mouseType(kMouseType433), _mouseCursorResource(vm), _frameNum(0) { _mouseRect = mouseRect; init(fileHash); if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 && _y >= _mouseRect.y1 && _y <= _mouseRect.y2) { _mouseCursorResource.setCursorNum(1); } else { _mouseCursorResource.setCursorNum(4); } updateCursor(); } Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, int16 x1, int16 x2) : StaticSprite(vm, 2000), _mouseType(kMouseType435), _mouseCursorResource(vm), _frameNum(0), _x1(x1), _x2(x2) { init(fileHash); if (_x <= _x1) { _mouseCursorResource.setCursorNum(6); } else if (_x >= _x2) { _mouseCursorResource.setCursorNum(5); } else { _mouseCursorResource.setCursorNum(4); } updateCursor(); } Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, int type) : StaticSprite(vm, 2000), _mouseType(kMouseTypeNavigation), _mouseCursorResource(vm), _type(type), _frameNum(0) { init(fileHash); _mouseCursorResource.setCursorNum(0); } Mouse::~Mouse() { CursorMan.showMouse(false); } void Mouse::init(uint32 fileHash) { _mouseCursorResource.load(fileHash); _x = _vm->getMouseX(); _y = _vm->getMouseY(); createSurface(2000, 32, 32); SetUpdateHandler(&Mouse::update); SetMessageHandler(&Mouse::handleMessage); _drawOffset.x = 0; _drawOffset.y = 0; _drawOffset.width = 32; _drawOffset.height = 32; _collisionBoundsOffset = _drawOffset; updateBounds(); _needRefresh = true; CursorMan.showMouse(false); } void Mouse::load(uint32 fileHash) { _mouseCursorResource.load(fileHash); _needRefresh = true; } void Mouse::update() { if (CursorMan.isVisible() && !_surface->getVisible()) { CursorMan.showMouse(false); } else if (!CursorMan.isVisible() && _surface->getVisible()) { CursorMan.showMouse(true); } updateCursor(); _frameNum++; if (_frameNum >= 6) _frameNum = 0; _needRefresh = _frameNum % 2 == 0; } uint32 Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { debug(7, "Mouse::handleMessage(%04X)", messageNum); uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); switch (messageNum) { case 0x2064: _x = param.asPoint().x; _y = param.asPoint().y; switch (_type) { case 1: if (_x >= 320) messageResult = 1; else messageResult = 0; break; case 2: default: if (_x < 100) messageResult = 0; else if (_x > 540) messageResult = 1; else messageResult = 2; break; case 3: if (_x < 100) messageResult = 0; else if (_x > 540) messageResult = 1; else messageResult = 4; break; case 4: if (_x < 100) messageResult = 0; else if (_x > 540) messageResult = 1; else if (_y >= 150) messageResult = 2; else messageResult = 3; break; case 5: if (_y >= 240) messageResult = 4; else messageResult = 3; break; } break; case 0x4002: _x = param.asPoint().x; _y = param.asPoint().y; updateCursorNum(); updateBounds(); break; } return messageResult; } void Mouse::updateCursor() { if (!_surface) return; if (_doDeltaX) { _surface->getDrawRect().x = filterX(_x - _drawOffset.width - _drawOffset.x + 1); } else { _surface->getDrawRect().x = filterX(_x + _drawOffset.x); } if (_doDeltaY) { _surface->getDrawRect().y = filterY(_y - _drawOffset.height - _drawOffset.y + 1); } else { _surface->getDrawRect().y = filterY(_y + _drawOffset.y); } if (_needRefresh) { _needRefresh = false; _drawOffset = _mouseCursorResource.getRect(); _surface->drawMouseCursorResource(_mouseCursorResource, _frameNum / 2); Graphics::Surface *cursorSurface = _surface->getSurface(); CursorMan.replaceCursor((const byte*)cursorSurface->getBasePtr(0, 0), cursorSurface->w, cursorSurface->h, -_drawOffset.x, -_drawOffset.y, 0); } } void Mouse::updateCursorNum() { switch (_mouseType) { case kMouseType433: if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 && _y >= _mouseRect.y1 && _y <= _mouseRect.y2) { _mouseCursorResource.setCursorNum(1); } else { _mouseCursorResource.setCursorNum(4); } break; case kMouseType435: if (_x <= _x1) { _mouseCursorResource.setCursorNum(6); } else if (_x >= _x2) { _mouseCursorResource.setCursorNum(5); } else { _mouseCursorResource.setCursorNum(4); } break; case kMouseTypeNavigation: switch (_type) { case 1: if (_x >= 320) _mouseCursorResource.setCursorNum(5); else _mouseCursorResource.setCursorNum(6); break; case 2: default: if (_x < 100) _mouseCursorResource.setCursorNum(6); else if (_x > 540) _mouseCursorResource.setCursorNum(5); else _mouseCursorResource.setCursorNum(0); break; case 3: if (_x < 100) _mouseCursorResource.setCursorNum(1); else if (_x > 540) _mouseCursorResource.setCursorNum(1); break; case 4: if (_x < 100) _mouseCursorResource.setCursorNum(6); else if (_x > 540) _mouseCursorResource.setCursorNum(5); else if (_y >= 150) _mouseCursorResource.setCursorNum(0); else _mouseCursorResource.setCursorNum(3); break; case 5: if (_y >= 240) _mouseCursorResource.setCursorNum(2); else _mouseCursorResource.setCursorNum(3); break; } break; } } } // End of namespace Neverhood