input_PSP.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009, Pal_Bazzi.
  4. //
  5. // All rights reserved.
  6. //
  7. // This file is part of SDLPAL.
  8. //
  9. // SDLPAL is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation, either version 3 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. //
  22. #include "main.h"
  23. #ifdef PSP
  24. #include <math.h>
  25. #include <pspkernel.h>
  26. #include <pspctrl.h>
  27. #include <SDL_thread.h>
  28. PALINPUTSTATE g_InputState;
  29. BOOL g_fUseJoystick = TRUE;
  30. static SceCtrlData pad;
  31. static SDL_sem *pad_sem = 0;
  32. static SDL_Thread *bthread = 0;
  33. static int running = 0;
  34. static unsigned int old_button=0;
  35. static unsigned char old_x = 0, old_y = 0;
  36. //
  37. // Collect pad data about once per frame
  38. //
  39. int PSP_JoystickUpdate(void *data)
  40. {
  41. while (running)
  42. {
  43. SDL_SemWait(pad_sem);
  44. sceCtrlPeekBufferPositive(&pad, 1);
  45. SDL_SemPost(pad_sem);
  46. //
  47. // Delay 1/60th of a second
  48. //
  49. sceKernelDelayThread(1000000 / 60);
  50. }
  51. return 0;
  52. }
  53. void PAL_calc_Axes(
  54. unsigned char x,
  55. unsigned char y
  56. )
  57. {
  58. if(x<y && x+y<51)
  59. {
  60. g_InputState.dwKeyPress = kKeyLeft;
  61. g_InputState.prevdir = g_InputState.dir;
  62. g_InputState.dir = kDirWest;
  63. return;
  64. }
  65. if(x<y && x+y>51)
  66. {
  67. g_InputState.dwKeyPress = kKeyDown;
  68. g_InputState.prevdir = g_InputState.dir;
  69. g_InputState.dir = kDirSouth;
  70. return;
  71. }
  72. if(x>y && x+y<51)
  73. {
  74. g_InputState.dwKeyPress = kKeyUp;
  75. g_InputState.prevdir = g_InputState.dir;
  76. g_InputState.dir = kDirNorth;
  77. return;
  78. }
  79. if(x>y && x+y>51)
  80. {
  81. g_InputState.dwKeyPress = kKeyRight;
  82. g_InputState.prevdir = g_InputState.dir;
  83. g_InputState.dir = kDirEast;
  84. return;
  85. }
  86. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  87. g_InputState.dir = kDirUnknown;
  88. }
  89. VOID
  90. PAL_JoystickEventFilter(
  91. VOID
  92. )
  93. /*++
  94. Purpose:
  95. Handle joystick events.
  96. Parameters:
  97. None.
  98. Return value:
  99. None.
  100. --*/
  101. {
  102. unsigned int button;
  103. unsigned char x, y;
  104. SDL_SemWait(pad_sem);
  105. button = pad.Buttons;
  106. x = pad.Lx;
  107. y = pad.Ly;
  108. SDL_SemPost(pad_sem);
  109. //
  110. //Axes
  111. //
  112. x /= 5;
  113. y /= 5;
  114. BOOL onCenter=(x>16 && x<32) && (y>16 && y<32);
  115. if(!onCenter)
  116. {
  117. if(old_x != x || old_y != y)
  118. {
  119. PAL_calc_Axes(x,y);
  120. old_y = y;
  121. old_x = x;
  122. }
  123. }
  124. else if (!button)
  125. {
  126. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  127. g_InputState.dir = kDirUnknown;
  128. }
  129. //
  130. //Buttons
  131. //
  132. int changed = (button != old_button);
  133. old_button = button;
  134. if(changed)
  135. {
  136. if (button & PSP_CTRL_UP)
  137. {
  138. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  139. g_InputState.dir = kDirNorth;
  140. g_InputState.dwKeyPress = kKeyUp;
  141. return;
  142. }
  143. if (button & PSP_CTRL_DOWN)
  144. {
  145. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  146. g_InputState.dir = kDirSouth;
  147. g_InputState.dwKeyPress = kKeyDown;
  148. return;
  149. }
  150. if (button & PSP_CTRL_LEFT)
  151. {
  152. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  153. g_InputState.dir = kDirWest;
  154. g_InputState.dwKeyPress = kKeyLeft;
  155. return;
  156. }
  157. if (button & PSP_CTRL_RIGHT)
  158. {
  159. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  160. g_InputState.dir = kDirEast;
  161. g_InputState.dwKeyPress = kKeyRight;
  162. return;
  163. }
  164. if (button & PSP_CTRL_SQUARE)
  165. {
  166. g_InputState.dwKeyPress = kKeyForce;
  167. return;
  168. }
  169. if (button & PSP_CTRL_TRIANGLE)
  170. {
  171. g_InputState.dwKeyPress = kKeyThrowItem;
  172. return;
  173. }
  174. if (button & PSP_CTRL_CIRCLE)
  175. {
  176. g_InputState.dwKeyPress = kKeySearch;
  177. return;
  178. }
  179. if (button & PSP_CTRL_CROSS)
  180. {
  181. g_InputState.dwKeyPress = kKeyMenu;
  182. return;
  183. }
  184. if (button & PSP_CTRL_START)
  185. {
  186. g_InputState.dwKeyPress = kKeySearch;
  187. return;
  188. }
  189. if (button & PSP_CTRL_SELECT)
  190. {
  191. g_InputState.dwKeyPress = kKeyMenu;
  192. return;
  193. }
  194. if (button & PSP_CTRL_LTRIGGER)
  195. {
  196. g_InputState.dwKeyPress = kKeyUseItem;
  197. return;
  198. }
  199. if (button & PSP_CTRL_RTRIGGER)
  200. {
  201. g_InputState.dwKeyPress = kKeyRepeat;
  202. return;
  203. }
  204. g_InputState.prevdir = (gpGlobals->fInBattle ? kDirUnknown : g_InputState.dir);
  205. g_InputState.dir = kDirUnknown;
  206. }
  207. }
  208. #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION <= 2
  209. static int SDLCALL
  210. PAL_EventFilter(
  211. const SDL_Event *lpEvent
  212. )
  213. #else
  214. static int SDLCALL
  215. PAL_EventFilter(
  216. void *userdata,
  217. const SDL_Event *lpEvent
  218. )
  219. #endif
  220. /*++
  221. Purpose:
  222. SDL event filter function. A filter to process all events.
  223. Parameters:
  224. [IN] lpEvent - pointer to the event.
  225. Return value:
  226. 1 = the event will be added to the internal queue.
  227. 0 = the event will be dropped from the queue.
  228. --*/
  229. {
  230. switch (lpEvent->type)
  231. {
  232. case SDL_QUIT:
  233. //
  234. // clicked on the close button of the window. Quit immediately.
  235. //
  236. PAL_Shutdown();
  237. exit(0);
  238. }
  239. //
  240. // All events are handled here; don't put anything to the internal queue
  241. //
  242. return 0;
  243. }
  244. VOID
  245. PAL_ClearKeyState(
  246. VOID
  247. )
  248. /*++
  249. Purpose:
  250. Clear the record of pressed keys.
  251. Parameters:
  252. None.
  253. Return value:
  254. None.
  255. --*/
  256. {
  257. g_InputState.dwKeyPress = 0;
  258. }
  259. VOID
  260. PAL_InitInput(
  261. VOID
  262. )
  263. /*++
  264. Purpose:
  265. Initialize the input subsystem.
  266. Parameters:
  267. None.
  268. Return value:
  269. None.
  270. --*/
  271. {
  272. memset(&g_InputState, 0, sizeof(g_InputState));
  273. g_InputState.dir = kDirUnknown;
  274. g_InputState.prevdir = kDirUnknown;
  275. #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION <= 2
  276. SDL_SetEventFilter(PAL_EventFilter);
  277. #else
  278. SDL_SetEventFilter(PAL_EventFilter, NULL);
  279. #endif
  280. //
  281. // Setup input
  282. //
  283. sceCtrlSetSamplingCycle(0);
  284. sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
  285. pad.Buttons = 0;
  286. //
  287. // Start thread to read data
  288. //
  289. if((pad_sem = SDL_CreateSemaphore(1)) == NULL)
  290. {
  291. TerminateOnError("Can't create input semaphore\n");
  292. return;
  293. }
  294. running = 1;
  295. if((bthread = SDL_CreateThread(PSP_JoystickUpdate, NULL)) == NULL)
  296. {
  297. TerminateOnError("Can't create input thread\n");
  298. return;
  299. }
  300. }
  301. VOID
  302. PAL_ShutdownInput(
  303. VOID
  304. )
  305. /*++
  306. Purpose:
  307. Shutdown the input subsystem.
  308. Parameters:
  309. None.
  310. Return value:
  311. None.
  312. --*/
  313. {
  314. //
  315. // Cleanup Threads and Semaphore.
  316. //
  317. running = 0;
  318. SDL_WaitThread(bthread, NULL);
  319. SDL_DestroySemaphore(pad_sem);
  320. }
  321. VOID
  322. PAL_ProcessEvent(
  323. VOID
  324. )
  325. /*++
  326. Purpose:
  327. Process all events.
  328. Parameters:
  329. None.
  330. Return value:
  331. None.
  332. --*/
  333. {
  334. while (SDL_PollEvent(NULL));
  335. PAL_JoystickEventFilter();
  336. }
  337. #endif