mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	HID: Refactored shared memory decoding for touchpad support.
This commit is contained in:
		
							parent
							
								
									6c37a90d3f
								
							
						
					
					
						commit
						83a66dd701
					
				
					 2 changed files with 64 additions and 33 deletions
				
			
		|  | @ -25,17 +25,17 @@ Kernel::SharedPtr<Kernel::Event> g_event_debug_pad; | |||
| 
 | ||||
| // Next Pad state update information
 | ||||
| static PadState next_state = {{0}}; | ||||
| static u32 next_index = 0; | ||||
| static s16 next_circle_x = 0; | ||||
| static s16 next_circle_y = 0; | ||||
| static u32 next_pad_index = 0; | ||||
| static s16 next_pad_circle_x = 0; | ||||
| static s16 next_pad_circle_y = 0; | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets a pointer to the PadData structure inside HID shared memory | ||||
|  */ | ||||
| static inline PadData* GetPadData() { | ||||
| static inline SharedMem* GetPadData() { | ||||
|     if (g_shared_mem == nullptr) | ||||
|         return nullptr; | ||||
|     return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr)); | ||||
|     return reinterpret_cast<SharedMem*>(g_shared_mem->GetPointer().ValueOr(nullptr)); | ||||
| } | ||||
| 
 | ||||
| // TODO(peachum):
 | ||||
