diff --git a/src/86box.c b/src/86box.c index ae58aca03..277d842b4 100644 --- a/src/86box.c +++ b/src/86box.c @@ -217,6 +217,7 @@ int test_mode = 0; /* (C) Test mo char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int sound_muted = 0; /* (C) Is sound muted? */ int inhibit_multimedia_keys; /* (C) Inhibit multimedia keys on Windows. */ +int force_10ms; /* (C) Force 10ms CPU frame intervals. */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are present */ @@ -1592,19 +1593,19 @@ update_mouse_msg(void) *(wcp - 1) = L'\0'; mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i.%%i%%%% - %ls", plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls", (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #else - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", + swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif } @@ -1714,7 +1715,7 @@ pc_run(void) /* Run a block of code. */ startblit(); - cpu_exec((int32_t) cpu_s->rspeed / 100); + cpu_exec((int32_t) cpu_s->rspeed / (force_10ms ? 100 : 1000)); ack_pause(); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ if (gdbstub_step == GDBSTUB_EXEC) { @@ -1729,14 +1730,14 @@ pc_run(void) /* Done with this frame, update statistics. */ framecount++; - if (++framecountx >= 100) { + if (++framecountx >= (force_10ms ? 100 : 1000)) { framecountx = 0; frames = 0; } if (title_update) { mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture; - swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps); + swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); diff --git a/src/config.c b/src/config.c index 272ca43b7..76abbae23 100644 --- a/src/config.c +++ b/src/config.c @@ -144,6 +144,8 @@ load_general(void) video_grayscale = ini_section_get_int(cat, "video_grayscale", 0); video_graytype = ini_section_get_int(cat, "video_graytype", 0); + force_10ms = !!ini_section_get_int(cat, "force_10ms", 0); + rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); @@ -1947,6 +1949,10 @@ save_general(void) const char *va_name; + ini_section_set_int(cat, "force_10ms", force_10ms); + if (force_10ms == 0) + ini_section_delete_var(cat, "force_10ms"); + ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys); if (inhibit_multimedia_keys == 0) ini_section_delete_var(cat, "inhibit_multimedia_keys"); diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index fd6285057..23f3f1e35 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -739,7 +739,7 @@ exec386_dynarec(int32_t cycs) uint64_t oldtsc; uint64_t delta; - int32_t cyc_period = cycs / 2000; /*5us*/ + int32_t cyc_period = cycs / (force_10ms ? 2000 : 200); /*5us*/ # ifdef USE_ACYCS acycs = 0; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index e572d670b..bba99b555 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -154,6 +154,7 @@ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ extern int enable_discord; /* (C) enable Discord integration */ +extern int force_10ms; /* (C) force 10ms CPU frame interval */ extern int other_ide_present; /* IDE controllers from non-IDE cards are present */ extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */ diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index da57bcf80..d02ed6b67 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -437,6 +437,9 @@ main_thread_fn() int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); +#ifdef _WIN32 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); +#endif plat_set_thread_name(nullptr, "main_thread_fn"); framecountx = 0; // title_update = 1; @@ -448,14 +451,14 @@ main_thread_fn() const uint64_t new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; + drawits = force_10ms ? 10 : 1; else #endif drawits += static_cast(new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ - drawits -= 10; + drawits -= force_10ms ? 10 : 1; if (drawits > 50) drawits = 0; @@ -474,8 +477,8 @@ main_thread_fn() break; } #endif - /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { + /* Every 2 emulated seconds we save the machine status. */ + if (++frames >= (force_10ms ? 200 : 2000) && nvr_dosave) { qt_nvr_save(); nvr_dosave = 0; frames = 0; diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index fb5576f69..0063ac727 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -117,6 +117,9 @@ SettingsMachine::SettingsMachine(QWidget *parent) ui->comboBoxMachineType->setCurrentIndex(-1); ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); + ui->radioButtonLargerFrames->setChecked(force_10ms); + ui->radioButtonSmallerFrames->setChecked(!force_10ms); + #ifndef USE_DYNAREC ui->checkBoxDynamicRecompiler->setEnabled(false); ui->checkBoxDynamicRecompiler->setVisible(false); @@ -137,6 +140,7 @@ SettingsMachine::save() fpu_type = ui->comboBoxFPU->currentData().toInt(); cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; fpu_softfloat = ui->checkBoxFPUSoftfloat->isChecked() ? 1 : 0; + force_10ms = ui->radioButtonLargerFrames->isChecked() ? 1 : 0; int64_t temp_mem_size; if (machine_get_ram_granularity(machine) < 1024) @@ -359,3 +363,15 @@ void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { ui->softFloatWarningText->setVisible(false); } } + +void SettingsMachine::on_radioButtonSmallerFrames_clicked() +{ + ui->radioButtonLargerFrames->setChecked(false); +} + + +void SettingsMachine::on_radioButtonLargerFrames_clicked() +{ + ui->radioButtonSmallerFrames->setChecked(false); +} + diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index 864894447..36ece7f18 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -28,6 +28,10 @@ private slots: void on_comboBoxMachineType_currentIndexChanged(int index); void on_checkBoxFPUSoftfloat_stateChanged(int state); + void on_radioButtonSmallerFrames_clicked(); + + void on_radioButtonLargerFrames_clicked(); + private: Ui::SettingsMachine *ui; }; diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index e3b3cdbde..0cd15e749 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -41,7 +41,6 @@ 0 - @@ -49,7 +48,6 @@ - @@ -57,7 +55,6 @@ - @@ -65,7 +62,6 @@ - @@ -73,7 +69,6 @@ - @@ -84,7 +79,6 @@ - @@ -92,7 +86,6 @@ - @@ -100,7 +93,6 @@ - @@ -129,18 +121,16 @@ - Frequency: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - @@ -157,7 +147,6 @@ - @@ -165,7 +154,6 @@ - @@ -173,7 +161,6 @@ - @@ -196,7 +183,6 @@ - @@ -213,7 +199,6 @@ - @@ -268,7 +253,6 @@ - @@ -286,7 +270,6 @@ - @@ -302,7 +285,6 @@ - @@ -310,7 +292,6 @@ - @@ -321,7 +302,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -333,39 +314,102 @@ - - - - - 0 - 0 - - - - Time synchronization - - - - - - Disabled + + + + + + + 0 + 0 + + + Time synchronization + + + + + + Disabled + + + + + + + Enabled (UTC) + + + + + + + Enabled (local time) + + + + - - - - Enabled (local time) + + + + Qt::Orientation::Horizontal + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + CPU frame size + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + + + + + + Larger frames (less smooth) + + + + + + + Smaller frames (smoother) + + + + - - - - Enabled (UTC) + + + + Qt::Orientation::Vertical - + + + 20 + 40 + + + @@ -373,7 +417,7 @@ - Qt::Vertical + Qt::Orientation::Vertical