mirror of
https://github.com/visualboyadvance-m/visualboyadvance-m
synced 2025-10-05 23:52:49 +02:00
Compare commits
1 Commits
ede668b712
...
turbo-mute
Author | SHA1 | Date | |
---|---|---|---|
|
123e5b5f54 |
@@ -59,6 +59,7 @@ extern struct CoreOptions {
|
||||
bool speedHack = false;
|
||||
bool speedup = false;
|
||||
bool speedup_throttle_frame_skip = false;
|
||||
bool speedup_mute = true;
|
||||
int cheatsEnabled = 1;
|
||||
int cpuDisableSfx = 0;
|
||||
int cpuSaveType = 0;
|
||||
@@ -125,4 +126,4 @@ extern int systemSpeed;
|
||||
#define SYSTEM_SAVE_UPDATED 30
|
||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||
|
||||
#endif // VBAM_CORE_BASE_SYSTEM_H_
|
||||
#endif // VBAM_CORE_BASE_SYSTEM_H_
|
||||
|
@@ -3845,6 +3845,8 @@ void CPULoop(int ticks)
|
||||
bool turbo_button_pressed = (joy >> 10) & 1;
|
||||
#ifndef __LIBRETRO__
|
||||
static uint32_t last_throttle;
|
||||
static bool current_volume_saved = false;
|
||||
static float current_volume;
|
||||
|
||||
if (turbo_button_pressed) {
|
||||
if (coreOptions.speedup_frame_skip)
|
||||
@@ -3859,10 +3861,23 @@ void CPULoop(int ticks)
|
||||
if (coreOptions.speedup_throttle_frame_skip)
|
||||
framesToSkip += static_cast<int>(std::ceil(double(coreOptions.speedup_throttle) / 100.0) - 1);
|
||||
}
|
||||
|
||||
if (coreOptions.speedup_mute && !current_volume_saved) {
|
||||
current_volume = soundGetVolume();
|
||||
current_volume_saved = true;
|
||||
soundSetVolume(0);
|
||||
}
|
||||
}
|
||||
else if (speedup_throttle_set) {
|
||||
soundSetThrottle(DowncastU16(last_throttle));
|
||||
speedup_throttle_set = false;
|
||||
else {
|
||||
if (current_volume_saved) {
|
||||
soundSetVolume(current_volume);
|
||||
current_volume_saved = false;
|
||||
}
|
||||
|
||||
if (speedup_throttle_set) {
|
||||
soundSetThrottle(DowncastU16(last_throttle));
|
||||
speedup_throttle_set = false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (turbo_button_pressed)
|
||||
|
@@ -98,7 +98,8 @@ enum named_opts
|
||||
OPT_SOUND_FILTERING,
|
||||
OPT_SPEEDUP_THROTTLE,
|
||||
OPT_SPEEDUP_FRAME_SKIP,
|
||||
OPT_NO_SPEEDUP_THROTTLE_FRAME_SKIP
|
||||
OPT_NO_SPEEDUP_THROTTLE_FRAME_SKIP,
|
||||
OPT_NO_SPEEDUP_MUTE
|
||||
};
|
||||
|
||||
#define SOUND_MAX_VOLUME 2.0
|
||||
@@ -232,6 +233,7 @@ struct option argOptions[] = {
|
||||
{ "speedup-throttle", required_argument, 0, OPT_SPEEDUP_THROTTLE },
|
||||
{ "speedup-frame-skip", required_argument, 0, OPT_SPEEDUP_FRAME_SKIP },
|
||||
{ "no-speedup-throttle-frame-skip", no_argument, 0, OPT_NO_SPEEDUP_THROTTLE_FRAME_SKIP },
|
||||
{ "no-speedup-mute", no_argument, 0, OPT_NO_SPEEDUP_MUTE },
|
||||
{ "use-bios", no_argument, &coreOptions.useBios, 1 },
|
||||
{ "verbose", required_argument, 0, 'v' },
|
||||
{ "win-gb-printer-enabled", no_argument, &coreOptions.winGbPrinterEnabled, 1 },
|
||||
@@ -347,6 +349,7 @@ void LoadConfig()
|
||||
coreOptions.speedup_throttle = ReadPref("speedupThrottle", 100);
|
||||
coreOptions.speedup_frame_skip = ReadPref("speedupFrameSkip", 9);
|
||||
coreOptions.speedup_throttle_frame_skip = ReadPref("speedupThrottleFrameSkip", 0);
|
||||
coreOptions.speedup_mute = ReadPref("speedupMute", 1);
|
||||
coreOptions.useBios = ReadPrefHex("useBiosGBA");
|
||||
coreOptions.winGbPrinterEnabled = ReadPref("gbPrinter", 0);
|
||||
|
||||
@@ -990,6 +993,9 @@ int ReadOpts(int argc, char ** argv)
|
||||
case OPT_NO_SPEEDUP_THROTTLE_FRAME_SKIP:
|
||||
coreOptions.speedup_throttle_frame_skip = false;
|
||||
break;
|
||||
case OPT_NO_SPEEDUP_MUTE:
|
||||
coreOptions.speedup_mute = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return op;
|
||||
|
@@ -31,6 +31,8 @@ set(VBAM_WX_COMMON
|
||||
dialogs/joypad-config.h
|
||||
dialogs/sound-config.cpp
|
||||
dialogs/sound-config.h
|
||||
dialogs/speedup-config.cpp
|
||||
dialogs/speedup-config.h
|
||||
drawing.h
|
||||
extra-translations.cpp
|
||||
gfxviewers.cpp
|
||||
|
@@ -328,9 +328,10 @@ std::array<Option, kNbOptions>& Option::All() {
|
||||
Option(OptionID::kPrefSkipSaveGameCheats, &coreOptions.skipSaveGameCheats, 0, 1),
|
||||
Option(OptionID::kPrefSkipSaveGameBattery, &coreOptions.skipSaveGameBattery, 0, 1),
|
||||
Option(OptionID::kPrefThrottle, &coreOptions.throttle, 0, 450),
|
||||
Option(OptionID::kPrefSpeedupThrottle, &coreOptions.speedup_throttle, 0, 3000),
|
||||
Option(OptionID::kPrefSpeedupFrameSkip, &coreOptions.speedup_frame_skip, 0, 300),
|
||||
Option(OptionID::kPrefSpeedupThrottle, &coreOptions.speedup_throttle, 0, 450),
|
||||
Option(OptionID::kPrefSpeedupFrameSkip, &coreOptions.speedup_frame_skip, 0, 40),
|
||||
Option(OptionID::kPrefSpeedupThrottleFrameSkip, &coreOptions.speedup_throttle_frame_skip),
|
||||
Option(OptionID::kPrefSpeedupMute, &coreOptions.speedup_mute),
|
||||
Option(OptionID::kPrefUseBiosGB, &g_owned_opts.use_bios_file_gb),
|
||||
Option(OptionID::kPrefUseBiosGBA, &g_owned_opts.use_bios_file_gba),
|
||||
Option(OptionID::kPrefUseBiosGBC, &g_owned_opts.use_bios_file_gbc),
|
||||
@@ -531,6 +532,8 @@ const std::array<OptionData, kNbOptions + 1> kAllOptionsData = {
|
||||
"throttle)")},
|
||||
OptionData{"preferences/speedupThrottleFrameSkip", "",
|
||||
_("Use frame skip for speedup throttle")},
|
||||
OptionData{"preferences/speedupMute", "",
|
||||
_("Mute sound during speedup")},
|
||||
OptionData{"preferences/useBiosGB", "BootRomGB", _("Use the specified BIOS file for Game Boy")},
|
||||
OptionData{"preferences/useBiosGBA", "BootRomEn", _("Use the specified BIOS file")},
|
||||
OptionData{"preferences/useBiosGBC", "BootRomGBC",
|
||||
|
@@ -99,6 +99,7 @@ enum class OptionID {
|
||||
kPrefSpeedupThrottle,
|
||||
kPrefSpeedupFrameSkip,
|
||||
kPrefSpeedupThrottleFrameSkip,
|
||||
kPrefSpeedupMute,
|
||||
kPrefUseBiosGB,
|
||||
kPrefUseBiosGBA,
|
||||
kPrefUseBiosGBC,
|
||||
|
@@ -103,6 +103,7 @@ static constexpr std::array<Option::Type, kNbOptions> kOptionsTypes = {
|
||||
/*kPrefSpeedupThrottle*/ Option::Type::kUnsigned,
|
||||
/*kPrefSpeedupFrameSkip*/ Option::Type::kUnsigned,
|
||||
/*kPrefSpeedupThrottleFrameSkip*/ Option::Type::kBool,
|
||||
/*kPrefSpeedupMute*/ Option::Type::kBool,
|
||||
/*kPrefUseBiosGB*/ Option::Type::kBool,
|
||||
/*kPrefUseBiosGBA*/ Option::Type::kBool,
|
||||
/*kPrefUseBiosGBC*/ Option::Type::kBool,
|
||||
@@ -174,11 +175,43 @@ private:
|
||||
Option* option_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class OptionProxyNumeric {
|
||||
public:
|
||||
virtual T Get() const = 0;
|
||||
virtual bool Set(T value) = 0;
|
||||
virtual T Min() const = 0;
|
||||
virtual T Max() const = 0;
|
||||
|
||||
bool operator++() { return *this += 1; }
|
||||
bool operator--() { return *this -= 1; }
|
||||
bool operator++(int) { return *this += 1; }
|
||||
bool operator--(int) { return *this -= 1; }
|
||||
bool operator+=(T value) {
|
||||
const int new_value = Get() + value;
|
||||
if (new_value > Max()) {
|
||||
return Set(Max());
|
||||
} else {
|
||||
return Set(new_value);
|
||||
}
|
||||
}
|
||||
bool operator-=(T value) {
|
||||
const int new_value = Get() - value;
|
||||
if (new_value < Min()) {
|
||||
return Set(Min());
|
||||
} else {
|
||||
return Set(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
operator T() const { return Get(); }
|
||||
};
|
||||
|
||||
template <OptionID ID>
|
||||
class OptionProxy<
|
||||
ID,
|
||||
typename std::enable_if<kOptionsTypes[static_cast<size_t>(ID)] ==
|
||||
Option::Type::kDouble>::type> {
|
||||
Option::Type::kDouble>::type> : public OptionProxyNumeric<double> {
|
||||
public:
|
||||
OptionProxy() : option_(Option::ByID(ID)) {}
|
||||
~OptionProxy() = default;
|
||||
@@ -187,9 +220,7 @@ public:
|
||||
bool Set(double value) { return option_->SetDouble(value); }
|
||||
double Min() const { return option_->GetDoubleMin(); }
|
||||
double Max() const { return option_->GetDoubleMax(); }
|
||||
|
||||
bool operator=(double value) { return Set(value); }
|
||||
operator double() const { return Get(); }
|
||||
|
||||
private:
|
||||
Option* option_;
|
||||
@@ -199,7 +230,7 @@ template <OptionID ID>
|
||||
class OptionProxy<
|
||||
ID,
|
||||
typename std::enable_if<kOptionsTypes[static_cast<size_t>(ID)] ==
|
||||
Option::Type::kInt>::type> {
|
||||
Option::Type::kInt>::type> : public OptionProxyNumeric<int32_t> {
|
||||
public:
|
||||
OptionProxy() : option_(Option::ByID(ID)) {}
|
||||
~OptionProxy() = default;
|
||||
@@ -208,25 +239,7 @@ public:
|
||||
bool Set(int32_t value) { return option_->SetInt(value); }
|
||||
int32_t Min() const { return option_->GetIntMin(); }
|
||||
int32_t Max() const { return option_->GetIntMax(); }
|
||||
|
||||
bool operator=(int32_t value) { return Set(value); }
|
||||
bool operator+=(int32_t value) {
|
||||
const int new_value = Get() + value;
|
||||
if (new_value > Max()) {
|
||||
return Set(Max());
|
||||
} else {
|
||||
return Set(new_value);
|
||||
}
|
||||
}
|
||||
bool operator-=(int32_t value) {
|
||||
const int new_value = Get() - value;
|
||||
if (new_value < Min()) {
|
||||
return Set(Min());
|
||||
} else {
|
||||
return Set(new_value);
|
||||
}
|
||||
}
|
||||
operator int32_t() const { return Get(); }
|
||||
|
||||
private:
|
||||
Option* option_;
|
||||
@@ -236,7 +249,7 @@ template <OptionID ID>
|
||||
class OptionProxy<
|
||||
ID,
|
||||
typename std::enable_if<kOptionsTypes[static_cast<size_t>(ID)] ==
|
||||
Option::Type::kUnsigned>::type> {
|
||||
Option::Type::kUnsigned>::type> : public OptionProxyNumeric<uint32_t> {
|
||||
public:
|
||||
OptionProxy() : option_(Option::ByID(ID)) {}
|
||||
~OptionProxy() = default;
|
||||
@@ -245,9 +258,7 @@ public:
|
||||
bool Set(uint32_t value) { return option_->SetUnsigned(value); }
|
||||
uint32_t Min() const { return option_->GetUnsignedMin(); }
|
||||
uint32_t Max() const { return option_->GetUnsignedMax(); }
|
||||
|
||||
bool operator=(int32_t value) { return Set(value); }
|
||||
operator int32_t() const { return Get(); }
|
||||
bool operator=(uint32_t value) { return Set(value); }
|
||||
|
||||
private:
|
||||
Option* option_;
|
||||
|
@@ -353,3 +353,109 @@ TEST(OptionProxyTest, MatchingTypes) {
|
||||
EXPECT_EQ(option->type(), proxy_type);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OptionProxyTest, NumericOperators) {
|
||||
wxLogNull disable_logging;
|
||||
|
||||
int32_t int_opt = OPTION(kDispMaxThreads);
|
||||
|
||||
int_opt++;
|
||||
OPTION(kDispMaxThreads)++;
|
||||
EXPECT_EQ(int_opt, OPTION(kDispMaxThreads));
|
||||
|
||||
int_opt--;
|
||||
OPTION(kDispMaxThreads)--;
|
||||
EXPECT_EQ(int_opt, OPTION(kDispMaxThreads));
|
||||
|
||||
++int_opt;
|
||||
OPTION(kDispMaxThreads)++;
|
||||
EXPECT_EQ(int_opt, OPTION(kDispMaxThreads));
|
||||
|
||||
--int_opt;
|
||||
OPTION(kDispMaxThreads)--;
|
||||
EXPECT_EQ(int_opt, OPTION(kDispMaxThreads));
|
||||
|
||||
int_opt += 2;
|
||||
OPTION(kDispMaxThreads) += 2;
|
||||
EXPECT_EQ(int_opt, OPTION(kDispMaxThreads));
|
||||
|
||||
int_opt -= 2;
|
||||
OPTION(kDispMaxThreads) -= 2;
|
||||
EXPECT_EQ(int_opt, OPTION(kDispMaxThreads));
|
||||
|
||||
OPTION(kDispMaxThreads) = OPTION(kDispMaxThreads).Max();
|
||||
OPTION(kDispMaxThreads)++;
|
||||
EXPECT_EQ(OPTION(kDispMaxThreads), OPTION(kDispMaxThreads).Max());
|
||||
|
||||
OPTION(kDispMaxThreads) = OPTION(kDispMaxThreads).Min();
|
||||
OPTION(kDispMaxThreads)--;
|
||||
EXPECT_EQ(OPTION(kDispMaxThreads), OPTION(kDispMaxThreads).Min());
|
||||
|
||||
uint32_t unsigned_opt = OPTION(kJoyDefault);
|
||||
|
||||
unsigned_opt++;
|
||||
OPTION(kJoyDefault)++;
|
||||
EXPECT_EQ(unsigned_opt, OPTION(kJoyDefault));
|
||||
|
||||
unsigned_opt--;
|
||||
OPTION(kJoyDefault)--;
|
||||
EXPECT_EQ(unsigned_opt, OPTION(kJoyDefault));
|
||||
|
||||
++unsigned_opt;
|
||||
OPTION(kJoyDefault)++;
|
||||
EXPECT_EQ(unsigned_opt, OPTION(kJoyDefault));
|
||||
|
||||
--unsigned_opt;
|
||||
OPTION(kJoyDefault)--;
|
||||
EXPECT_EQ(unsigned_opt, OPTION(kJoyDefault));
|
||||
|
||||
unsigned_opt += 2;
|
||||
OPTION(kJoyDefault) += 2;
|
||||
EXPECT_EQ(unsigned_opt, OPTION(kJoyDefault));
|
||||
|
||||
unsigned_opt -= 2;
|
||||
OPTION(kJoyDefault) -= 2;
|
||||
EXPECT_EQ(unsigned_opt, OPTION(kJoyDefault));
|
||||
|
||||
OPTION(kJoyDefault) = OPTION(kJoyDefault).Max();
|
||||
OPTION(kJoyDefault)++;
|
||||
EXPECT_EQ(OPTION(kJoyDefault), OPTION(kJoyDefault).Max());
|
||||
|
||||
OPTION(kJoyDefault) = OPTION(kJoyDefault).Min();
|
||||
OPTION(kJoyDefault)--;
|
||||
EXPECT_EQ(OPTION(kJoyDefault), OPTION(kJoyDefault).Min());
|
||||
|
||||
double double_opt = OPTION(kDispScale);
|
||||
|
||||
double_opt++;
|
||||
OPTION(kDispScale)++;
|
||||
EXPECT_EQ(double_opt, OPTION(kDispScale));
|
||||
|
||||
double_opt--;
|
||||
OPTION(kDispScale)--;
|
||||
EXPECT_EQ(double_opt, OPTION(kDispScale));
|
||||
|
||||
++double_opt;
|
||||
OPTION(kDispScale)++;
|
||||
EXPECT_EQ(double_opt, OPTION(kDispScale));
|
||||
|
||||
--double_opt;
|
||||
OPTION(kDispScale)--;
|
||||
EXPECT_EQ(double_opt, OPTION(kDispScale));
|
||||
|
||||
double_opt += 2;
|
||||
OPTION(kDispScale) += 2;
|
||||
EXPECT_EQ(double_opt, OPTION(kDispScale));
|
||||
|
||||
double_opt -= 2;
|
||||
OPTION(kDispScale) -= 2;
|
||||
EXPECT_EQ(double_opt, OPTION(kDispScale));
|
||||
|
||||
OPTION(kDispScale) = OPTION(kDispScale).Max();
|
||||
OPTION(kDispScale)++;
|
||||
EXPECT_EQ(OPTION(kDispScale), OPTION(kDispScale).Max());
|
||||
|
||||
OPTION(kDispScale) = OPTION(kDispScale).Min();
|
||||
OPTION(kDispScale)--;
|
||||
EXPECT_EQ(OPTION(kDispScale), OPTION(kDispScale).Min());
|
||||
}
|
||||
|
154
src/wx/dialogs/speedup-config.cpp
Normal file
154
src/wx/dialogs/speedup-config.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "wx/dialogs/speedup-config.h"
|
||||
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#include "core/base/check.h"
|
||||
#include "wx/config/option-proxy.h"
|
||||
#include "wx/dialogs/base-dialog.h"
|
||||
#include "wx/widgets/option-validator.h"
|
||||
|
||||
// This dialog has a spin control representing the speedup value as it feels
|
||||
// like to the user. Values below 450 can be an actual throttle or a number of
|
||||
// frames to skip depending on whether the Frame Skip checkbox is checked. The
|
||||
// number of frames is the spin control value divided by 100, for example 300
|
||||
// with the Frame Skip checkbox checked means 3 frames to skip. Values above 450
|
||||
// are always the number of frames to skip, for example 900 means 9 frames to skip.
|
||||
//
|
||||
// The config option SpeedupThrottle is the throttle value, if frame skip is
|
||||
// used it is 0. The config option SpeedupFrameSkip is the number of frames to
|
||||
// skip, if throttle is used it is 0. The config option SpeedupThrottleFrameSkip
|
||||
// represents the Frame Skip checkbox for values under 450, that is if they are
|
||||
// interpreted as a frame skip or a throttle.
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
bool SpeedupConfigValidator::TransferToWindow() {
|
||||
uint32_t opt_frame_skip = OPTION(kPrefSpeedupFrameSkip);
|
||||
uint32_t opt_throttle = OPTION(kPrefSpeedupThrottle);
|
||||
bool opt_throttle_frame_skip = OPTION(kPrefSpeedupThrottleFrameSkip);
|
||||
|
||||
auto dialog = static_cast<SpeedupConfig*>(GetWindow());
|
||||
|
||||
dialog->prev_frame_skip_cb_ = opt_throttle_frame_skip;
|
||||
|
||||
if (opt_frame_skip != 0) {
|
||||
dialog->speedup_throttle_spin_->SetValue(opt_frame_skip * 100);
|
||||
dialog->prev_throttle_spin_ = opt_frame_skip * 100;
|
||||
|
||||
dialog->frame_skip_cb_->SetValue(true);
|
||||
dialog->frame_skip_cb_->Disable();
|
||||
} else {
|
||||
dialog->speedup_throttle_spin_->SetValue(opt_throttle);
|
||||
dialog->prev_throttle_spin_ = opt_throttle;
|
||||
|
||||
dialog->frame_skip_cb_->SetValue(opt_throttle_frame_skip);
|
||||
|
||||
if (opt_throttle != 0)
|
||||
dialog->frame_skip_cb_->Enable();
|
||||
else
|
||||
dialog->frame_skip_cb_->Disable();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpeedupConfigValidator::TransferFromWindow() {
|
||||
auto dialog = static_cast<SpeedupConfig*>(GetWindow());
|
||||
|
||||
uint32_t val = dialog->speedup_throttle_spin_->GetValue();
|
||||
|
||||
VBAM_CHECK(val >= 0);
|
||||
|
||||
if (val == 0) {
|
||||
OPTION(kPrefSpeedupThrottle) = 0;
|
||||
OPTION(kPrefSpeedupFrameSkip) = 0;
|
||||
OPTION(kPrefSpeedupThrottleFrameSkip) = false;
|
||||
} else if (val <= OPTION(kPrefSpeedupThrottle).Max()) {
|
||||
OPTION(kPrefSpeedupThrottle) = val;
|
||||
OPTION(kPrefSpeedupFrameSkip) = 0;
|
||||
OPTION(kPrefSpeedupThrottleFrameSkip) = dialog->frame_skip_cb_->GetValue();
|
||||
} else { // val > throttle_max
|
||||
OPTION(kPrefSpeedupThrottle) = 100;
|
||||
OPTION(kPrefSpeedupFrameSkip) = val / 100;
|
||||
OPTION(kPrefSpeedupThrottleFrameSkip) = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
SpeedupConfig* SpeedupConfig::NewInstance(wxWindow* parent) {
|
||||
VBAM_CHECK(parent);
|
||||
return new SpeedupConfig(parent);
|
||||
}
|
||||
|
||||
SpeedupConfig::SpeedupConfig(wxWindow* parent)
|
||||
: BaseDialog(parent, "SpeedupConfig") {
|
||||
|
||||
speedup_throttle_spin_ = GetValidatedChild<wxSpinCtrl>("SpeedupThrottleSpin");
|
||||
frame_skip_cb_ = GetValidatedChild<wxCheckBox>("SpeedupThrottleFrameSkip");
|
||||
|
||||
speedup_throttle_spin_->SetRange(OPTION(kPrefSpeedupThrottle).Min(), OPTION(kPrefSpeedupFrameSkip).Max() * 100);
|
||||
|
||||
speedup_throttle_spin_->SetWindowStyle(wxSP_ARROW_KEYS);
|
||||
|
||||
#ifdef wxTE_PROCESS_ENTER
|
||||
speedup_throttle_spin_->SetWindowStyleFlag(wxTE_PROCESS_ENTER);
|
||||
#endif
|
||||
|
||||
GetValidatedChild<wxCheckBox>("SpeedupMute")->SetValidator(widgets::OptionBoolValidator(config::OptionID::kPrefSpeedupMute));
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
Bind(wxEVT_SPIN_UP, std::bind(&SpeedupConfig::SetSpeedupThrottle, this, _1), XRCID("SpeedupThrottleSpin"));
|
||||
Bind(wxEVT_SPIN_DOWN, std::bind(&SpeedupConfig::SetSpeedupThrottle, this, _1), XRCID("SpeedupThrottleSpin"));
|
||||
Bind(wxEVT_SPIN, std::bind(&SpeedupConfig::SetSpeedupThrottle, this, _1), XRCID("SpeedupThrottleSpin"));
|
||||
Bind(wxEVT_TEXT, std::bind(&SpeedupConfig::SetSpeedupThrottle, this, _1), XRCID("SpeedupThrottleSpin"));
|
||||
Bind(wxEVT_CHECKBOX, std::bind(&SpeedupConfig::ToggleSpeedupFrameSkip, this), XRCID("SpeedupThrottleFrameSkip"));
|
||||
|
||||
SetValidator(SpeedupConfigValidator());
|
||||
|
||||
Fit();
|
||||
}
|
||||
|
||||
void SpeedupConfig::SetSpeedupThrottle(wxCommandEvent& evt)
|
||||
{
|
||||
VBAM_CHECK(evt.GetEventObject() == speedup_throttle_spin_);
|
||||
|
||||
uint32_t val = speedup_throttle_spin_->GetValue();
|
||||
|
||||
VBAM_CHECK(val >= 0);
|
||||
|
||||
if (val == 0) {
|
||||
frame_skip_cb_->SetValue(false);
|
||||
frame_skip_cb_->Disable();
|
||||
} else if (val <= OPTION(kPrefSpeedupThrottle).Max()) {
|
||||
frame_skip_cb_->SetValue(prev_frame_skip_cb_);
|
||||
frame_skip_cb_->Enable();
|
||||
} else { // val > throttle_max
|
||||
if (val > prev_throttle_spin_)
|
||||
val += 100;
|
||||
|
||||
val = std::floor((double)val / 100) * 100;
|
||||
|
||||
uint32_t max = speedup_throttle_spin_->GetMax();
|
||||
|
||||
if (val > max)
|
||||
val = max;
|
||||
|
||||
frame_skip_cb_->SetValue(true);
|
||||
frame_skip_cb_->Disable();
|
||||
}
|
||||
|
||||
speedup_throttle_spin_->SetValue(val);
|
||||
prev_throttle_spin_ = val;
|
||||
}
|
||||
|
||||
void SpeedupConfig::ToggleSpeedupFrameSkip()
|
||||
{
|
||||
prev_frame_skip_cb_ = frame_skip_cb_->GetValue();
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
54
src/wx/dialogs/speedup-config.h
Normal file
54
src/wx/dialogs/speedup-config.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef VBAM_WX_DIALOGS_SPEEDUP_CONFIG_H_
|
||||
#define VBAM_WX_DIALOGS_SPEEDUP_CONFIG_H_
|
||||
|
||||
// Manages the Speedup/Turbo configuration dialog.
|
||||
//
|
||||
// See the explanation for the implementation in the .cpp file.
|
||||
|
||||
#include <wx/checkbox.h>
|
||||
#include "wx/dialogs/base-dialog.h"
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/validate.h>
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
class SpeedupConfigValidator : public wxValidator {
|
||||
public:
|
||||
SpeedupConfigValidator() = default;
|
||||
~SpeedupConfigValidator() override = default;
|
||||
|
||||
bool TransferToWindow() override;
|
||||
bool TransferFromWindow() override;
|
||||
|
||||
bool Validate([[maybe_unused]]wxWindow* parent) override { return true; }
|
||||
|
||||
private:
|
||||
wxObject* Clone() const override { return new SpeedupConfigValidator(); }
|
||||
};
|
||||
|
||||
class SpeedupConfig : public BaseDialog {
|
||||
public:
|
||||
static SpeedupConfig* NewInstance(wxWindow* parent);
|
||||
~SpeedupConfig() override = default;
|
||||
|
||||
void ToggleSpeedupFrameSkip();
|
||||
void ToggleSpeedupMute();
|
||||
void SetSpeedupThrottle(wxCommandEvent& evt);
|
||||
|
||||
private:
|
||||
// The constructor is private so initialization has to be done via the
|
||||
// static method. This is because this class is destroyed when its
|
||||
// owner, `parent` is destroyed. This prevents accidental deletion.
|
||||
SpeedupConfig(wxWindow* parent);
|
||||
|
||||
wxSpinCtrl* speedup_throttle_spin_;
|
||||
wxCheckBox* frame_skip_cb_;
|
||||
bool prev_frame_skip_cb_;
|
||||
unsigned prev_throttle_spin_;
|
||||
|
||||
friend class SpeedupConfigValidator;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
||||
#endif // VBAM_WX_DIALOGS_SPEEDUP_CONFIG_H_
|
@@ -48,6 +48,7 @@
|
||||
#include "wx/dialogs/gb-rom-info.h"
|
||||
#include "wx/dialogs/joypad-config.h"
|
||||
#include "wx/dialogs/sound-config.h"
|
||||
#include "wx/dialogs/speedup-config.h"
|
||||
#include "wx/opts.h"
|
||||
#include "wx/widgets/checkedlistctrl.h"
|
||||
#include "wx/widgets/option-validator.h"
|
||||
@@ -1483,92 +1484,6 @@ public:
|
||||
}
|
||||
} throttle_ctrl;
|
||||
|
||||
static class SpeedupThrottleCtrl_t : public wxEvtHandler {
|
||||
public:
|
||||
wxSpinCtrl* speedup_throttle_spin;
|
||||
wxCheckBox* frame_skip_cb;
|
||||
|
||||
void SetSpeedupThrottle(wxCommandEvent& evt)
|
||||
{
|
||||
unsigned val = speedup_throttle_spin->GetValue();
|
||||
|
||||
evt.Skip(false);
|
||||
|
||||
if (val == 0) {
|
||||
coreOptions.speedup_throttle = 0;
|
||||
coreOptions.speedup_frame_skip = 0;
|
||||
coreOptions.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 <= 450) {
|
||||
coreOptions.speedup_throttle = val;
|
||||
coreOptions.speedup_frame_skip = 0;
|
||||
|
||||
frame_skip_cb->SetValue(prev_frame_skip_cb);
|
||||
frame_skip_cb->Enable();
|
||||
}
|
||||
else { // val > 450
|
||||
coreOptions.speedup_throttle = 100;
|
||||
coreOptions.speedup_throttle_frame_skip = false;
|
||||
|
||||
unsigned rounded = std::round((double)val / 100) * 100;
|
||||
|
||||
coreOptions.speedup_frame_skip = rounded / 100 - 1;
|
||||
|
||||
// Round up or down to the nearest 100%.
|
||||
// For example, when the up/down buttons are pressed on the spin
|
||||
// control.
|
||||
if ((int)(val - rounded) > 0)
|
||||
coreOptions.speedup_frame_skip++;
|
||||
else if ((int)(val - rounded) < 0)
|
||||
coreOptions.speedup_frame_skip--;
|
||||
|
||||
frame_skip_cb->SetValue(true);
|
||||
frame_skip_cb->Disable();
|
||||
|
||||
val = (coreOptions.speedup_frame_skip + 1) * 100;
|
||||
}
|
||||
|
||||
speedup_throttle_spin->SetValue(val);
|
||||
}
|
||||
|
||||
void SetSpeedupFrameSkip(wxCommandEvent& evt)
|
||||
{
|
||||
(void)evt; // Unused param.
|
||||
|
||||
bool checked = frame_skip_cb->GetValue();
|
||||
|
||||
coreOptions.speedup_throttle_frame_skip = prev_frame_skip_cb = checked;
|
||||
}
|
||||
|
||||
void Init(wxShowEvent& ev)
|
||||
{
|
||||
if (coreOptions.speedup_frame_skip != 0) {
|
||||
speedup_throttle_spin->SetValue((coreOptions.speedup_frame_skip + 1) * 100);
|
||||
frame_skip_cb->SetValue(true);
|
||||
frame_skip_cb->Disable();
|
||||
}
|
||||
else {
|
||||
speedup_throttle_spin->SetValue(coreOptions.speedup_throttle);
|
||||
frame_skip_cb->SetValue(coreOptions.speedup_throttle_frame_skip);
|
||||
|
||||
if (coreOptions.speedup_throttle != 0)
|
||||
frame_skip_cb->Enable();
|
||||
else
|
||||
frame_skip_cb->Disable();
|
||||
}
|
||||
|
||||
ev.Skip();
|
||||
}
|
||||
private:
|
||||
bool prev_frame_skip_cb = coreOptions.speedup_throttle_frame_skip;
|
||||
} speedup_throttle_ctrl;
|
||||
|
||||
/////////////////////////////
|
||||
//Check if a pointer from the XRC file is valid. If it's not, throw an error telling the user.
|
||||
template <typename T>
|
||||
@@ -2376,38 +2291,6 @@ bool MainFrame::BindControls()
|
||||
d->Fit();
|
||||
}
|
||||
|
||||
// SpeedUp Key Config
|
||||
d = LoadXRCDialog("SpeedupConfig");
|
||||
{
|
||||
speedup_throttle_ctrl.frame_skip_cb = SafeXRCCTRL<wxCheckBox>(d, "SpeedupThrottleFrameSkip");
|
||||
speedup_throttle_ctrl.speedup_throttle_spin = SafeXRCCTRL<wxSpinCtrl>(d, "SpeedupThrottleSpin");
|
||||
|
||||
speedup_throttle_ctrl.speedup_throttle_spin->Connect(wxEVT_SPIN_UP,
|
||||
wxCommandEventHandler(SpeedupThrottleCtrl_t::SetSpeedupThrottle),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
|
||||
speedup_throttle_ctrl.speedup_throttle_spin->Connect(wxEVT_SPIN_DOWN,
|
||||
wxCommandEventHandler(SpeedupThrottleCtrl_t::SetSpeedupThrottle),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
|
||||
speedup_throttle_ctrl.speedup_throttle_spin->Connect(wxEVT_SPIN,
|
||||
wxCommandEventHandler(SpeedupThrottleCtrl_t::SetSpeedupThrottle),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
|
||||
speedup_throttle_ctrl.speedup_throttle_spin->Connect(wxEVT_TEXT,
|
||||
wxCommandEventHandler(SpeedupThrottleCtrl_t::SetSpeedupThrottle),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
|
||||
speedup_throttle_ctrl.frame_skip_cb->Connect(wxEVT_CHECKBOX,
|
||||
wxCommandEventHandler(SpeedupThrottleCtrl_t::SetSpeedupFrameSkip),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
|
||||
d->Connect(wxEVT_SHOW, wxShowEventHandler(SpeedupThrottleCtrl_t::Init),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
|
||||
d->Fit();
|
||||
}
|
||||
|
||||
wxMenuItem* suspend_scr_saver_mi = XRCITEM("SuspendScreenSaver");
|
||||
if (suspend_scr_saver_mi)
|
||||
{
|
||||
@@ -2470,6 +2353,7 @@ bool MainFrame::BindControls()
|
||||
dialogs::SoundConfig::NewInstance(this);
|
||||
dialogs::DirectoriesConfig::NewInstance(this);
|
||||
dialogs::JoypadConfig::NewInstance(this, std::bind(&wxvbamApp::bindings, &wxGetApp()));
|
||||
dialogs::SpeedupConfig::NewInstance(this);
|
||||
|
||||
#ifndef NO_LINK
|
||||
d = LoadXRCDialog("LinkConfig");
|
||||
|
@@ -2368,13 +2368,6 @@ void GLDrawingPanel::AdjustViewport()
|
||||
int x, y;
|
||||
widgets::GetRealPixelClientSize(this, &x, &y);
|
||||
glViewport(0, 0, x, y);
|
||||
|
||||
#ifdef DEBUG
|
||||
// you can use this to check that the gl surface is indeed high res
|
||||
GLint m_viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, m_viewport);
|
||||
wxLogDebug(wxT("GL VIEWPORT: %d, %d, %d, %d"), m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLDrawingPanel::RefreshGL()
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<weight>bold</weight>
|
||||
</font>
|
||||
</object>
|
||||
<flag>wxALL</flag>
|
||||
<flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
@@ -32,9 +32,7 @@
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxSpinCtrl" name="SpeedupThrottleSpin">
|
||||
<value>0</value>
|
||||
<min>0</min>
|
||||
<max>4000</max>
|
||||
<size>40,-1d</size>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
@@ -46,23 +44,48 @@
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxCheckBox" name="SpeedupThrottleFrameSkip">
|
||||
<label>Frame skip</label>
|
||||
<object class="wxFlexGridSizer">
|
||||
<rows>1</rows>
|
||||
<cols>2</cols>
|
||||
<growablerows>0</growablerows>
|
||||
<growablecols>0,1</growablecols>
|
||||
<object class="sizeritem">
|
||||
<object class="wxCheckBox" name="SpeedupThrottleFrameSkip">
|
||||
<label>Frame skip</label>
|
||||
</object>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxCheckBox" name="SpeedupMute">
|
||||
<label>Mute Sound</label>
|
||||
</object>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxALL</flag>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStdDialogButtonSizer">
|
||||
<object class="button">
|
||||
<object class="wxFlexGridSizer">
|
||||
<rows>1</rows>
|
||||
<cols>2</cols>
|
||||
<growablerows>0</growablerows>
|
||||
<growablecols>0,1</growablecols>
|
||||
<object class="sizeritem">
|
||||
<object class="wxButton" name="wxID_OK"/>
|
||||
<flag>wxALL</flag>
|
||||
<border>10</border>
|
||||
</object>
|
||||
<object class="button">
|
||||
<object class="sizeritem">
|
||||
<object class="wxButton" name="wxID_CANCEL"/>
|
||||
<flag>wxALL|wxALIGN_RIGHT</flag>
|
||||
<border>10</border>
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>10</border>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
Reference in New Issue
Block a user