]> Shamusworld >> Repos - virtualjaguar/blob - src/joystick.cpp
More changes for upcoming 1.0.5 release
[virtualjaguar] / src / joystick.cpp
1 //
2 // Joystick handler
3 //
4 // by cal2
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups/fixes by James L. Hammons
7 //
8
9 #include <time.h>
10 #include <SDL.h>
11 #include "jaguar.h"
12
13 #define BUTTON_U                0
14 #define BUTTON_D                1
15 #define BUTTON_L                2
16 #define BUTTON_R                3
17 #define BUTTON_s                4
18 #define BUTTON_7                5
19 #define BUTTON_4                6
20 #define BUTTON_1                7
21 #define BUTTON_0                8
22 #define BUTTON_8                9
23 #define BUTTON_5                10
24 #define BUTTON_2                11
25 #define BUTTON_d                12
26 #define BUTTON_9                13
27 #define BUTTON_6                14
28 #define BUTTON_3                15
29
30 #define BUTTON_A                16
31 #define BUTTON_B                17
32 #define BUTTON_C                18
33 #define BUTTON_OPTION   19
34 #define BUTTON_PAUSE    20
35
36 // Private function prototypes
37
38 void main_screen_switch(void);
39
40 // Global vars
41
42 static uint8 joystick_ram[4];
43 static uint8 joypad_0_buttons[21];
44 static uint8 joypad_1_buttons[21];
45 extern bool finished;
46 extern bool showGUI;
47 bool GUIKeyHeld = false;
48 extern int start_logging;
49 int gpu_start_log = 0;
50 int op_start_log = 0;
51 int blit_start_log = 0;
52 int effect_start = 0;
53 int effect_start2 = 0, effect_start3 = 0, effect_start4 = 0, effect_start5 = 0, effect_start6 = 0;
54 bool interactiveMode = false;
55 bool iLeft, iRight, iToggle = false;
56 bool keyHeld1 = false, keyHeld2 = false, keyHeld3 = false;
57 int objectPtr = 0;
58 bool startMemLog = false;
59
60
61 void main_screen_switch(void)
62 {
63         extern SDL_Surface * mainSurface;
64         extern Uint32 mainSurfaceFlags;
65         extern bool fullscreen;
66
67         fullscreen = !fullscreen;
68         mainSurfaceFlags &= ~SDL_FULLSCREEN;
69         if (fullscreen)
70                 mainSurfaceFlags |= SDL_FULLSCREEN;
71
72         mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
73
74         if (mainSurface == NULL)
75         {
76                 WriteLog("Joystick: SDL is unable to set the video mode: %s\n", SDL_GetError());
77                 exit(1);
78         }
79
80         SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
81 }
82
83 void joystick_init(void)
84 {
85         joystick_reset();
86 }
87
88 void joystick_exec(void)
89 {
90         extern SDL_Joystick * joystick;
91         extern bool useJoystick;
92         uint8 * keystate = SDL_GetKeyState(NULL);
93         
94         memset(joypad_0_buttons, 0, 21);
95         memset(joypad_1_buttons, 0, 21);
96         gpu_start_log = 0;                                                      // Only log while key down!
97         effect_start = 0;
98         effect_start2 = effect_start3 = effect_start4 = effect_start5 = effect_start6 = 0;
99         blit_start_log = 0;
100         iLeft = iRight = false;
101
102         if ((keystate[SDLK_LALT] || keystate[SDLK_RALT]) & keystate[SDLK_RETURN])
103                 main_screen_switch();
104
105         /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com) */
106
107         if (keystate[SDLK_UP])          joypad_0_buttons[BUTTON_U] = 0x01;
108         if (keystate[SDLK_DOWN])        joypad_0_buttons[BUTTON_D] = 0x01;
109         if (keystate[SDLK_LEFT])        joypad_0_buttons[BUTTON_L] = 0x01;
110         if (keystate[SDLK_RIGHT])       joypad_0_buttons[BUTTON_R] = 0x01;
111         // The buttons are labelled C,B,A on the controller (going from left to right)
112         if (keystate[SDLK_z])           joypad_0_buttons[BUTTON_C] = 0x01;
113         if (keystate[SDLK_x])           joypad_0_buttons[BUTTON_B] = 0x01;
114         if (keystate[SDLK_c])           joypad_0_buttons[BUTTON_A] = 0x01;
115 //I may yet move these to O and P...
116         if (keystate[SDLK_QUOTE])       joypad_0_buttons[BUTTON_OPTION] = 0x01;
117         if (keystate[SDLK_RETURN])      joypad_0_buttons[BUTTON_PAUSE] = 0x01;
118
119         if (keystate[SDLK_TAB])
120         {
121                 if (!GUIKeyHeld)
122                         showGUI = !showGUI, GUIKeyHeld = true;
123         }
124         else
125                 GUIKeyHeld = false;
126
127         if (keystate[SDLK_q])
128                 start_logging = 1;
129         if (keystate[SDLK_w])
130                 gpu_reset_stats();
131 //      if (keystate[SDLK_u])           jaguar_long_write(0xf1c384,jaguar_long_read(0xf1c384)+1);
132         if (keystate[SDLK_d])
133                 DumpMainMemory();
134         if (keystate[SDLK_l])
135                 gpu_start_log = 1;
136         if (keystate[SDLK_o])
137                 op_start_log = 1;
138         if (keystate[SDLK_b])
139                 blit_start_log = 1;
140
141         if (keystate[SDLK_1])
142                 effect_start = 1;
143         if (keystate[SDLK_2])
144                 effect_start2 = 1;
145         if (keystate[SDLK_3])
146                 effect_start3 = 1;
147         if (keystate[SDLK_4])
148                 effect_start4 = 1;
149         if (keystate[SDLK_5])
150                 effect_start5 = 1;
151         if (keystate[SDLK_6])
152                 effect_start6 = 1;
153
154         if (keystate[SDLK_i])
155                 interactiveMode = true;
156
157         if (keystate[SDLK_8] && interactiveMode)
158         {
159                 if (!keyHeld1)
160                         objectPtr--, keyHeld1 = true;
161         }
162         else
163                 keyHeld1 = false;
164
165         if (keystate[SDLK_0] && interactiveMode)
166         {
167                 if (!keyHeld2)
168                         objectPtr++, keyHeld2 = true;
169         }
170         else
171                 keyHeld2 = false;
172
173         if (keystate[SDLK_9] && interactiveMode)
174         {
175                 if (!keyHeld3)
176                         iToggle = !iToggle, keyHeld3 = true;
177         }
178         else
179                 keyHeld3 = false;
180
181         if (keystate[SDLK_e])
182                 startMemLog = true;
183         if (keystate[SDLK_r])
184                 WriteLog("\n--------> MARK!\n\n");
185
186         if (keystate[SDLK_KP0])         joypad_0_buttons[BUTTON_0] = 0x01;
187         if (keystate[SDLK_KP1])         joypad_0_buttons[BUTTON_1] = 0x01;
188         if (keystate[SDLK_KP2])         joypad_0_buttons[BUTTON_2] = 0x01;
189         if (keystate[SDLK_KP3])         joypad_0_buttons[BUTTON_3] = 0x01;
190         if (keystate[SDLK_KP4])         joypad_0_buttons[BUTTON_4] = 0x01;
191         if (keystate[SDLK_KP5])         joypad_0_buttons[BUTTON_5] = 0x01;
192         if (keystate[SDLK_KP6])         joypad_0_buttons[BUTTON_6] = 0x01;
193         if (keystate[SDLK_KP7])         joypad_0_buttons[BUTTON_7] = 0x01;
194         if (keystate[SDLK_KP8])         joypad_0_buttons[BUTTON_8] = 0x01;
195         if (keystate[SDLK_KP9])         joypad_0_buttons[BUTTON_9] = 0x01;
196
197     if (keystate[SDLK_ESCAPE])
198         finished = true;
199
200     /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com */
201     /* Joystick support                                 */
202     
203     if (useJoystick)
204     {
205                 int16 x = SDL_JoystickGetAxis(joystick, 0),
206                         y = SDL_JoystickGetAxis(joystick, 1);
207         
208                 if (x > 16384)
209                         joypad_0_buttons[BUTTON_R] = 0x01;
210                 if (x < -16384)
211                         joypad_0_buttons[BUTTON_L] = 0x01;
212                 if (y > 16384)
213                         joypad_0_buttons[BUTTON_D] = 0x01;
214                 if (y < -16384)
215                         joypad_0_buttons[BUTTON_U] = 0x01;
216         
217                 if (SDL_JoystickGetButton(joystick, 0) == SDL_PRESSED)
218                         joypad_0_buttons[BUTTON_A] = 0x01;
219                 if (SDL_JoystickGetButton(joystick, 1) == SDL_PRESSED)
220                         joypad_0_buttons[BUTTON_B] = 0x01;
221                 if (SDL_JoystickGetButton(joystick, 2) == SDL_PRESSED)
222                         joypad_0_buttons[BUTTON_C] = 0x01;
223         }
224         
225         /* ADDED by SDLEMU (http://sdlemu.ngemu.com */
226         /* Needed to make sure that the events queue is empty */
227     SDL_PumpEvents();            
228 }
229
230 void joystick_reset(void)
231 {
232         memset(joystick_ram, 0x00, 4);
233         memset(joypad_0_buttons, 0, 21);
234         memset(joypad_1_buttons, 0, 21);
235 }
236
237 void joystick_done(void)
238 {
239 }
240
241 uint8 joystick_byte_read(uint32 offset)
242 {
243         extern bool hardwareTypeNTSC;
244         offset &= 0x03;
245
246         if (offset == 0)
247         {
248                 uint8 data = 0x00;
249                 int pad0Index = joystick_ram[1] & 0x0F;
250                 int pad1Index = (joystick_ram[1] >> 4) & 0x0F;
251                 
252 // This is bad--we're assuming that a bit is set in the last case. Might not be so!
253                 if (!(pad0Index & 0x01)) 
254                         pad0Index = 0;
255                 else if (!(pad0Index & 0x02)) 
256                         pad0Index = 1;
257                 else if (!(pad0Index & 0x04)) 
258                         pad0Index = 2;
259                 else 
260                         pad0Index = 3;
261                 
262                 if (!(pad1Index & 0x01)) 
263                         pad1Index = 0;
264                 else if (!(pad1Index & 0x02)) 
265                         pad1Index = 1;
266                 else if (!(pad1Index & 0x04)) 
267                         pad1Index = 2;
268                 else
269                         pad1Index = 3;
270
271                 if (joypad_0_buttons[(pad0Index << 2) + 0])     data |= 0x01;
272                 if (joypad_0_buttons[(pad0Index << 2) + 1]) data |= 0x02;
273                 if (joypad_0_buttons[(pad0Index << 2) + 2]) data |= 0x04;
274                 if (joypad_0_buttons[(pad0Index << 2) + 3]) data |= 0x08;
275                 if (joypad_1_buttons[(pad1Index << 2) + 0]) data |= 0x10;
276                 if (joypad_1_buttons[(pad1Index << 2) + 1]) data |= 0x20;
277                 if (joypad_1_buttons[(pad1Index << 2) + 2]) data |= 0x40;
278                 if (joypad_1_buttons[(pad1Index << 2) + 3]) data |= 0x80;
279
280                 return ~data;
281         }
282         else if (offset == 3)
283         {
284                 uint8 data = 0x2F | (hardwareTypeNTSC ? 0x10 : 0x00);
285                 int pad0Index = joystick_ram[1] & 0x0F;
286 //unused                int pad1Index = (joystick_ram[1] >> 4) & 0x0F;
287                 
288                 if (!(pad0Index & 0x01))
289                 {
290                         if (joypad_0_buttons[BUTTON_PAUSE])
291                                 data ^= 0x01;
292                         if (joypad_0_buttons[BUTTON_A])
293                                 data ^= 0x02;
294                 }
295                 else if (!(pad0Index & 0x02))
296                 {
297                         if (joypad_0_buttons[BUTTON_B])
298                                 data ^= 0x02;
299                 }
300                 else if (!(pad0Index & 0x04))
301                 {
302                         if (joypad_0_buttons[BUTTON_C])
303                                 data ^= 0x02;
304                 }
305                 else
306                 {
307                         if (joypad_0_buttons[BUTTON_OPTION])
308                                 data ^= 0x02;
309                 }               
310                 return data;
311         }
312
313         return joystick_ram[offset];
314 }
315
316 uint16 joystick_word_read(uint32 offset)
317 {
318         return ((uint16)joystick_byte_read((offset+0)&0x03) << 8) | joystick_byte_read((offset+1)&0x03);
319 }
320
321 void joystick_byte_write(uint32 offset, uint8 data)
322 {
323         joystick_ram[offset&0x03] = data;
324 }
325
326 void joystick_word_write(uint32 offset, uint16 data)
327 {
328         offset &= 0x03;
329         joystick_ram[offset+0] = (data >> 8) & 0xFF;
330         joystick_ram[offset+1] = data & 0xFF;
331 }