Input refactor.
- Allow key shortcuts to run with loaded game. For example, when we set `CTRL+A` for `load most recent save state` and use `A` for some input command, holding `CTRL` and then pressing `A` will not execute the shortcut. Instead, the key press `A` will be used only as the input and nothing else. With this, we use both the input and shortcut key. - Isolate function to get keyboard key codes. As explained on [1]: "Using `GetUnicodeKey()` is in general the right thing to do if you are interested in the characters typed by the user, `GetKeyCode()` should be only used for special keys (for which `GetUnicodeKey()` returns `WXK_NONE`)." We also allow special keys to be mapped, hence the requirement of using both functions. [1] https://docs.wxwidgets.org/3.1/classwx_key_event.html - Allow use of unicode keys for input and shortcut. Use format `KeyCode:Modifier` for saving/loading unicode keys. `WxWidgets=3.{0,1}` does not create an accelerator from strings with unicode keys such as `ç` (`FromString` function). It fails with an assertion error and stops execution. At the same time, we use the keys' strings that are known for WxWidgets, such as `A`, `CTRL+O`, `PAGEUP` etc. Use both `EVT_KEY_DOWN` and `EVT_CHAR`. `EVT_CHAR` is better than `EVT_KEY_DOWN` here because it is where the raw key events will have been cooked using whatever recipes are in effect from the os, locale, international keyboard settings, etc. - Enable SDL joysticks input as key shortcuts. Start/Stop polling joysticks on Unload/load game. Our main loop already polls the joystick, we don't need the timer while a game is running. - Create function `str_split_with_sep` and use it. For when we parse strings that may include the sep string, such as game input and key shortcuts.
This commit is contained in:
parent
6b257d52f2
commit
baa0341bd5
|
@ -4953,7 +4953,6 @@ void gbEmulate(int ticksToStop)
|
||||||
if (turbo_button_pressed) {
|
if (turbo_button_pressed) {
|
||||||
if (!speedup_throttle_set && throttle != speedup_throttle) {
|
if (!speedup_throttle_set && throttle != speedup_throttle) {
|
||||||
last_throttle = throttle;
|
last_throttle = throttle;
|
||||||
//throttle = speedup_throttle;
|
|
||||||
soundSetThrottle(speedup_throttle);
|
soundSetThrottle(speedup_throttle);
|
||||||
speedup_throttle_set = true;
|
speedup_throttle_set = true;
|
||||||
}
|
}
|
||||||
|
@ -4970,7 +4969,6 @@ void gbEmulate(int ticksToStop)
|
||||||
framesToSkip = speedup_frame_skip;
|
framesToSkip = speedup_frame_skip;
|
||||||
}
|
}
|
||||||
else if (speedup_throttle_set) {
|
else if (speedup_throttle_set) {
|
||||||
//throttle = last_throttle;
|
|
||||||
soundSetThrottle(last_throttle);
|
soundSetThrottle(last_throttle);
|
||||||
|
|
||||||
speedup_throttle_set = false;
|
speedup_throttle_set = false;
|
||||||
|
|
|
@ -3799,7 +3799,6 @@ void CPULoop(int ticks)
|
||||||
if (turbo_button_pressed) {
|
if (turbo_button_pressed) {
|
||||||
if (!speedup_throttle_set && throttle != speedup_throttle) {
|
if (!speedup_throttle_set && throttle != speedup_throttle) {
|
||||||
last_throttle = throttle;
|
last_throttle = throttle;
|
||||||
//throttle = speedup_throttle;
|
|
||||||
soundSetThrottle(speedup_throttle);
|
soundSetThrottle(speedup_throttle);
|
||||||
speedup_throttle_set = true;
|
speedup_throttle_set = true;
|
||||||
}
|
}
|
||||||
|
@ -3816,7 +3815,6 @@ void CPULoop(int ticks)
|
||||||
framesToSkip = speedup_frame_skip;
|
framesToSkip = speedup_frame_skip;
|
||||||
}
|
}
|
||||||
else if (speedup_throttle_set) {
|
else if (speedup_throttle_set) {
|
||||||
//throttle = last_throttle;
|
|
||||||
soundSetThrottle(last_throttle);
|
soundSetThrottle(last_throttle);
|
||||||
|
|
||||||
speedup_throttle_set = false;
|
speedup_throttle_set = false;
|
||||||
|
|
|
@ -739,6 +739,7 @@ set(
|
||||||
viewsupt.cpp
|
viewsupt.cpp
|
||||||
wayland.cpp
|
wayland.cpp
|
||||||
strutils.cpp
|
strutils.cpp
|
||||||
|
wxutil.cpp
|
||||||
widgets/keyedit.cpp
|
widgets/keyedit.cpp
|
||||||
widgets/joyedit.cpp
|
widgets/joyedit.cpp
|
||||||
widgets/sdljoy.cpp
|
widgets/sdljoy.cpp
|
||||||
|
@ -769,6 +770,7 @@ set(
|
||||||
viewsupt.h
|
viewsupt.h
|
||||||
wxhead.h
|
wxhead.h
|
||||||
wayland.h
|
wayland.h
|
||||||
|
wxutil.h
|
||||||
widgets/wx/keyedit.h
|
widgets/wx/keyedit.h
|
||||||
widgets/wx/joyedit.h
|
widgets/wx/joyedit.h
|
||||||
widgets/wx/sdljoy.h
|
widgets/wx/sdljoy.h
|
||||||
|
|
|
@ -2706,7 +2706,6 @@ EVT_HANDLER(EmulatorDirectories, "Directories...")
|
||||||
EVT_HANDLER(JoypadConfigure, "Joypad options...")
|
EVT_HANDLER(JoypadConfigure, "Joypad options...")
|
||||||
{
|
{
|
||||||
wxDialog* dlg = GetXRCDialog("JoypadConfig");
|
wxDialog* dlg = GetXRCDialog("JoypadConfig");
|
||||||
joy.Attach(NULL);
|
|
||||||
joy.Add();
|
joy.Add();
|
||||||
|
|
||||||
if (ShowModal(dlg) == wxID_OK)
|
if (ShowModal(dlg) == wxID_OK)
|
||||||
|
@ -2718,9 +2717,12 @@ EVT_HANDLER(JoypadConfigure, "Joypad options...")
|
||||||
EVT_HANDLER(Customize, "Customize UI...")
|
EVT_HANDLER(Customize, "Customize UI...")
|
||||||
{
|
{
|
||||||
wxDialog* dlg = GetXRCDialog("AccelConfig");
|
wxDialog* dlg = GetXRCDialog("AccelConfig");
|
||||||
|
joy.Add();
|
||||||
|
|
||||||
if (ShowModal(dlg) == wxID_OK)
|
if (ShowModal(dlg) == wxID_OK)
|
||||||
update_opts();
|
update_opts();
|
||||||
|
|
||||||
|
SetJoystick();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_ONLINEUPDATES
|
#ifndef NO_ONLINEUPDATES
|
||||||
|
@ -3068,6 +3070,9 @@ void SetLinkTypeMenu(const char* type, int value)
|
||||||
mf->SetMenuOption(type, 1);
|
mf->SetMenuOption(type, 1);
|
||||||
gopts.gba_link_type = value;
|
gopts.gba_link_type = value;
|
||||||
update_opts();
|
update_opts();
|
||||||
|
#ifndef NO_LINK
|
||||||
|
CloseLink();
|
||||||
|
#endif
|
||||||
mf->EnableNetworkMenu();
|
mf->EnableNetworkMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3097,33 +3102,21 @@ EVT_HANDLER_MASK(LanLink, "Start Network link", CMDEN_LINK_ANY)
|
||||||
|
|
||||||
EVT_HANDLER(LinkType0Nothing, "Link nothing")
|
EVT_HANDLER(LinkType0Nothing, "Link nothing")
|
||||||
{
|
{
|
||||||
#ifndef NO_LINK
|
|
||||||
CloseLink();
|
|
||||||
#endif
|
|
||||||
SetLinkTypeMenu("LinkType0Nothing", 0);
|
SetLinkTypeMenu("LinkType0Nothing", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EVT_HANDLER(LinkType1Cable, "Link cable")
|
EVT_HANDLER(LinkType1Cable, "Link cable")
|
||||||
{
|
{
|
||||||
#ifndef NO_LINK
|
|
||||||
CloseLink();
|
|
||||||
#endif
|
|
||||||
SetLinkTypeMenu("LinkType1Cable", 1);
|
SetLinkTypeMenu("LinkType1Cable", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
EVT_HANDLER(LinkType2Wireless, "Link wireless")
|
EVT_HANDLER(LinkType2Wireless, "Link wireless")
|
||||||
{
|
{
|
||||||
#ifndef NO_LINK
|
|
||||||
CloseLink();
|
|
||||||
#endif
|
|
||||||
SetLinkTypeMenu("LinkType2Wireless", 2);
|
SetLinkTypeMenu("LinkType2Wireless", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
EVT_HANDLER(LinkType3GameCube, "Link GameCube")
|
EVT_HANDLER(LinkType3GameCube, "Link GameCube")
|
||||||
{
|
{
|
||||||
#ifndef NO_LINK
|
|
||||||
CloseLink();
|
|
||||||
#endif
|
|
||||||
SetLinkTypeMenu("LinkType3GameCube", 3);
|
SetLinkTypeMenu("LinkType3GameCube", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1695,19 +1695,6 @@ public:
|
||||||
}
|
}
|
||||||
} JoyPadConfigHandler[4];
|
} JoyPadConfigHandler[4];
|
||||||
|
|
||||||
class JoystickPoller : public wxTimer {
|
|
||||||
public:
|
|
||||||
void Notify() {
|
|
||||||
wxGetApp().frame->PollJoysticks();
|
|
||||||
}
|
|
||||||
void ShowDialog(wxShowEvent& ev) {
|
|
||||||
if (ev.IsShown())
|
|
||||||
Start(50);
|
|
||||||
else
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// manage fullscreen mode widget
|
// manage fullscreen mode widget
|
||||||
// technically, it's more than a validator: it modifies the widget as well
|
// technically, it's more than a validator: it modifies the widget as well
|
||||||
class ScreenModeList : public wxValidator {
|
class ScreenModeList : public wxValidator {
|
||||||
|
@ -2003,7 +1990,7 @@ static bool treeid_to_name(int id, wxString& name, wxTreeCtrl* tc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// for sorting accels by command ID
|
// for sorting accels by command ID
|
||||||
static bool cmdid_lt(const wxAcceleratorEntry& a, const wxAcceleratorEntry& b)
|
static bool cmdid_lt(const wxAcceleratorEntryUnicode& a, const wxAcceleratorEntryUnicode& b)
|
||||||
{
|
{
|
||||||
return a.GetCommand() < b.GetCommand();
|
return a.GetCommand() < b.GetCommand();
|
||||||
}
|
}
|
||||||
|
@ -2015,7 +2002,7 @@ public:
|
||||||
wxControlWithItems* lb;
|
wxControlWithItems* lb;
|
||||||
wxAcceleratorEntry_v user_accels, accels;
|
wxAcceleratorEntry_v user_accels, accels;
|
||||||
wxWindow *asb, *remb;
|
wxWindow *asb, *remb;
|
||||||
wxKeyTextCtrl* key;
|
wxJoyKeyTextCtrl* key;
|
||||||
wxControl* curas;
|
wxControl* curas;
|
||||||
|
|
||||||
// since this is not the actual dialog, derived from wxDialog, which is
|
// since this is not the actual dialog, derived from wxDialog, which is
|
||||||
|
@ -2076,10 +2063,17 @@ public:
|
||||||
asb->Enable(!key->GetValue().empty());
|
asb->Enable(!key->GetValue().empty());
|
||||||
int cmd = id->val;
|
int cmd = id->val;
|
||||||
|
|
||||||
for (size_t i = 0; i < accels.size(); i++)
|
for (size_t i = 0; i < accels.size(); ++i) {
|
||||||
if (accels[i].GetCommand() == cmdtab[cmd].cmd_id)
|
if (accels[i].GetCommand() == cmdtab[cmd].cmd_id) {
|
||||||
lb->Append(wxKeyTextCtrl::ToString(accels[i].GetFlags(),
|
if (accels[i].GetJoystick() == 0) {
|
||||||
accels[i].GetKeyCode()));
|
wxString key = wxJoyKeyTextCtrl::ToCandidateString(accels[i].GetFlags(), accels[i].GetKeyCode());
|
||||||
|
lb->Append(key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lb->Append(accels[i].GetUkey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// after selecting a key in key list, enable Remove button
|
// after selecting a key in key list, enable Remove button
|
||||||
|
@ -2099,10 +2093,11 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxString selstr = lb->GetString(lsel);
|
wxString selstr = lb->GetString(lsel);
|
||||||
int selmod, selkey;
|
int selmod, selkey, seljoy;
|
||||||
|
|
||||||
if (!wxKeyTextCtrl::FromString(selstr, selmod, selkey))
|
if (!wxJoyKeyTextCtrl::FromString(selstr, selmod, selkey, seljoy))
|
||||||
return; // this should never happen
|
// this should never happen
|
||||||
|
return;
|
||||||
|
|
||||||
remb->Enable(false);
|
remb->Enable(false);
|
||||||
|
|
||||||
|
@ -2115,7 +2110,9 @@ public:
|
||||||
// first drop from user accels, if applicable
|
// first drop from user accels, if applicable
|
||||||
for (wxAcceleratorEntry_v::iterator i = user_accels.begin();
|
for (wxAcceleratorEntry_v::iterator i = user_accels.begin();
|
||||||
i < user_accels.end(); ++i)
|
i < user_accels.end(); ++i)
|
||||||
if (i->GetFlags() == selmod && i->GetKeyCode() == selkey) {
|
if ((i->GetFlags() == selmod && i->GetKeyCode() == selkey)
|
||||||
|
|| (seljoy != 0 && i->GetUkey() == selstr))
|
||||||
|
{
|
||||||
user_accels.erase(i);
|
user_accels.erase(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2124,15 +2121,19 @@ public:
|
||||||
wxAcceleratorEntry_v& sys_accels = wxGetApp().frame->sys_accels;
|
wxAcceleratorEntry_v& sys_accels = wxGetApp().frame->sys_accels;
|
||||||
|
|
||||||
for (size_t i = 0; i < sys_accels.size(); i++)
|
for (size_t i = 0; i < sys_accels.size(); i++)
|
||||||
if (sys_accels[i].GetFlags() == selmod && sys_accels[i].GetKeyCode() == selkey) {
|
if ((sys_accels[i].GetFlags() == selmod && sys_accels[i].GetKeyCode() == selkey)
|
||||||
wxAcceleratorEntry ne(selmod, selkey, XRCID("NOOP"));
|
|| (seljoy != 0 && sys_accels[i].GetUkey() == selstr)) // joystick system bindings?
|
||||||
|
{
|
||||||
|
wxAcceleratorEntryUnicode ne(sys_accels[i].GetUkey(), sys_accels[i].GetJoystick(), selmod, selkey, XRCID("NOOP"));
|
||||||
user_accels.push_back(ne);
|
user_accels.push_back(ne);
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, remove from accels instead of recomputing
|
// finally, remove from accels instead of recomputing
|
||||||
for (wxAcceleratorEntry_v::iterator i = accels.begin();
|
for (wxAcceleratorEntry_v::iterator i = accels.begin();
|
||||||
i < accels.end(); ++i)
|
i < accels.end(); ++i)
|
||||||
if (i->GetFlags() == selmod && i->GetKeyCode() == selkey) {
|
if ((i->GetFlags() == selmod && i->GetKeyCode() == selkey)
|
||||||
|
|| (seljoy != 0 && i->GetUkey() == selstr))
|
||||||
|
{
|
||||||
accels.erase(i);
|
accels.erase(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2164,10 +2165,11 @@ public:
|
||||||
if (!csel.IsOk() || accel.empty())
|
if (!csel.IsOk() || accel.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int acmod, ackey;
|
int acmod, ackey, acjoy;
|
||||||
|
|
||||||
if (!wxKeyTextCtrl::FromString(accel, acmod, ackey))
|
if (!wxJoyKeyTextCtrl::FromString(accel, acmod, ackey, acjoy))
|
||||||
return; // this should never happen
|
// this should never happen
|
||||||
|
return;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < lb->GetCount(); i++)
|
for (unsigned int i = 0; i < lb->GetCount(); i++)
|
||||||
if (lb->GetString(i) == accel)
|
if (lb->GetString(i) == accel)
|
||||||
|
@ -2178,15 +2180,17 @@ public:
|
||||||
// first drop from user accels, if applicable
|
// first drop from user accels, if applicable
|
||||||
for (wxAcceleratorEntry_v::iterator i = user_accels.begin();
|
for (wxAcceleratorEntry_v::iterator i = user_accels.begin();
|
||||||
i < user_accels.end(); ++i)
|
i < user_accels.end(); ++i)
|
||||||
if (i->GetFlags() == acmod && i->GetKeyCode() == ackey) {
|
if ((i->GetFlags() == acmod && i->GetKeyCode() == ackey && i->GetJoystick() != acjoy)
|
||||||
|
|| (acjoy != 0 && i->GetUkey() == accel)) {
|
||||||
user_accels.erase(i);
|
user_accels.erase(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// then assign to this command
|
// then assign to this command
|
||||||
const TreeInt* id = static_cast<const TreeInt*>(tc->GetItemData(csel));
|
const TreeInt* id = static_cast<const TreeInt*>(tc->GetItemData(csel));
|
||||||
wxAcceleratorEntry ne(acmod, ackey, cmdtab[id->val].cmd_id);
|
wxAcceleratorEntryUnicode ne(accel, acjoy, acmod, ackey, cmdtab[id->val].cmd_id);
|
||||||
user_accels.push_back(ne);
|
user_accels.push_back(ne);
|
||||||
|
|
||||||
// now assigned to this cmd...
|
// now assigned to this cmd...
|
||||||
wxString lab;
|
wxString lab;
|
||||||
treeid_to_name(id->val, lab, tc, tc->GetRootItem());
|
treeid_to_name(id->val, lab, tc, tc->GetRootItem());
|
||||||
|
@ -2207,9 +2211,9 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int acmod, ackey;
|
int acmod, ackey, acjoy;
|
||||||
|
|
||||||
if (!wxKeyTextCtrl::FromString(nkey, acmod, ackey)) {
|
if (!wxJoyKeyTextCtrl::FromString(nkey, acmod, ackey, acjoy)) {
|
||||||
// this should never happen
|
// this should never happen
|
||||||
key->SetValue(wxT(""));
|
key->SetValue(wxT(""));
|
||||||
asb->Enable(false);
|
asb->Enable(false);
|
||||||
|
@ -2220,7 +2224,8 @@ public:
|
||||||
int cmd = -1;
|
int cmd = -1;
|
||||||
|
|
||||||
for (size_t i = 0; i < accels.size(); i++)
|
for (size_t i = 0; i < accels.size(); i++)
|
||||||
if (accels[i].GetFlags() == acmod && accels[i].GetKeyCode() == ackey) {
|
if ((accels[i].GetFlags() == acmod && accels[i].GetKeyCode() == ackey)
|
||||||
|
|| (acjoy != 0 && accels[i].GetUkey() == nkey)) {
|
||||||
int cmdid = accels[i].GetCommand();
|
int cmdid = accels[i].GetCommand();
|
||||||
|
|
||||||
for (cmd = 0; cmd < ncmds; cmd++)
|
for (cmd = 0; cmd < ncmds; cmd++)
|
||||||
|
@ -2547,10 +2552,11 @@ wxAcceleratorEntry_v MainFrame::get_accels(wxAcceleratorEntry_v user_accels)
|
||||||
// silently keep only last defined binding
|
// silently keep only last defined binding
|
||||||
// same horribly inefficent O(n*m) search for duplicates as above..
|
// same horribly inefficent O(n*m) search for duplicates as above..
|
||||||
for (size_t i = 0; i < user_accels.size(); i++) {
|
for (size_t i = 0; i < user_accels.size(); i++) {
|
||||||
const wxAcceleratorEntry& ae = user_accels[i];
|
const wxAcceleratorEntryUnicode& ae = user_accels[i];
|
||||||
|
|
||||||
for (wxAcceleratorEntry_v::iterator e = accels.begin(); e < accels.end(); ++e)
|
for (wxAcceleratorEntry_v::iterator e = accels.begin(); e < accels.end(); ++e)
|
||||||
if (ae.GetFlags() == e->GetFlags() && ae.GetKeyCode() == e->GetKeyCode()) {
|
if ((ae.GetFlags() == e->GetFlags() && ae.GetKeyCode() == e->GetKeyCode())
|
||||||
|
|| (ae.GetJoystick() == e->GetJoystick() && ae.GetUkey() == e->GetUkey())) {
|
||||||
accels.erase(e);
|
accels.erase(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2572,9 +2578,12 @@ void MainFrame::set_global_accels()
|
||||||
// the menus will be added now
|
// the menus will be added now
|
||||||
|
|
||||||
// first, zero out menu item on all accels
|
// first, zero out menu item on all accels
|
||||||
for (size_t i = 0; i < accels.size(); i++)
|
for (size_t i = 0; i < accels.size(); ++i) {
|
||||||
accels[i].Set(accels[i].GetFlags(), accels[i].GetKeyCode(),
|
accels[i].Set(accels[i].GetUkey(), accels[i].GetJoystick(), accels[i].GetFlags(), accels[i].GetKeyCode(), accels[i].GetCommand());
|
||||||
accels[i].GetCommand());
|
if (accels[i].GetJoystick()) {
|
||||||
|
joy.Add(accels[i].GetJoystick() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// yet another O(n*m) loop. I really ought to sort the accel arrays
|
// yet another O(n*m) loop. I really ought to sort the accel arrays
|
||||||
for (int i = 0; i < ncmds; i++) {
|
for (int i = 0; i < ncmds; i++) {
|
||||||
|
@ -2583,26 +2592,25 @@ void MainFrame::set_global_accels()
|
||||||
if (!mi)
|
if (!mi)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// only *last* accelerator is made visible in menu
|
// only *last* accelerator is made visible in menu (non-unicode)
|
||||||
// and is flagged as such by setting menu item in accel
|
// and is flagged as such by setting menu item in accel
|
||||||
// the last is chosen so menu overrides non-menu and user overrides
|
// the last is chosen so menu overrides non-menu and user overrides
|
||||||
// system
|
// system
|
||||||
int cmd = cmdtab[i].cmd_id;
|
int cmd = cmdtab[i].cmd_id;
|
||||||
int last_accel = -1;
|
int last_accel = -1;
|
||||||
|
|
||||||
for (size_t j = 0; j < accels.size(); j++)
|
for (size_t j = 0; j < accels.size(); ++j)
|
||||||
if (cmd == accels[j].GetCommand())
|
if (cmd == accels[j].GetCommand())
|
||||||
last_accel = j;
|
last_accel = j;
|
||||||
|
|
||||||
if (last_accel >= 0) {
|
if (last_accel >= 0) {
|
||||||
DoSetAccel(mi, &accels[last_accel]);
|
DoSetAccel(mi, &accels[last_accel]);
|
||||||
accels[last_accel].Set(accels[last_accel].GetFlags(),
|
accels[last_accel].Set(accels[last_accel].GetUkey(), accels[last_accel].GetJoystick(), accels[last_accel].GetFlags(), accels[last_accel].GetKeyCode(), accels[last_accel].GetCommand(), mi);
|
||||||
accels[last_accel].GetKeyCode(),
|
} else {
|
||||||
accels[last_accel].GetCommand(), mi);
|
|
||||||
} else
|
|
||||||
// clear out user-cleared menu items
|
// clear out user-cleared menu items
|
||||||
DoSetAccel(mi, NULL);
|
DoSetAccel(mi, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, install a global accelerator table for any non-menu accels
|
// Finally, install a global accelerator table for any non-menu accels
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
@ -2612,7 +2620,7 @@ void MainFrame::set_global_accels()
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
wxAcceleratorEntry tab[1000];
|
wxAcceleratorEntryUnicode tab[1000];
|
||||||
|
|
||||||
for (size_t i = 0, j = 0; i < accels.size(); i++)
|
for (size_t i = 0, j = 0; i < accels.size(); i++)
|
||||||
if (!accels[i].GetMenuItem())
|
if (!accels[i].GetMenuItem())
|
||||||
|
@ -2627,7 +2635,7 @@ void MainFrame::set_global_accels()
|
||||||
|
|
||||||
// save recent accels
|
// save recent accels
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
recent_accel[i] = wxAcceleratorEntry();
|
recent_accel[i] = wxAcceleratorEntryUnicode();
|
||||||
|
|
||||||
for (size_t i = 0; i < accels.size(); i++)
|
for (size_t i = 0; i < accels.size(); i++)
|
||||||
if (accels[i].GetCommand() >= wxID_FILE1 && accels[i].GetCommand() <= wxID_FILE10)
|
if (accels[i].GetCommand() >= wxID_FILE1 && accels[i].GetCommand() <= wxID_FILE10)
|
||||||
|
@ -2922,7 +2930,7 @@ bool MainFrame::BindControls()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a)
|
if (a)
|
||||||
sys_accels.push_back(*a);
|
sys_accels.push_back(wxAcceleratorEntryUnicode(a));
|
||||||
else
|
else
|
||||||
// strip from label so user isn't confused
|
// strip from label so user isn't confused
|
||||||
DoSetAccel(mi, NULL);
|
DoSetAccel(mi, NULL);
|
||||||
|
@ -3830,13 +3838,6 @@ bool MainFrame::BindControls()
|
||||||
NULL, &JoyPadConfigHandler[i]);
|
NULL, &JoyPadConfigHandler[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// poll the joystick
|
|
||||||
JoystickPoller* jpoll = new JoystickPoller();
|
|
||||||
|
|
||||||
joyDialog->Connect(wxID_ANY, wxEVT_SHOW,
|
|
||||||
wxShowEventHandler(JoystickPoller::ShowDialog),
|
|
||||||
jpoll, jpoll);
|
|
||||||
|
|
||||||
joyDialog->Fit();
|
joyDialog->Fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3860,7 +3861,7 @@ bool MainFrame::BindControls()
|
||||||
accel_config_handler.lb = lb;
|
accel_config_handler.lb = lb;
|
||||||
accel_config_handler.asb = SafeXRCCTRL<wxButton>(d, "Assign");
|
accel_config_handler.asb = SafeXRCCTRL<wxButton>(d, "Assign");
|
||||||
accel_config_handler.remb = SafeXRCCTRL<wxButton>(d, "Remove");
|
accel_config_handler.remb = SafeXRCCTRL<wxButton>(d, "Remove");
|
||||||
accel_config_handler.key = SafeXRCCTRL<wxKeyTextCtrl>(d, "Shortcut");
|
accel_config_handler.key = SafeXRCCTRL<wxJoyKeyTextCtrl>(d, "Shortcut");
|
||||||
accel_config_handler.curas = SafeXRCCTRL<wxControl>(d, "AlreadyThere");
|
accel_config_handler.curas = SafeXRCCTRL<wxControl>(d, "AlreadyThere");
|
||||||
accel_config_handler.key->MoveBeforeInTabOrder(accel_config_handler.asb);
|
accel_config_handler.key->MoveBeforeInTabOrder(accel_config_handler.asb);
|
||||||
accel_config_handler.key->SetMultikey(0);
|
accel_config_handler.key->SetMultikey(0);
|
||||||
|
|
147
src/wx/opts.cpp
147
src/wx/opts.cpp
|
@ -42,9 +42,9 @@
|
||||||
opts_t gopts;
|
opts_t gopts;
|
||||||
|
|
||||||
// having the standard menu accels here means they will work even without menus
|
// having the standard menu accels here means they will work even without menus
|
||||||
const wxAcceleratorEntry default_accels[] = {
|
const wxAcceleratorEntryUnicode default_accels[] = {
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('C'), XRCID("CheatsList")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('C'), XRCID("CheatsList")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('N'), XRCID("NextFrame")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('N'), XRCID("NextFrame")),
|
||||||
// some ports add ctrl-q anyway, so may as well make it official
|
// some ports add ctrl-q anyway, so may as well make it official
|
||||||
// maybe make alt-f4 universal as well...
|
// maybe make alt-f4 universal as well...
|
||||||
// FIXME: ctrl-Q does not work on wxMSW
|
// FIXME: ctrl-Q does not work on wxMSW
|
||||||
|
@ -56,79 +56,79 @@ const wxAcceleratorEntry default_accels[] = {
|
||||||
// this was annoying people #298
|
// this was annoying people #298
|
||||||
//wxAcceleratorEntry(wxMOD_CMD, wxT('X'), wxID_EXIT),
|
//wxAcceleratorEntry(wxMOD_CMD, wxT('X'), wxID_EXIT),
|
||||||
|
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('Q'), wxID_EXIT),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('Q'), wxID_EXIT),
|
||||||
// FIXME: ctrl-W does not work on wxMSW
|
// FIXME: ctrl-W does not work on wxMSW
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('W'), wxID_CLOSE),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('W'), wxID_CLOSE),
|
||||||
// load most recent is more commonly used than load other
|
// load most recent is more commonly used than load other
|
||||||
//wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("Load")),
|
//wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("Load")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('L'), XRCID("LoadGameRecent")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('L'), XRCID("LoadGameRecent")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F1, XRCID("LoadGame01")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F1, XRCID("LoadGame01")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F2, XRCID("LoadGame02")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F2, XRCID("LoadGame02")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F3, XRCID("LoadGame03")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F3, XRCID("LoadGame03")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F4, XRCID("LoadGame04")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F4, XRCID("LoadGame04")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F5, XRCID("LoadGame05")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F5, XRCID("LoadGame05")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F6, XRCID("LoadGame06")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F6, XRCID("LoadGame06")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F7, XRCID("LoadGame07")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F7, XRCID("LoadGame07")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F8, XRCID("LoadGame08")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F8, XRCID("LoadGame08")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F9, XRCID("LoadGame09")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F9, XRCID("LoadGame09")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_F10, XRCID("LoadGame10")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_F10, XRCID("LoadGame10")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_PAUSE, XRCID("Pause")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_PAUSE, XRCID("Pause")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('P'), XRCID("Pause")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('P'), XRCID("Pause")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('R'), XRCID("Reset")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('R'), XRCID("Reset")),
|
||||||
// add shortcuts for original size multiplier #415
|
// add shortcuts for original size multiplier #415
|
||||||
wxAcceleratorEntry(wxMOD_NONE, wxT('1'), XRCID("SetSize1x")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, wxT('1'), XRCID("SetSize1x")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, wxT('2'), XRCID("SetSize2x")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, wxT('2'), XRCID("SetSize2x")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, wxT('3'), XRCID("SetSize3x")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, wxT('3'), XRCID("SetSize3x")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, wxT('4'), XRCID("SetSize4x")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, wxT('4'), XRCID("SetSize4x")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, wxT('5'), XRCID("SetSize5x")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, wxT('5'), XRCID("SetSize5x")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, wxT('6'), XRCID("SetSize6x")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, wxT('6'), XRCID("SetSize6x")),
|
||||||
// save oldest is more commonly used than save other
|
// save oldest is more commonly used than save other
|
||||||
//wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("Save")),
|
//wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("Save")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('S'), XRCID("SaveGameOldest")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('S'), XRCID("SaveGameOldest")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F1, XRCID("SaveGame01")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F1, XRCID("SaveGame01")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F2, XRCID("SaveGame02")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F2, XRCID("SaveGame02")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F3, XRCID("SaveGame03")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F3, XRCID("SaveGame03")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F4, XRCID("SaveGame04")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F4, XRCID("SaveGame04")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F5, XRCID("SaveGame05")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F5, XRCID("SaveGame05")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F6, XRCID("SaveGame06")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F6, XRCID("SaveGame06")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F7, XRCID("SaveGame07")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F7, XRCID("SaveGame07")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F8, XRCID("SaveGame08")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F8, XRCID("SaveGame08")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F9, XRCID("SaveGame09")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F9, XRCID("SaveGame09")),
|
||||||
wxAcceleratorEntry(wxMOD_SHIFT, WXK_F10, XRCID("SaveGame10")),
|
wxAcceleratorEntryUnicode(wxMOD_SHIFT, WXK_F10, XRCID("SaveGame10")),
|
||||||
// I prefer the SDL ESC key binding
|
// I prefer the SDL ESC key binding
|
||||||
//wxAcceleratorEntry(wxMOD_NONE, WXK_ESCAPE, XRCID("ToggleFullscreen"),
|
//wxAcceleratorEntry(wxMOD_NONE, WXK_ESCAPE, XRCID("ToggleFullscreen"),
|
||||||
// alt-enter is more standard anyway
|
// alt-enter is more standard anyway
|
||||||
wxAcceleratorEntry(wxMOD_ALT, WXK_RETURN, XRCID("ToggleFullscreen")),
|
wxAcceleratorEntryUnicode(wxMOD_ALT, WXK_RETURN, XRCID("ToggleFullscreen")),
|
||||||
wxAcceleratorEntry(wxMOD_ALT, wxT('1'), XRCID("JoypadAutofireA")),
|
wxAcceleratorEntryUnicode(wxMOD_ALT, wxT('1'), XRCID("JoypadAutofireA")),
|
||||||
wxAcceleratorEntry(wxMOD_ALT, wxT('2'), XRCID("JoypadAutofireB")),
|
wxAcceleratorEntryUnicode(wxMOD_ALT, wxT('2'), XRCID("JoypadAutofireB")),
|
||||||
wxAcceleratorEntry(wxMOD_ALT, wxT('3'), XRCID("JoypadAutofireL")),
|
wxAcceleratorEntryUnicode(wxMOD_ALT, wxT('3'), XRCID("JoypadAutofireL")),
|
||||||
wxAcceleratorEntry(wxMOD_ALT, wxT('4'), XRCID("JoypadAutofireR")),
|
wxAcceleratorEntryUnicode(wxMOD_ALT, wxT('4'), XRCID("JoypadAutofireR")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('1'), XRCID("VideoLayersBG0")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('1'), XRCID("VideoLayersBG0")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('2'), XRCID("VideoLayersBG1")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('2'), XRCID("VideoLayersBG1")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('3'), XRCID("VideoLayersBG2")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('3'), XRCID("VideoLayersBG2")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('4'), XRCID("VideoLayersBG3")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('4'), XRCID("VideoLayersBG3")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('5'), XRCID("VideoLayersOBJ")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('5'), XRCID("VideoLayersOBJ")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('6'), XRCID("VideoLayersWIN0")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('6'), XRCID("VideoLayersWIN0")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('7'), XRCID("VideoLayersWIN1")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('7'), XRCID("VideoLayersWIN1")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('8'), XRCID("VideoLayersOBJWIN")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('8'), XRCID("VideoLayersOBJWIN")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('B'), XRCID("Rewind")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('B'), XRCID("Rewind")),
|
||||||
// following are not in standard menus
|
// following are not in standard menus
|
||||||
// FILExx are filled in when recent menu is filled
|
// FILExx are filled in when recent menu is filled
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F1, wxID_FILE1),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F1, wxID_FILE1),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F2, wxID_FILE2),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F2, wxID_FILE2),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F3, wxID_FILE3),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F3, wxID_FILE3),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F4, wxID_FILE4),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F4, wxID_FILE4),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F5, wxID_FILE5),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F5, wxID_FILE5),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F6, wxID_FILE6),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F6, wxID_FILE6),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F7, wxID_FILE7),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F7, wxID_FILE7),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F8, wxID_FILE8),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F8, wxID_FILE8),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F9, wxID_FILE9),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F9, wxID_FILE9),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, WXK_F10, wxID_FILE10),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, WXK_F10, wxID_FILE10),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('0'), XRCID("VideoLayersReset")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('0'), XRCID("VideoLayersReset")),
|
||||||
wxAcceleratorEntry(wxMOD_CMD, wxT('G'), XRCID("ChangeFilter")),
|
wxAcceleratorEntryUnicode(wxMOD_CMD, wxT('G'), XRCID("ChangeFilter")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_ADD, XRCID("IncreaseVolume")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_NUMPAD_ADD, XRCID("IncreaseVolume")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_SUBTRACT, XRCID("DecreaseVolume")),
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_NUMPAD_SUBTRACT, XRCID("DecreaseVolume")),
|
||||||
wxAcceleratorEntry(wxMOD_NONE, WXK_NUMPAD_ENTER, XRCID("ToggleSound"))
|
wxAcceleratorEntryUnicode(wxMOD_NONE, WXK_NUMPAD_ENTER, XRCID("ToggleSound"))
|
||||||
};
|
};
|
||||||
const int num_def_accels = sizeof(default_accels) / sizeof(default_accels[0]);
|
const int num_def_accels = sizeof(default_accels) / sizeof(default_accels[0]);
|
||||||
|
|
||||||
|
@ -669,17 +669,15 @@ void load_opts()
|
||||||
kbopt.append(cmdtab[i].cmd);
|
kbopt.append(cmdtab[i].cmd);
|
||||||
|
|
||||||
if (cfg->Read(kbopt, &s) && s.size()) {
|
if (cfg->Read(kbopt, &s) && s.size()) {
|
||||||
wxAcceleratorEntry_v val = wxKeyTextCtrl::FromString(s);
|
wxAcceleratorEntry_v val = wxJoyKeyTextCtrl::ToAccelFromString(s);
|
||||||
|
|
||||||
if (!val.size())
|
if (!val.size())
|
||||||
wxLogWarning(_("Invalid key binding %s for %s"), s.c_str(), kbopt.c_str());
|
wxLogWarning(_("Invalid key binding %s for %s"), s.c_str(), kbopt.c_str());
|
||||||
else {
|
else {
|
||||||
for (size_t j = 0; j < val.size(); j++)
|
for (size_t j = 0; j < val.size(); j++)
|
||||||
val[j].Set(val[j].GetFlags(), val[j].GetKeyCode(),
|
val[j].Set(val[j].GetUkey(), val[j].GetJoystick(), val[j].GetFlags(), val[j].GetKeyCode(), cmdtab[i].cmd_id);
|
||||||
cmdtab[i].cmd_id);
|
|
||||||
|
|
||||||
gopts.accels.insert(gopts.accels.end(),
|
gopts.accels.insert(gopts.accels.end(), val.begin(), val.end());
|
||||||
val.begin(), val.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,7 +761,7 @@ void update_opts()
|
||||||
wxString s, o;
|
wxString s, o;
|
||||||
wxString optname;
|
wxString optname;
|
||||||
optname.Printf(wxT("Joypad/%d/%s"), i + 1, joynames[j].c_str());
|
optname.Printf(wxT("Joypad/%d/%s"), i + 1, joynames[j].c_str());
|
||||||
s = wxJoyKeyTextCtrl::ToString(gopts.joykey_bindings[i][j]);
|
s = wxJoyKeyTextCtrl::ToString(gopts.joykey_bindings[i][j], wxT(','), true);
|
||||||
cfg->Read(optname, &o);
|
cfg->Read(optname, &o);
|
||||||
|
|
||||||
if (o != s)
|
if (o != s)
|
||||||
|
@ -825,7 +823,7 @@ void update_opts()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
wxAcceleratorEntry_v nv(i, j);
|
wxAcceleratorEntry_v nv(i, j);
|
||||||
wxString nvs = wxKeyTextCtrl::ToString(nv);
|
wxString nvs = wxJoyKeyTextCtrl::FromAccelToString(nv, wxT(','), true);
|
||||||
|
|
||||||
if (nvs != cfg->Read(command))
|
if (nvs != cfg->Read(command))
|
||||||
cfg->Write(command, nvs);
|
cfg->Write(command, nvs);
|
||||||
|
@ -953,11 +951,10 @@ bool opt_set(const wxString& name, const wxString& val)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!val.empty()) {
|
if (!val.empty()) {
|
||||||
auto aval = wxKeyTextCtrl::FromString(val);
|
auto aval = wxJoyKeyTextCtrl::ToAccelFromString(val);
|
||||||
|
|
||||||
for (size_t i = 0; i < aval.size(); i++)
|
for (size_t i = 0; i < aval.size(); i++)
|
||||||
aval[i].Set(aval[i].GetFlags(), aval[i].GetKeyCode(),
|
aval[i].Set(aval[i].GetUkey(), aval[i].GetJoystick(), aval[i].GetFlags(), aval[i].GetKeyCode(), cmd->cmd_id);
|
||||||
cmd->cmd_id);
|
|
||||||
|
|
||||||
if (!aval.size())
|
if (!aval.size())
|
||||||
wxLogWarning(_("Invalid key binding %s for %s"), val.c_str(), name.c_str());
|
wxLogWarning(_("Invalid key binding %s for %s"), val.c_str(), name.c_str());
|
||||||
|
|
|
@ -119,7 +119,7 @@ opt_desc new_opt_desc(wxString opt = wxT(""), const char* cmd = NULL, wxString d
|
||||||
|
|
||||||
extern const int num_opts;
|
extern const int num_opts;
|
||||||
|
|
||||||
extern const wxAcceleratorEntry default_accels[];
|
extern const wxAcceleratorEntryUnicode default_accels[];
|
||||||
extern const int num_def_accels;
|
extern const int num_def_accels;
|
||||||
|
|
||||||
// call to setup default keys.
|
// call to setup default keys.
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "wxvbam.h"
|
#include "wxvbam.h"
|
||||||
|
#include "wxutil.h"
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -317,6 +318,7 @@ void GameArea::LoadGame(const wxString& name)
|
||||||
emulating = true;
|
emulating = true;
|
||||||
was_paused = true;
|
was_paused = true;
|
||||||
MainFrame* mf = wxGetApp().frame;
|
MainFrame* mf = wxGetApp().frame;
|
||||||
|
mf->StopPoll();
|
||||||
mf->SetJoystick();
|
mf->SetJoystick();
|
||||||
mf->cmd_enable &= ~(CMDEN_GB | CMDEN_GBA);
|
mf->cmd_enable &= ~(CMDEN_GB | CMDEN_GBA);
|
||||||
mf->cmd_enable |= ONLOAD_CMDEN;
|
mf->cmd_enable |= ONLOAD_CMDEN;
|
||||||
|
@ -567,6 +569,7 @@ void GameArea::UnloadGame(bool destruct)
|
||||||
mf->enable_menus();
|
mf->enable_menus();
|
||||||
mf->SetJoystick();
|
mf->SetJoystick();
|
||||||
mf->ResetCheatSearch();
|
mf->ResetCheatSearch();
|
||||||
|
mf->StartPoll();
|
||||||
|
|
||||||
if (rewind_mem)
|
if (rewind_mem)
|
||||||
num_rewind_states = 0;
|
num_rewind_states = 0;
|
||||||
|
@ -1032,8 +1035,6 @@ void GameArea::OnIdle(wxIdleEvent& event)
|
||||||
wxWindow* w = panel->GetWindow();
|
wxWindow* w = panel->GetWindow();
|
||||||
|
|
||||||
// set up event handlers
|
// set up event handlers
|
||||||
// use both CHAR_HOOK and KEY_DOWN in case CHAR_HOOK does not work for whatever reason
|
|
||||||
w->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(GameArea::OnKeyDown), NULL, this);
|
|
||||||
w->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(GameArea::OnKeyDown), NULL, this);
|
w->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(GameArea::OnKeyDown), NULL, this);
|
||||||
w->Connect(wxEVT_KEY_UP, wxKeyEventHandler(GameArea::OnKeyUp), NULL, this);
|
w->Connect(wxEVT_KEY_UP, wxKeyEventHandler(GameArea::OnKeyUp), NULL, this);
|
||||||
w->Connect(wxEVT_PAINT, wxPaintEventHandler(GameArea::PaintEv), NULL, this);
|
w->Connect(wxEVT_PAINT, wxPaintEventHandler(GameArea::PaintEv), NULL, this);
|
||||||
|
@ -1313,28 +1314,19 @@ static void draw_black_background(wxWindow* win) {
|
||||||
|
|
||||||
void GameArea::OnKeyDown(wxKeyEvent& ev)
|
void GameArea::OnKeyDown(wxKeyEvent& ev)
|
||||||
{
|
{
|
||||||
// check if the key is pressed indeed and then process it
|
int kc = getKeyboardKeyCode(ev);
|
||||||
wxKeyCode keyCode = (wxKeyCode)ev.GetKeyCode();
|
if (process_key_press(true, kc, ev.GetModifiers())) {
|
||||||
if (wxGetKeyState(keyCode) && process_key_press(true, ev.GetKeyCode(), ev.GetModifiers())) {
|
|
||||||
ev.Skip(false);
|
|
||||||
ev.StopPropagation();
|
|
||||||
wxWakeUpIdle();
|
wxWakeUpIdle();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ev.Skip();
|
ev.Skip();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameArea::OnKeyUp(wxKeyEvent& ev)
|
void GameArea::OnKeyUp(wxKeyEvent& ev)
|
||||||
{
|
{
|
||||||
if (process_key_press(false, ev.GetKeyCode(), ev.GetModifiers())) {
|
int kc = getKeyboardKeyCode(ev);
|
||||||
ev.Skip(false);
|
if (process_key_press(false, kc, ev.GetModifiers())) {
|
||||||
ev.StopPropagation();
|
|
||||||
wxWakeUpIdle();
|
wxWakeUpIdle();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ev.Skip();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// these three are forwarded to the DrawingPanel instance
|
// these three are forwarded to the DrawingPanel instance
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
|
|
||||||
// From: https://stackoverflow.com/a/7408245/262458
|
// From: https://stackoverflow.com/a/7408245/262458
|
||||||
//
|
//
|
||||||
|
@ -21,6 +22,25 @@ wxArrayString str_split(const wxString& text, const wxString& sep) {
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxArrayString str_split_with_sep(const wxString& text, const wxString& sep)
|
||||||
|
{
|
||||||
|
wxArrayString tokens;
|
||||||
|
bool sepIsTokenToo = false;
|
||||||
|
wxStringTokenizer tokenizer(text, sep, wxTOKEN_RET_EMPTY_ALL);
|
||||||
|
while (tokenizer.HasMoreTokens()) {
|
||||||
|
wxString token = tokenizer.GetNextToken();
|
||||||
|
if (token.IsEmpty()) {
|
||||||
|
if (!sepIsTokenToo) {
|
||||||
|
sepIsTokenToo = true;
|
||||||
|
tokens.Add(sep);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tokens.Add(token);
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
size_t vec_find(wxArrayString& opts, const wxString& val) {
|
size_t vec_find(wxArrayString& opts, const wxString& val) {
|
||||||
return opts.Index(val);
|
return opts.Index(val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,11 @@
|
||||||
// From: https://stackoverflow.com/a/7408245/262458
|
// From: https://stackoverflow.com/a/7408245/262458
|
||||||
wxArrayString str_split(const wxString& text, const wxString& sep);
|
wxArrayString str_split(const wxString& text, const wxString& sep);
|
||||||
|
|
||||||
|
// Same as above, but it includes the sep dir.
|
||||||
|
// If "A,,,B" is the text and "," is sep, then
|
||||||
|
// 'A', ',' and 'B' will be in the output.
|
||||||
|
wxArrayString str_split_with_sep(const wxString& text, const wxString& sep);
|
||||||
|
|
||||||
// From: https://stackoverflow.com/a/15099743/262458
|
// From: https://stackoverflow.com/a/15099743/262458
|
||||||
size_t vec_find(wxArrayString& opts, const wxString& val);
|
size_t vec_find(wxArrayString& opts, const wxString& val);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "viewsupt.h"
|
#include "viewsupt.h"
|
||||||
#include "../common/ConfigManager.h"
|
#include "../common/ConfigManager.h"
|
||||||
#include "wxvbam.h"
|
#include "wxvbam.h"
|
||||||
|
#include "wxutil.h"
|
||||||
|
|
||||||
namespace Viewers {
|
namespace Viewers {
|
||||||
void Viewer::CloseDlg(wxCloseEvent& ev)
|
void Viewer::CloseDlg(wxCloseEvent& ev)
|
||||||
|
@ -415,7 +416,7 @@ void MemView::ShowCaret()
|
||||||
|
|
||||||
void MemView::KeyEvent(wxKeyEvent& ev)
|
void MemView::KeyEvent(wxKeyEvent& ev)
|
||||||
{
|
{
|
||||||
uint32_t k = ev.GetKeyCode();
|
uint32_t k = getKeyboardKeyCode(ev);
|
||||||
int nnib = 2 << fmt;
|
int nnib = 2 << fmt;
|
||||||
|
|
||||||
switch (k) {
|
switch (k) {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
#include "wx/joyedit.h"
|
#include "wx/joyedit.h"
|
||||||
|
#include "strutils.h"
|
||||||
|
|
||||||
// FIXME: suppport analog/digital flag on per-axis basis
|
// FIXME: suppport analog/digital flag on per-axis basis
|
||||||
|
|
||||||
|
@ -104,10 +106,10 @@ void wxJoyKeyTextCtrl::OnJoy(wxSDLJoyEvent& event)
|
||||||
Navigate();
|
Navigate();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxJoyKeyTextCtrl::ToString(int mod, int key, int joy)
|
wxString wxJoyKeyTextCtrl::ToString(int mod, int key, int joy, bool isConfig)
|
||||||
{
|
{
|
||||||
if (!joy)
|
if (!joy)
|
||||||
return wxKeyTextCtrl::ToString(mod, key);
|
return wxKeyTextCtrl::ToString(mod, key, isConfig);
|
||||||
|
|
||||||
wxString s;
|
wxString s;
|
||||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||||
|
@ -165,7 +167,7 @@ wxString wxJoyKeyTextCtrl::ToString(int mod, int key, int joy)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxJoyKeyTextCtrl::ToString(wxJoyKeyBinding_v keys, wxChar sep)
|
wxString wxJoyKeyTextCtrl::ToString(wxJoyKeyBinding_v keys, wxChar sep, bool isConfig)
|
||||||
{
|
{
|
||||||
wxString ret;
|
wxString ret;
|
||||||
|
|
||||||
|
@ -173,7 +175,26 @@ wxString wxJoyKeyTextCtrl::ToString(wxJoyKeyBinding_v keys, wxChar sep)
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
ret += sep;
|
ret += sep;
|
||||||
|
|
||||||
wxString key = ToString(keys[i].mod, keys[i].key, keys[i].joy);
|
wxString key = ToString(keys[i].mod, keys[i].key, keys[i].joy, isConfig);
|
||||||
|
|
||||||
|
if (key.empty())
|
||||||
|
return wxEmptyString;
|
||||||
|
|
||||||
|
ret += key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxJoyKeyTextCtrl::FromAccelToString(wxAcceleratorEntry_v keys, wxChar sep, bool isConfig)
|
||||||
|
{
|
||||||
|
wxString ret;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < keys.size(); i++) {
|
||||||
|
if (i > 0)
|
||||||
|
ret += sep;
|
||||||
|
|
||||||
|
wxString key = ToString(keys[i].GetFlags(), keys[i].GetKeyCode(), keys[i].GetJoystick(), isConfig);
|
||||||
|
|
||||||
if (key.empty())
|
if (key.empty())
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
|
@ -262,19 +283,16 @@ static bool ParseJoy(const wxString& s, int len, int& mod, int& key, int& joy)
|
||||||
} else if (is_ctrl(hatre)) {
|
} else if (is_ctrl(hatre)) {
|
||||||
hatre.GetMatch(&b, &l, 1);
|
hatre.GetMatch(&b, &l, 1);
|
||||||
key = simple_atoi(p.Mid(b), l);
|
key = simple_atoi(p.Mid(b), l);
|
||||||
#define check_dir(n, d) else if (hatre.GetMatch(&b, &l, n) && l > 0) mod = WXJB_HAT_##d
|
#define check_dir(n, d) if (hatre.GetMatch(&b, &l, n) && l > 0) mod = WXJB_HAT_##d
|
||||||
|
|
||||||
if (0)
|
|
||||||
;
|
|
||||||
|
|
||||||
check_dir(3, N);
|
check_dir(3, N);
|
||||||
check_dir(4, S);
|
else check_dir(4, S);
|
||||||
check_dir(5, E);
|
else check_dir(5, E);
|
||||||
check_dir(6, W);
|
else check_dir(6, W);
|
||||||
check_dir(7, NE);
|
else check_dir(7, NE);
|
||||||
check_dir(8, SE);
|
else check_dir(8, SE);
|
||||||
check_dir(9, SW);
|
else check_dir(9, SW);
|
||||||
check_dir(10, NW);
|
else check_dir(10, NW);
|
||||||
} else {
|
} else {
|
||||||
joy = 0;
|
joy = 0;
|
||||||
return false;
|
return false;
|
||||||
|
@ -300,34 +318,30 @@ wxJoyKeyBinding_v wxJoyKeyTextCtrl::FromString(const wxString& s, wxChar sep)
|
||||||
{
|
{
|
||||||
wxJoyKeyBinding_v ret, empty;
|
wxJoyKeyBinding_v ret, empty;
|
||||||
int mod, key, joy;
|
int mod, key, joy;
|
||||||
size_t len = s.size();
|
if (s.size() == 0)
|
||||||
|
|
||||||
if (!len)
|
|
||||||
return empty;
|
return empty;
|
||||||
|
|
||||||
for (size_t lastkey = len - 1; (lastkey = s.rfind(sep, lastkey)) != wxString::npos; lastkey--) {
|
for (const auto& token : str_split_with_sep(s, sep)) {
|
||||||
if (lastkey == len - 1) {
|
if (!ParseString(token, token.size(), mod, key, joy))
|
||||||
// sep as accel
|
|
||||||
if (!lastkey)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (s[lastkey - 1] == wxT('-') || s[lastkey - 1] == wxT('+') || s[lastkey - 1] == sep)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ParseString(s.Mid(lastkey + 1), len - lastkey - 1, mod, key, joy))
|
|
||||||
return empty;
|
return empty;
|
||||||
|
|
||||||
wxJoyKeyBinding jb = { key, mod, joy };
|
wxJoyKeyBinding jb = { key, mod, joy };
|
||||||
ret.insert(ret.begin(), jb);
|
ret.insert(ret.begin(), jb);
|
||||||
len = lastkey;
|
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ParseString(s, len, mod, key, joy))
|
wxAcceleratorEntry_v wxJoyKeyTextCtrl::ToAccelFromString(const wxString& s, wxChar sep)
|
||||||
|
{
|
||||||
|
wxAcceleratorEntry_v ret, empty;
|
||||||
|
int mod, key, joy;
|
||||||
|
if (s.size() == 0)
|
||||||
return empty;
|
return empty;
|
||||||
|
|
||||||
wxJoyKeyBinding jb = { key, mod, joy };
|
for (const auto& token : str_split_with_sep(s, sep)) {
|
||||||
ret.insert(ret.begin(), jb);
|
if (!ParseString(token, token.size(), mod, key, joy))
|
||||||
|
return empty;
|
||||||
|
ret.insert(ret.begin(), wxAcceleratorEntryUnicode(token, joy, mod, key));
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
#include "wx/keyedit.h"
|
#include "wx/keyedit.h"
|
||||||
|
#include "strutils.h"
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxKeyTextCtrl, wxTextCtrl)
|
IMPLEMENT_DYNAMIC_CLASS(wxKeyTextCtrl, wxTextCtrl)
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxKeyTextCtrl, wxTextCtrl)
|
BEGIN_EVENT_TABLE(wxKeyTextCtrl, wxTextCtrl)
|
||||||
|
// EVT_CHAR is better than EVT_KEY_DOWN here because it is where
|
||||||
|
// the raw key events will have been cooked using whatever recipes
|
||||||
|
// are in effect from the os, locale, international keyboard
|
||||||
|
// settings, etc. But we shouldn't need it for now, otherwise
|
||||||
|
// we would have problems detecting letter cases.
|
||||||
EVT_KEY_DOWN(wxKeyTextCtrl::OnKeyDown)
|
EVT_KEY_DOWN(wxKeyTextCtrl::OnKeyDown)
|
||||||
EVT_KEY_UP(wxKeyTextCtrl::OnKeyUp)
|
EVT_KEY_UP(wxKeyTextCtrl::OnKeyUp)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
@ -11,7 +18,11 @@ END_EVENT_TABLE()
|
||||||
void wxKeyTextCtrl::OnKeyDown(wxKeyEvent& event)
|
void wxKeyTextCtrl::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
lastmod = event.GetModifiers();
|
lastmod = event.GetModifiers();
|
||||||
lastkey = event.GetKeyCode();
|
lastkey = getKeyboardKeyCode(event);
|
||||||
|
if (lastkey != WXK_NONE) // not a control character
|
||||||
|
{
|
||||||
|
KeyboardInputMap::AddMap(ToCandidateString(lastmod, lastkey), lastkey, lastmod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxKeyTextCtrl::OnKeyUp(wxKeyEvent& event)
|
void wxKeyTextCtrl::OnKeyUp(wxKeyEvent& event)
|
||||||
|
@ -47,7 +58,7 @@ void wxKeyTextCtrl::OnKeyUp(wxKeyEvent& event)
|
||||||
} else
|
} else
|
||||||
Clear();
|
Clear();
|
||||||
} else {
|
} else {
|
||||||
wxString nv = ToString(mod, key);
|
wxString nv = ToCandidateString(mod, key);
|
||||||
|
|
||||||
if (nv.empty())
|
if (nv.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -66,18 +77,35 @@ void wxKeyTextCtrl::OnKeyUp(wxKeyEvent& event)
|
||||||
Navigate();
|
Navigate();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxKeyTextCtrl::ToString(int mod, int key)
|
wxString wxKeyTextCtrl::ToString(int mod, int key, bool isConfig)
|
||||||
|
{
|
||||||
|
wxString s = ToCandidateString(mod, key);
|
||||||
|
// Check for unicode char. It is not possible to use it for
|
||||||
|
// wxAcceleratorEntry `FromString`
|
||||||
|
wxLogNull disable_logging;
|
||||||
|
wxAcceleratorEntryUnicode aeTest;
|
||||||
|
if (!aeTest.FromString(s) || !s.IsAscii()) {
|
||||||
|
if (!KeyboardInputMap::GetMap(s, key, mod) || isConfig) {
|
||||||
|
wxString unicodeChar;
|
||||||
|
unicodeChar.Printf("%d:%d", key, mod);
|
||||||
|
return unicodeChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxKeyTextCtrl::ToCandidateString(int mod, int key)
|
||||||
{
|
{
|
||||||
// wx ignores non-alnum printable chars
|
// wx ignores non-alnum printable chars
|
||||||
// actually, wx gives an assertion error, so it's best to filter out
|
// actually, wx gives an assertion error, so it's best to filter out
|
||||||
// before passing to ToString()
|
// before passing to ToString()
|
||||||
bool char_override = key > 32 && key < WXK_START && !wxIsalnum(key);
|
bool char_override = key > 32 && key < WXK_START && !wxIsalnum(key) && key != WXK_DELETE;
|
||||||
// wx also ignores modifiers (and does not report meta at all)
|
// wx also ignores modifiers (and does not report meta at all)
|
||||||
bool mod_override = key == WXK_SHIFT || key == WXK_CONTROL || key == WXK_ALT || key == WXK_RAW_CONTROL;
|
bool mod_override = key == WXK_SHIFT || key == WXK_CONTROL || key == WXK_ALT || key == WXK_RAW_CONTROL;
|
||||||
wxAcceleratorEntry ae(mod, char_override || mod_override ? WXK_F1 : key);
|
wxAcceleratorEntryUnicode ae(mod, char_override || mod_override ? WXK_F1 : key);
|
||||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||||
// So any strings added below must also be translated unconditionally
|
// So any strings added below must also be translated unconditionally
|
||||||
wxString s = ae.ToString();
|
wxString s = ae.ToRawString();
|
||||||
|
|
||||||
if (char_override || mod_override) {
|
if (char_override || mod_override) {
|
||||||
size_t l = s.rfind(wxT('-'));
|
size_t l = s.rfind(wxT('-'));
|
||||||
|
@ -150,11 +178,10 @@ wxString wxKeyTextCtrl::ToString(int mod, int key)
|
||||||
s.Replace(display_name_tr, name_tr, true);
|
s.Replace(display_name_tr, name_tr, true);
|
||||||
s.Replace(display_name, name, true);
|
s.Replace(display_name, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxKeyTextCtrl::ToString(wxAcceleratorEntry_v keys, wxChar sep)
|
wxString wxKeyTextCtrl::ToString(wxAcceleratorEntry_v keys, wxChar sep, bool isConfig)
|
||||||
{
|
{
|
||||||
wxString ret;
|
wxString ret;
|
||||||
|
|
||||||
|
@ -162,7 +189,7 @@ wxString wxKeyTextCtrl::ToString(wxAcceleratorEntry_v keys, wxChar sep)
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
ret += sep;
|
ret += sep;
|
||||||
|
|
||||||
wxString key = ToString(keys[i].GetFlags(), keys[i].GetKeyCode());
|
wxString key = ToString(keys[i].GetFlags(), keys[i].GetKeyCode(), isConfig);
|
||||||
|
|
||||||
if (key.empty())
|
if (key.empty())
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
|
@ -173,6 +200,21 @@ wxString wxKeyTextCtrl::ToString(wxAcceleratorEntry_v keys, wxChar sep)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool checkForPairKeyMod(const wxString& s, int& mod, int& key)
|
||||||
|
{
|
||||||
|
long ulkey, ulmod;
|
||||||
|
// key:mod as pair
|
||||||
|
auto pair = str_split(s, ":");
|
||||||
|
if (pair.size() == 2 && pair[0].ToLong(&ulkey) && pair[1].ToLong(&ulmod))
|
||||||
|
{
|
||||||
|
key = (int)ulkey;
|
||||||
|
mod = (int)ulmod;
|
||||||
|
KeyboardInputMap::AddMap(wxKeyTextCtrl::ToCandidateString(mod, key), key, mod);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxKeyTextCtrl::ParseString(const wxString& s, int len, int& mod, int& key)
|
bool wxKeyTextCtrl::ParseString(const wxString& s, int len, int& mod, int& key)
|
||||||
{
|
{
|
||||||
mod = key = 0;
|
mod = key = 0;
|
||||||
|
@ -180,9 +222,15 @@ bool wxKeyTextCtrl::ParseString(const wxString& s, int len, int& mod, int& key)
|
||||||
if (!s || !len)
|
if (!s || !len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (checkForPairKeyMod(s, mod, key))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (KeyboardInputMap::GetMap(s, key, mod))
|
||||||
|
return true;
|
||||||
|
|
||||||
wxString a = wxT('\t');
|
wxString a = wxT('\t');
|
||||||
a.Append(s.Left(len));
|
a.Append(s.Left(len));
|
||||||
wxAcceleratorEntry ae;
|
wxAcceleratorEntryUnicode ae;
|
||||||
#ifndef __WXMAC__
|
#ifndef __WXMAC__
|
||||||
#define check_meta(str) \
|
#define check_meta(str) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -260,29 +308,12 @@ wxAcceleratorEntry_v wxKeyTextCtrl::FromString(const wxString& s, wxChar sep)
|
||||||
{
|
{
|
||||||
wxAcceleratorEntry_v ret, empty;
|
wxAcceleratorEntry_v ret, empty;
|
||||||
int mod, key;
|
int mod, key;
|
||||||
size_t len = s.size();
|
|
||||||
|
|
||||||
for (size_t lastkey = len - 1; (lastkey = s.rfind(sep, lastkey)) != wxString::npos; lastkey--) {
|
for (const auto& token : str_split_with_sep(s, sep)) {
|
||||||
if (lastkey == len - 1) {
|
if (!ParseString(token, token.size(), mod, key))
|
||||||
// sep as accel
|
|
||||||
if (!lastkey)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (s[lastkey - 1] == wxT('-') || s[lastkey - 1] == wxT('+') || s[lastkey - 1] == sep)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ParseString(s.Mid(lastkey + 1), len - lastkey - 1, mod, key))
|
|
||||||
return empty;
|
return empty;
|
||||||
|
ret.insert(ret.begin(), wxAcceleratorEntryUnicode(mod, key));
|
||||||
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));
|
|
||||||
len = lastkey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ParseString(s, len, mod, key))
|
|
||||||
return empty;
|
|
||||||
|
|
||||||
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,9 @@ public:
|
||||||
// convert wxSDLJoyEvent's type+val into mod (WXJB_*)
|
// convert wxSDLJoyEvent's type+val into mod (WXJB_*)
|
||||||
static int DigitalButton(wxSDLJoyEvent& event);
|
static int DigitalButton(wxSDLJoyEvent& event);
|
||||||
// convert mod+key to accel string, separated by -
|
// convert mod+key to accel string, separated by -
|
||||||
static wxString ToString(int mod, int key, int joy);
|
static wxString ToString(int mod, int key, int joy, bool isConfig = false);
|
||||||
// convert multiple keys, separated by multikey
|
// convert multiple keys, separated by multikey
|
||||||
static wxString ToString(wxJoyKeyBinding_v keys, wxChar sep = wxT(','));
|
static wxString ToString(wxJoyKeyBinding_v keys, wxChar sep = wxT(','), bool isConfig = false);
|
||||||
// parses single key string into mod+key
|
// parses single key string into mod+key
|
||||||
static bool FromString(const wxString& s, int& mod, int& key, int& joy);
|
static bool FromString(const wxString& s, int& mod, int& key, int& joy);
|
||||||
// parse multi-key string into array
|
// parse multi-key string into array
|
||||||
|
@ -61,6 +61,11 @@ public:
|
||||||
static wxJoyKeyBinding_v FromString(const wxString& s, wxChar sep = wxT(','));
|
static wxJoyKeyBinding_v FromString(const wxString& s, wxChar sep = wxT(','));
|
||||||
// parse a single key in given wxChar array up to given len
|
// parse a single key in given wxChar array up to given len
|
||||||
static bool ParseString(const wxString& s, int len, int& mod, int& key, int& joy);
|
static bool ParseString(const wxString& s, int len, int& mod, int& key, int& joy);
|
||||||
|
// parse multi-key string into array
|
||||||
|
// returns empty array on parse errors
|
||||||
|
static wxAcceleratorEntry_v ToAccelFromString(const wxString& s, wxChar sep = wxT(','));
|
||||||
|
// convert multiple keys, separated by multikey
|
||||||
|
static wxString FromAccelToString(wxAcceleratorEntry_v keys, wxChar sep = wxT(','), bool isConfig = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void OnJoy(wxSDLJoyEvent&);
|
void OnJoy(wxSDLJoyEvent&);
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/accel.h>
|
#include <wx/accel.h>
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
|
#include "wxutil.h"
|
||||||
|
|
||||||
typedef std::vector<wxAcceleratorEntry> wxAcceleratorEntry_v;
|
typedef std::vector<wxAcceleratorEntryUnicode> wxAcceleratorEntry_v;
|
||||||
|
|
||||||
class wxKeyTextCtrl : public wxTextCtrl {
|
class wxKeyTextCtrl : public wxTextCtrl {
|
||||||
public:
|
public:
|
||||||
|
@ -51,9 +52,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert mod+key to accel string, separated by -
|
// convert mod+key to accel string, separated by -
|
||||||
static wxString ToString(int mod, int key);
|
static wxString ToString(int mod, int key, bool isConfig = false);
|
||||||
// convert multiple keys, separated by multikey
|
// convert multiple keys, separated by multikey
|
||||||
static wxString ToString(wxAcceleratorEntry_v keys, wxChar sep = wxT(','));
|
static wxString ToString(wxAcceleratorEntry_v keys, wxChar sep = wxT(','), bool isConfig = false);
|
||||||
|
// convert mod+key to candidate accel string, separated by -
|
||||||
|
// this *should* work, but may fail for unicode chars
|
||||||
|
static wxString ToCandidateString(int mod, int key);
|
||||||
// parses single key string into mod+key
|
// parses single key string into mod+key
|
||||||
static bool FromString(const wxString& s, int& mod, int& key);
|
static bool FromString(const wxString& s, int& mod, int& key);
|
||||||
// parse multi-key string into accelentry array
|
// parse multi-key string into accelentry array
|
||||||
|
@ -115,6 +119,7 @@ const struct {
|
||||||
wxString display_name;
|
wxString display_name;
|
||||||
} keys_with_display_names[] = {
|
} keys_with_display_names[] = {
|
||||||
{ WXK_BACK, wxTRANSLATE("Back"), wxTRANSLATE("Backspace") },
|
{ WXK_BACK, wxTRANSLATE("Back"), wxTRANSLATE("Backspace") },
|
||||||
|
{ WXK_DELETE, wxTRANSLATE("Delete"), wxTRANSLATE("Delete") },
|
||||||
{ WXK_PAGEUP, wxTRANSLATE("PageUp"), wxTRANSLATE("Page Up") },
|
{ WXK_PAGEUP, wxTRANSLATE("PageUp"), wxTRANSLATE("Page Up") },
|
||||||
{ WXK_PAGEDOWN, wxTRANSLATE("PageDown"), wxTRANSLATE("Page Down") },
|
{ WXK_PAGEDOWN, wxTRANSLATE("PageDown"), wxTRANSLATE("Page Down") },
|
||||||
{ WXK_NUMLOCK, wxTRANSLATE("Num_lock"), wxTRANSLATE("Num Lock") },
|
{ WXK_NUMLOCK, wxTRANSLATE("Num_lock"), wxTRANSLATE("Num Lock") },
|
||||||
|
|
|
@ -65,8 +65,11 @@
|
||||||
|
|
||||||
#include "wx/keyedit.h"
|
#include "wx/keyedit.h"
|
||||||
|
|
||||||
static inline void DoSetAccel(wxMenuItem* mi, wxAcceleratorEntry* acc)
|
static inline void DoSetAccel(wxMenuItem* mi, wxAcceleratorEntryUnicode* acc)
|
||||||
{
|
{
|
||||||
|
// cannot use SDL keybinding as text without wx assertion error
|
||||||
|
if (!acc || acc->GetJoystick() != 0) return;
|
||||||
|
|
||||||
wxString lab = mi->GetItemLabel();
|
wxString lab = mi->GetItemLabel();
|
||||||
size_t tab = lab.find(wxT('\t'));
|
size_t tab = lab.find(wxT('\t'));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include "wxutil.h"
|
||||||
|
#include "../common/contains.h"
|
||||||
|
|
||||||
|
|
||||||
|
int getKeyboardKeyCode(wxKeyEvent& event)
|
||||||
|
{
|
||||||
|
int uc = event.GetUnicodeKey();
|
||||||
|
if (uc != WXK_NONE) {
|
||||||
|
if (uc < 32)
|
||||||
|
return WXK_NONE;
|
||||||
|
return uc;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return event.GetKeyCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxAcceleratorEntryUnicode::wxAcceleratorEntryUnicode(wxAcceleratorEntry *accel)
|
||||||
|
: wxAcceleratorEntry(accel->GetFlags(), accel->GetKeyCode(), accel->GetCommand(), accel->GetMenuItem())
|
||||||
|
{
|
||||||
|
init(accel->GetFlags(), accel->GetKeyCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxAcceleratorEntryUnicode::wxAcceleratorEntryUnicode(int flags, int keyCode, int cmd, wxMenuItem *item)
|
||||||
|
: wxAcceleratorEntry(flags, keyCode, cmd, item)
|
||||||
|
{
|
||||||
|
init(flags, keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxAcceleratorEntryUnicode::wxAcceleratorEntryUnicode(wxString uKey, int joy, int flags, int keyCode, int cmd, wxMenuItem *item)
|
||||||
|
: wxAcceleratorEntry(flags, keyCode, cmd, item)
|
||||||
|
{
|
||||||
|
ukey = uKey;
|
||||||
|
joystick = joy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wxAcceleratorEntryUnicode::Set(wxString uKey, int joy, int flags, int keyCode, int cmd, wxMenuItem *item)
|
||||||
|
{
|
||||||
|
ukey = uKey;
|
||||||
|
joystick = joy;
|
||||||
|
wxAcceleratorEntry::Set(flags, keyCode, cmd, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wxAcceleratorEntryUnicode::init(int flags, int keyCode)
|
||||||
|
{
|
||||||
|
joystick = 0;
|
||||||
|
if (!(flags == 0 && keyCode == 0)) {
|
||||||
|
ukey.Printf("%d:%d", keyCode, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardInputMap* KeyboardInputMap::getInstance()
|
||||||
|
{
|
||||||
|
static KeyboardInputMap instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardInputMap::KeyboardInputMap(){}
|
||||||
|
|
||||||
|
|
||||||
|
void KeyboardInputMap::AddMap(wxString keyStr, int key, int mod)
|
||||||
|
{
|
||||||
|
KeyboardInputMap* singleton = getInstance();
|
||||||
|
singleton->keysMap[keyStr.wc_str()] = singleton->newPair(key, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool KeyboardInputMap::GetMap(wxString keyStr, int &key, int &mod)
|
||||||
|
{
|
||||||
|
KeyboardInputMap* singleton = getInstance();
|
||||||
|
if (contains(singleton->keysMap, keyStr.wc_str())) {
|
||||||
|
key = singleton->keysMap.at(keyStr.wc_str()).key;
|
||||||
|
mod = singleton->keysMap.at(keyStr.wc_str()).mod;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef _WX_UTIL_H
|
||||||
|
#define _WX_UTIL_H
|
||||||
|
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
|
int getKeyboardKeyCode(wxKeyEvent& event);
|
||||||
|
|
||||||
|
#include <wx/accel.h>
|
||||||
|
|
||||||
|
class wxAcceleratorEntryUnicode : public wxAcceleratorEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxAcceleratorEntryUnicode(wxAcceleratorEntry *accel);
|
||||||
|
wxAcceleratorEntryUnicode(int flags=0, int keyCode=0, int cmd=0, wxMenuItem *item=nullptr);
|
||||||
|
wxAcceleratorEntryUnicode(wxString uKey, int joy=0, int flags=0, int keyCode=0, int cmd=0, wxMenuItem *item=nullptr);
|
||||||
|
|
||||||
|
void Set(wxString uKey, int joy, int flags, int keyCode, int cmd, wxMenuItem *item=nullptr);
|
||||||
|
|
||||||
|
int GetJoystick() const { return joystick; };
|
||||||
|
wxString GetUkey() const { return ukey; };
|
||||||
|
private:
|
||||||
|
void init(int flags, int keyCode);
|
||||||
|
wxString ukey;
|
||||||
|
int joystick;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include "widgets/wx/keyedit.h"
|
||||||
|
|
||||||
|
class KeyboardInputMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static KeyboardInputMap* getInstance();
|
||||||
|
static void AddMap(wxString keyStr, int key, int mod);
|
||||||
|
static bool GetMap(wxString keyStr, int &key, int &mod);
|
||||||
|
private:
|
||||||
|
KeyboardInputMap();
|
||||||
|
|
||||||
|
// We want to keep track of this pair for
|
||||||
|
// almost all keypresses.
|
||||||
|
typedef struct KeyMod {
|
||||||
|
int key;
|
||||||
|
int mod;
|
||||||
|
} KeyMod;
|
||||||
|
|
||||||
|
KeyMod newPair(int key, int mod)
|
||||||
|
{
|
||||||
|
KeyMod tmp;
|
||||||
|
tmp.key = key;
|
||||||
|
tmp.mod = mod;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map accel string to pair
|
||||||
|
std::unordered_map<std::wstring, KeyMod> keysMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -720,6 +720,8 @@ MainFrame::MainFrame()
|
||||||
, dialog_opened(0)
|
, dialog_opened(0)
|
||||||
, focused(false)
|
, focused(false)
|
||||||
{
|
{
|
||||||
|
jpoll = new JoystickPoller();
|
||||||
|
this->Connect(wxID_ANY, wxEVT_SHOW, wxShowEventHandler(JoystickPoller::ShowDialog), jpoll, jpoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainFrame::~MainFrame()
|
MainFrame::~MainFrame()
|
||||||
|
@ -846,7 +848,7 @@ int MainFrame::FilterEvent(wxEvent& event)
|
||||||
if (event.GetEventType() == wxEVT_KEY_DOWN && !menus_opened && !dialog_opened)
|
if (event.GetEventType() == wxEVT_KEY_DOWN && !menus_opened && !dialog_opened)
|
||||||
{
|
{
|
||||||
wxKeyEvent& ke = (wxKeyEvent&)event;
|
wxKeyEvent& ke = (wxKeyEvent&)event;
|
||||||
int keyCode = ke.GetKeyCode();
|
int keyCode = getKeyboardKeyCode(ke);
|
||||||
int keyMod = ke.GetModifiers();
|
int keyMod = ke.GetModifiers();
|
||||||
wxAcceleratorEntry_v accels = wxGetApp().GetAccels();
|
wxAcceleratorEntry_v accels = wxGetApp().GetAccels();
|
||||||
for (size_t i = 0; i < accels.size(); ++i)
|
for (size_t i = 0; i < accels.size(); ++i)
|
||||||
|
@ -858,6 +860,25 @@ int MainFrame::FilterEvent(wxEvent& event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event.GetEventType() == wxEVT_SDLJOY && !menus_opened && !dialog_opened)
|
||||||
|
{
|
||||||
|
wxSDLJoyEvent& je = (wxSDLJoyEvent&)event;
|
||||||
|
if (je.GetControlValue() == 0) return -1; // joystick button UP
|
||||||
|
int key = je.GetControlIndex();
|
||||||
|
int mod = wxJoyKeyTextCtrl::DigitalButton(je);
|
||||||
|
int joy = je.GetJoy() + 1;
|
||||||
|
wxString label = wxJoyKeyTextCtrl::ToString(mod, key, joy);
|
||||||
|
wxAcceleratorEntry_v accels = wxGetApp().GetAccels();
|
||||||
|
for (size_t i = 0; i < accels.size(); ++i) {
|
||||||
|
if (label == accels[i].GetUkey())
|
||||||
|
{
|
||||||
|
wxCommandEvent evh(wxEVT_COMMAND_MENU_SELECTED, accels[i].GetCommand());
|
||||||
|
evh.SetEventObject(this);
|
||||||
|
GetEventHandler()->ProcessEvent(evh);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,31 +907,39 @@ wxString MainFrame::GetGamePath(wxString path)
|
||||||
|
|
||||||
void MainFrame::SetJoystick()
|
void MainFrame::SetJoystick()
|
||||||
{
|
{
|
||||||
bool anyjoy = false;
|
/* Remove all attached joysticks to avoid errors while
|
||||||
|
* destroying and creating the GameArea `panel`. */
|
||||||
joy.Remove();
|
joy.Remove();
|
||||||
|
|
||||||
|
set_global_accels();
|
||||||
|
|
||||||
if (!emulating)
|
if (!emulating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
for (int j = 0; j < NUM_KEYS; j++) {
|
for (int j = 0; j < NUM_KEYS; j++) {
|
||||||
wxJoyKeyBinding_v b = gopts.joykey_bindings[i][j];
|
wxJoyKeyBinding_v b = gopts.joykey_bindings[i][j];
|
||||||
|
|
||||||
for (size_t k = 0; k < b.size(); k++) {
|
for (size_t k = 0; k < b.size(); k++) {
|
||||||
int jn = b[k].joy;
|
int jn = b[k].joy;
|
||||||
|
|
||||||
if (jn) {
|
if (jn) {
|
||||||
if (!anyjoy) {
|
|
||||||
anyjoy = true;
|
|
||||||
joy.Attach(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
joy.Add(jn - 1);
|
joy.Add(jn - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainFrame::StopPoll()
|
||||||
|
{
|
||||||
|
if (jpoll && jpoll->IsRunning())
|
||||||
|
jpoll->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainFrame::StartPoll()
|
||||||
|
{
|
||||||
|
if (jpoll && !jpoll->IsRunning())
|
||||||
|
jpoll->Start();
|
||||||
|
}
|
||||||
|
|
||||||
void MainFrame::enable_menus()
|
void MainFrame::enable_menus()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ncmds; i++)
|
for (int i = 0; i < ncmds; i++)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "../gba/Sound.h"
|
#include "../gba/Sound.h"
|
||||||
|
|
||||||
#include "wxlogdebug.h"
|
#include "wxlogdebug.h"
|
||||||
|
#include "wxutil.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void CheckPointer(T pointer)
|
void CheckPointer(T pointer)
|
||||||
|
@ -203,6 +204,8 @@ class GameArea;
|
||||||
|
|
||||||
class LogDialog;
|
class LogDialog;
|
||||||
|
|
||||||
|
class JoystickPoller;
|
||||||
|
|
||||||
// true if pause should happen at next frame
|
// true if pause should happen at next frame
|
||||||
extern bool pause_next;
|
extern bool pause_next;
|
||||||
|
|
||||||
|
@ -320,6 +323,10 @@ public:
|
||||||
|
|
||||||
void PollJoysticks() { joy.Poll(); }
|
void PollJoysticks() { joy.Poll(); }
|
||||||
|
|
||||||
|
// poll joysticks with timer
|
||||||
|
void StopPoll();
|
||||||
|
void StartPoll();
|
||||||
|
|
||||||
// required for building from xrc
|
// required for building from xrc
|
||||||
DECLARE_DYNAMIC_CLASS(MainFrame);
|
DECLARE_DYNAMIC_CLASS(MainFrame);
|
||||||
// required for event handling
|
// required for event handling
|
||||||
|
@ -345,9 +352,10 @@ private:
|
||||||
checkable_mi_array_t checkable_mi;
|
checkable_mi_array_t checkable_mi;
|
||||||
// recent menu item accels
|
// recent menu item accels
|
||||||
wxMenu* recent;
|
wxMenu* recent;
|
||||||
wxAcceleratorEntry recent_accel[10];
|
wxAcceleratorEntryUnicode recent_accel[10];
|
||||||
// joystick reader
|
// joystick reader
|
||||||
wxSDLJoy joy;
|
wxSDLJoy joy;
|
||||||
|
JoystickPoller* jpoll = nullptr;
|
||||||
|
|
||||||
// helper function for adding menu to accel editor
|
// helper function for adding menu to accel editor
|
||||||
void add_menu_accels(wxTreeCtrl* tc, wxTreeItemId& parent, wxMenu* menu);
|
void add_menu_accels(wxTreeCtrl* tc, wxTreeItemId& parent, wxMenu* menu);
|
||||||
|
@ -383,6 +391,20 @@ private:
|
||||||
double hidpi_scale_factor;
|
double hidpi_scale_factor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// a class for polling joystick keys
|
||||||
|
class JoystickPoller : public wxTimer {
|
||||||
|
public:
|
||||||
|
void Notify() {
|
||||||
|
wxGetApp().frame->PollJoysticks();
|
||||||
|
}
|
||||||
|
void ShowDialog(wxShowEvent& ev) {
|
||||||
|
if (ev.IsShown())
|
||||||
|
Start(50);
|
||||||
|
else
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// a helper class to avoid forgetting StopModal()
|
// a helper class to avoid forgetting StopModal()
|
||||||
class ModalPause {
|
class ModalPause {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
<border>5</border>
|
<border>5</border>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxTextCtrl" name="Shortcut" subclass="wxKeyTextCtrl">
|
<object class="wxTextCtrl" name="Shortcut" subclass="wxJoyKeyTextCtrl">
|
||||||
<style>wxTE_PROCESS_ENTER|wxTE_PROCESS_TAB</style>
|
<style>wxTE_PROCESS_ENTER|wxTE_PROCESS_TAB</style>
|
||||||
</object>
|
</object>
|
||||||
<flag>wxALL|wxEXPAND</flag>
|
<flag>wxALL|wxEXPAND</flag>
|
||||||
|
|
Loading…
Reference in New Issue