Compare commits

...

48 Commits

Author SHA1 Message Date
SuperSamus
c3bded43c7
Merge e7f22515d3 into 24b0bf01d5 2025-06-08 08:40:53 +02:00
JMC47
24b0bf01d5
Merge pull request #12836 from JosJuice/opensles-buffer-size
Android: Ask system for optimal audio buffer size and sample rate
2025-06-07 23:07:37 -04:00
Tilka
19fbbf0dba
Merge pull request #13727 from JoshuaVandaele/fmt-11.2.0-localtime-deprec
fmt: Replace deprecated `fmt::localtime` usage with `Common::LocalTime`
2025-06-08 04:04:37 +01:00
Jordan Woyak
1786e34bd3
Merge pull request #13665 from jordan-woyak/dark-mode-filter
DolphinQt: Replace widespread SetQWidgetWindowDecorations calls with an event filter.
2025-06-07 18:19:13 -05:00
Jordan Woyak
65f3ba70f5
Merge pull request #13522 from tygyh/Enforce-overriding-destructor-style-Core&UnitTests
Core & UnitTests: Make overriding explicit and remove redundant virtual specifiers on overriding destructors
2025-06-07 17:55:14 -05:00
Jordan Woyak
ec52a74967
Merge pull request #13023 from tygyh/Replace-ties-with-structured-bindings
UnitTests: Replace ties with structured bindings
2025-06-07 17:50:34 -05:00
Jordan Woyak
8b7669550f
Merge pull request #13454 from tygyh/Use-constants-DolphinQt-FifoAnalyzer
DolphinQt/FIFO/FIFOAnalyzer: Make parameters, arguments etc. constant
2025-06-07 17:50:08 -05:00
Jordan Woyak
46e66fe945
Merge pull request #13544 from tygyh/DolphinNoGUI-Replace-deprecated-signal-header
DolphinNoGUI: Apply style-alignment refactorings
2025-06-07 17:47:11 -05:00
Jordan Woyak
056ece6f29
Merge pull request #13697 from tygyh/AudioCommon/Remove-unused-includes
AudioCommon: Remove unused includes
2025-06-07 17:45:50 -05:00
Jordan Woyak
a07a2fe398
Merge pull request #13698 from tygyh/AudioCommon/Remove-unused-qualifiers-and-make-variables-constant
AudioCommon: Remove unused qualifiers and make variables constant
2025-06-07 17:45:33 -05:00
Jordan Woyak
5906512847 DolphinQt: Replace widespread SetQWidgetWindowDecorations calls with an event filter. 2025-06-07 16:15:34 -05:00
JMC47
52fcdde485
Merge pull request #13386 from iwubcode/resource_manager_system
VideoCommon: add resource manager, tracks resources to load assets in optimal way and manage memory
2025-06-07 15:51:34 -04:00
iwubcode
c3d3b81533 VideoCommon: remove 'GetByteSizeInMemory()' from custom asset, it is not needed anymore 2025-06-06 23:03:02 -05:00
iwubcode
774a84a953 VideoCommon: avoid race conditions with asset load/unload by moving the lock to the entire function, favor atomics for the memory/time getters 2025-06-06 23:03:02 -05:00
iwubcode
b3f50c969e VideoCommon: rename m_bytes_loaded in asset library to bytes_loaded 2025-06-06 23:03:02 -05:00
iwubcode
3b83907b88 VideoCommon: update CustomAsset's load time to be before the load occurs (this prevents issues where the load time might be incorrectly inflated by long load operations)
Co-authored-by: Jordan Woyak <jordan.woyak@gmail.com>
2025-06-06 23:03:02 -05:00
iwubcode
d940d62cae VideoCommon: watch texture pack folder for texture reloads (from dynamic input textures) 2025-06-06 23:03:02 -05:00
iwubcode
7afa9e6c6f VideoCommon: use CustomResourceManager in the texture cache and hook up to our hires textures 2025-06-06 23:03:02 -05:00
iwubcode
12d178a8df VideoCommon: initialize and shutdown the CustomResourceManager when the video thread initializes and shuts down 2025-06-06 23:03:02 -05:00
iwubcode
f910c1d934 Core: add CustomResourceManager to System 2025-06-06 23:03:02 -05:00
iwubcode
70abcb2030 VideoCommon: add resource manager and new asset loader; the resource manager uses a least recently used cache to determine which assets get priority for loading. Additionally, if the system is low on memory, assets will be purged with the less requested assets being the first to go. The loader is multithreaded now and loads assets as quickly as possible as long as memory is available
Co-authored-by: Jordan Woyak <jordan.woyak@gmail.com>
2025-06-06 23:03:02 -05:00
iwubcode
d8ea31ca46 VideoCommon: rename GameTextureAsset into TextureAsset and make it only contain CustomTextureData. Move validation and load logic to individual functions 2025-06-06 23:03:02 -05:00
iwubcode
2ae43324cb VideoCommon: move AssetMap to a types header file, so it can be pulled in without the DirectFilesystemAssetLibrary dependencies, the header will be expanded later 2025-06-06 23:03:02 -05:00
iwubcode
7d59c2743d Common: Add class 'FilesystemWatcher' that is used to watch paths and receive callbacks about filesystem level events for anything under that path 2025-06-06 23:03:02 -05:00
iwubcode
8113399b68 Externals: add watcher, a library used to watch a filesystem location for changes 2025-06-06 23:03:02 -05:00
iwubcode
bafe78203d VideoCommon: remove 'GetLastAssetWriteTime' and switch to a steady_clock for asset times 2025-06-06 23:03:02 -05:00
iwubcode
15f125ebee VideoCommon: change asset loading to return the number of bytes loaded instead of a pass/fail 2025-06-06 23:03:02 -05:00
iwubcode
316740daed VideoCommon: add 'Unload' functionality to CustomAsset 2025-06-06 23:03:02 -05:00
iwubcode
9ec69b5925 VideoCommon: add a handle to custom asset, this is an id that is only relevant for a particular game session but is slightly faster as a numeric value for lookups than the traditional asset id 2025-06-06 19:20:25 -05:00
iwubcode
d7de49ccf6 Core / VideoCommon: Remove original custom asset loader 2025-06-06 19:20:25 -05:00
Dr. Dystopia
bae0e5f67a DolphinNoGUI: Make override explicit 2025-06-04 21:49:29 +02:00
Dr. Dystopia
2ae928ca79 DolphinNoGUI: Make parameters constant 2025-06-04 21:49:15 +02:00
Dr. Dystopia
f04f659710 DolphinNoGUI: Replace C-style cast with reinterpret_cast 2025-06-04 21:49:01 +02:00
Dr. Dystopia
ec1d659363 DolphinNoGUI: Make classes final 2025-06-04 21:48:53 +02:00
Dr. Dystopia
c37933932d DolphinNoGUI: Make variables constant 2025-06-04 21:48:40 +02:00
Dr. Dystopia
23af1e025b DolphinNoGUI: Make function static 2025-06-04 21:30:59 +02:00
Dr. Dystopia
135b6840e5 DolphinNoGUI: Remove unused include directives 2025-06-04 21:30:59 +02:00
Dr. Dystopia
e3df00b7f4 DolphinNoGUI: Make variables constexpr 2025-06-04 21:30:59 +02:00
Dr. Dystopia
71da0f2d24 DolphinNoGUI: Replace deprecated signal.h header 2025-06-04 21:30:59 +02:00
Joshua Vandaële
4b65cc9a4c
fmt: Replace deprecated fmt::localtime usage with Common::LocalTime 2025-06-04 13:32:12 +02:00
Dr. Dystopia
8192d9d2a9 Make parameters, arguments etc. constant 2025-05-31 20:57:54 +02:00
Dr. Dystopia
a6b04f53e0 AudioCommon: Remove unused qualifiers and make variables constant 2025-05-30 21:48:38 +02:00
JosJuice
f99d3dbd5c Android: Ask system for optimal audio buffer size and sample rate
This can reduce audio latency according to
https://developer.android.com/ndk/guides/audio/opensl/opensl-prog-notes#perform.

