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 }
161 return messageResult;
162 }
163
updateCursor()164 void Mouse::updateCursor() {
165
166 if (!_surface)
167 return;
168
169 if (_doDeltaX) {
170 _surface->getDrawRect().x = filterX(_x - _drawOffset.width - _drawOffset.x + 1);
171 } else {
172 _surface->getDrawRect().x = filterX(_x + _drawOffset.x);
173 }
174
175 if (_doDeltaY) {
176 _surface->getDrawRect().y = filterY(_y - _drawOffset.height - _drawOffset.y + 1);
177 } else {
178 _surface->getDrawRect().y = filterY(_y + _drawOffset.y);
179 }
180
181 if (_needRefresh) {
182 _needRefresh = false;
183 _drawOffset = _mouseCursorResource.getRect();
184 _surface->drawMouseCursorResource(_mouseCursorResource, _frameNum / 2);
185 Graphics::Surface *cursorSurface = _surface->getSurface();
186 CursorMan.replaceCursor((const byte*)cursorSurface->getPixels(),
187 cursorSurface->w, cursorSurface->h, -_drawOffset.x, -_drawOffset.y, 0);
188 }
189
190 }
191
updateCursorNum()192 void Mouse::updateCursorNum() {
193 switch (_mouseType) {
194 case kMouseType433:
195 if (_x >= _mouseRect.x1 && _x <= _mouseRect.x2 &&
196 _y >= _mouseRect.y1 && _y <= _mouseRect.y2) {
197 _mouseCursorResource.setCursorNum(1);
198 } else {
199 _mouseCursorResource.setCursorNum(4);
200 }
201 break;
202 case kMouseType435:
203 if (_x <= _x1) {
204 _mouseCursorResource.setCursorNum(6);
205 } else if (_x >= _x2) {
206 _mouseCursorResource.setCursorNum(5);
207 } else {
208 _mouseCursorResource.setCursorNum(4);
209 }
210 break;
211 case kMouseTypeNavigation:
212 switch (_type) {
213 case 1:
214 if (_x >= 320)
215 _mouseCursorResource.setCursorNum(5);
216 else
217 _mouseCursorResource.setCursorNum(6);
218 break;
219 case 2:
220 default:
221 if (_x < 100)
222 _mouseCursorResource.setCursorNum(6);
223 else if (_x > 540)
224 _mouseCursorResource.setCursorNum(5);
225 else
226 _mouseCursorResource.setCursorNum(0);
227 break;
228 case 3:
229 if (_x < 100)
230 _mouseCursorResource.setCursorNum(1);
231 else if (_x > 540)
232 _mouseCursorResource.setCursorNum(1);
233 break;
234 case 4:
235 if (_x < 100)
236 _mouseCursorResource.setCursorNum(6);
237 else if (_x > 540)
238 _mouseCursorResource.setCursorNum(5);
239 else if (_y >= 150)
240 _mouseCursorResource.setCursorNum(0);
241 else
242 _mouseCursorResource.setCursorNum(3);
243 break;
244 case 5:
245 if (_y >= 240)
246 _mouseCursorResource.setCursorNum(2);
247 else
248 _mouseCursorResource.setCursorNum(3);
249 break;
250 }
251 break;
252 }
253
254 }
255
256 } // End of namespace Neverhood
257