diff options
| author | 2017-01-16 19:38:35 -0300 | |
|---|---|---|
| committer | 2017-01-16 19:38:35 -0300 | |
| commit | 55c91ae782f9a05411ba869f7a83de87d29a0adf (patch) | |
| tree | f40e211ce132a79fa9dbff5a74980d0a84bde3ff | |
| parent | Merge pull request #2435 from mailwl/gsp-mask (diff) | |
| parent | CoreTiming: use named constant for ARM11 clock rate (diff) | |
| download | yuzu-55c91ae782f9a05411ba869f7a83de87d29a0adf.tar.gz yuzu-55c91ae782f9a05411ba869f7a83de87d29a0adf.tar.xz yuzu-55c91ae782f9a05411ba869f7a83de87d29a0adf.zip | |
Merge pull request #2442 from wwylele/hid-signal
HID: manages updating itself using correct ticks
Diffstat (limited to '')
| -rw-r--r-- | src/core/core_timing.cpp | 2 | ||||
| -rw-r--r-- | src/core/core_timing.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 148 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 3 | ||||
| -rw-r--r-- | src/core/hw/gpu.cpp | 6 |
5 files changed, 96 insertions, 64 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index a437d0823..276ecfdf6 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include "core/core.h" | 13 | #include "core/core.h" |
| 14 | #include "core/core_timing.h" | 14 | #include "core/core_timing.h" |
| 15 | 15 | ||
| 16 | int g_clock_rate_arm11 = 268123480; | 16 | int g_clock_rate_arm11 = BASE_CLOCK_RATE_ARM11; |
| 17 | 17 | ||
| 18 | // is this really necessary? | 18 | // is this really necessary? |
| 19 | #define INITIAL_SLICE_LENGTH 20000 | 19 | #define INITIAL_SLICE_LENGTH 20000 |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index b72a1b500..d2f85cd4d 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | // inside callback: | 21 | // inside callback: |
| 22 | // ScheduleEvent(periodInCycles - cycles_late, callback, "whatever") | 22 | // ScheduleEvent(periodInCycles - cycles_late, callback, "whatever") |
| 23 | 23 | ||
| 24 | constexpr int BASE_CLOCK_RATE_ARM11 = 268123480; | ||
| 24 | extern int g_clock_rate_arm11; | 25 | extern int g_clock_rate_arm11; |
| 25 | 26 | ||
| 26 | inline s64 msToCycles(int ms) { | 27 | inline s64 msToCycles(int ms) { |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 676154bd4..9bca97c1c 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -35,6 +35,15 @@ static u32 next_gyroscope_index; | |||
| 35 | static int enable_accelerometer_count = 0; // positive means enabled | 35 | static int enable_accelerometer_count = 0; // positive means enabled |
| 36 | static int enable_gyroscope_count = 0; // positive means enabled | 36 | static int enable_gyroscope_count = 0; // positive means enabled |
| 37 | 37 | ||
| 38 | static int pad_update_event; | ||
| 39 | static int accelerometer_update_event; | ||
| 40 | static int gyroscope_update_event; | ||
| 41 | |||
| 42 | // Updating period for each HID device. These empirical values are measured from a 11.2 3DS. | ||
| 43 | constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234; | ||
| 44 | constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104; | ||
| 45 | constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101; | ||
| 46 | |||
| 38 | static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { | 47 | static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { |
| 39 | // 30 degree and 60 degree are angular thresholds for directions | 48 | // 30 degree and 60 degree are angular thresholds for directions |
| 40 | constexpr float TAN30 = 0.577350269f; | 49 | constexpr float TAN30 = 0.577350269f; |
| @@ -65,14 +74,9 @@ static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { | |||
| 65 | return state; | 74 | return state; |
| 66 | } | 75 | } |
| 67 | 76 | ||
| 68 | void Update() { | 77 | static void UpdatePadCallback(u64 userdata, int cycles_late) { |
| 69 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); | 78 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); |
| 70 | 79 | ||
| 71 | if (mem == nullptr) { | ||
| 72 | LOG_DEBUG(Service_HID, "Cannot update HID prior to mapping shared memory!"); | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | |||
| 76 | PadState state = VideoCore::g_emu_window->GetPadState(); | 80 | PadState state = VideoCore::g_emu_window->GetPadState(); |
| 77 | 81 | ||
| 78 | // Get current circle pad position and update circle pad direction | 82 | // Get current circle pad position and update circle pad direction |
| @@ -131,59 +135,68 @@ void Update() { | |||
| 131 | event_pad_or_touch_1->Signal(); | 135 | event_pad_or_touch_1->Signal(); |
| 132 | event_pad_or_touch_2->Signal(); | 136 | event_pad_or_touch_2->Signal(); |
| 133 | 137 | ||
| 134 | // Update accelerometer | 138 | // Reschedule recurrent event |
| 135 | if (enable_accelerometer_count > 0) { | 139 | CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); |
| 136 | mem->accelerometer.index = next_accelerometer_index; | 140 | } |
| 137 | next_accelerometer_index = | 141 | |
| 138 | (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); | 142 | static void UpdateAccelerometerCallback(u64 userdata, int cycles_late) { |
| 139 | 143 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); | |
| 140 | AccelerometerDataEntry& accelerometer_entry = | 144 | |
| 141 | mem->accelerometer.entries[mem->accelerometer.index]; | 145 | mem->accelerometer.index = next_accelerometer_index; |
| 142 | std::tie(accelerometer_entry.x, accelerometer_entry.y, accelerometer_entry.z) = | 146 | next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); |
| 143 | VideoCore::g_emu_window->GetAccelerometerState(); | ||
| 144 | |||
| 145 | // Make up "raw" entry | ||
| 146 | // TODO(wwylele): | ||
| 147 | // From hardware testing, the raw_entry values are approximately, | ||
| 148 | // but not exactly, as twice as corresponding entries (or with a minus sign). | ||
| 149 | // It may caused by system calibration to the accelerometer. | ||
| 150 | // Figure out how it works, or, if no game reads raw_entry, | ||
| 151 | // the following three lines can be removed and leave raw_entry unimplemented. | ||
| 152 | mem->accelerometer.raw_entry.x = -2 * accelerometer_entry.x; | ||
| 153 | mem->accelerometer.raw_entry.z = 2 * accelerometer_entry.y; | ||
| 154 | mem->accelerometer.raw_entry.y = -2 * accelerometer_entry.z; | ||
| 155 | |||
| 156 | // If we just updated index 0, provide a new timestamp | ||
| 157 | if (mem->accelerometer.index == 0) { | ||
| 158 | mem->accelerometer.index_reset_ticks_previous = mem->accelerometer.index_reset_ticks; | ||
| 159 | mem->accelerometer.index_reset_ticks = (s64)CoreTiming::GetTicks(); | ||
| 160 | } | ||
| 161 | 147 | ||
| 162 | event_accelerometer->Signal(); | 148 | AccelerometerDataEntry& accelerometer_entry = |
| 149 | mem->accelerometer.entries[mem->accelerometer.index]; | ||
| 150 | std::tie(accelerometer_entry.x, accelerometer_entry.y, accelerometer_entry.z) = | ||
| 151 | VideoCore::g_emu_window->GetAccelerometerState(); | ||
| 152 | |||
| 153 | // Make up "raw" entry | ||
| 154 | // TODO(wwylele): | ||
| 155 | // From hardware testing, the raw_entry values are approximately, but not exactly, as twice as | ||
| 156 | // corresponding entries (or with a minus sign). It may caused by system calibration to the | ||
| 157 | // accelerometer. Figure out how it works, or, if no game reads raw_entry, the following three | ||
| 158 | // lines can be removed and leave raw_entry unimplemented. | ||
| 159 | mem->accelerometer.raw_entry.x = -2 * accelerometer_entry.x; | ||
| 160 | mem->accelerometer.raw_entry.z = 2 * accelerometer_entry.y; | ||
| 161 | mem->accelerometer.raw_entry.y = -2 * accelerometer_entry.z; | ||
| 162 | |||
| 163 | // If we just updated index 0, provide a new timestamp | ||
| 164 | if (mem->accelerometer.index == 0) { | ||
| 165 | mem->accelerometer.index_reset_ticks_previous = mem->accelerometer.index_reset_ticks; | ||
| 166 | mem->accelerometer.index_reset_ticks = (s64)CoreTiming::GetTicks(); | ||
| 163 | } | 167 | } |
| 164 | 168 | ||
| 165 | // Update gyroscope | 169 | event_accelerometer->Signal(); |
| 166 | if (enable_gyroscope_count > 0) { | ||
| 167 | mem->gyroscope.index = next_gyroscope_index; | ||
| 168 | next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size(); | ||
| 169 | 170 | ||
| 170 | GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; | 171 | // Reschedule recurrent event |
| 171 | std::tie(gyroscope_entry.x, gyroscope_entry.y, gyroscope_entry.z) = | 172 | CoreTiming::ScheduleEvent(accelerometer_update_ticks - cycles_late, accelerometer_update_event); |
| 172 | VideoCore::g_emu_window->GetGyroscopeState(); | 173 | } |
| 173 | 174 | ||
| 174 | // Make up "raw" entry | 175 | static void UpdateGyroscopeCallback(u64 userdata, int cycles_late) { |
| 175 | mem->gyroscope.raw_entry.x = gyroscope_entry.x; | 176 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); |
| 176 | mem->gyroscope.raw_entry.z = -gyroscope_entry.y; | ||
| 177 | mem->gyroscope.raw_entry.y = gyroscope_entry.z; | ||
| 178 | 177 | ||
| 179 | // If we just updated index 0, provide a new timestamp | 178 | mem->gyroscope.index = next_gyroscope_index; |
| 180 | if (mem->gyroscope.index == 0) { | 179 | next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size(); |
| 181 | mem->gyroscope.index_reset_ticks_previous = mem->gyroscope.index_reset_ticks; | 180 | |
| 182 | mem->gyroscope.index_reset_ticks = (s64)CoreTiming::GetTicks(); | 181 | GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; |
| 183 | } | 182 | std::tie(gyroscope_entry.x, gyroscope_entry.y, gyroscope_entry.z) = |
| 183 | VideoCore::g_emu_window->GetGyroscopeState(); | ||
| 184 | |||
| 185 | // Make up "raw" entry | ||
| 186 | mem->gyroscope.raw_entry.x = gyroscope_entry.x; | ||
| 187 | mem->gyroscope.raw_entry.z = -gyroscope_entry.y; | ||
| 188 | mem->gyroscope.raw_entry.y = gyroscope_entry.z; | ||
| 184 | 189 | ||
| 185 | event_gyroscope->Signal(); | 190 | // If we just updated index 0, provide a new timestamp |
| 191 | if (mem->gyroscope.index == 0) { | ||
| 192 | mem->gyroscope.index_reset_ticks_previous = mem->gyroscope.index_reset_ticks; | ||
| 193 | mem->gyroscope.index_reset_ticks = (s64)CoreTiming::GetTicks(); | ||
| 186 | } | 194 | } |
| 195 | |||
| 196 | event_gyroscope->Signal(); | ||
| 197 | |||
| 198 | // Reschedule recurrent event | ||
| 199 | CoreTiming::ScheduleEvent(gyroscope_update_ticks - cycles_late, gyroscope_update_event); | ||
| 187 | } | 200 | } |
| 188 | 201 | ||
| 189 | void GetIPCHandles(Service::Interface* self) { | 202 | void GetIPCHandles(Service::Interface* self) { |
| @@ -204,7 +217,11 @@ void EnableAccelerometer(Service::Interface* self) { | |||
| 204 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 217 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 205 | 218 | ||
| 206 | ++enable_accelerometer_count; | 219 | ++enable_accelerometer_count; |
| 207 | event_accelerometer->Signal(); | 220 | |
| 221 | // Schedules the accelerometer update event if the accelerometer was just enabled | ||
| 222 | if (enable_accelerometer_count == 1) { | ||
| 223 | CoreTiming::ScheduleEvent(accelerometer_update_ticks, accelerometer_update_event); | ||
| 224 | } | ||
| 208 | 225 | ||
| 209 | cmd_buff[1] = RESULT_SUCCESS.raw; | 226 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 210 | 227 | ||
| @@ -215,7 +232,11 @@ void DisableAccelerometer(Service::Interface* self) { | |||
| 215 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 232 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 216 | 233 | ||
| 217 | --enable_accelerometer_count; | 234 | --enable_accelerometer_count; |
| 218 | event_accelerometer->Signal(); | 235 | |
| 236 | // Unschedules the accelerometer update event if the accelerometer was just disabled | ||
| 237 | if (enable_accelerometer_count == 0) { | ||
| 238 | CoreTiming::UnscheduleEvent(accelerometer_update_event, 0); | ||
| 239 | } | ||
| 219 | 240 | ||
| 220 | cmd_buff[1] = RESULT_SUCCESS.raw; | 241 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 221 | 242 | ||
| @@ -226,7 +247,11 @@ void EnableGyroscopeLow(Service::Interface* self) { | |||
| 226 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 247 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 227 | 248 | ||
| 228 | ++enable_gyroscope_count; | 249 | ++enable_gyroscope_count; |
| 229 | event_gyroscope->Signal(); | 250 | |
| 251 | // Schedules the gyroscope update event if the gyroscope was just enabled | ||
| 252 | if (enable_gyroscope_count == 1) { | ||
| 253 | CoreTiming::ScheduleEvent(gyroscope_update_ticks, gyroscope_update_event); | ||
| 254 | } | ||
| 230 | 255 | ||
| 231 | cmd_buff[1] = RESULT_SUCCESS.raw; | 256 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 232 | 257 | ||
| @@ -237,7 +262,11 @@ void DisableGyroscopeLow(Service::Interface* self) { | |||
| 237 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 262 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 238 | 263 | ||
| 239 | --enable_gyroscope_count; | 264 | --enable_gyroscope_count; |
| 240 | event_gyroscope->Signal(); | 265 | |
| 266 | // Unschedules the gyroscope update event if the gyroscope was just disabled | ||
| 267 | if (enable_gyroscope_count == 0) { | ||
| 268 | CoreTiming::UnscheduleEvent(gyroscope_update_event, 0); | ||
| 269 | } | ||
| 241 | 270 | ||
| 242 | cmd_buff[1] = RESULT_SUCCESS.raw; | 271 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 243 | 272 | ||
| @@ -298,6 +327,15 @@ void Init() { | |||
| 298 | event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); | 327 | event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); |
| 299 | event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); | 328 | event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); |
| 300 | event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); | 329 | event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); |
| 330 | |||
| 331 | // Register update callbacks | ||
| 332 | pad_update_event = CoreTiming::RegisterEvent("HID::UpdatePadCallback", UpdatePadCallback); | ||
| 333 | accelerometer_update_event = | ||
| 334 | CoreTiming::RegisterEvent("HID::UpdateAccelerometerCallback", UpdateAccelerometerCallback); | ||
| 335 | gyroscope_update_event = | ||
| 336 | CoreTiming::RegisterEvent("HID::UpdateGyroscopeCallback", UpdateGyroscopeCallback); | ||
| 337 | |||
| 338 | CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); | ||
| 301 | } | 339 | } |
| 302 | 340 | ||
| 303 | void Shutdown() { | 341 | void Shutdown() { |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 7904e7355..21e66dfe0 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -296,9 +296,6 @@ void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self); | |||
| 296 | */ | 296 | */ |
| 297 | void GetGyroscopeLowCalibrateParam(Service::Interface* self); | 297 | void GetGyroscopeLowCalibrateParam(Service::Interface* self); |
| 298 | 298 | ||
| 299 | /// Checks for user input updates | ||
| 300 | void Update(); | ||
| 301 | |||
| 302 | /// Initialize HID service | 299 | /// Initialize HID service |
| 303 | void Init(); | 300 | void Init(); |
| 304 | 301 | ||
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 1a1ee90b2..fa8c13d36 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include "common/vector_math.h" | 15 | #include "common/vector_math.h" |
| 16 | #include "core/core_timing.h" | 16 | #include "core/core_timing.h" |
| 17 | #include "core/hle/service/gsp_gpu.h" | 17 | #include "core/hle/service/gsp_gpu.h" |
| 18 | #include "core/hle/service/hid/hid.h" | ||
| 19 | #include "core/hw/gpu.h" | 18 | #include "core/hw/gpu.h" |
| 20 | #include "core/hw/hw.h" | 19 | #include "core/hw/hw.h" |
| 21 | #include "core/memory.h" | 20 | #include "core/memory.h" |
| @@ -33,7 +32,7 @@ namespace GPU { | |||
| 33 | Regs g_regs; | 32 | Regs g_regs; |
| 34 | 33 | ||
| 35 | /// 268MHz CPU clocks / 60Hz frames per second | 34 | /// 268MHz CPU clocks / 60Hz frames per second |
| 36 | const u64 frame_ticks = 268123480ull / 60; | 35 | const u64 frame_ticks = BASE_CLOCK_RATE_ARM11 / 60; |
| 37 | /// Event id for CoreTiming | 36 | /// Event id for CoreTiming |
| 38 | static int vblank_event; | 37 | static int vblank_event; |
| 39 | /// Total number of frames drawn | 38 | /// Total number of frames drawn |
| @@ -551,9 +550,6 @@ static void VBlankCallback(u64 userdata, int cycles_late) { | |||
| 551 | Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0); | 550 | Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0); |
| 552 | Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1); | 551 | Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1); |
| 553 | 552 | ||
| 554 | // Check for user input updates | ||
| 555 | Service::HID::Update(); | ||
| 556 | |||
| 557 | if (!Settings::values.use_vsync && Settings::values.toggle_framelimit) { | 553 | if (!Settings::values.use_vsync && Settings::values.toggle_framelimit) { |
| 558 | FrameLimiter(); | 554 | FrameLimiter(); |
| 559 | } | 555 | } |