Skip to content

Commit

Permalink
Emulation speed tuning
Browse files Browse the repository at this point in the history
  • Loading branch information
nzeemin committed Jan 8, 2025
1 parent f9b098d commit 4f21ce4
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 28 deletions.
4 changes: 3 additions & 1 deletion emulator/Emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,11 +613,13 @@ void Emulator_SetSpeed(uint16_t realspeed)
uint16_t speedpercent = 100;
switch (realspeed)
{
case 0: speedpercent = 200; break;
case 0: speedpercent = 500; break;
case 1: speedpercent = 100; break;
case 2: speedpercent = 200; break;
case 3: speedpercent = 400; break;
case 0x7fff: speedpercent = 50; break;
case 0x7ffe: speedpercent = 25; break;
case 0x7ffd: speedpercent = 10; break;
default: speedpercent = 100; break;
}
m_wEmulatorSoundSpeed = speedpercent;
Expand Down
50 changes: 33 additions & 17 deletions emulator/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ BKBTL. If not, see <http://www.gnu.org/licenses/>. */
#include <Vfw.h>
#include <CommCtrl.h>
#include <shellapi.h>
#include <timeapi.h>

#include "Main.h"
#include "Emulator.h"
Expand Down Expand Up @@ -93,6 +94,10 @@ int APIENTRY _tWinMain(
LARGE_INTEGER nPerformanceFrequency;
::QueryPerformanceFrequency(&nPerformanceFrequency);

TIMECAPS caps;
VERIFY(!::timeGetDevCaps(&caps, sizeof(caps)));
VERIFY(!::timeBeginPeriod(caps.wPeriodMin));

// Main message loop
MSG msg;
for (;;)
Expand All @@ -109,6 +114,8 @@ int APIENTRY _tWinMain(
// Turn on degugger if not yet
if (!Settings_GetDebug())
::PostMessage(g_hwnd, WM_COMMAND, ID_VIEW_DEBUG, 0);
else
::FlashWindow(g_hwnd, TRUE);
}

ScreenView_RedrawScreen();
Expand All @@ -129,26 +136,34 @@ int APIENTRY _tWinMain(

if (g_okEmulatorRunning && !Settings_GetSound())
{
if (Settings_GetRealSpeed() == 0)
::Sleep(1); // We should not consume 100% of CPU
WORD speed = Settings_GetRealSpeed();
if (speed == 0)
::Sleep(0); // Speed MAX, consume 100% of one CPU core
else
{
// Slow down to 25 frames per second
LARGE_INTEGER nFrameFinishTime; // Frame start time
::QueryPerformanceCounter(&nFrameFinishTime);
LONGLONG nTimeElapsed = (nFrameFinishTime.QuadPart - nFrameStartTime.QuadPart)
* 1000 / nPerformanceFrequency.QuadPart;
LONGLONG nFrameDelay = 1000 / 25 - 1; // 1000 millisec / 25 = 40 millisec
if (Settings_GetRealSpeed() == 0x7ffe) // Speed 25%
nFrameDelay = 1000 / 25 * 4 - 1;
else if (Settings_GetRealSpeed() == 0x7fff) // Speed 50%
nFrameDelay = 1000 / 25 * 2 - 1;
else if (Settings_GetRealSpeed() == 2) // Speed 200%
nFrameDelay = 1000 / 25 / 2 - 1;
if (nTimeElapsed > 0 && nTimeElapsed < nFrameDelay)
LONGLONG nFrameDelay;
switch (speed)
{
case 0x7ffd: nFrameDelay = 1000ll / FRAMERATE * 10; break; // Speed 10%
case 0x7ffe: nFrameDelay = 1000ll / FRAMERATE * 4; break; // Speed 25%
case 0x7fff: nFrameDelay = 1000ll / FRAMERATE * 2; break; // Speed 50%
case 2: nFrameDelay = 1000ll / FRAMERATE / 2; break; // Speed 200%
case 3: nFrameDelay = 1000ll / FRAMERATE / 4; break; // Speed 400%
default: // Speed 100%
nFrameDelay = 1000ll / FRAMERATE; // 1000 millisec / 50 = 20 millisec
break;
}

for (;;)
{
LONG nTimeToSleep = (LONG)(nFrameDelay - nTimeElapsed);
::Sleep((DWORD)nTimeToSleep);
LARGE_INTEGER nFrameFinishTime; // Frame start time
::QueryPerformanceCounter(&nFrameFinishTime);
LONGLONG nTimeElapsed = (nFrameFinishTime.QuadPart - nFrameStartTime.QuadPart)
* 1000ll / nPerformanceFrequency.QuadPart;
if (nTimeElapsed <= 0 || nTimeElapsed >= nFrameDelay)
break;
LONGLONG nDelayRemaining = nFrameDelay - nTimeElapsed;
::Sleep((DWORD)(nDelayRemaining / 2));
}
}
}
Expand All @@ -159,6 +174,7 @@ int APIENTRY _tWinMain(
}
endprog:

::timeEndPeriod(caps.wPeriodMin);
DoneInstance();

#ifdef _DEBUG
Expand Down
2 changes: 2 additions & 0 deletions emulator/Main.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ BKBTL. If not, see <http://www.gnu.org/licenses/>. */
//////////////////////////////////////////////////////////////////////


#define FRAMERATE 25 // Количество фремов в секунду

#define MAX_LOADSTRING 100

extern TCHAR g_szTitle[MAX_LOADSTRING]; // The title bar text
Expand Down
10 changes: 9 additions & 1 deletion emulator/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,13 +789,15 @@ void MainWindow_UpdateMenu()
UINT speedcmd = 0;
switch (Settings_GetRealSpeed())
{
case 0x7ffd: speedcmd = ID_EMULATOR_SPEED10; break;
case 0x7ffe: speedcmd = ID_EMULATOR_SPEED25; break;
case 0x7fff: speedcmd = ID_EMULATOR_SPEED50; break;
case 0: speedcmd = ID_EMULATOR_SPEEDMAX; break;
case 1: speedcmd = ID_EMULATOR_REALSPEED; break;
case 2: speedcmd = ID_EMULATOR_SPEED200; break;
case 3: speedcmd = ID_EMULATOR_SPEED400; break;
}
CheckMenuRadioItem(hMenu, ID_EMULATOR_SPEED25, ID_EMULATOR_SPEED200, speedcmd, MF_BYCOMMAND);
CheckMenuRadioItem(hMenu, ID_EMULATOR_SPEED10, ID_EMULATOR_SPEED400, speedcmd, MF_BYCOMMAND);

UINT joystickcmd = 0;
switch (Settings_GetJoystick())
Expand Down Expand Up @@ -946,6 +948,9 @@ bool MainWindow_DoCommand(int commandId)
case ID_EMULATOR_SOUNDAY:
MainWindow_DoEmulatorSoundAY();
break;
case ID_EMULATOR_SPEED10:
MainWindow_DoEmulatorSpeed(0x7ffd);
break;
case ID_EMULATOR_SPEED25:
MainWindow_DoEmulatorSpeed(0x7ffe);
break;
Expand All @@ -961,6 +966,9 @@ bool MainWindow_DoCommand(int commandId)
case ID_EMULATOR_SPEED200:
MainWindow_DoEmulatorSpeed(2);
break;
case ID_EMULATOR_SPEED400:
MainWindow_DoEmulatorSpeed(3);
break;
case ID_EMULATOR_JOYSTICKNUMPAD:
MainWindow_DoEmulatorJoystick(0);
break;
Expand Down
2 changes: 2 additions & 0 deletions emulator/res/BKBTL.rc
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,12 @@ BEGIN
MENUITEM "Covox", ID_EMULATOR_COVOX
MENUITEM "AY", ID_EMULATOR_SOUNDAY
MENUITEM SEPARATOR
MENUITEM "Speed 10%", ID_EMULATOR_SPEED10
MENUITEM "Speed 25%", ID_EMULATOR_SPEED25
MENUITEM "Speed 50%", ID_EMULATOR_SPEED50
MENUITEM "Speed 100%", ID_EMULATOR_REALSPEED
MENUITEM "Speed 200%", ID_EMULATOR_SPEED200
MENUITEM "Speed 400%", ID_EMULATOR_SPEED400
MENUITEM "Speed MAX", ID_EMULATOR_SPEEDMAX
MENUITEM SEPARATOR
MENUITEM "NumPad Joystick", ID_EMULATOR_JOYSTICKNUMPAD
Expand Down
20 changes: 11 additions & 9 deletions emulator/res/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,22 @@
#define ID_VIEW_TAPE 32787
#define ID_VIEW_TOOLBAR 32788
#define ID_VIEW_RGBSCREEN 32789
#define ID_EMULATOR 32794
#define ID_EMULATOR_RUN 32795
#define ID_EMULATOR_RESET 32796
#define ID_EMULATOR_AUTOSTART 32797
#define ID_EMULATOR 32793
#define ID_EMULATOR_RUN 32794
#define ID_EMULATOR_RESET 32795
#define ID_EMULATOR_AUTOSTART 32796
#define ID_EMULATOR_SPEED10 32797
#define ID_EMULATOR_SPEED25 32798
#define ID_EMULATOR_SPEED50 32799
#define ID_EMULATOR_SPEEDMAX 32800
#define ID_EMULATOR_REALSPEED 32801
#define ID_EMULATOR_SPEED200 32802
#define ID_EMULATOR_CONF 32803
#define ID_EMULATOR_FLOPPY0 32804
#define ID_EMULATOR_FLOPPY1 32805
#define ID_EMULATOR_FLOPPY2 32806
#define ID_EMULATOR_FLOPPY3 32807
#define ID_EMULATOR_SPEED400 32803
#define ID_EMULATOR_CONF 32804
#define ID_EMULATOR_FLOPPY0 32805
#define ID_EMULATOR_FLOPPY1 32806
#define ID_EMULATOR_FLOPPY2 32807
#define ID_EMULATOR_FLOPPY3 32808
#define ID_CONF_BK0010MONIT 32812
#define ID_CONF_BK0010BASIC 32813
#define ID_CONF_BK0010FOCAL 32814
Expand Down

0 comments on commit 4f21ce4

Please sign in to comment.