Skip to content

Commit

Permalink
Fix sound stutter in Windows/MinGW builds
Browse files Browse the repository at this point in the history
- Using SFML for timers/clocks instead of Boost/C++ stdlib
- Removed Boost as dependency, as it is unused (except for tests)
- Fixed Z80FileTest compilation
- Removed Z80File unused member
  • Loading branch information
MartianGirl committed Jun 30, 2024
1 parent 6b5cb81 commit d29e9ef
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 79 deletions.
1 change: 0 additions & 1 deletion source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU OR
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS} -g -O1 -DDEBUG")
if(WIN32)
add_definitions(-DUSE_BOOST_THREADS)
set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "X86")
endif()
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
Expand Down
5 changes: 0 additions & 5 deletions source/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ if(SPECIDE_MEDIA_LIB MATCHES "SDL2")
find_package(SDL2 REQUIRED)
elseif(WIN32)
find_package(SDL2 REQUIRED)
set(Boost_NO_BOOST_CMAKE TRUE)
endif()
set(MEDIA_LIBRARIES ${SDL2_LIBRARIES})
set(MEDIA_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS})
Expand All @@ -25,17 +24,13 @@ else()
find_package(SFML COMPONENTS audio graphics window system)
elseif(WIN32)
find_package(SFML COMPONENTS audio graphics window system)
set(Boost_NO_BOOST_CMAKE TRUE)
endif()
set(MEDIA_LIBRARIES sfml-audio sfml-graphics sfml-window sfml-system)
set(SpecIde_SDL2 0)
endif()
message("Media libraries found: " ${MEDIA_LIBRARIES})
message("Media include dirs found: " ${MEDIA_INCLUDE_DIRS})

if(USE_BOOST_THREADS)
find_package(Boost COMPONENTS chrono system thread REQUIRED)
endif()
find_package(ZLIB REQUIRED)

