diff --git a/common/video/wgl_context.cpp b/common/video/wgl_context.cpp index 62a11cb0..46717e39 100644 --- a/common/video/wgl_context.cpp +++ b/common/video/wgl_context.cpp @@ -25,8 +25,7 @@ WGLContext::~WGLContext() void WGLContext::deinit() { - if (wglMakeCurrent) - wglMakeCurrent(nullptr, nullptr); + wglMakeCurrent(nullptr, nullptr); if (hglrc) wglDeleteContext(hglrc); if (hdc) diff --git a/common/video/wgl_context.hpp b/common/video/wgl_context.hpp index d139aca5..22fcd527 100644 --- a/common/video/wgl_context.hpp +++ b/common/video/wgl_context.hpp @@ -22,7 +22,7 @@ class WGLContext : public OpenGLContext void swap_buffers() override; void swap_interval(int frames) override; void make_current() override; - bool ready(); + bool ready() override; void deinit(); HWND hwnd; diff --git a/external/glslang b/external/glslang index 9c7fd1a3..3ebb72cc 160000 --- a/external/glslang +++ b/external/glslang @@ -1 +1 @@ -Subproject commit 9c7fd1a33e5cecbe465e1cd70170167d5e40d398 +Subproject commit 3ebb72cc7429f0ab8218104dc3687c659c0f364d diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt index c2377ae5..1c453bbd 100644 --- a/qt/CMakeLists.txt +++ b/qt/CMakeLists.txt @@ -76,6 +76,7 @@ add_library(snes9x-core ${SNES9X_CORE_SOURCES}) target_include_directories(snes9x-core PRIVATE ../) target_compile_definitions(snes9x-core PRIVATE ZLIB HAVE_STDINT_H ALLOW_CPU_OVERCLOCK) + find_package(Qt6 REQUIRED COMPONENTS Widgets Gui) find_package(PkgConfig REQUIRED) pkg_check_modules(SDL REQUIRED sdl2) @@ -153,8 +154,10 @@ if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") else() list(APPEND PLATFORM_SOURCES ../common/video/wgl_context.cpp - ../external/glad/src/wgl.c) + ../external/glad/src/wgl.c + src/resources/snes9x_icon.rc) list(APPEND LIBS opengl32) + list(APPEND DEFINES SDL_MAIN_HANDLED) endif() set(QT_UI_FILES @@ -170,6 +173,7 @@ set(QT_UI_FILES set(USE_SANITIZERS CACHE BOOL OFF) set(BUILD_TESTS CACHE BOOL OFF) set(BUILD_TOOLS CACHE BOOL OFF) +set(BUNDLE_SPEEX FORCE BOOL ON) add_subdirectory("../external/cubeb" "cubeb" EXCLUDE_FROM_ALL) list(APPEND LIBS cubeb) list(APPEND INCLUDES "../external/cubeb/include") @@ -255,6 +259,10 @@ list(APPEND SOURCES ../external/imgui/imgui.cpp list(APPEND INCLUDES ../external/imgui) add_executable(snes9x-qt ${QT_GUI_SOURCES} ${SOURCES} ${PLATFORM_SOURCES} src/resources/snes9x.qrc) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") +set_target_properties(snes9x-qt PROPERTIES WIN32_EXECUTABLE True) +endif() target_link_libraries(snes9x-qt snes9x-core ${LIBS}) target_compile_definitions(snes9x-qt PRIVATE ${DEFINES}) target_compile_options(snes9x-qt PRIVATE ${FLAGS}) diff --git a/qt/QtStaticBuildVars.txt b/qt/QtStaticBuildVars.txt new file mode 100644 index 00000000..355b2f25 --- /dev/null +++ b/qt/QtStaticBuildVars.txt @@ -0,0 +1,37 @@ +-DBUILD_SHARED_LIBS=0 +-DCMAKE_BUILD_TYPE=Release +-DCMAKE_INSTALL_PREFIX="C:/Qt" +-DFEATURE_androiddeployqt=0 +-DFEATURE_brotli=0 +-DFEATURE_dbus=0 +-DFEATURE_freetype=0 +-DFEATURE_harfbuzz=0 +-DFEATURE_imageformat_ppm=0 +-DFEATURE_islamiccivilcalendar=0 +-DFEATURE_jalalicalendar=0 +-DFEATURE_lcdnumber=0 +-DFEATURE_movie=0 +-DFEATURE_openssl_linked=0 +-DFEATURE_openssl_runtime=0 +-DFEATURE_optimize_size=1 +-DFEATURE_pdf=0 +-DFEATURE_printsupport=0 +-DFEATURE_shani=0 +-DFEATURE_sql=0 +-DFEATURE_static=1 +-DFEATURE_system_doubleconversion=0 +-DFEATURE_system_freetype=0 +-DFEATURE_system_harfbuzz=0 +-DFEATURE_system_jpeg=0 +-DFEATURE_system_libb2=0 +-DFEATURE_system_png=0 +-DFEATURE_system_proxies=0 +-DFEATURE_system_textmarkdownreader=0 +-DFEATURE_system_zlib=0 +-DFEATURE_testlib=0 +-DFEATURE_textodfwriter=0 +-DFEATURE_vkgen=0 +-DFEATURE_vulkan=0 +-DFEATURE_zstd=0 +-DQT_BUILD_EXAMPLES_BY_DEFAULT=0 +-DQT_BUILD_TESTS_BY_DEFAULT=0 diff --git a/qt/src/BindingPanel.cpp b/qt/src/BindingPanel.cpp index 1a15da41..fd2cc040 100644 --- a/qt/src/BindingPanel.cpp +++ b/qt/src/BindingPanel.cpp @@ -1,4 +1,5 @@ #include "BindingPanel.hpp" +#include "EmuApplication.hpp" #include BindingPanel::BindingPanel(EmuApplication *app) diff --git a/qt/src/BindingPanel.hpp b/qt/src/BindingPanel.hpp index 5718b75f..59ce0b72 100644 --- a/qt/src/BindingPanel.hpp +++ b/qt/src/BindingPanel.hpp @@ -1,8 +1,10 @@ #pragma once -#include -#include + +#include #include -#include "EmuApplication.hpp" +#include "EmuBinding.hpp" + +class EmuApplication; class BindingPanel : public QWidget { diff --git a/qt/src/ControllerPanel.cpp b/qt/src/ControllerPanel.cpp index 98c1c108..301a0a21 100644 --- a/qt/src/ControllerPanel.cpp +++ b/qt/src/ControllerPanel.cpp @@ -1,5 +1,7 @@ #include "ControllerPanel.hpp" #include "SDLInputManager.hpp" +#include "EmuApplication.hpp" +#include "EmuConfig.hpp" #include "SDL_gamecontroller.h" #include #include diff --git a/qt/src/ControllerPanel.hpp b/qt/src/ControllerPanel.hpp index 401e22ff..d2ac3e38 100644 --- a/qt/src/ControllerPanel.hpp +++ b/qt/src/ControllerPanel.hpp @@ -1,9 +1,10 @@ #pragma once #include "ui_ControllerPanel.h" #include "BindingPanel.hpp" -#include "EmuApplication.hpp" #include +class EmuApplication; + class ControllerPanel : public Ui::ControllerPanel, public BindingPanel diff --git a/qt/src/DisplayPanel.cpp b/qt/src/DisplayPanel.cpp index e0449853..f1a203ed 100644 --- a/qt/src/DisplayPanel.cpp +++ b/qt/src/DisplayPanel.cpp @@ -1,4 +1,6 @@ #include "DisplayPanel.hpp" +#include "EmuMainWindow.hpp" +#include "EmuConfig.hpp" #include DisplayPanel::DisplayPanel(EmuApplication *app_) diff --git a/qt/src/EmuApplication.cpp b/qt/src/EmuApplication.cpp index 2f471af0..871ecf10 100644 --- a/qt/src/EmuApplication.cpp +++ b/qt/src/EmuApplication.cpp @@ -1,4 +1,7 @@ #include "EmuApplication.hpp" +#include "EmuMainWindow.hpp" +#include "SDLInputManager.hpp" +#include "Snes9xController.hpp" #include "common/audio/s9x_sound_driver_sdl.hpp" #include "common/audio/s9x_sound_driver_cubeb.hpp" #include @@ -135,13 +138,14 @@ void EmuApplication::startGame() core->screen_output_function = [&](uint16_t *data, int width, int height, int stride_bytes, double frame_rate) { if (window->canvas) { - QMetaObject::invokeMethod(window.get(), "output", Qt::ConnectionType::DirectConnection, - Q_ARG(uint8_t *, (uint8_t *)data), - Q_ARG(int, width), - Q_ARG(int, height), - Q_ARG(QImage::Format, QImage::Format_RGB16), - Q_ARG(int, stride_bytes), - Q_ARG(double, frame_rate)); + window->output((uint8_t *)data, width, height, QImage::Format_RGB16, stride_bytes, frame_rate); + // QMetaObject::invokeMethod(window.get(), "output", Qt::ConnectionType::DirectConnection, + // Q_ARG(uint8_t *, (uint8_t *)data), + // Q_ARG(int, width), + // Q_ARG(int, height), + // Q_ARG(QImage::Format, QImage::Format_RGB16), + // Q_ARG(int, stride_bytes), + // Q_ARG(double, frame_rate)); } }; diff --git a/qt/src/EmuApplication.hpp b/qt/src/EmuApplication.hpp index fe5c990a..4e61c302 100644 --- a/qt/src/EmuApplication.hpp +++ b/qt/src/EmuApplication.hpp @@ -3,11 +3,12 @@ #include #include -#include "EmuMainWindow.hpp" -#include "EmuConfig.hpp" -#include "SDLInputManager.hpp" -#include "Snes9xController.hpp" -#include "common/audio/s9x_sound_driver.hpp" +class EmuMainWindow; +class EmuConfig; +class EmuBinding; +class SDLInputManager; +class Snes9xController; +class S9xSoundDriver; struct EmuThread : public QThread { diff --git a/qt/src/EmuCanvas.cpp b/qt/src/EmuCanvas.cpp index 072f9223..1198ec4b 100644 --- a/qt/src/EmuCanvas.cpp +++ b/qt/src/EmuCanvas.cpp @@ -1,4 +1,5 @@ #include "EmuCanvas.hpp" +#include "EmuConfig.hpp" #include #include diff --git a/qt/src/EmuCanvas.hpp b/qt/src/EmuCanvas.hpp index 62e1e6a6..e609b67e 100644 --- a/qt/src/EmuCanvas.hpp +++ b/qt/src/EmuCanvas.hpp @@ -1,9 +1,10 @@ #pragma once #include #include -#include "EmuConfig.hpp" #include "../../vulkan/std_chrono_throttle.hpp" +class EmuConfig; + class EmuCanvas : public QWidget { public: @@ -33,7 +34,7 @@ class EmuCanvas : public QWidget struct Parameter { - bool operator==(const Parameter &other) + bool operator==(const Parameter &other) const { if (name == other.name && id == other.id && diff --git a/qt/src/EmuCanvasOpenGL.cpp b/qt/src/EmuCanvasOpenGL.cpp index f9e658e7..63e99ff1 100644 --- a/qt/src/EmuCanvasOpenGL.cpp +++ b/qt/src/EmuCanvasOpenGL.cpp @@ -17,6 +17,7 @@ using namespace QNativeInterface; #include "EmuMainWindow.hpp" #include "snes9x_imgui.h" #include "imgui_impl_opengl3.h" +#include static const char *stock_vertex_shader_140 = R"( #version 140 diff --git a/qt/src/EmuCanvasQt.cpp b/qt/src/EmuCanvasQt.cpp index 4f0ef70c..ba51d305 100644 --- a/qt/src/EmuCanvasQt.cpp +++ b/qt/src/EmuCanvasQt.cpp @@ -1,6 +1,10 @@ #include "EmuCanvasQt.hpp" +#include "EmuConfig.hpp" + #include #include +#include +#include EmuCanvasQt::EmuCanvasQt(EmuConfig *config, QWidget *parent, QWidget *main_window) : EmuCanvas(config, parent, main_window) @@ -19,8 +23,11 @@ void EmuCanvasQt::deinit() void EmuCanvasQt::draw() { - QWidget::repaint(0, 0, width(), height()); + qimage_mutex.lock(); + qimage = QImage((const uchar *)output_data.buffer, output_data.width, output_data.height, output_data.bytes_per_line, output_data.format); + qimage_mutex.unlock(); throttle(); + update(); } void EmuCanvasQt::paintEvent(QPaintEvent *event) @@ -34,7 +41,6 @@ void EmuCanvasQt::paintEvent(QPaintEvent *event) } QPainter paint(this); - QImage image((const uchar *)output_data.buffer, output_data.width, output_data.height, output_data.bytes_per_line, output_data.format); paint.setRenderHint(QPainter::SmoothPixmapTransform, config->bilinear_filter); QRect dest = { 0, 0, width(), height() }; if (config->maintain_aspect_ratio) @@ -43,7 +49,9 @@ void EmuCanvasQt::paintEvent(QPaintEvent *event) dest = applyAspect(dest); } - paint.drawImage(dest, image, QRect(0, 0, output_data.width, output_data.height)); + qimage_mutex.lock(); + paint.drawImage(dest, qimage, QRect(0, 0, output_data.width, output_data.height)); + qimage_mutex.unlock(); } void EmuCanvasQt::resizeEvent(QResizeEvent *event) diff --git a/qt/src/EmuCanvasQt.hpp b/qt/src/EmuCanvasQt.hpp index b754daf4..5638d83d 100644 --- a/qt/src/EmuCanvasQt.hpp +++ b/qt/src/EmuCanvasQt.hpp @@ -4,6 +4,7 @@ #include "EmuCanvas.hpp" #include +#include class EmuCanvasQt : public EmuCanvas { @@ -16,6 +17,9 @@ class EmuCanvasQt : public EmuCanvas void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; + + std::mutex qimage_mutex; + QImage qimage; }; #endif \ No newline at end of file diff --git a/qt/src/EmuCanvasVulkan.cpp b/qt/src/EmuCanvasVulkan.cpp index e957a8f9..566d4ac3 100644 --- a/qt/src/EmuCanvasVulkan.cpp +++ b/qt/src/EmuCanvasVulkan.cpp @@ -185,7 +185,9 @@ void EmuCanvasVulkan::draw() throttle(); context->swapchain->swap(); if (config->reduce_input_lag) + { context->wait_idle(); + } } } diff --git a/qt/src/EmuCanvasVulkan.hpp b/qt/src/EmuCanvasVulkan.hpp index 4c3c814e..0a2140b8 100644 --- a/qt/src/EmuCanvasVulkan.hpp +++ b/qt/src/EmuCanvasVulkan.hpp @@ -16,7 +16,7 @@ class EmuCanvasVulkan : public EmuCanvas EmuCanvasVulkan(EmuConfig *config, QWidget *parent, QWidget *main_window); ~EmuCanvasVulkan(); - void createContext(); + void createContext() override; void deinit() override; void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; @@ -30,7 +30,7 @@ class EmuCanvasVulkan : public EmuCanvas void draw() override; bool initImGui(); - void recreateUIAssets(); + void recreateUIAssets() override; vk::UniqueRenderPass imgui_render_pass; vk::UniqueDescriptorPool imgui_descriptor_pool; diff --git a/qt/src/EmuConfig.hpp b/qt/src/EmuConfig.hpp index ccba7633..03570916 100644 --- a/qt/src/EmuConfig.hpp +++ b/qt/src/EmuConfig.hpp @@ -2,6 +2,8 @@ #define __EMU_CONFIG_HPP #include +#include + #include "EmuBinding.hpp" struct EmuConfig diff --git a/qt/src/EmuMainWindow.cpp b/qt/src/EmuMainWindow.cpp index 7a0def5d..4532107c 100644 --- a/qt/src/EmuMainWindow.cpp +++ b/qt/src/EmuMainWindow.cpp @@ -13,6 +13,7 @@ #include "EmuMainWindow.hpp" #include "EmuSettingsWindow.hpp" #include "EmuApplication.hpp" +#include "EmuBinding.hpp" #include "EmuCanvasVulkan.hpp" #include "EmuCanvasOpenGL.hpp" #include "EmuCanvasQt.hpp" @@ -464,10 +465,13 @@ bool EmuMainWindow::event(QEvent *event) switch (event->type()) { case QEvent::Close: + app->suspendThread(); if (isFullScreen()) { toggleFullscreen(); } + QGuiApplication::processEvents(); + QGuiApplication::sync(); app->stopThread(); if (canvas) canvas->deinit(); diff --git a/qt/src/EmuSettingsWindow.cpp b/qt/src/EmuSettingsWindow.cpp index 69c6c969..67fd4bd8 100644 --- a/qt/src/EmuSettingsWindow.cpp +++ b/qt/src/EmuSettingsWindow.cpp @@ -1,10 +1,11 @@ #include "EmuSettingsWindow.hpp" -#include "src/EmuMainWindow.hpp" +#include "EmuMainWindow.hpp" +#include "EmuConfig.hpp" #include -EmuSettingsWindow::EmuSettingsWindow(QWidget *parent, EmuApplication *app) - : QDialog(parent), app(app) +EmuSettingsWindow::EmuSettingsWindow(QWidget *parent, EmuApplication *app_) + : QDialog(parent), app(app_) { setupUi(this); @@ -35,13 +36,19 @@ EmuSettingsWindow::EmuSettingsWindow(QWidget *parent, EmuApplication *app) stackedWidget->setCurrentIndex(0); - closeButton->connect(closeButton, &QPushButton::clicked, [&](bool) { + connect(closeButton, &QPushButton::clicked, [&](bool) { this->close(); }); - panelList->connect(panelList, &QListWidget::currentItemChanged, [&](QListWidgetItem *prev, QListWidgetItem *cur) { + connect(panelList, &QListWidget::currentItemChanged, [&](QListWidgetItem *prev, QListWidgetItem *cur) { stackedWidget->setCurrentIndex(panelList->currentRow()); }); + + connect(defaultsButton, &QPushButton::clicked, [&](bool) { + app->config->setDefaults(stackedWidget->currentIndex()); + stackedWidget->currentWidget()->hide(); + stackedWidget->currentWidget()->show(); + }); } EmuSettingsWindow::~EmuSettingsWindow() diff --git a/qt/src/EmulationPanel.cpp b/qt/src/EmulationPanel.cpp index 1cf4e4b1..91363bb3 100644 --- a/qt/src/EmulationPanel.cpp +++ b/qt/src/EmulationPanel.cpp @@ -1,4 +1,7 @@ #include "EmulationPanel.hpp" +#include "EmuApplication.hpp" +#include "EmuConfig.hpp" + EmulationPanel::EmulationPanel(EmuApplication *app_) : app(app_) { diff --git a/qt/src/EmulationPanel.hpp b/qt/src/EmulationPanel.hpp index 2286e7cd..ad4721dd 100644 --- a/qt/src/EmulationPanel.hpp +++ b/qt/src/EmulationPanel.hpp @@ -1,6 +1,7 @@ #pragma once #include "ui_EmulationPanel.h" -#include "EmuApplication.hpp" + +class EmuApplication; class EmulationPanel : public Ui::EmulationPanel, diff --git a/qt/src/FoldersPanel.cpp b/qt/src/FoldersPanel.cpp index 0ef79023..1bb092ac 100644 --- a/qt/src/FoldersPanel.cpp +++ b/qt/src/FoldersPanel.cpp @@ -1,4 +1,6 @@ #include "FoldersPanel.hpp" +#include "EmuBinding.hpp" +#include "EmuConfig.hpp" #include #include diff --git a/qt/src/GeneralPanel.cpp b/qt/src/GeneralPanel.cpp index 49899b70..384b6700 100644 --- a/qt/src/GeneralPanel.cpp +++ b/qt/src/GeneralPanel.cpp @@ -1,4 +1,6 @@ #include "GeneralPanel.hpp" +#include "EmuApplication.hpp" +#include "EmuConfig.hpp" GeneralPanel::GeneralPanel(EmuApplication *app_) : app(app_) diff --git a/qt/src/ShaderParametersDialog.cpp b/qt/src/ShaderParametersDialog.cpp index de9128f1..830d056b 100644 --- a/qt/src/ShaderParametersDialog.cpp +++ b/qt/src/ShaderParametersDialog.cpp @@ -145,9 +145,10 @@ void ShaderParametersDialog::save() saved_parameters = *parameters; - auto filename = config->findConfigDir() + "/customized_shader" + extension; - canvas->saveParameters(filename); - config->shader = filename; + QDir dir(config->findConfigDir().c_str()); + auto filename = dir.absoluteFilePath(QString::fromStdString("customized_shader" + extension)); + canvas->saveParameters(filename.toStdString()); + config->shader = QDir::toNativeSeparators(filename).toStdString(); } void ShaderParametersDialog::saveAs() @@ -155,7 +156,7 @@ void ShaderParametersDialog::saveAs() auto folder = config->last_shader_folder; auto filename = QFileDialog::getSaveFileName(this, tr("Save Shader Preset As"), folder.c_str()); canvas->saveParameters(filename.toStdString()); - config->shader = filename.toStdString(); + config->shader = QDir::toNativeSeparators(filename).toStdString(); } void ShaderParametersDialog::refreshWidgets() diff --git a/qt/src/SoundPanel.cpp b/qt/src/SoundPanel.cpp index 9c147a71..74955122 100644 --- a/qt/src/SoundPanel.cpp +++ b/qt/src/SoundPanel.cpp @@ -1,4 +1,6 @@ #include "SoundPanel.hpp" +#include "EmuApplication.hpp" +#include "EmuConfig.hpp" static const int playback_rates[] = { 96000, 48000, 44100 }; diff --git a/qt/src/main.cpp b/qt/src/main.cpp index 00fa71a5..7ee6acf6 100644 --- a/qt/src/main.cpp +++ b/qt/src/main.cpp @@ -1,11 +1,25 @@ #include "EmuApplication.hpp" +#include "EmuConfig.hpp" +#include "EmuMainWindow.hpp" +#include "SDLInputManager.hpp" + +#include +#include +#include #ifndef _WIN32 #include #endif +#ifdef _WIN32 +int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, const char *lpCmdLine, int nShowCmd) +{ + char **argv = nullptr; + int argc = 0; +#else int main(int argc, char *argv[]) { +#endif EmuApplication emu; emu.qtapp = std::make_unique(argc, argv); diff --git a/qt/src/resources/snes9x.ico b/qt/src/resources/snes9x.ico new file mode 100644 index 00000000..04f78c14 Binary files /dev/null and b/qt/src/resources/snes9x.ico differ diff --git a/qt/src/resources/snes9x_icon.rc b/qt/src/resources/snes9x_icon.rc new file mode 100644 index 00000000..dce3d274 --- /dev/null +++ b/qt/src/resources/snes9x_icon.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON "snes9x.ico" diff --git a/vulkan/std_chrono_throttle.cpp b/vulkan/std_chrono_throttle.cpp index c83af954..e6eb1ec1 100644 --- a/vulkan/std_chrono_throttle.cpp +++ b/vulkan/std_chrono_throttle.cpp @@ -22,25 +22,50 @@ microseconds Throttle::remaining() #include void Throttle::wait_for_frame() { - static HANDLE timer = nullptr; + static UINT (WINAPI *NtDelayExecution)(BOOL, LARGE_INTEGER *) = nullptr; + static UINT (WINAPI *NtQueryTimerResolution) (ULONG *, ULONG *, ULONG *) = nullptr; + static UINT (WINAPI *NtSetTimerResolution) (ULONG, BOOL, ULONG *) = nullptr; + static int timer_resolution = 12500; - if (timer == nullptr) - timer = CreateWaitableTimer(nullptr, true, nullptr); + if (NtDelayExecution == nullptr) + { + HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + + if (ntdll) + { + NtDelayExecution = reinterpret_cast(GetProcAddress(ntdll, "NtDelayExecution")); + NtQueryTimerResolution = reinterpret_cast(GetProcAddress(ntdll, "NtQueryTimerResolution")); + NtSetTimerResolution = reinterpret_cast(GetProcAddress(ntdll, "NtSetTimerResolution")); + } + + if (NtQueryTimerResolution) + { + ULONG min, max, current; + NtQueryTimerResolution(&min, &max, ¤t); + + if (NtSetTimerResolution) + NtSetTimerResolution(max, true, ¤t); + + timer_resolution = current * 5 / 4; + } + } auto time_to_wait = remaining(); - if (time_to_wait < -frame_duration_us) + if (time_to_wait < -(frame_duration_us / 8)) { reset(); return; } - if (time_to_wait.count() > 2000) + if (NtDelayExecution) { - LARGE_INTEGER li; - li.QuadPart = -(time_to_wait.count() - 2000) * 10; - SetWaitableTimer(timer, &li, 0, nullptr, nullptr, false); - WaitForSingleObject(timer, INFINITE); + if (time_to_wait.count() * 10 > timer_resolution) + { + LARGE_INTEGER li; + li.QuadPart = -(time_to_wait.count() * 10 - timer_resolution); + NtDelayExecution(false, &li); + } } time_to_wait = remaining(); @@ -64,7 +89,7 @@ void Throttle::wait_for_frame() } if (time_to_wait.count() > 1000) - std::this_thread::sleep_for(time_to_wait - 1ms); + std::this_thread::sleep_for(time_to_wait - 1000us); time_to_wait = remaining(); while (time_to_wait.count() > 0)