mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #2882 from danzel/movie-squash
Movie (Game Inputs) recording and playback
This commit is contained in:
		
						commit
						44d07574b1
					
				
					 13 changed files with 673 additions and 41 deletions
				
			
		|  | @ -16,6 +16,8 @@ | |||
| #include "core/hle/service/hid/hid_spvr.h" | ||||
| #include "core/hle/service/hid/hid_user.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/movie.h" | ||||
| #include "video_core/video_core.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace HID { | ||||
|  | @ -96,6 +98,9 @@ void Module::UpdatePadCallback(u64 userdata, int cycles_late) { | |||
|     constexpr int MAX_CIRCLEPAD_POS = 0x9C; // Max value for a circle pad position
 | ||||
|     s16 circle_pad_x = static_cast<s16>(circle_pad_x_f * MAX_CIRCLEPAD_POS); | ||||
|     s16 circle_pad_y = static_cast<s16>(circle_pad_y_f * MAX_CIRCLEPAD_POS); | ||||
| 
 | ||||
|     Core::Movie::GetInstance().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y); | ||||
| 
 | ||||
|     const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y); | ||||
|     state.circle_up.Assign(direction.up); | ||||
|     state.circle_down.Assign(direction.down); | ||||
|  | @ -141,6 +146,8 @@ void Module::UpdatePadCallback(u64 userdata, int cycles_late) { | |||
|     touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight); | ||||
|     touch_entry.valid.Assign(pressed ? 1 : 0); | ||||
| 
 | ||||
|     Core::Movie::GetInstance().HandleTouchStatus(touch_entry); | ||||
| 
 | ||||
|     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
 | ||||
|     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
 | ||||
|     // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8).
 | ||||
