Advertisement
Guest User

fpse

a guest
Sep 13th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.31 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <strings.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <exec/memory.h>
  8.  
  9. #include <devices/input.h>
  10. #include <devices/inputevent.h>
  11.  
  12. #include <proto/exec.h>
  13. #include <proto/dos.h>
  14. #include <proto/intuition.h>
  15. #include <proto/graphics.h>
  16. #include <proto/muimaster.h>
  17. #include <proto/lowlevel.h>
  18.  
  19. #if defined(__AROS__) || defined (__morphos__)
  20. #include <proto/alib.h>
  21. #endif
  22.  
  23. #ifndef MAKE_ID
  24. #define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
  25. #endif
  26.  
  27. #include "amidog/rawkey.h"
  28.  
  29. #include "plugin.h"
  30.  
  31. #define KEYNAME "JOYLL"
  32. static char ininame[16];
  33.  
  34. #include "version.h"
  35.  
  36. static FPSEAmigaAbout info = {
  37. FPSE_IFACE_MAGIC,
  38. FPSE_IFACE_VERSION,
  39. FPSE_JOY,
  40. "joyll",
  41. (char *)VERSION,
  42. "AmiDog",
  43. "LowLevel JOY plugin.",
  44. };
  45.  
  46. //-----------------------------------------------------------------
  47.  
  48. static int DummyPoll(int outbyte)
  49. {
  50. return ACK_OK;
  51. }
  52.  
  53. #define ANALOG_MIN (0x00)
  54. #define ANALOG_MAX (0xFF)
  55. #define ANALOG_MID (0x7F)
  56.  
  57. static UINT32 joy_ret = 0xffffffff;
  58. static UINT8 left_analog_x = ANALOG_MID;
  59. static UINT8 left_analog_y = ANALOG_MID;
  60. static UINT8 right_analog_x = ANALOG_MID;
  61. static UINT8 right_analog_y = ANALOG_MID;
  62. static UINT8 *padbuf0 = NULL;
  63. static int (*CmdPoll)(int) = DummyPoll;
  64. static int padcnt = 0;
  65.  
  66. static int NormalPoll(int outbyte);
  67. static int Cmd46Poll_Analog(int outbyte);
  68. static int Cmd46Poll_Digital(int outbyte);
  69. static int Cmd4CPoll(int outbyte);
  70. static int FirstPoll(int outbyte);
  71.  
  72. static int JOY_Device = 0;
  73.  
  74. #define DIGITAL_UP (12)
  75. #define DIGITAL_DOWN (14)
  76. #define DIGITAL_LEFT (15)
  77. #define DIGITAL_RIGHT (13)
  78. #define DIGITAL_START (11)
  79. #define DIGITAL_SELECT (8)
  80. #define DIGITAL_TRIANGLE (4)
  81. #define DIGITAL_CROSS (6)
  82. #define DIGITAL_SQUARE (7)
  83. #define DIGITAL_CIRCLE (5)
  84. #define DIGITAL_L1 (2)
  85. #define DIGITAL_L2 (0)
  86. #define DIGITAL_R1 (3)
  87. #define DIGITAL_R2 (1)
  88. #define DIGITAL_L3 (9)
  89. #define DIGITAL_R3 (10)
  90.  
  91. #define ANALOG_MODE (16)
  92. #define ANALOG_LEFT_UP (17)
  93. #define ANALOG_LEFT_DOWN (18)
  94. #define ANALOG_LEFT_LEFT (19)
  95. #define ANALOG_LEFT_RIGHT (20)
  96. #define ANALOG_RIGHT_UP (21)
  97. #define ANALOG_RIGHT_DOWN (22)
  98. #define ANALOG_RIGHT_LEFT (23)
  99. #define ANALOG_RIGHT_RIGHT (24)
  100.  
  101. #define TYPE_NONE (0)
  102. #define TYPE_BUTTON (1)
  103.  
  104. #define DEFAULT_LLPORT_A (1)
  105. #define DEFAULT_LLPORT_B (3)
  106.  
  107. static struct keysym_type {
  108. char *label;
  109. int bitnum;
  110. int rawkey;
  111. int type;
  112. unsigned int mask_a;
  113. unsigned int mask_b;
  114. } keysym[] = {
  115. /* Digital */
  116. { "Up", 12, KEY_UP, TYPE_BUTTON, JPF_JOY_UP, 0 },
  117. { "Down", 14, KEY_DOWN, TYPE_BUTTON, JPF_JOY_DOWN, 0 },
  118. { "Left", 15, KEY_LEFT, TYPE_BUTTON, JPF_JOY_LEFT, 0 },
  119. { "Right", 13, KEY_RIGHT, TYPE_BUTTON, JPF_JOY_RIGHT, 0 },
  120. { "Start", 11, KEY_ENTER, TYPE_BUTTON, JPF_BUTTON_PLAY, 0 },
  121. { "Select", 8, KEY_TAB, TYPE_NONE, 0, JPF_BUTTON_PLAY },
  122. { "Triangle", 4, KEY_E, TYPE_BUTTON, JPF_BUTTON_YELLOW, 0 },
  123. { "Cross", 6, KEY_X, TYPE_BUTTON, JPF_BUTTON_RED, 0 },
  124. { "Square", 7, KEY_S, TYPE_BUTTON, JPF_BUTTON_GREEN, 0 },
  125. { "Circle", 5, KEY_F, TYPE_BUTTON, JPF_BUTTON_BLUE, 0 },
  126. { "L1", 2, KEY_Q, TYPE_BUTTON, JPF_BUTTON_REVERSE, 0 },
  127. { "L2", 0, KEY_W, TYPE_NONE, 0, JPF_BUTTON_REVERSE },
  128. { "R1", 3, KEY_R, TYPE_BUTTON, JPF_BUTTON_FORWARD, 0 },
  129. { "R2", 1, KEY_T, TYPE_NONE, 0, JPF_BUTTON_FORWARD },
  130. /* Analog */
  131. { "Analog", ANALOG_MODE, 0 /* ~ */, TYPE_NONE, 0, 0 },
  132. { "LeftAnalogUp", ANALOG_LEFT_UP, KEY_U, TYPE_NONE, 0, 0 },
  133. { "LeftAnalogDown", ANALOG_LEFT_DOWN, KEY_N, TYPE_NONE, 0, 0 },
  134. { "LeftAnalogLeft", ANALOG_LEFT_LEFT, KEY_H, TYPE_NONE, 0, 0 },
  135. { "LeftAnalogRight", ANALOG_LEFT_RIGHT, KEY_K, TYPE_NONE, 0, 0 },
  136. { "LeftAnalogPress", 9, KEY_J, TYPE_NONE, 0, 0 },
  137. { "RightAnalogUp", ANALOG_RIGHT_UP, 26 /* : */, TYPE_NONE, 0, 0 },
  138. { "RightAnalogDown", ANALOG_RIGHT_DOWN, 58 /* / */, TYPE_NONE, 0, 0 },
  139. { "RightAnalogLeft", ANALOG_RIGHT_LEFT, 41 /* [ */, TYPE_NONE, 0, 0 },
  140. { "RightAnalogRight", ANALOG_RIGHT_RIGHT, 43 /* * */, TYPE_NONE, 0, 0 },
  141. { "RightAnalogPress", 10, 42 /* ] */, TYPE_NONE, 0, 0 },
  142. };
  143.  
  144. #define NUM_KEYSYM ((int)( (sizeof(keysym)) / (sizeof(struct keysym_type)) ))
  145.  
  146. static int ll_port_a = DEFAULT_LLPORT_A;
  147. static int ll_port_b = DEFAULT_LLPORT_B;
  148.  
  149. static const char *lowlevel_name[] = {
  150. "-",
  151. "A - JOY UP",
  152. "A - JOY DOWN",
  153. "A - JOY LEFT",
  154. "A - JOY RIGHT",
  155. "A - BUTTON GREEN",
  156. "A - BUTTON YELLOW",
  157. "A - BUTTON RED",
  158. "A - BUTTON BLUE",
  159. "A - BUTTON FORWARD",
  160. "A - BUTTON REVERSE",
  161. "A - BUTTON PLAY",
  162. "B - JOY UP",
  163. "B - JOY DOWN",
  164. "B - JOY LEFT",
  165. "B - JOY RIGHT",
  166. "B - BUTTON GREEN",
  167. "B - BUTTON YELLOW",
  168. "B - BUTTON RED",
  169. "B - BUTTON BLUE",
  170. "B - BUTTON FORWARD",
  171. "B - BUTTON REVERSE",
  172. "B - BUTTON PLAY",
  173. NULL
  174. };
  175.  
  176. static const ULONG lowlevel_mask[] = {
  177. 0,
  178. JPF_JOY_UP,
  179. JPF_JOY_DOWN,
  180. JPF_JOY_LEFT,
  181. JPF_JOY_RIGHT,
  182. JPF_BUTTON_GREEN,
  183. JPF_BUTTON_YELLOW,
  184. JPF_BUTTON_RED,
  185. JPF_BUTTON_BLUE,
  186. JPF_BUTTON_FORWARD,
  187. JPF_BUTTON_REVERSE,
  188. JPF_BUTTON_PLAY,
  189. JPF_JOY_UP,
  190. JPF_JOY_DOWN,
  191. JPF_JOY_LEFT,
  192. JPF_JOY_RIGHT,
  193. JPF_BUTTON_GREEN,
  194. JPF_BUTTON_YELLOW,
  195. JPF_BUTTON_RED,
  196. JPF_BUTTON_BLUE,
  197. JPF_BUTTON_FORWARD,
  198. JPF_BUTTON_REVERSE,
  199. JPF_BUTTON_PLAY
  200. };
  201.  
  202. #define NUM_LOWLEVEL ((int)( (sizeof(lowlevel_mask)) / (sizeof(ULONG)) ))
  203.  
  204. static int mask_to_index(ULONG mask_a, ULONG mask_b)
  205. {
  206. ULONG i;
  207. for (i=0; i<NUM_LOWLEVEL; i++) {
  208. if ((i <= 11) && (lowlevel_mask[i] & mask_a)) {
  209. return i;
  210. }
  211. if ((i >= 12) && (lowlevel_mask[i] & mask_b)) {
  212. return i;
  213. }
  214. }
  215. return 0;
  216. }
  217.  
  218. void read_cfg(UINT32 *par)
  219. {
  220. FPSEAmiga *spu = (FPSEAmiga *)par;
  221. char tmp[256];
  222. int i;
  223.  
  224. strcpy(ininame, KEYNAME);
  225. strcat(ininame, "_");
  226. strcat(ininame, (char *)((FPSEAmiga *)par)->PadNr);
  227.  
  228. if (spu->ReadCfg(ininame, "PortA", tmp) == FPSE_OK) {
  229. ll_port_a = atoi(tmp);
  230. if ((ll_port_a < 0) || (ll_port_a > 3)) {
  231. ll_port_a = DEFAULT_LLPORT_A;
  232. }
  233. }
  234.  
  235. if (spu->ReadCfg(ininame, "PortB", tmp) == FPSE_OK) {
  236. ll_port_b = atoi(tmp);
  237. if ((ll_port_b < 0) || (ll_port_b > 3)) {
  238. ll_port_b = DEFAULT_LLPORT_B;
  239. }
  240. }
  241.  
  242. for (i=0; i<NUM_KEYSYM; i++) {
  243. if (spu->ReadCfg(ininame, keysym[i].label, tmp) == FPSE_OK) {
  244. sscanf(tmp, "%d,%d,%d,%d", &keysym[i].type, &keysym[i].rawkey, &keysym[i].mask_a, &keysym[i].mask_b);
  245. }
  246. }
  247. }
  248.  
  249. void write_cfg(UINT32 *par)
  250. {
  251. FPSEAmiga *spu = (FPSEAmiga *)par;
  252. char tmp[256];
  253. int i;
  254.  
  255. strcpy(ininame, KEYNAME);
  256. strcat(ininame, "_");
  257. strcat(ininame, (char *)((FPSEAmiga *)par)->PadNr);
  258.  
  259. sprintf(tmp, "%d", ll_port_a);
  260. spu->WriteCfg(ininame, "PortA", tmp);
  261.  
  262. sprintf(tmp, "%d", ll_port_b);
  263. spu->WriteCfg(ininame, "PortB", tmp);
  264.  
  265. for (i=0; i<NUM_KEYSYM; i++) {
  266. sprintf(tmp, "%d,%d,%d,%d", keysym[i].type, keysym[i].rawkey, keysym[i].mask_a, keysym[i].mask_b);
  267. spu->WriteCfg(ininame, keysym[i].label, tmp);
  268. }
  269. }
  270.  
  271. #ifdef __morphos__
  272. static struct InputEvent *_MyInputHandler(void);
  273. static const struct EmulLibEntry gate_MyInputHandler = {
  274. TRAP_LIB,
  275. 0,
  276. (void (*)(void))_MyInputHandler}, *MyInputHandler = &gate_MyInputHandler;
  277.  
  278. static struct InputEvent *_MyInputHandler(void)
  279. {
  280. struct InputEvent *event_list = (APTR) REG_A0;
  281. #else
  282. struct InputEvent *MyInputHandler(REG(a0, struct InputEvent *event_list))
  283. {
  284. #endif
  285. #define JOY_SET_BIT(bitnum) ( ((joy_ret) & (1<<(bitnum))) ? (1) : (0) )
  286.  
  287. struct InputEvent *event;
  288.  
  289. for (event = event_list; event; event = event->ie_NextEvent) {
  290. if (event->ie_Class == IECLASS_RAWKEY) {
  291. int i;
  292. for(i=0;i<NUM_KEYSYM;i++) {
  293. if (keysym[i].rawkey == (event->ie_Code & 0x7f)) {
  294. if (!(event->ie_Code & IECODE_UP_PREFIX)) {
  295. joy_ret &= ~(1<<keysym[i].bitnum);
  296. } else {
  297. joy_ret |= (1<<keysym[i].bitnum);
  298. }
  299.  
  300. switch (keysym[i].bitnum) {
  301. case ANALOG_MODE:
  302. if (event->ie_Code & IECODE_UP_PREFIX) {
  303. if (JOY_Device == 0x73) {
  304. JOY_Device = 0x41;
  305. } else {
  306. JOY_Device = 0x73;
  307. }
  308. }
  309. break;
  310.  
  311. case ANALOG_LEFT_UP:
  312. case ANALOG_LEFT_DOWN:
  313. left_analog_y = (JOY_SET_BIT(ANALOG_LEFT_UP) == JOY_SET_BIT(ANALOG_LEFT_DOWN)) ? ANALOG_MID : JOY_SET_BIT(ANALOG_LEFT_UP) ? ANALOG_MAX : ANALOG_MIN;
  314. break;
  315.  
  316. case ANALOG_LEFT_LEFT:
  317. case ANALOG_LEFT_RIGHT:
  318. left_analog_x = (JOY_SET_BIT(ANALOG_LEFT_LEFT) == JOY_SET_BIT(ANALOG_LEFT_RIGHT)) ? ANALOG_MID : JOY_SET_BIT(ANALOG_LEFT_LEFT) ? ANALOG_MAX : ANALOG_MIN;
  319. break;
  320.  
  321. case ANALOG_RIGHT_UP:
  322. case ANALOG_RIGHT_DOWN:
  323. right_analog_y = (JOY_SET_BIT(ANALOG_RIGHT_UP) == JOY_SET_BIT(ANALOG_RIGHT_DOWN)) ? ANALOG_MID : JOY_SET_BIT(ANALOG_RIGHT_UP) ? ANALOG_MAX : ANALOG_MIN;
  324. break;
  325.  
  326. case ANALOG_RIGHT_LEFT:
  327. case ANALOG_RIGHT_RIGHT:
  328. right_analog_x = (JOY_SET_BIT(ANALOG_RIGHT_LEFT) == JOY_SET_BIT(ANALOG_RIGHT_RIGHT)) ? ANALOG_MID : JOY_SET_BIT(ANALOG_RIGHT_LEFT) ? ANALOG_MAX : ANALOG_MIN;
  329. break;
  330.  
  331. default:
  332. break;
  333. }
  334. }
  335. }
  336. }
  337. }
  338.  
  339. return event_list;
  340.  
  341. #undef JOY_SET_BIT
  342. }
  343.  
  344. static struct IOStdReq *inputReqBlk = NULL;
  345. static struct MsgPort *inputPort = NULL;
  346. static struct Interrupt *inputHandler = NULL;
  347. static char HandlerName[50];
  348. static int input_error = -1;
  349.  
  350. void rem_inputhandler(void)
  351. {
  352. if (!input_error) {
  353. inputReqBlk->io_Data=(APTR)inputHandler;
  354. inputReqBlk->io_Command=IND_REMHANDLER;
  355. DoIO((struct IORequest *)inputReqBlk);
  356. CloseDevice((struct IORequest *)inputReqBlk);
  357. input_error = -1;
  358. }
  359.  
  360. if (inputReqBlk) {
  361. DeleteIORequest((struct IORequest *)inputReqBlk);
  362. inputReqBlk = NULL;
  363. }
  364.  
  365. if (inputHandler) {
  366. FreeMem(inputHandler, sizeof(struct Interrupt));
  367. inputHandler = NULL;
  368. }
  369.  
  370. if (inputPort) {
  371. DeleteMsgPort(inputPort);
  372. inputPort = NULL;
  373. }
  374. }
  375.  
  376. int add_inputhandler(void)
  377. {
  378. sprintf(HandlerName, "input handler:%08x", (int)FindTask(NULL));
  379. if ((inputPort = CreateMsgPort())) {
  380. if ((inputHandler = (struct Interrupt *)AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC|MEMF_CLEAR))) {
  381. if ((inputReqBlk = (struct IOStdReq *)CreateIORequest(inputPort, sizeof(struct IOStdReq)))) {
  382. if (!(input_error = OpenDevice("input.device", 0, (struct IORequest *)inputReqBlk, 0))) {
  383. inputHandler->is_Code = (void *)MyInputHandler;
  384. inputHandler->is_Data = NULL;
  385. inputHandler->is_Node.ln_Pri = 100;
  386. inputHandler->is_Node.ln_Name = HandlerName;
  387. inputReqBlk->io_Data = (APTR)inputHandler;
  388. inputReqBlk->io_Command = IND_ADDHANDLER;
  389. DoIO((struct IORequest *)inputReqBlk);
  390. }
  391. }
  392. }
  393. }
  394.  
  395. if (!input_error) {
  396. return 0;
  397. } else {
  398. rem_inputhandler();
  399. return -1;
  400. }
  401. }
  402.  
  403. // This Function is called when emulator starts
  404. int JOY_Open(UINT32 *par)
  405. {
  406. /* Device type */
  407. JOY_Device = 0x41;
  408.  
  409. read_cfg(par);
  410.  
  411. if (add_inputhandler()) {
  412. return FPSE_ERR;
  413. }
  414.  
  415. /* Force CD32 pad */
  416. SetJoyPortAttrs(ll_port_a, SJA_Type, SJA_TYPE_GAMECTLR, TAG_END);
  417. SetJoyPortAttrs(ll_port_b, SJA_Type, SJA_TYPE_GAMECTLR, TAG_END);
  418.  
  419. return FPSE_OK;
  420. }
  421.  
  422. static int get_key(int *keycode, ULONG *mask_a, ULONG *mask_b)
  423. {
  424. static const char *window_text = "Press desired key/button, move stick or press ESC for no key.";
  425. struct Window *window;
  426. int done = 0;
  427.  
  428. *keycode = -1; /* no key */
  429. *mask_a = 0; /* no button */
  430. *mask_b = 0; /* no button */
  431.  
  432. window = OpenWindowTags(NULL,
  433. WA_Title, (ULONG)"",
  434. WA_Flags, WFLG_NOCAREREFRESH|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_RMBTRAP|WFLG_GIMMEZEROZERO,
  435. WA_IDCMP, IDCMP_CLOSEWINDOW|WFLG_REPORTMOUSE|IDCMP_RAWKEY|IDCMP_CHANGEWINDOW,
  436. WA_Left, 100,
  437. WA_Top, 100,
  438. WA_Width, 100,
  439. WA_Height, 40,
  440. WA_Activate, TRUE,
  441. TAG_DONE);
  442.  
  443. if (window != NULL) {
  444. struct IntuiMessage *imsg = NULL;
  445. ULONG imCode, imClass, portstate_a, portstate_b;
  446.  
  447. /* Resize window and set pens */
  448. int length = TextLength(window->RPort, window_text, strlen(window_text));
  449. ChangeWindowBox(window, 100, 100, window->BorderLeft+length+window->BorderRight+8, window->BorderTop+window->IFont->tf_YSize*2+window->BorderBottom);
  450. SetAPen(window->RPort, 1);
  451. SetBPen(window->RPort, 0);
  452.  
  453. /* Wait until window has been resized */
  454. while (done == 0) {
  455. /* Sleep a little */
  456. Delay(1);
  457.  
  458. /* Check for IDCMP messages */
  459. while ((imsg = (struct IntuiMessage *)GetMsg(window->UserPort))) {
  460. imClass = imsg->Class;
  461. imCode = imsg->Code;
  462.  
  463. ReplyMsg((struct Message *)imsg);
  464.  
  465. if (imClass == IDCMP_CHANGEWINDOW) {
  466. Move(window->RPort, 4, window->IFont->tf_YSize);
  467. Text(window->RPort, window_text, strlen(window_text));
  468. }
  469. else if (imClass == IDCMP_RAWKEY) {
  470. imCode &= 0x7f;
  471. if (imCode != 69) {
  472. *keycode = imCode;
  473. }
  474. done = 1; /* ok */
  475. }
  476. else if (imClass == IDCMP_CLOSEWINDOW) {
  477. done = -1; /* cancel */
  478. }
  479. }
  480.  
  481. /* Check for LowLevel input */
  482. portstate_a = ReadJoyPort(ll_port_a);
  483. portstate_b = ReadJoyPort(ll_port_b);
  484. if (portstate_a & (JP_BUTTON_MASK | JP_DIRECTION_MASK))
  485. {
  486. *mask_a = portstate_a;
  487. done = 2; /* lowlevel */
  488. }
  489. if (portstate_b & (JP_BUTTON_MASK | JP_DIRECTION_MASK))
  490. {
  491. *mask_b = portstate_b;
  492. done = 2; /* lowlevel */
  493. }
  494. }
  495. CloseWindow(window);
  496. }
  497.  
  498. return done;
  499. }
  500.  
  501. int JOY_Configure(UINT32 *par)
  502. {
  503. BOOL running = TRUE;
  504. ULONG signals;
  505.  
  506. #define BTN_OK (32)
  507. #define PORT_CHANGE_A (33)
  508. #define PORT_CHANGE_B (34)
  509.  
  510. APTR label, text[NUM_KEYSYM], button, app, main_group, window, ok, cancel, Oport_a, Oport_b, Oinput[NUM_KEYSYM];
  511. char *CY_PortContent[5];
  512.  
  513. CY_PortContent[0] = "0";
  514. CY_PortContent[1] = "1";
  515. CY_PortContent[2] = "2";
  516. CY_PortContent[3] = "3";
  517. CY_PortContent[4] = NULL;
  518.  
  519. read_cfg(par);
  520.  
  521. app = ApplicationObject,
  522. MUIA_Application_Author, "Mathias Roslund",
  523. MUIA_Application_Base, KEYNAME,
  524. MUIA_Application_Title, KEYNAME,
  525. MUIA_Application_Version, VERSTAG,
  526. MUIA_Application_Copyright, "Mathias Roslund",
  527. MUIA_Application_Description, KEYNAME,
  528. SubWindow, window = WindowObject,
  529. MUIA_Window_Title, KEYNAME,
  530. MUIA_Window_ID, MAKE_ID('0', 'W', 'I', 'N'),
  531. WindowContents, VGroup,
  532.  
  533. Child, HGroup,
  534. Child, TextObject,
  535. MUIA_Text_PreParse, "\033r",
  536. MUIA_Text_Contents, "Port A",
  537. MUIA_Weight, 0,
  538. MUIA_InnerLeft, 0,
  539. MUIA_InnerRight, 0,
  540. End,
  541.  
  542. Child, Oport_a = CycleObject,
  543. MUIA_Cycle_Entries, CY_PortContent,
  544. MUIA_Cycle_Active, ll_port_a,
  545. End,
  546. End,
  547.  
  548. Child, HGroup,
  549. Child, TextObject,
  550. MUIA_Text_PreParse, "\033r",
  551. MUIA_Text_Contents, "Port B",
  552. MUIA_Weight, 0,
  553. MUIA_InnerLeft, 0,
  554. MUIA_InnerRight, 0,
  555. End,
  556.  
  557. Child, Oport_b = CycleObject,
  558. MUIA_Cycle_Entries, CY_PortContent,
  559. MUIA_Cycle_Active, ll_port_b,
  560. End,
  561. End,
  562.  
  563. Child, main_group = ColGroup(4), End,
  564. Child, HGroup,
  565. Child, ok = TextObject,
  566. ButtonFrame,
  567. MUIA_Background, MUII_ButtonBack,
  568. MUIA_Text_Contents, "Ok",
  569. MUIA_Text_PreParse, "\033c",
  570. MUIA_InputMode, MUIV_InputMode_RelVerify,
  571. End,
  572. Child, cancel = TextObject,
  573. ButtonFrame,
  574. MUIA_Background, MUII_ButtonBack,
  575. MUIA_Text_Contents, "Cancel",
  576. MUIA_Text_PreParse, "\033c",
  577. MUIA_InputMode, MUIV_InputMode_RelVerify,
  578. End,
  579.  
  580. End,
  581. End,
  582. End,
  583. End;
  584.  
  585. if (app) {
  586. int i;
  587.  
  588. DoMethod(window,
  589. MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
  590. app,
  591. 2,
  592. MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
  593. );
  594.  
  595. DoMethod(cancel,
  596. MUIM_Notify, MUIA_Pressed, FALSE,
  597. app,
  598. 2,
  599. MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
  600. );
  601.  
  602. DoMethod(ok,
  603. MUIM_Notify, MUIA_Pressed, FALSE,
  604. app,
  605. 2,
  606. MUIM_Application_ReturnID, BTN_OK
  607. );
  608.  
  609. DoMethod(Oport_a,
  610. MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
  611. app,
  612. 2,
  613. MUIM_Application_ReturnID, PORT_CHANGE_A
  614. );
  615.  
  616. DoMethod(Oport_b,
  617. MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
  618. app,
  619. 2,
  620. MUIM_Application_ReturnID, PORT_CHANGE_B
  621. );
  622.  
  623. for (i=0; i<NUM_KEYSYM; i++) {
  624.  
  625. /* label */
  626. label = TextObject,
  627. MUIA_Text_PreParse, "\033r",
  628. MUIA_Text_Contents, keysym[i].label,
  629. MUIA_InnerLeft, 0,
  630. MUIA_InnerRight, 0,
  631. End;
  632.  
  633. Oinput[i] = CycleObject,
  634. MUIA_Cycle_Entries, lowlevel_name,
  635. MUIA_Cycle_Active, mask_to_index(keysym[i].mask_a, keysym[i].mask_b),
  636. End,
  637.  
  638. text[i] = TextObject,
  639. MUIA_Background, MUII_TextBack,
  640. MUIA_Frame, MUIV_Frame_Text,
  641. MUIA_Text_Contents, rawkey_to_name(keysym[i].rawkey),
  642. End;
  643.  
  644. button = TextObject,
  645. ButtonFrame,
  646. MUIA_Background, MUII_ButtonBack,
  647. MUIA_Text_Contents, "Change",
  648. MUIA_Text_PreParse, "\033c",
  649. MUIA_InputMode, MUIV_InputMode_RelVerify,
  650. End;
  651.  
  652. DoMethod(button,
  653. MUIM_Notify, MUIA_Pressed, FALSE,
  654. app,
  655. 2,
  656. MUIM_Application_ReturnID, (i + 1)
  657. );
  658.  
  659. /* add to window */
  660.  
  661. DoMethod(main_group, OM_ADDMEMBER, label);
  662. DoMethod(main_group, OM_ADDMEMBER, Oinput[i]);
  663. DoMethod(main_group, OM_ADDMEMBER, text[i]);
  664. DoMethod(main_group, OM_ADDMEMBER, button);
  665.  
  666. }
  667. }
  668.  
  669. if (app) {
  670. int i;
  671. set(window, MUIA_Window_Open, TRUE);
  672. while (running) {
  673. unsigned long retval = DoMethod(app, MUIM_Application_Input, &signals);
  674. switch (retval) {
  675. case MUIV_Application_ReturnID_Quit:
  676. running = FALSE;
  677. break;
  678.  
  679. case BTN_OK:
  680. for (i=0; i<NUM_KEYSYM; i++) {
  681. ULONG active;
  682. get(Oinput[i], MUIA_Cycle_Active, &active);
  683. if (active > 0) {
  684. keysym[i].type = TYPE_BUTTON;
  685. keysym[i].mask_a = (active <= 11) ? lowlevel_mask[active] : 0;
  686. keysym[i].mask_b = (active >= 12) ? lowlevel_mask[active] : 0;
  687. } else {
  688. keysym[i].type = TYPE_NONE;
  689. keysym[i].mask_a = 0;
  690. keysym[i].mask_b = 0;
  691. }
  692. }
  693. write_cfg(par);
  694. running = FALSE;
  695. break;
  696.  
  697. case PORT_CHANGE_A: {
  698. ULONG active;
  699. get(Oport_a, MUIA_Cycle_Active, &active);
  700.  
  701. /* Force CD32 pad */
  702. SetJoyPortAttrs(ll_port_a, SJA_Type, SJA_TYPE_AUTOSENSE, TAG_END);
  703. ll_port_a = active;
  704. SetJoyPortAttrs(ll_port_a, SJA_Type, SJA_TYPE_GAMECTLR, TAG_END);
  705.  
  706. for (i=0; i<NUM_KEYSYM; i++) {
  707. set(Oinput[i], MUIA_Cycle_Active, 0);
  708. }
  709. } break;
  710.  
  711. case PORT_CHANGE_B: {
  712. ULONG active;
  713. get(Oport_b, MUIA_Cycle_Active, &active);
  714.  
  715. /* Force CD32 pad */
  716. SetJoyPortAttrs(ll_port_b, SJA_Type, SJA_TYPE_AUTOSENSE, TAG_END);
  717. ll_port_b = active;
  718. SetJoyPortAttrs(ll_port_b, SJA_Type, SJA_TYPE_GAMECTLR, TAG_END);
  719.  
  720. for (i=0; i<NUM_KEYSYM; i++) {
  721. set(Oinput[i], MUIA_Cycle_Active, 0);
  722. }
  723. } break;
  724.  
  725. default:
  726. if ((retval >= 1) && (retval <= (1+NUM_KEYSYM))) {
  727. int keycode, result;
  728. ULONG mask_a, mask_b;
  729. result = get_key(&keycode, &mask_a, &mask_b);
  730. if (result == 1) { /* KEY */
  731. keysym[retval - 1].rawkey = keycode;
  732. set(text[retval - 1], MUIA_Text_Contents, (ULONG)rawkey_to_name(keycode));
  733. } else if (result == 2) { /* lowlevel */
  734. int index = mask_to_index(mask_a, mask_b);
  735. set(Oinput[retval - 1], MUIA_Cycle_Active, index);
  736. }
  737. }
  738. break;
  739. }
  740. if (running && signals) {
  741. Wait(signals);
  742. }
  743. }
  744. MUI_DisposeObject(app);
  745. }
  746.  
  747. #undef PORT_CHANGE
  748. #undef BTN_OK
  749.  
  750. return FPSE_OK;
  751. }
  752.  
  753. void JOY_About(UINT32 *par)
  754. {
  755. memcpy(par, &info, sizeof(FPSEAmigaAbout));
  756. }
  757.  
  758. void JOY_Close(void)
  759. {
  760. /* Force CD32 pad */
  761. SetJoyPortAttrs(ll_port_a, SJA_Type, SJA_TYPE_AUTOSENSE, TAG_END);
  762. SetJoyPortAttrs(ll_port_b, SJA_Type, SJA_TYPE_AUTOSENSE, TAG_END);
  763.  
  764. rem_inputhandler();
  765. }
  766.  
  767. void JOY_LoadState(JOY_State *state) {}
  768. void JOY_SaveState(JOY_State *state) {}
  769.  
  770. int JOY_SetAnalog(int mode)
  771. {
  772. int prev = (JOY_Device != 0x41);
  773.  
  774. if (mode == 1) {
  775. JOY_Device = 0x73;
  776. } else if (mode == 0) {
  777. JOY_Device = 0x41;
  778. }
  779.  
  780. return prev;
  781. }
  782.  
  783. void JOY_SetOutputBuffer(UINT8 *buf)
  784. {
  785. padbuf0 = buf;
  786. }
  787.  
  788. int JOY_StartPoll(void)
  789. {
  790. ULONG portstate_a, portstate_b;
  791. UINT32 ret = joy_ret;
  792. int lax = left_analog_x;
  793. int lay = left_analog_y;
  794. int rax = right_analog_x;
  795. int ray = right_analog_y;
  796. int i;
  797.  
  798. ret |= ((1 << DIGITAL_UP) | (1 << DIGITAL_DOWN) | (1 << DIGITAL_LEFT) | (1 << DIGITAL_RIGHT));
  799.  
  800. portstate_a = ReadJoyPort(ll_port_a);
  801. portstate_b = ReadJoyPort(ll_port_b);
  802.  
  803. for (i=0; i<NUM_KEYSYM; i++) {
  804. switch (keysym[i].type) {
  805. case TYPE_BUTTON:
  806. if (portstate_a & keysym[i].mask_a) {
  807. ret &= ~(1<<keysym[i].bitnum);
  808. } else {
  809. ret |= (1<<keysym[i].bitnum);
  810. }
  811.  
  812. if (portstate_b & keysym[i].mask_b) {
  813. ret &= ~(1<<keysym[i].bitnum);
  814. } else {
  815. ret |= (1<<keysym[i].bitnum);
  816. }
  817. break;
  818.  
  819. default:
  820. break;
  821. }
  822. }
  823.  
  824. padbuf0[1] = JOY_Device;
  825. padbuf0[2] = 0x5A;
  826. padbuf0[3] = ret >> 8;
  827. padbuf0[4] = ret;
  828. padbuf0[5] = rax;
  829. padbuf0[6] = ray;
  830. padbuf0[7] = lax;
  831. padbuf0[8] = lay;
  832. padcnt = 0;
  833.  
  834. CmdPoll = FirstPoll;
  835.  
  836. return ACK_OK;
  837. }
  838.  
  839. static int NormalPoll(int outbyte)
  840. {
  841. if (padcnt > (1+((JOY_Device&0xF)<<1)) ) return ACK_ERR;
  842. return ACK_OK;
  843. }
  844.  
  845. static int DeviceSelectPoll(int outbyte)
  846. {
  847. if (padcnt == 3) {
  848. if (outbyte == 0) {
  849. JOY_Device = 0x41;
  850. } else {
  851. JOY_Device = 0x73;
  852. }
  853. }
  854. return ACK_OK;
  855. }
  856.  
  857. static int Cmd46Poll_Digital(int outbyte)
  858. {
  859. if (padcnt == 3)
  860. {
  861. UINT32 *buf32 = (UINT32 *)padbuf0;
  862. if (outbyte) {
  863. buf32[1] = C_SWAP32(0x01010100);
  864. padbuf0[8] = 0x14;
  865. } else {
  866. buf32[1] = C_SWAP32(0x00020100);
  867. padbuf0[8] = 0x0A;
  868. }
  869. CmdPoll = NormalPoll;
  870. }
  871. return ACK_OK;
  872. }
  873.  
  874. static int Cmd46Poll_Analog(int outbyte)
  875. {
  876. if (padcnt == 3)
  877. {
  878. UINT32 *buf32 = (UINT32 *)padbuf0;
  879. if (outbyte) {
  880. buf32[1] = C_SWAP32(0x01000100);
  881. padbuf0[8] = 0x14;
  882. } else {
  883. buf32[1] = C_SWAP32(0x00000100);
  884. padbuf0[8] = 0x0A;
  885. }
  886. CmdPoll = NormalPoll;
  887. }
  888. return ACK_OK;
  889. }
  890. static int Cmd4CPoll(int outbyte)
  891. {
  892. if (padcnt == 3)
  893. {
  894. if (outbyte)
  895. padbuf0[6] = 0x07;
  896. else
  897. padbuf0[6] = 0x04;
  898. CmdPoll = NormalPoll;
  899. }
  900. return ACK_OK;
  901. }
  902.  
  903. static int FirstPoll(int outbyte)
  904. {
  905. UINT32 *buf32;
  906.  
  907. switch (outbyte) {
  908. case 0x44:
  909. buf32 = (UINT32 *)padbuf0;
  910. buf32[0] = C_SWAP32(0x005AF3FF);
  911. buf32[1] = C_SWAP32(0x00000000);
  912. padbuf0[8] = 0;
  913. CmdPoll = DeviceSelectPoll;
  914. break;
  915. case 0x45:
  916. buf32 = (UINT32 *)padbuf0;
  917. buf32[0] = C_SWAP32(0x035AF3FF);
  918. if (JOY_Device == 0x41)
  919. buf32[1] = C_SWAP32(0x01020002);
  920. else
  921. buf32[1] = C_SWAP32(0x01000102);
  922. padbuf0[8] = 0;
  923. CmdPoll = NormalPoll;
  924. break;
  925. case 0x46:
  926. buf32 = (UINT32 *)padbuf0;
  927. buf32[0] = C_SWAP32(0x005AF3FF);
  928. if (JOY_Device == 0x41)
  929. CmdPoll = Cmd46Poll_Digital;
  930. else
  931. CmdPoll = Cmd46Poll_Analog;
  932. break;
  933. case 0x47:
  934. buf32 = (UINT32 *)padbuf0;
  935. buf32[0] = C_SWAP32(0x005AF3FF);
  936. buf32[1] = C_SWAP32(0x01000200);
  937. padbuf0[8] = 0;
  938. CmdPoll = NormalPoll;
  939. break;
  940. case 0x4C:
  941. buf32 = (UINT32 *)padbuf0;
  942. buf32[0] = C_SWAP32(0x005AF3FF);
  943. buf32[1] = C_SWAP32(0x00000000);
  944. padbuf0[8] = 0;
  945. CmdPoll = Cmd4CPoll;
  946. break;
  947. case 0x4D:
  948. buf32 = (UINT32 *)padbuf0;
  949. buf32[0] = C_SWAP32(0xFF5AF3FF);
  950. buf32[1] = C_SWAP32(0xFFFFFFFF);
  951. padbuf0[8] = 0xFF;
  952. default:
  953. CmdPoll = NormalPoll;
  954. break;
  955. }
  956. return ACK_OK;
  957. }
  958.  
  959. int JOY_Poll(int outbyte)
  960. {
  961. padcnt++;
  962. return CmdPoll(outbyte);
  963. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement