mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #2442 from wwylele/hid-signal
HID: manages updating itself using correct ticks
This commit is contained in:
		
						commit
						55c91ae782
					
				@ -13,7 +13,7 @@
 | 
				
			|||||||
#include "core/core.h"
 | 
					#include "core/core.h"
 | 
				
			||||||
#include "core/core_timing.h"
 | 
					#include "core/core_timing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int g_clock_rate_arm11 = 268123480;
 | 
					int g_clock_rate_arm11 = BASE_CLOCK_RATE_ARM11;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// is this really necessary?
 | 
					// is this really necessary?
 | 
				
			||||||
#define INITIAL_SLICE_LENGTH 20000
 | 
					#define INITIAL_SLICE_LENGTH 20000
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@
 | 
				
			|||||||
// inside callback:
 | 
					// inside callback:
 | 
				
			||||||
//   ScheduleEvent(periodInCycles - cycles_late, callback, "whatever")
 | 
					//   ScheduleEvent(periodInCycles - cycles_late, callback, "whatever")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr int BASE_CLOCK_RATE_ARM11 = 268123480;
 | 
				
			||||||
extern int g_clock_rate_arm11;
 | 
					extern int g_clock_rate_arm11;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline s64 msToCycles(int ms) {
 | 
					inline s64 msToCycles(int ms) {
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,15 @@ static u32 next_gyroscope_index;
 | 
				
			|||||||
static int enable_accelerometer_count = 0; // positive means enabled
 | 
					static int enable_accelerometer_count = 0; // positive means enabled
 | 
				
			||||||
static int enable_gyroscope_count = 0;     // positive means enabled
 | 
					static int enable_gyroscope_count = 0;     // positive means enabled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int pad_update_event;
 | 
				
			||||||
 | 
					static int accelerometer_update_event;
 | 
				
			||||||
 | 
					static int gyroscope_update_event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Updating period for each HID device. These empirical values are measured from a 11.2 3DS.
 | 
				
			||||||
 | 
					constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234;
 | 
				
			||||||
 | 
					constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104;
 | 
				
			||||||
 | 
					constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
 | 
					static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
 | 
				
			||||||
    // 30 degree and 60 degree are angular thresholds for directions
 | 
					    // 30 degree and 60 degree are angular thresholds for directions
 | 
				
			||||||
    constexpr float TAN30 = 0.577350269f;
 | 
					    constexpr float TAN30 = 0.577350269f;
 | 
				
			||||||
@ -65,14 +74,9 @@ static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
 | 
				
			|||||||
    return state;
 | 
					    return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Update() {
 | 
					static void UpdatePadCallback(u64 userdata, int cycles_late) {
 | 
				
			||||||
    SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
 | 
					    SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (mem == nullptr) {
 | 
					 | 
				
			||||||
        LOG_DEBUG(Service_HID, "Cannot update HID prior to mapping shared memory!");
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    PadState state = VideoCore::g_emu_window->GetPadState();
 | 
					    PadState state = VideoCore::g_emu_window->GetPadState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Get current circle pad position and update circle pad direction
 | 
					    // Get current circle pad position and update circle pad direction
 | 
				
			||||||
@ -131,11 +135,15 @@ void Update() {
 | 
				
			|||||||
    event_pad_or_touch_1->Signal();
 | 
					    event_pad_or_touch_1->Signal();
 | 
				
			||||||
    event_pad_or_touch_2->Signal();
 | 
					    event_pad_or_touch_2->Signal();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update accelerometer
 | 
					    // Reschedule recurrent event
 | 
				
			||||||
    if (enable_accelerometer_count > 0) {
 | 
					    CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void UpdateAccelerometerCallback(u64 userdata, int cycles_late) {
 | 
				
			||||||
 | 
					    SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mem->accelerometer.index = next_accelerometer_index;
 | 
					    mem->accelerometer.index = next_accelerometer_index;
 | 
				
			||||||
        next_accelerometer_index =
 | 
					    next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size();
 | 
				
			||||||
            (next_accelerometer_index + 1) % mem->accelerometer.entries.size();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    AccelerometerDataEntry& accelerometer_entry =
 | 
					    AccelerometerDataEntry& accelerometer_entry =
 | 
				
			||||||
        mem->accelerometer.entries[mem->accelerometer.index];
 | 
					        mem->accelerometer.entries[mem->accelerometer.index];
 | 
				
			||||||
@ -144,11 +152,10 @@ void Update() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Make up "raw" entry
 | 
					    // Make up "raw" entry
 | 
				
			||||||
    // TODO(wwylele):
 | 
					    // TODO(wwylele):
 | 
				
			||||||
        // From hardware testing, the raw_entry values are approximately,
 | 
					    // From hardware testing, the raw_entry values are approximately, but not exactly, as twice as
 | 
				
			||||||
        // but not exactly, as twice as corresponding entries (or with a minus sign).
 | 
					    // corresponding entries (or with a minus sign). It may caused by system calibration to the
 | 
				
			||||||
        // It may caused by system calibration to the accelerometer.
 | 
					    // accelerometer. Figure out how it works, or, if no game reads raw_entry, the following three
 | 
				
			||||||
        // Figure out how it works, or, if no game reads raw_entry,
 | 
					    // lines can be removed and leave raw_entry unimplemented.
 | 
				
			||||||
        // the following three lines can be removed and leave raw_entry unimplemented.
 | 
					 | 
				
			||||||
    mem->accelerometer.raw_entry.x = -2 * accelerometer_entry.x;
 | 
					    mem->accelerometer.raw_entry.x = -2 * accelerometer_entry.x;
 | 
				
			||||||
    mem->accelerometer.raw_entry.z = 2 * accelerometer_entry.y;
 | 
					    mem->accelerometer.raw_entry.z = 2 * accelerometer_entry.y;
 | 
				
			||||||
    mem->accelerometer.raw_entry.y = -2 * accelerometer_entry.z;
 | 
					    mem->accelerometer.raw_entry.y = -2 * accelerometer_entry.z;
 | 
				
			||||||
@ -160,10 +167,14 @@ void Update() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event_accelerometer->Signal();
 | 
					    event_accelerometer->Signal();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update gyroscope
 | 
					    // Reschedule recurrent event
 | 
				
			||||||
    if (enable_gyroscope_count > 0) {
 | 
					    CoreTiming::ScheduleEvent(accelerometer_update_ticks - cycles_late, accelerometer_update_event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void UpdateGyroscopeCallback(u64 userdata, int cycles_late) {
 | 
				
			||||||
 | 
					    SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mem->gyroscope.index = next_gyroscope_index;
 | 
					    mem->gyroscope.index = next_gyroscope_index;
 | 
				
			||||||
    next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size();
 | 
					    next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -183,7 +194,9 @@ void Update() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event_gyroscope->Signal();
 | 
					    event_gyroscope->Signal();
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
 | 
					    // Reschedule recurrent event
 | 
				
			||||||
 | 
					    CoreTiming::ScheduleEvent(gyroscope_update_ticks - cycles_late, gyroscope_update_event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GetIPCHandles(Service::Interface* self) {
 | 
					void GetIPCHandles(Service::Interface* self) {
 | 
				
			||||||
@ -204,7 +217,11 @@ void EnableAccelerometer(Service::Interface* self) {
 | 
				
			|||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ++enable_accelerometer_count;
 | 
					    ++enable_accelerometer_count;
 | 
				
			||||||
    event_accelerometer->Signal();
 | 
					
 | 
				
			||||||
 | 
					    // Schedules the accelerometer update event if the accelerometer was just enabled
 | 
				
			||||||
 | 
					    if (enable_accelerometer_count == 1) {
 | 
				
			||||||
 | 
					        CoreTiming::ScheduleEvent(accelerometer_update_ticks, accelerometer_update_event);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -215,7 +232,11 @@ void DisableAccelerometer(Service::Interface* self) {
 | 
				
			|||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    --enable_accelerometer_count;
 | 
					    --enable_accelerometer_count;
 | 
				
			||||||
    event_accelerometer->Signal();
 | 
					
 | 
				
			||||||
 | 
					    // Unschedules the accelerometer update event if the accelerometer was just disabled
 | 
				
			||||||
 | 
					    if (enable_accelerometer_count == 0) {
 | 
				
			||||||
 | 
					        CoreTiming::UnscheduleEvent(accelerometer_update_event, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -226,7 +247,11 @@ void EnableGyroscopeLow(Service::Interface* self) {
 | 
				
			|||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ++enable_gyroscope_count;
 | 
					    ++enable_gyroscope_count;
 | 
				
			||||||
    event_gyroscope->Signal();
 | 
					
 | 
				
			||||||
 | 
					    // Schedules the gyroscope update event if the gyroscope was just enabled
 | 
				
			||||||
 | 
					    if (enable_gyroscope_count == 1) {
 | 
				
			||||||
 | 
					        CoreTiming::ScheduleEvent(gyroscope_update_ticks, gyroscope_update_event);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -237,7 +262,11 @@ void DisableGyroscopeLow(Service::Interface* self) {
 | 
				
			|||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    --enable_gyroscope_count;
 | 
					    --enable_gyroscope_count;
 | 
				
			||||||
    event_gyroscope->Signal();
 | 
					
 | 
				
			||||||
 | 
					    // Unschedules the gyroscope update event if the gyroscope was just disabled
 | 
				
			||||||
 | 
					    if (enable_gyroscope_count == 0) {
 | 
				
			||||||
 | 
					        CoreTiming::UnscheduleEvent(gyroscope_update_event, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -298,6 +327,15 @@ void Init() {
 | 
				
			|||||||
    event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer");
 | 
					    event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer");
 | 
				
			||||||
    event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope");
 | 
					    event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope");
 | 
				
			||||||
    event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad");
 | 
					    event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Register update callbacks
 | 
				
			||||||
 | 
					    pad_update_event = CoreTiming::RegisterEvent("HID::UpdatePadCallback", UpdatePadCallback);
 | 
				
			||||||
 | 
					    accelerometer_update_event =
 | 
				
			||||||
 | 
					        CoreTiming::RegisterEvent("HID::UpdateAccelerometerCallback", UpdateAccelerometerCallback);
 | 
				
			||||||
 | 
					    gyroscope_update_event =
 | 
				
			||||||
 | 
					        CoreTiming::RegisterEvent("HID::UpdateGyroscopeCallback", UpdateGyroscopeCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Shutdown() {
 | 
					void Shutdown() {
 | 
				
			||||||
 | 
				
			|||||||
@ -296,9 +296,6 @@ void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void GetGyroscopeLowCalibrateParam(Service::Interface* self);
 | 
					void GetGyroscopeLowCalibrateParam(Service::Interface* self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Checks for user input updates
 | 
					 | 
				
			||||||
void Update();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Initialize HID service
 | 
					/// Initialize HID service
 | 
				
			||||||
void Init();
 | 
					void Init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,6 @@
 | 
				
			|||||||
#include "common/vector_math.h"
 | 
					#include "common/vector_math.h"
 | 
				
			||||||
#include "core/core_timing.h"
 | 
					#include "core/core_timing.h"
 | 
				
			||||||
#include "core/hle/service/gsp_gpu.h"
 | 
					#include "core/hle/service/gsp_gpu.h"
 | 
				
			||||||
#include "core/hle/service/hid/hid.h"
 | 
					 | 
				
			||||||
#include "core/hw/gpu.h"
 | 
					#include "core/hw/gpu.h"
 | 
				
			||||||
#include "core/hw/hw.h"
 | 
					#include "core/hw/hw.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
@ -33,7 +32,7 @@ namespace GPU {
 | 
				
			|||||||
Regs g_regs;
 | 
					Regs g_regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// 268MHz CPU clocks / 60Hz frames per second
 | 
					/// 268MHz CPU clocks / 60Hz frames per second
 | 
				
			||||||
const u64 frame_ticks = 268123480ull / 60;
 | 
					const u64 frame_ticks = BASE_CLOCK_RATE_ARM11 / 60;
 | 
				
			||||||
/// Event id for CoreTiming
 | 
					/// Event id for CoreTiming
 | 
				
			||||||
static int vblank_event;
 | 
					static int vblank_event;
 | 
				
			||||||
/// Total number of frames drawn
 | 
					/// Total number of frames drawn
 | 
				
			||||||
@ -551,9 +550,6 @@ static void VBlankCallback(u64 userdata, int cycles_late) {
 | 
				
			|||||||
    Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0);
 | 
					    Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0);
 | 
				
			||||||
    Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1);
 | 
					    Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Check for user input updates
 | 
					 | 
				
			||||||
    Service::HID::Update();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!Settings::values.use_vsync && Settings::values.toggle_framelimit) {
 | 
					    if (!Settings::values.use_vsync && Settings::values.toggle_framelimit) {
 | 
				
			||||||
        FrameLimiter();
 | 
					        FrameLimiter();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user