mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-08 16:27:49 +00:00
Compare commits
71 Commits
93cffebc5d
...
f08b27f204
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f08b27f204 | ||
![]() |
65f3ba70f5 | ||
![]() |
ec52a74967 | ||
![]() |
8b7669550f | ||
![]() |
46e66fe945 | ||
![]() |
056ece6f29 | ||
![]() |
a07a2fe398 | ||
![]() |
52fcdde485 | ||
![]() |
5eb61024c6 | ||
![]() |
a27b845514 | ||
![]() |
1b1ca019a4 | ||
![]() |
241834709b | ||
![]() |
185b080f03 | ||
![]() |
c3d3b81533 | ||
![]() |
774a84a953 | ||
![]() |
b3f50c969e | ||
![]() |
3b83907b88 | ||
![]() |
d940d62cae | ||
![]() |
7afa9e6c6f | ||
![]() |
12d178a8df | ||
![]() |
f910c1d934 | ||
![]() |
70abcb2030 | ||
![]() |
d8ea31ca46 | ||
![]() |
2ae43324cb | ||
![]() |
7d59c2743d | ||
![]() |
8113399b68 | ||
![]() |
bafe78203d | ||
![]() |
15f125ebee | ||
![]() |
316740daed | ||
![]() |
903eafcf65 | ||
![]() |
2a7e8a4003 | ||
![]() |
9ec69b5925 | ||
![]() |
d7de49ccf6 | ||
![]() |
5ec5db9240 | ||
![]() |
974c56d3c5 | ||
![]() |
977f2da6a7 | ||
![]() |
b1d114f7f7 | ||
![]() |
be3d48ec5f | ||
![]() |
ae26b38fc0 | ||
![]() |
b9bea58f0f | ||
![]() |
2de9122b5f | ||
![]() |
bae0e5f67a | ||
![]() |
2ae928ca79 | ||
![]() |
f04f659710 | ||
![]() |
ec1d659363 | ||
![]() |
c37933932d | ||
![]() |
23af1e025b | ||
![]() |
135b6840e5 | ||
![]() |
e3df00b7f4 | ||
![]() |
71da0f2d24 | ||
![]() |
8192d9d2a9 | ||
![]() |
e3aa5f0763 | ||
![]() |
1d0d123447 | ||
![]() |
4138d691ae | ||
![]() |
d9b0fd2805 | ||
![]() |
d78e6fe165 | ||
![]() |
41b0c09486 | ||
![]() |
b4eee80103 | ||
![]() |
6b8533d012 | ||
![]() |
d3fc0c89e4 | ||
![]() |
e3de3ada05 | ||
![]() |
7208b64a94 | ||
![]() |
a6b04f53e0 | ||
![]() |
ca10f2fdf1 | ||
![]() |
013c162cf1 | ||
![]() |
a6a5e201b6 | ||
![]() |
7c237bbd7c | ||
![]() |
ec29d120b5 | ||
![]() |
f240e20e3f | ||
![]() |
d48e6e25ad | ||
![]() |
096ab8c026 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -84,6 +84,9 @@
|
||||
[submodule "Externals/Vulkan-Headers"]
|
||||
path = Externals/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "Externals/watcher/watcher"]
|
||||
path = Externals/watcher/watcher
|
||||
url = https://github.com/e-dant/watcher.git
|
||||
[submodule "Externals/SFML/SFML"]
|
||||
path = Externals/SFML/SFML
|
||||
url = https://github.com/SFML/SFML.git
|
||||
|
@ -784,6 +784,8 @@ if (USE_RETRO_ACHIEVEMENTS)
|
||||
add_subdirectory(Externals/rcheevos)
|
||||
endif()
|
||||
|
||||
add_subdirectory(Externals/watcher)
|
||||
|
||||
########################################
|
||||
# Pre-build events: Define configuration variables and write SCM info header
|
||||
#
|
||||
|
9
Data/Sys/GameSettings/SCYE4Q.ini
Normal file
9
Data/Sys/GameSettings/SCYE4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SCYE4Q - Cars 2
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8019CB1C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SCYP4Q.ini
Normal file
9
Data/Sys/GameSettings/SCYP4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SCYP4Q - Cars 2
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8019CB1C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SCYR4Q.ini
Normal file
9
Data/Sys/GameSettings/SCYR4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SCYR4Q - Cars 2
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8019B4EC:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SCYX4Q.ini
Normal file
9
Data/Sys/GameSettings/SCYX4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SCYX4Q - Cars 2
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8019CBBC:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SCYY4Q.ini
Normal file
9
Data/Sys/GameSettings/SCYY4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SCYY4Q - Cars 2
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8019B55C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SCYZ4Q.ini
Normal file
9
Data/Sys/GameSettings/SCYZ4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SCYZ4Q - Cars 2
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8019B55C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
@ -1,4 +1,4 @@
|
||||
# SQIE4Q, SQIP4Q - Disney Infinity
|
||||
# SQIE4Q, SQIP4Q, SQIY4Q - Disney Infinity
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
9
Data/Sys/GameSettings/SQIE4Q.ini
Normal file
9
Data/Sys/GameSettings/SQIE4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SQIE4Q - Disney Infinity
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8008E60C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SQIP4Q.ini
Normal file
9
Data/Sys/GameSettings/SQIP4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SQIP4Q - Disney Infinity
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8008E60C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/SQIY4Q.ini
Normal file
9
Data/Sys/GameSettings/SQIY4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# SQIY4Q - Disney Infinity
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x8008E60C:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSE4Q.ini
Normal file
9
Data/Sys/GameSettings/STSE4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSE4Q - Toy Story 3
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA2E4:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSP4Qr1.ini
Normal file
9
Data/Sys/GameSettings/STSP4Qr1.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSP4Q - Toy Story 3
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA2E4:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSP4Qr2.ini
Normal file
9
Data/Sys/GameSettings/STSP4Qr2.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSP4Q - Toy Story 3
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA354:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSX4Q.ini
Normal file
9
Data/Sys/GameSettings/STSX4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSX4Q - Toy Story 3
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA354:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSY4Qr0.ini
Normal file
9
Data/Sys/GameSettings/STSY4Qr0.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSY4Q - Toy Story 3
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA2E4:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSY4Qr1.ini
Normal file
9
Data/Sys/GameSettings/STSY4Qr1.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSY4Q - Toy Story 3
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA354:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
9
Data/Sys/GameSettings/STSZ4Q.ini
Normal file
9
Data/Sys/GameSettings/STSZ4Q.ini
Normal file
@ -0,0 +1,9 @@
|
||||
# STSZ4Q - Toy Story 3 Toy Box Special Edition
|
||||
|
||||
[OnFrame]
|
||||
#This speedhack modifies the way the game manages memory to run faster in Dolphin.
|
||||
$BAT Speedhack
|
||||
0x801FA2E4:dword:0x48000180
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$BAT Speedhack
|
4
Externals/watcher/CMakeLists.txt
vendored
Normal file
4
Externals/watcher/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
add_library(watcher INTERFACE IMPORTED GLOBAL)
|
||||
set_target_properties(watcher PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/watcher/include
|
||||
)
|
1
Externals/watcher/watcher
vendored
Submodule
1
Externals/watcher/watcher
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b03bdcfc11549df595b77239cefe2643943a3e2f
|
@ -3,9 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#if defined(HAVE_ALSA) && HAVE_ALSA
|
||||
|
@ -166,7 +166,8 @@ void UpdateSoundStream(Core::System& system)
|
||||
|
||||
if (sound_stream)
|
||||
{
|
||||
int volume = Config::Get(Config::MAIN_AUDIO_MUTED) ? 0 : Config::Get(Config::MAIN_AUDIO_VOLUME);
|
||||
int const volume =
|
||||
Config::Get(Config::MAIN_AUDIO_MUTED) ? 0 : Config::Get(Config::MAIN_AUDIO_VOLUME);
|
||||
sound_stream->SetVolume(volume);
|
||||
}
|
||||
}
|
||||
@ -192,7 +193,7 @@ void SetSoundStreamRunning(Core::System& system, bool running)
|
||||
|
||||
void SendAIBuffer(Core::System& system, const short* samples, unsigned int num_samples)
|
||||
{
|
||||
SoundStream* sound_stream = system.GetSoundStream();
|
||||
const SoundStream* const sound_stream = system.GetSoundStream();
|
||||
|
||||
if (!sound_stream)
|
||||
return;
|
||||
@ -212,9 +213,9 @@ void SendAIBuffer(Core::System& system, const short* samples, unsigned int num_s
|
||||
|
||||
void StartAudioDump(Core::System& system)
|
||||
{
|
||||
SoundStream* sound_stream = system.GetSoundStream();
|
||||
const SoundStream* const sound_stream = system.GetSoundStream();
|
||||
|
||||
std::time_t start_time = std::time(nullptr);
|
||||
std::time_t const start_time = std::time(nullptr);
|
||||
|
||||
std::string path_prefix = File::GetUserPath(D_DUMPAUDIO_IDX) + SConfig::GetInstance().GetGameID();
|
||||
|
||||
@ -232,7 +233,7 @@ void StartAudioDump(Core::System& system)
|
||||
|
||||
void StopAudioDump(Core::System& system)
|
||||
{
|
||||
SoundStream* sound_stream = system.GetSoundStream();
|
||||
const SoundStream* const sound_stream = system.GetSoundStream();
|
||||
|
||||
if (!sound_stream)
|
||||
return;
|
||||
@ -265,7 +266,7 @@ void DecreaseVolume(Core::System& system, unsigned short offset)
|
||||
|
||||
void ToggleMuteVolume(Core::System& system)
|
||||
{
|
||||
bool isMuted = Config::Get(Config::MAIN_AUDIO_MUTED);
|
||||
bool const isMuted = Config::Get(Config::MAIN_AUDIO_MUTED);
|
||||
Config::SetBaseOrCurrent(Config::MAIN_AUDIO_MUTED, !isMuted);
|
||||
UpdateSoundStream(system);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "Common/Event.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/ScopeGuard.h"
|
||||
#include "Common/Thread.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -23,7 +22,7 @@ constexpr u32 BUFFER_SAMPLES = 512;
|
||||
long CubebStream::DataCallback(cubeb_stream* stream, void* user_data, const void* /*input_buffer*/,
|
||||
void* output_buffer, long num_frames)
|
||||
{
|
||||
auto* self = static_cast<CubebStream*>(user_data);
|
||||
const auto* const self = static_cast<CubebStream*>(user_data);
|
||||
|
||||
if (self->m_stereo)
|
||||
self->m_mixer->Mix(static_cast<short*>(output_buffer), num_frames);
|
||||
@ -44,7 +43,7 @@ CubebStream::CubebStream()
|
||||
Common::Event sync_event;
|
||||
m_work_queue.Push([this, &sync_event] {
|
||||
Common::ScopeGuard sync_event_guard([&sync_event] { sync_event.Set(); });
|
||||
auto result = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
auto const result = CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
m_coinit_success = result == S_OK;
|
||||
m_should_couninit = result == S_OK || result == S_FALSE;
|
||||
});
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
@ -182,7 +182,8 @@ std::size_t Mixer::MixSurround(float* samples, std::size_t num_samples)
|
||||
|
||||
memset(samples, 0, num_samples * SURROUND_CHANNELS * sizeof(float));
|
||||
|
||||
std::size_t needed_frames = m_surround_decoder.QueryFramesNeededForSurroundOutput(num_samples);
|
||||
std::size_t const needed_frames =
|
||||
m_surround_decoder.QueryFramesNeededForSurroundOutput(num_samples);
|
||||
|
||||
constexpr std::size_t max_samples = 0x8000;
|
||||
ASSERT_MSG(AUDIO, needed_frames <= max_samples,
|
||||
@ -190,7 +191,7 @@ std::size_t Mixer::MixSurround(float* samples, std::size_t num_samples)
|
||||
needed_frames, max_samples);
|
||||
|
||||
std::array<s16, max_samples> buffer;
|
||||
std::size_t available_frames = Mix(buffer.data(), static_cast<std::size_t>(needed_frames));
|
||||
std::size_t const available_frames = Mix(buffer.data(), static_cast<std::size_t>(needed_frames));
|
||||
if (available_frames != needed_frames)
|
||||
{
|
||||
ERROR_LOG_FMT(AUDIO,
|
||||
@ -229,7 +230,7 @@ void Mixer::PushSamples(const s16* samples, std::size_t num_samples)
|
||||
if (m_log_dsp_audio)
|
||||
{
|
||||
const s32 sample_rate_divisor = m_dma_mixer.GetInputSampleRateDivisor();
|
||||
auto volume = m_dma_mixer.GetVolume();
|
||||
auto const volume = m_dma_mixer.GetVolume();
|
||||
m_wave_writer_dsp.AddStereoSamplesBE(samples, static_cast<u32>(num_samples),
|
||||
sample_rate_divisor, volume.first, volume.second);
|
||||
}
|
||||
@ -241,7 +242,7 @@ void Mixer::PushStreamingSamples(const s16* samples, std::size_t num_samples)
|
||||
if (m_log_dtk_audio)
|
||||
{
|
||||
const s32 sample_rate_divisor = m_streaming_mixer.GetInputSampleRateDivisor();
|
||||
auto volume = m_streaming_mixer.GetVolume();
|
||||
auto const volume = m_streaming_mixer.GetVolume();
|
||||
m_wave_writer_dtk.AddStereoSamplesBE(samples, static_cast<u32>(num_samples),
|
||||
sample_rate_divisor, volume.first, volume.second);
|
||||
}
|
||||
@ -286,7 +287,8 @@ void Mixer::PushSkylanderPortalSamples(const u8* samples, std::size_t num_sample
|
||||
{
|
||||
for (std::size_t i = 0; i < num_samples; ++i)
|
||||
{
|
||||
s16 sample = static_cast<u16>(samples[i * 2 + 1]) << 8 | static_cast<u16>(samples[i * 2]);
|
||||
s16 const sample =
|
||||
static_cast<u16>(samples[i * 2 + 1]) << 8 | static_cast<u16>(samples[i * 2]);
|
||||
samples_stereo[i * 2] = sample;
|
||||
samples_stereo[i * 2 + 1] = sample;
|
||||
}
|
||||
@ -335,7 +337,8 @@ void Mixer::StartLogDTKAudio(const std::string& filename)
|
||||
{
|
||||
if (!m_log_dtk_audio)
|
||||
{
|
||||
bool success = m_wave_writer_dtk.Start(filename, m_streaming_mixer.GetInputSampleRateDivisor());
|
||||
bool const success =
|
||||
m_wave_writer_dtk.Start(filename, m_streaming_mixer.GetInputSampleRateDivisor());
|
||||
if (success)
|
||||
{
|
||||
m_log_dtk_audio = true;
|
||||
@ -372,7 +375,7 @@ void Mixer::StartLogDSPAudio(const std::string& filename)
|
||||
{
|
||||
if (!m_log_dsp_audio)
|
||||
{
|
||||
bool success = m_wave_writer_dsp.Start(filename, m_dma_mixer.GetInputSampleRateDivisor());
|
||||
bool const success = m_wave_writer_dsp.Start(filename, m_dma_mixer.GetInputSampleRateDivisor());
|
||||
if (success)
|
||||
{
|
||||
m_log_dsp_audio = true;
|
||||
@ -494,10 +497,10 @@ void Mixer::MixerFifo::Enqueue()
|
||||
0.0002984010f, 0.0002102045f, 0.0001443499f, 0.0000961509f, 0.0000616906f, 0.0000377350f,
|
||||
0.0000216492f, 0.0000113187f, 0.0000050749f, 0.0000016272f};
|
||||
|
||||
const std::size_t head = m_queue_head.load(std::memory_order_acquire);
|
||||
std::size_t const head = m_queue_head.load(std::memory_order_acquire);
|
||||
|
||||
// Check if we run out of space in the circular queue. (rare)
|
||||
std::size_t next_head = (head + 1) & GRANULE_QUEUE_MASK;
|
||||
std::size_t const next_head = (head + 1) & GRANULE_QUEUE_MASK;
|
||||
if (next_head == m_queue_tail.load(std::memory_order_acquire))
|
||||
{
|
||||
WARN_LOG_FMT(AUDIO,
|
||||
|
@ -3,11 +3,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <bit>
|
||||
#include <cmath>
|
||||
|
||||
#include "AudioCommon/SurroundDecoder.h"
|
||||
#include "AudioCommon/WaveFile.h"
|
||||
|
@ -76,7 +76,7 @@ static bool InitLibrary()
|
||||
|
||||
if (!InitFunctions())
|
||||
{
|
||||
::FreeLibrary(s_openal_dll);
|
||||
FreeLibrary(s_openal_dll);
|
||||
s_openal_dll = nullptr;
|
||||
return false;
|
||||
}
|
||||
@ -168,7 +168,7 @@ bool OpenALStream::SetRunning(bool running)
|
||||
|
||||
static ALenum CheckALError(const char* desc)
|
||||
{
|
||||
ALenum err = palGetError();
|
||||
ALenum const err = palGetError();
|
||||
|
||||
if (err != AL_NO_ERROR)
|
||||
{
|
||||
@ -211,16 +211,16 @@ void OpenALStream::SoundLoop()
|
||||
{
|
||||
Common::SetCurrentThreadName("Audio thread - openal");
|
||||
|
||||
bool float32_capable = palIsExtensionPresent("AL_EXT_float32") != 0;
|
||||
bool surround_capable = palIsExtensionPresent("AL_EXT_MCFORMATS") || IsCreativeXFi();
|
||||
bool const float32_capable = palIsExtensionPresent("AL_EXT_float32") != 0;
|
||||
bool const surround_capable = palIsExtensionPresent("AL_EXT_MCFORMATS") || IsCreativeXFi();
|
||||
bool use_surround = Config::ShouldUseDPL2Decoder() && surround_capable;
|
||||
|
||||
// As there is no extension to check for 32-bit fixed point support
|
||||
// and we know that only a X-Fi with hardware OpenAL supports it,
|
||||
// we just check if one is being used.
|
||||
bool fixed32_capable = IsCreativeXFi();
|
||||
bool const fixed32_capable = IsCreativeXFi();
|
||||
|
||||
u32 frequency = m_mixer->GetSampleRate();
|
||||
u32 const frequency = m_mixer->GetSampleRate();
|
||||
|
||||
u32 frames_per_buffer;
|
||||
// Can't have zero samples per buffer
|
||||
@ -288,12 +288,12 @@ void OpenALStream::SoundLoop()
|
||||
num_buffers_queued -= num_buffers_processed;
|
||||
}
|
||||
|
||||
unsigned int min_frames = frames_per_buffer;
|
||||
unsigned int const min_frames = frames_per_buffer;
|
||||
|
||||
if (use_surround)
|
||||
{
|
||||
std::array<float, OAL_MAX_FRAMES * SURROUND_CHANNELS> dpl2;
|
||||
u32 rendered_frames = static_cast<u32>(m_mixer->MixSurround(dpl2.data(), min_frames));
|
||||
u32 const rendered_frames = static_cast<u32>(m_mixer->MixSurround(dpl2.data(), min_frames));
|
||||
|
||||
if (rendered_frames < min_frames)
|
||||
continue;
|
||||
@ -351,7 +351,8 @@ void OpenALStream::SoundLoop()
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 rendered_frames = static_cast<u32>(m_mixer->Mix(m_realtime_buffer.data(), min_frames));
|
||||
u32 const rendered_frames =
|
||||
static_cast<u32>(m_mixer->Mix(m_realtime_buffer.data(), min_frames));
|
||||
|
||||
if (!rendered_frames)
|
||||
continue;
|
||||
|
@ -7,9 +7,6 @@
|
||||
|
||||
#include "AudioCommon/SoundStream.h"
|
||||
#include "Common/Event.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/AudioInterface.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <al.h>
|
||||
|
@ -8,7 +8,6 @@
|
||||
#endif
|
||||
|
||||
#include "AudioCommon/SoundStream.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Flag.h"
|
||||
#include "Common/Thread.h"
|
||||
|
||||
|
@ -32,7 +32,7 @@ size_t SurroundDecoder::QueryFramesNeededForSurroundOutput(const size_t output_f
|
||||
if (m_decoded_fifo.size() < output_frames * SURROUND_CHANNELS)
|
||||
{
|
||||
// Output stereo frames needed to have at least the desired number of surround frames
|
||||
size_t frames_needed = output_frames - m_decoded_fifo.size() / SURROUND_CHANNELS;
|
||||
size_t const frames_needed = output_frames - m_decoded_fifo.size() / SURROUND_CHANNELS;
|
||||
return frames_needed + m_frame_block_size - frames_needed % m_frame_block_size;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
// clang-format off
|
||||
#include <Audioclient.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <devpkey.h>
|
||||
#include <functiondiscoverykeys_devpkey.h>
|
||||
#include <wil/resource.h>
|
||||
// clang-format on
|
||||
@ -159,8 +158,9 @@ ComPtr<IMMDevice> WASAPIStream::GetDeviceByName(std::string_view name)
|
||||
bool WASAPIStream::Init()
|
||||
{
|
||||
ASSERT(m_enumerator == nullptr);
|
||||
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARGS(m_enumerator.GetAddressOf()));
|
||||
HRESULT const result =
|
||||
CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARGS(m_enumerator.GetAddressOf()));
|
||||
|
||||
if (!HandleWinAPI("Failed to create MMDeviceEnumerator", result))
|
||||
return false;
|
||||
|
@ -32,7 +32,7 @@ class WASAPIStream final : public SoundStream
|
||||
#ifdef _WIN32
|
||||
public:
|
||||
explicit WASAPIStream();
|
||||
~WASAPIStream();
|
||||
~WASAPIStream() override;
|
||||
bool Init() override;
|
||||
bool SetRunning(bool running) override;
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
{
|
||||
m_active_block = &m_output_result.blocks.emplace_back(base_addr);
|
||||
}
|
||||
virtual ~GekkoIRPlugin() = default;
|
||||
~GekkoIRPlugin() override = default;
|
||||
|
||||
void OnDirectivePre(GekkoDirective directive) override;
|
||||
void OnDirectivePost(GekkoDirective directive) override;
|
||||
|
@ -64,6 +64,8 @@ add_library(common
|
||||
FatFsUtil.h
|
||||
FileSearch.cpp
|
||||
FileSearch.h
|
||||
FilesystemWatcher.cpp
|
||||
FilesystemWatcher.h
|
||||
FileUtil.cpp
|
||||
FileUtil.h
|
||||
FixedSizeQueue.h
|
||||
@ -184,6 +186,7 @@ PRIVATE
|
||||
FatFs
|
||||
Iconv::Iconv
|
||||
spng::spng
|
||||
watcher
|
||||
${VTUNE_LIBRARIES}
|
||||
)
|
||||
|
||||
|
@ -46,8 +46,7 @@ public:
|
||||
ASSERT(!mbedtls_aes_setkey_dec(&ctx, key, 128));
|
||||
}
|
||||
|
||||
virtual bool Crypt(const u8* iv, u8* iv_out, const u8* buf_in, u8* buf_out,
|
||||
size_t len) const override
|
||||
bool Crypt(const u8* iv, u8* iv_out, const u8* buf_in, u8* buf_out, size_t len) const override
|
||||
{
|
||||
std::array<u8, BLOCK_SIZE> iv_tmp{};
|
||||
if (iv)
|
||||
@ -206,8 +205,7 @@ public:
|
||||
_mm_storeu_si128(&((__m128i*)buf_out)[d], block[d]);
|
||||
}
|
||||
|
||||
virtual bool Crypt(const u8* iv, u8* iv_out, const u8* buf_in, u8* buf_out,
|
||||
size_t len) const override
|
||||
bool Crypt(const u8* iv, u8* iv_out, const u8* buf_in, u8* buf_out, size_t len) const override
|
||||
{
|
||||
if (len % BLOCK_SIZE)
|
||||
return false;
|
||||
|
@ -41,18 +41,18 @@ public:
|
||||
mbedtls_sha1_init(&ctx);
|
||||
ASSERT(!mbedtls_sha1_starts_ret(&ctx));
|
||||
}
|
||||
~ContextMbed() { mbedtls_sha1_free(&ctx); }
|
||||
virtual void Update(const u8* msg, size_t len) override
|
||||
~ContextMbed() override { mbedtls_sha1_free(&ctx); }
|
||||
void Update(const u8* msg, size_t len) override
|
||||
{
|
||||
ASSERT(!mbedtls_sha1_update_ret(&ctx, msg, len));
|
||||
}
|
||||
virtual Digest Finish() override
|
||||
Digest Finish() override
|
||||
{
|
||||
Digest digest;
|
||||
ASSERT(!mbedtls_sha1_finish_ret(&ctx, digest.data()));
|
||||
return digest;
|
||||
}
|
||||
virtual bool HwAccelerated() const override { return false; }
|
||||
bool HwAccelerated() const override { return false; }
|
||||
|
||||
private:
|
||||
mbedtls_sha1_context ctx{};
|
||||
@ -204,7 +204,7 @@ private:
|
||||
}
|
||||
|
||||
ATTRIBUTE_TARGET("sha")
|
||||
virtual void ProcessBlock(const u8* msg) override
|
||||
void ProcessBlock(const u8* msg) override
|
||||
{
|
||||
// There are 80 rounds with 4 bytes per round, giving 0x140 byte work space, but we can keep
|
||||
// active state in just 0x40 bytes.
|
||||
@ -248,7 +248,7 @@ private:
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
virtual Digest GetDigest() override
|
||||
Digest GetDigest() override
|
||||
{
|
||||
Digest digest;
|
||||
_mm_storeu_si128((__m128i*)&digest[0], byterev_16B(state[0]));
|
||||
@ -257,7 +257,7 @@ private:
|
||||
return digest;
|
||||
}
|
||||
|
||||
virtual bool HwAccelerated() const override { return true; }
|
||||
bool HwAccelerated() const override { return true; }
|
||||
|
||||
std::array<XmmReg, 2> state{};
|
||||
};
|
||||
|
67
Source/Core/Common/FilesystemWatcher.cpp
Normal file
67
Source/Core/Common/FilesystemWatcher.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2025 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "Common/FilesystemWatcher.h"
|
||||
|
||||
#include <wtr/watcher.hpp>
|
||||
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
namespace Common
|
||||
{
|
||||
FilesystemWatcher::FilesystemWatcher() = default;
|
||||
FilesystemWatcher::~FilesystemWatcher() = default;
|
||||
|
||||
void FilesystemWatcher::Watch(const std::string& path)
|
||||
{
|
||||
const auto [iter, inserted] = m_watched_paths.try_emplace(path, nullptr);
|
||||
if (inserted)
|
||||
{
|
||||
iter->second = std::make_unique<wtr::watch>(path, [this](wtr::event e) {
|
||||
const auto watched_path = PathToString(e.path_name);
|
||||
if (e.path_type == wtr::event::path_type::watcher)
|
||||
{
|
||||
if (watched_path.starts_with('e'))
|
||||
ERROR_LOG_FMT(COMMON, "Filesystem watcher: '{}'", watched_path);
|
||||
else if (watched_path.starts_with('w'))
|
||||
WARN_LOG_FMT(COMMON, "Filesystem watcher: '{}'", watched_path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.effect_type == wtr::event::effect_type::create)
|
||||
{
|
||||
const auto path = WithUnifiedPathSeparators(watched_path);
|
||||
PathAdded(path);
|
||||
}
|
||||
else if (e.effect_type == wtr::event::effect_type::modify)
|
||||
{
|
||||
const auto path = WithUnifiedPathSeparators(watched_path);
|
||||
PathModified(path);
|
||||
}
|
||||
else if (e.effect_type == wtr::event::effect_type::rename)
|
||||
{
|
||||
if (!e.associated)
|
||||
{
|
||||
WARN_LOG_FMT(COMMON, "Rename on path '{}' seen without association!", watched_path);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto old_path = WithUnifiedPathSeparators(watched_path);
|
||||
const auto new_path = WithUnifiedPathSeparators(PathToString(e.associated->path_name));
|
||||
PathRenamed(old_path, new_path);
|
||||
}
|
||||
else if (e.effect_type == wtr::event::effect_type::destroy)
|
||||
{
|
||||
const auto path = WithUnifiedPathSeparators(watched_path);
|
||||
PathDeleted(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FilesystemWatcher::Unwatch(const std::string& path)
|
||||
{
|
||||
m_watched_paths.erase(path);
|
||||
}
|
||||
} // namespace Common
|
47
Source/Core/Common/FilesystemWatcher.h
Normal file
47
Source/Core/Common/FilesystemWatcher.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2025 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace wtr
|
||||
{
|
||||
inline namespace watcher
|
||||
{
|
||||
class watch;
|
||||
}
|
||||
} // namespace wtr
|
||||
|
||||
namespace Common
|
||||
{
|
||||
// A class that can watch a path and receive callbacks
|
||||
// when files or directories underneath that path receive events
|
||||
class FilesystemWatcher
|
||||
{
|
||||
public:
|
||||
FilesystemWatcher();
|
||||
virtual ~FilesystemWatcher();
|
||||
|
||||
void Watch(const std::string& path);
|
||||
void Unwatch(const std::string& path);
|
||||
|
||||
private:
|
||||
// A new file or folder was added to one of the watched paths
|
||||
virtual void PathAdded(std::string_view path) {}
|
||||
|
||||
// A file or folder was modified in one of the watched paths
|
||||
virtual void PathModified(std::string_view path) {}
|
||||
|
||||
// A file or folder was renamed in one of the watched paths
|
||||
virtual void PathRenamed(std::string_view old_path, std::string_view new_path) {}
|
||||
|
||||
// A file or folder was deleted in one of the watched paths
|
||||
virtual void PathDeleted(std::string_view path) {}
|
||||
|
||||
std::map<std::string, std::unique_ptr<wtr::watch>> m_watched_paths;
|
||||
};
|
||||
} // namespace Common
|
@ -10,9 +10,9 @@
|
||||
class GLContextWGL final : public GLContext
|
||||
{
|
||||
public:
|
||||
~GLContextWGL();
|
||||
~GLContextWGL() override;
|
||||
|
||||
bool IsHeadless() const;
|
||||
bool IsHeadless() const override;
|
||||
|
||||
std::unique_ptr<GLContext> CreateSharedContext() override;
|
||||
|
||||
|
@ -101,7 +101,7 @@ class HostDisassemblerBochs final : public HostDisassembler
|
||||
{
|
||||
public:
|
||||
explicit HostDisassemblerBochs();
|
||||
~HostDisassemblerBochs() = default;
|
||||
~HostDisassemblerBochs() override = default;
|
||||
|
||||
private:
|
||||
disassembler m_disasm;
|
||||
|
@ -9,7 +9,7 @@ class ConsoleListener : public Common::Log::LogListener
|
||||
{
|
||||
public:
|
||||
ConsoleListener();
|
||||
~ConsoleListener();
|
||||
~ConsoleListener() override;
|
||||
|
||||
void Log(Common::Log::LogLevel level, const char* text) override;
|
||||
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
explicit DolReader(const std::string& filename);
|
||||
explicit DolReader(File::IOFile file);
|
||||
explicit DolReader(std::vector<u8> buffer);
|
||||
~DolReader();
|
||||
~DolReader() override;
|
||||
|
||||
bool IsValid() const override { return m_is_valid; }
|
||||
bool IsWii() const override { return m_is_wii; }
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
explicit ElfReader(const std::string& filename);
|
||||
explicit ElfReader(File::IOFile file);
|
||||
explicit ElfReader(std::vector<u8> buffer);
|
||||
~ElfReader();
|
||||
~ElfReader() override;
|
||||
u32 Read32(int off) const { return base32[off >> 2]; }
|
||||
// Quick accessors
|
||||
ElfType GetType() const { return (ElfType)(header->e_type); }
|
||||
|
@ -483,6 +483,9 @@ add_library(core
|
||||
NetworkCaptureLogger.h
|
||||
PatchEngine.cpp
|
||||
PatchEngine.h
|
||||
PerformanceSample.h
|
||||
PerformanceSampleAggregator.cpp
|
||||
PerformanceSampleAggregator.h
|
||||
PowerPC/BreakPoints.cpp
|
||||
PowerPC/BreakPoints.h
|
||||
PowerPC/CachedInterpreter/CachedInterpreter_Disassembler.cpp
|
||||
|
@ -45,6 +45,7 @@ const Info<bool> MAIN_ACCURATE_CPU_CACHE{{System::Main, "Core", "AccurateCPUCach
|
||||
const Info<bool> MAIN_DSP_HLE{{System::Main, "Core", "DSPHLE"}, true};
|
||||
const Info<int> MAIN_MAX_FALLBACK{{System::Main, "Core", "MaxFallback"}, 100};
|
||||
const Info<int> MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40};
|
||||
const Info<bool> MAIN_CORRECT_TIME_DRIFT{{System::Main, "Core", "CorrectTimeDrift"}, false};
|
||||
const Info<bool> MAIN_CPU_THREAD{{System::Main, "Core", "CPUThread"}, true};
|
||||
const Info<bool> MAIN_SYNC_ON_SKIP_IDLE{{System::Main, "Core", "SyncOnSkipIdle"}, true};
|
||||
const Info<std::string> MAIN_DEFAULT_ISO{{System::Main, "Core", "DefaultISO"}, ""};
|
||||
|
@ -63,6 +63,7 @@ extern const Info<bool> MAIN_ACCURATE_CPU_CACHE;
|
||||
extern const Info<bool> MAIN_DSP_HLE;
|
||||
extern const Info<int> MAIN_MAX_FALLBACK;
|
||||
extern const Info<int> MAIN_TIMING_VARIANCE;
|
||||
extern const Info<bool> MAIN_CORRECT_TIME_DRIFT;
|
||||
extern const Info<bool> MAIN_CPU_THREAD;
|
||||
extern const Info<bool> MAIN_SYNC_ON_SKIP_IDLE;
|
||||
extern const Info<std::string> MAIN_DEFAULT_ISO;
|
||||
|
@ -82,7 +82,6 @@
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
#include "InputCommon/GCAdapter.h"
|
||||
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
#include "VideoCommon/AsyncRequests.h"
|
||||
#include "VideoCommon/Fifo.h"
|
||||
#include "VideoCommon/FrameDumper.h"
|
||||
@ -528,9 +527,6 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
|
||||
|
||||
FreeLook::LoadInputConfig();
|
||||
|
||||
system.GetCustomAssetLoader().Init();
|
||||
Common::ScopeGuard asset_loader_guard([&system] { system.GetCustomAssetLoader().Shutdown(); });
|
||||
|
||||
system.GetMovie().Init(*boot);
|
||||
Common::ScopeGuard movie_guard([&system] { system.GetMovie().Shutdown(); });
|
||||
|
||||
|
@ -105,10 +105,20 @@ void CoreTimingManager::Init()
|
||||
|
||||
m_last_oc_factor = m_config_oc_factor;
|
||||
m_globals.last_OC_factor_inverted = m_config_oc_inv_factor;
|
||||
|
||||
m_on_state_changed_handle = Core::AddOnStateChangedCallback([this](Core::State state) {
|
||||
if (state == Core::State::Running)
|
||||
{
|
||||
// We don't want Throttle to attempt catch-up for all the time lost while paused.
|
||||
ResetThrottle(GetTicks());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CoreTimingManager::Shutdown()
|
||||
{
|
||||
Core::RemoveOnStateChangedCallback(&m_on_state_changed_handle);
|
||||
|
||||
std::lock_guard lk(m_ts_write_lock);
|
||||
MoveEvents();
|
||||
ClearPendingEvents();
|
||||
@ -131,6 +141,8 @@ void CoreTimingManager::RefreshConfig()
|
||||
|
||||
m_max_variance = std::chrono::duration_cast<DT>(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE)));
|
||||
|
||||
m_correct_time_drift = Config::Get(Config::MAIN_CORRECT_TIME_DRIFT);
|
||||
|
||||
if (AchievementManager::GetInstance().IsHardcoreModeActive() &&
|
||||
Config::Get(Config::MAIN_EMULATION_SPEED) < 1.0f &&
|
||||
Config::Get(Config::MAIN_EMULATION_SPEED) > 0.0f)
|
||||
@ -428,7 +440,9 @@ void CoreTimingManager::Throttle(const s64 target_cycle)
|
||||
const TimePoint time = Clock::now();
|
||||
|
||||
const TimePoint min_target = time - m_max_fallback;
|
||||
if (target_time < min_target)
|
||||
|
||||
// "Correct Time Drift" setting prevents timing relaxing.
|
||||
if (!m_correct_time_drift && target_time < min_target)
|
||||
{
|
||||
// Core is running too slow.. i.e. CPU bottleneck.
|
||||
const DT adjustment = min_target - target_time;
|
||||
|
@ -211,6 +211,7 @@ private:
|
||||
|
||||
DT m_max_fallback = {};
|
||||
DT m_max_variance = {};
|
||||
bool m_correct_time_drift = false;
|
||||
double m_emulation_speed = 1.0;
|
||||
|
||||
bool IsSpeedUnlimited() const;
|
||||
@ -225,6 +226,8 @@ private:
|
||||
std::atomic_bool m_use_precision_timer = false;
|
||||
Common::PrecisionTimer m_precision_cpu_timer;
|
||||
Common::PrecisionTimer m_precision_gpu_timer;
|
||||
|
||||
int m_on_state_changed_handle;
|
||||
};
|
||||
|
||||
} // namespace CoreTiming
|
||||
|
@ -132,7 +132,7 @@ class OSThreadView : public Common::Debug::ThreadView
|
||||
{
|
||||
public:
|
||||
explicit OSThreadView(const Core::CPUThreadGuard& guard, u32 addr);
|
||||
~OSThreadView() = default;
|
||||
~OSThreadView() override = default;
|
||||
|
||||
const OSThread& Data() const;
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@ -17,7 +16,6 @@
|
||||
#elif defined(__APPLE__)
|
||||
#include <objc/message.h>
|
||||
#elif defined(ANDROID)
|
||||
#include <functional>
|
||||
#include "Common/AndroidAnalytics.h"
|
||||
#endif
|
||||
|
||||
@ -28,24 +26,21 @@
|
||||
#include "Common/Crypto/SHA1.h"
|
||||
#include "Common/EnumUtils.h"
|
||||
#include "Common/Random.h"
|
||||
#include "Common/Timer.h"
|
||||
#include "Common/Version.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/HW/GCPad.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/NetPlayProto.h"
|
||||
|
||||
#include "Core/System.h"
|
||||
#include "InputCommon/GCAdapter.h"
|
||||
#include "InputCommon/InputConfig.h"
|
||||
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr char ANALYTICS_ENDPOINT[] = "https://analytics.dolphin-emu.org/report";
|
||||
} // namespace
|
||||
|
||||
#if defined(ANDROID)
|
||||
static std::function<std::string(std::string)> s_get_val_func;
|
||||
void DolphinAnalytics::AndroidSetGetValFunc(std::function<std::string(std::string)> func)
|
||||
@ -54,6 +49,100 @@ void DolphinAnalytics::AndroidSetGetValFunc(std::function<std::string(std::strin
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
void AddVersionInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
builder->AddData("version-desc", Common::GetScmDescStr());
|
||||
builder->AddData("version-hash", Common::GetScmRevGitStr());
|
||||
builder->AddData("version-branch", Common::GetScmBranchStr());
|
||||
builder->AddData("version-dist", Common::GetScmDistributorStr());
|
||||
}
|
||||
|
||||
void AddAutoUpdateInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
builder->AddData("update-track", Config::Get(Config::MAIN_AUTOUPDATE_UPDATE_TRACK));
|
||||
}
|
||||
|
||||
void AddCPUInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
builder->AddData("cpu-summary", cpu_info.Summarize());
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
void AddWindowsInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
const auto winver = WindowsRegistry::GetOSVersion();
|
||||
builder->AddData("win-ver-major", static_cast<u32>(winver.dwMajorVersion));
|
||||
builder->AddData("win-ver-minor", static_cast<u32>(winver.dwMinorVersion));
|
||||
builder->AddData("win-ver-build", static_cast<u32>(winver.dwBuildNumber));
|
||||
}
|
||||
#elif defined(ANDROID)
|
||||
void AddAndroidInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
builder->AddData("android-manufacturer", s_get_val_func("DEVICE_MANUFACTURER"));
|
||||
builder->AddData("android-model", s_get_val_func("DEVICE_MODEL"));
|
||||
builder->AddData("android-version", s_get_val_func("DEVICE_OS"));
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
void AddMacOSInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
// id processInfo = [NSProcessInfo processInfo]
|
||||
id processInfo = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(
|
||||
objc_getClass("NSProcessInfo"), sel_getUid("processInfo"));
|
||||
if (processInfo)
|
||||
{
|
||||
struct OSVersion // NSOperatingSystemVersion
|
||||
{
|
||||
s64 major_version; // NSInteger majorVersion
|
||||
s64 minor_version; // NSInteger minorVersion
|
||||
s64 patch_version; // NSInteger patchVersion
|
||||
};
|
||||
// On x86_64, we need to explicitly call objc_msgSend_stret for a struct.
|
||||
#ifdef _M_ARM_64
|
||||
#define msgSend objc_msgSend
|
||||
#else
|
||||
#define msgSend objc_msgSend_stret
|
||||
#endif
|
||||
// NSOperatingSystemVersion version = [processInfo operatingSystemVersion]
|
||||
OSVersion version = reinterpret_cast<OSVersion (*)(id, SEL)>(msgSend)(
|
||||
processInfo, sel_getUid("operatingSystemVersion"));
|
||||
#undef msgSend
|
||||
builder->AddData("osx-ver-major", version.major_version);
|
||||
builder->AddData("osx-ver-minor", version.minor_version);
|
||||
builder->AddData("osx-ver-bugfix", version.patch_version);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void AddPlatformInformationToReportBuilder(Common::AnalyticsReportBuilder* builder)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
builder->AddData("os-type", "windows");
|
||||
AddWindowsInformationToReportBuilder(builder);
|
||||
#elif defined(ANDROID)
|
||||
builder->AddData("os-type", "android");
|
||||
AddAndroidInformationToReportBuilder(builder);
|
||||
#elif defined(__APPLE__)
|
||||
builder->AddData("os-type", "osx");
|
||||
AddMacOSInformationToReportBuilder(builder);
|
||||
#elif defined(__linux__)
|
||||
builder->AddData("os-type", "linux");
|
||||
#elif defined(__FreeBSD__)
|
||||
builder->AddData("os-type", "freebsd");
|
||||
#elif defined(__OpenBSD__)
|
||||
builder->AddData("os-type", "openbsd");
|
||||
#elif defined(__NetBSD__)
|
||||
builder->AddData("os-type", "netbsd");
|
||||
#elif defined(__HAIKU__)
|
||||
builder->AddData("os-type", "haiku");
|
||||
#else
|
||||
builder->AddData("os-type", "unknown");
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Under arm64, we need to call objc_msgSend to receive a struct.
|
||||
DolphinAnalytics::DolphinAnalytics()
|
||||
{
|
||||
ReloadConfig();
|
||||
@ -68,16 +157,17 @@ DolphinAnalytics& DolphinAnalytics::Instance()
|
||||
|
||||
void DolphinAnalytics::ReloadConfig()
|
||||
{
|
||||
std::lock_guard lk{m_reporter_mutex};
|
||||
const std::lock_guard lk{m_reporter_mutex};
|
||||
|
||||
// Install the HTTP backend if analytics support is enabled.
|
||||
std::unique_ptr<Common::AnalyticsReportingBackend> new_backend;
|
||||
if (Config::Get(Config::MAIN_ANALYTICS_ENABLED))
|
||||
{
|
||||
constexpr char analytics_endpoint[] = "https://analytics.dolphin-emu.org/report";
|
||||
#if defined(ANDROID)
|
||||
new_backend = std::make_unique<Common::AndroidAnalyticsBackend>(ANALYTICS_ENDPOINT);
|
||||
new_backend = std::make_unique<Common::AndroidAnalyticsBackend>(analytics_endpoint);
|
||||
#else
|
||||
new_backend = std::make_unique<Common::HttpAnalyticsBackend>(ANALYTICS_ENDPOINT);
|
||||
new_backend = std::make_unique<Common::HttpAnalyticsBackend>(analytics_endpoint);
|
||||
#endif
|
||||
}
|
||||
m_reporter.SetBackend(std::move(new_backend));
|
||||
@ -134,7 +224,7 @@ void DolphinAnalytics::ReportGameStart()
|
||||
|
||||
// Reset per-game state.
|
||||
m_reported_quirks.fill(false);
|
||||
InitializePerformanceSampling();
|
||||
m_sample_aggregator.InitializePerformanceSampling();
|
||||
}
|
||||
|
||||
// Keep in sync with enum class GameQuirk definition.
|
||||
@ -173,12 +263,12 @@ constexpr std::array GAME_QUIRKS_NAMES{
|
||||
"invalid-texture-coordinate-component-format",
|
||||
"invalid-color-component-format",
|
||||
};
|
||||
static_assert(GAME_QUIRKS_NAMES.size() == static_cast<u32>(GameQuirk::COUNT),
|
||||
static_assert(GAME_QUIRKS_NAMES.size() == static_cast<u32>(GameQuirk::Count),
|
||||
"Game quirks names and enum definition are out of sync.");
|
||||
|
||||
void DolphinAnalytics::ReportGameQuirk(GameQuirk quirk)
|
||||
{
|
||||
u32 quirk_idx = static_cast<u32>(quirk);
|
||||
const u32 quirk_idx = static_cast<u32>(quirk);
|
||||
|
||||
// Only report once per run.
|
||||
if (m_reported_quirks[quirk_idx])
|
||||
@ -193,140 +283,34 @@ void DolphinAnalytics::ReportGameQuirk(GameQuirk quirk)
|
||||
|
||||
void DolphinAnalytics::ReportPerformanceInfo(PerformanceSample&& sample)
|
||||
{
|
||||
if (ShouldStartPerformanceSampling())
|
||||
m_sample_aggregator.AddSampleIfSamplingInProgress(std::move(sample));
|
||||
const std::optional<PerformanceSampleAggregator::CompletedReport> report_optional =
|
||||
m_sample_aggregator.PopReportIfComplete();
|
||||
if (!report_optional)
|
||||
{
|
||||
m_sampling_performance_info = true;
|
||||
return;
|
||||
}
|
||||
const PerformanceSampleAggregator::CompletedReport& report = *report_optional;
|
||||
|
||||
if (m_sampling_performance_info)
|
||||
{
|
||||
m_performance_samples.emplace_back(std::move(sample));
|
||||
}
|
||||
// The per game builder should already exist -- there is no way we can be reporting performance
|
||||
// info without a game start event having been generated.
|
||||
Common::AnalyticsReportBuilder builder(m_per_game_builder);
|
||||
builder.AddData("type", "performance");
|
||||
builder.AddData("speed", report.speed);
|
||||
builder.AddData("prims", report.primitives);
|
||||
builder.AddData("draw-calls", report.draw_calls);
|
||||
|
||||
if (m_performance_samples.size() >= NUM_PERFORMANCE_SAMPLES_PER_REPORT)
|
||||
{
|
||||
std::vector<u32> speed_times_1000(m_performance_samples.size());
|
||||
std::vector<u32> num_prims(m_performance_samples.size());
|
||||
std::vector<u32> num_draw_calls(m_performance_samples.size());
|
||||
for (size_t i = 0; i < m_performance_samples.size(); ++i)
|
||||
{
|
||||
speed_times_1000[i] = static_cast<u32>(m_performance_samples[i].speed_ratio * 1000);
|
||||
num_prims[i] = m_performance_samples[i].num_prims;
|
||||
num_draw_calls[i] = m_performance_samples[i].num_draw_calls;
|
||||
}
|
||||
|
||||
// The per game builder should already exist -- there is no way we can be reporting performance
|
||||
// info without a game start event having been generated.
|
||||
Common::AnalyticsReportBuilder builder(m_per_game_builder);
|
||||
builder.AddData("type", "performance");
|
||||
builder.AddData("speed", speed_times_1000);
|
||||
builder.AddData("prims", num_prims);
|
||||
builder.AddData("draw-calls", num_draw_calls);
|
||||
|
||||
Send(builder);
|
||||
|
||||
// Clear up and stop sampling until next time ShouldStartPerformanceSampling() says so.
|
||||
m_performance_samples.clear();
|
||||
m_sampling_performance_info = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DolphinAnalytics::InitializePerformanceSampling()
|
||||
{
|
||||
m_performance_samples.clear();
|
||||
m_sampling_performance_info = false;
|
||||
|
||||
u64 wait_us =
|
||||
PERFORMANCE_SAMPLING_INITIAL_WAIT_TIME_SECS * 1000000 +
|
||||
Common::Random::GenerateValue<u64>() % (PERFORMANCE_SAMPLING_WAIT_TIME_JITTER_SECS * 1000000);
|
||||
m_sampling_next_start_us = Common::Timer::NowUs() + wait_us;
|
||||
}
|
||||
|
||||
bool DolphinAnalytics::ShouldStartPerformanceSampling()
|
||||
{
|
||||
if (Common::Timer::NowUs() < m_sampling_next_start_us)
|
||||
return false;
|
||||
|
||||
u64 wait_us =
|
||||
PERFORMANCE_SAMPLING_INTERVAL_SECS * 1000000 +
|
||||
Common::Random::GenerateValue<u64>() % (PERFORMANCE_SAMPLING_WAIT_TIME_JITTER_SECS * 1000000);
|
||||
m_sampling_next_start_us = Common::Timer::NowUs() + wait_us;
|
||||
return true;
|
||||
Send(builder);
|
||||
}
|
||||
|
||||
void DolphinAnalytics::MakeBaseBuilder()
|
||||
{
|
||||
Common::AnalyticsReportBuilder builder;
|
||||
m_base_builder = Common::AnalyticsReportBuilder();
|
||||
|
||||
// Version information.
|
||||
builder.AddData("version-desc", Common::GetScmDescStr());
|
||||
builder.AddData("version-hash", Common::GetScmRevGitStr());
|
||||
builder.AddData("version-branch", Common::GetScmBranchStr());
|
||||
builder.AddData("version-dist", Common::GetScmDistributorStr());
|
||||
|
||||
// Auto-Update information.
|
||||
builder.AddData("update-track", Config::Get(Config::MAIN_AUTOUPDATE_UPDATE_TRACK));
|
||||
|
||||
// CPU information.
|
||||
builder.AddData("cpu-summary", cpu_info.Summarize());
|
||||
|
||||
// OS information.
|
||||
#if defined(_WIN32)
|
||||
builder.AddData("os-type", "windows");
|
||||
|
||||
const auto winver = WindowsRegistry::GetOSVersion();
|
||||
builder.AddData("win-ver-major", static_cast<u32>(winver.dwMajorVersion));
|
||||
builder.AddData("win-ver-minor", static_cast<u32>(winver.dwMinorVersion));
|
||||
builder.AddData("win-ver-build", static_cast<u32>(winver.dwBuildNumber));
|
||||
#elif defined(ANDROID)
|
||||
builder.AddData("os-type", "android");
|
||||
builder.AddData("android-manufacturer", s_get_val_func("DEVICE_MANUFACTURER"));
|
||||
builder.AddData("android-model", s_get_val_func("DEVICE_MODEL"));
|
||||
builder.AddData("android-version", s_get_val_func("DEVICE_OS"));
|
||||
#elif defined(__APPLE__)
|
||||
builder.AddData("os-type", "osx");
|
||||
|
||||
// id processInfo = [NSProcessInfo processInfo]
|
||||
id processInfo = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(
|
||||
objc_getClass("NSProcessInfo"), sel_getUid("processInfo"));
|
||||
if (processInfo)
|
||||
{
|
||||
struct OSVersion // NSOperatingSystemVersion
|
||||
{
|
||||
s64 major_version; // NSInteger majorVersion
|
||||
s64 minor_version; // NSInteger minorVersion
|
||||
s64 patch_version; // NSInteger patchVersion
|
||||
};
|
||||
// Under arm64, we need to call objc_msgSend to receive a struct.
|
||||
// On x86_64, we need to explicitly call objc_msgSend_stret for a struct.
|
||||
#ifdef _M_ARM_64
|
||||
#define msgSend objc_msgSend
|
||||
#else
|
||||
#define msgSend objc_msgSend_stret
|
||||
#endif
|
||||
// NSOperatingSystemVersion version = [processInfo operatingSystemVersion]
|
||||
OSVersion version = reinterpret_cast<OSVersion (*)(id, SEL)>(msgSend)(
|
||||
processInfo, sel_getUid("operatingSystemVersion"));
|
||||
#undef msgSend
|
||||
builder.AddData("osx-ver-major", version.major_version);
|
||||
builder.AddData("osx-ver-minor", version.minor_version);
|
||||
builder.AddData("osx-ver-bugfix", version.patch_version);
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
builder.AddData("os-type", "linux");
|
||||
#elif defined(__FreeBSD__)
|
||||
builder.AddData("os-type", "freebsd");
|
||||
#elif defined(__OpenBSD__)
|
||||
builder.AddData("os-type", "openbsd");
|
||||
#elif defined(__NetBSD__)
|
||||
builder.AddData("os-type", "netbsd");
|
||||
#elif defined(__HAIKU__)
|
||||
builder.AddData("os-type", "haiku");
|
||||
#else
|
||||
builder.AddData("os-type", "unknown");
|
||||
#endif
|
||||
|
||||
m_base_builder = builder;
|
||||
AddVersionInformationToReportBuilder(&m_base_builder);
|
||||
AddAutoUpdateInformationToReportBuilder(&m_base_builder);
|
||||
AddCPUInformationToReportBuilder(&m_base_builder);
|
||||
AddPlatformInformationToReportBuilder(&m_base_builder);
|
||||
}
|
||||
|
||||
static const char* GetShaderCompilationMode(const VideoConfig& video_config)
|
||||
@ -348,12 +332,13 @@ static const char* GetShaderCompilationMode(const VideoConfig& video_config)
|
||||
void DolphinAnalytics::MakePerGameBuilder()
|
||||
{
|
||||
Common::AnalyticsReportBuilder builder(m_base_builder);
|
||||
const SConfig& config = SConfig::GetInstance();
|
||||
|
||||
// Gameid.
|
||||
builder.AddData("gameid", SConfig::GetInstance().GetGameID());
|
||||
builder.AddData("gameid", config.GetGameID());
|
||||
|
||||
// Unique id bound to the gameid.
|
||||
builder.AddData("id", MakeUniqueId(SConfig::GetInstance().GetGameID()));
|
||||
builder.AddData("id", MakeUniqueId(config.GetGameID()));
|
||||
|
||||
// Configuration.
|
||||
builder.AddData("cfg-dsp-hle", Config::Get(Config::MAIN_DSP_HLE));
|
||||
|
@ -7,10 +7,11 @@
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Analytics.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include "Core/PerformanceSample.h"
|
||||
#include "Core/PerformanceSampleAggregator.h"
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <functional>
|
||||
@ -21,86 +22,86 @@
|
||||
enum class GameQuirk
|
||||
{
|
||||
// Several Wii DI commands that are rarely/never used and not implemented by Dolphin
|
||||
USES_DVD_LOW_STOP_LASER,
|
||||
USES_DVD_LOW_OFFSET,
|
||||
USES_DVD_LOW_READ_DISK_BCA, // NSMBW known to use this
|
||||
USES_DVD_LOW_REQUEST_DISC_STATUS,
|
||||
USES_DVD_LOW_REQUEST_RETRY_NUMBER,
|
||||
USES_DVD_LOW_SER_MEAS_CONTROL,
|
||||
UsesDVDLowStopLaser,
|
||||
UsesDVDLowOffset,
|
||||
UsesDVDLowReadDiskBCA, // NSMBW known to use this
|
||||
UsesDVDLowRequestDiscStatus,
|
||||
UsesDVDLowRequestRetryNumber,
|
||||
UsesDVDLowSerMeasControl,
|
||||
|
||||
// Dolphin only implements the simple DVDLowOpenPartition, not any of the variants where some
|
||||
// already-read data is provided
|
||||
USES_DIFFERENT_PARTITION_COMMAND,
|
||||
UsesDifferentPartitionCommand,
|
||||
|
||||
// IOS has implementations for ioctls 0x85 and 0x89 and a stub for 0x87, but
|
||||
// DVDLowMaskCoverInterrupt/DVDLowUnmaskCoverInterrupt/DVDLowUnmaskStatusInterrupts
|
||||
// are all stubbed on the PPC side so they presumably will never be used.
|
||||
// (DVDLowClearCoverInterrupt is used, though)
|
||||
USES_DI_INTERRUPT_MASK_COMMAND,
|
||||
UsesDIInterruptMaskCommand,
|
||||
|
||||
// Some games configure a mismatched number of texture coordinates or colors between the transform
|
||||
// and TEV/BP stages of the rendering pipeline. Currently, Dolphin just skips over these objects
|
||||
// as the hardware renderers are not equipped to handle the case where the registers between
|
||||
// stages are mismatched.
|
||||
MISMATCHED_GPU_TEXGENS_BETWEEN_XF_AND_BP,
|
||||
MISMATCHED_GPU_COLORS_BETWEEN_XF_AND_BP,
|
||||
MismatchedGPUTexgensBetweenXFAndBP,
|
||||
MismatchedGPUColorsBetweenXFAndBP,
|
||||
|
||||
// The WD module can be configured to operate in six different modes.
|
||||
// In practice, only mode 1 (DS communications) and mode 3 (AOSS access point scanning)
|
||||
// are used by games and the system menu respectively.
|
||||
USES_UNCOMMON_WD_MODE,
|
||||
UsesUncommonWDMode,
|
||||
|
||||
USES_WD_UNIMPLEMENTED_IOCTL,
|
||||
UsesWDUnimplementedIoctl,
|
||||
|
||||
// Some games use invalid/unknown graphics commands (see e.g. bug 10931).
|
||||
// These are different from unknown opcodes: it is known that a BP/CP/XF command is being used,
|
||||
// but the command itself is not understood.
|
||||
USES_UNKNOWN_BP_COMMAND,
|
||||
USES_UNKNOWN_CP_COMMAND,
|
||||
USES_UNKNOWN_XF_COMMAND,
|
||||
UsesUnknownBPCommand,
|
||||
UsesUnknownCPCommand,
|
||||
UsesUnknownXFCommand,
|
||||
// YAGCD and Dolphin's implementation disagree about what is valid in some cases
|
||||
USES_MAYBE_INVALID_CP_COMMAND,
|
||||
UsesMaybeInvalidCPCommand,
|
||||
// These commands are used by a few games (e.g. bug 12461), and seem to relate to perf queries.
|
||||
// Track them separately.
|
||||
USES_CP_PERF_COMMAND,
|
||||
UsesCPPerfCommand,
|
||||
|
||||
// We don't implement all AX features yet.
|
||||
USES_UNIMPLEMENTED_AX_COMMAND,
|
||||
USES_AX_INITIAL_TIME_DELAY,
|
||||
USES_AX_WIIMOTE_LOWPASS,
|
||||
USES_AX_WIIMOTE_BIQUAD,
|
||||
UsesUnimplementedAXCommand,
|
||||
UsesAXInitialTimeDelay,
|
||||
UsesAXWiimoteLowpass,
|
||||
UsesAXWiimoteBiquad,
|
||||
|
||||
// We don't implement XFMEM_CLIPDISABLE yet.
|
||||
SETS_XF_CLIPDISABLE_BIT_0,
|
||||
SETS_XF_CLIPDISABLE_BIT_1,
|
||||
SETS_XF_CLIPDISABLE_BIT_2,
|
||||
SetsXFClipdisableBit0,
|
||||
SetsXFClipdisableBit1,
|
||||
SetsXFClipdisableBit2,
|
||||
|
||||
// Similar to the XF-BP mismatch, CP and XF might be configured with different vertex formats.
|
||||
// Real hardware seems to hang in this case, so games probably don't do this, but it would
|
||||
// be good to know if anything does it.
|
||||
MISMATCHED_GPU_COLORS_BETWEEN_CP_AND_XF,
|
||||
MISMATCHED_GPU_NORMALS_BETWEEN_CP_AND_XF,
|
||||
MISMATCHED_GPU_TEX_COORDS_BETWEEN_CP_AND_XF,
|
||||
MismatchedGPUColorsBetweenCPAndXF,
|
||||
MismatchedGPUNormalsBetweenCPAndXF,
|
||||
MismatchedGPUTexCoordsBetweenCPAndXF,
|
||||
// Both CP and XF have normally-identical matrix index information. We currently always
|
||||
// use the CP one in the hardware renderers and the XF one in the software renderer,
|
||||
// but testing is needed to find out which of these is actually used for what.
|
||||
MISMATCHED_GPU_MATRIX_INDICES_BETWEEN_CP_AND_XF,
|
||||
MismatchedGPUMatrixIndicesBetweenCPAndXF,
|
||||
|
||||
// Only a few games use the Bounding Box feature. Note that every game initializes the bounding
|
||||
// box registers (using BPMEM_CLEARBBOX1/BPMEM_CLEARBBOX2) on startup, as part of the SDK, but
|
||||
// only a few read them (from PE_BBOX_LEFT etc.)
|
||||
READS_BOUNDING_BOX,
|
||||
ReadsBoundingBox,
|
||||
|
||||
// A few games use invalid vertex component formats, but the two known cases (Fifa Street and
|
||||
// Def Jam: Fight for New York, see https://bugs.dolphin-emu.org/issues/12719) only use invalid
|
||||
// normal formats and lighting is disabled in those cases, so it doesn't end up mattering.
|
||||
// It's possible other games use invalid formats, possibly on other vertex components.
|
||||
INVALID_POSITION_COMPONENT_FORMAT,
|
||||
INVALID_NORMAL_COMPONENT_FORMAT,
|
||||
INVALID_TEXTURE_COORDINATE_COMPONENT_FORMAT,
|
||||
INVALID_COLOR_COMPONENT_FORMAT,
|
||||
InvalidPositionComponentFormat,
|
||||
InvalidNormalComponentFormat,
|
||||
InvalidTextureCoordinateComponentFormat,
|
||||
InvalidColorComponentFormat,
|
||||
|
||||
COUNT,
|
||||
Count,
|
||||
};
|
||||
|
||||
class DolphinAnalytics
|
||||
@ -134,14 +135,12 @@ public:
|
||||
// Get the base builder for building a report
|
||||
const Common::AnalyticsReportBuilder& BaseBuilder() const { return m_base_builder; }
|
||||
|
||||
struct PerformanceSample
|
||||
{
|
||||
double speed_ratio; // See SystemTimers::GetEstimatedEmulationPerformance().
|
||||
int num_prims;
|
||||
int num_draw_calls;
|
||||
};
|
||||
// Reports performance information. This method performs its own throttling / aggregation --
|
||||
// calling it does not guarantee when a report will actually be sent.
|
||||
// Performance reports are generated using data from 100 consecutive frames.
|
||||
// Report starting times are randomized to obtain a wider range of sample data.
|
||||
// The first report begins 5-8 minutes after a game is launched.
|
||||
// Successive reports begin 30-33 minutes after the previous report finishes.
|
||||
//
|
||||
// This method is NOT thread-safe.
|
||||
void ReportPerformanceInfo(PerformanceSample&& sample);
|
||||
@ -169,24 +168,10 @@ private:
|
||||
// values created by MakeUniqueId.
|
||||
std::string m_unique_id;
|
||||
|
||||
// Performance sampling configuration constants.
|
||||
//
|
||||
// 5min after startup + rand(0, 3min) jitter time, collect performance for 100 frames in a row.
|
||||
// Repeat collection after 30min + rand(0, 3min).
|
||||
static constexpr int NUM_PERFORMANCE_SAMPLES_PER_REPORT = 100;
|
||||
static constexpr int PERFORMANCE_SAMPLING_INITIAL_WAIT_TIME_SECS = 300;
|
||||
static constexpr int PERFORMANCE_SAMPLING_WAIT_TIME_JITTER_SECS = 180;
|
||||
static constexpr int PERFORMANCE_SAMPLING_INTERVAL_SECS = 1800;
|
||||
|
||||
// Performance sampling state & internal helpers.
|
||||
void InitializePerformanceSampling(); // Called on game start / title switch.
|
||||
bool ShouldStartPerformanceSampling();
|
||||
u64 m_sampling_next_start_us; // Next timestamp (in us) at which to trigger sampling.
|
||||
bool m_sampling_performance_info = false; // Whether we are currently collecting samples.
|
||||
std::vector<PerformanceSample> m_performance_samples;
|
||||
PerformanceSampleAggregator m_sample_aggregator;
|
||||
|
||||
// What quirks have already been reported about the current game.
|
||||
std::array<bool, static_cast<size_t>(GameQuirk::COUNT)> m_reported_quirks;
|
||||
std::array<bool, static_cast<size_t>(GameQuirk::Count)> m_reported_quirks;
|
||||
|
||||
// Builder that contains all non variable data that should be sent with all
|
||||
// reports.
|
||||
|
@ -220,7 +220,7 @@ class FifoPlayer::CPUCore final : public CPUCoreBase
|
||||
public:
|
||||
explicit CPUCore(FifoPlayer* parent) : m_parent(parent) {}
|
||||
CPUCore(const CPUCore&) = delete;
|
||||
~CPUCore() {}
|
||||
~CPUCore() override {}
|
||||
CPUCore& operator=(const CPUCore&) = delete;
|
||||
|
||||
void Init() override
|
||||
|
@ -157,7 +157,7 @@ class VAListStruct : public VAList
|
||||
{
|
||||
public:
|
||||
explicit VAListStruct(const Core::CPUThreadGuard& guard, u32 address);
|
||||
~VAListStruct() = default;
|
||||
~VAListStruct() override = default;
|
||||
|
||||
private:
|
||||
struct svr4_va_list
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
DSPHLE(DSPHLE&& other) = delete;
|
||||
DSPHLE& operator=(const DSPHLE& other) = delete;
|
||||
DSPHLE& operator=(DSPHLE&& other) = delete;
|
||||
~DSPHLE();
|
||||
~DSPHLE() override;
|
||||
|
||||
bool Initialize(bool wii, bool dsp_thread) override;
|
||||
void Shutdown() override;
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
AESndAccelerator(AESndAccelerator&&) = delete;
|
||||
AESndAccelerator& operator=(const AESndAccelerator&) = delete;
|
||||
AESndAccelerator& operator=(AESndAccelerator&&) = delete;
|
||||
~AESndAccelerator();
|
||||
~AESndAccelerator() override;
|
||||
|
||||
protected:
|
||||
void OnRawReadEndException() override {}
|
||||
|
@ -180,7 +180,7 @@ void AXUCode::HandleCommandList()
|
||||
break;
|
||||
|
||||
case CMD_UNK_08:
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_UNIMPLEMENTED_AX_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesUnimplementedAXCommand);
|
||||
curr_idx += 10;
|
||||
break; // TODO: check
|
||||
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
HLEAccelerator(HLEAccelerator&&) = delete;
|
||||
HLEAccelerator& operator=(const HLEAccelerator&) = delete;
|
||||
HLEAccelerator& operator=(HLEAccelerator&&) = delete;
|
||||
~HLEAccelerator() = default;
|
||||
~HLEAccelerator() override = default;
|
||||
|
||||
PB_TYPE* acc_pb = nullptr;
|
||||
|
||||
@ -536,7 +536,7 @@ void ProcessVoice(HLEAccelerator* accelerator, PB_TYPE& pb, const AXBuffers& buf
|
||||
if (pb.initial_time_delay.on)
|
||||
{
|
||||
// TODO
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_AX_INITIAL_TIME_DELAY);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesAXInitialTimeDelay);
|
||||
}
|
||||
|
||||
#ifdef AX_WII
|
||||
@ -548,12 +548,12 @@ void ProcessVoice(HLEAccelerator* accelerator, PB_TYPE& pb, const AXBuffers& buf
|
||||
// Only one filter at most for Wiimotes.
|
||||
if (pb.remote_iir.on == 2)
|
||||
{
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_AX_WIIMOTE_BIQUAD);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesAXWiimoteBiquad);
|
||||
BiquadFilter(samples, count, pb.remote_iir.biquad);
|
||||
}
|
||||
else
|
||||
{
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_AX_WIIMOTE_LOWPASS);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesAXWiimoteLowpass);
|
||||
LowPassFilter(samples, count, pb.remote_iir.lpf);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class DSPLLE : public DSPEmulator
|
||||
{
|
||||
public:
|
||||
DSPLLE();
|
||||
~DSPLLE();
|
||||
~DSPLLE() override;
|
||||
|
||||
bool Initialize(bool wii, bool dsp_thread) override;
|
||||
void Shutdown() override;
|
||||
|
@ -885,14 +885,14 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
||||
// Wii-exclusive
|
||||
case DICommand::StopLaser:
|
||||
ERROR_LOG_FMT(DVDINTERFACE, "DVDLowStopLaser");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DVD_LOW_STOP_LASER);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDVDLowStopLaser);
|
||||
SetDriveError(DriveError::InvalidCommand);
|
||||
interrupt_type = DIInterruptType::DEINT;
|
||||
break;
|
||||
// Wii-exclusive
|
||||
case DICommand::Offset:
|
||||
ERROR_LOG_FMT(DVDINTERFACE, "DVDLowOffset");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DVD_LOW_OFFSET);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDVDLowOffset);
|
||||
SetDriveError(DriveError::InvalidCommand);
|
||||
interrupt_type = DIInterruptType::DEINT;
|
||||
break;
|
||||
@ -900,7 +900,7 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
||||
case DICommand::ReadBCA:
|
||||
{
|
||||
WARN_LOG_FMT(DVDINTERFACE, "DVDLowReadDiskBca - supplying dummy data to appease NSMBW");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DVD_LOW_READ_DISK_BCA);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDVDLowReadDiskBCA);
|
||||
// NSMBW checks that the first 0x33 bytes of the BCA are 0, then it expects a 1.
|
||||
// Most (all?) other games have 0x34 0's at the start of the BCA, but don't actually
|
||||
// read it. NSMBW doesn't care about the other 12 bytes (which contain manufacturing data?)
|
||||
@ -915,14 +915,14 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
||||
// Wii-exclusive
|
||||
case DICommand::RequestDiscStatus:
|
||||
ERROR_LOG_FMT(DVDINTERFACE, "DVDLowRequestDiscStatus");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DVD_LOW_REQUEST_DISC_STATUS);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDVDLowRequestDiscStatus);
|
||||
SetDriveError(DriveError::InvalidCommand);
|
||||
interrupt_type = DIInterruptType::DEINT;
|
||||
break;
|
||||
// Wii-exclusive
|
||||
case DICommand::RequestRetryNumber:
|
||||
ERROR_LOG_FMT(DVDINTERFACE, "DVDLowRequestRetryNumber");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DVD_LOW_REQUEST_RETRY_NUMBER);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDVDLowRequestRetryNumber);
|
||||
SetDriveError(DriveError::InvalidCommand);
|
||||
interrupt_type = DIInterruptType::DEINT;
|
||||
break;
|
||||
@ -935,7 +935,7 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
||||
// Wii-exclusive
|
||||
case DICommand::SerMeasControl:
|
||||
ERROR_LOG_FMT(DVDINTERFACE, "DVDLowSerMeasControl");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DVD_LOW_SER_MEAS_CONTROL);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDVDLowSerMeasControl);
|
||||
SetDriveError(DriveError::InvalidCommand);
|
||||
interrupt_type = DIInterruptType::DEINT;
|
||||
break;
|
||||
|
@ -18,7 +18,7 @@ class CEXIAgp : public IEXIDevice
|
||||
{
|
||||
public:
|
||||
CEXIAgp(Core::System& system, const Slot slot);
|
||||
virtual ~CEXIAgp() override;
|
||||
~CEXIAgp() override;
|
||||
bool IsPresent() const override { return true; }
|
||||
void ImmWrite(u32 _uData, u32 _uSize) override;
|
||||
u32 ImmRead(u32 _uSize) override;
|
||||
|
@ -216,7 +216,7 @@ class CEXIETHERNET : public IEXIDevice
|
||||
{
|
||||
public:
|
||||
CEXIETHERNET(Core::System& system, BBADeviceType type);
|
||||
virtual ~CEXIETHERNET();
|
||||
~CEXIETHERNET() override;
|
||||
void SetCS(int cs) override;
|
||||
bool IsPresent() const override;
|
||||
bool IsInterruptSet() override;
|
||||
|
@ -18,7 +18,7 @@ class CEXIMic : public IEXIDevice
|
||||
{
|
||||
public:
|
||||
CEXIMic(Core::System& system, const int index);
|
||||
virtual ~CEXIMic();
|
||||
~CEXIMic() override;
|
||||
void SetCS(int cs) override;
|
||||
bool IsInterruptSet() override;
|
||||
bool IsPresent() const override;
|
||||
|
@ -33,7 +33,7 @@ class CEXIModem : public IEXIDevice
|
||||
{
|
||||
public:
|
||||
CEXIModem(Core::System& system, ModemDeviceType type);
|
||||
virtual ~CEXIModem();
|
||||
~CEXIModem() override;
|
||||
void SetCS(int cs) override;
|
||||
bool IsPresent() const override;
|
||||
bool IsInterruptSet() override;
|
||||
@ -136,13 +136,13 @@ private:
|
||||
TAPServerNetworkInterface(CEXIModem* modem_ref, const std::string& destination);
|
||||
|
||||
public:
|
||||
virtual bool Activate() override;
|
||||
virtual void Deactivate() override;
|
||||
virtual bool IsActivated() override;
|
||||
virtual bool SendAndRemoveAllHDLCFrames(std::string* send_buffer) override;
|
||||
virtual bool RecvInit() override;
|
||||
virtual void RecvStart() override;
|
||||
virtual void RecvStop() override;
|
||||
bool Activate() override;
|
||||
void Deactivate() override;
|
||||
bool IsActivated() override;
|
||||
bool SendAndRemoveAllHDLCFrames(std::string* send_buffer) override;
|
||||
bool RecvInit() override;
|
||||
void RecvStart() override;
|
||||
void RecvStop() override;
|
||||
|
||||
private:
|
||||
TAPServerConnection m_tapserver_if;
|
||||
|
@ -24,7 +24,7 @@ class GCMemcardDirectory : public MemoryCardBase
|
||||
public:
|
||||
GCMemcardDirectory(const std::string& directory, ExpansionInterface::Slot slot,
|
||||
const Memcard::HeaderData& header_data, u32 game_id);
|
||||
~GCMemcardDirectory();
|
||||
~GCMemcardDirectory() override;
|
||||
|
||||
GCMemcardDirectory(const GCMemcardDirectory&) = delete;
|
||||
GCMemcardDirectory& operator=(const GCMemcardDirectory&) = delete;
|
||||
|
@ -19,7 +19,7 @@ class MemoryCard : public MemoryCardBase
|
||||
public:
|
||||
MemoryCard(const std::string& filename, ExpansionInterface::Slot card_slot,
|
||||
u16 size_mbits = Memcard::MBIT_SIZE_MEMORY_CARD_2043);
|
||||
~MemoryCard();
|
||||
~MemoryCard() override;
|
||||
void FlushThread();
|
||||
void MakeDirty();
|
||||
|
||||
|
@ -39,7 +39,7 @@ class ConstantHandlingMethod : public ReadHandlingMethod<T>
|
||||
{
|
||||
public:
|
||||
explicit ConstantHandlingMethod(T value) : value_(value) {}
|
||||
virtual ~ConstantHandlingMethod() = default;
|
||||
~ConstantHandlingMethod() override = default;
|
||||
void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const override
|
||||
{
|
||||
v.VisitConstant(value_);
|
||||
@ -62,7 +62,7 @@ class NopHandlingMethod : public WriteHandlingMethod<T>
|
||||
{
|
||||
public:
|
||||
NopHandlingMethod() {}
|
||||
virtual ~NopHandlingMethod() = default;
|
||||
~NopHandlingMethod() override = default;
|
||||
void AcceptWriteVisitor(WriteHandlingMethodVisitor<T>& v) const override { v.VisitNop(); }
|
||||
};
|
||||
template <typename T>
|
||||
@ -79,7 +79,7 @@ class DirectHandlingMethod : public ReadHandlingMethod<T>, public WriteHandlingM
|
||||
{
|
||||
public:
|
||||
DirectHandlingMethod(T* addr, u32 mask) : addr_(addr), mask_(mask) {}
|
||||
virtual ~DirectHandlingMethod() = default;
|
||||
~DirectHandlingMethod() override = default;
|
||||
void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const override
|
||||
{
|
||||
v.VisitDirect(addr_, mask_);
|
||||
@ -122,7 +122,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ComplexHandlingMethod() = default;
|
||||
~ComplexHandlingMethod() override = default;
|
||||
void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const override
|
||||
{
|
||||
v.VisitComplex(&read_lambda_);
|
||||
|
@ -21,7 +21,7 @@ class CSIDevice_GBAEmu final : public ISIDevice
|
||||
{
|
||||
public:
|
||||
CSIDevice_GBAEmu(Core::System& system, SIDevices device, int device_number);
|
||||
~CSIDevice_GBAEmu();
|
||||
~CSIDevice_GBAEmu() override;
|
||||
|
||||
int RunBuffer(u8* buffer, int request_length) override;
|
||||
int TransferInterval() override;
|
||||
|
@ -120,7 +120,7 @@ protected:
|
||||
using EncryptedExtension::EncryptedExtension;
|
||||
|
||||
private:
|
||||
void UpdateEncryptionKey() final override;
|
||||
void UpdateEncryptionKey() final;
|
||||
};
|
||||
|
||||
class Extension3rdParty : public EncryptedExtension
|
||||
@ -129,7 +129,7 @@ protected:
|
||||
using EncryptedExtension::EncryptedExtension;
|
||||
|
||||
private:
|
||||
void UpdateEncryptionKey() final override;
|
||||
void UpdateEncryptionKey() final;
|
||||
};
|
||||
|
||||
} // namespace WiimoteEmu
|
||||
|
@ -137,7 +137,7 @@ public:
|
||||
static constexpr const char* SIDEWAYS_OPTION = "Sideways Wiimote";
|
||||
|
||||
explicit Wiimote(unsigned int index);
|
||||
~Wiimote();
|
||||
~Wiimote() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
|
||||
|
@ -34,7 +34,7 @@ class WiimoteScannerHidapi final : public WiimoteScannerBackend
|
||||
{
|
||||
public:
|
||||
WiimoteScannerHidapi();
|
||||
~WiimoteScannerHidapi();
|
||||
~WiimoteScannerHidapi() override;
|
||||
bool IsReady() const override;
|
||||
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
|
||||
void Update() override {} // not needed for hidapi
|
||||
|
@ -233,7 +233,7 @@ class HotkeyManager : public ControllerEmu::EmulatedController
|
||||
{
|
||||
public:
|
||||
HotkeyManager();
|
||||
~HotkeyManager();
|
||||
~HotkeyManager() override;
|
||||
|
||||
void GetInput(HotkeyStatus* hk, bool ignore_focus);
|
||||
std::string GetName() const override;
|
||||
|
@ -261,7 +261,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartIOCtl(const IOCtlRequest& reque
|
||||
case DIIoctl::DVDLowMaskCoverInterrupt:
|
||||
INFO_LOG_FMT(IOS_DI, "DVDLowMaskCoverInterrupt");
|
||||
system.GetDVDInterface().SetInterruptEnabled(DVD::DIInterruptType::CVRINT, false);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DI_INTERRUPT_MASK_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDIInterruptMaskCommand);
|
||||
return DIResult::Success;
|
||||
case DIIoctl::DVDLowClearCoverInterrupt:
|
||||
DEBUG_LOG_FMT(IOS_DI, "DVDLowClearCoverInterrupt");
|
||||
@ -269,7 +269,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartIOCtl(const IOCtlRequest& reque
|
||||
return DIResult::Success;
|
||||
case DIIoctl::DVDLowUnmaskStatusInterrupts:
|
||||
INFO_LOG_FMT(IOS_DI, "DVDLowUnmaskStatusInterrupts");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DI_INTERRUPT_MASK_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDIInterruptMaskCommand);
|
||||
// Dummied out
|
||||
return DIResult::Success;
|
||||
case DIIoctl::DVDLowGetCoverStatus:
|
||||
@ -282,7 +282,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartIOCtl(const IOCtlRequest& reque
|
||||
case DIIoctl::DVDLowUnmaskCoverInterrupt:
|
||||
INFO_LOG_FMT(IOS_DI, "DVDLowUnmaskCoverInterrupt");
|
||||
system.GetDVDInterface().SetInterruptEnabled(DVD::DIInterruptType::CVRINT, true);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DI_INTERRUPT_MASK_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDIInterruptMaskCommand);
|
||||
return DIResult::Success;
|
||||
case DIIoctl::DVDLowReset:
|
||||
{
|
||||
@ -319,7 +319,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartIOCtl(const IOCtlRequest& reque
|
||||
}
|
||||
case DIIoctl::DVDLowOpenPartition:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartition as an ioctl - rejecting");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
return DIResult::SecurityError;
|
||||
case DIIoctl::DVDLowClosePartition:
|
||||
INFO_LOG_FMT(IOS_DI, "DVDLowClosePartition");
|
||||
@ -372,23 +372,23 @@ std::optional<DIDevice::DIResult> DIDevice::StartIOCtl(const IOCtlRequest& reque
|
||||
// Dolphin as games are unlikely to use them.
|
||||
case DIIoctl::DVDLowGetNoDiscOpenPartitionParams:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscOpenPartitionParams as an ioctl - rejecting");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
return DIResult::SecurityError;
|
||||
case DIIoctl::DVDLowNoDiscOpenPartition:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowNoDiscOpenPartition as an ioctl - rejecting");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
return DIResult::SecurityError;
|
||||
case DIIoctl::DVDLowGetNoDiscBufferSizes:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscBufferSizes as an ioctl - rejecting");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
return DIResult::SecurityError;
|
||||
case DIIoctl::DVDLowOpenPartitionWithTmdAndTicket:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartitionWithTmdAndTicket as an ioctl - rejecting");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
return DIResult::SecurityError;
|
||||
case DIIoctl::DVDLowOpenPartitionWithTmdAndTicketView:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartitionWithTmdAndTicketView as an ioctl - rejecting");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
return DIResult::SecurityError;
|
||||
case DIIoctl::DVDLowGetStatusRegister:
|
||||
{
|
||||
@ -721,14 +721,14 @@ std::optional<IPCReply> DIDevice::IOCtlV(const IOCtlVRequest& request)
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_DI,
|
||||
"DVDLowOpenPartition with ticket - not implemented, ignoring ticket parameter");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
}
|
||||
if (request.in_vectors[2].address != 0)
|
||||
{
|
||||
ERROR_LOG_FMT(
|
||||
IOS_DI,
|
||||
"DVDLowOpenPartition with cert chain - not implemented, ignoring certs parameter");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
}
|
||||
|
||||
const u64 partition_offset =
|
||||
@ -752,26 +752,26 @@ std::optional<IPCReply> DIDevice::IOCtlV(const IOCtlVRequest& request)
|
||||
}
|
||||
case DIIoctl::DVDLowGetNoDiscOpenPartitionParams:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscOpenPartitionParams - dummied out");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||
break;
|
||||
case DIIoctl::DVDLowNoDiscOpenPartition:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowNoDiscOpenPartition - dummied out");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||
break;
|
||||
case DIIoctl::DVDLowGetNoDiscBufferSizes:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscBufferSizes - dummied out");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||
break;
|
||||
case DIIoctl::DVDLowOpenPartitionWithTmdAndTicket:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartitionWithTmdAndTicket - not implemented");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
break;
|
||||
case DIIoctl::DVDLowOpenPartitionWithTmdAndTicketView:
|
||||
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartitionWithTmdAndTicketView - not implemented");
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesDifferentPartitionCommand);
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG_FMT(IOS_DI, "Unknown ioctlv {:#04x}", request.request);
|
||||
|
@ -234,7 +234,7 @@ public:
|
||||
ESDevice(ESDevice&& other) = delete;
|
||||
ESDevice& operator=(const ESDevice& other) = delete;
|
||||
ESDevice& operator=(ESDevice&& other) = delete;
|
||||
~ESDevice();
|
||||
~ESDevice() override;
|
||||
|
||||
static void InitializeEmulationState(CoreTiming::CoreTimingManager& core_timing);
|
||||
static void FinalizeEmulationState();
|
||||
|
@ -117,7 +117,7 @@ class FSDevice final : public EmulationDevice
|
||||
{
|
||||
public:
|
||||
FSDevice(EmulationKernel& ios, FSCore& core, const std::string& device_name);
|
||||
~FSDevice();
|
||||
~FSDevice() override;
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
|
@ -23,7 +23,7 @@ class HostFileSystem final : public FileSystem
|
||||
{
|
||||
public:
|
||||
HostFileSystem(const std::string& root_path, std::vector<NandRedirect> nand_redirects = {});
|
||||
~HostFileSystem();
|
||||
~HostFileSystem() override;
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
|
@ -153,7 +153,7 @@ class EmulationKernel final : public Kernel
|
||||
{
|
||||
public:
|
||||
EmulationKernel(Core::System& system, u64 ios_title_id);
|
||||
~EmulationKernel();
|
||||
~EmulationKernel() override;
|
||||
|
||||
// Get a resource manager by name.
|
||||
// This only works for devices which are part of the device map.
|
||||
|
@ -84,7 +84,7 @@ class NetSSLDevice : public EmulationDevice
|
||||
public:
|
||||
NetSSLDevice(EmulationKernel& ios, const std::string& device_name);
|
||||
|
||||
virtual ~NetSSLDevice();
|
||||
~NetSSLDevice() override;
|
||||
|
||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
@ -198,7 +198,7 @@ std::optional<IPCReply> NetWDCommandDevice::Open(const OpenRequest& request)
|
||||
if (mode != WD::Mode::DSCommunications && mode != WD::Mode::AOSSAccessPointScan)
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_NET, "Unsupported WD operating mode: {}", mode);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_UNCOMMON_WD_MODE);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesUncommonWDMode);
|
||||
return IPCReply(s32(ResultCode::UnavailableCommand));
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ std::optional<IPCReply> NetWDCommandDevice::IOCtlV(const IOCtlVRequest& request)
|
||||
case IOCTLV_WD_CHANGE_GAMEINFO:
|
||||
case IOCTLV_WD_CHANGE_VTSF:
|
||||
default:
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_WD_UNIMPLEMENTED_IOCTL);
|
||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::UsesWDUnimplementedIoctl);
|
||||
request.Dump(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_NET,
|
||||
Common::Log::LogLevel::LWARNING);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class BluetoothEmuDevice final : public BluetoothBaseDevice
|
||||
public:
|
||||
BluetoothEmuDevice(EmulationKernel& ios, const std::string& device_name);
|
||||
|
||||
virtual ~BluetoothEmuDevice();
|
||||
~BluetoothEmuDevice() override;
|
||||
|
||||
std::optional<IPCReply> Close(u32 fd) override;
|
||||
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
@ -73,7 +73,7 @@ class SkylanderUSB final : public Device
|
||||
{
|
||||
public:
|
||||
SkylanderUSB();
|
||||
~SkylanderUSB();
|
||||
~SkylanderUSB() override;
|
||||
DeviceDescriptor GetDeviceDescriptor() const override;
|
||||
std::vector<ConfigDescriptor> GetConfigurations() const override;
|
||||
std::vector<InterfaceDescriptor> GetInterfaces(u8 config) const override;
|
||||
|
@ -78,8 +78,8 @@ std::string USBHost::GetDeviceNameFromVIDPID(u16 vid, u16 pid)
|
||||
libusb_get_string_descriptor_ascii(handle, desc.iProduct, buffer, sizeof(buffer)) > 0)
|
||||
{
|
||||
device_name = reinterpret_cast<char*>(buffer);
|
||||
libusb_close(handle);
|
||||
}
|
||||
libusb_close(handle);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class USBHost : public EmulationDevice
|
||||
{
|
||||
public:
|
||||
USBHost(EmulationKernel& ios, const std::string& device_name);
|
||||
virtual ~USBHost();
|
||||
~USBHost() override;
|
||||
|
||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||
|
||||
|
@ -27,7 +27,7 @@ class LibusbDevice final : public Device
|
||||
{
|
||||
public:
|
||||
LibusbDevice(libusb_device* device, const libusb_device_descriptor& device_descriptor);
|
||||
~LibusbDevice();
|
||||
~LibusbDevice() override;
|
||||
DeviceDescriptor GetDeviceDescriptor() const override;
|
||||
std::vector<ConfigDescriptor> GetConfigurations() const override;
|
||||
std::vector<InterfaceDescriptor> GetInterfaces(u8 config) const override;
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
|
||||
NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog,
|
||||
const std::string& name, const NetTraversalConfig& traversal_config);
|
||||
~NetPlayClient();
|
||||
~NetPlayClient() override;
|
||||
|
||||
std::vector<const Player*> GetPlayers();
|
||||
const NetSettings& GetNetSettings() const;
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
|
||||
NetPlayServer(u16 port, bool forward_port, NetPlayUI* dialog,
|
||||
const NetTraversalConfig& traversal_config);
|
||||
~NetPlayServer();
|
||||
~NetPlayServer() override;
|
||||
|
||||
bool ChangeGame(const SyncIdentifier& sync_identifier, const std::string& netplay_name);
|
||||
bool ComputeGameDigest(const SyncIdentifier& sync_identifier);
|
||||
|
@ -86,7 +86,7 @@ class PCAPSSLCaptureLogger final : public NetworkCaptureLogger
|
||||
{
|
||||
public:
|
||||
PCAPSSLCaptureLogger();
|
||||
~PCAPSSLCaptureLogger();
|
||||
~PCAPSSLCaptureLogger() override;
|
||||
|
||||
void OnNewSocket(s32 socket) override;
|
||||
|
||||
|
12
Source/Core/Core/PerformanceSample.h
Normal file
12
Source/Core/Core/PerformanceSample.h
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
struct PerformanceSample
|
||||
{
|
||||
double speed_ratio; // See SystemTimers::GetEstimatedEmulationPerformance().
|
||||
int num_prims;
|
||||
int num_draw_calls;
|
||||
};
|
105
Source/Core/Core/PerformanceSampleAggregator.cpp
Normal file
105
Source/Core/Core/PerformanceSampleAggregator.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/PerformanceSampleAggregator.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "Common/Random.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr size_t s_samples_per_report = 100;
|
||||
|
||||
std::chrono::microseconds GetCurrentMicroseconds()
|
||||
{
|
||||
const std::chrono::high_resolution_clock::duration time_since_epoch =
|
||||
std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(time_since_epoch);
|
||||
}
|
||||
|
||||
std::chrono::microseconds GetSamplingStartTimeJitter()
|
||||
{
|
||||
constexpr long long max_delay = std::chrono::microseconds(std::chrono::minutes(3)).count();
|
||||
return std::chrono::microseconds(Common::Random::GenerateValue<u64>() % max_delay);
|
||||
}
|
||||
|
||||
std::chrono::microseconds
|
||||
GetSamplingStartTimestampUsingBaseDelay(const std::chrono::microseconds base_delay)
|
||||
{
|
||||
const std::chrono::microseconds now = GetCurrentMicroseconds();
|
||||
const std::chrono::microseconds jitter = GetSamplingStartTimeJitter();
|
||||
const std::chrono::microseconds sampling_start_timestamp = now + base_delay + jitter;
|
||||
return sampling_start_timestamp;
|
||||
}
|
||||
|
||||
std::chrono::microseconds GetInitialSamplingStartTimestamp()
|
||||
{
|
||||
constexpr std::chrono::microseconds base_initial_delay = std::chrono::minutes(5);
|
||||
return GetSamplingStartTimestampUsingBaseDelay(base_initial_delay);
|
||||
}
|
||||
|
||||
std::chrono::microseconds GetRepeatSamplingStartTimestamp()
|
||||
{
|
||||
constexpr std::chrono::microseconds base_repeat_delay = std::chrono::minutes(30);
|
||||
return GetSamplingStartTimestampUsingBaseDelay(base_repeat_delay);
|
||||
}
|
||||
|
||||
PerformanceSampleAggregator::CompletedReport
|
||||
GetCompletedReport(const std::vector<PerformanceSample>& samples)
|
||||
{
|
||||
PerformanceSampleAggregator::CompletedReport report;
|
||||
const size_t num_samples = samples.size();
|
||||
report.speed.resize(num_samples);
|
||||
report.primitives.resize(num_samples);
|
||||
report.draw_calls.resize(num_samples);
|
||||
|
||||
for (size_t i = 0; i < num_samples; ++i)
|
||||
{
|
||||
const PerformanceSample& sample = samples[i];
|
||||
report.speed[i] = static_cast<u32>(sample.speed_ratio * 1'000);
|
||||
report.primitives[i] = sample.num_prims;
|
||||
report.draw_calls[i] = sample.num_draw_calls;
|
||||
}
|
||||
return report;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PerformanceSampleAggregator::PerformanceSampleAggregator()
|
||||
: m_samples(std::vector<PerformanceSample>(s_samples_per_report)),
|
||||
m_next_starting_timestamp(std::numeric_limits<std::chrono::microseconds>::max())
|
||||
{
|
||||
}
|
||||
|
||||
void PerformanceSampleAggregator::InitializePerformanceSampling()
|
||||
{
|
||||
m_samples.clear();
|
||||
m_next_starting_timestamp = GetInitialSamplingStartTimestamp();
|
||||
}
|
||||
|
||||
void PerformanceSampleAggregator::ResetPerformanceSampling()
|
||||
{
|
||||
m_samples.clear();
|
||||
m_next_starting_timestamp = GetRepeatSamplingStartTimestamp();
|
||||
}
|
||||
|
||||
void PerformanceSampleAggregator::AddSampleIfSamplingInProgress(PerformanceSample&& sample)
|
||||
{
|
||||
if (GetCurrentMicroseconds() >= m_next_starting_timestamp)
|
||||
{
|
||||
m_samples.push_back(sample);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<PerformanceSampleAggregator::CompletedReport>
|
||||
PerformanceSampleAggregator::PopReportIfComplete()
|
||||
{
|
||||
if (m_samples.size() < s_samples_per_report)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
const CompletedReport report = GetCompletedReport(m_samples);
|
||||
ResetPerformanceSampling();
|
||||
return report;
|
||||
}
|
38
Source/Core/Core/PerformanceSampleAggregator.h
Normal file
38
Source/Core/Core/PerformanceSampleAggregator.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include "Core/PerformanceSample.h"
|
||||
|
||||
class PerformanceSampleAggregator
|
||||
{
|
||||
public:
|
||||
PerformanceSampleAggregator();
|
||||
|
||||
struct CompletedReport
|
||||
{
|
||||
std::vector<u32> speed;
|
||||
std::vector<u32> primitives;
|
||||
std::vector<u32> draw_calls;
|
||||
};
|
||||
|
||||
// Called on game start / title switch.
|
||||
void InitializePerformanceSampling();
|
||||
void AddSampleIfSamplingInProgress(PerformanceSample&& sample);
|
||||
std::optional<CompletedReport> PopReportIfComplete();
|
||||
|
||||
private:
|
||||
// Called after sampling report is completed
|
||||
void ResetPerformanceSampling();
|
||||
|
||||
std::vector<PerformanceSample> m_samples;
|
||||
std::chrono::microseconds m_next_starting_timestamp;
|
||||
};
|
@ -31,7 +31,7 @@ public:
|
||||
CachedInterpreter(CachedInterpreter&&) = delete;
|
||||
CachedInterpreter& operator=(const CachedInterpreter&) = delete;
|
||||
CachedInterpreter& operator=(CachedInterpreter&&) = delete;
|
||||
~CachedInterpreter();
|
||||
~CachedInterpreter() override;
|
||||
|
||||
void Init() override;
|
||||
void Shutdown() override;
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
Interpreter(Interpreter&&) = delete;
|
||||
Interpreter& operator=(const Interpreter&) = delete;
|
||||
Interpreter& operator=(Interpreter&&) = delete;
|
||||
~Interpreter();
|
||||
~Interpreter() override;
|
||||
|
||||
void Init() override;
|
||||
void Shutdown() override;
|
||||
|
@ -8,7 +8,7 @@
|
||||
class CSVSignatureDB final : public HashSignatureDB
|
||||
{
|
||||
public:
|
||||
~CSVSignatureDB() = default;
|
||||
~CSVSignatureDB() override = default;
|
||||
bool Load(const std::string& file_path) override;
|
||||
bool Save(const std::string& file_path) const override;
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
class DSYSignatureDB final : public HashSignatureDB
|
||||
{
|
||||
public:
|
||||
~DSYSignatureDB() = default;
|
||||
~DSYSignatureDB() override = default;
|
||||
bool Load(const std::string& file_path) override;
|
||||
bool Save(const std::string& file_path) const override;
|
||||
};
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "IOS/USB/Emulated/Infinity.h"
|
||||
#include "IOS/USB/Emulated/Skylanders/Skylander.h"
|
||||
#include "IOS/USB/USBScanner.h"
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
#include "VideoCommon/Assets/CustomResourceManager.h"
|
||||
#include "VideoCommon/CommandProcessor.h"
|
||||
#include "VideoCommon/Fifo.h"
|
||||
#include "VideoCommon/GeometryShaderManager.h"
|
||||
@ -96,7 +96,7 @@ struct System::Impl
|
||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||
Interpreter m_interpreter;
|
||||
JitInterface m_jit_interface;
|
||||
VideoCommon::CustomAssetLoader m_custom_asset_loader;
|
||||
VideoCommon::CustomResourceManager m_custom_resource_manager;
|
||||
FifoPlayer m_fifo_player;
|
||||
FifoRecorder m_fifo_recorder;
|
||||
Movie::MovieManager m_movie;
|
||||
@ -335,8 +335,8 @@ VideoInterface::VideoInterfaceManager& System::GetVideoInterface() const
|
||||
return m_impl->m_video_interface;
|
||||
}
|
||||
|
||||
VideoCommon::CustomAssetLoader& System::GetCustomAssetLoader() const
|
||||
VideoCommon::CustomResourceManager& System::GetCustomResourceManager() const
|
||||
{
|
||||
return m_impl->m_custom_asset_loader;
|
||||
return m_impl->m_custom_resource_manager;
|
||||
}
|
||||
} // namespace Core
|
||||
|
@ -108,8 +108,8 @@ class SystemTimersManager;
|
||||
}
|
||||
namespace VideoCommon
|
||||
{
|
||||
class CustomAssetLoader;
|
||||
}
|
||||
class CustomResourceManager;
|
||||
} // namespace VideoCommon
|
||||
namespace VideoInterface
|
||||
{
|
||||
class VideoInterfaceManager;
|
||||
@ -197,7 +197,7 @@ public:
|
||||
VertexShaderManager& GetVertexShaderManager() const;
|
||||
XFStateManager& GetXFStateManager() const;
|
||||
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
|
||||
VideoCommon::CustomAssetLoader& GetCustomAssetLoader() const;
|
||||
VideoCommon::CustomResourceManager& GetCustomResourceManager() const;
|
||||
|
||||
private:
|
||||
System();
|
||||
|
@ -107,7 +107,7 @@ protected:
|
||||
class SectorReader : public BlobReader
|
||||
{
|
||||
public:
|
||||
virtual ~SectorReader() = 0;
|
||||
~SectorReader() override = 0;
|
||||
|
||||
bool Read(u64 offset, u64 size, u8* out_ptr) override;
|
||||
|
||||
|
@ -45,7 +45,7 @@ class CompressedBlobReader final : public SectorReader
|
||||
public:
|
||||
static std::unique_ptr<CompressedBlobReader> Create(File::IOFile file,
|
||||
const std::string& filename);
|
||||
~CompressedBlobReader();
|
||||
~CompressedBlobReader() override;
|
||||
|
||||
const CompressedBlobHeader& GetHeader() const { return m_header; }
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user