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 #ifndef NUVIE_CORE_MAP_WINDOW_H
24 #define NUVIE_CORE_MAP_WINDOW_H
25 
26 #include "ultima/shared/std/containers.h"
27 
28 
29 #include "ultima/nuvie/core/nuvie_defs.h"
30 #include "ultima/nuvie/core/obj_manager.h"
31 #include "ultima/nuvie/gui/widgets/gui_widget.h"
32 #include "ultima/nuvie/core/map.h"
33 
34 namespace Ultima {
35 namespace Nuvie {
36 
37 class Configuration;
38 class TileManager;
39 class ActorManager;
40 class Actor;
41 class AnimManager;
42 class Map;
43 class MapCoord;
44 class Screen;
45 class CallBack;
46 class Game;
47 
48 #define MAPWINDOW_THUMBNAIL_SIZE 52
49 #define MAPWINDOW_THUMBNAIL_SCALE 3
50 
51 #define MAP_OVERLAY_DEFAULT 0 /* just below border */
52 #define MAP_OVERLAY_ONTOP   1 /* cover border */
53 
54 #define MAPWINDOW_ROOFTILES_IMG_W 5
55 #define MAPWINDOW_ROOFTILES_IMG_H 204
56 
57 typedef struct {
58 	Tile *t;
59 	uint16 x, y;
60 } TileInfo;
61 
62 typedef struct {
63 	Tile *eye_tile;
64 	uint16 prev_x, prev_y;
65 	uint16 moves_left;
66 	CallBack *caller;
67 } WizardEye;
68 
69 enum RoofDisplayType {ROOF_DISPLAY_OFF, ROOF_DISPLAY_NORMAL, ROOF_DISPLAY_FORCE_ON };
70 enum InterfaceType { INTERFACE_NORMAL, INTERFACE_FULLSCREEN, INTERFACE_IGNORE_BLOCK };
71 enum X_RayType { X_RAY_CHEAT_OFF = -1,  X_RAY_OFF = 0, X_RAY_ON = 1, X_RAY_CHEAT_ON = 2};
72 enum CanDropOrMoveMsg { MSG_NOT_POSSIBLE, MSG_SUCCESS, MSG_BLOCKED, MSG_OUT_OF_RANGE, MSG_NO_TILE};
73 
74 class MapWindow: public GUI_Widget {
75 	friend class AnimManager;
76 	friend class ConverseGumpWOU;
77 	Game *game;
78 	Configuration *config;
79 	int game_type;
80 	bool enable_doubleclick;
81 	bool walk_with_left_button;
82 	uint8 walk_button_mask;
83 	X_RayType x_ray_view;
84 	InterfaceType interface;
85 
86 	bool custom_actor_tiles;
87 
88 	Map *map;
89 
90 	uint16 *tmp_map_buf; // tempory buffer for flood fill, hide rooms.
91 	uint16 tmp_map_width, tmp_map_height;
92 	Graphics::ManagedSurface *overlay; // used for visual effects
93 	uint8 overlay_level; // where the overlay surface is placed
94 	int min_brightness;
95 
96 	TileManager *tile_manager;
97 	ObjManager *obj_manager;
98 	ActorManager *actor_manager;
99 	AnimManager *anim_manager;
100 
101 	sint16 cur_x, cur_y;
102 	uint16 cursor_x, cursor_y, map_center_xoff;
103 	sint16 mousecenter_x, mousecenter_y; // location mousecursor rotates around, relative to cur_x&cur_y
104 	uint16 last_boundary_fill_x, last_boundary_fill_y; // start of boundary-fill in previous blacking update
105 	Tile *cursor_tile;
106 	Tile *use_tile;
107 
108 	bool show_cursor;
109 	bool show_use_cursor;
110 	bool show_grid;
111 
112 	unsigned char *thumbnail;
113 	bool new_thumbnail;
114 
115 	uint16 win_width, win_height, border_width;
116 	uint8 cur_level;
117 	uint16 map_width;
118 
119 	uint8 cur_x_add, cur_y_add; // pixel offset from cur_x,cur_y (set by shiftMapRelative)
120 	sint32 vel_x, vel_y; // velocity of automatic map movement (pixels per second)
121 
122 	Common::Rect clip_rect;
123 
124 	Obj *selected_obj;
125 	Actor *look_actor;
126 	Obj *look_obj;
127 	bool hackmove;
128 	bool walking;
129 	bool look_on_left_click;
130 	bool looking; // used to stop look_on_left_click from triggering during mouseup from left button walking, failed drag, or input mode
131 
132 	bool window_updated;
133 	bool freeze_blacking_location;
134 	bool enable_blacking;
135 
136 	bool roof_mode;
137 	RoofDisplayType roof_display;
138 
139 	Graphics::ManagedSurface *roof_tiles;
140 
141 	WizardEye wizard_eye_info;
142 
143 	bool draw_brit_lens_anim;
144 	bool draw_garg_lens_anim;
145 // Std::vector<TileInfo> m_ViewableObjTiles; // shouldn't need this for in_town checks
146 	Std::vector<TileInfo> m_ViewableMapTiles;
147 
148 	bool lighting_update_required;
149 
150 public:
151 
152 	MapWindow(Configuration *cfg, Map *m);
153 	~MapWindow() override;
154 
155 	bool init(TileManager *tm, ObjManager *om, ActorManager *am);
156 
get_cur_x()157 	sint16 get_cur_x() {
158 		return cur_x;
159 	}
get_cur_y()160 	sint16 get_cur_y() {
161 		return cur_y;
162 	}
163 	bool set_windowSize(uint16 width, uint16 height);
164 	void set_show_cursor(bool state);
165 	void set_show_use_cursor(bool state);
166 	void set_show_grid(bool state);
is_grid_showing()167 	bool is_grid_showing() {
168 		return show_grid;
169 	}
set_velocity(sint16 vx,sint16 vy)170 	void set_velocity(sint16 vx, sint16 vy) {
171 		vel_x = vx;
172 		vel_y = vy;
173 	}
174 	void set_overlay(Graphics::ManagedSurface *surfpt);
175 	void set_overlay_level(int level = MAP_OVERLAY_DEFAULT) {
176 		overlay_level = level;
177 	}
178 	void set_x_ray_view(X_RayType state, bool cheat_off = false);
get_x_ray_view()179 	X_RayType get_x_ray_view() {
180 		return x_ray_view;
181 	}
182 	void set_freeze_blacking_location(bool state);
183 	void set_enable_blacking(bool state);
184 	void set_roof_mode(bool roofs);
set_roof_display_mode(enum RoofDisplayType mode)185 	void set_roof_display_mode(enum RoofDisplayType mode) {
186 		roof_display = mode;
187 	}
188 	void set_walking(bool state);
189 	void set_walk_button_mask();
will_walk_with_left_button()190 	bool will_walk_with_left_button() {
191 		return walk_with_left_button;
192 	}
set_walk_with_left_button(bool val)193 	void set_walk_with_left_button(bool val) {
194 		walk_with_left_button = val;
195 		set_walk_button_mask();
196 	}
set_looking(bool state)197 	void set_looking(bool state) {
198 		looking = state;
199 	}
get_min_brightness()200 	int get_min_brightness() {
201 		return min_brightness;
202 	}
set_min_brightness(int brightness)203 	void set_min_brightness(int brightness) {
204 		min_brightness = brightness;
205 	}
206 
207 	void moveLevel(uint8 new_level);
208 	void moveMap(sint16 new_x, sint16 new_y, sint8 new_level, uint8 new_x_add = 0, uint8 new_y_add = 0);
209 	void moveMapRelative(sint16 rel_x, sint16 rel_y);
210 	void shiftMapRelative(sint16 rel_x, sint16 rel_y);
set_mousecenter(sint16 new_x,sint16 new_y)211 	void set_mousecenter(sint16 new_x, sint16 new_y) {
212 		mousecenter_x = new_x;
213 		mousecenter_y = new_y;
214 	}
reset_mousecenter()215 	void reset_mousecenter() {
216 		mousecenter_x = win_width / 2;
217 		mousecenter_y = win_height / 2;
218 	}
get_win_area()219 	uint16 get_win_area() {
220 		return win_width * win_height;
221 	}
222 	void centerMapOnActor(Actor *actor);
223 	void centerMap(uint16 x, uint16 y, uint8 z);
224 	void centerCursor();
225 
226 	void moveCursor(sint16 new_x, sint16 new_y);
227 	void moveCursorRelative(sint16 rel_x, sint16 rel_y);
228 
is_doubleclick_enabled()229 	bool is_doubleclick_enabled() {
230 		return enable_doubleclick;
231 	}
set_enable_doubleclick(bool val)232 	void set_enable_doubleclick(bool val) {
233 		enable_doubleclick = val;
234 	}
set_look_on_left_click(bool val)235 	void set_look_on_left_click(bool val) {
236 		look_on_left_click = val;
237 	}
238 	void set_use_left_clicks();
will_look_on_left_click()239 	bool will_look_on_left_click() {
240 		return look_on_left_click;
241 	}
242 	bool is_on_screen(uint16 x, uint16 y, uint8 z);
243 	bool tile_is_black(uint16 x, uint16 y, Obj *obj = NULL); // subtracts cur_x and cur_y
244 	const char *look(uint16 x, uint16 y, bool show_prefix = true);
245 	const char *lookAtCursor(bool show_prefix = true) {
246 		return (look(cursor_x, cursor_y, show_prefix));
247 	}
248 	Obj *get_objAtCursor(bool for_use = false);
249 	Obj *get_objAtCoord(MapCoord coord, bool top_obj, bool include_ignored_objects, bool for_use = false);
250 	Actor *get_actorAtCursor();
251 	MapCoord get_cursorCoord();
252 	Obj *get_objAtMousePos(int x, int y);
253 	Actor *get_actorAtMousePos(int x, int y);
254 	void teleport_to_cursor();
255 	void select_target(int x, int y);
256 	void mouseToWorldCoords(int mx, int my, int &wx, int &wy);
257 	void get_movement_direction(uint16 mx, uint16 my, sint16 &rel_x, sint16 &rel_y, uint8 *mptr = NULL);
258 
get_tile_manager()259 	TileManager *get_tile_manager() {
260 		return tile_manager;
261 	}
get_anim_manager()262 	AnimManager *get_anim_manager() {
263 		return anim_manager;
264 	}
get_clip_rect()265 	Common::Rect *get_clip_rect()       {
266 		return &clip_rect;
267 	}
268 	Graphics::ManagedSurface *get_overlay();
269 
270 	void get_level(uint8 *level);
271 	void get_pos(uint16 *x, uint16 *y, uint8 *px = NULL, uint8 *py = NULL);
get_velocity(sint16 * vx,sint16 * vy)272 	void get_velocity(sint16 *vx, sint16 *vy) {
273 		*vx = vel_x;
274 		*vy = vel_y;
275 	}
276 	void get_windowSize(uint16 *width, uint16 *height);
277 
278 	bool in_window(uint16 x, uint16 y, uint8 z);
279 	bool in_dungeon_level();
280 	bool in_town();
281 // can put object at world location x,y?
282 	CanDropOrMoveMsg can_drop_or_move_obj(uint16 x, uint16 y, Actor *actor, Obj *obj);
283 	void display_can_drop_or_move_msg(CanDropOrMoveMsg msg, Std::string msg_text = "");
284 	bool can_get_obj(Actor *actor, Obj *obj);
285 	bool blocked_by_wall(Actor *actor, Obj *obj);
286 	void display_move_text(Actor *target_actor, Obj *obj);
287 	MapCoord original_obj_loc;
288 
289 	void updateBlacking();
290 	void updateAmbience();
291 	void update();
292 	void Display(bool full_redraw) override;
293 
294 	GUI_status MouseDown(int x, int y, Shared::MouseButton button) override;
295 	GUI_status MouseUp(int x, int y, Shared::MouseButton button) override;
296 	GUI_status MouseMotion(int x, int y, uint8 state) override;
297 	GUI_status MouseDouble(int x, int y, Shared::MouseButton button) override;
298 	GUI_status MouseClick(int x, int y, Shared::MouseButton button) override;
299 	GUI_status Idle(void) override;
300 	GUI_status MouseLeave(uint8 state) override;
301 	GUI_status MouseDelayed(int x, int y, Shared::MouseButton button) override;
302 	GUI_status MouseHeld(int x, int y, Shared::MouseButton button) override;
303 	GUI_status KeyDown(const Common::KeyState &key) override;
304 	GUI_status MouseWheel(sint32 x, sint32 y) override;
305 
306 	void drag_drop_success(int x, int y, int message, void *data) override;
307 	void drag_drop_failed(int x, int y, int message, void *data) override;
308 
309 	bool drag_accept_drop(int x, int y, int message, void *data) override;
310 	void drag_perform_drop(int x, int y, int message, void *data) override;
311 	bool move_on_drop(Obj *obj);
312 	void set_interface();
313 	InterfaceType get_interface();
314 	bool is_interface_fullscreen_in_combat();
315 
316 	void drag_draw(int x, int y, int message, void *data) override;
317 
318 	void update_mouse_cursor(uint32 mx, uint32 my);
319 
320 	unsigned char *make_thumbnail();
321 	void free_thumbnail();
322 	Graphics::ManagedSurface *get_sdl_surface();
323 	Graphics::ManagedSurface *get_sdl_surface(uint16 x, uint16 y, uint16 w, uint16 h);
get_roof_tiles()324 	Graphics::ManagedSurface *get_roof_tiles() {
325 		return roof_tiles;
326 	}
327 
328 	Std::vector<Obj *> m_ViewableObjects; //^^ dodgy public buffer
329 
330 	void wizard_eye_start(MapCoord location, uint16 duration, CallBack *caller);
331 
332 	bool using_map_tile_lighting;
333 
334 protected:
335 	void create_thumbnail();
336 
337 	void drawActors();
338 	void drawAnims(bool top_anims);
339 	void drawObjs();
340 	void drawObjSuperBlock(bool draw_lowertiles, bool toptile);
341 	inline void drawObj(Obj *obj, bool draw_lowertiles, bool toptile);
342 	inline void drawTile(Tile *tile, uint16 x, uint16 y, bool toptile, bool use_tile_data = false);
343 	inline void drawNewTile(Tile *tile, uint16 x, uint16 y, bool toptile);
344 	void drawBorder();
345 	inline void drawTopTile(Tile *tile, uint16 x, uint16 y, bool toptile);
346 	inline void drawActor(Actor *actor);
347 	void drawRoofs();
348 	void drawGrid();
349 	void drawRain();
350 	inline void drawLensAnim();
351 
352 	void updateLighting();
353 	void generateTmpMap();
354 	void boundaryFill(unsigned char *map_ptr, uint16 pitch, uint16 x, uint16 y);
355 	bool floorTilesVisible();
356 	bool boundaryLookThroughWindow(uint16 tile_num, uint16 x, uint16 y);
357 
358 	void reshapeBoundary();
359 	inline bool tmpBufTileIsBlack(uint16 x, uint16 y);
360 	bool tmpBufTileIsBoundary(uint16 x, uint16 y);
361 	bool tmpBufTileIsWall(uint16 x, uint16 y, uint8 direction);
362 
363 	void wizard_eye_stop();
364 	void wizard_eye_update();
is_wizard_eye_mode()365 	bool is_wizard_eye_mode() {
366 		if (wizard_eye_info.moves_left != 0) return true;
367 		else return false;
368 	}
369 
370 	void loadRoofTiles();
371 
372 private:
373 	void createLightOverlay();
374 
375 	void AddMapTileToVisibleList(uint16 tile_num, uint16 x, uint16 y);
376 	bool can_display_obj(uint16 x, uint16 y, Obj *obj);
377 };
378 
379 } // End of namespace Nuvie
380 } // End of namespace Ultima
381 
382 #endif
383