Previously we were using the hardcoded values of 48000 Hz and 256 frames
per buffer. The sample rate we use with this change is 48000 Hz on all
devices I'm aware of, but the buffer size does vary across devices.

Terminology note: The old code used the term "sample" to refer to what
Android refers to as a "frame". "Frame" is a clearer term to use for
this, so I've changed OpenSLESStream's terminology. One frame consists
of one sample per channel.
2025-05-25 11:59:33 +02:00
JosJuice
34e8fb068f Android: Get rid of OpenSLESStream's global state
Not sure if we're ever going to want to have more than one of these at
the same time, but these global variables are a code smell nonetheless.

I'm also deleting the existing member variables because they were
unused.
2025-05-25 11:55:22 +02:00
Dr. Dystopia
7c237bbd7c AudioCommon: Remove unused includes 2025-05-25 10:30:41 +02:00
Martino Fontana
e7f22515d3 GameINI: Disable Immediately Present XFB for Dragon Ball Z: Budokai and Dragon Ball Z: Budokai 2 2025-05-10 14:14:12 +02:00
Dr. Dystopia
f240e20e3f Make overriding explicit and remove redundant virtual specifiers on overriding destructors - Core & UnitTests 2025-05-01 15:00:37 +02:00
Dr. Dystopia
096ab8c026 Replace ties with structured bindings - UnitTests 2024-08-20 15:09:44 +02:00
246 changed files with 1876 additions and 1495 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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
#

View File

@ -0,0 +1,5 @@
# GD7JB2, GD7E70, GD7PB2 - Dragon Ball Z: Budokai
[Video_Hacks]
# Frame pacing
ImmediateXFBEnable = False

View File

@ -0,0 +1,5 @@
# GZ3E70, GZ3PB2 - Dragon Ball Z: Budokai 2
[Video_Hacks]
# Frame pacing
ImmediateXFBEnable = False

4
Externals/watcher/CMakeLists.txt vendored Normal file
View 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

@ -0,0 +1 @@
Subproject commit b03bdcfc11549df595b77239cefe2643943a3e2f

View File

@ -0,0 +1,28 @@
package org.dolphinemu.dolphinemu.utils
import android.content.Context
import android.media.AudioManager
import androidx.annotation.Keep
import org.dolphinemu.dolphinemu.DolphinApplication
object AudioUtils {
@JvmStatic @Keep
fun getSampleRate(): Int =
getAudioServiceProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE, 48000)
@JvmStatic @Keep
fun getFramesPerBuffer(): Int =
getAudioServiceProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER, 256)
private fun getAudioServiceProperty(property: String, fallback: Int): Int {
return try {
val context = DolphinApplication.getAppContext()
val am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
Integer.parseUnsignedInt(am.getProperty(property))
} catch (e: NullPointerException) {
fallback
} catch (e: NumberFormatException) {
fallback
}
}
}

View File

