MetaEvent.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: MetaEvent.h ///////////////////////////////////////////////////////////
  24. // Author: Steven Johnson, Dec 2001
  25. #pragma once
  26. #ifndef _H_MetaEvent
  27. #define _H_MetaEvent
  28. #include "Common/SubsystemInterface.h"
  29. #include "GameClient/InGameUI.h"
  30. enum MappableKeyCategories
  31. {
  32. CATEGORY_CONTROL = 0,
  33. CATEGORY_INFORMATION,
  34. CATEGORY_INTERFACE,
  35. CATEGORY_SELECTION,
  36. CATEGORY_TAUNT,
  37. CATEGORY_TEAM,
  38. CATEGORY_MISC,
  39. CATEGORY_DEBUG,
  40. CATEGORY_NUM_CATEGORIES // keep this last
  41. };
  42. static const LookupListRec CategoryListName[] =
  43. {
  44. {"CONTROL", CATEGORY_CONTROL},
  45. {"INFORMATION", CATEGORY_INFORMATION},
  46. {"INTERFACE", CATEGORY_INTERFACE},
  47. {"SELECTION", CATEGORY_SELECTION},
  48. {"TAUNT", CATEGORY_TAUNT},
  49. {"TEAM", CATEGORY_TEAM},
  50. {"MISC", CATEGORY_MISC},
  51. {"DEBUG", CATEGORY_DEBUG},
  52. {NULL, 0}// keep this last
  53. };
  54. // -------------------------------------------------------------------------------
  55. // the keys we allow to be mapped to Meta-events.
  56. // note that this is a subset of all the keys available;
  57. // in particular, "modifier" keys and keypad keys aren't
  58. // available. Note that MappableKeyType is a SUBSET of
  59. // KeyDefType; this is extremely important to maintain!
  60. enum MappableKeyType
  61. {
  62. MK_ESC = KEY_ESC,
  63. MK_BACKSPACE = KEY_BACKSPACE,
  64. MK_ENTER = KEY_ENTER,
  65. MK_SPACE = KEY_SPACE,
  66. MK_TAB = KEY_TAB,
  67. MK_F1 = KEY_F1,
  68. MK_F2 = KEY_F2,
  69. MK_F3 = KEY_F3,
  70. MK_F4 = KEY_F4,
  71. MK_F5 = KEY_F5,
  72. MK_F6 = KEY_F6,
  73. MK_F7 = KEY_F7,
  74. MK_F8 = KEY_F8,
  75. MK_F9 = KEY_F9,
  76. MK_F10 = KEY_F10,
  77. MK_F11 = KEY_F11,
  78. MK_F12 = KEY_F12,
  79. MK_A = KEY_A,
  80. MK_B = KEY_B,
  81. MK_C = KEY_C,
  82. MK_D = KEY_D,
  83. MK_E = KEY_E,
  84. MK_F = KEY_F,
  85. MK_G = KEY_G,
  86. MK_H = KEY_H,
  87. MK_I = KEY_I,
  88. MK_J = KEY_J,
  89. MK_K = KEY_K,
  90. MK_L = KEY_L,
  91. MK_M = KEY_M,
  92. MK_N = KEY_N,
  93. MK_O = KEY_O,
  94. MK_P = KEY_P,
  95. MK_Q = KEY_Q,
  96. MK_R = KEY_R,
  97. MK_S = KEY_S,
  98. MK_T = KEY_T,
  99. MK_U = KEY_U,
  100. MK_V = KEY_V,
  101. MK_W = KEY_W,
  102. MK_X = KEY_X,
  103. MK_Y = KEY_Y,
  104. MK_Z = KEY_Z,
  105. MK_1 = KEY_1,
  106. MK_2 = KEY_2,
  107. MK_3 = KEY_3,
  108. MK_4 = KEY_4,
  109. MK_5 = KEY_5,
  110. MK_6 = KEY_6,
  111. MK_7 = KEY_7,
  112. MK_8 = KEY_8,
  113. MK_9 = KEY_9,
  114. MK_0 = KEY_0,
  115. MK_KP1 = KEY_KP1,
  116. MK_KP2 = KEY_KP2,
  117. MK_KP3 = KEY_KP3,
  118. MK_KP4 = KEY_KP4,
  119. MK_KP5 = KEY_KP5,
  120. MK_KP6 = KEY_KP6,
  121. MK_KP7 = KEY_KP7,
  122. MK_KP8 = KEY_KP8,
  123. MK_KP9 = KEY_KP9,
  124. MK_KP0 = KEY_KP0,
  125. MK_MINUS = KEY_MINUS,
  126. MK_EQUAL = KEY_EQUAL,
  127. MK_LBRACKET = KEY_LBRACKET,
  128. MK_RBRACKET = KEY_RBRACKET,
  129. MK_SEMICOLON = KEY_SEMICOLON,
  130. MK_APOSTROPHE = KEY_APOSTROPHE,
  131. MK_TICK = KEY_TICK,
  132. MK_BACKSLASH = KEY_BACKSLASH,
  133. MK_COMMA = KEY_COMMA,
  134. MK_PERIOD = KEY_PERIOD,
  135. MK_SLASH = KEY_SLASH,
  136. MK_UP = KEY_UP,
  137. MK_DOWN = KEY_DOWN,
  138. MK_LEFT = KEY_LEFT,
  139. MK_RIGHT = KEY_RIGHT,
  140. MK_HOME = KEY_HOME,
  141. MK_END = KEY_END,
  142. MK_PGUP = KEY_PGUP,
  143. MK_PGDN = KEY_PGDN,
  144. MK_INS = KEY_INS,
  145. MK_DEL = KEY_DEL,
  146. MK_KPSLASH = KEY_KPSLASH,
  147. MK_NONE = KEY_NONE
  148. };
  149. static const LookupListRec KeyNames[] =
  150. {
  151. { "KEY_ESC", MK_ESC },
  152. { "KEY_BACKSPACE", MK_BACKSPACE },
  153. { "KEY_ENTER", MK_ENTER },
  154. { "KEY_SPACE", MK_SPACE },
  155. { "KEY_TAB", MK_TAB },
  156. { "KEY_F1", MK_F1 },
  157. { "KEY_F2", MK_F2 },
  158. { "KEY_F3", MK_F3 },
  159. { "KEY_F4", MK_F4 },
  160. { "KEY_F5", MK_F5 },
  161. { "KEY_F6", MK_F6 },
  162. { "KEY_F7", MK_F7 },
  163. { "KEY_F8", MK_F8 },
  164. { "KEY_F9", MK_F9 },
  165. { "KEY_F10", MK_F10 },
  166. { "KEY_F11", MK_F11 },
  167. { "KEY_F12", MK_F12 },
  168. { "KEY_A", MK_A },
  169. { "KEY_B", MK_B },
  170. { "KEY_C", MK_C },
  171. { "KEY_D", MK_D },
  172. { "KEY_E", MK_E },
  173. { "KEY_F", MK_F },
  174. { "KEY_G", MK_G },
  175. { "KEY_H", MK_H },
  176. { "KEY_I", MK_I },
  177. { "KEY_J", MK_J },
  178. { "KEY_K", MK_K },
  179. { "KEY_L", MK_L },
  180. { "KEY_M", MK_M },
  181. { "KEY_N", MK_N },
  182. { "KEY_O", MK_O },
  183. { "KEY_P", MK_P },
  184. { "KEY_Q", MK_Q },
  185. { "KEY_R", MK_R },
  186. { "KEY_S", MK_S },
  187. { "KEY_T", MK_T },
  188. { "KEY_U", MK_U },
  189. { "KEY_V", MK_V },
  190. { "KEY_W", MK_W },
  191. { "KEY_X", MK_X },
  192. { "KEY_Y", MK_Y },
  193. { "KEY_Z", MK_Z },
  194. { "KEY_1", MK_1 },
  195. { "KEY_2", MK_2 },
  196. { "KEY_3", MK_3 },
  197. { "KEY_4", MK_4 },
  198. { "KEY_5", MK_5 },
  199. { "KEY_6", MK_6 },
  200. { "KEY_7", MK_7 },
  201. { "KEY_8", MK_8 },
  202. { "KEY_9", MK_9 },
  203. { "KEY_0", MK_0 },
  204. { "KEY_KP1", MK_KP1 },
  205. { "KEY_KP2", MK_KP2 },
  206. { "KEY_KP3", MK_KP3 },
  207. { "KEY_KP4", MK_KP4 },
  208. { "KEY_KP5", MK_KP5 },
  209. { "KEY_KP6", MK_KP6 },
  210. { "KEY_KP7", MK_KP7 },
  211. { "KEY_KP8", MK_KP8 },
  212. { "KEY_KP9", MK_KP9 },
  213. { "KEY_KP0", MK_KP0 },
  214. { "KEY_MINUS", MK_MINUS },
  215. { "KEY_EQUAL", MK_EQUAL },
  216. { "KEY_LBRACKET", MK_LBRACKET },
  217. { "KEY_RBRACKET", MK_RBRACKET },
  218. { "KEY_SEMICOLON", MK_SEMICOLON },
  219. { "KEY_APOSTROPHE", MK_APOSTROPHE },
  220. { "KEY_TICK", MK_TICK },
  221. { "KEY_BACKSLASH", MK_BACKSLASH },
  222. { "KEY_COMMA", MK_COMMA },
  223. { "KEY_PERIOD", MK_PERIOD },
  224. { "KEY_SLASH", MK_SLASH },
  225. { "KEY_UP", MK_UP },
  226. { "KEY_DOWN", MK_DOWN },
  227. { "KEY_LEFT", MK_LEFT },
  228. { "KEY_RIGHT", MK_RIGHT },
  229. { "KEY_HOME", MK_HOME },
  230. { "KEY_END", MK_END },
  231. { "KEY_PGUP", MK_PGUP },
  232. { "KEY_PGDN", MK_PGDN },
  233. { "KEY_INS", MK_INS },
  234. { "KEY_DEL", MK_DEL },
  235. { "KEY_KPSLASH", MK_KPSLASH },
  236. { "KEY_NONE", MK_NONE },
  237. { NULL, 0 } // keep this last!
  238. };
  239. // -------------------------------------------------------------------------------
  240. enum MappableKeyTransition
  241. {
  242. DOWN,
  243. UP,
  244. DOUBLEDOWN // if a key transition is repeated immediately, we generate this.
  245. };
  246. static const LookupListRec TransitionNames[] =
  247. {
  248. { "DOWN", DOWN },
  249. { "UP", UP },
  250. { "DOUBLEDOWN", DOUBLEDOWN },
  251. { NULL, 0 }// keep this last!
  252. };
  253. // -------------------------------------------------------------------------------
  254. // an easier-to-type subset of the KEY_STATE stuff.
  255. enum MappableKeyModState
  256. {
  257. NONE = 0,
  258. CTRL = KEY_STATE_LCONTROL,
  259. ALT = KEY_STATE_LALT,
  260. SHIFT = KEY_STATE_LSHIFT,
  261. CTRL_ALT = CTRL|ALT,
  262. SHIFT_CTRL = SHIFT|CTRL,
  263. SHIFT_ALT = SHIFT|ALT,
  264. SHIFT_ALT_CTRL = SHIFT|ALT|CTRL
  265. };
  266. static const LookupListRec ModifierNames[] =
  267. {
  268. { "NONE", NONE },
  269. { "CTRL", CTRL },
  270. { "ALT", ALT },
  271. { "SHIFT", SHIFT },
  272. { "CTRL_ALT", CTRL_ALT },
  273. { "SHIFT_CTRL", SHIFT_CTRL },
  274. { "SHIFT_ALT", SHIFT_ALT },
  275. { "SHIFT_ALT_CTRL" , SHIFT_ALT_CTRL },
  276. { NULL, 0 }// keep this last!
  277. };
  278. // -------------------------------------------------------------------------------
  279. // CommandUsableInType sets in what state the commands are allowed.
  280. enum CommandUsableInType
  281. {
  282. COMMANDUSABLE_NONE = 0,
  283. COMMANDUSABLE_SHELL = (1 << 0),
  284. COMMANDUSABLE_GAME = (1 << 1)
  285. };
  286. static const char* TheCommandUsableInNames[] =
  287. {
  288. "SHELL",
  289. "GAME",
  290. NULL
  291. };
  292. // -------------------------------------------------------------------------------
  293. class MetaMapRec : public MemoryPoolObject
  294. {
  295. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(MetaMapRec, "MetaMapRec")
  296. public:
  297. MetaMapRec* m_next;
  298. GameMessage::Type m_meta; ///< the meta-event to emit
  299. MappableKeyType m_key; ///< the key we want
  300. MappableKeyTransition m_transition; ///< the state of the key
  301. MappableKeyModState m_modState; ///< the required state of the ctrl-alt-shift keys
  302. CommandUsableInType m_usableIn; ///< the allowed place the command can be used in
  303. // Next fields are added for Key mapping Dialog
  304. MappableKeyCategories m_category; ///< This is the catagory the key falls under
  305. UnicodeString m_description; ///< The description string for the keys
  306. UnicodeString m_displayName; ///< The display name of our command
  307. };
  308. EMPTY_DTOR(MetaMapRec)
  309. //-----------------------------------------------------------------------------
  310. class MetaEventTranslator : public GameMessageTranslator
  311. {
  312. private:
  313. Int m_lastKeyDown; // really a MappableKeyType
  314. Int m_lastModState; // really a MappableKeyModState
  315. enum { NUM_MOUSE_BUTTONS = 3 };
  316. ICoord2D m_mouseDownPosition[NUM_MOUSE_BUTTONS];
  317. Bool m_nextUpShouldCreateDoubleClick[NUM_MOUSE_BUTTONS];
  318. public:
  319. MetaEventTranslator();
  320. ~MetaEventTranslator();
  321. virtual GameMessageDisposition translateGameMessage(const GameMessage *msg);
  322. };
  323. //-----------------------------------------------------------------------------
  324. class MetaMap : public SubsystemInterface
  325. {
  326. friend class MetaEventTranslator;
  327. private:
  328. MetaMapRec *m_metaMaps;
  329. protected:
  330. GameMessage::Type findGameMessageMetaType(const char* name);
  331. MetaMapRec *getMetaMapRec(GameMessage::Type t);
  332. public:
  333. MetaMap();
  334. ~MetaMap();
  335. void init() { }
  336. void reset() { }
  337. void update() { }
  338. static void parseMetaMap(INI* ini);
  339. const MetaMapRec *getFirstMetaMapRec() const { return m_metaMaps; }
  340. };
  341. extern MetaMap *TheMetaMap;
  342. #endif