1 /*
2  *  gamewin.h - X-windows Ultima7 map browser.
3  *
4  *  Copyright (C) 1998-1999  Jeffrey S. Freedman
5  *  Copyright (C) 2000-2013  The Exult Team
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #ifndef GAMEWIN_H
23 #define GAMEWIN_H
24 
25 #include "flags.h"
26 #include "iwin8.h"
27 #include "rect.h"
28 #include "tiles.h"
29 #include "vgafile.h"
30 #include "shapeid.h"
31 
32 #include <memory>
33 #include <string>   // STL string
34 #include <vector>
35 
36 #ifndef ATTR_PRINTF
37 #ifdef __GNUC__
38 #define ATTR_PRINTF(x,y) __attribute__((format(printf, (x), (y))))
39 #else
40 #define ATTR_PRINTF(x,y)
41 #endif
42 #endif
43 
44 class Actor;
45 class Barge_object;
46 class Map_chunk;
47 class Chunk_terrain;
48 class Egg_object;
49 class Font;
50 class Game_object;
51 class Game_clock;
52 class Time_sensitive;
53 class Gump;
54 class Gump_button;
55 class Ireg_game_object;
56 class Dead_body;
57 class Main_actor;
58 class Npc_actor;
59 class Npc_face_info;
60 class Npc_proximity_handler;
61 class Palette;
62 class Time_queue;
63 class Usecode_machine;
64 class Deleted_objects;
65 class Gump_manager;
66 struct SaveGame_Details;
67 struct SaveGame_Party;
68 class Map_patch_collection;
69 class Dragging_info;
70 class Game_map;
71 class Shape_manager;
72 class Party_manager;
73 class ShapeID;
74 class Shape_info;
75 class Game_render;
76 class Effects_manager;
77 using Actor_shared = std::shared_ptr<Actor>;
78 
79 struct Position2d {
80 	int x;
81 	int y;
82 };
83 using Game_object_map_xy = std::map<Game_object*, Position2d>;
84 
85 /*
86  *  The main game window:
87  */
88 class Game_window {
89 	static Game_window *game_window;// There's just one.
90 	// Game component classes:
91 	Dragging_info *dragging;    // Dragging info:
92 	Effects_manager *effects;   // Manages special effects.
93 	Game_clock *clock;      // Keeps track of time.
94 	std::vector<Game_map *> maps; // Hold all terrain.
95 	Game_map *map;          // The current map.
96 	Game_render *render;        // Helps with rendering.
97 	Gump_manager *gump_man;     // Open containers on screen.
98 	Party_manager *party_man;   // Keeps party list.
99 	Image_window8 *win;     // Window to display into.
100 	Npc_proximity_handler *npc_prox;// Handles nearby NPC's.
101 	Palette *pal;
102 	Shape_manager *shape_man;   // Manages shape file.
103 	Time_queue *tqueue;     // Time-based queue.
104 	Time_sensitive *background_noise;
105 	Usecode_machine *usecode;   // Drives game plot.
106 	// Game state flags:
107 	bool combat;             // true if in combat.
108 	bool focus;              // Do we have focus?
109 	bool ice_dungeon;        // true if inside ice dungeon
110 	bool painted;            // true if we updated image buffer.
111 	bool ambient_light;      // Permanent version of special_light.
112 	bool infravision_active; // Infravision flag.
113 	// Game state values:
114 	int skip_above_actor;       // Level above actor to skip rendering.
115 	unsigned int in_dungeon;    // true if inside a dungeon.
116 	int num_npcs1;          // Number of type1 NPC's.
117 	int std_delay;          // Standard delay between frames.
118 	long time_stopped;      // For 'stop time' spell.
119 	unsigned long special_light;    // Game minute when light spell ends.
120 	int theft_warnings;     // # times warned in current chunk.
121 	short theft_cx, theft_cy;   // Chunk where warnings occurred.
122 	// Gameplay objects:
123 	Barge_object *moving_barge; // ->cart/ship that's moving, or 0.
124 	Main_actor *main_actor;     // Main sprite to move around.
125 	Actor *camera_actor;        // What to center view around.
126 	std::vector<Actor_shared> npcs;  // Array of NPC's + the Avatar.
127 	std::vector<Dead_body *> bodies; // Corresponding Dead_body's.
128 	// Rendering info:
129 	int scrolltx, scrollty;     // Top-left tile of screen.
130 	TileRect scroll_bounds;    // Walking outside this scrolls.
131 	TileRect dirty;        // Dirty rectangle.
132 	// Savegames:
133 	char *save_names[10];       // Names of saved games.
134 	// Options:
135 	bool mouse3rd;          // use third (middle) mouse button
136 	bool fastmouse;
137 	bool double_click_closes_gumps;
138 	int text_bg;            // draw a dark background behind text
139 	int step_tile_delta;    // multiplier for the delta in start_actor_alt
140 	int allow_right_pathfind;   // If moving with right click is allowed
141 	bool scroll_with_mouse;         // scroll game view with mousewheel
142 	bool alternate_drop;    // don't split stacks, can be inverted with a CTRL key modifier
143 	bool allow_autonotes;
144 	bool in_exult_menu;     // used for menu options
145 	uint8 use_shortcutbar; // 0 = no, 1 = trans, 2 = yes
146 	Pixel_colors outline_color;
147 	bool sb_hide_missing;
148 	bool extended_intro;
149 
150 	// Touch Options
151 	bool item_menu;
152 	int dpad_location;
153 	bool touch_pathfind;
154 
155 	// Private methods:
156 	void set_scrolls(Tile_coord cent);
157 	void clear_world(bool restoremapedit);      // Clear out world's contents.
158 	void read_save_names();     // Read in saved-game names.
159 	long check_time_stopped();
160 
161 	// Red plasma animation during game load
162 	uint32 load_palette_timer;
163 	int plasma_start_color, plasma_cycle_range;
164 
165 public:
166 	friend class Game_render;
167 	/*
168 	 *  Public flags and gameplay options:
169 	 */
170 	int skip_lift;          // Skip objects with lift >= this.  0
171 	//   means 'terrain-editing' mode.
172 	bool paint_eggs;
173 	bool armageddon;        // Spell was cast.
174 	bool walk_in_formation;     // Use Party_manager for walking.
175 	int debug;
176 	uint32 blits;           // For frame-counting.
177 	/*
178 	 *  Class maintenance:
179 	 */
180 	Game_window(int width, int height, bool fullscreen, int gwidth, int gheight, int scale = 1,
181 	            int scaler = 0, Image_window::FillMode fillmode = Image_window::AspectCorrectCentre, unsigned int fillsclr = 0);
182 	~Game_window();
183 	// Get the one game window.
get_instance()184 	static Game_window *get_instance() {
185 		return game_window;
186 	}
187 	void abort(const char *msg, ...) ATTR_PRINTF(2,3);   // Fatal error.
188 	/*
189 	 *  Display:
190 	 */
191 	void clear_screen(bool update = false);
192 
193 	//int get_width() const
194 	//  { return win->get_width(); }
195 	//int get_height() const
196 	//  { return win->get_height(); }
get_width()197 	int get_width() const {
198 		return win->get_game_width();
199 	}
get_height()200 	int get_height() const {
201 		return win->get_game_height();
202 	}
get_game_width()203 	int get_game_width() const {
204 		return win->get_game_width();
205 	}
get_game_height()206 	int get_game_height() const {
207 		return win->get_game_height();
208 	}
209 
get_scrolltx()210 	inline int get_scrolltx() const {   // Get window offsets in tiles.
211 		return scrolltx;
212 	}
get_scrollty()213 	inline int get_scrollty() const {
214 		return scrollty;
215 	}
get_game_rect()216 	inline TileRect get_game_rect() const  // Get window's rectangle.
217 	{
218 		return TileRect(0, 0, win->get_game_width(), win->get_game_height());
219 	}
get_full_rect()220 	inline TileRect get_full_rect() const { // Get window's rectangle.
221 		return TileRect(win->get_start_x(), win->get_start_y(), win->get_full_width(), win->get_full_height());
222 	}
get_win_tile_rect()223 	TileRect get_win_tile_rect() const { // Get it in tiles, rounding up.
224 		return TileRect(get_scrolltx(), get_scrollty(),
225 		                (win->get_game_width() + c_tilesize - 1) / c_tilesize,
226 		                (win->get_game_height() + c_tilesize - 1) / c_tilesize);
227 	}
228 	// Clip rectangle to window's.
clip_to_game(TileRect const & r)229 	TileRect clip_to_game(TileRect const &r) const {
230 		TileRect wr = get_game_rect();
231 		return r.intersect(wr);
232 	}
clip_to_win(TileRect const & r)233 	TileRect clip_to_win(TileRect const &r) const {
234 		TileRect wr = get_full_rect();
235 		return r.intersect(wr);
236 	}
237 	// Resize event occurred.
238 	void resized(unsigned int neww, unsigned int newh, bool newfs,
239 	             unsigned int newgw, unsigned int newgh,
240 	             unsigned int newsc, unsigned int newsclr,
241 	             Image_window::FillMode newfill, unsigned int newfillsclr
242 	            );
243 
244 	void get_focus();       // Get/lose focus.
245 	void lose_focus();
have_focus()246 	inline bool have_focus() const {
247 		return focus;
248 	}
249 	/*
250 	 *  Game options:
251 	 */
get_mouse3rd()252 	bool get_mouse3rd() const {
253 		return mouse3rd;
254 	}
set_mouse3rd(bool m)255 	void set_mouse3rd(bool m) {
256 		mouse3rd = m;
257 	}
258 	bool get_fastmouse(bool ignorefs = false) const {
259 		return (ignorefs || get_win()->is_fullscreen()) ? fastmouse : false;
260 	}
set_fastmouse(bool f)261 	void set_fastmouse(bool f) {
262 		fastmouse = f;
263 	}
get_double_click_closes_gumps()264 	bool get_double_click_closes_gumps() const {
265 		return double_click_closes_gumps;
266 	}
set_double_click_closes_gumps(bool d)267 	void set_double_click_closes_gumps(bool d) {
268 		double_click_closes_gumps = d;
269 	}
get_text_bg()270 	int get_text_bg() const {
271 		return text_bg;
272 	}
set_text_bg(int t)273 	void set_text_bg(int t) {
274 		text_bg = t;
275 	}
can_scroll_with_mouse()276 	bool can_scroll_with_mouse() const { // scroll game view with mousewheel
277 		return scroll_with_mouse;
278 	}
set_mouse_with_scroll(bool ms)279 	void set_mouse_with_scroll(bool ms) {
280 		scroll_with_mouse = ms;
281 	}
get_alternate_drop()282 	bool get_alternate_drop() const {
283 		return alternate_drop;
284 	}
set_alternate_drop(bool s)285 	void set_alternate_drop(bool s) {
286 		alternate_drop = s;
287 	}
get_allow_autonotes()288 	bool get_allow_autonotes() const {
289 		return allow_autonotes;
290 	}
set_allow_autonotes(bool s)291 	void set_allow_autonotes(bool s) {
292 		allow_autonotes = s;
293 	}
is_in_exult_menu()294 	bool is_in_exult_menu() const {     // used for menu options
295 		return in_exult_menu;
296 	}
set_in_exult_menu(bool im)297 	void set_in_exult_menu(bool im) {
298 		in_exult_menu = im;
299 	}
using_shortcutbar()300 	bool using_shortcutbar() const {
301 		return use_shortcutbar > 0;
302 	}
303 	void set_shortcutbar(uint8 s);
get_shortcutbar_type()304 	uint8 get_shortcutbar_type() const {
305 		return use_shortcutbar;
306 	}
get_outline_color()307 	Pixel_colors get_outline_color() const {
308 		return outline_color;
309 	}
set_outline_color(Pixel_colors s)310 	void set_outline_color(Pixel_colors s) {
311 		outline_color = s;
312 	}
sb_hide_missing_items()313 	bool sb_hide_missing_items() const {
314 		return sb_hide_missing;
315 	}
set_sb_hide_missing_items(bool s)316 	void set_sb_hide_missing_items(bool s) {
317 		sb_hide_missing = s;
318 	}
get_extended_intro()319 	bool get_extended_intro() const {
320 		return extended_intro;
321 	}
set_extended_intro(bool i)322 	void set_extended_intro(bool i) {
323 		extended_intro = i;
324 	}
325 	/*
326 	 * Touch options:
327  	*/
get_item_menu()328 	bool get_item_menu() const {
329 		return item_menu;
330 	}
set_item_menu(bool s)331 	void set_item_menu(bool s) {
332 		item_menu = s;
333 	}
set_dpad_location(int a)334 	inline void set_dpad_location(int a) {
335 		dpad_location = a;
336 	}
get_dpad_location()337 	inline int get_dpad_location() const {
338 		return dpad_location;
339 	}
get_touch_pathfind()340 	bool get_touch_pathfind() const {
341 		return touch_pathfind;
342 	}
set_touch_pathfind(bool s)343 	void set_touch_pathfind(bool s) {
344 		touch_pathfind = s;
345 	}
346 
347 	/*
348 	 *  Game components:
349 	 */
get_map()350 	inline Game_map *get_map() const {
351 		return map;
352 	}
get_maps()353 	inline const std::vector<Game_map *> &get_maps() const {
354 		return maps;
355 	}
get_usecode()356 	inline Usecode_machine *get_usecode() const {
357 		return usecode;
358 	}
get_win()359 	inline Image_window8 *get_win() const {
360 		return win;
361 	}
get_tqueue()362 	inline Time_queue *get_tqueue() const {
363 		return tqueue;
364 	}
get_pal()365 	inline Palette *get_pal() const {
366 		return pal;
367 	}
get_effects()368 	inline Effects_manager *get_effects() const {
369 		return effects;
370 	}
get_gump_man()371 	inline Gump_manager *get_gump_man() const {
372 		return gump_man;
373 	}
get_party_man()374 	inline Party_manager *get_party_man() const {
375 		return party_man;
376 	}
get_npc_prox()377 	inline Npc_proximity_handler *get_npc_prox() const {
378 		return npc_prox;
379 	}
get_clock()380 	Game_clock *get_clock() const {
381 		return clock;
382 	}
383 	bool is_bg_track(int num) const; // ripped out of Background_noise
384 	Game_map *get_map(int num); // Read in additional map.
385 	void set_map(int num);      // Make map #num the current map.
386 	/*
387 	 *  ExultStudio support:
388 	 */
389 	Map_patch_collection& get_map_patches();
390 	// Locate shape (for EStudio).
391 	bool locate_shape(int shapenum, bool upwards, int frnum, int qual);
392 	void send_location();       // Send our location to EStudio.
393 	/*
394 	 *  Gameplay data:
395 	 */
get_moving_barge()396 	inline Barge_object *get_moving_barge() const {
397 		return moving_barge;
398 	}
399 	void set_moving_barge(Barge_object *b);
400 	bool is_moving() const;       // Is Avatar (or barge) moving?
get_main_actor()401 	inline Main_actor *get_main_actor() const {
402 		return main_actor;
403 	}
is_main_actor_inside()404 	bool is_main_actor_inside() const {
405 		return skip_above_actor < 31 ;
406 	}
407 	// Returns if skip_above_actor changed!
set_above_main_actor(int lift)408 	bool set_above_main_actor(int lift) {
409 		if (skip_above_actor == lift) return false;
410 		skip_above_actor = lift;
411 		return true;
412 	}
get_render_skip_lift()413 	int get_render_skip_lift() const {  // Skip rendering here.
414 		return skip_above_actor < skip_lift ?
415 		       skip_above_actor : skip_lift;
416 	}
417 	bool main_actor_dont_move() const;
418 	bool main_actor_can_act() const;
419 	bool main_actor_can_act_charmed() const;
set_in_dungeon(unsigned int lift)420 	inline bool set_in_dungeon(unsigned int lift) {
421 		if (in_dungeon == lift)
422 			return false;
423 		in_dungeon = lift;
424 		return true;
425 	}
set_ice_dungeon(bool ice)426 	inline void set_ice_dungeon(bool ice) {
427 		ice_dungeon = ice;
428 	}
is_in_dungeon()429 	inline unsigned int is_in_dungeon() const {
430 		return in_dungeon;
431 	}
432 	bool in_infravision() const;
toggle_infravision(bool state)433 	void toggle_infravision(bool state) {
434 		infravision_active = state;
435 	}
is_special_light()436 	inline bool is_special_light() const { // Light spell in effect?
437 		return ambient_light || special_light != 0;
438 	}
439 	// Light spell.
440 	void add_special_light(int units);
toggle_ambient_light(bool state)441 	void toggle_ambient_light(bool state) {
442 		ambient_light = state;
443 	}
444 	// Handle 'stop time' spell.
445 	void set_time_stopped(long delay);
is_time_stopped()446 	long is_time_stopped() {
447 		return !time_stopped ? 0 : check_time_stopped();
448 	}
get_std_delay()449 	int get_std_delay() const { // Get/set animation frame delay.
450 		return std_delay;
451 	}
set_std_delay(int msecs)452 	void set_std_delay(int msecs) {
453 		std_delay = msecs;
454 	}
455 	Actor *get_npc(long npc_num) const;
456 	void locate_npc(int npc_num);
set_body(int npc_num,Dead_body * body)457 	void set_body(int npc_num, Dead_body *body) {
458 		if (npc_num >= static_cast<int>(bodies.size()))
459 			bodies.resize(npc_num + 1);
460 		bodies[npc_num] = body;
461 	}
get_body(int npc_num)462 	Dead_body *get_body(int npc_num) const {
463 		return bodies[npc_num];
464 	}
get_num_npcs()465 	int get_num_npcs() const {
466 		return npcs.size();
467 	}
468 	int get_unused_npc();       // Find first unused NPC #.
469 	void add_npc(Actor *npc, int num);  // Add new one.
in_combat()470 	inline bool in_combat() const {    // In combat mode?
471 		return combat;
472 	}
473 	void toggle_combat();
get_frame_skipping()474 	inline bool get_frame_skipping() const {  // This needs doing
475 		return true;
476 	}
477 	// Get ->party members.
478 	int get_party(Actor **list, int avatar_too = 0);
479 	// Add npc to 'nearby' list.
480 	void add_nearby_npc(Npc_actor *npc);
481 	void remove_nearby_npc(Npc_actor *npc);
482 	// Get all nearby NPC's.
483 	void get_nearby_npcs(std::vector<Actor *> &list) const;
484 	// Update NPCs' schedules.
485 	void schedule_npcs(int hour, bool repaint = true);
486 	void mend_npcs();       // Restore HP's each hour.
487 	// Find witness to Avatar's 'crime'.
488 	Actor *find_witness(Actor  *&closest_npc, int align);
489 	void theft();           // Handle thievery.
490 	static int get_guard_shape();
491 	void call_guards(Actor *witness = nullptr, bool theft = false);
492 	void stop_arresting();
493 	void attack_avatar(int create_guards = 0, int align = 0);
494 	bool is_hostile_nearby() const; // detects if hostiles are nearby for movement speed
495 	bool failed_copy_protection();
496 	void got_bad_feeling(int odds);
497 	/*
498 	 *  Rendering:
499 	 */
set_painted()500 	inline void set_painted() { // Force blit.
501 		painted = true;
502 	}
was_painted()503 	inline bool was_painted() const {
504 		return painted;
505 	}
506 	bool show(bool force = false) { // Returns true if blit occurred.
507 		if (painted || force) {
508 			win->show();
509 			++blits;
510 			painted = false;
511 			return true;
512 		}
513 		return false;
514 	}
clear_dirty()515 	void clear_dirty() {    // Clear dirty rectangle.
516 		dirty.w = 0;
517 	}
is_dirty()518 	bool is_dirty() const {
519 		return dirty.w > 0;
520 	}
521 	// Paint scene at given tile.
522 	void paint_map_at_tile(int x, int y, int w, int h,
523 	                       int toptx, int topty, int skip_above = 31);
524 	// Paint area of image.
525 	void paint(int x, int y, int w, int h);
paint(TileRect & r)526 	void paint(TileRect &r) {
527 		paint(r.x, r.y, r.w, r.h);
528 	}
529 	void paint();           // Paint whole image.
530 	// Paint 'dirty' rectangle.
531 	void paint_dirty();
set_all_dirty()532 	void set_all_dirty() {      // Whole window.
533 		dirty = TileRect(win->get_start_x(), win->get_start_y(), win->get_full_width(), win->get_full_height());
534 	}
add_dirty(TileRect const & r)535 	void add_dirty(TileRect const &r) { // Add rectangle to dirty area.
536 		dirty = dirty.w > 0 ? dirty.add(r) : r;
537 	}
538 	// Add dirty rect. for obj. Rets. false
539 	//   if not on screen.
add_dirty(const Game_object * obj)540 	bool add_dirty(const Game_object *obj) {
541 		TileRect rect = get_shape_rect(obj);
542 		rect.enlarge(1 + c_tilesize / 2);
543 		rect = clip_to_win(rect);
544 		if (rect.w > 0 && rect.h > 0) {
545 			add_dirty(rect);
546 			return true;
547 		} else
548 			return false;
549 	}
550 	// Set view (upper-left).
551 	void set_scrolls(int newscrolltx, int newscrollty);
552 	void center_view(Tile_coord const &t);  // Center view around t.
553 	void set_camera_actor(Actor *a);
get_camera_actor()554 	Actor *get_camera_actor() {
555 		return camera_actor;
556 	}
557 	// Scroll if necessary.
558 	bool scroll_if_needed(Tile_coord t);
scroll_if_needed(const Actor * a,Tile_coord const & t)559 	bool scroll_if_needed(const Actor *a, Tile_coord const &t) {
560 		if (a == camera_actor) return scroll_if_needed(t);
561 		else return false;
562 	}
563 	// Show abs. location of mouse.
564 	void show_game_location(int x, int y);
565 	// Get screen area of shape at pt.
get_shape_rect(const Shape_frame * s,int x,int y)566 	TileRect get_shape_rect(const Shape_frame *s, int x, int y) const {
567 		return TileRect(x - s->get_xleft(), y - s->get_yabove(),
568 		                 s->get_width(), s->get_height());
569 	}
570 	// Get screen area used by object.
571 	TileRect get_shape_rect(const Game_object *obj) const;
572 	// Get screen loc. of object.
573 	void get_shape_location(const Game_object *obj, int &x, int &y);
574 	void get_shape_location(Tile_coord const &t, int &x, int &y);
575 	void plasma(int w, int h, int x, int y, int startc, int endc);
576 	/*
577 	 *  Save/restore/startup:
578 	 */
579 	void write();           // Write out to 'gamedat'.
580 	void read();            // Read in 'gamedat'.
581 	void write_gwin();      // Write gamedat/gamewin.dat.
582 	void read_gwin();       // Read gamedat/gamewin.dat.
583 	bool was_map_modified();    // Was any map modified?
584 	void write_map();       // Write map data to <PATCH> dir.
585 	void read_map();        // Reread initial game map.
586 	void reload_usecode();      // Reread (patched) usecode.
587 	void init_actors();     // Place actors in the world.
588 	void init_files(bool cycle = true); // Load all files
589 
590 	// From Gamedat
591 	void get_saveinfo(std::unique_ptr<Shape_file> &map,
592 	                  SaveGame_Details *&details,
593 	                  SaveGame_Party  *&party);
594 	// From Savegame
595 	bool get_saveinfo(int num, char *&name,
596 	                  std::unique_ptr<Shape_file> &map,
597 	                  SaveGame_Details *&details,
598 	                  SaveGame_Party  *&party);
599 	void read_saveinfo(IDataSource *in,
600 	                   SaveGame_Details *&details,
601 	                   SaveGame_Party  *&party);
602 private:
603 #ifdef HAVE_ZIP_SUPPORT
604 	bool get_saveinfo_zip(const char *fname, char *&name,
605 	                      std::unique_ptr<Shape_file> &map,
606 	                      SaveGame_Details *&details,
607 	                      SaveGame_Party  *&party);
608 #endif
609 	void restore_flex_files(IDataSource &in, const char *basepath);
610 public:
611 	void write_saveinfo();      // Write the save info to gamedat
get_save_name(int i)612 	inline char *get_save_name(int i) const { // Get ->saved-game name.
613 		return save_names[i];
614 	}
615 	void setup_game(bool map_editing);  // Prepare for game
616 	void read_npcs();       // Read in npc's.
617 	void write_npcs();      // Write them back.
618 	void read_schedules();      // Read npc's schedules.
619 	void write_schedules();     // Write npc's schedules.
620 	void revert_schedules(Actor *); // Reset a npc's schedule.
621 	// Explode a savegame into "gamedat".
622 	void restore_gamedat(const char *fname);
623 	void restore_gamedat(int num);
624 	// Save "gamedat".
625 	void save_gamedat(const char *fname, const char *savename);
626 	void save_gamedat(int num, const char *savename);
627 	bool init_gamedat(bool create); // Initialize gamedat directory
628 #ifdef HAVE_ZIP_SUPPORT
629 private:
630 	bool save_gamedat_zip(const char *fname, const char *savename);
631 	bool Restore_level2(void *uzf, const char *dirname, int dirlen);
632 	bool restore_gamedat_zip(const char *fname);
633 public:
634 #endif
635 	/*
636 	 *  Game control:
637 	 */
638 	void view_right();      // Move view 1 chunk to right.
639 	void view_left();       // Move view left by 1 chunk.
640 	void view_down();       // Move view down.
641 	void view_up();         // Move view up.
642 	// Start moving actor.
643 	void start_actor_alt(int winx, int winy, int speed);
644 	void start_actor(int winx, int winy, int speed = 125);
645 	void start_actor_along_path(int winx, int winy, int speed = 125);
646 	void stop_actor();      // Stop main actor.
set_step_tile_delta(int size)647 	inline void set_step_tile_delta(int size) {
648 		step_tile_delta = size;
649 	}
get_step_tile_delta()650 	inline int get_step_tile_delta() const {
651 		return step_tile_delta;
652 	}
set_allow_right_pathfind(int a)653 	inline void set_allow_right_pathfind(int a) {
654 		allow_right_pathfind = a;
655 	}
get_allow_right_pathfind()656 	inline int get_allow_right_pathfind() const {
657 		return allow_right_pathfind;
658 	}
659 	void teleport_party(Tile_coord const &t, bool skip_eggs = false,
660 	                    int newmap = -1, bool no_status_check = true);
661 	bool activate_item(int shnum, int frnum = c_any_framenum,
662 	                   int qual = c_any_qual); // Activate item in party.
663 	// Find object (x, y) is in.
664 	Game_object *find_object(int x, int y);
665 	void find_nearby_objects(Game_object_map_xy& mobjxy, int x, int y, Gump *gump = nullptr);
666 
667 	// Show names of items clicked on.
668 	void show_items(int x, int y, bool ctrl = false);
669 	// Right-click while combat paused.
670 	void paused_combat_select(int x, int y);
671 	ShapeID get_flat(int x, int y); // Return terrain (x, y) is in.
672 	// Schedule object for deletion.
673 	// Handle a double-click in window.
674 	void double_clicked(int x, int y);
675 	bool start_dragging(int x, int y);
676 	bool drag(int x, int y);    // During dragging.
677 	bool drop_dragged(int x, int y, bool moved);// Done dragging.
678 	void stop_dragging();
is_dragging()679 	bool is_dragging() const {
680 		return dragging != nullptr;
681 	}
682 	int drop_at_lift(Game_object *to_drop, int x, int y, int at_lift);
683 	Gump *get_dragging_gump();
684 	// Create a mini-screenshot (96x60)
685 	std::unique_ptr<Shape_file> create_mini_screenshot();
686 	/*
687 	 *  Chunk-caching:
688 	 */
689 	// Old Style Caching Emulation. Called if player has changed chunks
690 	void emulate_cache(Map_chunk *olist, Map_chunk *nlist);
691 	// Is a specific move by a monster or item allowed
692 	bool emulate_is_move_allowed(int tx, int ty);
693 	// Swapping a superchunk to disk emulation
694 	void emulate_swapout(int scx, int scy);
695 
696 	void setup_load_palette();
697 	void cycle_load_palette();
698 
699 private:
700 	//
701 	// Interpolated painting stuff, for smooth scrolling
702 	//
703 
704 	// These are saved scroll positions
705 	int scrolltx_l, scrollty_l;
706 	int scrolltx_lp, scrollty_lp;
707 	// These are the pixel offset that needs to be subtracted from shape positions due to smooth scrolling
708 	int scrolltx_lo, scrollty_lo;
709 	// Delta for camera actor position in pixels due to lerping of position
710 	int avposx_ld, avposy_ld;
711 	// Is lerping enabled
712 	int lerping_enabled;
713 
714 public:
715 	// Reset (well update really) saved lerp scroll positions
716 	void lerp_reset();
717 
718 	// (Re)paint the entire screen using a lerp factor 0-0x10000
719 	void paint_lerped(int factor);
720 
get_scrolltx_lo()721 	inline int get_scrolltx_lo() const {
722 		return scrolltx_lo;
723 	}
get_scrollty_lo()724 	inline int get_scrollty_lo() const {
725 		return scrollty_lo;
726 	}
727 
is_lerping_enabled()728 	int is_lerping_enabled() const {
729 		return lerping_enabled;
730 	}
set_lerping_enabled(int e)731 	void set_lerping_enabled(int e) {
732 		lerping_enabled = e;
733 	}
734 };
735 
736 #endif
737