wrap_JoystickModule.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /**
  2. * Copyright (c) 2006-2013 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "wrap_JoystickModule.h"
  21. #include "wrap_Joystick.h"
  22. namespace love
  23. {
  24. namespace joystick
  25. {
  26. namespace sdl
  27. {
  28. static JoystickModule *instance = 0;
  29. int w_getJoysticks(lua_State *L)
  30. {
  31. int stickcount = instance->getJoystickCount();
  32. lua_createtable(L, stickcount, 0);
  33. for (int i = 0; i < stickcount; i++)
  34. {
  35. love::joystick::Joystick *stick = instance->getJoystick(i);
  36. stick->retain();
  37. luax_pushtype(L, "Joystick", JOYSTICK_JOYSTICK_T, stick);
  38. lua_rawseti(L, -2, i + 1);
  39. }
  40. return 1;
  41. }
  42. int w_getIndex(lua_State *L)
  43. {
  44. love::joystick::Joystick *j = luax_checkjoystick(L, 1);
  45. int index = instance->getIndex(j);
  46. if (index >= 0)
  47. lua_pushinteger(L, index + 1);
  48. else
  49. lua_pushnil(L);
  50. return 1;
  51. }
  52. int w_getJoystickCount(lua_State *L)
  53. {
  54. lua_pushinteger(L, instance->getJoystickCount());
  55. return 1;
  56. }
  57. int w_setGamepadMapping(lua_State *L)
  58. {
  59. // Only accept a GUID string. We don't accept a Joystick object because
  60. // the gamepad mapping applies to all joysticks with the same GUID (e.g. all
  61. // Xbox 360 controllers on the system), rather than individual objects.
  62. std::string guid = luax_checkstring(L, 1);
  63. const char *gpbindstr = luaL_checkstring(L, 2);
  64. Joystick::GamepadInput gpinput;
  65. if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis))
  66. gpinput.type = Joystick::INPUT_TYPE_AXIS;
  67. else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button))
  68. gpinput.type = Joystick::INPUT_TYPE_BUTTON;
  69. else
  70. return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
  71. const char *jinputtypestr = luaL_checkstring(L, 3);
  72. Joystick::JoystickInput jinput;
  73. if (!love::joystick::Joystick::getConstant(jinputtypestr, jinput.type))
  74. return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr);
  75. const char *hatstr;
  76. switch (jinput.type)
  77. {
  78. case Joystick::INPUT_TYPE_AXIS:
  79. jinput.axis = luaL_checkint(L, 4) - 1;
  80. break;
  81. case Joystick::INPUT_TYPE_BUTTON:
  82. jinput.button = luaL_checkint(L, 4) - 1;
  83. break;
  84. case Joystick::INPUT_TYPE_HAT:
  85. // Hats need both a hat index and a hat value.
  86. jinput.hat.index = luaL_checkint(L, 4) - 1;
  87. hatstr = luaL_checkstring(L, 5);
  88. if (!love::joystick::Joystick::getConstant(hatstr, jinput.hat.value))
  89. return luaL_error(L, "Invalid joystick hat: %s", hatstr);
  90. break;
  91. default:
  92. return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr);
  93. }
  94. bool success = false;
  95. try
  96. {
  97. success = instance->setGamepadMapping(guid, gpinput, jinput);
  98. }
  99. catch (love::Exception &e)
  100. {
  101. return luaL_error(L, "%s", e.what());
  102. }
  103. luax_pushboolean(L, success);
  104. return 1;
  105. }
  106. int w_getGamepadMapping(lua_State *L)
  107. {
  108. std::string guid;
  109. // Accept either a GUID string or a Joystick object. This way we can re-use
  110. // the function for Joystick:getGamepadMapping.
  111. if (lua_type(L, 1) == LUA_TSTRING)
  112. guid = luax_checkstring(L, 1);
  113. else
  114. {
  115. love::joystick::Joystick *stick = luax_checkjoystick(L, 1);
  116. guid = stick->getProductGUID();
  117. }
  118. const char *gpbindstr = luaL_checkstring(L, 2);
  119. Joystick::GamepadInput gpinput;
  120. if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis))
  121. gpinput.type = Joystick::INPUT_TYPE_AXIS;
  122. else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button))
  123. gpinput.type = Joystick::INPUT_TYPE_BUTTON;
  124. else
  125. return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
  126. Joystick::JoystickInput jinput;
  127. jinput.type = Joystick::INPUT_TYPE_MAX_ENUM;
  128. try
  129. {
  130. jinput = instance->getGamepadMapping(guid, gpinput);
  131. }
  132. catch (love::Exception &e)
  133. {
  134. return luaL_error(L, "%s", e.what());
  135. }
  136. if (jinput.type == Joystick::INPUT_TYPE_MAX_ENUM)
  137. return 0;
  138. const char *inputtypestr;
  139. if (!love::joystick::Joystick::getConstant(jinput.type, inputtypestr))
  140. return luaL_error(L, "Unknown joystick input type.");
  141. lua_pushstring(L, inputtypestr);
  142. const char *hatstr;
  143. switch (jinput.type)
  144. {
  145. case Joystick::INPUT_TYPE_AXIS:
  146. lua_pushinteger(L, jinput.axis + 1);
  147. return 2;
  148. case Joystick::INPUT_TYPE_BUTTON:
  149. lua_pushinteger(L, jinput.button + 1);
  150. return 2;
  151. case Joystick::INPUT_TYPE_HAT:
  152. lua_pushinteger(L, jinput.hat.index + 1);
  153. if (love::joystick::Joystick::getConstant(jinput.hat.value, hatstr))
  154. {
  155. lua_pushstring(L, hatstr);
  156. return 3;
  157. }
  158. else
  159. return luaL_error(L, "Unknown joystick hat.");
  160. default:
  161. break; // ?
  162. }
  163. return 1;
  164. }
  165. // List of functions to wrap.
  166. static const luaL_Reg functions[] =
  167. {
  168. { "getJoysticks", w_getJoysticks },
  169. { "getJoystickCount", w_getJoystickCount },
  170. { "setGamepadMapping", w_setGamepadMapping },
  171. { "getGamepadMapping", w_getGamepadMapping },
  172. { 0, 0 }
  173. };
  174. static const lua_CFunction types[] =
  175. {
  176. luaopen_joystick,
  177. 0,
  178. };
  179. extern "C" int luaopen_love_joystick(lua_State *L)
  180. {
  181. if (instance == 0)
  182. {
  183. try
  184. {
  185. instance = new JoystickModule();
  186. }
  187. catch (Exception &e)
  188. {
  189. return luaL_error(L, e.what());
  190. }
  191. }
  192. else
  193. instance->retain();
  194. WrappedModule w;
  195. w.module = instance;
  196. w.name = "joystick";
  197. w.flags = MODULE_T;
  198. w.functions = functions;
  199. w.types = types;
  200. return luax_register_module(L, w);
  201. }
  202. } // sdl
  203. } // joystick
  204. } // love