@ -122,6 +122,10 @@ static jmethodID s_permission_handler_request_record_audio_permission;
static jmethodID s_runnable_run;
static jclass s_audio_utils_class;
static jmethodID s_audio_utils_get_sample_rate;
static jmethodID s_audio_utils_get_frames_per_buffer;
namespace IDCache
{
JNIEnv* GetEnvForThread()
@ -562,6 +566,21 @@ jmethodID GetRunnableRun()
return s_runnable_run;
}
jclass GetAudioUtilsClass()
{
return s_audio_utils_class;
}
jmethodID GetAudioUtilsGetSampleRate()
{
return s_audio_utils_get_sample_rate;
}
jmethodID GetAudioUtilsGetFramesPerBuffer()
{
return s_audio_utils_get_frames_per_buffer;
}
} // namespace IDCache
extern "C" {
@ -798,6 +817,13 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
s_runnable_run = env->GetMethodID(runnable_class, "run", "()V");
env->DeleteLocalRef(runnable_class);
const jclass audio_utils_class = env->FindClass("org/dolphinemu/dolphinemu/utils/AudioUtils");
s_audio_utils_class = reinterpret_cast<jclass>(env->NewGlobalRef(audio_utils_class));
s_audio_utils_get_sample_rate = env->GetStaticMethodID(audio_utils_class, "getSampleRate", "()I");
s_audio_utils_get_frames_per_buffer =
env->GetStaticMethodID(audio_utils_class, "getFramesPerBuffer", "()I");
env->DeleteLocalRef(audio_utils_class);
return JNI_VERSION;
}
@ -834,5 +860,6 @@ JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
env->DeleteGlobalRef(s_core_device_control_class);
env->DeleteGlobalRef(s_input_detector_class);
env->DeleteGlobalRef(s_permission_handler_class);
env->DeleteGlobalRef(s_audio_utils_class);
}
}

View File

@ -121,4 +121,8 @@ jmethodID GetPermissionHandlerRequestRecordAudioPermission();
jmethodID GetRunnableRun();
jclass GetAudioUtilsClass();
jmethodID GetAudioUtilsGetSampleRate();
jmethodID GetAudioUtilsGetFramesPerBuffer();
} // namespace IDCache

View File

@ -3,9 +3,7 @@
#pragma once
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>
#if defined(HAVE_ALSA) && HAVE_ALSA

View File

@ -16,6 +16,7 @@
#include "AudioCommon/WASAPIStream.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/TimeUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/System.h"
@ -166,7 +167,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 +194,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,14 +214,17 @@ 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();
std::string base_name =
fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, fmt::localtime(start_time));
const auto local_time = Common::LocalTime(start_time);
if (!local_time)
return;
std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, *local_time);
const std::string audio_file_name_dtk = fmt::format("{}_dtkdump.wav", base_name);
const std::string audio_file_name_dsp = fmt::format("{}_dspdump.wav", base_name);
@ -232,7 +237,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 +270,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);
}

View File

@ -3,7 +3,6 @@
#pragma once
#include <memory>
#include <string>
#include <string_view>
#include <vector>

View File

@ -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;
});

View File

@ -3,8 +3,6 @@
#pragma once
#include <cstddef>
#include <functional>
#include <memory>
#include <vector>

View File

@ -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,

View File

@ -3,11 +3,9 @@
#pragma once
#include <algorithm>
#include <array>
#include <atomic>
#include <bit>
#include <cmath>
#include "AudioCommon/SurroundDecoder.h"
#include "AudioCommon/WaveFile.h"

View File

@ -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;

View File

@ -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>

View File