|  | @ -60,10 +60,10 @@ static inline PadData* GetPadData() { | |||
|  */ | ||||
| static void UpdateNextCirclePadState() { | ||||
|     static const s16 max_value = 0x9C; | ||||
|     next_circle_x = next_state.circle_left ? -max_value : 0x0; | ||||
|     next_circle_x += next_state.circle_right ? max_value : 0x0; | ||||
|     next_circle_y = next_state.circle_down ? -max_value : 0x0; | ||||
|     next_circle_y += next_state.circle_up ? max_value : 0x0; | ||||
|     next_pad_circle_x = next_state.circle_left ? -max_value : 0x0; | ||||
|     next_pad_circle_x += next_state.circle_right ? max_value : 0x0; | ||||
|     next_pad_circle_y = next_state.circle_down ? -max_value : 0x0; | ||||
|     next_pad_circle_y += next_state.circle_up ? max_value : 0x0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -87,20 +87,18 @@ void PadButtonRelease(const PadState& pad_state) { | |||
|  * including both Pad key changes and analog circle Pad changes. | ||||
|  */ | ||||
| void PadUpdateComplete() { | ||||
|     PadData* pad_data = GetPadData(); | ||||
|     SharedMem* shared_mem = GetPadData(); | ||||
| 
 | ||||
|     if (pad_data == nullptr) { | ||||
|     if (shared_mem == nullptr) | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Update PadData struct
 | ||||
|     pad_data->current_state.hex = next_state.hex; | ||||
|     pad_data->index = next_index; | ||||
|     next_index = (next_index + 1) % pad_data->entries.size(); | ||||
|     shared_mem->pad.current_state.hex = next_state.hex; | ||||
|     shared_mem->pad.index = next_pad_index; | ||||
|     next_pad_index = (next_pad_index + 1) % shared_mem->pad.entries.size(); | ||||
| 
 | ||||
|     // Get the previous Pad state
 | ||||
|     u32 last_entry_index = (pad_data->index - 1) % pad_data->entries.size(); | ||||
|     PadState old_state = pad_data->entries[last_entry_index].current_state; | ||||
|     u32 last_entry_index = (shared_mem->pad.index - 1) % shared_mem->pad.entries.size(); | ||||
|     PadState old_state = shared_mem->pad.entries[last_entry_index].current_state; | ||||
| 
 | ||||
|     // Compute bitmask with 1s for bits different from the old state
 | ||||
|     PadState changed; | ||||
|  | @ -115,7 +113,7 @@ void PadUpdateComplete() { | |||
|     removals.hex = changed.hex & old_state.hex; | ||||
| 
 | ||||
|     // Get the current Pad entry
 | ||||
|     PadDataEntry* current_pad_entry = &pad_data->entries[pad_data->index]; | ||||
|     PadDataEntry* current_pad_entry = &shared_mem->pad.entries[shared_mem->pad.index]; | ||||
| 
 | ||||
|     // Update entry properties
 | ||||
|     current_pad_entry->current_state.hex = next_state.hex; | ||||
|  | @ -123,8 +121,19 @@ void PadUpdateComplete() { | |||
|     current_pad_entry->delta_removals.hex = removals.hex; | ||||
| 
 | ||||
|     // Set circle Pad
 | ||||
|     current_pad_entry->circle_pad_x = next_circle_x; | ||||
|     current_pad_entry->circle_pad_y = next_circle_y; | ||||
|     current_pad_entry->circle_pad_x = next_pad_circle_x; | ||||
|     current_pad_entry->circle_pad_y = next_pad_circle_y; | ||||
| 
 | ||||
|     // If we just updated index 0, provide a new timestamp
 | ||||
|     if (shared_mem->pad.index == 0) { | ||||
|         shared_mem->pad.index_reset_ticks_previous = shared_mem->pad.index_reset_ticks; | ||||
|         shared_mem->pad.index_reset_ticks = (s64)Core::g_app_core->GetTicks(); | ||||
|     } | ||||
| 
 | ||||
|     // Signal both handles when there's an update to Pad or touch
 | ||||
|     g_event_pad_or_touch_1->Signal(); | ||||
|     g_event_pad_or_touch_2->Signal(); | ||||
| } | ||||
| 
 | ||||
|     // If we just updated index 0, provide a new timestamp
 | ||||
|     if (pad_data->index == 0) { | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ struct PadState { | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Structure of a single entry in the PadData's Pad state history array. | ||||
|  * Structure of a single entry of Pad state history within HID shared memory | ||||
|  */ | ||||
| struct PadDataEntry { | ||||
|     PadState current_state; | ||||
|  | @ -77,22 +77,44 @@ struct PadDataEntry { | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Structure of all data related to the 3DS Pad. | ||||
|  * Structure of a single entry of touch state history within HID shared memory | ||||
|  */ | ||||
| struct PadData { | ||||
|     s64 index_reset_ticks; | ||||
|     s64 index_reset_ticks_previous; | ||||
|     u32 index; // the index of the last updated Pad state history element
 | ||||
| struct TouchDataEntry { | ||||
|     u16 x; | ||||
|     u16 y; | ||||
|     u32 data_valid; | ||||
| }; | ||||
| 
 | ||||
|     u32 pad1; | ||||
|     u32 pad2; | ||||
| /**
 | ||||
|  * Structure of data stored in HID shared memory | ||||
|  */ | ||||
| struct SharedMem { | ||||
|     // Offset 0x0 : "PAD" data, this is used for buttons and the circle pad
 | ||||
|     struct { | ||||
|         s64 index_reset_ticks; | ||||
|         s64 index_reset_ticks_previous; | ||||
|         u32 index; // Index of the last updated pad state history element
 | ||||
| 
 | ||||
|     PadState current_state; // same as entries[index].current_state
 | ||||
|     u32 raw_circle_pad_data; | ||||
|         INSERT_PADDING_BYTES(0x8); | ||||
| 
 | ||||
|     u32 pad3; | ||||
|         PadState current_state; // Same as entries[index].current_state
 | ||||
|         u32 raw_circle_pad_data; | ||||
| 
 | ||||
|     std::array<PadDataEntry, 8> entries; // Pad state history
 | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
| 
 | ||||
|         std::array<PadDataEntry, 8> entries; // Pad state history
 | ||||
|     } pad; | ||||
| 
 | ||||
|     // Offset 0xA8 : Touchpad data, this is used for touchpad input
 | ||||
|     struct { | ||||
|         s64 index_reset_ticks; | ||||
|         s64 index_reset_ticks_previous; | ||||
|         u32 index; // Index of the last updated touch state history element
 | ||||
| 
 | ||||
|         INSERT_PADDING_BYTES(0xC); | ||||
| 
 | ||||
|         std::array<TouchDataEntry, 8> entries; | ||||
|     } touch; | ||||
| }; | ||||
| 
 | ||||
| // Pre-defined PadStates for single button presses
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue