gpfce patch part2
[fceu.git] / drivers / pc / sdl-joystick.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *  Copyright (C) 2002 Paul Kuliniewicz
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 /* PK: SDL joystick input stuff */
23
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <errno.h>
28
29 #include "sdl.h"
30 #ifndef GP2X
31 static SDL_Joystick *jo[4] = {NULL, NULL, NULL, NULL};
32 static void ConfigJoystick (int z);
33
34 #define JOY_A           0x01
35 #define JOY_B           0x02
36 #define JOY_SELECT      0x04
37 #define JOY_START       0x08
38 #define JOY_UP          0x10
39 #define JOY_DOWN        0x20
40 #define JOY_LEFT        0x40
41 #define JOY_RIGHT       0x80
42 #endif
43
44 /* Gets the current joystick position information. */
45 uint32 GetJSOr (void)
46 {
47 #ifndef GP2X
48         int n;                  /* joystick index */
49         int b;                  /* button index */
50         int *joym;              /* pointer to a joystick's button map */
51         Sint16 pos;             /* axis position */
52         uint32 ret = 0;         /* return value */
53
54         for (n = 0; n < 4; n++)
55         {
56                 if (joy[n] == 0)
57                         continue;
58                 joym = joyBMap[n];
59
60                 /* Axis information. */
61                 pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][0]);
62                 if (pos <= -16383)
63                         ret |= JOY_LEFT << (n << 3);
64                 else if (pos >= 16363)
65                         ret |= JOY_RIGHT << (n << 3);
66                 pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][1]);
67                 if (pos <= -16383)
68                         ret |= JOY_UP << (n << 3);
69                 else if (pos >= 16383)
70                         ret |= JOY_DOWN << (n << 3);
71
72                 /* Button information. */
73                 for (b = 0; b < 4; b++)
74                 {
75                         if (SDL_JoystickGetButton(jo[n], joym[b]))
76                                 ret |= (1 << b) << (n << 3);
77                 }
78         }
79
80         return ret;
81 #else
82         return 0;
83 #endif
84 }
85
86 /* Cleanup opened joysticks. */
87 void KillJoysticks (void)
88 {
89 #ifndef GP2X
90         int n;                  /* joystick index */
91
92         for (n = 0; n < 4; n++)
93         {
94                 if (joy[n] != 0)
95                         SDL_JoystickClose(jo[n]);
96         }
97         SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
98         return;
99 #endif
100 }
101
102 /* Initialize joysticks. */
103 int InitJoysticks (void)
104 {
105 #ifndef GP2X
106         int n;                  /* joystick index */
107         if(!(joy[0]|joy[1]|joy[2]|joy[3]))
108          return(0);
109         SDL_InitSubSystem(SDL_INIT_JOYSTICK);
110         for (n = 0; n < 4; n++)
111         {
112                 if (joy[n] == 0)
113                         continue;
114                 
115                 /* Open the joystick under SDL. */
116                 jo[n] = SDL_JoystickOpen(joy[n] - 1);
117                 if (jo[n] == NULL)
118                 {
119                         printf("Could not open joystick %d: %s.\n",
120                                 joy[n] - 1, SDL_GetError());
121                         joy[n] = 0;
122                         continue;
123                 }
124
125                 /* Check for a button map. */
126                 if (!(joyBMap[n][0] | joyBMap[n][1] | joyBMap[n][2] |
127                         joyBMap[n][3]))
128                 {
129                         ConfigJoystick(n);
130                 }
131         }
132
133         return (1);
134 #endif
135 }
136
137 #define WNOINPUT(); for(;;){uint8 t; if(read(fileno(stdin),&t,1)==-1) \
138                         {break;}}
139
140 /* Configure a joystick button. */
141 static void BConfig (int n, int b)
142 {
143 #ifndef GP2X
144         SDL_Event event;                /* SDL event structure */
145         WNOINPUT();
146         while (1)
147         {
148                 uint8 t;
149                 if (read(fileno(stdin), &t, 1) == -1)
150                 {
151                         if (errno != EAGAIN)
152                                 break;
153                 }
154                 else
155                         break;
156                 
157                 if (SDL_PollEvent(&event) && event.type == SDL_JOYBUTTONDOWN)
158                 {
159                         joyBMap[n][b] = event.jbutton.button;
160                         goto endsa;
161                 }
162         }
163
164         endsa:
165         WNOINPUT();
166
167         return;
168 #endif
169 }
170
171 /* Joystick button and axis configuration. */
172 void ConfigJoystick (int n)
173 {
174 #ifndef GP2X
175         int sa;                 /* buffer value */
176         char buf[128];          /* input buffer */
177
178         printf("\n\n Joystick button and axis configuration:\n\n");
179         printf("   Select the joystick axes to use for the virtual d-pad.\n");
180         printf("   If you do not wish to assign an axis, press Enter to skip\n");
181         printf("   that axis.\n");
182         printf("   Push the button to map to the virtual joystick.\n");
183         printf("   If you do not wish to assign a button, press Enter to skip\n");
184         printf("   that button.\n   Press enter to continue...\n");
185         getchar();
186         printf("****  Configuring joystick %d ****\n\n", n + 1);
187
188         printf("** Enter axis to use for the x-axis (default 0).\n");
189         fgets(buf, sizeof(buf), stdin);
190         joyAMap[n][0] = ('0' <= buf[0] && buf[9] <= '9') ? atoi(buf) : 0;
191
192         printf("** Enter axis to use for the y-axis (default 1).\n");
193         fgets(buf, sizeof(buf), stdin);
194         joyAMap[n][1] = ('0' <= buf[0] && buf[9] <= '9') ? atoi(buf) : 1;
195
196         sa = fcntl(fileno(stdin), F_GETFL);
197         fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
198
199         printf("** Press button for \"Select\".\n");
200         BConfig(n, 2);
201
202         printf("** Press button for \"Start\".\n");
203         BConfig(n, 3);
204
205         printf("** Press button for \"B\".\n");
206         BConfig(n, 1);
207
208         printf("** Press button for \"A\".\n");
209         BConfig(n, 0);
210         
211         fcntl(fileno(stdin), F_SETFL, sa);
212 #endif
213 }