1 /**********************************************/
2 // File : joystick.c
3 // Author : John Bliss
4 // Date : September 27th 2019
5 /**********************************************/
6
7 #include "joystick.h"
8
9
10 enum joy_status joy1_mode = NONE;
11 enum joy_status joy2_mode = NONE;
12
13
14 static SDL_GameController *joystick1 = NULL;
15 static SDL_GameController *joystick2 = NULL;
16 static bool old_clock = false;
17 static bool writing = false;
18 static uint16_t joystick1_state = 0;
19 static uint16_t joystick2_state = 0;
20 static uint8_t clock_count = 0;
21
22 bool joystick_latch, joystick_clock;
23 bool joystick1_data, joystick2_data;
24
joystick_init()25 bool joystick_init()
26 {
27 int joystick1_number = -1;
28 //Try to get first controller, if it is not set to 1
29 if (joy1_mode != NONE) {
30 for (int i = 0; i < SDL_NumJoysticks(); i++) {
31 if (SDL_IsGameController(i)) {
32 joystick1 = SDL_GameControllerOpen(i);
33 if (joystick1) {
34 joystick1_number = i;
35 break;
36 } else {
37 fprintf(stderr, "Could not open gamecontroller %i: %s\n", i, SDL_GetError());
38 }
39 }
40 }
41 }
42 if (joy2_mode != NONE) {
43 for (int i=0; i < SDL_NumJoysticks(); i++) {
44 if (SDL_IsGameController(i) && joystick1_number != i) {
45 joystick2 = SDL_GameControllerOpen(i);
46 if (joystick2) {
47 break;
48 } else {
49 fprintf(stderr, "Could not open gamecontroller %i: %s\n", i, SDL_GetError());
50 }
51 }
52 }
53 }
54 writing = false;
55 return true;
56 }
57
joystick_step()58 void joystick_step()
59 {
60 if (!writing) { //if we are not already writing, check latch to
61 //see if we need to start
62 handle_latch(joystick_latch, joystick_clock);
63 return;
64 }
65
66 //if we have started writing controller data and the latch has dropped,
67 // we need to start the next bit
68 if (!joystick_latch) {
69 //check if clock has changed
70 if (joystick_clock != old_clock) {
71 if (old_clock) {
72 old_clock = joystick_clock;
73 } else { //only write next bit when the new clock is high
74 clock_count +=1;
75 old_clock = joystick_clock;
76 if (clock_count < 16) { // write out the next 15 bits
77 joystick1_data = (joy1_mode != NONE) ? (joystick1_state & 1) : 1;
78 joystick2_data = (joy2_mode != NONE) ? (joystick2_state & 1) : 1;
79 joystick1_state = joystick1_state >> 1;
80 joystick2_state = joystick2_state >> 1;
81 } else {
82 //Done writing controller data
83 //reset flag and set count to 0
84 writing = false;
85 clock_count = 0;
86 joystick1_data = (joy1_mode != NONE) ? 0 : 1;
87 joystick2_data = (joy2_mode != NONE) ? 0 : 1;
88 }
89 }
90 }
91 }
92
93
94
95 }
96
handle_latch(bool latch,bool clock)97 bool handle_latch(bool latch, bool clock)
98 {
99 if (latch){
100 clock_count = 0;
101 //get the 16-representation to put to the VIA
102 joystick1_state = get_joystick_state(joystick1, joy1_mode);
103 joystick2_state = get_joystick_state(joystick2, joy2_mode);
104 //set writing flag to true to signal we will start writing controller data
105 writing = true;
106 old_clock = clock;
107 //preload the first bit onto VIA
108 joystick1_data = (joy1_mode != NONE) ? (joystick1_state & 1) : 1;
109 joystick2_data = (joy2_mode != NONE) ? (joystick2_state & 1) : 1;
110 joystick1_state = joystick1_state >> 1;
111 joystick2_state = joystick2_state >> 1;
112 }
113
114 return latch;
115 }
116
117 //get current state from SDL controller
118 //Should replace this with SDL events, so we do not miss inputs when polling
get_joystick_state(SDL_GameController * control,enum joy_status mode)119 uint16_t get_joystick_state(SDL_GameController *control, enum joy_status mode)
120 {
121 if (mode == NES) {
122 bool a_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_A);
123 bool b_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_X);
124 bool select_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_BACK);
125 bool start_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_START);
126 bool up_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_UP);
127 bool down_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
128 bool left_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
129 bool right_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
130
131 return
132 (!a_pressed) |
133 (!b_pressed) << 1 |
134 (!select_pressed) << 2 |
135 (!start_pressed) << 3 |
136 (!up_pressed) << 4 |
137 (!down_pressed) << 5 |
138 (!left_pressed) << 6 |
139 (!right_pressed) << 7 |
140 0x0000;
141 }
142 if (mode == SNES) {
143 bool b_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_A);
144 bool y_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_X);
145 bool select_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_BACK);
146 bool start_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_START);
147 bool up_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_UP);
148 bool down_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
149 bool left_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
150 bool right_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
151 bool a_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_B);
152 bool x_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_Y);
153 bool l_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
154 bool r_pressed = SDL_GameControllerGetButton(control, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
155
156
157 return
158 (!b_pressed) |
159 (!y_pressed) << 1 |
160 (!select_pressed) << 2 |
161 (!start_pressed) << 3 |
162 (!up_pressed) << 4 |
163 (!down_pressed) << 5 |
164 (!left_pressed) << 6 |
165 (!right_pressed) << 7 |
166 (!a_pressed) << 8 |
167 (!x_pressed) << 9 |
168 (!l_pressed) << 10 |
169 (!r_pressed) << 11 |
170 0xF000;
171 }
172
173 return 0xFFFF;
174 }
175