Turbo/throttle config and DirectSound fixes.

Make `speedup_frame_skip` and `speedup_throttle` independent settings,
with `speedup_frame_skip == 0` when `speedup_throttle` is not in effect,
and `speedup_throttle == 100` when `speedup_frame_skip` is in effect.

This fixes a previously introduced bug where `speedup == true &&
speedup_frame_skip = X` was never enabled.

This also allows `speedup_throttle == 0` for no throttle and no frame
skip during speedup.

Also set the upper bound on `throttle` and `speedup_throttle` to `450`
instead of `600`, as the DirectSound driver does not support values
higher than that.

In the DirectSound implementation of `setThrottle`, for `throttle == 0`
use a `throttle == 450` frequency multiplier, because a zero frequency
does nothing.

- Fix #719.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2020-08-21 08:19:29 +00:00
parent 5114c1dc87
commit c169420fbc
7 changed files with 56 additions and 72 deletions

View File

@ -257,9 +257,9 @@ uint32_t autoFrameSkipLastTime;
uint32_t movieLastJoypad;
uint32_t movieNextJoypad;
uint32_t throttle = 100;
uint32_t speedup_throttle = 0;
uint32_t speedup_throttle = 100;
uint32_t speedup_frame_skip = 9;
bool speedup_throttle_frame_skip = true;
bool speedup_throttle_frame_skip = false;
const char* preparedCheatCodes[MAX_CHEATS];
@ -557,9 +557,9 @@ void LoadConfig()
soundRecordDir = ReadPrefString("soundRecordDir");
threadPriority = ReadPref("priority", 2);
throttle = ReadPref("throttle", 100);
speedup_throttle = ReadPref("speedupThrottle", 0);
speedup_throttle = ReadPref("speedupThrottle", 100);
speedup_frame_skip = ReadPref("speedupFrameSkip", 9);
speedup_throttle_frame_skip = ReadPref("speedupThrottleFrameSkip", 1);
speedup_throttle_frame_skip = ReadPref("speedupThrottleFrameSkip", 0);
tripleBuffering = ReadPref("tripleBuffering", 0);
useBios = ReadPrefHex("useBiosGBA");
useBiosFileGB = ReadPref("useBiosGB", 0);

View File

@ -4951,26 +4951,21 @@ void gbEmulate(int ticksToStop)
static uint32_t last_throttle;
if (turbo_button_pressed) {
if (!speedup_throttle_set && throttle != speedup_throttle) {
last_throttle = throttle;
soundSetThrottle(speedup_throttle);
speedup_throttle_set = true;
}
if (speedup_throttle_set) {
if (speedup_throttle_frame_skip) {
if (speedup_throttle == 0)
framesToSkip += speedup_frame_skip;
else if (speedup_throttle > 100)
framesToSkip += std::ceil(double(speedup_throttle) / 100.0) - 1;
}
}
else
if (speedup_frame_skip)
framesToSkip = speedup_frame_skip;
else {
if (!speedup_throttle_set && throttle != speedup_throttle) {
last_throttle = throttle;
soundSetThrottle(speedup_throttle);
speedup_throttle_set = true;
}
if (speedup_throttle_frame_skip)
framesToSkip += std::ceil(double(speedup_throttle) / 100.0) - 1;
}
}
else if (speedup_throttle_set) {
soundSetThrottle(last_throttle);
speedup_throttle_set = false;
}
#else

View File

@ -3798,26 +3798,21 @@ void CPULoop(int ticks)
static uint32_t last_throttle;
if (turbo_button_pressed) {
if (!speedup_throttle_set && throttle != speedup_throttle) {
last_throttle = throttle;
soundSetThrottle(speedup_throttle);
speedup_throttle_set = true;
}
if (speedup_throttle_set) {
if (speedup_throttle_frame_skip) {
if (speedup_throttle == 0)
framesToSkip += speedup_frame_skip;
else if (speedup_throttle > 100)
framesToSkip += std::ceil(double(speedup_throttle) / 100.0) - 1;
}
}
else
if (speedup_frame_skip)
framesToSkip = speedup_frame_skip;
else {
if (!speedup_throttle_set && throttle != speedup_throttle) {
last_throttle = throttle;
soundSetThrottle(speedup_throttle);
speedup_throttle_set = true;
}
if (speedup_throttle_frame_skip)
framesToSkip += std::ceil(double(speedup_throttle) / 100.0) - 1;
}
}
else if (speedup_throttle_set) {
soundSetThrottle(last_throttle);
speedup_throttle_set = false;
}
#else

View File