@ -8,40 +8,27 @@
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <jni.h>
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"
#include "jni/AndroidCommon/IDCache.h"
// engine interfaces
static SLObjectItf engineObject;
static SLEngineItf engineEngine;
static SLObjectItf outputMixObject;
// buffer queue player interfaces
static SLObjectItf bqPlayerObject = nullptr;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLVolumeItf bqPlayerVolume;
static Mixer* g_mixer;
#define BUFFER_SIZE 512
#define BUFFER_SIZE_IN_SAMPLES (BUFFER_SIZE / 2)
// Double buffering.
static short buffer[2][BUFFER_SIZE];
static int curBuffer = 0;
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
void OpenSLESStream::BQPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
{
ASSERT(bq == bqPlayerBufferQueue);
ASSERT(nullptr == context);
reinterpret_cast<OpenSLESStream*>(context)->PushSamples(bq);
}
void OpenSLESStream::PushSamples(SLAndroidSimpleBufferQueueItf bq)
{
ASSERT(bq == m_bq_player_buffer_queue);
// Render to the fresh buffer
g_mixer->Mix(reinterpret_cast<short*>(buffer[curBuffer]), BUFFER_SIZE_IN_SAMPLES);
SLresult result =
(*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[0]));
curBuffer ^= 1; // Switch buffer
m_mixer->Mix(m_buffer[m_current_buffer].data(), m_frames_per_buffer);
SLresult result = (*bq)->Enqueue(bq, m_buffer[m_current_buffer].data(), m_bytes_per_buffer);
m_current_buffer ^= 1; // Switch buffer
// Comment from sample code:
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
@ -51,61 +38,78 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
bool OpenSLESStream::Init()
{
JNIEnv* env = IDCache::GetEnvForThread();
jclass audio_utils = IDCache::GetAudioUtilsClass();
const SLuint32 sample_rate =
env->CallStaticIntMethod(audio_utils, IDCache::GetAudioUtilsGetSampleRate());
m_frames_per_buffer =
env->CallStaticIntMethod(audio_utils, IDCache::GetAudioUtilsGetFramesPerBuffer());
INFO_LOG_FMT(AUDIO, "OpenSLES configuration: {} Hz, {} frames per buffer", sample_rate,
m_frames_per_buffer);
constexpr SLuint32 channels = 2;
const SLuint32 samples_per_buffer = m_frames_per_buffer * channels;
m_bytes_per_buffer = m_frames_per_buffer * channels * sizeof(m_buffer[0][0]);
for (std::vector<short>& buffer : m_buffer)
buffer.resize(samples_per_buffer);
SLresult result;
// create engine
result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
result = slCreateEngine(&m_engine_object, 0, nullptr, 0, nullptr, nullptr);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
result = (*m_engine_object)->Realize(m_engine_object, SL_BOOLEAN_FALSE);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
result = (*m_engine_object)->GetInterface(m_engine_object, SL_IID_ENGINE, &m_engine_engine);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
result = (*m_engine_engine)->CreateOutputMix(m_engine_engine, &m_output_mix_object, 0, 0, 0);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
result = (*m_output_mix_object)->Realize(m_output_mix_object, SL_BOOLEAN_FALSE);
ASSERT(SL_RESULT_SUCCESS == result);
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,
2,
m_mixer->GetSampleRate() * 1000,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN};
SLDataFormat_PCM format_pcm = {
SL_DATAFORMAT_PCM, channels,
sample_rate * 1000, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, m_output_mix_object};
SLDataSink audioSnk = {&loc_outmix, nullptr};
// create audio player
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result =
(*engineEngine)
->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
result = (*m_engine_engine)
->CreateAudioPlayer(m_engine_engine, &m_bq_player_object, &audioSrc, &audioSnk, 2,
ids, req);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
result = (*m_bq_player_object)->Realize(m_bq_player_object, SL_BOOLEAN_FALSE);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
result = (*m_bq_player_object)->GetInterface(m_bq_player_object, SL_IID_PLAY, &m_bq_player_play);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*m_bq_player_object)
->GetInterface(m_bq_player_object, SL_IID_BUFFERQUEUE, &m_bq_player_buffer_queue);
ASSERT(SL_RESULT_SUCCESS == result);
result =
(*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &bqPlayerBufferQueue);
(*m_bq_player_object)->GetInterface(m_bq_player_object, SL_IID_VOLUME, &m_bq_player_volume);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
result = (*m_bq_player_buffer_queue)
->RegisterCallback(m_bq_player_buffer_queue, BQPlayerCallback, this);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
result = (*m_bq_player_play)->SetPlayState(m_bq_player_play, SL_PLAYSTATE_PLAYING);
ASSERT(SL_RESULT_SUCCESS == result);
// Render and enqueue a first buffer.
curBuffer ^= 1;
g_mixer = m_mixer.get();
m_current_buffer ^= 1;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[0], sizeof(buffer[0]));
result = (*m_bq_player_buffer_queue)
->Enqueue(m_bq_player_buffer_queue, m_buffer[0].data(), m_bytes_per_buffer);
if (SL_RESULT_SUCCESS != result)
return false;
@ -114,39 +118,39 @@ bool OpenSLESStream::Init()
OpenSLESStream::~OpenSLESStream()
{
if (bqPlayerObject != nullptr)
if (m_bq_player_object != nullptr)
{
(*bqPlayerObject)->Destroy(bqPlayerObject);
bqPlayerObject = nullptr;
bqPlayerPlay = nullptr;
bqPlayerBufferQueue = nullptr;
bqPlayerVolume = nullptr;
(*m_bq_player_object)->Destroy(m_bq_player_object);
m_bq_player_object = nullptr;
m_bq_player_play = nullptr;
m_bq_player_buffer_queue = nullptr;
m_bq_player_volume = nullptr;
}
if (outputMixObject != nullptr)
if (m_output_mix_object != nullptr)
{
(*outputMixObject)->Destroy(outputMixObject);
outputMixObject = nullptr;
(*m_output_mix_object)->Destroy(m_output_mix_object);
m_output_mix_object = nullptr;
}
if (engineObject != nullptr)
if (m_engine_object != nullptr)
{
(*engineObject)->Destroy(engineObject);
engineObject = nullptr;
engineEngine = nullptr;
(*m_engine_object)->Destroy(m_engine_object);
m_engine_object = nullptr;
m_engine_engine = nullptr;
}
}
bool OpenSLESStream::SetRunning(bool running)
{
SLuint32 new_state = running ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED;
return (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, new_state) == SL_RESULT_SUCCESS;
return (*m_bq_player_play)->SetPlayState(m_bq_player_play, new_state) == SL_RESULT_SUCCESS;
}
void OpenSLESStream::SetVolume(int volume)
{
const SLmillibel attenuation =
volume <= 0 ? SL_MILLIBEL_MIN : static_cast<SLmillibel>(2000 * std::log10(volume / 100.0f));
(*bqPlayerVolume)->SetVolumeLevel(bqPlayerVolume, attenuation);
(*m_bq_player_volume)->SetVolumeLevel(m_bq_player_volume, attenuation);
}
#endif // HAVE_OPENSL_ES

View File

@ -3,10 +3,15 @@
#pragma once
#include <thread>
#ifdef HAVE_OPENSL_ES
#include <array>
#include <vector>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#endif // HAVE_OPENSL_ES
#include "AudioCommon/SoundStream.h"
#include "Common/Event.h"
class OpenSLESStream final : public SoundStream
{
@ -19,7 +24,25 @@ public:
static bool IsValid() { return true; }
private:
std::thread thread;
Common::Event soundSyncEvent;
static void BQPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context);
void PushSamples(SLAndroidSimpleBufferQueueItf bq);
// engine interfaces
SLObjectItf m_engine_object;
SLEngineItf m_engine_engine;
SLObjectItf m_output_mix_object;
// buffer queue player interfaces
SLObjectItf m_bq_player_object = nullptr;
SLPlayItf m_bq_player_play;
SLAndroidSimpleBufferQueueItf m_bq_player_buffer_queue;
SLVolumeItf m_bq_player_volume;
SLuint32 m_frames_per_buffer;
SLuint32 m_bytes_per_buffer;
// Double buffering.
std::array<std::vector<short>, 2> m_buffer;
int m_current_buffer = 0;
#endif // HAVE_OPENSL_ES
};

