No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

334 líneas
7.3 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdlib>
  14. #if defined USE_SDL
  15. # if defined HAVE_SDL_SDL_H
  16. # include <SDL/SDL.h>
  17. # else
  18. # include <SDL.h>
  19. # endif
  20. #endif
  21. #include "core.h"
  22. namespace lol
  23. {
  24. /*
  25. * Input implementation class
  26. */
  27. Array<ButtonSetting> Input::InputAssocationList;
  28. static class InputData
  29. {
  30. friend class Input;
  31. public:
  32. InputData()
  33. : mouse(-1),
  34. buttons(0),
  35. nentities(0),
  36. lastfocus(0)
  37. { }
  38. private:
  39. ivec2 mouse;
  40. ivec3 buttons;
  41. static int const MAX_ENTITIES = 100;
  42. WorldEntity *entities[MAX_ENTITIES];
  43. int nentities;
  44. WorldEntity *lastfocus;
  45. Array<Stick *> m_sticks;
  46. }
  47. inputdata;
  48. static InputData * const data = &inputdata;
  49. /*
  50. * Public Input class
  51. */
  52. #if 0
  53. vec2 Input::GetAxis(int axis)
  54. {
  55. vec2 ret;
  56. #if defined USE_SDL
  57. /* Simulate a joystick using the keyboard. This SDL call is free. */
  58. #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3
  59. Uint8 *keystate = SDL_GetKeyboardState(NULL);
  60. #else
  61. Uint8 *keystate = SDL_GetKeyState(NULL);
  62. #endif
  63. int left = keystate[SDLK_d] - (keystate[SDLK_a] | keystate[SDLK_q]);
  64. int up = (keystate[SDLK_w] | keystate[SDLK_z]) - keystate[SDLK_s] ;
  65. ret.x += left;
  66. ret.y += up;
  67. if (left && up)
  68. ret = ret * sqrtf(0.5f);
  69. #else
  70. ret = vec2(0, 0);
  71. #endif
  72. return ret;
  73. }
  74. #endif
  75. ivec2 Input::GetMousePos()
  76. {
  77. return data->mouse;
  78. }
  79. ivec3 Input::GetMouseButtons()
  80. {
  81. return data->buttons;
  82. }
  83. //BH : Added this, is a v0.1 Alpha version.
  84. int Input::GetButtonState(int button)
  85. {
  86. #if defined USE_SDL
  87. #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3
  88. Uint8 *keystate = SDL_GetKeyboardState(NULL);
  89. #else
  90. Uint8 *keystate = SDL_GetKeyState(NULL);
  91. #endif
  92. return keystate[button];
  93. #else
  94. return 0;
  95. #endif
  96. }
  97. //--
  98. //---
  99. //Internal : Updates the action status & timers
  100. void Input::UpdateActionStatus(float seconds)
  101. {
  102. for (int i = 0; i < InputAssocationList.Count(); i++)
  103. {
  104. ButtonSetting &CurIT = InputAssocationList[i];
  105. CurIT.PrevStatus = CurIT.CurStatus;
  106. CurIT.CurStatus = Input::GetButtonState(CurIT.RawButtonId);
  107. for (int j = 0; j < CurIT.AssociatedActionList.Count(); j++)
  108. {
  109. ActionSetting &CurAS = CurIT.AssociatedActionList[j];
  110. if (CurAS.BufferedSince <= CurAS.BufferingTime)
  111. CurAS.BufferedSince += seconds;
  112. if (CurIT.CurStatus && CurAS.BufferingTime >= .0f)
  113. CurAS.BufferedSince = .0f;
  114. }
  115. }
  116. }
  117. //Helps link a software input Action-Id to an hardware input Button-Id.
  118. void Input::LinkActionIdToButtonId(int ActionId, int ButtonId)
  119. {
  120. int ITIdx = GetButtonSettingIdx(ButtonId);
  121. if (ITIdx == -1)
  122. {
  123. ITIdx = InputAssocationList.Count();
  124. InputAssocationList << ButtonSetting(ButtonId);
  125. }
  126. ButtonSetting &CurIT = InputAssocationList[ITIdx];
  127. int ASIdx = CurIT.GetActionSettingIdx(ActionId);
  128. if (ASIdx == -1)
  129. {
  130. ASIdx = CurIT.AssociatedActionList.Count();
  131. CurIT.AssociatedActionList << ActionSetting(ActionId);
  132. }
  133. }
  134. //Helps unlink a software input Action-Id to an hardware input Button-Id.
  135. void Input::UnlinkActionId(int ActionId)
  136. {
  137. for (int i = 0; i < InputAssocationList.Count(); i++)
  138. {
  139. ButtonSetting &CurIT = InputAssocationList[i];
  140. int ASIdx = CurIT.GetActionSettingIdx(ActionId);
  141. if (ASIdx != -1)
  142. CurIT.AssociatedActionList.Remove(ASIdx);
  143. }
  144. }
  145. //Returns the current status of a given action
  146. int Input::GetActionStatus(int ActionId)
  147. {
  148. for (int i = 0; i < InputAssocationList.Count(); i++)
  149. {
  150. ButtonSetting &CurIT = InputAssocationList[i];
  151. int ASIdx = CurIT.GetActionSettingIdx(ActionId);
  152. if (ASIdx != -1)
  153. {
  154. ActionSetting &CurAS = CurIT.AssociatedActionList[ASIdx];
  155. if (CurAS.BufferingTime >= .0f && CurAS.BufferedSince <= CurAS.BufferingTime)
  156. return 1;
  157. return 0;
  158. }
  159. }
  160. return 0;
  161. }
  162. //Returns TRUE if action status when from Active to Inactive this frame
  163. bool Input::WasActionJustReleased(int ActionId)
  164. {
  165. for (int i = 0; i < InputAssocationList.Count(); i++)
  166. {
  167. ButtonSetting &CurIT = InputAssocationList[i];
  168. int ASIdx = CurIT.GetActionSettingIdx(ActionId);
  169. if (ASIdx != -1)
  170. {
  171. if (!CurIT.CurStatus && CurIT.PrevStatus)
  172. return TRUE;
  173. return FALSE;
  174. }
  175. }
  176. return FALSE;
  177. }
  178. //--
  179. void Input::TrackMouse(WorldEntity *e)
  180. {
  181. if (data->nentities >= InputData::MAX_ENTITIES)
  182. return;
  183. data->entities[data->nentities] = e;
  184. data->nentities++;
  185. }
  186. void Input::UntrackMouse(WorldEntity *e)
  187. {
  188. for (int n = 0; n < data->nentities; n++)
  189. {
  190. if (data->entities[n] != e)
  191. continue;
  192. data->entities[n] = data->entities[data->nentities - 1];
  193. data->nentities--;
  194. n--;
  195. }
  196. }
  197. void Input::SetMousePos(ivec2 coord)
  198. {
  199. data->mouse = coord;
  200. WorldEntity *top = NULL;
  201. for (int n = 0; n < data->nentities; n++)
  202. {
  203. if (coord.x < data->entities[n]->m_bbox[0].x
  204. || coord.x >= data->entities[n]->m_bbox[1].x
  205. || coord.y < data->entities[n]->m_bbox[0].y
  206. || coord.y >= data->entities[n]->m_bbox[1].y)
  207. continue;
  208. if (!top || top->m_bbox[1].z < data->entities[n]->m_bbox[1].z)
  209. top = data->entities[n];
  210. }
  211. for (int n = 0; n < data->nentities; n++)
  212. {
  213. if (data->entities[n] == top)
  214. {
  215. data->entities[n]->m_mousepos = coord - (ivec2)top->m_bbox[0].xy;
  216. if (top != data->lastfocus)
  217. data->entities[n]->m_pressed = data->buttons;
  218. else
  219. data->entities[n]->m_clicked = ivec3(0);
  220. }
  221. else
  222. {
  223. data->entities[n]->m_mousepos = ivec2(-1);
  224. /* FIXME */
  225. data->entities[n]->m_released = ivec3(0);
  226. data->entities[n]->m_pressed = ivec3(0);
  227. data->entities[n]->m_clicked = ivec3(0);
  228. }
  229. }
  230. data->lastfocus = top;
  231. }
  232. void Input::SetMouseButton(int index)
  233. {
  234. data->buttons[index] = 1;
  235. if (data->lastfocus)
  236. {
  237. if (!data->lastfocus->m_pressed[index])
  238. data->lastfocus->m_clicked[index] = 1;
  239. data->lastfocus->m_pressed[index] = 1;
  240. data->lastfocus->m_released[index] = 0;
  241. }
  242. }
  243. void Input::UnsetMouseButton(int index)
  244. {
  245. data->buttons[index] = 0;
  246. if (data->lastfocus)
  247. {
  248. if (data->lastfocus->m_pressed[index])
  249. data->lastfocus->m_released[index] = 1;
  250. data->lastfocus->m_pressed[index] = 0;
  251. data->lastfocus->m_clicked[index] = 0;
  252. }
  253. }
  254. Stick *Input::CreateStick()
  255. {
  256. Stick *stick = new Stick();
  257. Ticker::Ref(stick);
  258. data->m_sticks.Push(stick);
  259. return stick;
  260. }
  261. void Input::DestroyStick(Stick *stick)
  262. {
  263. for (int i = 0; i < data->m_sticks.Count(); i++)
  264. if (data->m_sticks[i] == stick)
  265. data->m_sticks.Remove(i);
  266. Ticker::Unref(stick);
  267. }
  268. Stick *Input::TrackStick(int desired)
  269. {
  270. /* FIXME: add the possibility to choose amongst sticks */
  271. if (desired >= data->m_sticks.Count())
  272. return NULL;
  273. Ticker::Ref(data->m_sticks[desired]);
  274. return data->m_sticks[desired];
  275. }
  276. void Input::UntrackStick(Stick *stick)
  277. {
  278. Ticker::Unref(stick);
  279. }
  280. } /* namespace lol */