make speedup/turbo configurable + misc #339
Add Speedup / Turbo configuration panel which allows setting the throttle or number of frames to skip for when the speed key is pressed or turbo is enabled (which just presses the speed key.) Throttle and frame-skip are mutually exclusive, throttle must be 0 (no throttle) when number of frames to skip is non-zero. The dialog controls handle this. This is implemented in the core in GBA.cpp, GB.cpp and ConfigManager. Two new options are added both in ConfigManager and in the wx options, speedup_throttle and speedup_frame_skip, the defaults are: ``` speedup_throttle = 0 (no throttle) speedup_frame_skip = 9 ``` this was the original behavior. Add support for unsigned ints to wx/opts.cpp for these and for throttle, this requires a new validator wxUIntValidator to use them in spin controls. Clean up appearance of the throttle spin control in the General dialog. Maximum throttle and speedup_throttle is 600, values much over 500 will not behave differently from 0 on modern hardware. Maximum frame skip is 30 at the moment. Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
parent
5379708fcc
commit
16dd5d4068
|
@ -104,8 +104,9 @@ enum named_opts
|
|||
OPT_THREAD_PRIORITY,
|
||||
OPT_VIDEO_OPTION,
|
||||
OPT_WINDOW_POSITION_X,
|
||||
OPT_WINDOW_POSITION_Y
|
||||
|
||||
OPT_WINDOW_POSITION_Y,
|
||||
OPT_SPEEDUP_THROTTLE,
|
||||
OPT_SPEEDUP_FRAME_SKIP
|
||||
};
|
||||
|
||||
#define SOUND_MAX_VOLUME 2.0
|
||||
|
@ -242,7 +243,9 @@ int* rewindSerials = NULL;
|
|||
uint32_t autoFrameSkipLastTime;
|
||||
uint32_t movieLastJoypad;
|
||||
uint32_t movieNextJoypad;
|
||||
int throttle;
|
||||
uint32_t throttle = 100;
|
||||
uint32_t speedup_throttle = 0;
|
||||
uint32_t speedup_frame_skip = 9;
|
||||
|
||||
const char* preparedCheatCodes[MAX_CHEATS];
|
||||
|
||||
|
@ -374,6 +377,8 @@ struct option argOptions[] = {
|
|||
{ "synchronize", required_argument, 0, OPT_SYNCHRONIZE },
|
||||
{ "thread-priority", required_argument, 0, OPT_THREAD_PRIORITY },
|
||||
{ "throttle", required_argument, 0, 'T' },
|
||||
{ "speedup_throttle", required_argument, 0, OPT_SPEEDUP_THROTTLE },
|
||||
{ "speedup_frame_skip", required_argument, 0, OPT_SPEEDUP_FRAME_SKIP },
|
||||
{ "triple-buffering", no_argument, &tripleBuffering, 1 },
|
||||
{ "use-bios", no_argument, &useBios, 1 },
|
||||
{ "use-bios-file-gb", no_argument, &useBiosFileGB, 1 },
|
||||
|
@ -527,6 +532,8 @@ void LoadConfig()
|
|||
soundRecordDir = ReadPrefString("soundRecordDir");
|
||||
threadPriority = ReadPref("priority", 2);
|
||||
throttle = ReadPref("throttle", 100);
|
||||
speedup_throttle = ReadPref("speedup_throttle", 0);
|
||||
speedup_frame_skip = ReadPref("speedup_frame_skip", 9);
|
||||
tripleBuffering = ReadPref("tripleBuffering", 0);
|
||||
useBios = ReadPrefHex("useBiosGBA");
|
||||
useBiosFileGB = ReadPref("useBiosGB", 0);
|
||||
|
@ -971,6 +978,10 @@ int ReadOpts(int argc, char ** argv)
|
|||
filter = kStretch2x;
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (optarg)
|
||||
throttle = atoi(optarg);
|
||||
break;
|
||||
case 'I':
|
||||
if (optarg) {
|
||||
ifbType = (IFBFilter)atoi(optarg);
|
||||
|
@ -1339,6 +1350,14 @@ int ReadOpts(int argc, char ** argv)
|
|||
// --dotcode-file-name-save
|
||||
saveDotCodeFile = optarg;
|
||||
break;
|
||||
case OPT_SPEEDUP_THROTTLE:
|
||||
if (optarg)
|
||||
speedup_throttle = atoi(optarg);
|
||||
break;
|
||||
case OPT_SPEEDUP_FRAME_SKIP:
|
||||
if (optarg)
|
||||
speedup_frame_skip = atoi(optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return op;
|
||||
|
|
|
@ -141,7 +141,9 @@ extern int winPauseNextFrame;
|
|||
extern uint32_t autoFrameSkipLastTime;
|
||||
extern uint32_t movieLastJoypad;
|
||||
extern uint32_t movieNextJoypad;
|
||||
extern int throttle;
|
||||
extern uint32_t throttle;
|
||||
extern uint32_t speedup_throttle;
|
||||
extern uint32_t speedup_frame_skip;
|
||||
|
||||
extern int preparedCheats;
|
||||
extern const char *preparedCheatCodes[MAX_CHEATS];
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../Util.h"
|
||||
#include "../common/ConfigManager.h"
|
||||
#include "../gba/GBALink.h"
|
||||
#include "../gba/Sound.h"
|
||||
#include "gb.h"
|
||||
#include "gbCheats.h"
|
||||
#include "gbGlobals.h"
|
||||
|
@ -4842,8 +4843,32 @@ void gbEmulate(int ticksToStop)
|
|||
|
||||
if ((gbLcdTicksDelayed <= 0) && (gbLCDChangeHappened)) {
|
||||
int framesToSkip = systemFrameSkip;
|
||||
if (speedup)
|
||||
framesToSkip = 9; // try 6 FPS during speedup
|
||||
static bool speedup_throttle_set = false;
|
||||
static uint32_t last_throttle;
|
||||
|
||||
if ((gbJoymask[0] >> 10) & 1) {
|
||||
if (speedup_throttle != 0) {
|
||||
if (!speedup_throttle_set && throttle != speedup_throttle) {
|
||||
last_throttle = throttle;
|
||||
throttle = speedup_throttle;
|
||||
soundSetThrottle(speedup_throttle);
|
||||
speedup_throttle_set = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (speedup_frame_skip)
|
||||
framesToSkip = speedup_frame_skip;
|
||||
|
||||
speedup_throttle_set = false;
|
||||
}
|
||||
}
|
||||
else if (speedup_throttle_set) {
|
||||
throttle = last_throttle;
|
||||
soundSetThrottle(last_throttle);
|
||||
|
||||
speedup_throttle_set = false;
|
||||
}
|
||||
|
||||
//gbLcdTicksDelayed = gbLcdTicks+1;
|
||||
gbLCDChangeHappened = false;
|
||||
switch (gbLcdModeDelayed) {
|
||||
|
@ -4919,7 +4944,11 @@ void gbEmulate(int ticksToStop)
|
|||
|
||||
newmask = (gbJoymask[0] >> 10);
|
||||
|
||||
speedup = (newmask & 1) ? true : false;
|
||||
speedup = false;
|
||||
|
||||
if (newmask & 1 && speedup_throttle == 0)
|
||||
speedup = true;
|
||||
|
||||
gbCapture = (newmask & 2) ? true : false;
|
||||
|
||||
if (gbCapture && !gbCapturePrevious) {
|
||||
|
|
|
@ -3756,8 +3756,31 @@ void CPULoop(int ticks)
|
|||
}
|
||||
} else {
|
||||
int framesToSkip = systemFrameSkip;
|
||||
if (speedup)
|
||||
framesToSkip = 9; // try 6 FPS during speedup
|
||||
static bool speedup_throttle_set = false;
|
||||
static uint32_t last_throttle;
|
||||
|
||||
if ((joy >> 10) & 1) {
|
||||
if (speedup_throttle != 0) {
|
||||
if (!speedup_throttle_set && throttle != speedup_throttle) {
|
||||
last_throttle = throttle;
|
||||
throttle = speedup_throttle;
|
||||
soundSetThrottle(speedup_throttle);
|
||||
speedup_throttle_set = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (speedup_frame_skip)
|
||||
framesToSkip = speedup_frame_skip;
|
||||
|
||||
speedup_throttle_set = false;
|
||||
}
|
||||
}
|
||||
else if (speedup_throttle_set) {
|
||||
throttle = last_throttle;
|
||||
soundSetThrottle(last_throttle);
|
||||
|
||||
speedup_throttle_set = false;
|
||||
}
|
||||
|
||||
if (DISPSTAT & 2) {
|
||||
// if in H-Blank, leave it and move to drawing mode
|
||||
|
@ -3788,7 +3811,12 @@ void CPULoop(int ticks)
|
|||
// If no (m) code is enabled, apply the cheats at each LCDline
|
||||
if ((cheatsEnabled) && (mastercode == 0))
|
||||
remainingTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext);
|
||||
speedup = (ext & 1) ? true : false;
|
||||
|
||||
speedup = false;
|
||||
|
||||
if (ext & 1 && speedup_throttle == 0)
|
||||
speedup = true;
|
||||
|
||||
capture = (ext & 2) ? true : false;
|
||||
|
||||
if (capture && !capturePrevious) {
|
||||
|
|
|
@ -432,6 +432,7 @@ SET(XRC_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/xrc/PaletteViewer.xrc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xrc/SoundConfig.xrc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xrc/TileViewer.xrc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xrc/SpeedupConfig.xrc
|
||||
)
|
||||
|
||||
# wxrc does not support xrs files in -c output (> 10x compression)
|
||||
|
|
|
@ -2041,6 +2041,14 @@ EVT_HANDLER(GeneralConfigure, "General options...")
|
|||
}
|
||||
}
|
||||
|
||||
EVT_HANDLER(SpeedupConfigure, "Speedup / Turbo options...")
|
||||
{
|
||||
wxDialog* dlg = GetXRCDialog("SpeedupConfig");
|
||||
|
||||
if (ShowModal(dlg) == wxID_OK)
|
||||
update_opts();
|
||||
}
|
||||
|
||||
EVT_HANDLER(GameBoyConfigure, "Game Boy options...")
|
||||
{
|
||||
wxDialog* dlg = GetXRCDialog("GameBoyConfig");
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <wx/filepicker.h>
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/valnum.h>
|
||||
#include <wx/stockitem.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <wx/txtstrm.h>
|
||||
|
@ -2221,70 +2222,23 @@ public:
|
|||
DoSetThrottleSel(thr->GetValue());
|
||||
}
|
||||
|
||||
void DoSetThrottleSel(int val)
|
||||
void DoSetThrottleSel(uint32_t val)
|
||||
{
|
||||
switch (val) {
|
||||
case 0:
|
||||
thrsel->SetSelection(1);
|
||||
break;
|
||||
|
||||
case 25:
|
||||
thrsel->SetSelection(2);
|
||||
break;
|
||||
|
||||
case 50:
|
||||
thrsel->SetSelection(3);
|
||||
break;
|
||||
|
||||
case 100:
|
||||
thrsel->SetSelection(4);
|
||||
break;
|
||||
|
||||
case 150:
|
||||
thrsel->SetSelection(5);
|
||||
break;
|
||||
|
||||
case 200:
|
||||
thrsel->SetSelection(6);
|
||||
break;
|
||||
|
||||
default:
|
||||
thrsel->SetSelection(0);
|
||||
break;
|
||||
}
|
||||
if (val <= 600)
|
||||
thrsel->SetSelection(std::round((double)val / 25));
|
||||
else
|
||||
thrsel->SetSelection(100 / 25);
|
||||
}
|
||||
|
||||
// set thr from thrsel
|
||||
void SetThrottle(wxCommandEvent& evt)
|
||||
{
|
||||
switch (thrsel->GetSelection()) {
|
||||
case 0: // blank; leave it alone
|
||||
break;
|
||||
uint32_t val = thrsel->GetSelection() * 25;
|
||||
|
||||
case 1:
|
||||
thr->SetValue(0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
thr->SetValue(25);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
thr->SetValue(50);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (val <= 600)
|
||||
thr->SetValue(val);
|
||||
else
|
||||
thr->SetValue(100);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
thr->SetValue(150);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
thr->SetValue(200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// since this is not the actual dialog, derived from wxDialog, which is
|
||||
|
@ -2298,6 +2252,102 @@ public:
|
|||
}
|
||||
} throttle_ctrl;
|
||||
|
||||
// manage speedup key frame skip spinctrl/canned setting choice interaction
|
||||
static class SpeedupFrameSkipCtrl_t : public wxEvtHandler {
|
||||
public:
|
||||
wxSpinCtrl* speedup_frame_skip_spin;
|
||||
wxChoice* speedup_frame_skip_sel;
|
||||
void SetSpeedupFrameSkipSel(wxSpinEvent& evt);
|
||||
void DoSetSpeedupFrameSkipSel(uint32_t val);
|
||||
void SetSpeedupFrameSkip(wxCommandEvent& evt);
|
||||
void Init(wxShowEvent& ev);
|
||||
} speedup_frame_skip_ctrl;
|
||||
|
||||
// manage speedup key throttle spinctrl/canned setting choice interaction
|
||||
static class SpeedupThrottleCtrl_t : public wxEvtHandler {
|
||||
public:
|
||||
wxSpinCtrl* speedup_throttle_spin;
|
||||
wxChoice* speedup_throttle_sel;
|
||||
|
||||
// set speedup_throttle_sel from speedup_throttle
|
||||
void SetSpeedupThrottleSel(wxSpinEvent& evt)
|
||||
{
|
||||
DoSetSpeedupThrottleSel(speedup_throttle_spin->GetValue());
|
||||
}
|
||||
|
||||
void DoSetSpeedupThrottleSel(uint32_t val)
|
||||
{
|
||||
if (val > 0 && val <= 600) {
|
||||
speedup_throttle_sel->SetSelection(std::round((double)val / 25));
|
||||
speedup_frame_skip_ctrl.DoSetSpeedupFrameSkipSel(0);
|
||||
wxCommandEvent nil;
|
||||
speedup_frame_skip_ctrl.SetSpeedupFrameSkip(nil);
|
||||
}
|
||||
else
|
||||
speedup_throttle_sel->SetSelection(0);
|
||||
}
|
||||
|
||||
// set speedup_throttle from speedup_throttle_sel
|
||||
void SetSpeedupThrottle(wxCommandEvent& evt)
|
||||
{
|
||||
uint32_t val = speedup_throttle_sel->GetSelection() * 25;
|
||||
|
||||
if (val > 0 && val <= 600) {
|
||||
speedup_throttle_spin->SetValue(val);
|
||||
speedup_frame_skip_ctrl.DoSetSpeedupFrameSkipSel(0);
|
||||
wxCommandEvent nil;
|
||||
speedup_frame_skip_ctrl.SetSpeedupFrameSkip(nil);
|
||||
}
|
||||
else
|
||||
speedup_throttle_spin->SetValue(0);
|
||||
}
|
||||
|
||||
void Init(wxShowEvent& ev)
|
||||
{
|
||||
ev.Skip();
|
||||
DoSetSpeedupThrottleSel(speedup_throttle);
|
||||
}
|
||||
} speedup_throttle_ctrl;
|
||||
|
||||
// set speedup_frame_skip_sel from speedup_frame_skip
|
||||
void SpeedupFrameSkipCtrl_t::SetSpeedupFrameSkipSel(wxSpinEvent& evt)
|
||||
{
|
||||
DoSetSpeedupFrameSkipSel(speedup_frame_skip_spin->GetValue());
|
||||
}
|
||||
|
||||
void SpeedupFrameSkipCtrl_t::DoSetSpeedupFrameSkipSel(uint32_t val)
|
||||
{
|
||||
if (val > 0 && val <= 30) {
|
||||
speedup_frame_skip_sel->SetSelection(val);
|
||||
speedup_throttle_ctrl.DoSetSpeedupThrottleSel(0);
|
||||
wxCommandEvent nil;
|
||||
speedup_throttle_ctrl.SetSpeedupThrottle(nil);
|
||||
}
|
||||
else
|
||||
speedup_frame_skip_sel->SetSelection(0);
|
||||
}
|
||||
|
||||
// set speedup_frame_skip from speedup_frame_skip_sel
|
||||
void SpeedupFrameSkipCtrl_t::SetSpeedupFrameSkip(wxCommandEvent& evt)
|
||||
{
|
||||
uint32_t val = speedup_frame_skip_sel->GetSelection();
|
||||
|
||||
if (val > 0 && val <= 30) {
|
||||
speedup_frame_skip_spin->SetValue(val);
|
||||
speedup_throttle_ctrl.DoSetSpeedupThrottleSel(0);
|
||||
wxCommandEvent nil;
|
||||
speedup_throttle_ctrl.SetSpeedupThrottle(nil);
|
||||
}
|
||||
else
|
||||
speedup_frame_skip_spin->SetValue(0);
|
||||
}
|
||||
|
||||
void SpeedupFrameSkipCtrl_t::Init(wxShowEvent& ev)
|
||||
{
|
||||
ev.Skip();
|
||||
DoSetSpeedupFrameSkipSel(speedup_frame_skip);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
//Check if a pointer from the XRC file is valid. If it's not, throw an error telling the user.
|
||||
template <typename T>
|
||||
|
@ -3207,6 +3257,11 @@ bool MainFrame::BindControls()
|
|||
sc = SafeXRCCTRL<wxSpinCtrl>(d, n); \
|
||||
sc->SetValidator(wxGenericValidator(&o)); \
|
||||
} while (0)
|
||||
#define getsc_uint(n, o) \
|
||||
do { \
|
||||
sc = SafeXRCCTRL<wxSpinCtrl>(d, n); \
|
||||
sc->SetValidator(wxUIntValidator(&o)); \
|
||||
} while (0)
|
||||
{
|
||||
// Online Auto Update check frequency
|
||||
getrbi("UpdateNever", gopts.onlineupdates, 0);
|
||||
|
@ -3215,7 +3270,7 @@ bool MainFrame::BindControls()
|
|||
getrbi("PNG", captureFormat, 0);
|
||||
getrbi("BMP", captureFormat, 1);
|
||||
getsc("RewindInterval", gopts.rewind_interval);
|
||||
getsc("Throttle", throttle);
|
||||
getsc_uint("Throttle", throttle);
|
||||
throttle_ctrl.thr = sc;
|
||||
throttle_ctrl.thrsel = SafeXRCCTRL<wxChoice>(d, "ThrottleSel");
|
||||
throttle_ctrl.thr->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED,
|
||||
|
@ -3228,6 +3283,35 @@ bool MainFrame::BindControls()
|
|||
NULL, &throttle_ctrl);
|
||||
d->Fit();
|
||||
}
|
||||
// SpeedUp Key Config
|
||||
d = LoadXRCDialog("SpeedupConfig");
|
||||
{
|
||||
getsc_uint("SpeedupThrottle", speedup_throttle);
|
||||
speedup_throttle_ctrl.speedup_throttle_spin = sc;
|
||||
speedup_throttle_ctrl.speedup_throttle_sel = SafeXRCCTRL<wxChoice>(d, "SpeedupThrottleSel");
|
||||
speedup_throttle_ctrl.speedup_throttle_spin->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED,
|
||||
wxSpinEventHandler(SpeedupThrottleCtrl_t::SetSpeedupThrottleSel),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
speedup_throttle_ctrl.speedup_throttle_sel->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
|
||||
wxCommandEventHandler(SpeedupThrottleCtrl_t::SetSpeedupThrottle),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
d->Connect(wxEVT_SHOW, wxShowEventHandler(SpeedupThrottleCtrl_t::Init),
|
||||
NULL, &speedup_throttle_ctrl);
|
||||
d->Fit();
|
||||
|
||||
getsc_uint("SpeedupFrameSkip", speedup_frame_skip);
|
||||
speedup_frame_skip_ctrl.speedup_frame_skip_spin = sc;
|
||||
speedup_frame_skip_ctrl.speedup_frame_skip_sel = SafeXRCCTRL<wxChoice>(d, "SpeedupFrameSkipSel");
|
||||
speedup_frame_skip_ctrl.speedup_frame_skip_spin->Connect(wxEVT_COMMAND_SPINCTRL_UPDATED,
|
||||
wxSpinEventHandler(SpeedupFrameSkipCtrl_t::SetSpeedupFrameSkipSel),
|
||||
NULL, &speedup_frame_skip_ctrl);
|
||||
speedup_frame_skip_ctrl.speedup_frame_skip_sel->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
|
||||
wxCommandEventHandler(SpeedupFrameSkipCtrl_t::SetSpeedupFrameSkip),
|
||||
NULL, &speedup_frame_skip_ctrl);
|
||||
d->Connect(wxEVT_SHOW, wxShowEventHandler(SpeedupFrameSkipCtrl_t::Init),
|
||||
NULL, &speedup_frame_skip_ctrl);
|
||||
d->Fit();
|
||||
}
|
||||
#define getcbbe(n, o) getbe(n, o, cb, wxCheckBox, CB)
|
||||
wxBoolIntEnValidator* bienval;
|
||||
#define getbie(n, o, v, cv, t, wt) \
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
{ \
|
||||
wxT(c), (n), d, NULL, NULL, wxT(""), min, max, NULL, &v \
|
||||
}
|
||||
#define UINTOPT(c, n, d, v, min, max) \
|
||||
{ \
|
||||
wxT(c), (n), d, NULL, NULL, wxT(""), min, max, NULL, NULL, &v \
|
||||
}
|
||||
#define BOOLOPT(c, n, d, v) \
|
||||
{ \
|
||||
wxT(c), (n), d, NULL, NULL, wxT(""), 0, 0, &v \
|
||||
|
@ -252,7 +256,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),
|
||||
INTOPT("preferences/throttle", "", wxTRANSLATE("Throttle game speed, even when accelerated (0-1000%, 0 = disabled)"), throttle, 0, 1000),
|
||||
UINTOPT("preferences/throttle", "", wxTRANSLATE("Throttle game speed, even when accelerated (0-500%, 0 = no throttle)"), throttle, 0, 600),
|
||||
UINTOPT("preferences/speedupThrottle", "", wxTRANSLATE("Set throttle for speedup key (0-600%, 0 = no throttle)"), speedup_throttle, 0, 600),
|
||||
UINTOPT("preferences/speedupFrameSkip", "", wxTRANSLATE("Set frame skip for speedup key (0-30)"), speedup_frame_skip, 0, 30),
|
||||
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),
|
||||
INTOPT("preferences/useBiosGBC", "BootRomGBC", wxTRANSLATE("Use the specified BIOS file for GBC"), useBiosFileGBC, 0, 1),
|
||||
|
@ -525,6 +531,15 @@ void load_opts()
|
|||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), opt.curdouble, opt.opt, opt.min, opt.max);
|
||||
} else
|
||||
*opt.doubleopt = opt.curdouble;
|
||||
} else if (opt.uintopt) {
|
||||
int val;
|
||||
cfg->Read(opt.opt, &val, *opt.uintopt);
|
||||
opt.curuint = val;
|
||||
|
||||
if (opt.curuint < opt.min || opt.curuint > opt.max) {
|
||||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), opt.curuint, opt.opt, opt.min, opt.max);
|
||||
} else
|
||||
*opt.uintopt = opt.curuint;
|
||||
} else if (opt.boolopt) {
|
||||
cfg->Read(opt.opt, opt.boolopt, *opt.boolopt);
|
||||
opt.curbool = *opt.boolopt;
|
||||
|
@ -648,6 +663,9 @@ void update_opts()
|
|||
} else if (opt.doubleopt) {
|
||||
if (*opt.doubleopt != opt.curdouble)
|
||||
cfg->Write(opt.opt, (opt.curdouble = *opt.doubleopt));
|
||||
} else if (opt.uintopt) {
|
||||
if (*opt.uintopt != opt.curuint)
|
||||
cfg->Write(opt.opt, (opt.curuint = *opt.uintopt));
|
||||
} else if (opt.boolopt) {
|
||||
if (*opt.boolopt != opt.curbool)
|
||||
cfg->Write(opt.opt, (opt.curbool = *opt.boolopt));
|
||||
|
@ -802,6 +820,14 @@ bool opt_set(const wxString& name, const wxString& val)
|
|||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), dval, name, opt->min, opt->max);
|
||||
else
|
||||
*opt->doubleopt = dval;
|
||||
} else if (opt->uintopt) {
|
||||
const wxString s(val);
|
||||
unsigned long uival;
|
||||
|
||||
if (!s.ToULong(&uival) || uival < opt->min || uival > opt->max)
|
||||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), uival, name, opt->min, opt->max);
|
||||
else
|
||||
*opt->uintopt = (uint32_t)uival;
|
||||
} else {
|
||||
// GB/Palette[0-2] is virtual
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
|
|
@ -93,10 +93,12 @@ extern struct opt_desc {
|
|||
double min, max;
|
||||
bool* boolopt;
|
||||
double* doubleopt;
|
||||
uint32_t* uintopt;
|
||||
// current configured value
|
||||
wxString curstr;
|
||||
int curint;
|
||||
double curdouble;
|
||||
uint32_t curuint;
|
||||
#define curbool curint
|
||||
} opts[];
|
||||
extern const int num_opts;
|
||||
|
|
|
@ -72,6 +72,17 @@ protected:
|
|||
wxString str_val;
|
||||
};
|
||||
|
||||
class wxUIntValidator : public wxValidator {
|
||||
public:
|
||||
wxUIntValidator(uint32_t* _val);
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* parent);
|
||||
wxObject* Clone() const;
|
||||
protected:
|
||||
uint32_t* uint_val;
|
||||
};
|
||||
|
||||
// boolean copy-only validator with reversed value
|
||||
// may be attached to radio button or checkbox
|
||||
class wxBoolRevValidator : public wxValidator {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// utility widgets
|
||||
#include "wx/wxmisc.h"
|
||||
#include <wx/wx.h>
|
||||
#include <wx/spinctrl.h>
|
||||
|
||||
wxFarRadio::wxFarRadio()
|
||||
: wxCheckBox()
|
||||
|
@ -429,3 +430,50 @@ wxObject* wxPositiveDoubleValidator::Clone() const
|
|||
{
|
||||
return new wxPositiveDoubleValidator(double_val);
|
||||
}
|
||||
|
||||
|
||||
wxUIntValidator::wxUIntValidator(uint32_t* _val)
|
||||
: uint_val(_val)
|
||||
{
|
||||
if (uint_val)
|
||||
TransferToWindow();
|
||||
}
|
||||
|
||||
bool wxUIntValidator::TransferToWindow()
|
||||
{
|
||||
wxSpinCtrl* ctrl = wxDynamicCast(GetWindow(), wxSpinCtrl);
|
||||
if (ctrl && uint_val) {
|
||||
ctrl->SetValue(*uint_val);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxUIntValidator::TransferFromWindow()
|
||||
{
|
||||
wxSpinCtrl* ctrl = wxDynamicCast(GetWindow(), wxSpinCtrl);
|
||||
if (ctrl && uint_val) {
|
||||
*uint_val = ctrl->GetValue();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxUIntValidator::Validate(wxWindow* parent)
|
||||
{
|
||||
wxSpinCtrl* ctrl = wxDynamicCast(GetWindow(), wxSpinCtrl);
|
||||
|
||||
if (ctrl) {
|
||||
if (ctrl->GetValue() >= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
wxObject* wxUIntValidator::Clone() const
|
||||
{
|
||||
return new wxUIntValidator(uint_val);
|
||||
}
|
||||
|
|
|
@ -149,14 +149,33 @@
|
|||
<object class="sizeritem">
|
||||
<object class="wxChoice" name="ThrottleSel">
|
||||
<content>
|
||||
<item/>
|
||||
<item>No throttle</item>
|
||||
<item>None</item>
|
||||
<item>25%</item>
|
||||
<item>50%</item>
|
||||
<item>75%</item>
|
||||
<item>100%</item>
|
||||
<item>125%</item>
|
||||
<item>150%</item>
|
||||
<item>175%</item>
|
||||
<item>200%</item>
|
||||
<item>225%</item>
|
||||
<item>250%</item>
|
||||
<item>275%</item>
|
||||
<item>300%</item>
|
||||
<item>325%</item>
|
||||
<item>350%</item>
|
||||
<item>375%</item>
|
||||
<item>400%</item>
|
||||
<item>425%</item>
|
||||
<item>450%</item>
|
||||
<item>475%</item>
|
||||
<item>500%</item>
|
||||
<item>525%</item>
|
||||
<item>550%</item>
|
||||
<item>575%</item>
|
||||
<item>600%</item>
|
||||
</content>
|
||||
<size>40,-1d</size>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
|
|
|
@ -457,6 +457,9 @@
|
|||
<object class="wxMenuItem" name="GeneralConfigure">
|
||||
<label>_General ...</label>
|
||||
</object>
|
||||
<object class="wxMenuItem" name="SpeedupConfigure">
|
||||
<label>_Speedup / Turbo ...</label>
|
||||
</object>
|
||||
<object class="wxMenuItem" name="EmulatorDirectories">
|
||||
<label>D_irectories ...</label>
|
||||
</object>
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
|
||||
<object class="wxDialog" name="SpeedupConfig">
|
||||
<title>SpeedUp / Turbo Settings</title>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText">
|
||||
<label>Speedup Throttle</label>
|
||||
<font>
|
||||
<weight>bold</weight>
|
||||
</font>
|
||||
</object>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText">
|
||||
<label>% of normal:</label>
|
||||
<size>60,-1d</size>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxSpinCtrl" name="SpeedupThrottle">
|
||||
<value>0</value>
|
||||
<min>0</min>
|
||||
<max>600</max>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxChoice" name="SpeedupThrottleSel">
|
||||
<content>
|
||||
<item>None</item>
|
||||
<item>25%</item>
|
||||
<item>50%</item>
|
||||
<item>75%</item>
|
||||
<item>100%</item>
|
||||
<item>125%</item>
|
||||
<item>150%</item>
|
||||
<item>175%</item>
|
||||
<item>200%</item>
|
||||
<item>225%</item>
|
||||
<item>250%</item>
|
||||
<item>275%</item>
|
||||
<item>300%</item>
|
||||
<item>325%</item>
|
||||
<item>350%</item>
|
||||
<item>375%</item>
|
||||
<item>400%</item>
|
||||
<item>425%</item>
|
||||
<item>450%</item>
|
||||
<item>475%</item>
|
||||
<item>500%</item>
|
||||
<item>525%</item>
|
||||
<item>550%</item>
|
||||
<item>575%</item>
|
||||
<item>600%</item>
|
||||
</content>
|
||||
<size>40,-1d</size>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText">
|
||||
<label>Speedup Frame Skip</label>
|
||||
<font>
|
||||
<weight>bold</weight>
|
||||
</font>
|
||||
</object>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText">
|
||||
<label># of frames:</label>
|
||||
<size>60,-1d</size>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxSpinCtrl" name="SpeedupFrameSkip">
|
||||
<value>9</value>
|
||||
<min>0</min>
|
||||
<max>30</max>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxChoice" name="SpeedupFrameSkipSel">
|
||||
<content>
|
||||
<item>None</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>6</item>
|
||||
<item>7</item>
|
||||
<item>8</item>
|
||||
<item>9</item>
|
||||
<item>10</item>
|
||||
<item>11</item>
|
||||
<item>12</item>
|
||||
<item>13</item>
|
||||
<item>14</item>
|
||||
<item>15</item>
|
||||
<item>16</item>
|
||||
<item>17</item>
|
||||
<item>18</item>
|
||||
<item>19</item>
|
||||
<item>20</item>
|
||||
<item>21</item>
|
||||
<item>22</item>
|
||||
<item>23</item>
|
||||
<item>24</item>
|
||||
<item>25</item>
|
||||
<item>26</item>
|
||||
<item>27</item>
|
||||
<item>28</item>
|
||||
<item>29</item>
|
||||
<item>30</item>
|
||||
</content>
|
||||
<size>40,-1d</size>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<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="wxButton" name="wxID_OK"/>
|
||||
</object>
|
||||
<object class="button">
|
||||
<object class="wxButton" name="wxID_CANCEL"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</resource>
|
Loading…
Reference in New Issue