|  | @ -179,6 +186,8 @@ void Module::UpdateAccelerometerCallback(u64 userdata, int cycles_late) { | |||
|     accelerometer_entry.y = static_cast<s16>(accel.y); | ||||
|     accelerometer_entry.z = static_cast<s16>(accel.z); | ||||
| 
 | ||||
|     Core::Movie::GetInstance().HandleAccelerometerStatus(accelerometer_entry); | ||||
| 
 | ||||
|     // Make up "raw" entry
 | ||||
|     // TODO(wwylele):
 | ||||
|     // From hardware testing, the raw_entry values are approximately, but not exactly, as twice as
 | ||||
|  | @ -217,6 +226,8 @@ void Module::UpdateGyroscopeCallback(u64 userdata, int cycles_late) { | |||
|     gyroscope_entry.y = static_cast<s16>(gyro.y); | ||||
|     gyroscope_entry.z = static_cast<s16>(gyro.z); | ||||
| 
 | ||||
|     Core::Movie::GetInstance().HandleGyroscopeStatus(gyroscope_entry); | ||||
| 
 | ||||
|     // Make up "raw" entry
 | ||||
|     mem->gyroscope.raw_entry.x = gyroscope_entry.x; | ||||
|     mem->gyroscope.raw_entry.z = -gyroscope_entry.y; | ||||
|  |  | |||
|  | @ -3,10 +3,10 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/alignment.h" | ||||
| #include "common/bit_field.h" | ||||
| #include "common/string_util.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/service/ir/extra_hid.h" | ||||
| #include "core/movie.h" | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| namespace Service { | ||||
|  | @ -176,22 +176,6 @@ void ExtraHID::SendHIDStatus() { | |||
|     if (is_device_reload_pending.exchange(false)) | ||||
|         LoadInputDevices(); | ||||
| 
 | ||||
|     struct { | ||||
|         union { | ||||
|             BitField<0, 8, u32_le> header; | ||||
|             BitField<8, 12, u32_le> c_stick_x; | ||||
|             BitField<20, 12, u32_le> c_stick_y; | ||||
|         } c_stick; | ||||
|         union { | ||||
|             BitField<0, 5, u8> battery_level; | ||||
|             BitField<5, 1, u8> zl_not_held; | ||||
|             BitField<6, 1, u8> zr_not_held; | ||||
|             BitField<7, 1, u8> r_not_held; | ||||
|         } buttons; | ||||
|         u8 unknown; | ||||
|     } response; | ||||
|     static_assert(sizeof(response) == 6, "HID status response has wrong size!"); | ||||
| 
 | ||||
|     constexpr int C_STICK_CENTER = 0x800; | ||||
|     // TODO(wwylele): this value is not accurately measured. We currently assume that the axis can
 | ||||
|     // take values in the whole range of a 12-bit integer.
 | ||||
|  | @ -200,6 +184,7 @@ void ExtraHID::SendHIDStatus() { | |||
|     float x, y; | ||||
|     std::tie(x, y) = c_stick->GetStatus(); | ||||
| 
 | ||||
|     ExtraHIDResponse response; | ||||
|     response.c_stick.header.Assign(static_cast<u8>(ResponseID::PollHID)); | ||||
|     response.c_stick.c_stick_x.Assign(static_cast<u32>(C_STICK_CENTER + C_STICK_RADIUS * x)); | ||||
|     response.c_stick.c_stick_y.Assign(static_cast<u32>(C_STICK_CENTER + C_STICK_RADIUS * y)); | ||||
|  | @ -209,6 +194,8 @@ void ExtraHID::SendHIDStatus() { | |||
|     response.buttons.r_not_held.Assign(1); | ||||
|     response.unknown = 0; | ||||
| 
 | ||||
|     Core::Movie::GetInstance().HandleExtraHidResponse(response); | ||||
| 
 | ||||
|     std::vector<u8> response_buffer(sizeof(response)); | ||||
|     memcpy(response_buffer.data(), &response, sizeof(response)); | ||||
|     Send(response_buffer); | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ | |||
| 
 | ||||
| #include <array> | ||||
| #include <atomic> | ||||
| #include "common/bit_field.h" | ||||
| #include "common/swap.h" | ||||
| #include "core/frontend/input.h" | ||||
| #include "core/hle/service/ir/ir_user.h" | ||||
| 
 | ||||
|  | @ -16,6 +18,22 @@ struct EventType; | |||
| namespace Service { | ||||
| namespace IR { | ||||
| 
 | ||||
| struct ExtraHIDResponse { | ||||
|     union { | ||||
|         BitField<0, 8, u32_le> header; | ||||
|         BitField<8, 12, u32_le> c_stick_x; | ||||
|         BitField<20, 12, u32_le> c_stick_y; | ||||
|     } c_stick; | ||||
|     union { | ||||
|         BitField<0, 5, u8> battery_level; | ||||
|         BitField<5, 1, u8> zl_not_held; | ||||
|         BitField<6, 1, u8> zr_not_held; | ||||
|         BitField<7, 1, u8> r_not_held; | ||||
|     } buttons; | ||||
|     u8 unknown; | ||||
| }; | ||||
| static_assert(sizeof(ExtraHIDResponse) == 6, "HID status response has wrong size!"); | ||||
| 
 | ||||
| /**
 | ||||
|  * An IRDevice emulating Circle Pad Pro or New 3DS additional HID hardware. | ||||
|  * This device sends periodic udates at a rate configured by the 3DS, and sends calibration data if | ||||
|  |  | |||
|  | @ -2,30 +2,18 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/shared_memory.h" | ||||
| #include "core/hle/service/hid/hid.h" | ||||
| #include "core/hle/service/ir/ir_rst.h" | ||||
| #include "core/movie.h" | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace IR { | ||||
| 
 | ||||
| union PadState { | ||||
|     u32_le hex{}; | ||||
| 
 | ||||
|     BitField<14, 1, u32_le> zl; | ||||
|     BitField<15, 1, u32_le> zr; | ||||
| 
 | ||||
|     BitField<24, 1, u32_le> c_stick_right; | ||||
|     BitField<25, 1, u32_le> c_stick_left; | ||||
|     BitField<26, 1, u32_le> c_stick_up; | ||||
|     BitField<27, 1, u32_le> c_stick_down; | ||||
| }; | ||||
| 
 | ||||
| struct PadDataEntry { | ||||
|     PadState current_state; | ||||
|     PadState delta_additions; | ||||
|  | @ -74,8 +62,10 @@ void IR_RST::UpdateCallback(u64 userdata, int cycles_late) { | |||
|     float c_stick_x_f, c_stick_y_f; | ||||
|     std::tie(c_stick_x_f, c_stick_y_f) = c_stick->GetStatus(); | ||||
|     constexpr int MAX_CSTICK_RADIUS = 0x9C; // Max value for a c-stick radius
 | ||||
|     const s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS); | ||||
|     const s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS); | ||||
|     s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS); | ||||
|     s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS); | ||||
| 
 | ||||
|     Core::Movie::GetInstance().HandleIrRst(state, c_stick_x, c_stick_y); | ||||
| 
 | ||||
|     if (!raw_c_stick) { | ||||
|         const HID::DirectionState direction = HID::GetStickDirectionState(c_stick_x, c_stick_y); | ||||
|  |  | |||
|  | @ -6,6 +6,9 @@ | |||
| 
 | ||||
| #include <atomic> | ||||
| #include <memory> | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/swap.h" | ||||
| #include "core/frontend/input.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | @ -22,6 +25,18 @@ class EventType; | |||
| namespace Service { | ||||
| namespace IR { | ||||
| 
 | ||||
| union PadState { | ||||
|     u32_le hex{}; | ||||
| 
 | ||||
|     BitField<14, 1, u32_le> zl; | ||||
|     BitField<15, 1, u32_le> zr; | ||||
| 
 | ||||
|     BitField<24, 1, u32_le> c_stick_right; | ||||
|     BitField<25, 1, u32_le> c_stick_left; | ||||
|     BitField<26, 1, u32_le> c_stick_up; | ||||
|     BitField<27, 1, u32_le> c_stick_down; | ||||
| }; | ||||
| 
 | ||||
| /// Interface to "ir:rst" service
 | ||||
| class IR_RST final : public ServiceFramework<IR_RST> { | ||||
| public: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue