input_PSP.c 7.0 KB

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