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 &param, 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