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:
Rafael Kitover 2019-02-02 17:50:23 -08:00
parent 5379708fcc
commit 16dd5d4068
No known key found for this signature in database
GPG Key ID: 08AB596679D86240
14 changed files with 527 additions and 70 deletions

View File

@ -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;

View File

@ -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];

View File

@ -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) {

View File

@ -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) {

View File

@ -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)

View File

@ -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");

View File

@ -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) \

View File

@ -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++) {

View File

@ -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;

View File

@ -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 {

View File

@ -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);
}

View File

@ -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>

View File

@ -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>

View File

@ -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>