summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/stream.cpp8
-rw-r--r--src/audio_core/stream.h3
-rw-r--r--src/core/hle/service/audio/audout_u.cpp10
-rw-r--r--src/core/hle/service/prepo/prepo.cpp11
-rw-r--r--src/video_core/memory_manager.cpp23
-rw-r--r--src/video_core/memory_manager.h6
-rw-r--r--src/yuzu/configuration/configure_input.cpp6
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp46
8 files changed, 94 insertions, 19 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index afe68c9ed..5b0b285cd 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -51,6 +51,14 @@ void Stream::Stop() {
51 UNIMPLEMENTED(); 51 UNIMPLEMENTED();
52} 52}
53 53
54bool Stream::Flush() {
55 const bool had_buffers = !queued_buffers.empty();
56 while (!queued_buffers.empty()) {
57 queued_buffers.pop();
58 }
59 return had_buffers;
60}
61
54void Stream::SetVolume(float volume) { 62void Stream::SetVolume(float volume) {
55 game_volume = volume; 63 game_volume = volume;
56} 64}
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index 506ac536b..559844b9b 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -56,6 +56,9 @@ public:
56 /// Queues a buffer into the audio stream, returns true on success 56 /// Queues a buffer into the audio stream, returns true on success
57 bool QueueBuffer(BufferPtr&& buffer); 57 bool QueueBuffer(BufferPtr&& buffer);
58 58
59 /// Flush audio buffers
60 bool Flush();
61
59 /// Returns true if the audio stream contains a buffer with the specified tag 62 /// Returns true if the audio stream contains a buffer with the specified tag
60 [[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const; 63 [[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const;
61 64
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 02ca711fb..273a46265 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -58,7 +58,7 @@ public:
58 {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, 58 {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
59 {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, 59 {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
60 {10, nullptr, "GetAudioOutPlayedSampleCount"}, 60 {10, nullptr, "GetAudioOutPlayedSampleCount"},
61 {11, nullptr, "FlushAudioOutBuffers"}, 61 {11, &IAudioOut::FlushAudioOutBuffers, "FlushAudioOutBuffers"},
62 {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"}, 62 {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"},
63 {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"}, 63 {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"},
64 }; 64 };
@@ -185,6 +185,14 @@ private:
185 rb.Push(static_cast<u32>(stream->GetQueueSize())); 185 rb.Push(static_cast<u32>(stream->GetQueueSize()));
186 } 186 }
187 187
188 void FlushAudioOutBuffers(Kernel::HLERequestContext& ctx) {
189 LOG_DEBUG(Service_Audio, "called");
190
191 IPC::ResponseBuilder rb{ctx, 3};
192 rb.Push(RESULT_SUCCESS);
193 rb.Push(stream->Flush());
194 }
195
188 void SetAudioOutVolume(Kernel::HLERequestContext& ctx) { 196 void SetAudioOutVolume(Kernel::HLERequestContext& ctx) {
189 IPC::RequestParser rp{ctx}; 197 IPC::RequestParser rp{ctx};
190 const float volume = rp.Pop<float>(); 198 const float volume = rp.Pop<float>();
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 6edd45455..86ecc5b97 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -27,7 +27,7 @@ public:
27 {10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"}, 27 {10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
28 {10200, nullptr, "RequestImmediateTransmission"}, 28 {10200, nullptr, "RequestImmediateTransmission"},
29 {10300, nullptr, "GetTransmissionStatus"}, 29 {10300, nullptr, "GetTransmissionStatus"},
30 {10400, nullptr, "GetSystemSessionId"}, 30 {10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
31 {20100, &PlayReport::SaveSystemReport, "SaveSystemReport"}, 31 {20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
32 {20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"}, 32 {20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
33 {20200, nullptr, "SetOperationMode"}, 33 {20200, nullptr, "SetOperationMode"},
@@ -108,6 +108,15 @@ private:
108 rb.Push(RESULT_SUCCESS); 108 rb.Push(RESULT_SUCCESS);
109 } 109 }
110 110
111 void GetSystemSessionId(Kernel::HLERequestContext& ctx) {
112 LOG_WARNING(Service_PREPO, "(STUBBED) called");
113
114 constexpr u64 system_session_id = 0;
115 IPC::ResponseBuilder rb{ctx, 4};
116 rb.Push(RESULT_SUCCESS);
117 rb.Push(system_session_id);
118 }
119
111 void SaveSystemReport(Kernel::HLERequestContext& ctx) { 120 void SaveSystemReport(Kernel::HLERequestContext& ctx) {
112 IPC::RequestParser rp{ctx}; 121 IPC::RequestParser rp{ctx};
113 const auto title_id = rp.PopRaw<u64>(); 122 const auto title_id = rp.PopRaw<u64>();
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index f5cdf548e..c841f3cd7 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -4,6 +4,7 @@
4 4
5#include "common/alignment.h" 5#include "common/alignment.h"
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/logging/log.h"
7#include "core/core.h" 8#include "core/core.h"
8#include "core/hle/kernel/memory/page_table.h" 9#include "core/hle/kernel/memory/page_table.h"
9#include "core/hle/kernel/process.h" 10#include "core/hle/kernel/process.h"
@@ -38,6 +39,12 @@ GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std
38} 39}
39 40
40GPUVAddr MemoryManager::Map(VAddr cpu_addr, GPUVAddr gpu_addr, std::size_t size) { 41GPUVAddr MemoryManager::Map(VAddr cpu_addr, GPUVAddr gpu_addr, std::size_t size) {
42 const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first);
43 if (it != map_ranges.end() && it->first == gpu_addr) {
44 it->second = size;
45 } else {
46 map_ranges.insert(it, MapRange{gpu_addr, size});
47 }
41 return UpdateRange(gpu_addr, cpu_addr, size); 48 return UpdateRange(gpu_addr, cpu_addr, size);
42} 49}
43 50
@@ -52,10 +59,16 @@ GPUVAddr MemoryManager::MapAllocate32(VAddr cpu_addr, std::size_t size) {
52} 59}
53 60
54void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) { 61void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) {
55 if (!size) { 62 if (size == 0) {
56 return; 63 return;
57 } 64 }
58 65 const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first);
66 if (it != map_ranges.end()) {
67 ASSERT(it->first == gpu_addr);
68 map_ranges.erase(it);
69 } else {
70 UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr);
71 }
59 // Flush and invalidate through the GPU interface, to be asynchronous if possible. 72 // Flush and invalidate through the GPU interface, to be asynchronous if possible.
60 const std::optional<VAddr> cpu_addr = GpuToCpuAddress(gpu_addr); 73 const std::optional<VAddr> cpu_addr = GpuToCpuAddress(gpu_addr);
61 ASSERT(cpu_addr); 74 ASSERT(cpu_addr);
@@ -218,6 +231,12 @@ const u8* MemoryManager::GetPointer(GPUVAddr gpu_addr) const {
218 return system.Memory().GetPointer(*address); 231 return system.Memory().GetPointer(*address);
219} 232}
220 233
234size_t MemoryManager::BytesToMapEnd(GPUVAddr gpu_addr) const noexcept {
235 auto it = std::ranges::upper_bound(map_ranges, gpu_addr, {}, &MapRange::first);
236 --it;
237 return it->second - (gpu_addr - it->first);
238}
239
221void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { 240void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const {
222 std::size_t remaining_size{size}; 241 std::size_t remaining_size{size};
223 std::size_t page_index{gpu_src_addr >> page_bits}; 242 std::size_t page_index{gpu_src_addr >> page_bits};
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index a52fbbd8c..b468a67de 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -85,6 +85,9 @@ public:
85 [[nodiscard]] u8* GetPointer(GPUVAddr addr); 85 [[nodiscard]] u8* GetPointer(GPUVAddr addr);
86 [[nodiscard]] const u8* GetPointer(GPUVAddr addr) const; 86 [[nodiscard]] const u8* GetPointer(GPUVAddr addr) const;
87 87
88 /// Returns the number of bytes until the end of the memory map containing the given GPU address
89 [[nodiscard]] size_t BytesToMapEnd(GPUVAddr gpu_addr) const noexcept;
90
88 /** 91 /**
89 * ReadBlock and WriteBlock are full read and write operations over virtual 92 * ReadBlock and WriteBlock are full read and write operations over virtual
90 * GPU Memory. It's important to use these when GPU memory may not be continuous 93 * GPU Memory. It's important to use these when GPU memory may not be continuous
@@ -151,6 +154,9 @@ private:
151 VideoCore::RasterizerInterface* rasterizer = nullptr; 154 VideoCore::RasterizerInterface* rasterizer = nullptr;
152 155
153 std::vector<PageEntry> page_table; 156 std::vector<PageEntry> page_table;
157
158 using MapRange = std::pair<GPUVAddr, size_t>;
159 std::vector<MapRange> map_ranges;
154}; 160};
155 161
156} // namespace Tegra 162} // namespace Tegra
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 567a36d9b..422022d02 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -190,12 +190,16 @@ void ConfigureInput::ApplyConfiguration() {
190 // This emulates a delay between disconnecting and reconnecting controllers as some games 190 // This emulates a delay between disconnecting and reconnecting controllers as some games
191 // do not respond to a change in controller type if it was instantaneous. 191 // do not respond to a change in controller type if it was instantaneous.
192 using namespace std::chrono_literals; 192 using namespace std::chrono_literals;
193 std::this_thread::sleep_for(60ms); 193 std::this_thread::sleep_for(150ms);
194 194
195 for (auto* controller : player_controllers) { 195 for (auto* controller : player_controllers) {
196 controller->TryConnectSelectedController(); 196 controller->TryConnectSelectedController();
197 } 197 }
198 198
199 // This emulates a delay between disconnecting and reconnecting controllers as some games
200 // do not respond to a change in controller type if it was instantaneous.
201 std::this_thread::sleep_for(150ms);
202
199 advanced->ApplyConfiguration(); 203 advanced->ApplyConfiguration();
200 204
201 const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue(); 205 const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 13f0351d4..fbe36046b 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -579,11 +579,11 @@ void ConfigureInputPlayer::ApplyConfiguration() {
579 // Apply configuration for handheld 579 // Apply configuration for handheld
580 if (player_index == 0) { 580 if (player_index == 0) {
581 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; 581 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
582 const auto handheld_connected = handheld.connected;
582 if (player.controller_type == Settings::ControllerType::Handheld) { 583 if (player.controller_type == Settings::ControllerType::Handheld) {
583 handheld = player; 584 handheld = player;
584 } 585 }
585 handheld.connected = ui->groupConnectedController->isChecked() && 586 handheld.connected = handheld_connected;
586 player.controller_type == Settings::ControllerType::Handheld;
587 } 587 }
588} 588}
589 589
@@ -595,6 +595,18 @@ void ConfigureInputPlayer::TryConnectSelectedController() {
595 const auto player_connected = ui->groupConnectedController->isChecked() && 595 const auto player_connected = ui->groupConnectedController->isChecked() &&
596 controller_type != Settings::ControllerType::Handheld; 596 controller_type != Settings::ControllerType::Handheld;
597 597
598 // Connect Handheld depending on Player 1's controller configuration.
599 if (player_index == 0 && controller_type == Settings::ControllerType::Handheld) {
600 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
601 const auto handheld_connected = ui->groupConnectedController->isChecked() &&
602 controller_type == Settings::ControllerType::Handheld;
603 // Connect only if handheld is going from disconnected to connected
604 if (!handheld.connected && handheld_connected) {
605 UpdateController(controller_type, HANDHELD_INDEX, true);
606 }
607 handheld.connected = handheld_connected;
608 }
609
598 if (player.controller_type == controller_type && player.connected == player_connected) { 610 if (player.controller_type == controller_type && player.connected == player_connected) {
599 // Set vibration devices in the event that the input device has changed. 611 // Set vibration devices in the event that the input device has changed.
600 ConfigureVibration::SetVibrationDevices(player_index); 612 ConfigureVibration::SetVibrationDevices(player_index);
@@ -606,22 +618,11 @@ void ConfigureInputPlayer::TryConnectSelectedController() {
606 618
607 ConfigureVibration::SetVibrationDevices(player_index); 619 ConfigureVibration::SetVibrationDevices(player_index);
608 620
609 // Connect/Disconnect Handheld depending on Player 1's controller configuration.
610 if (player_index == 0) {
611 auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
612 if (controller_type == Settings::ControllerType::Handheld) {
613 handheld = player;
614 }
615 handheld.connected = ui->groupConnectedController->isChecked() &&
616 controller_type == Settings::ControllerType::Handheld;
617 UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected);
618 }
619
620 if (!player.connected) { 621 if (!player.connected) {
621 return; 622 return;
622 } 623 }
623 624
624 UpdateController(controller_type, player_index, player_connected); 625 UpdateController(controller_type, player_index, true);
625} 626}
626 627
627void ConfigureInputPlayer::TryDisconnectSelectedController() { 628void ConfigureInputPlayer::TryDisconnectSelectedController() {
@@ -632,11 +633,28 @@ void ConfigureInputPlayer::TryDisconnectSelectedController() {
632 const auto player_connected = ui->groupConnectedController->isChecked() && 633 const auto player_connected = ui->groupConnectedController->isChecked() &&
633 controller_type != Settings::ControllerType::Handheld; 634 controller_type != Settings::ControllerType::Handheld;
634 635
636 // Disconnect Handheld depending on Player 1's controller configuration.
637 if (player_index == 0 && player.controller_type == Settings::ControllerType::Handheld) {
638 const auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
639 const auto handheld_connected = ui->groupConnectedController->isChecked() &&
640 controller_type == Settings::ControllerType::Handheld;
641 // Disconnect only if handheld is going from connected to disconnected
642 if (handheld.connected && !handheld_connected) {
643 UpdateController(controller_type, HANDHELD_INDEX, false);
644 }
645 return;
646 }
647
635 // Do not do anything if the controller configuration has not changed. 648 // Do not do anything if the controller configuration has not changed.
636 if (player.controller_type == controller_type && player.connected == player_connected) { 649 if (player.controller_type == controller_type && player.connected == player_connected) {
637 return; 650 return;
638 } 651 }
639 652
653 // Do not disconnect if the controller is already disconnected
654 if (!player.connected) {
655 return;
656 }
657
640 // Disconnect the controller first. 658 // Disconnect the controller first.
641 UpdateController(controller_type, player_index, false); 659 UpdateController(controller_type, player_index, false);
642} 660}