include_directories(${Boost_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${MEDIA_INCLUDE_DIRS})
Expand Down
48 changes: 15 additions & 33 deletions source/src/CpcScreen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,10 @@
*/

#include "CpcScreen.h"
#include "config.h"
#include "KeyBinding.h"
#include "config.h"

#ifdef USE_BOOST_THREADS
#include <boost/chrono/include.hpp>
#include <boost/thread.hpp>
using namespace boost::this_thread;
using namespace boost::chrono;
#else
#include <chrono>
#include <thread>
using namespace std::this_thread;
using namespace std::chrono;
#endif
#include <SFML/System.hpp>

#include <cfenv>
#include <cmath>
Expand Down Expand Up @@ -179,12 +169,14 @@ void CpcScreen::loadFiles() {
void CpcScreen::run() {

while (!done) {
high_resolution_clock::time_point start = high_resolution_clock::now();
high_resolution_clock::time_point frame;
high_resolution_clock::time_point wakeup;
Clock clock;
Time frameTime; // Emulated frame time
Time spentTime; // Time spent in emulation
Time delayTime; // Delay time to adjust emulation pace
Time sleepTime; // Time that will be relinquished to the system

while (!done && !menu) {
start = high_resolution_clock::now();
clock.restart();

// Run until either we get a new frame, or we get 20ms of emulation.
pollEvents();
Expand All @@ -197,22 +189,17 @@ void CpcScreen::run() {
update();

if (!syncToVideo) {
uint_fast32_t delay = cpc.cycles / 16;
uint_fast32_t sleep = delay - (delay % SLEEP_STEP);
frameTime = microseconds(cpc.cycles / 16);
spentTime = clock.getElapsedTime();
delayTime = frameTime - spentTime;
sleepTime = delayTime - (delayTime % microseconds(SLEEP_STEP));

// By not sleeping until the next frame is due, we get some
// better adjustment
#ifdef USE_BOOST_THREADS
frame = start + boost::chrono::microseconds(delay);
wakeup = start + boost::chrono::microseconds(sleep);
#else
frame = start + std::chrono::microseconds(delay);
wakeup = start + std::chrono::microseconds(sleep);
#endif
#ifndef DO_NOT_SLEEP
sleep_until(wakeup);
sleep(sleepTime);
#endif
while (high_resolution_clock::now() < frame);
while (clock.getElapsedTime() < frameTime);
} else {
// If we are syncing with the PC's vertical refresh, we need
// to get at least 20ms of emulation. If this is the case, we
Expand All @@ -226,12 +213,7 @@ void CpcScreen::run() {
while (!done && menu) {
// Menu thingy
updateMenu();

#ifdef USE_BOOST_THREADS
sleep_for(boost::chrono::microseconds(20000));
#else
sleep_for(std::chrono::microseconds(20000));
#endif
sleep(microseconds(20000));
}
}
}
Expand Down
15 changes: 10 additions & 5 deletions source/src/FDC765.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ void FDC765::clock() {
setup();
} else if (cmdIndex > cmdBytes) {
reset();
#ifdef DEBUGFDC765
} else {
cout << "Command byte " << static_cast<uint32_t>(cmdIndex) << ": "
<< cmdBuffer[cmdIndex] << endl;
#endif
}
}
break;
Expand Down Expand Up @@ -163,7 +168,7 @@ void FDC765::checkCommand() {

case 0x06: // Read sector(s)
#ifdef DEBUGFDC765
cout << "Read sector." << endl;
cout << "Read sector" << endl;
#endif
cmdBytes = 9; // 06+MT+MF+SK HU TR HD SC SZ LS GP SL
resBytes = 7; // S0 S1 S2 TR HD LS SZ
Expand Down Expand Up @@ -208,7 +213,7 @@ void FDC765::checkCommand() {

case 0x0C: // Read deleted sector(s)
#ifdef DEBUGFDC765
cout << "Read deleted." << endl;
cout << "Read deleted" << endl;
#endif
cmdBytes = 9; // 0C+MT+MF+SK HU TR HD SC SZ LS GP SL
resBytes = 7; // S0 S1 S2 TR HD LS SZ
Expand Down Expand Up @@ -244,7 +249,7 @@ void FDC765::checkCommand() {

case 0x11: // Scan equal
#ifdef DEBUGFDC765
cout << "Scan equal." << endl;
cout << "Scan equal" << endl;
#endif
cmdBytes = 9; // 11+MT+MF+SK HU TR HD SC SZ LS GP SL
resBytes = 7; // S0 S1 S2 TR HD LS SZ
Expand All @@ -253,7 +258,7 @@ void FDC765::checkCommand() {

case 0x19: // Scan low or equal
#ifdef DEBUGFDC765
cout << "Scan low or equal." << endl;
cout << "Scan low or equal" << endl;
#endif
cmdBytes = 9; // 19+MT+MF+SK HU TR HD SC SZ LS GP SL
resBytes = 7; // S0 S1 S2 TR HD LS SZ
Expand All @@ -262,7 +267,7 @@ void FDC765::checkCommand() {

case 0x1D: // Scan high or equal
#ifdef DEBUGFDC765
cout << "Scan high or equal." << endl;
cout << "Scan high or equal" << endl;
#endif
cmdBytes = 9; // 1D+MT+MF+SK HU TR HD SC SZ LS GP SL
resBytes = 7; // S0 S1 S2 TR HD LS SZ
Expand Down
43 changes: 13 additions & 30 deletions source/src/SpeccyScreen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,7 @@
#include "SNAFile.h"
#include "Z80File.h"

#ifdef USE_BOOST_THREADS
#include <boost/chrono/include.hpp>
#include <boost/thread.hpp>
using namespace boost::this_thread;
using namespace boost::chrono;
#else
#include <chrono>
#include <thread>
using namespace std::this_thread;
using namespace std::chrono;
#endif
#include <SFML/System.hpp>

#include <cfenv>
#include <cmath>
Expand Down Expand Up @@ -287,12 +277,14 @@ void SpeccyScreen::loadFiles() {
void SpeccyScreen::run() {

while (!done) {
high_resolution_clock::time_point start = high_resolution_clock::now();
high_resolution_clock::time_point frame;
high_resolution_clock::time_point wakeup;
Clock clock;
Time frameTime = microseconds(spectrum.frame);
Time spentTime; // Time elapsed in emulating a frame
Time delayTime; // Delay time to adjust emulation pace
Time sleepTime; // Time that will be relinquished to the system

while (!done && !menu) {
start = high_resolution_clock::now();
clock.restart();

// Run a complete frame.
pollEvents();
Expand All @@ -301,7 +293,6 @@ void SpeccyScreen::run() {
spectrum.playSound(true);
}


// Update the screen.
// These conditions cannot happen at the same time:
// - HSYNC and VSYNC only happen during the blanking interval.
Expand All @@ -313,17 +304,13 @@ void SpeccyScreen::run() {
if (!syncToVideo) {
// By not sleeping until the next frame is due, we get some
// better adjustment
#ifdef USE_BOOST_THREADS
frame = start + boost::chrono::microseconds(spectrum.frame);
wakeup = start + boost::chrono::microseconds(20000 - SLEEP_STEP);
#else
frame = start + std::chrono::microseconds(spectrum.frame);
wakeup = start + std::chrono::microseconds(20000 - SLEEP_STEP);
#endif
spentTime = clock.getElapsedTime();
delayTime = frameTime - spentTime;
sleepTime = delayTime - (delayTime % microseconds(SLEEP_STEP));
#ifndef DO_NOT_SLEEP
sleep_until(wakeup);
sleep(sleepTime);
#endif
while (high_resolution_clock::now() < frame);
while (clock.getElapsedTime() < frameTime);
}
}

Expand All @@ -335,11 +322,7 @@ void SpeccyScreen::run() {
updateMenu();

if (!syncToVideo) {
#ifdef USE_BOOST_THREADS
sleep_for(boost::chrono::microseconds(20000));
#else
sleep_for(std::chrono::microseconds(20000));
#endif
sleep(microseconds(20000));
}
}
}
Expand Down
1 change: 0 additions & 1 deletion source/src/Z80File.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class Z80File {

std::string name;
uint32_t dataIndex = 0;
bool valid = false;

std::vector<uint8_t> fileData;
SaveState state;
Expand Down
2 changes: 1 addition & 1 deletion source/tst/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if(WIN32)
set(Boost_NO_BOOST_CMAKE TRUE)
endif()

find_package(Boost COMPONENTS thread unit_test_framework REQUIRED)
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
find_package(ZLIB REQUIRED)

# This is for all platforms
Expand Down
3 changes: 0 additions & 3 deletions source/tst/Z80FileTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ BOOST_AUTO_TEST_CASE(v1_header_test)
file.fileData.push_back(0x00);

BOOST_CHECK_EQUAL(file.checkVersion(), true);
BOOST_CHECK_EQUAL(file.version, 1);

BOOST_CHECK_EQUAL(file.parseHeader(), true);
}

Expand All @@ -77,7 +75,6 @@ BOOST_AUTO_TEST_CASE(file_reporter)
Z80File file;
file.load(boost::unit_test::framework::master_test_suite().argv[1]);
file.checkVersion();
cout << "File version: " << static_cast<uint32_t>(file.version) << endl;
file.parseHeader();
cout << hex;
cout << "AF: " << setfill('0') << setw(4) << file.state.af
Expand Down

0 comments on commit d29e9ef

Please sign in to comment.