]> Shamusworld >> Repos - virtualjaguar/blob - src/joystick.cpp
25aef85b2a23e1a72c14d2853c4988649a7ca864
[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 // Extensive rewrite by James Hammons
7 // (C) 2013 Underground Software
8 //
9 // JLH = James Hammons <jlhamm@acm.org>
10 //
11 // Who  When        What
12 // ---  ----------  -------------------------------------------------------------
13 // JLH  01/16/2010  Created this log ;-)
14 //
15
16 #include "joystick.h"
17 #include <string.h>                     // For memset()
18 #include "gpu.h"
19 #include "jaguar.h"
20 #include "log.h"
21 #include "settings.h"
22
23 // Global vars
24
25 static uint8_t joystick_ram[4];
26 uint8_t joypad0Buttons[21];
27 uint8_t joypad1Buttons[21];
28 bool audioEnabled = false;
29 bool joysticksEnabled = false;
30
31
32 bool GUIKeyHeld = false;
33 extern int start_logging;
34 int gpu_start_log = 0;
35 int op_start_log = 0;
36 int blit_start_log = 0;
37 int effect_start = 0;
38 int effect_start2 = 0, effect_start3 = 0, effect_start4 = 0, effect_start5 = 0, effect_start6 = 0;
39 bool interactiveMode = false;
40 bool iLeft, iRight, iToggle = false;
41 bool keyHeld1 = false, keyHeld2 = false, keyHeld3 = false;
42 int objectPtr = 0;
43 bool startMemLog = false;
44 extern bool doDSPDis, doGPUDis;
45
46 bool blitterSingleStep = false;
47 bool bssGo = false;
48 bool bssHeld = false;
49
50
51 void JoystickInit(void)
52 {
53         JoystickReset();
54 }
55
56
57 void JoystickExec(void)
58 {
59         gpu_start_log = 0;                                                      // Only log while key down!
60         effect_start = 0;
61         effect_start2 = effect_start3 = effect_start4 = effect_start5 = effect_start6 = 0;
62         blit_start_log = 0;
63         iLeft = iRight = false;
64 }
65
66
67 void JoystickReset(void)
68 {
69         memset(joystick_ram, 0x00, 4);
70         memset(joypad0Buttons, 0, 21);
71         memset(joypad1Buttons, 0, 21);
72 }
73
74
75 void JoystickDone(void)
76 {
77 }
78
79
80 uint16_t JoystickReadWord(uint32_t offset)
81 {
82         // E, D, B, 7
83         uint8_t joypad0Offset[16] = {
84                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xFF, 0xFF, 0xFF, 0x08, 0xFF, 0x04, 0x00, 0xFF
85         };
86         uint8_t joypad1Offset[16] = {
87                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x0C, 0xFF
88         };
89
90 #warning "No bounds checking done in JoystickReadByte!"
91         offset &= 0x03;
92
93         if (offset == 0)
94         {
95                 if (!joysticksEnabled)
96                         return 0xFFFF;
97
98                 // Joystick data returns active low for buttons pressed, high for non-
99                 // pressed.
100                 uint16_t data = 0xFFFF;
101                 uint8_t offset0 = joypad0Offset[joystick_ram[1] & 0x0F];
102                 uint8_t offset1 = joypad1Offset[(joystick_ram[1] >> 4) & 0x0F];
103
104                 if (offset0 != 0xFF)
105                 {
106                         uint16_t mask[4] = { 0xFEFF, 0xFDFF, 0xFBFF, 0xF7FF };
107 //No!                   uint16_t mask[4] = { 0xFFFE, 0xFFFD, 0xFFFB, 0xFFF7 };
108
109                         for(uint8_t i=0; i<4; i++)
110                                 data &= (joypad0Buttons[offset0 + i] ? mask[i] : 0xFFFF);
111                 }
112
113                 if (offset1 != 0xFF)
114                 {
115                         uint16_t mask[4] = { 0xEFFF, 0xDFFF, 0xBFFF, 0x7FFF };
116 //No!                   uint16_t mask[4] = { 0xFFEF, 0xFFDF, 0xFFBF, 0xFF7F };
117
118                         for(uint8_t i=0; i<4; i++)
119                                 data &= (joypad1Buttons[offset1 + i] ? mask[i] : 0xFFFF);
120                 }
121
122                 return data;
123         }
124         else if (offset == 2)
125         {
126                 // Hardware ID returns NTSC/PAL identification bit here
127                 uint16_t data = 0xFFEF | (vjs.hardwareTypeNTSC ? 0x10 : 0x00);
128
129                 if (!joysticksEnabled)
130                         return data;
131
132                 // Joystick data returns active low for buttons pressed, high for non-
133                 // pressed.
134                 uint8_t offset0 = joypad0Offset[joystick_ram[1] & 0x0F];
135                 uint8_t offset1 = joypad1Offset[(joystick_ram[1] >> 4) & 0x0F];
136
137                 if (offset0 != 0xFF)
138                 {
139                         offset0 /= 4;   // Make index 0, 1, 2, 3 instead of 0, 4, 8, 12
140                         uint8_t mask[4][2] = { { BUTTON_A, BUTTON_PAUSE }, { BUTTON_B, 0xFF }, { BUTTON_C, 0xFF }, { BUTTON_OPTION, 0xFF } };
141                         data &= (joypad0Buttons[mask[offset0][0]] ? 0xFFFD : 0xFFFF);
142
143                         if (mask[offset0][1] != -1)
144                                 data &= (joypad0Buttons[mask[offset0][1]] ? 0xFFFE : 0xFFFF);
145                 }
146
147                 if (offset1 != 0xFF)
148                 {
149                         offset1 /= 4;   // Make index 0, 1, 2, 3 instead of 0, 4, 8, 12
150                         uint8_t mask[4][2] = { { BUTTON_A, BUTTON_PAUSE }, { BUTTON_B, 0xFF }, { BUTTON_C, 0xFF }, { BUTTON_OPTION, 0xFF } };
151                         data &= (joypad1Buttons[mask[offset1][0]] ? 0xFFF7 : 0xFFFF);
152
153                         if (mask[offset1][1] != -1)
154                                 data &= (joypad1Buttons[mask[offset1][1]] ? 0xFFFB : 0xFFFF);
155                 }
156
157                 return data;
158         }
159
160         return 0xFFFF;
161 }
162
163
164 void JoystickWriteWord(uint32_t offset, uint16_t data)
165 {
166 #warning "No bounds checking done for JoystickWriteWord!"
167         offset &= 0x03;
168         joystick_ram[offset + 0] = (data >> 8) & 0xFF;
169         joystick_ram[offset + 1] = data & 0xFF;
170
171         if (offset == 0)
172         {
173                 audioEnabled = (data & 0x0100 ? true : false);
174                 joysticksEnabled = (data & 0x8000 ? true : false);
175         }
176 }
177