View File

@ -8,7 +8,6 @@
#endif
#include "AudioCommon/SoundStream.h"
#include "Common/CommonTypes.h"
#include "Common/Flag.h"
#include "Common/Thread.h"

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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}
)

View File

@ -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;

View File

@ -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{};
};

View File

@ -25,6 +25,7 @@
#include "Common/Logging/Log.h"
#include "Common/ScopeGuard.h"
#include "Common/StringUtil.h"
#include "Common/TimeUtil.h"
#include "Core/Config/MainSettings.h"
@ -95,12 +96,7 @@ int SDCardDiskIOCtl(File::IOFile* image, u8 pdrv, u8 cmd, void* buff)
u32 GetSystemTimeFAT()
{
const std::time_t time = std::time(nullptr);
std::tm tm;
#ifdef _WIN32
localtime_s(&tm, &time);
#else
localtime_r(&time, &tm);
#endif
std::tm tm = *Common::LocalTime(time);
DWORD fattime = 0;
fattime |= (tm.tm_year - 80) << 25;

View 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

View 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

View File

@ -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;

View File

@ -101,7 +101,7 @@ class HostDisassemblerBochs final : public HostDisassembler
{
public:
explicit HostDisassemblerBochs();
~HostDisassemblerBochs() = default;
~HostDisassemblerBochs() override = default;
private:
disassembler m_disasm;

View File

@ -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;

View File

@ -122,7 +122,6 @@ std::string SettingsWriter::GenerateSerialNumber()
// Must be 9 characters at most; otherwise the serial number will be rejected by SDK libraries,
// as there is a check to ensure the string length is strictly lower than 10.
// 3 for %j, 2 for %H, 2 for %M, 2 for %S.
return fmt::format("{:%j%H%M%S}", fmt::localtime(t));
return fmt::format("{:09}", t % 1000000000);
}
} // namespace Common

View File

@ -2,23 +2,25 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Common/TimeUtil.h"
#include "Common/Logging/Log.h"
#include <ctime>
#include <optional>
namespace Common
{
std::optional<std::tm> Localtime(std::time_t time)
std::optional<std::tm> LocalTime(std::time_t time)
{
std::tm local_time;
#ifdef _MSC_VER
if (localtime_s(&local_time, &time) != 0)
return std::nullopt;
#else
std::tm* result = localtime_r(&time, &local_time);
if (result != &local_time)
return std::nullopt;
if (localtime_r(&time, &local_time) == NULL)
#endif
{
ERROR_LOG_FMT(COMMON, "Failed to convert time to local time: {}", std::strerror(errno));
return std::nullopt;
}
return local_time;
}
} // Namespace Common

View File

@ -9,5 +9,5 @@
namespace Common
{
// Threadsafe and error-checking variant of std::localtime()
std::optional<std::tm> Localtime(std::time_t time);
std::optional<std::tm> LocalTime(std::time_t time);
} // Namespace Common

View File

@ -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; }

View File

@ -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); }

View File

@ -8,6 +8,7 @@
#include <cstring>
#include <functional>
#include <mutex>
#include <optional>
#include <queue>
#include <utility>
#include <variant>
@ -34,6 +35,7 @@
#include "Common/ScopeGuard.h"
#include "Common/StringUtil.h"
#include "Common/Thread.h"
#include "Common/TimeUtil.h"
#include "Common/Version.h"
#include "Core/AchievementManager.h"
@ -82,7 +84,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 +529,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(); });
@ -737,15 +735,17 @@ static std::string GenerateScreenshotFolderPath()
return path;
}
static std::string GenerateScreenshotName()
static std::optional<std::string> GenerateScreenshotName()
{
// append gameId, path only contains the folder here.
const std::string path_prefix =
GenerateScreenshotFolderPath() + SConfig::GetInstance().GetGameID();
const std::time_t cur_time = std::time(nullptr);
const std::string base_name =
fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, fmt::localtime(cur_time));
const auto local_time = Common::LocalTime(cur_time);
if (!local_time)
return std::nullopt;
const std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, *local_time);
// First try a filename without any suffixes, if already exists then append increasing numbers
std::string name = fmt::format("{}.png", base_name);
@ -761,7 +761,9 @@ static std::string GenerateScreenshotName()
void SaveScreenShot()
{
const Core::CPUThreadGuard guard(Core::System::GetInstance());
g_frame_dumper->SaveScreenshot(GenerateScreenshotName());
std::optional<std::string> name = GenerateScreenshotName();
if (name)
g_frame_dumper->SaveScreenshot(*name);
}
void SaveScreenShot(std::string_view name)

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -27,7 +27,7 @@ public:
AESndAccelerator(AESndAccelerator&&) = delete;
AESndAccelerator& operator=(const AESndAccelerator&) = delete;
AESndAccelerator& operator=(AESndAccelerator&&) = delete;
~AESndAccelerator();
~AESndAccelerator() override;
protected:
void OnRawReadEndException() override {}

View File

@ -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;

View File

@ -20,7 +20,7 @@ class DSPLLE : public DSPEmulator
{
public:
DSPLLE();
~DSPLLE();
~DSPLLE() override;
bool Initialize(bool wii, bool dsp_thread) override;
void Shutdown() override;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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_);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -16,6 +16,7 @@
#include "Common/Network.h"
#include "Common/PcapFile.h"
#include "Common/ScopeGuard.h"
#include "Common/TimeUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
@ -82,7 +83,7 @@ PCAPSSLCaptureLogger::PCAPSSLCaptureLogger()
{
const std::string filepath =
fmt::format("{}{} {:%Y-%m-%d %Hh%Mm%Ss}.pcap", File::GetUserPath(D_DUMPSSL_IDX),
SConfig::GetInstance().GetGameID(), fmt::localtime(std::time(nullptr)));
SConfig::GetInstance().GetGameID(), *Common::LocalTime(std::time(nullptr)));
m_file = std::make_unique<Common::PCAP>(
new File::IOFile(filepath, "wb", File::SharedAccess::Read), Common::PCAP::LinkType::Ethernet);
}

