1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "neverhood/mouse.h"
24 #include "graphics/cursorman.h"
25
26 namespace Neverhood {
27
Mouse(NeverhoodEngine * vm,uint32 fileHash,const NRect & mouseRect)28 Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, const NRect &mouseRect)
29 : StaticSprite(vm, 2000), _mouseType(kMouseType433),
30 _mouseCursorResource(vm), _frameNum(0) {
31
32 _mouseRect = mouseRect;
33 init(fileHash);
34 if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 &&
35 _y >= _mouseRect.y1 && _y <= _mouseRect.y2) {
36 _mouseCursorResource.setCursorNum(1);
37 } else {
38 _mouseCursorResource.setCursorNum(4);
39 }
40 updateCursor();
41 }
42
Mouse(NeverhoodEngine * vm,uint32 fileHash,int16 x1,int16 x2)43 Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, int16 x1, int16 x2)
44 : StaticSprite(vm, 2000), _mouseType(kMouseType435),
45 _mouseCursorResource(vm), _frameNum(0), _x1(x1), _x2(x2) {
46
47 init(fileHash);
48 if (_x <= _x1) {
49 _mouseCursorResource.setCursorNum(6);
50 } else if (_x >= _x2) {
51 _mouseCursorResource.setCursorNum(5);
52 } else {
53 _mouseCursorResource.setCursorNum(4);
54 }
55 updateCursor();
56 }
57
Mouse(NeverhoodEngine * vm,uint32 fileHash,int type)58 Mouse::Mouse(NeverhoodEngine *vm, uint32 fileHash, int type)
59 : StaticSprite(vm, 2000), _mouseType(kMouseTypeNavigation),
60 _mouseCursorResource(vm), _type(type), _frameNum(0) {
61
62 init(fileHash);
63 _mouseCursorResource.setCursorNum(0);
64 }
65
~Mouse()66 Mouse::~Mouse() {
67 CursorMan.showMouse(false);
68 }
69
init(uint32 fileHash)70 void Mouse::init(uint32 fileHash) {
71 _mouseCursorResource.load(fileHash);
72 _x = _vm->getMouseX();
73 _y = _vm->getMouseY();
74 createSurface(2000, 32, 32);
75 SetUpdateHandler(&Mouse::update);
76 SetMessageHandler(&Mouse::handleMessage);
77 _drawOffset.x = 0;
78 _drawOffset.y = 0;
79 _drawOffset.width = 32;
80 _drawOffset.height = 32;
81 _collisionBoundsOffset = _drawOffset;
82 updateBounds();
83 _needRefresh = true;
84 CursorMan.showMouse(false);
85 }
86
load(uint32 fileHash)87 void Mouse::load(uint32 fileHash) {
88 _mouseCursorResource.load(fileHash);
89 _needRefresh = true;
90 }
91
update()92 void Mouse::update() {
93 if (CursorMan.isVisible() && !_surface->getVisible()) {
94 CursorMan.showMouse(false);
95 } else if (!CursorMan.isVisible() && _surface->getVisible()) {
96 CursorMan.showMouse(true);
97 }
98 updateCursor();
99 _frameNum++;
100 if (_frameNum >= 6)
101 _frameNum = 0;
102 _needRefresh = _frameNum % 2 == 0;
103 }
104
handleMessage(int messageNum,const MessageParam & param,Entity * sender)105 uint32 Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
106 debug(7, "Mouse::handleMessage(%04X)", messageNum);
107 uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
108 switch (messageNum) {
109 case 0x2064:
110 _x = param.asPoint().x;
111 _y = param.asPoint().y;
112 switch (_type) {
113 case 1:
114 if (_x >= 320)
115 messageResult = 1;
116 else
117 messageResult = 0;
118 break;
119 case 2:
120 default:
121 if (_x < 100)
122 messageResult = 0;
123 else if (_x > 540)
124 messageResult = 1;
125 else
126 messageResult = 2;
127 break;
128 case 3:
129 if (_x < 100)
130 messageResult = 0;
131 else if (_x > 540)
132 messageResult = 1;
133 else
134 messageResult = 4;
135 break;
136 case 4:
137 if (_x < 100)
138 messageResult = 0;
139 else if (_x > 540)
140 messageResult = 1;
141 else if (_y >= 150)
142 messageResult = 2;
143 else
144 messageResult = 3;
145 break;
146 case 5:
147 if (_y >= 240)
148 messageResult = 4;
149 else
150 messageResult = 3;
151 break;
152 }
153 break;
154 case 0x4002:
155 _x = param.asPoint().x;
156 _y = param.asPoint().y;
157 updateCursorNum();
158 updateBounds();
159 break;
160 default:
161 break;
162 }
163 return messageResult;
164 }
165
updateCursor()166 void Mouse::updateCursor() {
167
168 if (!_surface)
169 return;
170
171 if (_doDeltaX) {
172 _surface->getDrawRect().x = filterX(_x - _drawOffset.width - _drawOffset.x + 1);
173 } else {
174 _surface->getDrawRect().x = filterX(_x + _drawOffset.x);
175 }
176
177 if (_doDeltaY) {
178 _surface->getDrawRect().y = filterY(_y - _drawOffset.height - _drawOffset.y + 1);
179 } else {
180 _surface->getDrawRect().y = filterY(_y + _drawOffset.y);
181 }
182
183 if (_needRefresh) {
184 _needRefresh = false;
185 _drawOffset = _mouseCursorResource.getRect();
186 _surface->drawMouseCursorResource(_mouseCursorResource, _frameNum / 2);
187 Graphics::Surface *cursorSurface = _surface->getSurface();
188 CursorMan.replaceCursor((const byte*)cursorSurface->getPixels(),
189 cursorSurface->w, cursorSurface->h, -_drawOffset.x, -_drawOffset.y, 0);
190 }
191
192 }
193
updateCursorNum()194 void Mouse::updateCursorNum() {
195 switch (_mouseType) {
196 case kMouseType433:
197 if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 &&
198 _y >= _mouseRect.y1 && _y <= _mouseRect.y2) {
199 _mouseCursorResource.setCursorNum(1);
200 } else {
201 _mouseCursorResource.setCursorNum(4);
202 }
203 break;
204 case kMouseType435:
205 if (_x <= _x1) {
206 _mouseCursorResource.setCursorNum(6);
207 } else if (_x >= _x2) {
208 _mouseCursorResource.setCursorNum(5);
209 } else {
210 _mouseCursorResource.setCursorNum(4);
211 }
212 break;
213 case kMouseTypeNavigation:
214 switch (_type) {
215 case 1:
216 if (_x >= 320)
217 _mouseCursorResource.setCursorNum(5);
218 else
219 _mouseCursorResource.setCursorNum(6);
220 break;
221 case 2:
222 default:
223 if (_x < 100)
224 _mouseCursorResource.setCursorNum(6);
225 else if (_x > 540)
226 _mouseCursorResource.setCursorNum(5);
227 else
228 _mouseCursorResource.setCursorNum(0);
229 break;
230 case 3:
231 if (_x < 100)
232 _mouseCursorResource.setCursorNum(1);
233 else if (_x > 540)
234 _mouseCursorResource.setCursorNum(1);
235 break;
236 case 4:
237 if (_x < 100)
238 _mouseCursorResource.setCursorNum(6);
239 else if (_x > 540)
240 _mouseCursorResource.setCursorNum(5);
241 else if (_y >= 150)
242 _mouseCursorResource.setCursorNum(0);
243 else
244 _mouseCursorResource.setCursorNum(3);
245 break;
246 case 5:
247 if (_y >= 240)
248 _mouseCursorResource.setCursorNum(2);
249 else
250 _mouseCursorResource.setCursorNum(3);
251 break;
252 }
253 break;
254 default:
255 break;
256 }
257
258 }
259
260 } // End of namespace Neverhood
261