@@ -68,6 +68,22 @@ static uint8_t *pack_input_state(struct si_device_gc_input_state *src, uint8_t a
6868 return packed_state ;
6969}
7070
71+ // Set or clear the "need origin" flag in the input state and device info
72+ static void set_need_origin (struct si_device_gc_controller * device , bool need_origin )
73+ {
74+ // Always set the need_origin flag in the input state
75+ device -> input .buttons .need_origin = need_origin ;
76+
77+ // Also update the device info for non-wireless controllers
78+ if (!si_device_gc_is_wireless (device )) {
79+ if (need_origin ) {
80+ device -> info [2 ] |= SI_NEED_ORIGIN ;
81+ } else {
82+ device -> info [2 ] &= ~SI_NEED_ORIGIN ;
83+ }
84+ }
85+ }
86+
7187/**
7288 * Handle "info" commands.
7389 *
@@ -118,8 +134,7 @@ static int handle_short_poll(const uint8_t *command, si_complete_cb_t callback,
118134
119135 if (!si_device_gc_is_wireless (device )) {
120136 // Update the origin flags
121- device -> input .buttons .need_origin = (device -> info [2 ] & SI_NEED_ORIGIN ) != 0 ;
122- device -> input .buttons .use_origin = true;
137+ device -> input .buttons .use_origin = true;
123138
124139 // Save the analog mode and motor state
125140 device -> info [2 ] &= ~(SI_MOTOR_STATE_MASK | SI_ANALOG_MODE_MASK );
@@ -154,13 +169,8 @@ static int handle_read_origin(const uint8_t *command, si_complete_cb_t callback,
154169{
155170 struct si_device_gc_controller * device = (struct si_device_gc_controller * )context ;
156171
157- // Tell the host it no longer needs to fetch the origin
158- if (!si_device_gc_is_wireless (device )) {
159- device -> info [2 ] &= ~SI_NEED_ORIGIN ;
160- }
161-
162172 // Clear the "need origin" flag
163- device -> input . buttons . need_origin = false;
173+ set_need_origin ( device , false) ;
164174
165175 // Respond with the origin
166176 si_write_bytes ((uint8_t * )(& device -> origin ), SI_CMD_GC_READ_ORIGIN_RESP , callback );
@@ -186,10 +196,8 @@ static int handle_calibrate(const uint8_t *command, si_complete_cb_t callback, v
186196 device -> origin .trigger_left = device -> input .trigger_left ;
187197 device -> origin .trigger_right = device -> input .trigger_right ;
188198
189- // Tell the host it no longer needs to fetch the origin
190- if (!si_device_gc_is_wireless (device )) {
191- device -> info [2 ] &= ~SI_NEED_ORIGIN ;
192- }
199+ // Clear the "need origin" flag
200+ set_need_origin (device , false);
193201
194202 // Respond with the new origin
195203 si_write_bytes ((uint8_t * )(& device -> origin ), SI_CMD_GC_CALIBRATE_RESP , callback );
@@ -213,18 +221,20 @@ static int handle_long_poll(const uint8_t *command, si_complete_cb_t callback, v
213221 uint8_t analog_mode = command [1 ] & 0x07 ;
214222 uint8_t motor_state = command [2 ] & 0x03 ;
215223
216- // Update the origin flags before responding
217- device -> input .buttons .need_origin = (device -> info [2 ] & SI_NEED_ORIGIN ) != 0 ;
218- device -> input .buttons .use_origin = true;
219-
220- // Save the analog mode and motor state
221224 if (!si_device_gc_is_wireless (device )) {
225+ // Update the origin flags
226+ device -> input .buttons .use_origin = true;
227+
228+ // Save the analog mode and motor state
222229 device -> info [2 ] &= ~(SI_MOTOR_STATE_MASK | SI_ANALOG_MODE_MASK );
223230 device -> info [2 ] |= motor_state << 3 | analog_mode ;
224231 }
225232
233+ // If the input state is valid, use that for the response, otherwise use the origin
234+ struct si_device_gc_input_state * state = device -> input_valid ? & device -> input : & device -> origin ;
235+
226236 // Respond with the current input state
227- si_write_bytes ((uint8_t * )& device -> input , SI_CMD_GC_LONG_POLL_RESP , callback );
237+ si_write_bytes ((uint8_t * )state , SI_CMD_GC_LONG_POLL_RESP , callback );
228238
229239 return SI_CMD_GC_LONG_POLL_RESP ;
230240}
@@ -296,10 +306,6 @@ void si_device_gc_init(struct si_device_gc_controller *device, uint8_t type)
296306 // Mark the input as valid initially
297307 device -> input_valid = true;
298308
299- // Request the origin on non-wireless controllers
300- if (!si_device_gc_is_wireless (device ))
301- device -> info [2 ] = SI_NEED_ORIGIN ;
302-
303309 // Register the SI commands handled by GameCube controllers
304310 si_command_register (SI_CMD_INFO , SI_CMD_INFO_LEN , handle_info , device );
305311 si_command_register (SI_CMD_RESET , SI_CMD_RESET_LEN , handle_reset , device );
@@ -328,15 +334,15 @@ void si_device_gc_set_wireless_id(struct si_device_gc_controller *device, uint16
328334 device -> info [0 ] |= SI_GC_STANDARD | SI_WIRELESS_RECEIVED ;
329335}
330336
331- void si_device_gc_set_wireless_origin (struct si_device_gc_controller * device , uint8_t * origin_data )
337+ void si_device_gc_set_origin (struct si_device_gc_controller * device , struct si_device_gc_input_state * new_origin )
332338{
333339 // Check if the origin packet is different from the last known origin
334- if (memcmp (& device -> origin .stick_x , origin_data , 6 ) != 0 ) {
340+ if (memcmp (& device -> origin .stick_x , & new_origin -> stick_x , 6 ) != 0 ) {
335341 // Update the origin state
336- memcpy (& device -> origin .stick_x , origin_data , 6 );
342+ memcpy (& device -> origin .stick_x , & new_origin -> stick_x , 6 );
337343
338- // Set the "need origin" flag to true so the host knows to fetch the new origin
339- device -> input . buttons . need_origin = true;
344+ // Tell the host that new origin data is available
345+ set_need_origin ( device , true) ;
340346 }
341347
342348 // Set the "has wireless origin" flag in the device info
0 commit comments