sa2: add some logic to implement Full Speed.
Because we run a frame at a time, this is a bit different than in AppleWin. Run up to 5 extra frames. Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
parent
96e3f37b76
commit
db2f9be009
4 changed files with 58 additions and 13 deletions
|
@ -19,12 +19,17 @@ namespace common2
|
|||
myStartCycles = g_nCumulativeCycles;
|
||||
}
|
||||
|
||||
uint64_t Speed::getCyclesAtFixedSpeed(const size_t microseconds) const
|
||||
{
|
||||
const uint64_t cycles = static_cast<uint64_t>(microseconds * g_fCurrentCLK6502 * 1.0e-6);
|
||||
return cycles;
|
||||
}
|
||||
|
||||
uint64_t Speed::getCyclesTillNext(const size_t microseconds) const
|
||||
{
|
||||
if (myFixedSpeed)
|
||||
{
|
||||
const uint64_t cycles = static_cast<uint64_t>(microseconds * g_fCurrentCLK6502 * 1.0e-6);
|
||||
return cycles;
|
||||
return getCyclesAtFixedSpeed(microseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace common2
|
|||
// calculate the number of cycles to execute in the current period
|
||||
// assuming the next call will happen in x microseconds
|
||||
uint64_t getCyclesTillNext(const size_t microseconds) const;
|
||||
uint64_t getCyclesAtFixedSpeed(const size_t microseconds) const;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -32,6 +32,11 @@
|
|||
namespace
|
||||
{
|
||||
|
||||
bool canDoFullSpeed()
|
||||
{
|
||||
return GetCardMgr().GetDisk2CardMgr().IsConditionForFullSpeed() && !Spkr_IsActive() && !MB_IsActive();
|
||||
}
|
||||
|
||||
void processAppleKey(const SDL_KeyboardEvent & key, const bool forceCapsLock)
|
||||
{
|
||||
// using keycode (or scan code) one takes a physical view of the keyboard
|
||||
|
@ -493,7 +498,7 @@ namespace sa2
|
|||
|
||||
void SDLFrame::Execute(const DWORD cyclesToExecute)
|
||||
{
|
||||
const bool bVideoUpdate = true;
|
||||
const bool bVideoUpdate = !g_bFullSpeed;
|
||||
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
|
||||
|
||||
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
|
||||
|
@ -504,28 +509,59 @@ namespace sa2
|
|||
SpkrUpdate(executedCycles);
|
||||
}
|
||||
|
||||
void SDLFrame::ExecuteInRunningMode(const size_t msNextFrame)
|
||||
{
|
||||
// 1 frame at normal speed
|
||||
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(msNextFrame * 1000);
|
||||
Execute(cyclesToExecute);
|
||||
|
||||
// up to 5x more as maximum speed
|
||||
const int maximumFrames = 5;
|
||||
|
||||
const uint64_t cyclesToExecutePerFrame = mySpeed.getCyclesAtFixedSpeed(msNextFrame * 1000);
|
||||
int count = maximumFrames;
|
||||
while (g_bFullSpeed = (count && canDoFullSpeed()))
|
||||
{
|
||||
Execute(cyclesToExecutePerFrame);
|
||||
--count;
|
||||
}
|
||||
|
||||
if (count < maximumFrames)
|
||||
{
|
||||
// we have run something in full speed
|
||||
// Redraw and Reset
|
||||
VideoRedrawScreenDuringFullSpeed(g_dwCyclesThisFrame);
|
||||
ResetSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
void SDLFrame::ExecuteInDebugMode(const size_t msNextFrame)
|
||||
{
|
||||
// In AppleWin this is called without a timer for just one iteration
|
||||
// because we run a "frame" at a time, we need a bit of ingenuity
|
||||
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(msNextFrame * 1000);
|
||||
const uint64_t target = g_nCumulativeCycles + cyclesToExecute;
|
||||
|
||||
while (g_nAppMode == MODE_STEPPING && g_nCumulativeCycles < target)
|
||||
{
|
||||
DebugContinueStepping();
|
||||
}
|
||||
}
|
||||
|
||||
void SDLFrame::ExecuteOneFrame(const size_t msNextFrame)
|
||||
{
|
||||
// when running in adaptive speed
|
||||
// the value msNextFrame is only a hint for when the next frame will arrive
|
||||
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(msNextFrame * 1000);
|
||||
switch (g_nAppMode)
|
||||
{
|
||||
case MODE_RUNNING:
|
||||
{
|
||||
Execute(cyclesToExecute);
|
||||
ExecuteInRunningMode(msNextFrame);
|
||||
break;
|
||||
}
|
||||
case MODE_STEPPING:
|
||||
{
|
||||
// In AppleWin this is called without a timer for just one iteration
|
||||
// because we run a "frame" at a time, we need a bit of ingenuity
|
||||
const uint64_t target = g_nCumulativeCycles + cyclesToExecute;
|
||||
|
||||
while (g_nAppMode == MODE_STEPPING && g_nCumulativeCycles < target)
|
||||
{
|
||||
DebugContinueStepping();
|
||||
}
|
||||
ExecuteInDebugMode(msNextFrame);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,6 +52,9 @@ namespace sa2
|
|||
void ProcessMouseButton(const SDL_MouseButtonEvent & button);
|
||||
void ProcessMouseMotion(const SDL_MouseMotionEvent & motion);
|
||||
|
||||
void ExecuteInRunningMode(const size_t msNextFrame);
|
||||
void ExecuteInDebugMode(const size_t msNextFrame);
|
||||
|
||||
std::shared_ptr<SDL_Window> myWindow;
|
||||
|
||||
bool myForceCapsLock;
|
||||
|
|
Loading…
Add table
Reference in a new issue