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  * Additional copyright for this file:
8  * Copyright (C) 1994-1998 Revolution Software Ltd.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  */
24 
25 #ifndef SWORD2_MOUSE_H
26 #define SWORD2_MOUSE_H
27 
28 #include "common/rect.h"
29 
30 #define MENU_MASTER_OBJECT	44
31 
32 #define	MAX_SUBJECT_LIST 30	// is that enough?
33 
34 #define TOTAL_subjects		(375 - 256 + 1)	// the speech subject bar
35 #define TOTAL_engine_pockets	(15 + 10)	// +10 for overflow
36 #define	TOTAL_mouse_list 50
37 
38 namespace Sword2 {
39 
40 struct MenuObject;
41 struct BuildUnit;
42 
43 // Menubar defines.
44 
45 #define RDMENU_TOP		0
46 #define RDMENU_BOTTOM		1
47 
48 enum {
49 	MOUSE_normal		= 0,	// normal in game
50 	MOUSE_menu		= 1,	// menu chooser
51 	MOUSE_drag		= 2,	// dragging luggage
52 	MOUSE_system_menu	= 3,	// system menu chooser
53 	MOUSE_holding		= 4	// special
54 };
55 
56 enum {
57 	RDMOUSE_NOFLASH,
58 	RDMOUSE_FLASH
59 };
60 
61 enum {
62 	RDMENU_HIDDEN,
63 	RDMENU_SHOWN,
64 	RDMENU_OPENING,
65 	RDMENU_CLOSING,
66 	RDMENU_ALMOST_HIDDEN
67 };
68 
69 #define RDMENU_ICONWIDE		35
70 #define RDMENU_PSXICONWIDE	36
71 #define RDMENU_ICONDEEP		30
72 #define RDMENU_ICONSTART	24
73 #define RDMENU_ICONSPACING	5
74 #define RDMENU_MAXPOCKETS	15
75 
76 #define MOUSE_ANIM_HEADER_SIZE	6
77 
78 struct MouseAnim {
79 	uint8 runTimeComp;	// type of runtime compression used for the
80 				// frame data
81 	uint8 noAnimFrames;	// number of frames in the anim
82 	int8 xHotSpot;
83 	int8 yHotSpot;
84 	uint8 mousew;
85 	uint8 mouseh;
86 
87 	byte *data;
88 };
89 
90 // The MOUSE_holding mode is entered when the conversation menu is closed, and
91 // exited when the mouse cursor moves off that menu area. I don't know why yet.
92 
93 // mouse unit - like ObjectMouse, but with anim resource & pc (needed if
94 // sprite is to act as mouse detection mask)
95 
96 struct MouseUnit {
97 	// Basically the same information as in ObjectMouse, except the
98 	// coordinates are adjusted to conform to standard ScummVM usage.
99 
100 	Common::Rect rect;
101 	int32 priority;
102 	int32 pointer;
103 
104 	// In addition, we need an id when checking the mouse list, and a
105 	// text id for mouse-overs.
106 
107 	int32 id;
108 	int32 pointer_text;
109 };
110 
111 // Array of these for subject menu build up
112 
113  struct SubjectUnit {
114 	uint32 res;
115 	uint32 ref;
116 };
117 
118 // define these in a script and then register them with the system
119 
120 struct MenuObject {
121 	int32 icon_resource;	// icon graphic graphic
122 	int32 luggage_resource;	// luggage icon resource (for attaching to
123 				// mouse pointer)
124 };
125 
126 class Mouse {
127 private:
128 	Sword2Engine *_vm;
129 
130 	MouseUnit _mouseList[TOTAL_mouse_list];
131 	uint32 _curMouse;
132 
133 	MenuObject _tempList[TOTAL_engine_pockets];
134 	uint32 _totalTemp;
135 
136 	MenuObject _masterMenuList[TOTAL_engine_pockets];
137 	uint32 _totalMasters;
138 
139 	SubjectUnit _subjectList[MAX_SUBJECT_LIST];
140 
141 	// ref number for default response when luggage icon is used on a
142 	// person & it doesn't match any of the icons which would have been in
143 	// the chooser
144 
145 	uint32 _defaultResponseId;
146 
147 	// could alternately use logic->looping of course
148 	bool _choosing;
149 
150 	uint8 _menuStatus[2];
151 	byte *_icons[2][RDMENU_MAXPOCKETS];
152 	uint8 _pocketStatus[2][RDMENU_MAXPOCKETS];
153 
154 	uint8 _iconCount;
155 
156 	// If it's NORMAL_MOUSE_ID (ie. normal pointer) then it's over a floor
157 	// area (or hidden hot-zone)
158 
159 	uint32 _mousePointerRes;
160 
161 	MouseAnim _mouseAnim;
162 	MouseAnim _luggageAnim;
163 
164 	uint8 _mouseFrame;
165 
166 	uint32 _mouseMode;
167 
168 	bool _mouseStatus;		// Human 0 on/1 off
169 	bool _mouseModeLocked;		// 0 not !0 mode cannot be changed from
170 					// normal mouse to top menu (i.e. when
171 					// carrying big objects)
172 	uint32 _realLuggageItem;	// Last minute for pause mode
173 	uint32 _currentLuggageResource;
174 	uint32 _oldButton;		// For the re-click stuff - must be
175 					// the same button you see
176 	uint32 _buttonClick;
177 	uint32 _pointerTextBlocNo;
178 	uint32 _playerActivityDelay;	// Player activity delay counter
179 
180 	bool _examiningMenuIcon;
181 
182 	// Set by checkMouseList()
183 	uint32 _mouseTouching;
184 	uint32 _oldMouseTouching;
185 
186 	bool _objectLabels;
187 
188 	uint32 _menuSelectedPos;
189 
190 	void decompressMouse(byte *decomp, byte *comp, uint8 frame, int width, int height, int pitch, int xOff = 0, int yOff = 0);
191 
192 	int32 setMouseAnim(byte *ma, int32 size, int32 mouseFlash);
193 	int32 setLuggageAnim(byte *la, int32 size);
194 
195 	void clearIconArea(int menu, int pocket, Common::Rect *r);
196 
197 public:
198 	Mouse(Sword2Engine *vm);
199 	~Mouse();
200 
201 	void getPos(int &x, int &y);
202 	int getX();
203 	int getY();
204 
getObjectLabels()205 	bool getObjectLabels() { return _objectLabels; }
setObjectLabels(bool b)206 	void setObjectLabels(bool b) { _objectLabels = b; }
207 
getMouseStatus()208 	bool getMouseStatus() { return _mouseStatus; }
getMouseTouching()209 	uint32 getMouseTouching() { return _mouseTouching; }
setMouseTouching(uint32 touching)210 	void setMouseTouching(uint32 touching) { _mouseTouching = touching; }
211 
212 	void pauseEngine(bool pause);
213 
214 	void setMouse(uint32 res);
215 	void setLuggage(uint32 res);
216 
217 	void setObjectHeld(uint32 res);
218 
219 	void resetMouseList();
220 
221 	void registerMouse(byte *ob_mouse, BuildUnit *build_unit);
222 	void registerPointerText(int32 text_id);
223 
224 	void createPointerText(uint32 text_id, uint32 pointer_res);
225 	void clearPointerText();
226 
227 	void drawMouse();
228 	int32 animateMouse();
229 
230 	void processMenu();
231 
232 	void addMenuObject(byte *ptr);
233 	void addSubject(int32 id, int32 ref);
234 
235 	void buildMenu();
236 	void buildSystemMenu();
237 
238 	int32 showMenu(uint8 menu);
239 	int32 hideMenu(uint8 menu);
240 	int32 setMenuIcon(uint8 menu, uint8 pocket, byte *icon);
241 
242 	void closeMenuImmediately();
243 
244 	void refreshInventory();
245 
246 	void startConversation();
247 	void endConversation();
248 
249 	void hideMouse();
250 	void noHuman();
251 	void addHuman();
252 
resetPlayerActivityDelay()253 	void resetPlayerActivityDelay() { _playerActivityDelay = 0; }
254 	void monitorPlayerActivity();
255 	void checkPlayerActivity(uint32 seconds);
256 
257 	void mouseOnOff();
258 	uint32 checkMouseList();
259 	void mouseEngine();
260 
261 	void normalMouse();
262 	void menuMouse();
263 	void dragMouse();
264 	void systemMenuMouse();
265 
isChoosing()266 	bool isChoosing() { return _choosing; }
267 	uint32 chooseMouse();
268 
269 	int menuClick(int menu_items);
270 
271 	int getMouseMode();
272 
273 	void setMouseMode(int mouseMode); // Used to force mouse mode
274 };
275 
276 } // End of namespace Sword2
277 
278 #endif
279