@ -194,8 +194,8 @@ bool DirectSound::init(long sampleRate)
void DirectSound::setThrottle(unsigned short throttle_) {
HRESULT hr;
if (!throttle_)
throttle_ = 100;
if (throttle_ == 0)
throttle_ = 450; // Close to upper bound on frequency.
long freq = soundGetSampleRate();

View File

@ -2333,7 +2333,7 @@ public:
void DoSetThrottleSel(uint32_t val)
{
if (val <= 600)
if (val <= 450)
thrsel->SetSelection(std::round((double)val / 25));
else
thrsel->SetSelection(100 / 25);
@ -2345,7 +2345,7 @@ public:
(void)evt; // unused params
uint32_t val = thrsel->GetSelection() * 25;
if (val <= 600)
if (val <= 450)
thr->SetValue(val);
else
thr->SetValue(100);
@ -2374,24 +2374,26 @@ public:
evt.Skip(false);
if (val == 0) {
speedup_throttle = 0;
speedup_frame_skip = 0;
speedup_throttle = 0;
speedup_frame_skip = 0;
speedup_throttle_frame_skip = false;
frame_skip_cb->SetValue(false);
frame_skip_cb->Disable();
if (evt.GetEventType() == wxEVT_TEXT)
return; // Do not update value if user cleared text box.
}
else if (val <= 600) {
speedup_throttle = val;
else if (val <= 450) {
speedup_throttle = val;
speedup_frame_skip = 0;
frame_skip_cb->SetValue(prev_frame_skip_cb);
frame_skip_cb->Enable();
}
else { // val > 600
speedup_throttle = 0;
else { // val > 450
speedup_throttle = 100;
speedup_throttle_frame_skip = false;
unsigned rounded = std::round((double)val / 100) * 100;
@ -2405,7 +2407,6 @@ public:
else if ((int)(val - rounded) < 0)
speedup_frame_skip--;
speedup_throttle_frame_skip = true;
frame_skip_cb->SetValue(true);
frame_skip_cb->Disable();
@ -2426,26 +2427,25 @@ public:
void Init(wxShowEvent& ev)
{
uint32_t val = 0;
if (speedup_throttle != 0)
val = speedup_throttle;
else if (speedup_frame_skip != 0)
val = (speedup_frame_skip + 1) * 100;
speedup_throttle_spin->SetValue(val);
frame_skip_cb->SetValue(speedup_throttle_frame_skip);
prev_frame_skip_cb = frame_skip_cb->GetValue();
if (val > 600 || val == 0)
if (speedup_frame_skip != 0) {
speedup_throttle_spin->SetValue((speedup_frame_skip + 1) * 100);
frame_skip_cb->SetValue(true);
frame_skip_cb->Disable();
}
else {
speedup_throttle_spin->SetValue(speedup_throttle);
frame_skip_cb->SetValue(speedup_throttle_frame_skip);
if (speedup_throttle != 0)
frame_skip_cb->Enable();
else
frame_skip_cb->Disable();
}
ev.Skip();
}
private:
bool prev_frame_skip_cb = true;
bool prev_frame_skip_cb = speedup_throttle_frame_skip;
} speedup_throttle_ctrl;
/////////////////////////////

View File

@ -290,9 +290,9 @@ opt_desc opts[] = {
INTOPT("preferences/skipBios", "SkipIntro", wxTRANSLATE("Skip BIOS initialization"), skipBios, 0, 1),
INTOPT("preferences/skipSaveGameCheats", "", wxTRANSLATE("Do not overwrite cheat list when loading state"), skipSaveGameCheats, 0, 1),
INTOPT("preferences/skipSaveGameBattery", "", wxTRANSLATE("Do not overwrite native (battery) save when loading state"), skipSaveGameBattery, 0, 1),
UINTOPT("preferences/throttle", "", wxTRANSLATE("Throttle game speed, even when accelerated (0-600%, 0 = no throttle)"), throttle, 0, 600),
UINTOPT("preferences/throttle", "", wxTRANSLATE("Throttle game speed, even when accelerated (0-450%, 0 = no throttle)"), throttle, 0, 450),
UINTOPT("preferences/speedupThrottle", "", wxTRANSLATE("Set throttle for speedup key (0-3000%, 0 = no throttle)"), speedup_throttle, 0, 3000),
UINTOPT("preferences/speedupFrameSkip", "", wxTRANSLATE("Number of frames to skip with speedupThrottle == 0 (no throttle)"), speedup_frame_skip, 0, 300),
UINTOPT("preferences/speedupFrameSkip", "", wxTRANSLATE("Number of frames to skip with speedup (instead of speedup throttle)"), speedup_frame_skip, 0, 300),
BOOLOPT("preferences/speedupThrottleFrameSkip", "", wxTRANSLATE("Use frame skip for speedup throttle"), speedup_throttle_frame_skip),
INTOPT("preferences/useBiosGB", "BootRomGB", wxTRANSLATE("Use the specified BIOS file for GB"), useBiosFileGB, 0, 1),
INTOPT("preferences/useBiosGBA", "BootRomEn", wxTRANSLATE("Use the specified BIOS file"), useBiosFileGBA, 0, 1),

View File

@ -102,7 +102,7 @@
<object class="wxSpinCtrl" name="Throttle">
<value>0</value>
<min>0</min>
<max>1000</max>
<max>450</max>
<tooltip>0 = no throttle</tooltip>
</object>
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
@ -130,12 +130,6 @@
<item translate="0">400%</item>
<item translate="0">425%</item>
<item translate="0">450%</item>
<item translate="0">475%</item>
<item translate="0">500%</item>
<item translate="0">525%</item>
<item translate="0">550%</item>
<item translate="0">575%</item>
<item translate="0">600%</item>
</content>
</object>
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>