diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/core/core.cpp | 3 | ||||
-rw-r--r-- | src/core/core_timing_util.cpp | 84 | ||||
-rw-r--r-- | src/core/core_timing_util.h | 61 | ||||
-rw-r--r-- | src/core/frontend/applets/controller.h | 1 | ||||
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 9 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 63 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 26 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 7 | ||||
-rw-r--r-- | src/core/hle/service/time/time_manager.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/time/time_manager.h | 2 |
12 files changed, 161 insertions, 104 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e74e6a668..c6bdf72ec 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -19,7 +19,6 @@ add_library(core STATIC core.h core_timing.cpp core_timing.h - core_timing_util.cpp core_timing_util.h cpu_manager.cpp cpu_manager.h @@ -266,6 +265,7 @@ add_library(core STATIC hle/service/am/applets/software_keyboard.h hle/service/am/applets/web_browser.cpp hle/service/am/applets/web_browser.h + hle/service/am/applets/web_types.h hle/service/am/idle.cpp hle/service/am/idle.h hle/service/am/omm.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 30f5e1128..de6305e2a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -308,6 +308,9 @@ struct System::Impl { // Close all CPU/threading state cpu_manager.Shutdown(); + // Release the Time Manager's resources + time_manager.Shutdown(); + // Shutdown kernel and core timing core_timing.Shutdown(); kernel.Shutdown(); diff --git a/src/core/core_timing_util.cpp b/src/core/core_timing_util.cpp deleted file mode 100644 index 8ce8e602e..000000000 --- a/src/core/core_timing_util.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project / 2017 Citra Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "core/core_timing_util.h" - -#include <cinttypes> -#include <limits> -#include "common/logging/log.h" -#include "common/uint128.h" -#include "core/hardware_properties.h" - -namespace Core::Timing { - -constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / Hardware::BASE_CLOCK_RATE; - -s64 msToCycles(std::chrono::milliseconds ms) { - if (static_cast<u64>(ms.count() / 1000) > MAX_VALUE_TO_MULTIPLY) { - LOG_ERROR(Core_Timing, "Integer overflow, use max value"); - return std::numeric_limits<s64>::max(); - } - if (static_cast<u64>(ms.count()) > MAX_VALUE_TO_MULTIPLY) { - LOG_DEBUG(Core_Timing, "Time very big, do rounding"); - return Hardware::BASE_CLOCK_RATE * (ms.count() / 1000); - } - return (Hardware::BASE_CLOCK_RATE * ms.count()) / 1000; -} - -s64 usToCycles(std::chrono::microseconds us) { - if (static_cast<u64>(us.count() / 1000000) > MAX_VALUE_TO_MULTIPLY) { - LOG_ERROR(Core_Timing, "Integer overflow, use max value"); - return std::numeric_limits<s64>::max(); - } - if (static_cast<u64>(us.count()) > MAX_VALUE_TO_MULTIPLY) { - LOG_DEBUG(Core_Timing, "Time very big, do rounding"); - return Hardware::BASE_CLOCK_RATE * (us.count() / 1000000); - } - return (Hardware::BASE_CLOCK_RATE * us.count()) / 1000000; -} - -s64 nsToCycles(std::chrono::nanoseconds ns) { - const u128 temporal = Common::Multiply64Into128(ns.count(), Hardware::BASE_CLOCK_RATE); - return Common::Divide128On32(temporal, static_cast<u32>(1000000000)).first; -} - -u64 msToClockCycles(std::chrono::milliseconds ns) { - const u128 temp = Common::Multiply64Into128(ns.count(), Hardware::CNTFREQ); - return Common::Divide128On32(temp, 1000).first; -} - -u64 usToClockCycles(std::chrono::microseconds ns) { - const u128 temp = Common::Multiply64Into128(ns.count(), Hardware::CNTFREQ); - return Common::Divide128On32(temp, 1000000).first; -} - -u64 nsToClockCycles(std::chrono::nanoseconds ns) { - const u128 temp = Common::Multiply64Into128(ns.count(), Hardware::CNTFREQ); - return Common::Divide128On32(temp, 1000000000).first; -} - -u64 CpuCyclesToClockCycles(u64 ticks) { - const u128 temporal = Common::Multiply64Into128(ticks, Hardware::CNTFREQ); - return Common::Divide128On32(temporal, static_cast<u32>(Hardware::BASE_CLOCK_RATE)).first; -} - -std::chrono::milliseconds CyclesToMs(s64 cycles) { - const u128 temporal = Common::Multiply64Into128(cycles, 1000); - u64 ms = Common::Divide128On32(temporal, static_cast<u32>(Hardware::BASE_CLOCK_RATE)).first; - return std::chrono::milliseconds(ms); -} - -std::chrono::nanoseconds CyclesToNs(s64 cycles) { - const u128 temporal = Common::Multiply64Into128(cycles, 1000000000); - u64 ns = Common::Divide128On32(temporal, static_cast<u32>(Hardware::BASE_CLOCK_RATE)).first; - return std::chrono::nanoseconds(ns); -} - -std::chrono::microseconds CyclesToUs(s64 cycles) { - const u128 temporal = Common::Multiply64Into128(cycles, 1000000); - u64 us = Common::Divide128On32(temporal, static_cast<u32>(Hardware::BASE_CLOCK_RATE)).first; - return std::chrono::microseconds(us); -} - -} // namespace Core::Timing diff --git a/src/core/core_timing_util.h b/src/core/core_timing_util.h index e4a046bf9..14c36a485 100644 --- a/src/core/core_timing_util.h +++ b/src/core/core_timing_util.h @@ -1,24 +1,59 @@ -// Copyright 2008 Dolphin Emulator Project / 2017 Citra Emulator Project -// Licensed under GPLv2+ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include <chrono> + #include "common/common_types.h" +#include "core/hardware_properties.h" namespace Core::Timing { -s64 msToCycles(std::chrono::milliseconds ms); -s64 usToCycles(std::chrono::microseconds us); -s64 nsToCycles(std::chrono::nanoseconds ns); -u64 msToClockCycles(std::chrono::milliseconds ns); -u64 usToClockCycles(std::chrono::microseconds ns); -u64 nsToClockCycles(std::chrono::nanoseconds ns); -std::chrono::milliseconds CyclesToMs(s64 cycles); -std::chrono::nanoseconds CyclesToNs(s64 cycles); -std::chrono::microseconds CyclesToUs(s64 cycles); - -u64 CpuCyclesToClockCycles(u64 ticks); +namespace detail { +constexpr u64 CNTFREQ_ADJUSTED = Hardware::CNTFREQ / 1000; +constexpr u64 BASE_CLOCK_RATE_ADJUSTED = Hardware::BASE_CLOCK_RATE / 1000; +} // namespace detail + +[[nodiscard]] constexpr s64 msToCycles(std::chrono::milliseconds ms) { + return ms.count() * detail::BASE_CLOCK_RATE_ADJUSTED; +} + +[[nodiscard]] constexpr s64 usToCycles(std::chrono::microseconds us) { + return us.count() * detail::BASE_CLOCK_RATE_ADJUSTED / 1000; +} + +[[nodiscard]] constexpr s64 nsToCycles(std::chrono::nanoseconds ns) { + return ns.count() * detail::BASE_CLOCK_RATE_ADJUSTED / 1000000; +} + +[[nodiscard]] constexpr u64 msToClockCycles(std::chrono::milliseconds ms) { + return static_cast<u64>(ms.count()) * detail::CNTFREQ_ADJUSTED; +} + +[[nodiscard]] constexpr u64 usToClockCycles(std::chrono::microseconds us) { + return us.count() * detail::CNTFREQ_ADJUSTED / 1000; +} + +[[nodiscard]] constexpr u64 nsToClockCycles(std::chrono::nanoseconds ns) { + return ns.count() * detail::CNTFREQ_ADJUSTED / 1000000; +} + +[[nodiscard]] constexpr u64 CpuCyclesToClockCycles(u64 ticks) { + return ticks * detail::CNTFREQ_ADJUSTED / detail::BASE_CLOCK_RATE_ADJUSTED; +} + +[[nodiscard]] constexpr std::chrono::milliseconds CyclesToMs(s64 cycles) { + return std::chrono::milliseconds(cycles / detail::BASE_CLOCK_RATE_ADJUSTED); +} + +[[nodiscard]] constexpr std::chrono::nanoseconds CyclesToNs(s64 cycles) { + return std::chrono::nanoseconds(cycles * 1000000 / detail::BASE_CLOCK_RATE_ADJUSTED); +} + +[[nodiscard]] constexpr std::chrono::microseconds CyclesToUs(s64 cycles) { + return std::chrono::microseconds(cycles * 1000 / detail::BASE_CLOCK_RATE_ADJUSTED); +} } // namespace Core::Timing diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h index dff71d8d9..b0626a0f9 100644 --- a/src/core/frontend/applets/controller.h +++ b/src/core/frontend/applets/controller.h @@ -31,6 +31,7 @@ struct ControllerParameters { bool allow_dual_joycons{}; bool allow_left_joycon{}; bool allow_right_joycon{}; + bool allow_gamecube_controller{}; }; class ControllerApplet { diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b6e6f115e..39c5182c5 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -101,8 +101,6 @@ struct KernelCore::Impl { current_process = nullptr; - system_resource_limit = nullptr; - global_handle_table.Clear(); preemption_event = nullptr; @@ -111,6 +109,13 @@ struct KernelCore::Impl { exclusive_monitor.reset(); + hid_shared_mem = nullptr; + font_shared_mem = nullptr; + irs_shared_mem = nullptr; + time_shared_mem = nullptr; + + system_resource_limit = nullptr; + // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; } diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index dbf198345..70b9f3824 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -21,6 +21,7 @@ namespace Service::HID { constexpr s32 HID_JOYSTICK_MAX = 0x7fff; +constexpr s32 HID_TRIGGER_MAX = 0x7fff; [[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff; constexpr std::size_t NPAD_OFFSET = 0x9A00; constexpr u32 BATTERY_FULL = 2; @@ -48,6 +49,8 @@ Controller_NPad::NPadControllerType Controller_NPad::MapSettingsTypeToNPad( return NPadControllerType::JoyRight; case Settings::ControllerType::Handheld: return NPadControllerType::Handheld; + case Settings::ControllerType::GameCube: + return NPadControllerType::GameCube; default: UNREACHABLE(); return NPadControllerType::ProController; @@ -67,6 +70,8 @@ Settings::ControllerType Controller_NPad::MapNPadToSettingsType( return Settings::ControllerType::RightJoycon; case NPadControllerType::Handheld: return Settings::ControllerType::Handheld; + case NPadControllerType::GameCube: + return Settings::ControllerType::GameCube; default: UNREACHABLE(); return Settings::ControllerType::ProController; @@ -209,6 +214,13 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.assignment_mode = NpadAssignments::Single; controller.footer_type = AppletFooterUiType::JoyRightHorizontal; break; + case NPadControllerType::GameCube: + controller.style_set.gamecube.Assign(1); + // The GC Controller behaves like a wired Pro Controller + controller.device_type.fullkey.Assign(1); + controller.system_properties.is_vertical.Assign(1); + controller.system_properties.use_plus.Assign(1); + break; case NPadControllerType::Pokeball: controller.style_set.palma.Assign(1); controller.device_type.palma.Assign(1); @@ -259,6 +271,7 @@ void Controller_NPad::OnInit() { style.joycon_right.Assign(1); style.joycon_dual.Assign(1); style.fullkey.Assign(1); + style.gamecube.Assign(1); style.palma.Assign(1); } @@ -339,6 +352,7 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { auto& pad_state = npad_pad_states[controller_idx].pad_states; auto& lstick_entry = npad_pad_states[controller_idx].l_stick; auto& rstick_entry = npad_pad_states[controller_idx].r_stick; + auto& trigger_entry = npad_trigger_states[controller_idx]; const auto& button_state = buttons[controller_idx]; const auto& analog_state = sticks[controller_idx]; const auto [stick_l_x_f, stick_l_y_f] = @@ -404,6 +418,17 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); } + + if (controller_type == NPadControllerType::GameCube) { + trigger_entry.l_analog = static_cast<s32>( + button_state[ZL - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); + trigger_entry.r_analog = static_cast<s32>( + button_state[ZR - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); + pad_state.zl.Assign(false); + pad_state.zr.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.l.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); + pad_state.r.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); + } } void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, @@ -418,6 +443,11 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states, &npad.system_ext_states}; + // There is the posibility to have more controllers with analog triggers + const std::array<TriggerGeneric*, 1> controller_triggers{ + &npad.gc_trigger_states, + }; + for (auto* main_controller : controller_npads) { main_controller->common.entry_count = 16; main_controller->common.total_entry_count = 17; @@ -435,6 +465,21 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.timestamp2 = cur_entry.timestamp; } + for (auto* analog_trigger : controller_triggers) { + analog_trigger->entry_count = 16; + analog_trigger->total_entry_count = 17; + + const auto& last_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; + + analog_trigger->timestamp = core_timing.GetCPUTicks(); + analog_trigger->last_entry_index = (analog_trigger->last_entry_index + 1) % 17; + + auto& cur_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; + + cur_entry.timestamp = last_entry.timestamp + 1; + cur_entry.timestamp2 = cur_entry.timestamp; + } + const auto& controller_type = connected_controllers[i].type; if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { @@ -444,6 +489,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* RequestPadStateUpdate(npad_index); auto& pad_state = npad_pad_states[npad_index]; + auto& trigger_state = npad_trigger_states[npad_index]; auto& main_controller = npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index]; @@ -456,6 +502,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index]; auto& libnx_entry = npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; + auto& trigger_entry = + npad.gc_trigger_states.trigger[npad.gc_trigger_states.last_entry_index]; libnx_entry.connection_status.raw = 0; libnx_entry.connection_status.is_connected.Assign(1); @@ -524,6 +572,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* libnx_entry.connection_status.is_right_connected.Assign(1); break; + case NPadControllerType::GameCube: + main_controller.connection_status.raw = 0; + main_controller.connection_status.is_connected.Assign(1); + main_controller.connection_status.is_wired.Assign(1); + main_controller.pad.pad_states.raw = pad_state.pad_states.raw; + main_controller.pad.l_stick = pad_state.l_stick; + main_controller.pad.r_stick = pad_state.r_stick; + trigger_entry.l_analog = trigger_state.l_analog; + trigger_entry.r_analog = trigger_state.r_analog; + + libnx_entry.connection_status.is_wired.Assign(1); + break; case NPadControllerType::Pokeball: pokeball_entry.connection_status.raw = 0; pokeball_entry.connection_status.is_connected.Assign(1); @@ -674,6 +734,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing right_sixaxis_entry.orientation = motion_devices[1].orientation; } break; + case NPadControllerType::GameCube: case NPadControllerType::Pokeball: break; } @@ -1135,6 +1196,8 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const return style.joycon_left; case NPadControllerType::JoyRight: return style.joycon_right; + case NPadControllerType::GameCube: + return style.gamecube; case NPadControllerType::Pokeball: return style.palma; default: diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 48bab988c..bc2e6779d 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -51,6 +51,7 @@ public: JoyDual, JoyLeft, JoyRight, + GameCube, Pokeball, }; @@ -60,6 +61,7 @@ public: JoyconDual = 5, JoyconLeft = 6, JoyconRight = 7, + GameCube = 8, Pokeball = 9, MaxNpadType = 10, }; @@ -389,6 +391,25 @@ private: }; static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); + struct TriggerState { + s64_le timestamp{}; + s64_le timestamp2{}; + s32_le l_analog{}; + s32_le r_analog{}; + }; + static_assert(sizeof(TriggerState) == 0x18, "TriggerState is an invalid size"); + + struct TriggerGeneric { + INSERT_PADDING_BYTES(0x4); + s64_le timestamp; + INSERT_PADDING_BYTES(0x4); + s64_le total_entry_count; + s64_le last_entry_index; + s64_le entry_count; + std::array<TriggerState, 17> trigger{}; + }; + static_assert(sizeof(TriggerGeneric) == 0x1C8, "TriggerGeneric is an invalid size"); + struct NPadSystemProperties { union { s64_le raw{}; @@ -509,7 +530,9 @@ private: AppletFooterUiType footer_type; // nfc_states needs to be checked switchbrew does not match with HW NfcXcdHandle nfc_states; - INSERT_PADDING_BYTES(0xdef); + INSERT_PADDING_BYTES(0x8); // Mutex + TriggerGeneric gc_trigger_states; + INSERT_PADDING_BYTES(0xc1f); }; static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); @@ -560,6 +583,7 @@ private: f32 sixaxis_fusion_parameter2{}; bool sixaxis_at_rest{true}; std::array<ControllerPad, 10> npad_pad_states{}; + std::array<TriggerState, 10> npad_trigger_states{}; bool is_in_lr_assignment_mode{false}; Core::System& system; }; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 36970f828..ecba1dba1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -34,8 +34,7 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, case 0xa: { if (command.length == 0x1c) { LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); - Tegra::ChCommandHeaderList cmdlist(1); - cmdlist[0] = Tegra::ChCommandHeader{0xDEADB33F}; + Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; system.GPU().PushCommandBuffer(cmdlist); } return UnmapBuffer(input, output); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 72499654c..70849a9bd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -28,8 +28,13 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve return GetWaitbase(input, output); case 0x9: return MapBuffer(input, output); - case 0xa: + case 0xa: { + if (command.length == 0x1c) { + Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; + system.GPU().PushCommandBuffer(cmdlist); + } return UnmapBuffer(input, output); + } default: break; } diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index 858623e2b..1f7309f6b 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp @@ -279,6 +279,10 @@ const SharedMemory& TimeManager::GetSharedMemory() const { return impl->shared_memory; } +void TimeManager::Shutdown() { + impl.reset(); +} + void TimeManager::UpdateLocalSystemClockTime(s64 posix_time) { impl->UpdateLocalSystemClockTime(system, posix_time); } diff --git a/src/core/hle/service/time/time_manager.h b/src/core/hle/service/time/time_manager.h index 993c7c288..4db8cc0e1 100644 --- a/src/core/hle/service/time/time_manager.h +++ b/src/core/hle/service/time/time_manager.h @@ -61,6 +61,8 @@ public: const SharedMemory& GetSharedMemory() const; + void Shutdown(); + void SetupTimeZoneManager(std::string location_name, Clock::SteadyClockTimePoint time_zone_updated_time_point, std::size_t total_location_name_count, u128 time_zone_rule_version, |