ScummVM API documentation
events.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef NUVIE_CORE_EVENT_H
23#define NUVIE_CORE_EVENT_H
24
25#include "common/str.h"
26#include "ultima/nuvie/misc/call_back.h"
27#include "ultima/nuvie/keybinding/keys_enum.h"
28#include "ultima/nuvie/core/obj_manager.h"
29
30namespace Ultima {
31namespace Nuvie {
32
33class Actor;
34class CallbackTarget;
35class Configuration;
36class Converse;
37class Book;
38class Game;
39class TimeQueue;
40class MapWindow;
41class MsgScroll;
42class GameClock;
43class Player;
44class ViewManager;
45class UseCode;
46class GUI;
47class GUI_Dialog;
48class Magic;
49class KeyBinder;
50class FpsCounter;
51class ScriptThread;
52
53#define NUVIE_INTERVAL 50
54#define PUSH_FROM_PLAYER false
55#define PUSH_FROM_OBJECT true
56
57#define BUTTON_MASK(MB) (1 << ((int)(MB) - 1))
58
59enum EventMode {
60 LOOK_MODE = 0,
61 USE_MODE,
62 GET_MODE,
63 MOVE_MODE,
64 DROP_MODE,
65 TALK_MODE, /* finding an actor to talk to */
66 ATTACK_MODE,
67 PUSH_MODE,
68 REST_MODE, /* modes before this need targets if using the command bar selected action */
69 CAST_MODE,
70 COMBAT_MODE, /* only used to cancel previous actions */
71 SPELL_MODE, //direct spell casting without spell select etc.
72 EQUIP_MODE,
73 WAIT_MODE, /* waiting for something, optionally display prompt when finished */
74 INPUT_MODE,
75 MULTIUSE_MODE,
76 KEYINPUT_MODE,
77 SCRIPT_MODE
78};
79
80extern uint32 nuvieGameCounter;
81
82// type of input that event may collect and send somewhere
83#define EVENTINPUT_MAPCOORD 0
84#define EVENTINPUT_KEY 1
85#define EVENTINPUT_STRING 2
86#define EVENTINPUT_OBJECT 3
87#define EVENTINPUT_MAPCOORD_DIR 4
88#define EVENTINPUT_SPELL_NUM 5
89
93const Common::KeyCode FIRST_JOY = (Common::KeyCode)400;
94const Common::KeyCode JOY_UP = FIRST_JOY; // PS d-pad when analog is disabled. left stick when enabled
95const Common::KeyCode JOY_DOWN = (Common::KeyCode)(FIRST_JOY + 1);
96const Common::KeyCode JOY_LEFT = (Common::KeyCode)(FIRST_JOY + 2);
97const Common::KeyCode JOY_RIGHT = (Common::KeyCode)(FIRST_JOY + 3);
98const Common::KeyCode JOY_RIGHTUP = (Common::KeyCode)(FIRST_JOY + 4);
99const Common::KeyCode JOY_RIGHTDOWN = (Common::KeyCode)(FIRST_JOY + 5);
100const Common::KeyCode JOY_LEFTUP = (Common::KeyCode)(FIRST_JOY + 6);
101const Common::KeyCode JOY_LEFTDOWN = (Common::KeyCode)(FIRST_JOY + 7);
102const Common::KeyCode JOY_UP2 = (Common::KeyCode)(FIRST_JOY + 8); // PS right stick when analog is enabled
103const Common::KeyCode JOY_DOWN2 = (Common::KeyCode)(FIRST_JOY + 9);
104const Common::KeyCode JOY_LEFT2 = (Common::KeyCode)(FIRST_JOY + 10);
105const Common::KeyCode JOY_RIGHT2 = (Common::KeyCode)(FIRST_JOY + 11);
106const Common::KeyCode JOY_RIGHTUP2 = (Common::KeyCode)(FIRST_JOY + 12);
107const Common::KeyCode JOY_RIGHTDOWN2 = (Common::KeyCode)(FIRST_JOY + 13);
108const Common::KeyCode JOY_LEFTUP2 = (Common::KeyCode)(FIRST_JOY + 14);
109const Common::KeyCode JOY_LEFTDOWN2 = (Common::KeyCode)(FIRST_JOY + 15);
110const Common::KeyCode JOY_UP3 = (Common::KeyCode)(FIRST_JOY + 16);
111const Common::KeyCode JOY_DOWN3 = (Common::KeyCode)(FIRST_JOY + 17);
112const Common::KeyCode JOY_LEFT3 = (Common::KeyCode)(FIRST_JOY + 18);
113const Common::KeyCode JOY_RIGHT3 = (Common::KeyCode)(FIRST_JOY + 19);
114const Common::KeyCode JOY_RIGHTUP3 = (Common::KeyCode)(FIRST_JOY + 20);
115const Common::KeyCode JOY_RIGHTDOWN3 = (Common::KeyCode)(FIRST_JOY + 21);
116const Common::KeyCode JOY_LEFTUP3 = (Common::KeyCode)(FIRST_JOY + 22);
117const Common::KeyCode JOY_LEFTDOWN3 = (Common::KeyCode)(FIRST_JOY + 23);
118const Common::KeyCode JOY_UP4 = (Common::KeyCode)(FIRST_JOY + 24);
119const Common::KeyCode JOY_DOWN4 = (Common::KeyCode)(FIRST_JOY + 25);
120const Common::KeyCode JOY_LEFT4 = (Common::KeyCode)(FIRST_JOY + 26);
121const Common::KeyCode JOY_RIGHT4 = (Common::KeyCode)(FIRST_JOY + 27);
122const Common::KeyCode JOY_RIGHTUP4 = (Common::KeyCode)(FIRST_JOY + 28);
123const Common::KeyCode JOY_RIGHTDOWN4 = (Common::KeyCode)(FIRST_JOY + 29);
124const Common::KeyCode JOY_LEFTUP4 = (Common::KeyCode)(FIRST_JOY + 30);
125const Common::KeyCode JOY_LEFTDOWN4 = (Common::KeyCode)(FIRST_JOY + 31);
126const Common::KeyCode JOY_HAT_UP = (Common::KeyCode)(FIRST_JOY + 32); // PS d-pad when analog is enabled
127const Common::KeyCode JOY_HAT_DOWN = (Common::KeyCode)(FIRST_JOY + 33);
128const Common::KeyCode JOY_HAT_LEFT = (Common::KeyCode)(FIRST_JOY + 34);
129const Common::KeyCode JOY_HAT_RIGHT = (Common::KeyCode)(FIRST_JOY + 35);
130const Common::KeyCode JOY_HAT_RIGHTUP = (Common::KeyCode)(FIRST_JOY + 36);
131const Common::KeyCode JOY_HAT_RIGHTDOWN = (Common::KeyCode)(FIRST_JOY + 37);
132const Common::KeyCode JOY_HAT_LEFTUP = (Common::KeyCode)(FIRST_JOY + 38);
133const Common::KeyCode JOY_HAT_LEFTDOWN = (Common::KeyCode)(FIRST_JOY + 39);
134const Common::KeyCode JOY0 = (Common::KeyCode)(FIRST_JOY + 40); // PS triangle
135const Common::KeyCode JOY1 = (Common::KeyCode)(FIRST_JOY + 41); // PS circle
136const Common::KeyCode JOY2 = (Common::KeyCode)(FIRST_JOY + 42); // PS x
137const Common::KeyCode JOY3 = (Common::KeyCode)(FIRST_JOY + 43); // PS square
138const Common::KeyCode JOY4 = (Common::KeyCode)(FIRST_JOY + 44); // PS L2
139const Common::KeyCode JOY5 = (Common::KeyCode)(FIRST_JOY + 45); // PS R2
140const Common::KeyCode JOY6 = (Common::KeyCode)(FIRST_JOY + 46); // PS L1
141const Common::KeyCode JOY7 = (Common::KeyCode)(FIRST_JOY + 47); // PS R1
142const Common::KeyCode JOY8 = (Common::KeyCode)(FIRST_JOY + 48); // PS select
143const Common::KeyCode JOY9 = (Common::KeyCode)(FIRST_JOY + 49); // PS start
144const Common::KeyCode JOY10 = (Common::KeyCode)(FIRST_JOY + 50); // PS L3 (analog must be enabled)
145const Common::KeyCode JOY11 = (Common::KeyCode)(FIRST_JOY + 51); // PS R3 (analog must be enabled)
146const Common::KeyCode JOY12 = (Common::KeyCode)(FIRST_JOY + 52);
147const Common::KeyCode JOY13 = (Common::KeyCode)(FIRST_JOY + 53);
148const Common::KeyCode JOY14 = (Common::KeyCode)(FIRST_JOY + 54);
149const Common::KeyCode JOY15 = (Common::KeyCode)(FIRST_JOY + 55);
150const Common::KeyCode JOY16 = (Common::KeyCode)(FIRST_JOY + 56);
151const Common::KeyCode JOY17 = (Common::KeyCode)(FIRST_JOY + 57);
152const Common::KeyCode JOY18 = (Common::KeyCode)(FIRST_JOY + 58);
153const Common::KeyCode JOY19 = (Common::KeyCode)(FIRST_JOY + 59);
154
155
157 uint8 type; // 0=loc,1=key,2=str,3=obj,4=actor
158// union
159// {
160 Common::KeyCode key; // last key entered, if capturing input
161 ActionKeyType action_key_type; // last ActionKeyType entered if capturing input
162 MapCoord *loc; // target location, or direction if relative ???
163 Common::String *str; // ???
164// };
165 void set_loc(const MapCoord &c);
166 EventInput_s() : loc(0), str(0), obj(0), actor(0), get_direction(false), get_text(false),
167 target_init(0), select_from_inventory(false), select_range(0), key(Common::KEYCODE_INVALID),
168 action_key_type(ActionKeyType::CANCEL_ACTION_KEY), spell_num(0), type(0) {
169 }
171
172 Obj *obj; // top object at loc (or object from inventory)
173 Actor *actor; // actor at loc
174 bool get_direction; // if true, entering directions selects a target
175 bool get_text; // if true, the MsgScroll is polled for text input
176 MapCoord *target_init; // where MapWindow cursor is centered when targeting
177 bool select_from_inventory; // if true, objects from inventory will be selected (and not from the map)
178 uint8 select_range; // limits movement of MapWindow cursor from center
179 sint16 spell_num;
180};
181typedef struct EventInput_s EventInput;
182
183class Events : public CallBack {
184 friend class Magic; // FIXME
185private:
186 const Configuration *config;
187 GUI *gui;
188 Game *game;
189 ObjManager *obj_manager;
190 MapWindow *map_window;
191 MsgScroll *scroll;
192 GameClock *clock;
193 Player *player;
194 Converse *converse;
195 ViewManager *view_manager;
196 UseCode *usecode;
197 Magic *magic;
198 KeyBinder *keybinder;
199 GUI_Dialog *gamemenu_dialog;
200 GUI_Dialog *assetviewer_dialog;
201
202 Common::Event event;
203 EventMode mode, last_mode;
204 EventInput input; // collected/received input (of any type)
205// Common::Array<EventMode> mode_stack; // current mode is at the end of the list
206 int ts; //timestamp for TimeLeft() method.
207 int altCodeVal;
208 uint16 active_alt_code; // alt-code that needs more input
209 uint8 alt_code_input_num; // alt-code can get multiple inputs
210
211 TimeQueue *time_queue, *game_time_queue;
212 Obj *drop_obj;
213 uint16 drop_qty;
214 sint32 drop_x, drop_y; // only to allow pre-targeting from MapWindow, feel free to ignore this
215 uint8 rest_time; // How many hours?
216 uint8 rest_guard; // Who will guard?
217 Obj *push_obj;
218 Actor *push_actor;
219
220 bool drop_from_key;
221 bool showingDialog;
222 bool showingQuitDialog;
223 bool ignore_timeleft; // do not wait for NUVIE_INTERVAL
224 bool move_in_inventory;
225 bool in_control_cheat;
226 bool looking_at_spellbook;
227 bool direction_selects_target;
228 bool _keymapperStateBeforeKEYINPUT;
229
230 uint32 fps_timestamp;
231 uint16 fps_counter;
232 FpsCounter *fps_counter_widget;
233 ScriptThread *scriptThread;
234
235 Common::Point _mousePos;
236 uint8 _buttonsDown;
237
238 static Events *g_events;
239protected:
240 inline uint32 TimeLeft();
241
242 uint16 callback(uint16 msg, CallBack *caller, void *data = nullptr) override;
243 bool handleSDL_KEYDOWN(const Common::Event *event);
244 const char *print_mode(EventMode mode);
245 void try_next_attack();
246
247public:
248 enum MouseButton {
249 BUTTON_NONE = 0,
250 BUTTON_LEFT = 1,
251 BUTTON_RIGHT = 2,
252 BUTTON_MIDDLE = 3,
253 MOUSE_LAST
254 };
255
256 Events(const Configuration *cfg);
257 ~Events() override;
258
259 void clear();
260
261 bool init(ObjManager *om, MapWindow *mw, MsgScroll *ms, Player *p, Magic *mg,
262 GameClock *gc, ViewManager *vm, UseCode *uc, GUI *g, KeyBinder *kb);
263 GUI_Dialog *get_gamemenu_dialog() {
264 return gamemenu_dialog;
265 }
266 TimeQueue *get_time_queue() {
267 return time_queue;
268 }
269 TimeQueue *get_game_time_queue() {
270 return game_time_queue;
271 }
272 EventMode get_mode() const {
273 return mode;
274 }
275 EventMode get_last_mode() const {
276 return last_mode;
277 }
278 void set_mode(EventMode new_mode);
279
280 bool is_direction_selecting_targets() const {
281 return direction_selects_target;
282 }
283 void set_direction_selects_target(bool val) {
284 direction_selects_target = val;
285 }
286
291 return _mousePos;
292 }
293
297 byte getButtonState() const {
298 return _buttonsDown;
299 }
300
301 bool using_pickpocket_cheat;
302 bool cursor_mode;
303 void update_timers();
304 bool update();
305 static MouseButton whichButton(Common::EventType type);
306 bool pollEvent(Common::Event &event);
307 bool handleEvent(const Common::Event *event);
308 void request_input(CallBack *caller, void *user_data = nullptr);
309 void target_spell();
310 void close_spellbook();
311// Prompt for input.
312// obsolete:
313// void useselect_mode(Obj *src, const char *prompt = nullptr); // deprecated
314// void freeselect_mode(Obj *src, const char *prompt = nullptr); // deprecated
315 void get_scroll_input(const char *allowed = nullptr, bool can_escape = true, bool using_target_cursor = false, bool set_numbers_only_to_true = true);
316 void get_inventory_obj(Actor *actor, bool getting_target = true);
317 void get_spell_num(Actor *caster, Obj *spell_container);
318// void get_amount();
319 void get_direction(const char *prompt);
320 void get_direction(const MapCoord &from, const char *prompt);
321 void get_target(const char *prompt);
322 void get_target(const MapCoord &init, const char *prompt);
323// void get_obj_from_inventory(Actor *actor, const char *prompt);
324 void display_portrait(Actor *actor, const char *name = nullptr);
325// Start a new action, setting a new mode and prompting for input.
326 bool newAction(EventMode new_mode);
327// void doAction(sint16 rel_x = 0, sint16 rel_y = 0);
328// void doAction(Obj *obj);
329 void doAction();
330 void cancelAction();
331 void endAction(bool prompt = false);
332// Send input back to Events, performing an action for the current mode.
333 bool select_obj(Obj *obj, Actor *actor = nullptr);
334 bool select_view_obj(Obj *obj, Actor *actor);
335 bool select_actor(Actor *actor);
336 bool select_direction(sint16 rel_x, sint16 rel_y);
337 bool select_target(uint16 x, uint16 y, uint8 z = 0);
338 bool select_party_member(uint8 num);
339 bool select_spell_num(sint16 spell_num);
340// bool select_obj(Obj *obj = nullptr, Actor *actor = nullptr);
341// bool select_obj(sint16 rel_x, sint16 rel_y);
342// There is no "select_text", as Events polls MsgScroll for new input.
343// Similarly, a "select_key" is unnecessary. The following method
344// starts sending all keyboard input to 'caller'. (with the CB_DATA_READY message)
345 void key_redirect(CallBack *caller, void *user_data);
346 void cancel_key_redirect();
347
348 /* These will be replaced in the future with an InputAction class. */
349 bool move(sint16 rel_x, sint16 rel_y);
350
351 bool use_start();
352 bool use(sint16 rel_x, sint16 rel_y);
353 bool use(const MapCoord &coord);
354 bool use(Obj *obj);
355 bool use(Actor *actor, uint16 x, uint16 y);
356
357 bool get_start();
358 bool get(const MapCoord &coord);
359 bool get(sint16 rel_x, sint16 rel_y);
360 bool perform_get(Obj *obj, Obj *container_obj = nullptr, Actor *actor = nullptr);
361
362 bool look_start();
363 bool lookAtCursor(bool delayed = false, uint16 x = 0, uint16 y = 0, uint8 z = 0, Obj *obj = nullptr, Actor *actor = nullptr);
364 bool look(Obj *obj);
365 bool look(Actor *actor);
366 bool search(Obj *obj);
367
368 bool talk_start();
369 bool talk_cursor();
370 bool talk(Actor *actor);
371 bool talk(Obj *obj);
372 bool perform_talk(Actor *actor);
373
374 bool attack();
375
376 bool push_start();
377 bool pushFrom(Obj *obj);
378 bool pushFrom(sint16 rel_x, sint16 rel_y);
379 bool pushFrom(const MapCoord &target);
380 bool pushTo(Obj *obj, Actor *actor);
381 bool pushTo(sint16 rel_x, sint16 rel_y, bool push_from = PUSH_FROM_PLAYER);
382
383 void solo_mode(uint32 actor_num);
384 bool party_mode();
385 bool toggle_combat();
386
387 bool ready(Obj *obj, Actor *actor = nullptr);
388 bool unready(Obj *obj);
389
390 bool drop_start();
391 bool drop_select(Obj *obj, uint16 qty = 0);
392 bool drop_count(uint16 qty);
393 bool perform_drop();
394 void set_drop_from_key(bool closing_gumps) {
395 drop_from_key = closing_gumps;
396 }
397 bool drop(Obj *obj, uint16 qty, uint16 x, uint16 y);
398 bool drop(uint16 x, uint16 y) {
399 return (drop(drop_obj, drop_qty, x, y));
400 }
401 void set_drop_target(uint16 x, uint16 y) {
402 drop_x = sint32(x);
403 drop_y = sint32(y);
404 }
405 bool can_move_obj_between_actors(Obj *obj, Actor *src_actor, Actor *target_actor, bool display_name = false);
406 void display_not_aboard_vehicle(bool show_prompt = true);
407 void display_move_text(Actor *target_actor, Obj *obj);
408 bool can_get_to_actor(const Actor *actor, uint16 x, uint16 y);
409 bool using_control_cheat() const {
410 return in_control_cheat;
411 }
412 void set_control_cheat(bool control_cheat) {
413 in_control_cheat = control_cheat;
414 }
415 bool is_looking_at_spellbook() const {
416 return looking_at_spellbook;
417 }
418 void set_looking_at_spellbook(bool looking) {
419 looking_at_spellbook = looking;
420 }
421
422 bool rest();
423 bool rest_input(uint16 input);
424
425 void cast_spell_directly(uint8 spell_num);
426 bool can_target_icon(); // Target the actor or container tile in inventory and party view
427
428// these are both for mouse-using convenience
429 void walk_to_mouse_cursor(uint32 mx, uint32 my);
430 void multiuse(uint16 wx, uint16 wy);
431
432 void alt_code(int c);
433 void alt_code_input(const char *in);
434 void clear_alt_code() { altCodeVal = 0; }
435
436 void toggleAltCodeMode(bool enable);
437 void appendAltCode(int code);
438
439 bool alt_code_teleport(const char *location_string);
440 void alt_code_infostring();
441 void alt_code_teleport_menu(uint32 selection);
442 bool alt_code_teleport_to_person(uint32 npc);
443
444 void wait();
445 void set_ignore_timeleft(bool newsetting) {
446 ignore_timeleft = newsetting;
447 }
448 EventInput *get_input() {
449 return &input;
450 }
451// These cursor methods are use to make sure Events knows where the cursor is
452// when objects are selected with ENTER. (since MapWindow and InventoryView
453// may each independently show/hide their own cursors)
454 void moveCursorToMapWindow(bool ToggleCursor = false);
455 void moveCursorToInventory();
456
457 void toggleFpsDisplay();
458 void close_gumps();
459 bool do_not_show_target_cursor;
460 bool dont_show_target_cursor() const;
461 bool input_really_needs_directon() const;
462 void quitDialog();
463 void gameMenuDialog();
464 void assetViewer();
465 bool actor_exists(const Actor *a) const;
466
467 /* FIXME: Some of the above (action) functions can be removed from public, so
468 that we don't need to check for WAIT mode in all of them. */
469
473 static Events *get() { return g_events; }
474};
475
476extern bool shouldQuit();
477
478} // End of namespace Nuvie
479} // End of namespace Ultima
480
481#endif
Definition: str.h:59
Definition: actor.h:174
Definition: call_back.h:50
Definition: configuration.h:60
Definition: converse.h:78
Definition: events.h:183
Common::Point getMousePos() const
Definition: events.h:290
static Events * get()
Definition: events.h:473
byte getButtonState() const
Definition: events.h:297
Definition: fps_counter.h:33
Definition: gui_dialog.h:36
Definition: gui.h:42
Definition: game_clock.h:45
Definition: game.h:72
Definition: keys.h:59
Definition: magic.h:79
Definition: map.h:84
Definition: map_window.h:70
Definition: msg_scroll.h:90
Definition: obj.h:84
Definition: obj_manager.h:74
Definition: player.h:41
Definition: script.h:58
Definition: timed_event.h:45
Definition: usecode.h:151
Definition: view_manager.h:55
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
EventType
Definition: events.h:49
MouseButton
Definition: events.h:202
Definition: events.h:218
Definition: rect.h:144
Definition: events.h:156