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 /*
24 * Based on the Reverse Engineering work of Christophe Fontanel,
25 * maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/)
26 */
27
28 #include "common/system.h"
29 #include "graphics/cursorman.h"
30 #include "graphics/thumbnail.h"
31
32 #include "dm/eventman.h"
33 #include "dm/dungeonman.h"
34 #include "dm/movesens.h"
35 #include "dm/objectman.h"
36 #include "dm/inventory.h"
37 #include "dm/menus.h"
38 #include "dm/timeline.h"
39 #include "dm/projexpl.h"
40 #include "dm/text.h"
41 #include "dm/group.h"
42 #include "dm/dialog.h"
43 #include "dm/sounds.h"
44
45
46 namespace DM {
47
initArrays()48 void EventManager::initArrays() {
49 KeyboardInput primaryKeyboardInputInterface[7] = { // @ G0458_as_Graphic561_PrimaryKeyboardInput_Interface
50 /* { Command, Code } */
51 KeyboardInput(kDMCommandToggleInventoryChampion0, Common::KEYCODE_F1, 0), /* F1 (<CSI>1~) Atari ST: Code = 0x3B00 */
52 KeyboardInput(kDMCommandToggleInventoryChampion1, Common::KEYCODE_F2, 0), /* F2 (<CSI>2~) Atari ST: Code = 0x3C00 */
53 KeyboardInput(kDMCommandToggleInventoryChampion2, Common::KEYCODE_F3, 0), /* F3 (<CSI>3~) Atari ST: Code = 0x3D00 */
54 KeyboardInput(kDMCommandToggleInventoryChampion3, Common::KEYCODE_F4, 0), /* F4 (<CSI>4~) Atari ST: Code = 0x3E00 */
55 KeyboardInput(kDMCommandSaveGame, Common::KEYCODE_s, Common::KBD_CTRL), /* CTRL-S Atari ST: Code = 0x0013 */
56 KeyboardInput(kDMCommandFreezeGame, Common::KEYCODE_ESCAPE, 0), /* Esc (0x1B) Atari ST: Code = 0x001B */
57 KeyboardInput(kDMCommandNone, Common::KEYCODE_INVALID, 0)
58 };
59
60 KeyboardInput secondaryKeyboardInputMovement[19] = { // @ G0459_as_Graphic561_SecondaryKeyboardInput_Movement
61 /* { Command, Code } */
62 KeyboardInput(kDMCommandTurnLeft, Common::KEYCODE_KP4, 0), /* Numeric pad 4 Atari ST: Code = 0x5200 */
63 KeyboardInput(kDMCommandMoveForward, Common::KEYCODE_KP5, 0), /* Numeric pad 5 Atari ST: Code = 0x4800 */
64 KeyboardInput(kDMCommandTurnRight, Common::KEYCODE_KP6, 0), /* Numeric pad 6 Atari ST: Code = 0x4700 */
65 KeyboardInput(kDMCommandMoveLeft, Common::KEYCODE_KP1, 0), /* Numeric pad 1 Atari ST: Code = 0x4B00 */
66 KeyboardInput(kDMCommandMoveBackward, Common::KEYCODE_KP2, 0), /* Numeric pad 2 Atari ST: Code = 0x5000 */
67 KeyboardInput(kDMCommandMoveRight, Common::KEYCODE_KP3, 0), /* Numeric pad 3 Atari ST: Code = 0x4D00. Remaining entries below not present */
68 KeyboardInput(kDMCommandMoveForward, Common::KEYCODE_w, 0), /* Up Arrow (<CSI>A) */ /*Differs for testing convenience*/
69 KeyboardInput(kDMCommandMoveForward, Common::KEYCODE_w, Common::KBD_SHIFT), /* Shift Up Arrow (<CSI>T) */ /*Differs for testing convenience*/
70 KeyboardInput(kDMCommandMoveLeft, Common::KEYCODE_a, 0), /* Backward Arrow (<CSI>D) */ /*Differs for testing convenience*/
71 KeyboardInput(kDMCommandMoveLeft, Common::KEYCODE_a, Common::KBD_SHIFT), /* Shift Forward Arrow (<CSI> A) */ /*Differs for testing convenience*/
72 KeyboardInput(kDMCommandMoveRight, Common::KEYCODE_d, 0), /* Forward Arrow (<CSI>C) */ /*Differs for testing convenience*/
73 KeyboardInput(kDMCommandMoveRight, Common::KEYCODE_d, Common::KBD_SHIFT), /* Shift Backward Arrow (<CSI> @) */ /*Differs for testing convenience*/
74 KeyboardInput(kDMCommandMoveBackward, Common::KEYCODE_s, 0), /* Down arrow (<CSI>B) */ /*Differs for testing convenience*/
75 KeyboardInput(kDMCommandMoveBackward, Common::KEYCODE_s, Common::KBD_SHIFT), /* Shift Down arrow (<CSI>S) */ /*Differs for testing convenience*/
76 KeyboardInput(kDMCommandTurnLeft, Common::KEYCODE_q, 0), /* Del (0x7F) */ /*Differs for testing convenience*/
77 KeyboardInput(kDMCommandTurnLeft, Common::KEYCODE_q, Common::KBD_SHIFT), /* Shift Del (0x7F) */ /*Differs for testing convenience*/
78 KeyboardInput(kDMCommandTurnRight, Common::KEYCODE_e, 0), /* Help (<CSI>?~) */ /*Differs for testing convenience*/
79 KeyboardInput(kDMCommandTurnRight, Common::KEYCODE_e, Common::KBD_SHIFT), /* Shift Help (<CSI>?~) */ /*Differs for testing convenience*/
80 KeyboardInput(kDMCommandNone, Common::KEYCODE_INVALID, 0)
81 };
82 KeyboardInput primaryKeyboardInputPartySleeping[3] = { // @ G0460_as_Graphic561_PrimaryKeyboardInput_PartySleeping
83 /* { Command, Code } */
84 KeyboardInput(kDMCommandWakeUp, Common::KEYCODE_RETURN, 0), /* Return */
85 KeyboardInput(kDMCommandFreezeGame, Common::KEYCODE_ESCAPE, 0), /* Esc */
86 KeyboardInput(kDMCommandNone, Common::KEYCODE_INVALID, 0)
87 };
88 KeyboardInput primaryKeyboardInputFrozenGame[2] = { // @ G0461_as_Graphic561_PrimaryKeyboardInput_FrozenGame
89 /* { Command, Code } */
90 KeyboardInput(kDMCommandUnfreezeGame, Common::KEYCODE_ESCAPE, 0), /* Esc */
91 KeyboardInput(kDMCommandNone, Common::KEYCODE_INVALID, 0)
92 };
93 MouseInput primaryMouseInputEntrance[4] = { // @ G0445_as_Graphic561_PrimaryMouseInput_Entrance[4]
94 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
95 MouseInput(kDMCommandEntranceEnterDungeon, 244, 298, 45, 58, kDMMouseButtonLeft),
96 // Strangerke - C201_COMMAND_ENTRANCE_RESUME isn't present in the demo
97 MouseInput(kDMCommandEntranceResume, 244, 298, 76, 93, kDMMouseButtonLeft),
98 MouseInput(kDMCommandEntranceDrawCredits, 248, 293, 187, 199, kDMMouseButtonLeft),
99 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
100 };
101 MouseInput primaryMouseInputRestartGame[2] = { // @ G0446_as_Graphic561_PrimaryMouseInput_RestartGame[2]
102 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
103 MouseInput(kDMCommandRestartGame, 103, 217, 145, 159, kDMMouseButtonLeft),
104 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
105 };
106 MouseInput primaryMouseInputInterface[20] = { // @ G0447_as_Graphic561_PrimaryMouseInput_Interface[20]
107 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
108 MouseInput(kDMCommandClickInChampion0StatusBox, 0, 42, 0, 28, kDMMouseButtonLeft),
109 MouseInput(kDMCommandClickInChampion1StatusBox, 69, 111, 0, 28, kDMMouseButtonLeft),
110 MouseInput(kDMCommandClickInChampion2StatusBox, 138, 180, 0, 28, kDMMouseButtonLeft),
111 MouseInput(kDMCommandClickInChampion3StatusBox, 207, 249, 0, 28, kDMMouseButtonLeft),
112 MouseInput(kDMCommandClickOnChamptionIconTopLeft, 274, 299, 0, 13, kDMMouseButtonLeft),
113 MouseInput(kDMCommandClickOnChamptionIconTopRight, 301, 319, 0, 13, kDMMouseButtonLeft),
114 MouseInput(kDMCommandClickOnChamptionIconLowerRight, 301, 319, 15, 28, kDMMouseButtonLeft),
115 MouseInput(kDMCommandClickOnChamptionIconLowerLeft, 274, 299, 15, 28, kDMMouseButtonLeft),
116 MouseInput(kDMCommandToggleInventoryChampion0, 43, 66, 0, 28, kDMMouseButtonLeft), /* Atari ST: Only present in CSB 2.x and with Box.X1 = 44. swapped with 4 next entries */
117 MouseInput(kDMCommandToggleInventoryChampion1, 112, 135, 0, 28, kDMMouseButtonLeft), /* Atari ST: Only present in CSB 2.x and with Box.X1 = 113. swapped with 4 next entries */
118 MouseInput(kDMCommandToggleInventoryChampion2, 181, 204, 0, 28, kDMMouseButtonLeft), /* Atari ST: Only present in CSB 2.x and with Box.X1 = 182. swapped with 4 next entries */
119 MouseInput(kDMCommandToggleInventoryChampion3, 250, 273, 0, 28, kDMMouseButtonLeft), /* Atari ST: Only present in CSB 2.x and with Box.X1 = 251. swapped with 4 next entries */
120 MouseInput(kDMCommandToggleInventoryChampion0, 0, 66, 0, 28, kDMMouseButtonRight), /* Atari ST: swapped with 4 previous entries */
121 MouseInput(kDMCommandToggleInventoryChampion1, 69, 135, 0, 28, kDMMouseButtonRight), /* Atari ST: swapped with 4 previous entries */
122 MouseInput(kDMCommandToggleInventoryChampion2, 138, 204, 0, 28, kDMMouseButtonRight), /* Atari ST: swapped with 4 previous entries */
123 MouseInput(kDMCommandToggleInventoryChampion3, 207, 273, 0, 28, kDMMouseButtonRight), /* Atari ST: swapped with 4 previous entries */
124 MouseInput(kDMCommandClickInSpellArea, 233, 319, 42, 73, kDMMouseButtonLeft),
125 MouseInput(kDMCommandClickInActionArea, 233, 319, 77, 121, kDMMouseButtonLeft),
126 MouseInput(kDMCommandFreezeGame, 0, 1, 198, 199, kDMMouseButtonLeft),
127 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
128 };
129 MouseInput secondaryMouseInputMovement[9] = { // @ G0448_as_Graphic561_SecondaryMouseInput_Movement[9]
130 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
131 MouseInput(kDMCommandTurnLeft, 234, 261, 125, 145, kDMMouseButtonLeft),
132 MouseInput(kDMCommandMoveForward, 263, 289, 125, 145, kDMMouseButtonLeft),
133 MouseInput(kDMCommandTurnRight, 291, 318, 125, 145, kDMMouseButtonLeft),
134 MouseInput(kDMCommandMoveLeft, 234, 261, 147, 167, kDMMouseButtonLeft),
135 MouseInput(kDMCommandMoveBackward, 263, 289, 147, 167, kDMMouseButtonLeft),
136 MouseInput(kDMCommandMoveRight, 291, 318, 147, 167, kDMMouseButtonLeft),
137 MouseInput(kDMCommandClickInDungeonView, 0, 223, 33, 168, kDMMouseButtonLeft),
138 MouseInput(kDMCommandToggleInventoryLeader, 0, 319, 33, 199, kDMMouseButtonRight),
139 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
140 };
141 MouseInput secondaryMouseInputChampionInventory[38] = { // @ G0449_as_Graphic561_SecondaryMouseInput_ChampionInventory[38]
142 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
143 MouseInput(kDMCommandCloseInventory, 0, 319, 0, 199, kDMMouseButtonRight),
144 MouseInput(kDMCommandSaveGame, 174, 182, 36, 44, kDMMouseButtonLeft),
145 MouseInput(kDMCommandSleep, 188, 204, 36, 44, kDMMouseButtonLeft),
146 MouseInput(kDMCommandCloseInventory, 210, 218, 36, 44, kDMMouseButtonLeft),
147 MouseInput(kDMCommandClickOnSlotBoxInventoryReadyHand , 6, 21, 86, 101, kDMMouseButtonLeft),
148 MouseInput(kDMCommandClickOnSlotBoxInventoryActionHand, 62, 77, 86, 101, kDMMouseButtonLeft),
149 MouseInput(kDMCommandClickOnSlotBoxInventoryHead, 34, 49, 59, 74, kDMMouseButtonLeft),
150 MouseInput(kDMCommandClickOnSlotBoxInventoryTorso, 34, 49, 79, 94, kDMMouseButtonLeft),
151 MouseInput(kDMCommandClickOnSlotBoxInventoryLegs, 34, 49, 99, 114, kDMMouseButtonLeft),
152 MouseInput(kDMCommandClickOnSlotBoxInventoryFeet, 34, 49, 119, 134, kDMMouseButtonLeft),
153 MouseInput(kDMCommandClickOnSlotBoxInventoryPouch2, 6, 21, 123, 138, kDMMouseButtonLeft),
154 MouseInput(kDMCommandClickOnMouth, 56, 71, 46, 61, kDMMouseButtonLeft),
155 MouseInput(kDMCommandClickOnEye, 12, 27, 46, 61, kDMMouseButtonLeft),
156 MouseInput(kDMCommandClickOnSlotBoxInventoryQuiverLine2_1, 79, 94, 106, 121, kDMMouseButtonLeft),
157 MouseInput(kDMCommandClickOnSlotBoxInventoryQuiverLine1_2, 62, 77, 123, 138, kDMMouseButtonLeft),
158 MouseInput(kDMCommandClickOnSlotBoxInventoryQuiverLine2_2, 79, 94, 123, 138, kDMMouseButtonLeft),
159 MouseInput(kDMCommandClickOnSlotBoxInventoryNeck, 6, 21, 66, 81, kDMMouseButtonLeft),
160 MouseInput(kDMCommandClickOnSlotBoxInventoryPouch1, 6, 21, 106, 121, kDMMouseButtonLeft),
161 MouseInput(kDMCommandClickOnSlotBoxInventoryQuiverLine1_1, 62, 77, 106, 121, kDMMouseButtonLeft),
162 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_1, 66, 81, 66, 81, kDMMouseButtonLeft),
163 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_2, 83, 98, 49, 64, kDMMouseButtonLeft),
164 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_3, 100, 115, 49, 64, kDMMouseButtonLeft),
165 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_4, 117, 132, 49, 64, kDMMouseButtonLeft),
166 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_5, 134, 149, 49, 64, kDMMouseButtonLeft),
167 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_6, 151, 166, 49, 64, kDMMouseButtonLeft),
168 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_7, 168, 183, 49, 64, kDMMouseButtonLeft),
169 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_8, 185, 200, 49, 64, kDMMouseButtonLeft),
170 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine2_9, 202, 217, 49, 64, kDMMouseButtonLeft),
171 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_2, 83, 98, 66, 81, kDMMouseButtonLeft),
172 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_3, 100, 115, 66, 81, kDMMouseButtonLeft),
173 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_4, 117, 132, 66, 81, kDMMouseButtonLeft),
174 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_5, 134, 149, 66, 81, kDMMouseButtonLeft),
175 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_6, 151, 166, 66, 81, kDMMouseButtonLeft),
176 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_7, 168, 183, 66, 81, kDMMouseButtonLeft),
177 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_8, 185, 200, 66, 81, kDMMouseButtonLeft),
178 MouseInput(kDMCommandClickOnSlotBoxInventoryBackpackLine1_9, 202, 217, 66, 81, kDMMouseButtonLeft),
179 MouseInput(kDMCommandClickInPanel, 96, 223, 83, 167, kDMMouseButtonLeft),
180 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
181 };
182 MouseInput primaryMouseInputPartySleeping[3] = { // @ G0450_as_Graphic561_PrimaryMouseInput_PartySleeping[3]
183 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
184 MouseInput(kDMCommandWakeUp, 0, 223, 33, 168, kDMMouseButtonLeft),
185 MouseInput(kDMCommandWakeUp, 0, 223, 33, 168, kDMMouseButtonRight),
186 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
187 };
188 MouseInput primaryMouseInputFrozenGame[3] = { // @ G0451_as_Graphic561_PrimaryMouseInput_FrozenGame[3]
189 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
190 MouseInput(kDMCommandUnfreezeGame, 0, 319, 0, 199, kDMMouseButtonLeft),
191 MouseInput(kDMCommandUnfreezeGame, 0, 319, 0, 199, kDMMouseButtonRight),
192 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
193 };
194 MouseInput mouseInputActionAreaNames[5] = { // @ G0452_as_Graphic561_MouseInput_ActionAreaNames[5]
195 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
196 MouseInput(kDMCommandClickInActionAreaPass, 285, 318, 77, 83, kDMMouseButtonLeft),
197 MouseInput(kDMCommandClickInActionAreaAction0, 234, 318, 86, 96, kDMMouseButtonLeft),
198 MouseInput(kDMCommandClickInActionAreaAction1, 234, 318, 98, 108, kDMMouseButtonLeft),
199 MouseInput(kDMCommandClickInActionAreaAction2, 234, 318, 110, 120, kDMMouseButtonLeft),
200 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
201 };
202 MouseInput mouseInputActionAreaIcons[5] = { // @ G0453_as_Graphic561_MouseInput_ActionAreaIcons[5]
203 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
204 MouseInput(kDMCommandClickInActionAreaChampion0Action, 233, 252, 86, 120, kDMMouseButtonLeft),
205 MouseInput(kDMCommandClickInActionAreaChampion1Action, 255, 274, 86, 120, kDMMouseButtonLeft),
206 MouseInput(kDMCommandClickInActionAreaChampion2Action, 277, 296, 86, 120, kDMMouseButtonLeft),
207 MouseInput(kDMCommandClickInActionAreaChampion3Action, 299, 318, 86, 120, kDMMouseButtonLeft),
208 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
209 };
210 MouseInput mouseInputSpellArea[9] = { // @ G0454_as_Graphic561_MouseInput_SpellArea[9]
211 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
212 MouseInput(kDMCommandClickInSpellAreaSymbol1, 235, 247, 51, 61, kDMMouseButtonLeft),
213 MouseInput(kDMCommandClickInSpellAreaSymbol2, 249, 261, 51, 61, kDMMouseButtonLeft),
214 MouseInput(kDMCommandClickInSpellAreaSymbol3, 263, 275, 51, 61, kDMMouseButtonLeft),
215 MouseInput(kDMCommandClickInSpellAreaSymbol4, 277, 289, 51, 61, kDMMouseButtonLeft),
216 MouseInput(kDMCommandClickInSpellAreaSymbol5, 291, 303, 51, 61, kDMMouseButtonLeft),
217 MouseInput(kDMCommandClickInSpellAreaSymbol6, 305, 317, 51, 61, kDMMouseButtonLeft),
218 MouseInput(kDMCommandClickInSpeallAreaCastSpell, 234, 303, 63, 73, kDMMouseButtonLeft),
219 MouseInput(kDMCommandClickInSpellAreaRecantSymbol, 305, 318, 63, 73, kDMMouseButtonLeft),
220 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
221 };
222 MouseInput mouseInputChampionNamesHands[13] = { // @ G0455_as_Graphic561_MouseInput_ChampionNamesHands[13]
223 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
224 MouseInput(kDMCommandSetLeaderChampion0, 0, 42, 0, 6, kDMMouseButtonLeft),
225 MouseInput(kDMCommandSetLeaderChampion1, 69, 111, 0, 6, kDMMouseButtonLeft),
226 MouseInput(kDMCommandSetLeaderChampion2, 138, 180, 0, 6, kDMMouseButtonLeft),
227 MouseInput(kDMCommandSetLeaderChampion3, 207, 249, 0, 6, kDMMouseButtonLeft),
228 MouseInput(kDMCommandClickOnSlotBoxChampion0StatusBoxReadyHand, 4, 19, 10, 25, kDMMouseButtonLeft),
229 MouseInput(kDMCommandClickOnSlotBoxChampion0StatusBoxActionHand, 24, 39, 10, 25, kDMMouseButtonLeft),
230 MouseInput(kDMCommandClickOnSlotBoxChampion1StatusBoxReadyHand, 73, 88, 10, 25, kDMMouseButtonLeft),
231 MouseInput(kDMCommandClickOnSlotBoxChampion1StatusBoxActionHand, 93, 108, 10, 25, kDMMouseButtonLeft),
232 MouseInput(kDMCommandClickOnSlotBoxChampion2StatusBoxReadyHand, 142, 157, 10, 25, kDMMouseButtonLeft),
233 MouseInput(kDMCommandClickOnSlotBoxChampion2StatusBoxActionHand, 162, 177, 10, 25, kDMMouseButtonLeft),
234 MouseInput(kDMCommandClickOnSlotBoxChampion3StatusBoxReadyHand, 211, 226, 10, 25, kDMMouseButtonLeft),
235 MouseInput(kDMCommandClickOnSlotBoxChampion3StatusBoxActionHand, 231, 246, 10, 25, kDMMouseButtonLeft),
236 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
237 };
238 MouseInput mouseInputPanelChest[9] = { // @ G0456_as_Graphic561_MouseInput_PanelChest[9]
239 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
240 MouseInput(kDMCommandClickOnSlotBoxChest1, 117, 132, 92, 107, kDMMouseButtonLeft),
241 MouseInput(kDMCommandClickOnSlotBoxChest2, 106, 121, 109, 124, kDMMouseButtonLeft),
242 MouseInput(kDMCommandClickOnSlotBoxChest3, 111, 126, 126, 141, kDMMouseButtonLeft),
243 MouseInput(kDMCommandClickOnSlotBoxChest4, 128, 143, 131, 146, kDMMouseButtonLeft),
244 MouseInput(kDMCommandClickOnSlotBoxChest5, 145, 160, 134, 149, kDMMouseButtonLeft),
245 MouseInput(kDMCommandClickOnSlotBoxChest6, 162, 177, 136, 151, kDMMouseButtonLeft),
246 MouseInput(kDMCommandClickOnSlotBoxChest7, 179, 194, 137, 152, kDMMouseButtonLeft),
247 MouseInput(kDMCommandClickOnSlotBoxChest8, 196, 211, 138, 153, kDMMouseButtonLeft),
248 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
249 };
250 MouseInput mouseInputPanelResurrectReincarnateCancel[4] = { // @ G0457_as_Graphic561_MouseInput_PanelResurrectReincarnateCancel[4]
251 /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */
252 MouseInput(kDMCommandClickInPanelResurrect, 108, 158, 90, 138, kDMMouseButtonLeft), /* Atari ST: Box = 104, 158, 86, 142 */
253 MouseInput(kDMCommandClickInPanelReincarnate, 161, 211, 90, 138, kDMMouseButtonLeft), /* Atari ST: Box = 163, 217, 86, 142 */
254 MouseInput(kDMCommandClickInPanelCancel, 108, 211, 141, 153, kDMMouseButtonLeft), /* Atari ST: Box = 104, 217, 146, 156 */
255 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
256 };
257 MouseInput primaryMouseInputViewportDialog1Choice[2] = { // @ G0471_as_Graphic561_PrimaryMouseInput_ViewportDialog1Choice[2]
258 MouseInput(kDMCommandClickOnDialogChoice1, 16, 207, 138, 152, kDMMouseButtonLeft), /* Bottom button */
259 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
260 };
261 MouseInput primaryMouseInputViewportDialog2Choices[3] = { // @ G0472_as_Graphic561_PrimaryMouseInput_ViewportDialog2Choices[3]
262 MouseInput(kDMCommandClickOnDialogChoice1, 16, 207, 101, 115, kDMMouseButtonLeft), /* Top button */
263 MouseInput(kDMCommandClickOnDialogChoice2, 16, 207, 138, 152, kDMMouseButtonLeft), /* Bottom button */
264 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
265 };
266 MouseInput primaryMouseInputViewportDialog3Choices[4] = { // @ G0473_as_Graphic561_PrimaryMouseInput_ViewportDialog3Choices[4]
267 MouseInput(kDMCommandClickOnDialogChoice1, 16, 207, 101, 115, kDMMouseButtonLeft), /* Top button */
268 MouseInput(kDMCommandClickOnDialogChoice2, 16, 101, 138, 152, kDMMouseButtonLeft), /* Lower left button */
269 MouseInput(kDMCommandClickOnDialogChoice3, 123, 207, 138, 152, kDMMouseButtonLeft), /* Lower right button */
270 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
271 };
272 MouseInput primaryMouseInputViewportDialog4Choices[5] = { // @ G0474_as_Graphic561_PrimaryMouseInput_ViewportDialog4Choices[5]
273 MouseInput(kDMCommandClickOnDialogChoice1, 16, 101, 101, 115, kDMMouseButtonLeft), /* Top left button */
274 MouseInput(kDMCommandClickOnDialogChoice2, 123, 207, 101, 115, kDMMouseButtonLeft), /* Top right button */
275 MouseInput(kDMCommandClickOnDialogChoice3, 16, 101, 138, 152, kDMMouseButtonLeft), /* Lower left button */
276 MouseInput(kDMCommandClickOnDialogChoice4, 123, 207, 138, 152, kDMMouseButtonLeft), /* Lower right button */
277 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
278 };
279 MouseInput primaryMouseInputScreenDialog1Choice[2] = { // @ G0475_as_Graphic561_PrimaryMouseInput_ScreenDialog1Choice[2]
280 MouseInput(kDMCommandClickOnDialogChoice1, 63, 254, 138, 152, kDMMouseButtonLeft), /* Bottom button */
281 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
282 };
283 MouseInput primaryMouseInputScreenDialog2Choices[3] = { // @ G0476_as_Graphic561_PrimaryMouseInput_ScreenDialog2Choices[3]
284 MouseInput(kDMCommandClickOnDialogChoice1, 63, 254, 101, 115, kDMMouseButtonLeft), /* Top button */
285 MouseInput(kDMCommandClickOnDialogChoice2, 63, 254, 138, 152, kDMMouseButtonLeft), /* Bottom button */
286 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
287 };
288 MouseInput primaryMouseInputScreenDialog3Choices[4] = { // @ G0477_as_Graphic561_PrimaryMouseInput_ScreenDialog3Choices[4]
289 MouseInput(kDMCommandClickOnDialogChoice1, 63, 254, 101, 115, kDMMouseButtonLeft), /* Top button */
290 MouseInput(kDMCommandClickOnDialogChoice2, 63, 148, 138, 152, kDMMouseButtonLeft), /* Lower left button */
291 MouseInput(kDMCommandClickOnDialogChoice3, 170, 254, 138, 152, kDMMouseButtonLeft), /* Lower right button */
292 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
293 };
294 MouseInput primaryMouseInputScreenDialog4Choices[5] = { // @ G0478_as_Graphic561_PrimaryMouseInput_ScreenDialog4Choices[5]
295 MouseInput(kDMCommandClickOnDialogChoice1, 63, 148, 101, 115, kDMMouseButtonLeft), /* Top left button */
296 MouseInput(kDMCommandClickOnDialogChoice2, 170, 254, 101, 115, kDMMouseButtonLeft), /* Top right button */
297 MouseInput(kDMCommandClickOnDialogChoice3, 63, 148, 138, 152, kDMMouseButtonLeft), /* Lower left button */
298 MouseInput(kDMCommandClickOnDialogChoice4, 170, 254, 138, 152, kDMMouseButtonLeft), /* Lower right button */
299 MouseInput(kDMCommandNone, 0, 0, 0, 0, kDMMouseButtonNone)
300 };
301
302 MouseInput *primaryMouseInputDialogSets[2][4] = { // @ G0480_aaps_PrimaryMouseInput_DialogSets
303 {
304 _primaryMouseInputViewportDialog1Choice,
305 _primaryMouseInputViewportDialog2Choices,
306 _primaryMouseInputViewportDialog3Choices,
307 _primaryMouseInputViewportDialog4Choices
308 },
309 {
310 _primaryMouseInputScreenDialog1Choice,
311 _primaryMouseInputScreenDialog2Choices,
312 _primaryMouseInputScreenDialog3Choices,
313 _primaryMouseInputScreenDialog4Choices
314 }
315 };
316
317 for (int i = 0; i < 2; i++) {
318 _primaryKeyboardInputFrozenGame[i] = primaryKeyboardInputFrozenGame[i];
319 _primaryMouseInputRestartGame[i] = primaryMouseInputRestartGame[i];
320 _primaryMouseInputViewportDialog1Choice[i] = primaryMouseInputViewportDialog1Choice[i];
321 _primaryMouseInputScreenDialog1Choice[i] = primaryMouseInputScreenDialog1Choice[i];
322 for (int j = 0; j < 4; j++)
323 _primaryMouseInputDialogSets[i][j] = primaryMouseInputDialogSets[i][j];
324 }
325
326 for (int i = 0; i < 3 ; i++) {
327 _primaryKeyboardInputPartySleeping[i] = primaryKeyboardInputPartySleeping[i];
328 _primaryMouseInputPartySleeping[i] = primaryMouseInputPartySleeping[i];
329 _primaryMouseInputFrozenGame[i] = primaryMouseInputFrozenGame[i];
330 _primaryMouseInputViewportDialog2Choices[i] = primaryMouseInputViewportDialog2Choices[i];
331 _primaryMouseInputScreenDialog2Choices[i] = primaryMouseInputScreenDialog2Choices[i];
332 }
333
334 for (int i = 0; i < 4; i++) {
335 _primaryMouseInputEntrance[i] = primaryMouseInputEntrance[i];
336 _mouseInputPanelResurrectReincarnateCancel[i] = mouseInputPanelResurrectReincarnateCancel[i];
337 _primaryMouseInputViewportDialog3Choices[i] = primaryMouseInputViewportDialog3Choices[i];
338 _primaryMouseInputScreenDialog3Choices[i] = primaryMouseInputScreenDialog3Choices[i];
339 }
340
341 for (int i = 0; i < 5; i++) {
342 _mouseInputActionAreaNames[i] = mouseInputActionAreaNames[i];
343 _mouseInputActionAreaIcons[i] = mouseInputActionAreaIcons[i];
344 _primaryMouseInputViewportDialog4Choices[i] = primaryMouseInputViewportDialog4Choices[i];
345 _primaryMouseInputScreenDialog4Choices[i] = primaryMouseInputScreenDialog4Choices[i];
346 }
347
348 for (int i = 0; i < 7; i++)
349 _primaryKeyboardInputInterface[i] = primaryKeyboardInputInterface[i];
350
351 for (int i = 0; i < 9; i++) {
352 _secondaryMouseInputMovement[i] = secondaryMouseInputMovement[i];
353 _mouseInputSpellArea[i] = mouseInputSpellArea[i];
354 _mouseInputPanelChest[i] = mouseInputPanelChest[i];
355 }
356
357 for (int i = 0; i < 13; i++)
358 _mouseInputChampionNamesHands[i] = mouseInputChampionNamesHands[i];
359
360 for (int i = 0; i < 19; i++)
361 _secondaryKeyboardInputMovement[i] = secondaryKeyboardInputMovement[i];
362
363 for (int i = 0; i < 20; i++)
364 _primaryMouseInputInterface[i] = primaryMouseInputInterface[i];
365
366 for (int i = 0; i < 38; i++)
367 _secondaryMouseInputChampionInventory[i] = secondaryMouseInputChampionInventory[i];
368 }
EventManager(DMEngine * vm)369 EventManager::EventManager(DMEngine *vm) : _vm(vm) {
370 _mousePos = Common::Point(0, 0);
371 _dummyMapIndex = 0;
372 _pendingClickPresent = false;
373 _pendingClickPos = Common::Point(0, 0);
374 _mousePointerOriginalColorsObject = nullptr;
375 _mousePointerOriginalColorsChampionIcon = nullptr;
376 _mousePointerTempBuffer = nullptr;
377 _isCommandQueueLocked = true;
378 _mousePointerType = 0;
379 _previousMousePointerType = 0;
380 _primaryMouseInput = nullptr;
381 _secondaryMouseInput = nullptr;
382 _mousePointerBitmapUpdated = true;
383 _refreshMousePointerInMainLoop = false;
384 _highlightBoxEnabled = false;
385 _useChampionIconOrdinalAsMousePointerBitmap = 0;
386 _pendingClickButton = kDMMouseButtonNone;
387 _useObjectAsMousePointerBitmap = false;
388 _useHandAsMousePointerBitmap = false;
389 _preventBuildPointerScreenArea = false;
390 _primaryKeyboardInput = nullptr;
391 _secondaryKeyboardInput = nullptr;
392 _ignoreMouseMovements = false;
393 warning("_g587_hideMousePointerRequestCount should start with value 1");
394 _hideMousePointerRequestCount = 0;
395 _mouseButtonStatus = 0;
396 _highlightScreenBox.setToZero();
397
398 initArrays();
399 }
400
~EventManager()401 EventManager::~EventManager() {
402 delete[] _mousePointerOriginalColorsObject;
403 delete[] _mousePointerTempBuffer;
404 delete[] _mousePointerOriginalColorsChampionIcon;
405 }
406
initMouse()407 void EventManager::initMouse() {
408 static uint16 gK150_PalMousePointer[16] = {0x000, 0x666, 0x888, 0x620, 0x0CC, 0x840, 0x080, 0x0C0, 0xF00, 0xFA0, 0xC86, 0xFF0, 0x000, 0xAAA, 0x00F, 0xFFF}; // @ K0150_aui_Palette_MousePointer
409
410 if (!_mousePointerOriginalColorsObject)
411 _mousePointerOriginalColorsObject = new byte[32 * 18];
412 if (!_mousePointerTempBuffer)
413 _mousePointerTempBuffer = new byte[32 * 18];
414 if (!_mousePointerOriginalColorsChampionIcon)
415 _mousePointerOriginalColorsChampionIcon = new byte[32 * 18];
416
417 _mousePointerType = k0_pointerArrow;
418 _previousMousePointerType = k1_pointerHand;
419
420 byte mousePalette[16 * 3];
421 for (int i = 0; i < 16; ++i) {
422 mousePalette[i * 3] = (gK150_PalMousePointer[i] >> 8) * (256 / 16);
423 mousePalette[i * 3 + 1] = (gK150_PalMousePointer[i] >> 4) * (256 / 16);
424 mousePalette[i * 3 + 2] = gK150_PalMousePointer[i] * (256 / 16);
425 }
426 CursorMan.pushCursorPalette(mousePalette, 0, 16);
427
428 _mousePos = Common::Point(0, 0);
429 buildpointerScreenArea(_mousePos.x, _mousePos.y);
430 CursorMan.showMouse(false);
431
432 setMousePos(Common::Point(320 / 2, 200 / 2));
433 }
434
setMousePointerToNormal(int16 mousePointer)435 void EventManager::setMousePointerToNormal(int16 mousePointer) {
436 _preventBuildPointerScreenArea = true;
437 _useObjectAsMousePointerBitmap = false;
438 _useHandAsMousePointerBitmap = (mousePointer == k1_pointerHand);
439 _mousePointerBitmapUpdated = true;
440 _preventBuildPointerScreenArea = false;
441 buildpointerScreenArea(_mousePos.x, _mousePos.y);
442 }
443
setPointerToObject(byte * bitmap)444 void EventManager::setPointerToObject(byte *bitmap) {
445 static byte palChangesMousepointerOjbectIconShadow[16] = {120, 120, 120, 120, 120, 120, 120, 120,
446 120, 120, 120, 120, 0, 120, 120, 120}; // @ K0027_auc_PaletteChanges_MousePointerObjectIconShadow
447 static byte palChangesMousePointerIcon[16] = {120, 10, 20, 30, 40, 50, 60, 70, 80, 90,
448 100, 110, 0, 130, 140, 150}; // @ G0044_auc_Graphic562_PaletteChanges_MousePointerIcon
449 static Box boxMousePointerObjectShadow(2, 17, 2, 17); // @ G0619_s_Box_MousePointer_ObjectShadow
450 static Box boxMousePointerObject(0, 15, 0, 15); // @ G0620_s_Box_MousePointer_Object
451
452 DisplayMan &displMan = *_vm->_displayMan;
453
454 _preventBuildPointerScreenArea = true;
455 _useObjectAsMousePointerBitmap = true;
456 _useHandAsMousePointerBitmap = false;
457 _mousePointerBitmapUpdated = true;
458 displMan._useByteBoxCoordinates = true;
459 byte *L0051_puc_Bitmap = _mousePointerOriginalColorsObject;
460 memset(L0051_puc_Bitmap, 0, 32 * 18);
461
462 displMan.blitToBitmapShrinkWithPalChange(bitmap, _mousePointerTempBuffer, 16, 16, 16, 16, palChangesMousepointerOjbectIconShadow);
463 displMan.blitToBitmap(_mousePointerTempBuffer, L0051_puc_Bitmap, boxMousePointerObjectShadow, 0, 0, 8, 16, kDMColorNoTransparency, 16, 18);
464 displMan.blitToBitmapShrinkWithPalChange(bitmap, _mousePointerTempBuffer, 16, 16, 16, 16, palChangesMousePointerIcon);
465 displMan.blitToBitmap(_mousePointerTempBuffer, L0051_puc_Bitmap, boxMousePointerObject, 0, 0, 8, 16, kDMColorBlack, 16, 18);
466
467 _preventBuildPointerScreenArea = false;
468 buildpointerScreenArea(_mousePos.x, _mousePos.y);
469 }
470
mouseDropChampionIcon()471 void EventManager::mouseDropChampionIcon() {
472 DisplayMan &displMan = *_vm->_displayMan;
473
474 _preventBuildPointerScreenArea = true;
475 uint16 championIconIndex = _vm->ordinalToIndex(_useChampionIconOrdinalAsMousePointerBitmap);
476 _useChampionIconOrdinalAsMousePointerBitmap = _vm->indexToOrdinal(kDMChampionNone);
477 _mousePointerBitmapUpdated = true;
478 bool useByteBoxCoordinatesBackup = displMan._useByteBoxCoordinates;
479 displMan.blitToScreen(_mousePointerOriginalColorsChampionIcon, &_vm->_championMan->_boxChampionIcons[championIconIndex << 2], 16, kDMColorDarkestGray, 18);
480 displMan._useByteBoxCoordinates = useByteBoxCoordinatesBackup;
481 _preventBuildPointerScreenArea = false;
482 }
483
buildpointerScreenArea(int16 mousePosX,int16 mousePosY)484 void EventManager::buildpointerScreenArea(int16 mousePosX, int16 mousePosY) {
485 static unsigned char bitmapArrowPointer[288] = { // @ G0042_auc_Graphic562_Bitmap_ArrowPointer
486 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
487 0x78, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
488 0x7F, 0x80, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
489 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
491 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00,
492 0x7E, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00,
493 0x6C, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
494 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0xC0, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
496 0x84, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
497 0x80, 0x40, 0x00, 0x00, 0x83, 0xC0, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0xA9, 0x00, 0x00, 0x00,
498 0xC9, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00,
500 0xF0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00,
501 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00,
502 0xFE, 0x00, 0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0xCF, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
503 0x07, 0x80, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
504 };
505 static unsigned char bitmapHanPointer[288] = { // @ G0043_auc_Graphic562_Bitmap_HandPointer
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00,
511 0x35, 0x40, 0x00, 0x00, 0x1A, 0xA0, 0x00, 0x00, 0x0D, 0x50, 0x00, 0x00, 0x0E, 0xA8, 0x00, 0x00,
512 0x07, 0xF8, 0x00, 0x00, 0xC7, 0xFC, 0x00, 0x00, 0x67, 0xFC, 0x00, 0x00, 0x77, 0xFC, 0x00, 0x00,
513 0x3F, 0xFC, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0x00, 0x00,
514 0x01, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x20, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x4A, 0xA0, 0x00, 0x00, 0x25, 0x50, 0x00, 0x00,
516 0x12, 0xA8, 0x00, 0x00, 0x11, 0x54, 0x00, 0x00, 0xC8, 0x04, 0x00, 0x00, 0x28, 0x02, 0x00, 0x00,
517 0x98, 0x02, 0x00, 0x00, 0x88, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00,
518 0x20, 0x01, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
520 0x7F, 0xE0, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00,
521 0xCF, 0xFC, 0x00, 0x00, 0xEF, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00,
522 0x7F, 0xFE, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00,
523 0x07, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
524 };
525
526 _preventBuildPointerScreenArea = true;
527 if (_useChampionIconOrdinalAsMousePointerBitmap) {
528 if ((mousePosY > 28) || (mousePosX < 274)) {
529 _mousePointerType = k4_pointerTypeAutoselect;
530 mouseDropChampionIcon();
531 } else
532 _mousePointerType = k2_pointerTypeChampionIcon;
533 } else if (mousePosY >= 169)
534 _mousePointerType = k0_pointerTypeArrow;
535 else if (mousePosX >= 274)
536 _mousePointerType = k0_pointerTypeArrow;
537 else if (mousePosY <= 28) {
538 uint16 championIdx = mousePosX / 69;
539 uint16 xOverChampionStatusBox = mousePosX % 69;
540 if (championIdx >= _vm->_championMan->_partyChampionCount)
541 _mousePointerType = k4_pointerTypeAutoselect;
542 else if (xOverChampionStatusBox > 42)
543 _mousePointerType = k4_pointerTypeAutoselect;
544 else {
545 championIdx++;
546 if (championIdx == _vm->_inventoryMan->_inventoryChampionOrdinal)
547 _mousePointerType = k0_pointerTypeArrow;
548 else if (mousePosY <= 6)
549 _mousePointerType = k0_pointerTypeArrow;
550 else
551 _mousePointerType = k4_pointerTypeAutoselect;
552 }
553 } else if (mousePosX >= 224)
554 _mousePointerType = k0_pointerTypeArrow;
555 else
556 _mousePointerType = k4_pointerTypeAutoselect;
557
558 if (_mousePointerType == k4_pointerTypeAutoselect)
559 _mousePointerType = (_useObjectAsMousePointerBitmap) ? k1_pointerTypeObjectIcon : (_useHandAsMousePointerBitmap) ? k3_pointerTypeHand : k0_pointerTypeArrow;
560
561 if (_mousePointerBitmapUpdated || (_mousePointerType != _previousMousePointerType)) {
562 _mousePointerBitmapUpdated = false;
563 switch (_mousePointerType) {
564 case k0_pointerTypeArrow:
565 setMousePointerFromSpriteData(bitmapArrowPointer);
566 break;
567 case k1_pointerTypeObjectIcon:
568 CursorMan.replaceCursor(_mousePointerOriginalColorsObject, 32, 18, 0, 0, 0);
569 break;
570 case k2_pointerTypeChampionIcon:
571 CursorMan.replaceCursor(_mousePointerOriginalColorsChampionIcon, 32, 18, 0, 0, 0);
572 break;
573 case k3_pointerTypeHand:
574 setMousePointerFromSpriteData(bitmapHanPointer);
575 break;
576 default:
577 break;
578 }
579 }
580 _previousMousePointerType = _mousePointerType;
581 _preventBuildPointerScreenArea = false;
582 }
583
setMousePointer()584 void EventManager::setMousePointer() {
585 if (_vm->_championMan->_leaderEmptyHanded)
586 setMousePointerToNormal((_vm->_championMan->_leaderIndex == kDMChampionNone) ? k0_pointerArrow : k1_pointerHand);
587 else
588 setPointerToObject(_vm->_objectMan->_objectIconForMousePointer);
589 }
590
showMouse()591 void EventManager::showMouse() {
592 if (_hideMousePointerRequestCount++ == 0)
593 CursorMan.showMouse(true);
594 }
595
hideMouse()596 void EventManager::hideMouse() {
597 if (_hideMousePointerRequestCount-- == 1)
598 CursorMan.showMouse(false);
599 }
600
isMouseButtonDown(MouseButton button)601 bool EventManager::isMouseButtonDown(MouseButton button) {
602 return (button != kDMMouseButtonNone) ? (_mouseButtonStatus & button) : (_mouseButtonStatus == 0);
603 }
604
setMousePos(Common::Point pos)605 void EventManager::setMousePos(Common::Point pos) {
606 g_system->warpMouse(pos.x, pos.y);
607 }
608
processInput(Common::Event * grabKey,Common::Event * grabMouseClick)609 Common::EventType EventManager::processInput(Common::Event *grabKey, Common::Event *grabMouseClick) {
610 Common::Event event;
611 while (g_system->getEventManager()->pollEvent(event)) {
612 switch (event.type) {
613 case Common::EVENT_KEYDOWN: {
614 if (event.kbdRepeat)
615 break;
616
617 if (grabKey) {
618 *grabKey = event;
619 return event.type;
620 }
621
622 if (_primaryKeyboardInput) {
623 KeyboardInput *input = _primaryKeyboardInput;
624 while (input->_commandToIssue != kDMCommandNone) {
625 if ((input->_key == event.kbd.keycode) && (input->_modifiers == (event.kbd.flags & input->_modifiers))) {
626 processPendingClick(); // possible fix to BUG0_73
627 _commandQueue.push(Command(Common::Point(-1, -1), input->_commandToIssue));
628 break;
629 }
630 input++;
631 }
632 }
633
634 if (_secondaryKeyboardInput) {
635 KeyboardInput *input = _secondaryKeyboardInput;
636 while (input->_commandToIssue != kDMCommandNone) {
637 if ((input->_key == event.kbd.keycode) && (input->_modifiers == (event.kbd.flags & input->_modifiers))) {
638 processPendingClick(); // possible fix to BUG0_73
639 _commandQueue.push(Command(Common::Point(-1, -1), input->_commandToIssue));
640 break;
641 }
642 input++;
643 }
644 }
645 break;
646 }
647 case Common::EVENT_MOUSEMOVE:
648 if (!_ignoreMouseMovements)
649 _mousePos = event.mouse;
650 break;
651 case Common::EVENT_LBUTTONDOWN:
652 case Common::EVENT_RBUTTONDOWN: {
653 MouseButton button = (event.type == Common::EVENT_LBUTTONDOWN) ? kDMMouseButtonLeft : kDMMouseButtonRight;
654 _mouseButtonStatus |= button;
655 if (grabMouseClick) {
656 *grabMouseClick = event;
657 return event.type;
658 }
659 _pendingClickPresent = true;
660 _pendingClickPos = _mousePos;
661 _pendingClickButton = button;
662 break;
663 }
664 case Common::EVENT_LBUTTONUP:
665 case Common::EVENT_RBUTTONUP: {
666 MouseButton button = (event.type == Common::EVENT_LBUTTONDOWN) ? kDMMouseButtonLeft : kDMMouseButtonRight;
667 _mouseButtonStatus &= ~button;
668 resetPressingEyeOrMouth();
669 break;
670 }
671 case Common::EVENT_QUIT:
672 _vm->_engineShouldQuit = true;
673 break;
674 default:
675 break;
676 }
677 }
678 if (_ignoreMouseMovements)
679 setMousePos(_mousePos);
680 return Common::EVENT_INVALID;
681 }
682
683
processPendingClick()684 void EventManager::processPendingClick() {
685 if (_pendingClickPresent) {
686 _pendingClickPresent = false;
687 processClick(_pendingClickPos, _pendingClickButton);
688 }
689 }
690
processClick(Common::Point mousePos,MouseButton button)691 void EventManager::processClick(Common::Point mousePos, MouseButton button) {
692 CommandType commandType;
693
694 commandType = getCommandTypeFromMouseInput(_primaryMouseInput, mousePos, button);
695 if (commandType == kDMCommandNone)
696 commandType = getCommandTypeFromMouseInput(_secondaryMouseInput, mousePos, button);
697
698 if (commandType != kDMCommandNone)
699 _commandQueue.push(Command(mousePos, commandType));
700
701 _isCommandQueueLocked = false;
702 }
703
getCommandTypeFromMouseInput(MouseInput * input,Common::Point mousePos,MouseButton button)704 CommandType EventManager::getCommandTypeFromMouseInput(MouseInput *input, Common::Point mousePos, MouseButton button) {
705 if (!input)
706 return kDMCommandNone;
707
708 CommandType commandType = kDMCommandNone;
709 while ((commandType = input->_commandTypeToIssue) != kDMCommandNone) {
710 if (input->_hitbox.isPointInside(mousePos) && input->_button == button)
711 break;
712 input++;
713 }
714 return commandType;
715 }
716
processCommandQueue()717 void EventManager::processCommandQueue() {
718 static KeyboardInput *primaryKeyboardInputBackup;
719 static KeyboardInput *secondaryKeyboardInputBackup;
720 static MouseInput *primaryMouseInputBackup;
721 static MouseInput *secondaryMouseInputBackup;
722
723 DisplayMan &displMan = *_vm->_displayMan;
724 TextMan &txtMan = *_vm->_textMan;
725 InventoryMan &inventory = *_vm->_inventoryMan;
726
727 _isCommandQueueLocked = true;
728 if (_commandQueue.empty()) { /* If the command queue is empty */
729 _isCommandQueueLocked = false;
730 processPendingClick();
731 return;
732 }
733
734 Command cmd = _commandQueue.pop();
735 CommandType cmdType = cmd._type;
736 if ((cmdType >= kDMCommandMoveForward) && (cmdType <= kDMCommandMoveLeft) && (_vm->_disabledMovementTicks || (_vm->_projectileDisableMovementTicks && (_vm->_lastProjectileDisabledMovementDirection == (_vm->normalizeModulo4(_vm->_dungeonMan->_partyDir + cmdType - kDMCommandMoveForward)))))) { /* If movement is disabled */
737 _isCommandQueueLocked = false;
738 processPendingClick();
739 return;
740 }
741
742 int16 commandX = cmd._pos.x;
743 int16 commandY = cmd._pos.y;
744 _isCommandQueueLocked = false;
745 processPendingClick();
746 if ((cmdType == kDMCommandTurnRight) || (cmdType == kDMCommandTurnLeft)) {
747 commandTurnParty(cmdType);
748 return;
749 }
750
751 if ((cmdType >= kDMCommandMoveForward) && (cmdType <= kDMCommandMoveLeft)) {
752 commandMoveParty(cmdType);
753 return;
754 }
755
756 if ((cmdType >= kDMCommandClickInChampion0StatusBox) && (cmdType <= kDMCommandClickInChampion3StatusBox)) {
757 int16 championIdx = cmdType - kDMCommandClickInChampion0StatusBox;
758 if ((championIdx < _vm->_championMan->_partyChampionCount) && !_vm->_championMan->_candidateChampionOrdinal)
759 commandProcessTypes12to27_clickInChampionStatusBox(championIdx, commandX, commandY);
760
761 return;
762 }
763
764 if ((cmdType >= kDMCommandClickOnChamptionIconTopLeft) && (cmdType <= kDMCommandClickOnChamptionIconLowerLeft)) {
765 mouseProcessCommands125To128_clickOnChampionIcon(cmdType - kDMCommandClickOnChamptionIconTopLeft);
766
767 return;
768 }
769
770 if ((cmdType >= kDMCommandClickOnSlotBoxInventoryReadyHand) && (cmdType < (kDMCommandClickOnSlotBoxChest8 + 1))) {
771 if (_vm->_championMan->_leaderIndex != kDMChampionNone)
772 _vm->_championMan->clickOnSlotBox(cmdType - kDMCommandClickOnSlotBoxChampion0StatusBoxReadyHand);
773
774 return;
775 }
776
777 if ((cmdType >= kDMCommandToggleInventoryChampion0) && (cmdType <= kDMCommandCloseInventory)) {
778 if (cmdType == kDMCommandCloseInventory) {
779 delete _vm->_saveThumbnail;
780 _vm->_saveThumbnail = nullptr;
781 } else if (!_vm->_saveThumbnail) {
782 _vm->_saveThumbnail = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
783 Graphics::saveThumbnail(*_vm->_saveThumbnail);
784 }
785
786 int16 championIndex = cmdType - kDMCommandToggleInventoryChampion0;
787 if (((championIndex == kDMChampionCloseInventory) || (championIndex < _vm->_championMan->_partyChampionCount)) && !_vm->_championMan->_candidateChampionOrdinal)
788 inventory.toggleInventory((ChampionIndex)championIndex);
789
790 return;
791 }
792
793 if (cmdType == kDMCommandToggleInventoryLeader) {
794 if (_vm->_championMan->_leaderIndex != kDMChampionNone)
795 inventory.toggleInventory(_vm->_championMan->_leaderIndex);
796
797 return;
798 }
799
800 if (cmdType == kDMCommandClickInSpellArea) {
801 if ((!_vm->_championMan->_candidateChampionOrdinal) && (_vm->_championMan->_magicCasterChampionIndex != kDMChampionNone))
802 commandProcessType100_clickInSpellArea(commandX, commandY);
803
804 return;
805 }
806
807 if (cmdType == kDMCommandClickInActionArea) {
808 if (!_vm->_championMan->_candidateChampionOrdinal)
809 commandProcessType111To115_ClickInActionArea(commandX, commandY);
810
811 return;
812 }
813
814 if (cmdType == kDMCommandClickOnMouth) {
815 inventory.clickOnMouth();
816 return;
817 }
818
819 if (cmdType == kDMCommandClickOnEye) {
820 inventory.clickOnEye();
821 return;
822 }
823
824 if (cmdType == kDMCommandClickInDungeonView) {
825 commandProcessType80ClickInDungeonView(commandX, commandY);
826 return;
827 }
828 if (cmdType == kDMCommandClickInPanel) {
829 commandProcess81ClickInPanel(commandX, commandY);
830 return;
831 }
832
833 if (_vm->_pressingEye || _vm->_pressingMouth)
834 return;
835
836 if (cmdType == kDMCommandSleep) {
837 if (!_vm->_championMan->_candidateChampionOrdinal) {
838 if (inventory._inventoryChampionOrdinal)
839 inventory.toggleInventory(kDMChampionCloseInventory);
840
841 _vm->_menuMan->drawDisabledMenu();
842 _vm->_championMan->_partyIsSleeping = true;
843 drawSleepScreen();
844 displMan.drawViewport(k2_viewportAsBeforeSleepOrFreezeGame);
845 _vm->_waitForInputMaxVerticalBlankCount = 0;
846 _primaryMouseInput = _primaryMouseInputPartySleeping;
847 _secondaryMouseInput = 0;
848 _primaryKeyboardInput = _primaryKeyboardInputPartySleeping;
849 _secondaryKeyboardInput = nullptr;
850 discardAllInput();
851 }
852 return;
853 }
854
855 if (cmdType == kDMCommandWakeUp) {
856 _vm->_championMan->wakeUp();
857 return;
858 }
859
860 if (cmdType == kDMCommandSaveGame) {
861 if ((_vm->_championMan->_partyChampionCount > 0) && !_vm->_championMan->_candidateChampionOrdinal)
862 _vm->saveGame();
863
864 return;
865 }
866
867 if (cmdType == kDMCommandFreezeGame) {
868 _vm->_gameTimeTicking = false;
869 _vm->_menuMan->drawDisabledMenu();
870 displMan.fillBitmap(displMan._bitmapViewport, kDMColorBlack, 112, 136);
871
872 switch (_vm->getGameLanguage()) { // localized
873 default:
874 case Common::EN_ANY:
875 txtMan.printTextToBitmap(displMan._bitmapViewport, k112_byteWidthViewport, 81, 69, kDMColorCyan, kDMColorBlack,
876 "GAME FROZEN", k136_heightViewport);
877 break;
878 case Common::DE_DEU:
879 txtMan.printTextToBitmap(displMan._bitmapViewport, k112_byteWidthViewport, 66, 69, kDMColorCyan, kDMColorBlack,
880 "SPIEL ANGEHALTEN", k136_heightViewport);
881 break;
882 case Common::FR_FRA:
883 txtMan.printTextToBitmap(displMan._bitmapViewport, k112_byteWidthViewport, 84, 69, kDMColorCyan, kDMColorBlack,
884 "JEU BLOQUE", k136_heightViewport);
885 break;
886 }
887 displMan.drawViewport(k2_viewportAsBeforeSleepOrFreezeGame);
888 primaryMouseInputBackup = _primaryMouseInput;
889 secondaryMouseInputBackup = _secondaryMouseInput;
890 primaryKeyboardInputBackup = _primaryKeyboardInput;
891 secondaryKeyboardInputBackup = _secondaryKeyboardInput;
892 _primaryMouseInput = _primaryMouseInputFrozenGame;
893 _secondaryMouseInput = 0;
894 _primaryKeyboardInput = _primaryKeyboardInputFrozenGame;
895 _secondaryKeyboardInput = nullptr;
896 discardAllInput();
897 return;
898 }
899
900 if (cmdType == kDMCommandUnfreezeGame) {
901 _vm->_gameTimeTicking = true;
902 _vm->_menuMan->drawEnabledMenus();
903 _primaryMouseInput = primaryMouseInputBackup;
904 _secondaryMouseInput = secondaryMouseInputBackup;
905 _primaryKeyboardInput = primaryKeyboardInputBackup;
906 _secondaryKeyboardInput = secondaryKeyboardInputBackup;
907 discardAllInput();
908 return;
909 }
910
911 if (cmdType == kDMCommandEntranceEnterDungeon) {
912 _vm->_gameMode = kDMModeLoadDungeon;
913 return;
914 }
915
916 if (cmdType == kDMCommandEntranceResume) {
917 _vm->_gameMode = kDMModeLoadSavedGame;
918 return;
919 }
920
921 if (cmdType == kDMCommandEntranceDrawCredits) {
922 _vm->entranceDrawCredits();
923 return;
924 }
925
926 if ((cmdType >= kDMCommandClickOnDialogChoice1) && (cmdType <= kDMCommandClickOnDialogChoice4)) {
927 _vm->_dialog->_selectedDialogChoice = cmdType - (kDMCommandClickOnDialogChoice1 - 1);
928 return;
929 }
930
931 if (cmdType == kDMCommandRestartGame)
932 _vm->_restartGameRequest = true;
933 }
934
commandTurnParty(CommandType cmdType)935 void EventManager::commandTurnParty(CommandType cmdType) {
936 _vm->_stopWaitingForPlayerInput = true;
937 if (cmdType == kDMCommandTurnLeft)
938 commandHighlightBoxEnable(234, 261, 125, 145);
939 else
940 commandHighlightBoxEnable(291, 318, 125, 145);
941
942 uint16 partySquare = _vm->_dungeonMan->getSquare(_vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY).toByte();
943 if (Square(partySquare).getType() == kDMElementTypeStairs) {
944 commandTakeStairs(getFlag(partySquare, kDMSquareMaskStairsUp));
945 return;
946 }
947
948 _vm->_moveSens->processThingAdditionOrRemoval(_vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, _vm->_thingParty, true, false);
949 _vm->_championMan->setPartyDirection(_vm->normalizeModulo4(_vm->_dungeonMan->_partyDir + ((cmdType == kDMCommandTurnRight) ? 1 : 3)));
950 _vm->_moveSens->processThingAdditionOrRemoval(_vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, _vm->_thingParty, true, true);
951 }
952
commandMoveParty(CommandType cmdType)953 void EventManager::commandMoveParty(CommandType cmdType) {
954 static Box boxMovementArrows[4] = { // @ G0463_as_Graphic561_Box_MovementArrows
955 /* { X1, X2, Y1, Y2 } */
956 Box(263, 289, 125, 145), /* Forward */
957 Box(291, 318, 147, 167), /* Right */
958 Box(263, 289, 147, 167), /* Backward */
959 Box(234, 261, 147, 167) /* Left */
960 };
961
962 static int16 movementArrowToStepForwardCount[4] = { // @ G0465_ai_Graphic561_MovementArrowToStepForwardCount
963 1, /* Forward */
964 0, /* Right */
965 -1, /* Backward */
966 0 /* Left */
967 };
968
969 static int16 movementArrowToSepRightCount[4] = { // @ G0466_ai_Graphic561_MovementArrowToStepRightCount
970 0, /* Forward */
971 1, /* Right */
972 0, /* Backward */
973 -1 /* Left */
974 };
975
976 _vm->_stopWaitingForPlayerInput = true;
977 Champion *championsPtr = _vm->_championMan->_champions;
978 for (uint16 idx = kDMChampionFirst; idx < _vm->_championMan->_partyChampionCount; idx++) {
979 _vm->_championMan->decrementStamina(idx, ((championsPtr->_load * 3) / _vm->_championMan->getMaximumLoad(championsPtr)) + 1); /* BUG0_50 When a champion is brought back to life at a Vi Altar, his current stamina is lower than what it was before dying. Each time the party moves the current stamina of all champions is decreased, including for dead champions, by an amount that depends on the current load of the champion. For a dead champion the load before he died is used */
980 championsPtr++;
981 }
982 uint16 movementArrowIdx = cmdType - kDMCommandMoveForward;
983 Box *highlightBox = &boxMovementArrows[movementArrowIdx];
984 commandHighlightBoxEnable(highlightBox->_rect.left, highlightBox->_rect.right, highlightBox->_rect.top, highlightBox->_rect.bottom);
985 int16 partyMapX = _vm->_dungeonMan->_partyMapX;
986 int16 partyMapY = _vm->_dungeonMan->_partyMapY;
987
988 Square curSquare = _vm->_dungeonMan->getSquare(partyMapX, partyMapY);
989 bool isStairsSquare = (curSquare.getType() == kDMElementTypeStairs);
990 if (isStairsSquare && (movementArrowIdx == 2)) { /* If moving backward while in stairs */
991 commandTakeStairs(getFlag(curSquare.toByte(), kDMSquareMaskStairsUp));
992 return;
993 }
994
995 _vm->_dungeonMan->mapCoordsAfterRelMovement(_vm->_dungeonMan->_partyDir, movementArrowToStepForwardCount[movementArrowIdx], movementArrowToSepRightCount[movementArrowIdx], partyMapX, partyMapY);
996 curSquare = _vm->_dungeonMan->getSquare(partyMapX, partyMapY);
997
998 bool isMovementBlocked = false;
999 ElementType partySquareType = curSquare.getType();
1000 switch (partySquareType){
1001 case kDMElementTypeWall:
1002 isMovementBlocked = true;
1003 break;
1004 case kDMElementTypeStairs: {
1005 _vm->_moveSens->getMoveResult(_vm->_thingParty, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMMapXNotOnASquare, 0);
1006 _vm->_dungeonMan->_partyMapX = partyMapX;
1007 _vm->_dungeonMan->_partyMapY = partyMapY;
1008 byte stairState = curSquare.toByte();
1009 commandTakeStairs(getFlag(stairState, kDMSquareMaskStairsUp));
1010 return;
1011 }
1012 case kDMElementTypeDoor: {
1013 byte doorState = curSquare.getDoorState();
1014 isMovementBlocked = (doorState != kDMDoorStateOpen) && (doorState != kDMDoorStateOneFourth) && (doorState != kDMDoorStateDestroyed);
1015 }
1016 break;
1017 case kDMElementTypeFakeWall: {
1018 byte wallState = curSquare.toByte();
1019 isMovementBlocked = (!getFlag(wallState, kDMSquareMaskFakeWallOpen) && !getFlag(wallState, kDMSquareMaskFakeWallImaginary));
1020 }
1021 break;
1022 default:
1023 break;
1024 }
1025
1026 if (_vm->_championMan->_partyChampionCount) {
1027 if (isMovementBlocked) {
1028 movementArrowIdx += (_vm->_dungeonMan->_partyDir + 2);
1029 int16 firstDamagedChampionIndex = _vm->_championMan->getTargetChampionIndex(partyMapX, partyMapY, _vm->normalizeModulo4(movementArrowIdx));
1030 int16 secondDamagedChampionIndex = _vm->_championMan->getTargetChampionIndex(partyMapX, partyMapY, _vm->turnDirRight(movementArrowIdx));
1031 int16 damage = _vm->_championMan->addPendingDamageAndWounds_getDamage(firstDamagedChampionIndex, 1, kDMWoundTorso | kDMWoundLegs, kDMAttackTypeSelf);
1032 if (firstDamagedChampionIndex != secondDamagedChampionIndex)
1033 damage |= _vm->_championMan->addPendingDamageAndWounds_getDamage(secondDamagedChampionIndex, 1, kDMWoundTorso | kDMWoundLegs, kDMAttackTypeSelf);
1034
1035 if (damage)
1036 _vm->_sound->requestPlay(kDMSoundIndexPartyDamaged, partyMapX, partyMapY, kDMSoundModePlayImmediately);
1037 } else {
1038 isMovementBlocked = (_vm->_groupMan->groupGetThing(partyMapX, partyMapY) != _vm->_thingEndOfList);
1039 if (isMovementBlocked)
1040 _vm->_groupMan->processEvents29to41(partyMapX, partyMapY, kDMEventTypeCreateReactionPartyIsAdjacent, 0);
1041 }
1042 }
1043
1044 // DEBUG CODE: check for Console flag
1045 if (isMovementBlocked && !_vm->_console->_debugNoclip) {
1046 discardAllInput();
1047 _vm->_stopWaitingForPlayerInput = false;
1048 return;
1049 }
1050
1051 if (isStairsSquare)
1052 _vm->_moveSens->getMoveResult(_vm->_thingParty, kDMMapXNotOnASquare, 0, partyMapX, partyMapY);
1053 else
1054 _vm->_moveSens->getMoveResult(_vm->_thingParty, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, partyMapX, partyMapY);
1055
1056 uint16 disabledMovtTicks = 1;
1057 championsPtr = _vm->_championMan->_champions;
1058 for (uint16 idx = kDMChampionFirst; idx < _vm->_championMan->_partyChampionCount; idx++) {
1059 if (championsPtr->_currHealth)
1060 disabledMovtTicks = MAX((int32)disabledMovtTicks, (int32)_vm->_championMan->getMovementTicks(championsPtr));
1061
1062 championsPtr++;
1063 }
1064 _vm->_disabledMovementTicks = disabledMovtTicks;
1065 _vm->_projectileDisableMovementTicks = 0;
1066 }
1067
isLeaderHandObjThrown(int16 posX,int16 posY)1068 bool EventManager::isLeaderHandObjThrown(int16 posX, int16 posY) {
1069 #define k0_sideLeft 0 // @ C0_SIDE_LEFT
1070 #define k1_sideRight 1 // @ C0_SIDE_LEFT
1071
1072 if ((posY < 47) || (posY > 102))
1073 return false;
1074
1075 bool objectThrownFl;
1076 if (posX <= 111) {
1077 if (_vm->_dungeonMan->_squareAheadElement == kDMElementTypeDoorFront) {
1078 if (posX < 64)
1079 return false;
1080 } else if (posX < 32)
1081 return false;
1082
1083 // Strangerke: Only present in CSB2.1... But it fixes a bug so we keep it
1084 objectThrownFl = _vm->_championMan->isLeaderHandObjectThrown(k0_sideLeft);
1085 } else {
1086 if (_vm->_dungeonMan->_squareAheadElement == kDMElementTypeDoorFront) {
1087 if (posX > 163)
1088 return false;
1089 } else if (posX > 191)
1090 return false;
1091
1092 objectThrownFl = _vm->_championMan->isLeaderHandObjectThrown(k1_sideRight);
1093 }
1094
1095 if (objectThrownFl)
1096 _vm->_stopWaitingForPlayerInput = true;
1097
1098 return objectThrownFl;
1099 }
1100
setMousePointerFromSpriteData(byte * mouseSprite)1101 void EventManager::setMousePointerFromSpriteData(byte *mouseSprite) {
1102 byte bitmap[16 * 18];
1103 memset(bitmap, 0, sizeof(bitmap));
1104 for (int16 imgPart = 1; imgPart < 3; ++imgPart) {
1105 for (byte *line = mouseSprite + 72 * imgPart, *pixel = bitmap;
1106 line < mouseSprite + 72 * (imgPart + 1);
1107 line += 4) {
1108
1109 uint16 words[2];
1110 words[0] = READ_BE_UINT16(line);
1111 words[1] = READ_BE_UINT16(line + 2);
1112 for (int16 i = 15; i >= 0; --i, ++pixel) {
1113 uint16 val = (((words[0] >> i) & 1) | (((words[1] >> i) & 1) << 1)) << (imgPart & 0x2);
1114 if (val)
1115 *pixel = val + 8;
1116 }
1117 }
1118 }
1119
1120 CursorMan.replaceCursor(bitmap, 16, 18, 0, 0, 0);
1121 }
1122
commandSetLeader(ChampionIndex champIndex)1123 void EventManager::commandSetLeader(ChampionIndex champIndex) {
1124 ChampionMan &cm = *_vm->_championMan;
1125 ChampionIndex leaderIndex;
1126
1127 if ((cm._leaderIndex == champIndex) || ((champIndex != kDMChampionNone) && !cm._champions[champIndex]._currHealth))
1128 return;
1129
1130 if (cm._leaderIndex != kDMChampionNone) {
1131 leaderIndex = cm._leaderIndex;
1132 cm._champions[leaderIndex].setAttributeFlag(kDMAttributeLoad, true);
1133 cm._champions[leaderIndex].setAttributeFlag(kDMAttributeNameTitle, true);
1134 cm._champions[leaderIndex]._load -= _vm->_dungeonMan->getObjectWeight(cm._leaderHandObject);
1135 cm._leaderIndex = kDMChampionNone;
1136 cm.drawChampionState(leaderIndex);
1137 }
1138 if (champIndex == kDMChampionNone) {
1139 cm._leaderIndex = kDMChampionNone;
1140 return;
1141 }
1142 cm._leaderIndex = champIndex;
1143 Champion *champion = &cm._champions[cm._leaderIndex];
1144 champion->_dir = _vm->_dungeonMan->_partyDir;
1145 cm._champions[champIndex]._load += _vm->_dungeonMan->getObjectWeight(cm._leaderHandObject);
1146 if (_vm->indexToOrdinal(champIndex) != cm._candidateChampionOrdinal) {
1147 champion->setAttributeFlag(kDMAttributeIcon, true);
1148 champion->setAttributeFlag(kDMAttributeNameTitle, true);
1149 cm.drawChampionState(champIndex);
1150 }
1151 }
1152
commandProcessType80ClickInDungeonViewTouchFrontWall()1153 void EventManager::commandProcessType80ClickInDungeonViewTouchFrontWall() {
1154 int16 mapX = _vm->_dungeonMan->_partyMapX + _vm->_dirIntoStepCountEast[_vm->_dungeonMan->_partyDir];
1155 int16 mapY = _vm->_dungeonMan->_partyMapY + _vm->_dirIntoStepCountNorth[_vm->_dungeonMan->_partyDir];
1156
1157 if ((mapX >= 0) && (mapX < _vm->_dungeonMan->_currMapWidth)
1158 && (mapY >= 0) && (mapY < _vm->_dungeonMan->_currMapHeight))
1159 _vm->_stopWaitingForPlayerInput = _vm->_moveSens->sensorIsTriggeredByClickOnWall(mapX, mapY, _vm->returnOppositeDir(_vm->_dungeonMan->_partyDir));
1160 }
1161
commandProcessType80ClickInDungeonView(int16 posX,int16 posY)1162 void EventManager::commandProcessType80ClickInDungeonView(int16 posX, int16 posY) {
1163 Box boxObjectPiles[4] = { // @ G0462_as_Graphic561_Box_ObjectPiles
1164 /* { X1, X2, Y1, Y2 } */
1165 Box(24, 111, 148, 168), /* Front left */
1166 Box(112, 199, 148, 168), /* Front right */
1167 Box(112, 183, 122, 147), /* Back right */
1168 Box(40, 111, 122, 147) /* Back left */
1169 };
1170
1171 if (_vm->_dungeonMan->_squareAheadElement == kDMElementTypeDoorFront) {
1172 if (_vm->_championMan->_leaderIndex == kDMChampionNone)
1173 return;
1174
1175 int16 mapX = _vm->_dungeonMan->_partyMapX + _vm->_dirIntoStepCountEast[_vm->_dungeonMan->_partyDir];
1176 int16 mapY = _vm->_dungeonMan->_partyMapY + _vm->_dirIntoStepCountNorth[_vm->_dungeonMan->_partyDir];
1177
1178 if (_vm->_championMan->_leaderEmptyHanded) {
1179 Junk *junkPtr = (Junk*)_vm->_dungeonMan->getSquareFirstThingData(mapX, mapY);
1180 if ((((Door*)junkPtr)->hasButton()) && _vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn].isPointInside(posX, posY - 33)) {
1181 _vm->_stopWaitingForPlayerInput = true;
1182 _vm->_sound->requestPlay(kDMSoundIndexSwitch, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayIfPrioritized);
1183 _vm->_moveSens->addEvent(kDMEventTypeDoor, mapX, mapY, kDMCellNorthWest, kDMSensorEffectToggle, _vm->_gameTime + 1);
1184 return;
1185 }
1186 } else if (isLeaderHandObjThrown(posX, posY))
1187 return;
1188 }
1189
1190 if (_vm->_championMan->_leaderEmptyHanded) {
1191 for (uint16 currViewCell = kDMViewCellFronLeft; currViewCell < kDMViewCellDoorButtonOrWallOrn + 1; currViewCell++) {
1192 if (_vm->_dungeonMan->_dungeonViewClickableBoxes[currViewCell].isPointInside(posX, posY - 33)) {
1193 if (currViewCell == kDMViewCellDoorButtonOrWallOrn) {
1194 if (!_vm->_dungeonMan->_isFacingAlcove)
1195 commandProcessType80ClickInDungeonViewTouchFrontWall();
1196 } else
1197 processType80_clickInDungeonView_grabLeaderHandObject(currViewCell);
1198
1199 return;
1200 }
1201 }
1202 } else {
1203 Thing thingHandObject = _vm->_championMan->_leaderHandObject;
1204 Junk *junkPtr = (Junk*)_vm->_dungeonMan->getThingData(thingHandObject);
1205 if (_vm->_dungeonMan->_squareAheadElement == kDMElementTypeWall) {
1206 for (uint16 currViewCell = kDMViewCellFronLeft; currViewCell < kDMViewCellFrontRight + 1; currViewCell++) {
1207 if (boxObjectPiles[currViewCell].isPointInside(posX, posY)) {
1208 clickInDungeonViewDropLeaderHandObject(currViewCell);
1209 return;
1210 }
1211 }
1212 if (_vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn].isPointInside(posX, posY - 33)) {
1213 if (_vm->_dungeonMan->_isFacingAlcove)
1214 clickInDungeonViewDropLeaderHandObject(kDMViewCellAlcove);
1215 else {
1216 if (_vm->_dungeonMan->_isFacingFountain) {
1217 uint16 iconIdx = _vm->_objectMan->getIconIndex(thingHandObject);
1218 uint16 weight = _vm->_dungeonMan->getObjectWeight(thingHandObject);
1219 if ((iconIdx >= kDMIconIndiceJunkWater) && (iconIdx <= kDMIconIndiceJunkWaterSkin))
1220 junkPtr->setChargeCount(3); /* Full */
1221 else if (iconIdx == kDMIconIndicePotionEmptyFlask)
1222 ((Potion*)junkPtr)->setType(kDMPotionTypeWaterFlask);
1223 else {
1224 commandProcessType80ClickInDungeonViewTouchFrontWall();
1225 return;
1226 }
1227 _vm->_championMan->drawChangedObjectIcons();
1228 _vm->_championMan->_champions[_vm->_championMan->_leaderIndex]._load += _vm->_dungeonMan->getObjectWeight(thingHandObject) - weight;
1229 }
1230 commandProcessType80ClickInDungeonViewTouchFrontWall();
1231 }
1232 }
1233 } else {
1234 if (isLeaderHandObjThrown(posX, posY))
1235 return;
1236
1237 for (uint16 currViewCell = kDMViewCellFronLeft; currViewCell < kDMViewCellBackLeft + 1; currViewCell++) {
1238 if (boxObjectPiles[currViewCell].isPointInside(posX, posY)) {
1239 clickInDungeonViewDropLeaderHandObject(currViewCell);
1240 return;
1241 }
1242 }
1243 }
1244 }
1245 }
1246
commandProcessCommands160To162ClickInResurrectReincarnatePanel(CommandType commandType)1247 void EventManager::commandProcessCommands160To162ClickInResurrectReincarnatePanel(CommandType commandType) {
1248 ChampionMan &champMan = *_vm->_championMan;
1249 InventoryMan &invMan = *_vm->_inventoryMan;
1250 DisplayMan &dispMan = *_vm->_displayMan;
1251 DungeonMan &dunMan = *_vm->_dungeonMan;
1252 TextMan &txtMan = *_vm->_textMan;
1253
1254 uint16 championIndex = champMan._partyChampionCount - 1;
1255 Champion *champ = &champMan._champions[championIndex];
1256 if (commandType == kDMCommandClickInPanelCancel) {
1257 invMan.toggleInventory(kDMChampionCloseInventory);
1258 champMan._candidateChampionOrdinal = _vm->indexToOrdinal(kDMChampionNone);
1259 if (champMan._partyChampionCount == 1) {
1260 commandSetLeader(kDMChampionNone);
1261 }
1262 champMan._partyChampionCount--;
1263 Box box;
1264 box._rect.top = 0;
1265 box._rect.bottom = 28;
1266 box._rect.left = championIndex * kDMChampionStatusBoxSpacing;
1267 box._rect.right = box._rect.left + 66;
1268 dispMan._useByteBoxCoordinates = false;
1269 dispMan.fillScreenBox(box, kDMColorBlack);
1270 dispMan.fillScreenBox(_vm->_championMan->_boxChampionIcons[champMan.getChampionIconIndex(champ->_cell, dunMan._partyDir) * 2], kDMColorBlack);
1271 _vm->_menuMan->drawEnabledMenus();
1272 showMouse();
1273 return;
1274 }
1275
1276 champMan._candidateChampionOrdinal = _vm->indexToOrdinal(kDMChampionNone);
1277 int16 mapX = dunMan._partyMapX + _vm->_dirIntoStepCountEast[dunMan._partyDir];
1278 int16 mapY = dunMan._partyMapY + _vm->_dirIntoStepCountNorth[dunMan._partyDir];
1279
1280 for (uint16 slotIndex = kDMSlotReadyHand; slotIndex < kDMSlotChest1; slotIndex++) {
1281 Thing thing = champ->getSlot((ChampionSlot)slotIndex);
1282 if (thing != _vm->_thingNone) {
1283 _vm->_dungeonMan->unlinkThingFromList(thing, Thing(0), mapX, mapY);
1284 }
1285 }
1286 Thing thing = dunMan.getSquareFirstThing(mapX, mapY);
1287 for (;;) { // infinite
1288 if (thing.getType() == kDMThingTypeSensor) {
1289 ((Sensor*)dunMan.getThingData(thing))->setTypeDisabled();
1290 break;
1291 }
1292 thing = dunMan.getNextThing(thing);
1293 }
1294
1295 if (commandType == kDMCommandClickInPanelReincarnate) {
1296 champMan.renameChampion(champ);
1297 if (_vm->_engineShouldQuit)
1298 return;
1299 champ->resetSkillsToZero();
1300
1301 for (uint16 i = 0; i < 12; i++) {
1302 uint16 statIndex = _vm->getRandomNumber(7);
1303 champ->getStatistic((ChampionStatType)statIndex, kDMStatCurrent)++; // returns reference
1304 champ->getStatistic((ChampionStatType)statIndex, kDMStatMaximum)++; // returns reference
1305 }
1306 }
1307
1308 if (champMan._partyChampionCount == 1) {
1309 _vm->_projexpl->_lastPartyMovementTime = _vm->_gameTime;
1310 commandSetLeader(kDMChampionFirst);
1311 _vm->_menuMan->setMagicCasterAndDrawSpellArea(kDMChampionFirst);
1312 } else
1313 _vm->_menuMan->drawSpellAreaControls(champMan._magicCasterChampionIndex);
1314
1315 txtMan.printLineFeed();
1316 Color champColor = _vm->_championMan->_championColor[championIndex];
1317 txtMan.printMessage(champColor, champ->_name);
1318
1319 switch (_vm->getGameLanguage()) { // localized
1320 default:
1321 case Common::EN_ANY:
1322 txtMan.printMessage(champColor, (commandType == kDMCommandClickInPanelResurrect) ? " RESURRECTED." : " REINCARNATED.");
1323 break;
1324 case Common::DE_DEU:
1325 txtMan.printMessage(champColor, (commandType == kDMCommandClickInPanelResurrect) ? " VOM TODE ERWECKT." : " REINKARNIERT.");
1326 break;
1327 case Common::FR_FRA:
1328 txtMan.printMessage(champColor, (commandType == kDMCommandClickInPanelResurrect) ? " RESSUSCITE." : " REINCARNE.");
1329 break;
1330 }
1331
1332 invMan.toggleInventory(kDMChampionCloseInventory);
1333 _vm->_menuMan->drawEnabledMenus();
1334 setMousePointerToNormal((_vm->_championMan->_leaderIndex == kDMChampionNone) ? k0_pointerArrow : k1_pointerHand);
1335 }
1336
commandProcess81ClickInPanel(int16 x,int16 y)1337 void EventManager::commandProcess81ClickInPanel(int16 x, int16 y) {
1338 ChampionMan &champMan = *_vm->_championMan;
1339 InventoryMan &invMan = *_vm->_inventoryMan;
1340
1341 CommandType commandType;
1342 switch (invMan._panelContent) {
1343 case kDMPanelContentChest:
1344 if (champMan._leaderIndex == kDMChampionNone) // if no leader
1345 return;
1346 commandType = getCommandTypeFromMouseInput(_mouseInputPanelChest, Common::Point(x, y), kDMMouseButtonLeft);
1347 if (commandType != kDMCommandNone)
1348 champMan.clickOnSlotBox(commandType - kDMCommandClickOnSlotBoxChampion0StatusBoxReadyHand);
1349 break;
1350 case kDMPanelContentResurrectReincarnate:
1351 if (!champMan._leaderEmptyHanded)
1352 break;
1353 commandType = getCommandTypeFromMouseInput(_mouseInputPanelResurrectReincarnateCancel, Common::Point(x, y), kDMMouseButtonLeft);
1354 if (commandType != kDMCommandNone)
1355 commandProcessCommands160To162ClickInResurrectReincarnatePanel(commandType);
1356 break;
1357 default:
1358 break;
1359 }
1360 }
1361
processType80_clickInDungeonView_grabLeaderHandObject(uint16 viewCell)1362 void EventManager::processType80_clickInDungeonView_grabLeaderHandObject(uint16 viewCell) {
1363 if (_vm->_championMan->_leaderIndex == kDMChampionNone)
1364 return;
1365
1366 int16 mapX = _vm->_dungeonMan->_partyMapX;
1367 int16 mapY = _vm->_dungeonMan->_partyMapY;
1368 if (viewCell >= kDMViewCellBackRight) {
1369 mapX += _vm->_dirIntoStepCountEast[_vm->_dungeonMan->_partyDir];
1370 mapY += _vm->_dirIntoStepCountNorth[_vm->_dungeonMan->_partyDir];
1371 Thing groupThing = _vm->_groupMan->groupGetThing(mapX, mapY);
1372 if ((groupThing != _vm->_thingEndOfList) &&
1373 !_vm->_moveSens->isLevitating(groupThing) &&
1374 _vm->_groupMan->getCreatureOrdinalInCell((Group*)_vm->_dungeonMan->getThingData(groupThing), _vm->normalizeModulo4(viewCell + _vm->_dungeonMan->_partyDir))) {
1375 return; /* It is not possible to grab an object on floor if there is a non levitating creature on its cell */
1376 }
1377 }
1378
1379 Thing topPileThing = _vm->_dungeonMan->_pileTopObject[viewCell];
1380 if (_vm->_objectMan->getIconIndex(topPileThing) != kDMIconIndiceNone) {
1381 _vm->_moveSens->getMoveResult(topPileThing, mapX, mapY, kDMMapXNotOnASquare, 0);
1382 _vm->_championMan->putObjectInLeaderHand(topPileThing, true);
1383 }
1384
1385 _vm->_stopWaitingForPlayerInput = true;
1386 }
1387
clickInDungeonViewDropLeaderHandObject(uint16 viewCell)1388 void EventManager::clickInDungeonViewDropLeaderHandObject(uint16 viewCell) {
1389 if (_vm->_championMan->_leaderIndex == kDMChampionNone)
1390 return;
1391
1392 int16 mapX = _vm->_dungeonMan->_partyMapX;
1393 int16 mapY = _vm->_dungeonMan->_partyMapY;
1394 bool droppingIntoAnAlcove = (viewCell == kDMViewCellAlcove);
1395 if (droppingIntoAnAlcove)
1396 viewCell = kDMViewCellBackRight;
1397
1398 if (viewCell > kDMViewCellFrontRight) {
1399 mapX += _vm->_dirIntoStepCountEast[_vm->_dungeonMan->_partyDir];
1400 mapY += _vm->_dirIntoStepCountNorth[_vm->_dungeonMan->_partyDir];
1401 }
1402
1403 uint16 currCell = _vm->normalizeModulo4(_vm->_dungeonMan->_partyDir + viewCell);
1404 Thing removedThing = _vm->_championMan->getObjectRemovedFromLeaderHand();
1405 _vm->_moveSens->getMoveResult(_vm->thingWithNewCell(removedThing, currCell), kDMMapXNotOnASquare, 0, mapX, mapY);
1406 if (droppingIntoAnAlcove && _vm->_dungeonMan->_isFacingViAltar && (_vm->_objectMan->getIconIndex(removedThing) == kDMIconIndiceJunkChampionBones)) {
1407 Junk *removedJunk = (Junk*)_vm->_dungeonMan->getThingData(removedThing);
1408 TimelineEvent newEvent;
1409 newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + 1);
1410 newEvent._type = kDMEventTypeViAltarRebirth;
1411 newEvent._priority = removedJunk->getChargeCount();
1412 newEvent._Bu._location._mapX = mapX;
1413 newEvent._Bu._location._mapY = mapY;
1414 newEvent._Cu.A._cell = currCell;
1415 newEvent._Cu.A._effect = kDMSensorEffectToggle;
1416 _vm->_timeline->addEventGetEventIndex(&newEvent);
1417 }
1418 _vm->_stopWaitingForPlayerInput = true;
1419 }
1420
hasPendingClick(Common::Point & point,MouseButton button)1421 bool EventManager::hasPendingClick(Common::Point& point, MouseButton button) {
1422 if (_pendingClickButton && button == _pendingClickButton)
1423 point = _pendingClickPos;
1424
1425 return _pendingClickPresent;
1426 }
1427
drawSleepScreen()1428 void EventManager::drawSleepScreen() {
1429 DisplayMan &displMan = *_vm->_displayMan;
1430 TextMan &txtMan = *_vm->_textMan;
1431
1432 displMan.fillBitmap(displMan._bitmapViewport, kDMColorBlack, 112, 136);
1433 switch (_vm->getGameLanguage()) { // localized
1434 default:
1435 case Common::EN_ANY:
1436 txtMan.printTextToBitmap(displMan._bitmapViewport, k112_byteWidthViewport, 93, 69, kDMColorCyan, kDMColorBlack, "WAKE UP", k136_heightViewport);
1437 break;
1438 case Common::DE_DEU:
1439 txtMan.printTextToBitmap(displMan._bitmapViewport, k112_byteWidthViewport, 96, 69, kDMColorCyan, kDMColorBlack, "WECKEN", k136_heightViewport);
1440 break;
1441 case Common::FR_FRA:
1442 txtMan.printTextToBitmap(displMan._bitmapViewport, k112_byteWidthViewport, 72, 69, kDMColorCyan, kDMColorBlack, "REVEILLEZ-VOUS", k136_heightViewport);
1443 break;
1444 }
1445 }
1446
discardAllInput()1447 void EventManager::discardAllInput() {
1448 Common::Event event;
1449 while (g_system->getEventManager()->pollEvent(event) && !_vm->_engineShouldQuit) {
1450 if (event.type == Common::EVENT_QUIT)
1451 _vm->_engineShouldQuit = true;
1452 }
1453 _commandQueue.clear();
1454 }
1455
commandTakeStairs(bool stairsGoDown)1456 void EventManager::commandTakeStairs(bool stairsGoDown) {
1457 _vm->_moveSens->getMoveResult(_vm->_thingParty, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMMapXNotOnASquare, 0);
1458 _vm->_newPartyMapIndex = _vm->_dungeonMan->getLocationAfterLevelChange(_vm->_dungeonMan->_partyMapIndex, stairsGoDown ? -1 : 1, &_vm->_dungeonMan->_partyMapX, &_vm->_dungeonMan->_partyMapY);
1459 _vm->_dungeonMan->setCurrentMap(_vm->_newPartyMapIndex);
1460 _vm->_championMan->setPartyDirection(_vm->_dungeonMan->getStairsExitDirection(_vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY));
1461 _vm->_dungeonMan->setCurrentMap(_vm->_dungeonMan->_partyMapIndex);
1462 }
1463
commandProcessTypes12to27_clickInChampionStatusBox(uint16 champIndex,int16 posX,int16 posY)1464 void EventManager::commandProcessTypes12to27_clickInChampionStatusBox(uint16 champIndex, int16 posX, int16 posY) {
1465 if (_vm->indexToOrdinal(champIndex) == _vm->_inventoryMan->_inventoryChampionOrdinal) {
1466 commandSetLeader((ChampionIndex)champIndex);
1467 } else {
1468 uint16 commandType = getCommandTypeFromMouseInput(_mouseInputChampionNamesHands, Common::Point(posX, posY), kDMMouseButtonLeft);
1469 if ((commandType >= kDMCommandSetLeaderChampion0) && (commandType <= kDMCommandSetLeaderChampion3))
1470 commandSetLeader((ChampionIndex)(commandType - kDMCommandSetLeaderChampion0));
1471 else if ((commandType >= kDMCommandClickOnSlotBoxChampion0StatusBoxReadyHand) && (commandType <= kDMCommandClickOnSlotBoxChampion3StatusBoxActionHand))
1472 _vm->_championMan->clickOnSlotBox(commandType - kDMCommandClickOnSlotBoxChampion0StatusBoxReadyHand);
1473 }
1474 }
1475
mouseProcessCommands125To128_clickOnChampionIcon(uint16 champIconIndex)1476 void EventManager::mouseProcessCommands125To128_clickOnChampionIcon(uint16 champIconIndex) {
1477 static Box championIconShadowBox = Box(2, 20, 2, 15);
1478 static Box championIconBox = Box(0, 18, 0, 13);
1479 static byte mousePointerIconShadowBox[16] = {0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 0, 120, 120, 120};
1480
1481 DisplayMan &displMan = *_vm->_displayMan;
1482
1483 _preventBuildPointerScreenArea = true;
1484 if (!_useChampionIconOrdinalAsMousePointerBitmap) {
1485 if (_vm->_championMan->getIndexInCell(_vm->normalizeModulo4(champIconIndex + _vm->_dungeonMan->_partyDir)) == kDMChampionNone) {
1486 _preventBuildPointerScreenArea = false;
1487 return;
1488 }
1489 _mousePointerBitmapUpdated = true;
1490 _useChampionIconOrdinalAsMousePointerBitmap = true;
1491 displMan._useByteBoxCoordinates = false;
1492 byte *tmpBitmap = _mousePointerTempBuffer;
1493 memset(tmpBitmap, 0, 32 * 18);
1494 Box *curChampionIconBox = &_vm->_championMan->_boxChampionIcons[champIconIndex];
1495
1496 displMan.blitToBitmap(displMan._bitmapScreen, tmpBitmap, championIconShadowBox, curChampionIconBox->_rect.left, curChampionIconBox->_rect.top, k160_byteWidthScreen, k16_byteWidth, kDMColorBlack, 200, 18);
1497 displMan.blitToBitmapShrinkWithPalChange(tmpBitmap, _mousePointerOriginalColorsChampionIcon, 32, 18, 32, 18, mousePointerIconShadowBox);
1498 displMan.blitToBitmap(displMan._bitmapScreen, _mousePointerOriginalColorsChampionIcon, championIconBox, curChampionIconBox->_rect.left, curChampionIconBox->_rect.top, k160_byteWidthScreen, k16_byteWidth, kDMColorBlack, 200, 18);
1499 displMan.fillScreenBox(*curChampionIconBox, kDMColorBlack);
1500 _useChampionIconOrdinalAsMousePointerBitmap = _vm->indexToOrdinal(champIconIndex);
1501 } else {
1502 _mousePointerBitmapUpdated = true;
1503 uint16 championIconIndex = _vm->ordinalToIndex(_useChampionIconOrdinalAsMousePointerBitmap);
1504 _useChampionIconOrdinalAsMousePointerBitmap = _vm->indexToOrdinal(kDMChampionNone);
1505 int16 championCellIndex = _vm->_championMan->getIndexInCell(_vm->normalizeModulo4(championIconIndex + _vm->_dungeonMan->_partyDir));
1506 if (championIconIndex == champIconIndex) {
1507 setFlag(_vm->_championMan->_champions[championCellIndex]._attributes, kDMAttributeIcon);
1508 _vm->_championMan->drawChampionState((ChampionIndex)championCellIndex);
1509 } else {
1510 int16 championIndex = _vm->_championMan->getIndexInCell(_vm->normalizeModulo4(champIconIndex + _vm->_dungeonMan->_partyDir));
1511 if (championIndex >= 0) {
1512 _vm->_championMan->_champions[championIndex]._cell = (ViewCell)_vm->normalizeModulo4(championIconIndex + _vm->_dungeonMan->_partyDir);
1513 setFlag(_vm->_championMan->_champions[championIndex]._attributes, kDMAttributeIcon);
1514 _vm->_championMan->drawChampionState((ChampionIndex)championIndex);
1515 } else
1516 displMan.fillScreenBox(_vm->_championMan->_boxChampionIcons[championIconIndex], kDMColorBlack);
1517
1518 _vm->_championMan->_champions[championCellIndex]._cell = (ViewCell)_vm->normalizeModulo4(champIconIndex + _vm->_dungeonMan->_partyDir);
1519 setFlag(_vm->_championMan->_champions[championCellIndex]._attributes, kDMAttributeIcon);
1520 _vm->_championMan->drawChampionState((ChampionIndex)championCellIndex);
1521 }
1522 }
1523 _preventBuildPointerScreenArea = false;
1524 buildpointerScreenArea(_mousePos.x, _mousePos.y);
1525 }
1526
commandProcessType100_clickInSpellArea(uint16 posX,uint16 posY)1527 void EventManager::commandProcessType100_clickInSpellArea(uint16 posX, uint16 posY) {
1528 ChampionIndex championIndex = kDMChampionNone;
1529 if (posY <= 48) {
1530 switch (_vm->_championMan->_magicCasterChampionIndex) {
1531 case 0:
1532 if ((posX >= 280) && (posX <= 291))
1533 championIndex = kDMChampionSecond;
1534 else if ((posX >= 294) && (posX <= 305))
1535 championIndex = kDMChampionThird;
1536 else if (posX >= 308)
1537 championIndex = kDMChampionFourth;
1538
1539 break;
1540 case 1:
1541 if ((posX >= 233) && (posX <= 244))
1542 championIndex = kDMChampionFirst;
1543 else if ((posX >= 294) && (posX <= 305))
1544 championIndex = kDMChampionThird;
1545 else if (posX >= 308)
1546 championIndex = kDMChampionFourth;
1547
1548 break;
1549 case 2:
1550 if ((posX >= 233) && (posX <= 244))
1551 championIndex = kDMChampionFirst;
1552 else if ((posX >= 247) && (posX <= 258))
1553 championIndex = kDMChampionSecond;
1554 else if (posX >= 308)
1555 championIndex = kDMChampionFourth;
1556
1557 break;
1558 case 3:
1559 if ((posX >= 247) && (posX <= 258))
1560 championIndex = kDMChampionSecond;
1561 else if ((posX >= 261) && (posX <= 272))
1562 championIndex = kDMChampionThird;
1563 else if (posX <= 244)
1564 championIndex = kDMChampionFirst;
1565 break;
1566 default:
1567 break;
1568 }
1569
1570 if ((championIndex != kDMChampionNone) && (championIndex < _vm->_championMan->_partyChampionCount))
1571 _vm->_menuMan->setMagicCasterAndDrawSpellArea(championIndex);
1572
1573 return;
1574 }
1575
1576 CommandType newCommand = getCommandTypeFromMouseInput(_mouseInputSpellArea, Common::Point(posX, posY), kDMMouseButtonLeft);
1577 if (newCommand != kDMCommandNone)
1578 commandProcessTypes101To108_clickInSpellSymbolsArea(newCommand);
1579 }
1580
commandProcessTypes101To108_clickInSpellSymbolsArea(CommandType cmdType)1581 void EventManager::commandProcessTypes101To108_clickInSpellSymbolsArea(CommandType cmdType) {
1582 static Box spellSymbolsAndDelete[7] = {
1583 /* { X1, X2, Y1, Y2 } */
1584 Box(235, 247, 51, 61), /* Symbol 1 */
1585 Box(249, 261, 51, 61), /* Symbol 2 */
1586 Box(263, 275, 51, 61), /* Symbol 3 */
1587 Box(277, 289, 51, 61), /* Symbol 4 */
1588 Box(291, 303, 51, 61), /* Symbol 5 */
1589 Box(305, 317, 51, 61), /* Symbol 6 */
1590 Box(305, 318, 63, 73) /* Delete */
1591 };
1592
1593 if (cmdType == kDMCommandClickInSpeallAreaCastSpell) {
1594 if (_vm->_championMan->_champions[_vm->_championMan->_magicCasterChampionIndex]._symbols[0] == '\0')
1595 return;
1596
1597 commandHighlightBoxEnable(234, 303, 63, 73);
1598 _vm->_stopWaitingForPlayerInput = _vm->_menuMan->getClickOnSpellCastResult();
1599 return;
1600 }
1601
1602 uint16 symbolIndex = cmdType - kDMCommandClickInSpellAreaSymbol1;
1603 Box *highlightBox = &spellSymbolsAndDelete[symbolIndex];
1604 commandHighlightBoxEnable(highlightBox->_rect.left, highlightBox->_rect.right, highlightBox->_rect.top, highlightBox->_rect.bottom);
1605 _vm->delay(1);
1606 highlightBoxDisable();
1607
1608 if (symbolIndex < 6)
1609 _vm->_menuMan->addChampionSymbol(symbolIndex);
1610 else
1611 _vm->_menuMan->deleteChampionSymbol();
1612 }
1613
commandProcessType111To115_ClickInActionArea(int16 posX,int16 posY)1614 void EventManager::commandProcessType111To115_ClickInActionArea(int16 posX, int16 posY) {
1615 if (_vm->_championMan->_actingChampionOrdinal) {
1616 uint16 mouseCommand = getCommandTypeFromMouseInput(_mouseInputActionAreaNames, Common::Point(posX, posY), kDMMouseButtonLeft);
1617 if (mouseCommand != kDMCommandNone) {
1618 if (mouseCommand == kDMCommandClickInActionAreaPass) {
1619 commandHighlightBoxEnable(285, 319, 77, 83);
1620 _vm->_menuMan->didClickTriggerAction(-1);
1621 } else if ((mouseCommand - kDMCommandClickInActionAreaPass) <= _vm->_menuMan->_actionCount) {
1622 if (mouseCommand == kDMCommandClickInActionAreaAction0)
1623 commandHighlightBoxEnable(234, 318, 86, 96);
1624 else if (mouseCommand == kDMCommandClickInActionAreaAction1)
1625 commandHighlightBoxEnable(234, 318, 98, 108);
1626 else
1627 commandHighlightBoxEnable(234, 318, 110, 120);
1628
1629 _vm->_stopWaitingForPlayerInput = _vm->_menuMan->didClickTriggerAction(mouseCommand - kDMCommandClickInActionAreaAction0);
1630 }
1631 }
1632 } else if (_vm->_menuMan->_actionAreaContainsIcons) {
1633 uint16 mouseCommand = getCommandTypeFromMouseInput(_mouseInputActionAreaIcons, Common::Point(posX, posY), kDMMouseButtonLeft);
1634 if (mouseCommand != kDMCommandNone) {
1635 mouseCommand -= kDMCommandClickInActionAreaChampion0Action;
1636 if (mouseCommand < _vm->_championMan->_partyChampionCount)
1637 _vm->_menuMan->processCommands116To119_setActingChampion(mouseCommand);
1638 }
1639 }
1640 }
1641
resetPressingEyeOrMouth()1642 void EventManager::resetPressingEyeOrMouth() {
1643 if (_vm->_pressingEye) {
1644 _ignoreMouseMovements = false;
1645 _vm->_stopPressingEye = true;
1646 }
1647 if (_vm->_pressingMouth) {
1648 _ignoreMouseMovements = false;
1649 _vm->_stopPressingMouth = true;
1650 }
1651 }
1652
waitForMouseOrKeyActivity()1653 void EventManager::waitForMouseOrKeyActivity() {
1654 discardAllInput();
1655 Common::Event event;
1656 DisplayMan &displMan = *_vm->_displayMan;
1657 while (true) {
1658 if (g_system->getEventManager()->pollEvent(event)) {
1659 switch (event.type) {
1660 case Common::EVENT_QUIT:
1661 _vm->_engineShouldQuit = true;
1662 case Common::EVENT_KEYDOWN: // Intentional fall through
1663 case Common::EVENT_LBUTTONDOWN:
1664 case Common::EVENT_RBUTTONDOWN:
1665 return;
1666 default:
1667 break;
1668 }
1669 }
1670 _vm->delay(1);
1671 displMan.updateScreen();
1672 }
1673 }
1674
commandHighlightBoxEnable(int16 x1,int16 x2,int16 y1,int16 y2)1675 void EventManager::commandHighlightBoxEnable(int16 x1, int16 x2, int16 y1, int16 y2) {
1676 _highlightScreenBox = Box(x1, x2, y1, y2);
1677 highlightScreenBox(x1, x2, y1, y2);
1678 _highlightBoxEnabled = true;
1679 }
1680
highlightBoxDisable()1681 void EventManager::highlightBoxDisable() {
1682 if (_highlightBoxEnabled == true) {
1683 highlightScreenBox(_highlightScreenBox._rect.left, _highlightScreenBox._rect.right, _highlightScreenBox._rect.top, _highlightScreenBox._rect.bottom);
1684 _highlightBoxEnabled = false;
1685 }
1686 }
1687
1688 } // end of namespace DM
1689