View File

@ -86,7 +86,7 @@ class PCAPSSLCaptureLogger final : public NetworkCaptureLogger
{
public:
PCAPSSLCaptureLogger();
~PCAPSSLCaptureLogger();
~PCAPSSLCaptureLogger() override;
void OnNewSocket(s32 socket) override;

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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;
};

View File

@ -281,7 +281,7 @@ static std::string SystemTimeAsDoubleToString(double time)
{
// revert adjustments from GetSystemTimeAsDouble() to get a normal Unix timestamp again
const time_t seconds = static_cast<time_t>(time) + DOUBLE_TIME_OFFSET;
const auto local_time = Common::Localtime(seconds);
const auto local_time = Common::LocalTime(seconds);
if (!local_time)
return "";

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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; }

View File

@ -29,7 +29,7 @@ class VolumeGC final : public VolumeDisc
{
public:
VolumeGC(std::unique_ptr<BlobReader> reader);
~VolumeGC();
~VolumeGC() override;
bool Read(u64 offset, u64 length, u8* buffer,
const Partition& partition = PARTITION_NONE) const override;
const FileSystem* GetFileSystem(const Partition& partition = PARTITION_NONE) const override;

View File

@ -58,7 +58,7 @@ public:
static_assert(sizeof(HashBlock) == BLOCK_HEADER_SIZE);
VolumeWii(std::unique_ptr<BlobReader> reader);
~VolumeWii();
~VolumeWii() override;
bool Read(u64 offset, u64 length, u8* buffer, const Partition& partition) const override;
bool HasWiiHashes() const override;
bool HasWiiEncryption() const override;

View File

@ -44,7 +44,7 @@ template <bool RVZ>
class WIARVZFileReader final : public BlobReader
{
public:
~WIARVZFileReader();
~WIARVZFileReader() override;
static std::unique_ptr<WIARVZFileReader> Create(File::IOFile file, const std::string& path);

View File

@ -75,7 +75,7 @@ private:
class Bzip2Decompressor final : public Decompressor
{
public:
~Bzip2Decompressor();
~Bzip2Decompressor() override;
bool Decompress(const DecompressionBuffer& in, DecompressionBuffer* out,
size_t* in_bytes_read) override;
@ -89,7 +89,7 @@ class LZMADecompressor final : public Decompressor
{
public:
LZMADecompressor(bool lzma2, const u8* filter_options, size_t filter_options_size);
~LZMADecompressor();
~LZMADecompressor() override;
bool Decompress(const DecompressionBuffer& in, DecompressionBuffer* out,
size_t* in_bytes_read) override;
@ -106,7 +106,7 @@ class ZstdDecompressor final : public Decompressor
{
public:
ZstdDecompressor();
~ZstdDecompressor();
~ZstdDecompressor() override;
bool Decompress(const DecompressionBuffer& in, DecompressionBuffer* out,
size_t* in_bytes_read) override;
@ -164,7 +164,7 @@ class PurgeCompressor final : public Compressor
{
public:
PurgeCompressor();
~PurgeCompressor();
~PurgeCompressor() override;
bool Start(std::optional<u64> size) override;
bool AddPrecedingDataOnlyForPurgeHashing(const u8* data, size_t size) override;
@ -184,7 +184,7 @@ class Bzip2Compressor final : public Compressor
{
public:
Bzip2Compressor(int compression_level);
~Bzip2Compressor();
~Bzip2Compressor() override;
bool Start(std::optional<u64> size) override;
bool Compress(const u8* data, size_t size) override;
@ -206,7 +206,7 @@ class LZMACompressor final : public Compressor
public:
LZMACompressor(bool lzma2, int compression_level, u8 compressor_data_out[7],
u8* compressor_data_size_out);
~LZMACompressor();
~LZMACompressor() override;
bool Start(std::optional<u64> size) override;
bool Compress(const u8* data, size_t size) override;
@ -229,7 +229,7 @@ class ZstdCompressor final : public Compressor
{
public:
ZstdCompressor(int compression_level);
~ZstdCompressor();
~ZstdCompressor() override;
bool Start(std::optional<u64> size) override;
bool Compress(const u8* data, size_t size) override;

View File

@ -18,7 +18,7 @@ static constexpr u32 WBFS_MAGIC = 0x53464257; // "WBFS" (byteswapped to little
class WbfsFileReader final : public BlobReader
{
public:
~WbfsFileReader();
~WbfsFileReader() override;
static std::unique_ptr<WbfsFileReader> Create(File::IOFile file, const std::string& path);

View File

@ -59,6 +59,7 @@
<ClInclude Include="Common\Event.h" />
<ClInclude Include="Common\FatFsUtil.h" />
<ClInclude Include="Common\FileSearch.h" />
<ClInclude Include="Common\FilesystemWatcher.h" />
<ClInclude Include="Common\FileUtil.h" />
<ClInclude Include="Common\FixedSizeQueue.h" />
<ClInclude Include="Common\Flag.h" />
@ -669,12 +670,16 @@
<ClInclude Include="VideoCommon\Assets\CustomAsset.h" />
<ClInclude Include="VideoCommon\Assets\CustomAssetLibrary.h" />
<ClInclude Include="VideoCommon\Assets\CustomAssetLoader.h" />
<ClInclude Include="VideoCommon\Assets\CustomResourceManager.h" />
<ClInclude Include="VideoCommon\Assets\CustomTextureData.h" />
<ClInclude Include="VideoCommon\Assets\DirectFilesystemAssetLibrary.h" />
<ClInclude Include="VideoCommon\Assets\MaterialAsset.h" />
<ClInclude Include="VideoCommon\Assets\MeshAsset.h" />
<ClInclude Include="VideoCommon\Assets\ShaderAsset.h" />
<ClInclude Include="VideoCommon\Assets\TextureAsset.h" />
<ClInclude Include="VideoCommon\Assets\TextureAssetUtils.h" />
<ClInclude Include="VideoCommon\Assets\Types.h" />
<ClInclude Include="VideoCommon\Assets\WatchableFilesystemAssetLibrary.h" />
<ClInclude Include="VideoCommon\AsyncRequests.h" />
<ClInclude Include="VideoCommon\AsyncShaderCompiler.h" />
<ClInclude Include="VideoCommon\BoundingBox.h" />
@ -814,6 +819,7 @@
<ClCompile Include="Common\ENet.cpp" />
<ClCompile Include="Common\FatFsUtil.cpp" />
<ClCompile Include="Common\FileSearch.cpp" />
<ClCompile Include="Common\FilesystemWatcher.cpp" />
<ClCompile Include="Common\FileUtil.cpp" />
<ClCompile Include="Common\FloatUtils.cpp" />
<ClCompile Include="Common\GekkoDisassembler.cpp" />
@ -1320,14 +1326,15 @@
<ClCompile Include="VideoCommon\AbstractStagingTexture.cpp" />
<ClCompile Include="VideoCommon\AbstractTexture.cpp" />
<ClCompile Include="VideoCommon\Assets\CustomAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\CustomAssetLibrary.cpp" />
<ClCompile Include="VideoCommon\Assets\CustomAssetLoader.cpp" />
<ClCompile Include="VideoCommon\Assets\CustomResourceManager.cpp" />
<ClCompile Include="VideoCommon\Assets\CustomTextureData.cpp" />
<ClCompile Include="VideoCommon\Assets\DirectFilesystemAssetLibrary.cpp" />
<ClCompile Include="VideoCommon\Assets\MaterialAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\MeshAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\ShaderAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\TextureAsset.cpp" />
<ClCompile Include="VideoCommon\Assets\TextureAssetUtils.cpp" />
<ClCompile Include="VideoCommon\AsyncRequests.cpp" />
<ClCompile Include="VideoCommon\AsyncShaderCompiler.cpp" />
<ClCompile Include="VideoCommon\BoundingBox.cpp" />

View File

@ -4,10 +4,8 @@
#include "DolphinNoGUI/Platform.h"
#include <OptionParser.h>
#include <cstddef>
#include <csignal>
#include <cstdio>
#include <cstring>
#include <signal.h>
#include <string>
#include <vector>
@ -32,15 +30,13 @@
#endif
#include "UICommon/UICommon.h"
#include "InputCommon/GCAdapter.h"
#include "VideoCommon/VideoBackendBase.h"
static std::unique_ptr<Platform> s_platform;
static void signal_handler(int)
{
const char message[] = "A signal was received. A second signal will force Dolphin to stop.\n";
constexpr char message[] = "A signal was received. A second signal will force Dolphin to stop.\n";
#ifdef _WIN32
puts(message);
#else
@ -75,7 +71,7 @@ bool Host_UIBlocksControllerState()
}
static Common::Event s_update_main_frame_event;
void Host_Message(HostMessageID id)
void Host_Message(const HostMessageID id)
{
if (id == HostMessageID::WMUserStop)
s_platform->Stop();
@ -201,11 +197,12 @@ static std::unique_ptr<Platform> GetPlatform(const optparse::Values& options)
#define main app_main
#endif
int main(int argc, char* argv[])
int main(const int argc, char* argv[])
{
Core::DeclareAsHostThread();
auto parser = CommandLineParse::CreateParser(CommandLineParse::ParserOptions::OmitGUIOptions);
const auto parser =
CommandLineParse::CreateParser(CommandLineParse::ParserOptions::OmitGUIOptions);
parser->add_option("-p", "--platform")
.action("store")
.help("Window platform to use [%choices]")
@ -301,14 +298,14 @@ int main(int argc, char* argv[])
return 1;
}
Core::AddOnStateChangedCallback([](Core::State state) {
Core::AddOnStateChangedCallback([](const Core::State state) {
if (state == Core::State::Uninitialized)
s_platform->Stop();
});
#ifdef _WIN32
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
std::signal(SIGINT, signal_handler);
std::signal(SIGTERM, signal_handler);
#else
// Shut down cleanly on SIGINT and SIGTERM
struct sigaction sa;

View File

@ -6,7 +6,6 @@
#include "Core/HW/ProcessorInterface.h"
#include "Core/IOS/IOS.h"
#include "Core/IOS/STM/STM.h"
#include "Core/State.h"
#include "Core/System.h"
Platform::~Platform() = default;
@ -24,7 +23,7 @@ void Platform::UpdateRunningFlag()
{
if (m_shutdown_requested.TestAndClear())
{
auto& system = Core::System::GetInstance();
const auto& system = Core::System::GetInstance();
const auto ios = system.GetIOS();
const auto stm = ios ? ios->GetDeviceByName("/dev/stm/eventhook") : nullptr;
if (!m_tried_graceful_shutdown.IsSet() && stm &&

View File

@ -10,7 +10,7 @@
namespace
{
class PlatformHeadless : public Platform
class PlatformHeadless final : public Platform
{
public:
void SetTitle(const std::string& title) override;

View File

@ -3,16 +3,13 @@
#include "DolphinNoGUI/Platform.h"
#include "Common/MsgHandler.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/State.h"
#include "Core/System.h"
#include <Windows.h>
#include <climits>
#include <cstdio>
#include <dwmapi.h>
#include "VideoCommon/Present.h"
@ -20,7 +17,7 @@
namespace
{
class PlatformWin32 : public Platform
class PlatformWin32 final : public Platform
{
public:
~PlatformWin32() override;
@ -29,14 +26,14 @@ public:
void SetTitle(const std::string& string) override;
void MainLoop() override;
WindowSystemInfo GetWindowSystemInfo() const;
WindowSystemInfo GetWindowSystemInfo() const override;
private:
static constexpr TCHAR WINDOW_CLASS_NAME[] = _T("DolphinNoGUI");
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
bool RegisterRenderWindowClass();
static bool RegisterRenderWindowClass();
bool CreateRenderWindow();
void UpdateWindowPosition();
void ProcessEvents();
@ -66,7 +63,7 @@ bool PlatformWin32::RegisterRenderWindowClass()
wc.hInstance = GetModuleHandle(nullptr);
wc.hIcon = LoadIcon(nullptr, IDI_ICON1);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
wc.lpszMenuName = nullptr;
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.hIconSm = LoadIcon(nullptr, IDI_ICON1);
@ -168,7 +165,8 @@ void PlatformWin32::ProcessEvents()
}
}
LRESULT PlatformWin32::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
LRESULT PlatformWin32::WndProc(const HWND hwnd, const UINT msg, const WPARAM wParam,
const LPARAM lParam)
{
PlatformWin32* platform = reinterpret_cast<PlatformWin32*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
switch (msg)
@ -185,7 +183,7 @@ LRESULT PlatformWin32::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
if (hwnd)
{
// Remove rounded corners from the render window on Windows 11
const DWM_WINDOW_CORNER_PREFERENCE corner_preference = DWMWCP_DONOTROUND;
constexpr DWM_WINDOW_CORNER_PREFERENCE corner_preference = DWMWCP_DONOTROUND;
DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &corner_preference,
sizeof(corner_preference));
}

View File

@ -34,7 +34,7 @@ class CheatsManager : public QDialog
Q_OBJECT
public:
explicit CheatsManager(Core::System& system, QWidget* parent = nullptr);
~CheatsManager();
~CheatsManager() override;
signals:
void OpenGeneralSettings();

View File

@ -23,7 +23,6 @@
#include "DolphinQt/Config/CheatWarningWidget.h"
#include "DolphinQt/Config/HardcoreWarningWidget.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
ARCodeWidget::ARCodeWidget(std::string game_id, u16 game_revision, bool restart_required)
: m_game_id(std::move(game_id)), m_game_revision(game_revision),
@ -257,7 +256,6 @@ void ARCodeWidget::OnCodeAddClicked()
ar.enabled = true;
m_cheat_code_editor->SetARCode(&ar);
SetQWidgetWindowDecorations(m_cheat_code_editor);
if (m_cheat_code_editor->exec() == QDialog::Rejected)
return;
@ -275,7 +273,6 @@ void ARCodeWidget::OnCodeEditClicked()
const auto* const selected = items[0];
auto& current_ar = m_ar_codes[m_code_list->row(selected)];
SetQWidgetWindowDecorations(m_cheat_code_editor);
if (current_ar.user_defined)
{

View File

@ -13,7 +13,6 @@
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@ -60,7 +59,6 @@ void CommonControllersWidget::OnControllerInterfaceConfigure()
ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

View File

@ -14,7 +14,6 @@
#include "Common/Config/Config.h"
#include "DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"
DualShockUDPClientWidget::DualShockUDPClientWidget()
@ -112,7 +111,6 @@ void DualShockUDPClientWidget::OnServerAdded()
DualShockUDPClientAddServerDialog add_server_dialog(this);
connect(&add_server_dialog, &DualShockUDPClientAddServerDialog::accepted, this,
&DualShockUDPClientWidget::RefreshServerList);
SetQWidgetWindowDecorations(&add_server_dialog);
add_server_dialog.exec();
}

View File

@ -25,7 +25,6 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "UICommon/UICommon.h"
@ -367,7 +366,6 @@ void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, cons
dialog.Reset();
});
SetQWidgetWindowDecorations(dialog.GetRaw());
dialog.GetRaw()->exec();
future.get();
}

View File

@ -19,7 +19,6 @@
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
FreeLookWidget::FreeLookWidget(QWidget* parent) : QWidget(parent)
@ -104,7 +103,6 @@ void FreeLookWidget::OnFreeLookControllerConfigured()
MappingWindow* window = new MappingWindow(this, MappingWindow::Type::MAPPING_FREELOOK, index);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

View File

@ -17,7 +17,7 @@ class GameConfigHighlighter : public QSyntaxHighlighter
public:
explicit GameConfigHighlighter(QTextDocument* parent = nullptr);
~GameConfigHighlighter();
~GameConfigHighlighter() override;
protected:
void highlightBlock(const QString& text) override;

View File

@ -29,7 +29,7 @@ class GameConfigWidget : public QWidget
Q_OBJECT
public:
explicit GameConfigWidget(const UICommon::GameFile& game);
~GameConfigWidget();
~GameConfigWidget() override;
private:
void CreateWidgets();

View File

@ -24,7 +24,6 @@
#include "DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@ -140,7 +139,6 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index)
case SerialInterface::SIDEVICE_WIIU_ADAPTER:
{
GCPadWiiUConfigDialog dialog(static_cast<int>(index), this);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
@ -166,7 +164,6 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index)
MappingWindow* window = new MappingWindow(this, type, static_cast<int>(index));
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

Some files were not shown because too many files have changed in this diff Show More