restore wx 2.8 compat, improve string processing

Fix building with wx 2.8 by rewriting some more string related code.

Replace all calls to .c_str() with .mb_str().

Remove some of the .c_str()/.mb_str() calls where the target is already
wxString.

Move the split()/enum_idx() functions from opts.cpp into
str_split()/vec_find() in strutils.h/strutils.cpp for use in other
files.

Replace the C-style string parsing code in a couple of places in
wxvbam.cpp for processing possible command line options by splitting on
'='.

Also replace a couple of places that use pointer arithmetic in
widgets/joyedit.cpp and widgets/keyedit.cpp with wxString methods.
This commit is contained in:
Rafael Kitover 2017-09-13 05:32:44 -07:00
parent fa9afa4e18
commit 02b3defcd0
14 changed files with 163 additions and 145 deletions

View File

@ -54,7 +54,7 @@ And the following development libraries:
- [SDL](https://www.libsdl.org/)2 (required) - [SDL](https://www.libsdl.org/)2 (required)
- [SFML](https://www.sfml-dev.org/) (optional, for link) - [SFML](https://www.sfml-dev.org/) (optional, for link)
- OpenAL (optional, a sound interface) - OpenAL (optional, a sound interface)
- [wxWidgets](https://wxwidgets.org/) (required, 2.8 is still supported) - [wxWidgets](https://wxwidgets.org/) (required, 2.8 is still supported, --enable-stl is supported)
On Linux and similar, you also need the version of GTK your wxWidgets is linked On Linux and similar, you also need the version of GTK your wxWidgets is linked
to (usually 2 or 3). to (usually 2 or 3).

View File

@ -422,6 +422,7 @@ SET( SRC_WX
panel.cpp panel.cpp
viewsupt.cpp viewsupt.cpp
wayland.cpp wayland.cpp
strutils.cpp
widgets/keyedit.cpp widgets/keyedit.cpp
widgets/joyedit.cpp widgets/joyedit.cpp
widgets/sdljoy.cpp widgets/sdljoy.cpp

View File

@ -547,7 +547,7 @@ EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB | CMDEN_GBA)
s.Printf(wxT("%02x"), gbRom[0x14b]); s.Printf(wxT("%02x"), gbRom[0x14b]);
setlab("MakerCode"); setlab("MakerCode");
const rom_maker m = { s.c_str() }, *rm; const rom_maker m = { s }, *rm;
rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt); rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt);
if (rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code)) if (rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code))
@ -775,7 +775,7 @@ EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB | CMDEN_GBA)
SetDialogLabel(dlg, wxT("CRC32"), rom_crc32, 8); SetDialogLabel(dlg, wxT("CRC32"), rom_crc32, 8);
setlabs("GameCode", rom[0xac], 4); setlabs("GameCode", rom[0xac], 4);
setlabs("MakerCode", rom[0xb0], 2); setlabs("MakerCode", rom[0xb0], 2);
const rom_maker m = { s.c_str() }, *rm; const rom_maker m = { s }, *rm;
rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt); rm = std::lower_bound(&makers[0], &makers[num_makers], m, maker_lt);
if (rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code)) if (rm < &makers[num_makers] && !wxStrcmp(m.code, rm->code))
@ -864,9 +864,9 @@ EVT_HANDLER_MASK(ImportBatteryFile, "Import battery file...", CMDEN_GB | CMDEN_G
wxString msg; wxString msg;
if (panel->emusys->emuReadBattery(fn.mb_fn_str())) if (panel->emusys->emuReadBattery(fn.mb_fn_str()))
msg.Printf(_("Loaded battery %s"), fn.c_str()); msg.Printf(_("Loaded battery %s"), fn.mb_str());
else else
msg.Printf(_("Error loading battery %s"), fn.c_str()); msg.Printf(_("Error loading battery %s"), fn.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -902,7 +902,7 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN
wxFFile f(fn, wxT("rb")); wxFFile f(fn, wxT("rb"));
if (!f.IsOpened()) { if (!f.IsOpened()) {
wxLogError(_("Cannot open file %s"), fn.c_str()); wxLogError(_("Cannot open file %s"), fn.mb_str());
return; return;
} }
@ -912,7 +912,7 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN
char buf[14]; char buf[14];
if (f.Read(&len, sizeof(len)) != sizeof(len) || wxUINT32_SWAP_ON_BE(len) != 14 || f.Read(buf, 14) != 14 || memcmp(buf, "SharkPortCODES", 14)) { if (f.Read(&len, sizeof(len)) != sizeof(len) || wxUINT32_SWAP_ON_BE(len) != 14 || f.Read(buf, 14) != 14 || memcmp(buf, "SharkPortCODES", 14)) {
wxLogError(_("Unsupported code file %s"), fn.c_str()); wxLogError(_("Unsupported code file %s"), fn.mb_str());
return; return;
} }
@ -982,9 +982,9 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN
} }
if (res) if (res)
msg.Printf(_("Loaded code file %s"), fn.c_str()); msg.Printf(_("Loaded code file %s"), fn.mb_str());
else else
msg.Printf(_("Error loading code file %s"), fn.c_str()); msg.Printf(_("Error loading code file %s"), fn.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -1030,9 +1030,9 @@ EVT_HANDLER_MASK(ImportGamesharkActionReplaySnapshot,
} }
if (res) if (res)
msg.Printf(_("Loaded snapshot file %s"), fn.c_str()); msg.Printf(_("Loaded snapshot file %s"), fn.mb_str());
else else
msg.Printf(_("Error loading snapshot file %s"), fn.c_str()); msg.Printf(_("Error loading snapshot file %s"), fn.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -1055,9 +1055,9 @@ EVT_HANDLER_MASK(ExportBatteryFile, "Export battery file...", CMDEN_GB | CMDEN_G
wxString msg; wxString msg;
if (panel->emusys->emuWriteBattery(fn.mb_fn_str())) if (panel->emusys->emuWriteBattery(fn.mb_fn_str()))
msg.Printf(_("Wrote battery %s"), fn.c_str()); msg.Printf(_("Wrote battery %s"), fn.mb_str());
else else
msg.Printf(_("Error writing battery %s"), fn.c_str()); msg.Printf(_("Error writing battery %s"), fn.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -1096,11 +1096,11 @@ EVT_HANDLER_MASK(ExportGamesharkSnapshot, "Export GameShark snapshot...", CMDEN_
// FIXME: this will fail on big-endian machines if file format is // FIXME: this will fail on big-endian machines if file format is
// little-endian // little-endian
// fix in GBA.cpp // fix in GBA.cpp
if (CPUWriteGSASnapshot(fn.mb_fn_str(), tit->GetValue().utf8_str(), if (CPUWriteGSASnapshot(fn.mb_str(), tit->GetValue().mb_str(),
dsc->GetValue().utf8_str(), n->GetValue().utf8_str())) dsc->GetValue().mb_str(), n->GetValue().mb_str()))
msg.Printf(_("Saved snapshot file %s"), fn.c_str()); msg.Printf(_("Saved snapshot file %s"), fn.mb_str());
else else
msg.Printf(_("Error saving snapshot file %s"), fn.c_str()); msg.Printf(_("Error saving snapshot file %s"), fn.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -1140,7 +1140,7 @@ EVT_HANDLER_MASK(ScreenCapture, "Screen capture...", CMDEN_GB | CMDEN_GBA)
panel->emusys->emuWriteBMP(fn.mb_fn_str()); panel->emusys->emuWriteBMP(fn.mb_fn_str());
wxString msg; wxString msg;
msg.Printf(_("Wrote snapshot %s"), fn.c_str()); msg.Printf(_("Wrote snapshot %s"), fn.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -1936,7 +1936,7 @@ void MainFrame::GDBBreak()
if (!debugOpenPty()) if (!debugOpenPty())
return; return;
msg.Printf(_("Waiting for connection at %s"), debugGetSlavePty().c_str()); msg.Printf(_("Waiting for connection at %s"), debugGetSlavePty().mb_str());
} else } else
#endif #endif
{ {

View File

@ -110,10 +110,10 @@ public:
char host[length]; char host[length];
GetLinkServerHost(host, length); GetLinkServerHost(host, length);
title.Printf(_("Waiting for clients...")); title.Printf(_("Waiting for clients..."));
connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).c_str()); connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).mb_str());
} else { } else {
title.Printf(_("Waiting for connection...")); title.Printf(_("Waiting for connection..."));
connmsg.Printf(_("Connecting to %s\n"), gopts.link_host.c_str()); connmsg.Printf(_("Connecting to %s\n"), gopts.link_host.mb_str());
} }
// Init link // Init link
@ -1802,7 +1802,7 @@ public:
// to put the plugins... it depends on where program was // to put the plugins... it depends on where program was
// installed, and of course OS // installed, and of course OS
wxString msg; wxString msg;
msg.Printf(_("No usable rpi plugins found in %s"), plpath.c_str()); msg.Printf(_("No usable rpi plugins found in %s"), plpath.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
ch->Hide(); ch->Hide();
txt->Hide(); txt->Hide();
@ -2298,7 +2298,7 @@ void CheckThrowXRCError(T pointer, const wxString& name)
std::string errormessage = "Unable to load a \""; std::string errormessage = "Unable to load a \"";
errormessage += typeid(pointer).name(); errormessage += typeid(pointer).name();
errormessage += "\" from the builtin xrc file: "; errormessage += "\" from the builtin xrc file: ";
errormessage += name.utf8_str(); errormessage += name.mb_str();
throw std::runtime_error(errormessage); throw std::runtime_error(errormessage);
} }
} }
@ -2661,9 +2661,9 @@ bool MainFrame::BindControls()
if (a->GetFlags() == e->GetFlags() && a->GetKeyCode() == e->GetKeyCode()) { if (a->GetFlags() == e->GetFlags() && a->GetKeyCode() == e->GetKeyCode()) {
if (e->GetMenuItem()) { if (e->GetMenuItem()) {
wxLogInfo(_("Duplicate menu accelerator: %s for %s and %s; keeping first"), wxLogInfo(_("Duplicate menu accelerator: %s for %s and %s; keeping first"),
wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(), wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).mb_str(),
e->GetMenuItem()->GetItemLabelText().c_str(), e->GetMenuItem()->GetItemLabelText().mb_str(),
mi->GetItemLabelText().c_str()); mi->GetItemLabelText().mb_str());
delete a; delete a;
a = 0; a = 0;
} else { } else {
@ -2675,8 +2675,8 @@ bool MainFrame::BindControls()
break; break;
wxLogInfo(_("Menu accelerator %s for %s overrides default for %s ; keeping menu"), wxLogInfo(_("Menu accelerator %s for %s overrides default for %s ; keeping menu"),
wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(), wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).mb_str(),
mi->GetItemLabelText().c_str(), mi->GetItemLabelText().mb_str(),
cmdtab[cmd].cmd); cmdtab[cmd].cmd);
} }
@ -2781,7 +2781,7 @@ bool MainFrame::BindControls()
for (int i = 0; i < checkable_mi.size(); i++) for (int i = 0; i < checkable_mi.size(); i++)
if (!checkable_mi[i].boolopt && !checkable_mi[i].intopt) { if (!checkable_mi[i].boolopt && !checkable_mi[i].intopt) {
wxLogError(_("Invalid menu item %s; removing"), wxLogError(_("Invalid menu item %s; removing"),
checkable_mi[i].mi->GetItemLabelText().c_str()); checkable_mi[i].mi->GetItemLabelText().mb_str());
checkable_mi[i].mi->GetMenu()->Remove(checkable_mi[i].mi); checkable_mi[i].mi->GetMenu()->Remove(checkable_mi[i].mi);
checkable_mi[i].mi = NULL; checkable_mi[i].mi = NULL;
} }

View File

@ -1,9 +1,8 @@
#include "../common/ConfigManager.h" #include "../common/ConfigManager.h"
#include "wxvbam.h" #include "wxvbam.h"
#include <algorithm> #include <algorithm>
#include <string>
#include <vector>
#include <wx/display.h> #include <wx/display.h>
#include "strutils.h"
/* /*
disableSfx(F) -> cpuDisableSfx disableSfx(F) -> cpuDisableSfx
@ -21,15 +20,15 @@
} }
#define INTOPT(c, n, d, v, min, max) \ #define INTOPT(c, n, d, v, min, max) \
{ \ { \
wxT(c), (n), d, NULL, &v, "", min, max \ wxT(c), (n), d, NULL, &v, wxT(""), min, max \
} }
#define DOUBLEOPT(c, n, d, v, min, max) \ #define DOUBLEOPT(c, n, d, v, min, max) \
{ \ { \
wxT(c), (n), d, NULL, NULL, "", min, max, NULL, &v \ wxT(c), (n), d, NULL, NULL, wxT(""), min, max, NULL, &v \
} }
#define BOOLOPT(c, n, d, v) \ #define BOOLOPT(c, n, d, v) \
{ \ { \
wxT(c), (n), d, NULL, NULL, "", 0, 0, &v \ wxT(c), (n), d, NULL, NULL, wxT(""), 0, 0, &v \
} }
#define ENUMOPT(c, n, d, v, e) \ #define ENUMOPT(c, n, d, v, e) \
{ \ { \
@ -333,31 +332,6 @@ bool opt_lt(const opt_desc& opt1, const opt_desc& opt2)
return wxStrcmp(opt1.opt, opt2.opt) < 0; return wxStrcmp(opt1.opt, opt2.opt) < 0;
} }
// From: https://stackoverflow.com/a/7408245/262458
static std::vector<wxString> split(const wxString& text_, const wxString& sep_) {
std::vector<wxString> tokens;
std::size_t start = 0, end = 0;
std::string text = text_.ToStdString(), sep = sep_.ToStdString();
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
static std::size_t enum_idx(std::vector<wxString>& opts, const wxString& val) {
auto it = std::find(opts.begin(), opts.end(), val);
if (it == opts.end())
return wxNOT_FOUND;
return std::distance(opts.begin(), it);
}
// FIXME: simulate MakeInstanceFilename(vbam.ini) using subkeys (Slave%d/*) // FIXME: simulate MakeInstanceFilename(vbam.ini) using subkeys (Slave%d/*)
void load_opts() void load_opts()
@ -389,7 +363,7 @@ void load_opts()
for (cont = cfg->GetFirstEntry(s, grp_idx); cont; for (cont = cfg->GetFirstEntry(s, grp_idx); cont;
cont = cfg->GetNextEntry(s, grp_idx)) { cont = cfg->GetNextEntry(s, grp_idx)) {
//wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str()); //wxLogWarning(_("Invalid option %s present; removing if possible"), s.mb_str());
item_del.push_back(s); item_del.push_back(s);
} }
@ -427,7 +401,7 @@ void load_opts()
for (cont = cfg->GetFirstGroup(e, key_idx); cont; for (cont = cfg->GetFirstGroup(e, key_idx); cont;
cont = cfg->GetNextGroup(e, key_idx)) { cont = cfg->GetNextGroup(e, key_idx)) {
s.append(e); s.append(e);
//wxLogWarning(_("Invalid option group %s present; removing if possible"), s.c_str()); //wxLogWarning(_("Invalid option group %s present; removing if possible"), s.mb_str());
grp_del.push_back(s); grp_del.push_back(s);
s.resize(poff2); s.resize(poff2);
} }
@ -442,7 +416,7 @@ void load_opts()
if (i == NUM_KEYS) { if (i == NUM_KEYS) {
s.append(e); s.append(e);
//wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str()); //wxLogWarning(_("Invalid option %s present; removing if possible"), s.mb_str());
item_del.push_back(s); item_del.push_back(s);
s.resize(poff2); s.resize(poff2);
} }
@ -454,7 +428,7 @@ void load_opts()
} else { } else {
s.append(wxT('/')); s.append(wxT('/'));
s.append(e); s.append(e);
//wxLogWarning(_("Invalid option group %s present; removing if possible"), s.c_str()); //wxLogWarning(_("Invalid option group %s present; removing if possible"), s.mb_str());
grp_del.push_back(s); grp_del.push_back(s);
s.resize(poff); s.resize(poff);
} }
@ -464,23 +438,23 @@ void load_opts()
cont = cfg->GetNextEntry(e, entry_idx)) { cont = cfg->GetNextEntry(e, entry_idx)) {
// kb options come from a different list // kb options come from a different list
if (s == wxT("Keyboard")) { if (s == wxT("Keyboard")) {
const cmditem dummy = { e.c_str() }; const cmditem dummy = { e };
if (!std::binary_search(&cmdtab[0], &cmdtab[ncmds], dummy, cmditem_lt)) { if (!std::binary_search(&cmdtab[0], &cmdtab[ncmds], dummy, cmditem_lt)) {
s.append(wxT('/')); s.append(wxT('/'));
s.append(e); s.append(e);
//wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str()); //wxLogWarning(_("Invalid option %s present; removing if possible"), s.mb_str());
item_del.push_back(s); item_del.push_back(s);
s.resize(poff); s.resize(poff);
} }
} else { } else {
s.append(wxT('/')); s.append(wxT('/'));
s.append(e); s.append(e);
const opt_desc dummy = { s.c_str() }; const opt_desc dummy = { s };
wxString opt_name(dummy.opt); wxString opt_name(dummy.opt);
if (!std::binary_search(&opts[0], &opts[num_opts], dummy, opt_lt) && opt_name != wxT("General/LastUpdated") && opt_name != wxT("General/LastUpdatedFileName")) { if (!std::binary_search(&opts[0], &opts[num_opts], dummy, opt_lt) && opt_name != wxT("General/LastUpdated") && opt_name != wxT("General/LastUpdatedFileName")) {
//wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str()); //wxLogWarning(_("Invalid option %s present; removing if possible"), s.mb_str());
item_del.push_back(s); item_del.push_back(s);
} }
@ -507,13 +481,13 @@ void load_opts()
if (opt.stropt) { if (opt.stropt) {
opt.curstr = *opt.stropt; opt.curstr = *opt.stropt;
} else if (!opt.enumvals.empty()) { } else if (!opt.enumvals.empty()) {
auto enum_opts = split(opt.enumvals.MakeLower(), wxT("|")); auto enum_opts = str_split(opt.enumvals.MakeLower(), wxT("|"));
opt.curint = *opt.intopt; opt.curint = *opt.intopt;
bool gotit = cfg->Read(opt.opt, &s); s.MakeLower(); bool gotit = cfg->Read(opt.opt, &s); s.MakeLower();
if (gotit && !s.empty()) { if (gotit && !s.empty()) {
const std::size_t found_pos = enum_idx(enum_opts, s); const auto found_pos = vec_find(enum_opts, s);
const bool matched = found_pos != wxNOT_FOUND; const bool matched = found_pos != wxNOT_FOUND;
if (!matched) { if (!matched) {
opt.curint = 0; opt.curint = 0;
@ -560,7 +534,7 @@ void load_opts()
wxString optn; wxString optn;
optn.Printf(wxT("GB/Palette%d"), i); optn.Printf(wxT("GB/Palette%d"), i);
wxString val; wxString val;
const opt_desc dummy = { optn.c_str() }; const opt_desc dummy = { optn };
opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt); opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
wxString entry; wxString entry;
@ -605,7 +579,7 @@ void load_opts()
gopts.joykey_bindings[i][j] = wxJoyKeyTextCtrl::FromString(s); gopts.joykey_bindings[i][j] = wxJoyKeyTextCtrl::FromString(s);
if (s.size() && !gopts.joykey_bindings[i][j].size()) if (s.size() && !gopts.joykey_bindings[i][j].size())
wxLogWarning(_("Invalid key binding %s for %s"), s.c_str(), optname.c_str()); wxLogWarning(_("Invalid key binding %s for %s"), s.mb_str(), optname.mb_str());
} else { } else {
s = wxJoyKeyTextCtrl::ToString(gopts.joykey_bindings[i][j]); s = wxJoyKeyTextCtrl::ToString(gopts.joykey_bindings[i][j]);
cfg->Write(optname, s); cfg->Write(optname, s);
@ -626,7 +600,7 @@ void load_opts()
wxAcceleratorEntry_v val = wxKeyTextCtrl::FromString(s); wxAcceleratorEntry_v val = wxKeyTextCtrl::FromString(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.mb_str(), kbopt.mb_str());
else { else {
for (int j = 0; j < val.size(); j++) for (int j = 0; j < val.size(); j++)
val[j].Set(val[j].GetFlags(), val[j].GetKeyCode(), val[j].Set(val[j].GetFlags(), val[j].GetKeyCode(),
@ -662,7 +636,7 @@ void update_opts()
} else if (!opt.enumvals.empty()) { } else if (!opt.enumvals.empty()) {
if (*opt.intopt != opt.curint) { if (*opt.intopt != opt.curint) {
opt.curint = *opt.intopt; opt.curint = *opt.intopt;
auto enum_opts = split(opt.enumvals.MakeLower(), wxT("|")); auto enum_opts = str_split(opt.enumvals.MakeLower(), wxT("|"));
cfg->Write(opt.opt, enum_opts[opt.curint]); cfg->Write(opt.opt, enum_opts[opt.curint]);
} }
@ -683,7 +657,7 @@ void update_opts()
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
wxString optn; wxString optn;
optn.Printf(wxT("GB/Palette%d"), i); optn.Printf(wxT("GB/Palette%d"), i);
const opt_desc dummy = { optn.c_str() }; const opt_desc dummy = { optn };
opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt); opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
wxString val; wxString val;
wxString entry; wxString entry;
@ -727,7 +701,7 @@ void update_opts()
for (bool cont = cfg->GetFirstEntry(s, entry_idx); cont; for (bool cont = cfg->GetFirstEntry(s, entry_idx); cont;
cont = cfg->GetNextEntry(s, entry_idx)) { cont = cfg->GetNextEntry(s, entry_idx)) {
const cmditem dummy = { s.c_str() }; const cmditem dummy = { s };
cmditem* cmd = std::lower_bound(&cmdtab[0], &cmdtab[ncmds], dummy, cmditem_lt); cmditem* cmd = std::lower_bound(&cmdtab[0], &cmdtab[ncmds], dummy, cmditem_lt);
int i; int i;
@ -793,9 +767,9 @@ bool opt_set(const wxString& name, const wxString& val)
} else if (!opt->enumvals.empty()) { } else if (!opt->enumvals.empty()) {
wxString s = val; s.MakeLower(); wxString s = val; s.MakeLower();
wxString ev = opt->enumvals; ev.MakeLower(); wxString ev = opt->enumvals; ev.MakeLower();
auto enum_opts = split(ev, wxT("|")); auto enum_opts = str_split(ev, wxT("|"));
const std::size_t found_pos = enum_idx(enum_opts, s); const std::size_t found_pos = vec_find(enum_opts, s);
const bool matched = found_pos != wxNOT_FOUND; const bool matched = found_pos != wxNOT_FOUND;
if (!matched) { if (!matched) {
@ -863,7 +837,7 @@ bool opt_set(const wxString& name, const wxString& val)
if (name.Find(wxT('/')) == wxNOT_FOUND) if (name.Find(wxT('/')) == wxNOT_FOUND)
return false; return false;
auto parts = split(name, wxT("/")); auto parts = str_split(name, wxT("/"));
if (parts[0] != wxT("Keyboard")) { if (parts[0] != wxT("Keyboard")) {
const cmditem parts_1 = { parts[1] }; const cmditem parts_1 = { parts[1] };

View File

@ -81,7 +81,7 @@ void GameArea::LoadGame(const wxString& name)
if (t == IMAGE_UNKNOWN) { if (t == IMAGE_UNKNOWN) {
wxString s; wxString s;
s.Printf(_("%s is not a valid ROM file"), name.c_str()); s.Printf(_("%s is not a valid ROM file"), name.mb_str());
wxMessageDialog dlg(GetParent(), s, _("Problem loading file"), wxOK | wxICON_ERROR); wxMessageDialog dlg(GetParent(), s, _("Problem loading file"), wxOK | wxICON_ERROR);
dlg.ShowModal(); dlg.ShowModal();
return; return;
@ -138,7 +138,7 @@ void GameArea::LoadGame(const wxString& name)
if (t == IMAGE_GB) { if (t == IMAGE_GB) {
if (!gbLoadRom(fn)) { if (!gbLoadRom(fn)) {
wxString s; wxString s;
s.Printf(_("Unable to load Game Boy ROM %s"), name.c_str()); s.Printf(_("Unable to load Game Boy ROM %s"), name.mb_str());
wxMessageDialog dlg(GetParent(), s, _("Problem loading file"), wxOK | wxICON_ERROR); wxMessageDialog dlg(GetParent(), s, _("Problem loading file"), wxOK | wxICON_ERROR);
dlg.ShowModal(); dlg.ShowModal();
return; return;
@ -188,7 +188,7 @@ void GameArea::LoadGame(const wxString& name)
gbCPUInit(fn, use_bios); gbCPUInit(fn, use_bios);
if (use_bios && !useBios) { if (use_bios && !useBios) {
wxLogError(_("Could not load BIOS %s"), (gbCgbMode ? gopts.gbc_bios : gopts.gb_bios).c_str()); wxLogError(_("Could not load BIOS %s"), (gbCgbMode ? gopts.gbc_bios : gopts.gb_bios).mb_str());
// could clear use flag & file name now, but better to force // could clear use flag & file name now, but better to force
// user to do it // user to do it
} }
@ -211,7 +211,7 @@ void GameArea::LoadGame(const wxString& name)
{ {
if (!(rom_size = CPULoadRom(fn))) { if (!(rom_size = CPULoadRom(fn))) {
wxString s; wxString s;
s.Printf(_("Unable to load Game Boy Advance ROM %s"), name.c_str()); s.Printf(_("Unable to load Game Boy Advance ROM %s"), name.mb_str());
wxMessageDialog dlg(GetParent(), s, _("Problem loading file"), wxOK | wxICON_ERROR); wxMessageDialog dlg(GetParent(), s, _("Problem loading file"), wxOK | wxICON_ERROR);
dlg.ShowModal(); dlg.ShowModal();
return; return;
@ -285,7 +285,7 @@ void GameArea::LoadGame(const wxString& name)
CPUInit(gopts.gba_bios.mb_fn_str(), useBiosFileGBA); CPUInit(gopts.gba_bios.mb_fn_str(), useBiosFileGBA);
if (useBiosFileGBA && !useBios) { if (useBiosFileGBA && !useBios) {
wxLogError(_("Could not load BIOS %s"), gopts.gba_bios.c_str()); wxLogError(_("Could not load BIOS %s"), gopts.gba_bios.mb_str());
// could clear use flag & file name now, but better to force // could clear use flag & file name now, but better to force
// user to do it // user to do it
} }
@ -354,7 +354,7 @@ void GameArea::LoadGame(const wxString& name)
if (emusys->emuReadBattery(fnb.data())) { if (emusys->emuReadBattery(fnb.data())) {
wxString msg; wxString msg;
msg.Printf(_("Loaded battery %s"), bat.GetFullPath().c_str()); msg.Printf(_("Loaded battery %s"), bat.GetFullPath().mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
if (cpuSaveType == 0 && ovSaveType == 0 && t == IMAGE_GBA) { if (cpuSaveType == 0 && ovSaveType == 0 && t == IMAGE_GBA) {
@ -570,7 +570,7 @@ bool GameArea::LoadState()
bool GameArea::LoadState(int slot) bool GameArea::LoadState(int slot)
{ {
wxString fname; wxString fname;
fname.Printf(SAVESLOT_FMT, game_name().c_str(), slot); fname.Printf(SAVESLOT_FMT, game_name().mb_str(), slot);
return LoadState(wxFileName(statedir, fname)); return LoadState(wxFileName(statedir, fname));
} }
@ -604,7 +604,7 @@ bool GameArea::LoadState(const wxFileName& fname)
wxString msg; wxString msg;
msg.Printf(ret ? _("Loaded state %s") : _("Error loading state %s"), msg.Printf(ret ? _("Loaded state %s") : _("Error loading state %s"),
fname.GetFullPath().c_str()); fname.GetFullPath().mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
return ret; return ret;
} }
@ -617,7 +617,7 @@ bool GameArea::SaveState()
bool GameArea::SaveState(int slot) bool GameArea::SaveState(int slot)
{ {
wxString fname; wxString fname;
fname.Printf(SAVESLOT_FMT, game_name().c_str(), slot); fname.Printf(SAVESLOT_FMT, game_name().mb_str(), slot);
return SaveState(wxFileName(statedir, fname)); return SaveState(wxFileName(statedir, fname));
} }
@ -628,7 +628,7 @@ bool GameArea::SaveState(const wxFileName& fname)
wxGetApp().frame->update_state_ts(true); wxGetApp().frame->update_state_ts(true);
wxString msg; wxString msg;
msg.Printf(ret ? _("Saved state %s") : _("Error saving state %s"), msg.Printf(ret ? _("Saved state %s") : _("Error saving state %s"),
fname.GetFullPath().c_str()); fname.GetFullPath().mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
return ret; return ret;
} }
@ -659,9 +659,9 @@ void GameArea::SaveBattery(bool quiet)
// of course some games just write battery way too often for such // of course some games just write battery way too often for such
// a thing to be useful // a thing to be useful
if (emusys->emuWriteBattery(fnb.data())) if (emusys->emuWriteBattery(fnb.data()))
msg.Printf(_("Wrote battery %s"), fn.c_str()); msg.Printf(_("Wrote battery %s"), fn.mb_str());
else else
msg.Printf(_("Error writing battery %s"), fn.c_str()); msg.Printf(_("Error writing battery %s"), fn.mb_str());
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
@ -1782,7 +1782,7 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
if (panel->osdstat.size()) if (panel->osdstat.size())
drawText(todraw + outstride * (systemColorDepth != 24), outstride, drawText(todraw + outstride * (systemColorDepth != 24), outstride,
10, 20, panel->osdstat.utf8_str(), showSpeedTransparent); 10, 20, panel->osdstat.mb_str(), showSpeedTransparent);
if (!disableStatusMessages && !panel->osdtext.empty()) { if (!disableStatusMessages && !panel->osdtext.empty()) {
if (systemGetClock() - panel->osdtime < OSD_TIME) { if (systemGetClock() - panel->osdtime < OSD_TIME) {
@ -1790,7 +1790,7 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
int linelen = std::ceil(width * scale - 20) / 8; int linelen = std::ceil(width * scale - 20) / 8;
int nlines = (message.size() + linelen - 1) / linelen; int nlines = (message.size() + linelen - 1) / linelen;
int cury = height - 14 - nlines * 10; int cury = height - 14 - nlines * 10;
const char* msg_data = message.utf8_str(); const char* msg_data = message.mb_str();
char buf[message.size() + 1]; char buf[message.size() + 1];
char* ptr = &buf[0]; char* ptr = &buf[0];
std::strncpy(ptr, msg_data, message.size() + 1); std::strncpy(ptr, msg_data, message.size() + 1);
@ -2262,7 +2262,7 @@ void GameArea::StartVidRecording(const wxString& fname)
if ((ret = vid_rec.Record(fnb.data(), basic_width, basic_height, if ((ret = vid_rec.Record(fnb.data(), basic_width, basic_height,
systemColorDepth)) systemColorDepth))
!= MRET_OK) != MRET_OK)
wxLogError(_("Unable to begin recording to %s (%s)"), fname.c_str(), wxLogError(_("Unable to begin recording to %s (%s)"), fname.mb_str(),
media_err(ret)); media_err(ret));
else { else {
MainFrame* mf = wxGetApp().frame; MainFrame* mf = wxGetApp().frame;
@ -2293,7 +2293,7 @@ void GameArea::StartSoundRecording(const wxString& fname)
MediaRet ret; MediaRet ret;
if ((ret = snd_rec.Record(fnb.data())) != MRET_OK) if ((ret = snd_rec.Record(fnb.data())) != MRET_OK)
wxLogError(_("Unable to begin recording to %s (%s)"), fname.c_str(), wxLogError(_("Unable to begin recording to %s (%s)"), fname.mb_str(),
media_err(ret)); media_err(ret));
else { else {
MainFrame* mf = wxGetApp().frame; MainFrame* mf = wxGetApp().frame;

30
src/wx/strutils.cpp Normal file
View File

@ -0,0 +1,30 @@
#include <algorithm>
#include <wx/string.h>
#include <string>
#include <vector>
#include "strutils.h"
// From: https://stackoverflow.com/a/7408245/262458
std::vector<wxString> str_split(const wxString& text, const wxString& sep) {
std::vector<wxString> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
// From: https://stackoverflow.com/a/15099743/262458
std::size_t vec_find(std::vector<wxString>& opts, const wxString& val) {
auto it = std::find(opts.begin(), opts.end(), val);
if (it == opts.end())
return wxNOT_FOUND;
return std::distance(opts.begin(), it);
}

15
src/wx/strutils.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef STRUTILS_H
#define STRUTILS_H
#include <algorithm>
#include <wx/string.h>
#include <string>
#include <vector>
// From: https://stackoverflow.com/a/7408245/262458
std::vector<wxString> str_split(const wxString& text, const wxString& sep);
// From: https://stackoverflow.com/a/15099743/262458
std::size_t vec_find(std::vector<wxString>& opts, const wxString& val);
#endif

View File

@ -44,7 +44,7 @@ void systemMessage(int id, const char* fmt, ...)
va_list args; va_list args;
// auto-conversion of wxCharBuffer to const char * seems broken // auto-conversion of wxCharBuffer to const char * seems broken
// so save underlying wxCharBuffer (or create one of none is used) // so save underlying wxCharBuffer (or create one of none is used)
wxCharBuffer _fmt(wxString(wxGetTranslation(wxString(fmt, wxConvLibc))).utf8_str()); wxCharBuffer _fmt(wxString(wxGetTranslation(wxString(fmt, wxConvLibc))).mb_str());
if (!buf) { if (!buf) {
buf = (char*)malloc(buflen); buf = (char*)malloc(buflen);
@ -71,7 +71,7 @@ void systemMessage(int id, const char* fmt, ...)
exit(1); exit(1);
} }
wxLogError(wxT("%s"), wxString(buf, wxConvLibc).c_str()); wxLogError(wxT("%s"), wxString(buf, wxConvLibc).mb_str());
} }
static int frames = 0; static int frames = 0;
@ -128,8 +128,8 @@ void systemStartGameRecording(const wxString& fname)
uint32_t version = 1; uint32_t version = 1;
if (!game_file.Open(fn.c_str(), wxT("wb")) || game_file.Write(&version, sizeof(version)) != sizeof(version)) { if (!game_file.Open(fn, wxT("wb")) || game_file.Write(&version, sizeof(version)) != sizeof(version)) {
wxLogError(_("Cannot open output file %s"), fname.c_str()); wxLogError(_("Cannot open output file %s"), fname.mb_str());
return; return;
} }
@ -189,8 +189,8 @@ void systemStartGamePlayback(const wxString& fname)
uint32_t version; uint32_t version;
if (!game_file.Open(fn.c_str(), wxT("rb")) || game_file.Read(&version, sizeof(version)) != sizeof(version) || wxUINT32_SWAP_ON_BE(version) != 1) { if (!game_file.Open(fn, wxT("rb")) || game_file.Read(&version, sizeof(version)) != sizeof(version) || wxUINT32_SWAP_ON_BE(version) != 1) {
wxLogError(_("Cannot open recording file %s"), fname.c_str()); wxLogError(_("Cannot open recording file %s"), fname.mb_str());
return; return;
} }
@ -415,7 +415,7 @@ void systemScreenCapture(int num)
do { do {
wxString bfn; wxString bfn;
bfn.Printf(wxT("%s%02d"), panel->game_name().c_str(), bfn.Printf(wxT("%s%02d"), panel->game_name().mb_str(),
num++); num++);
if (captureFormat == 0) if (captureFormat == 0)
@ -434,7 +434,7 @@ void systemScreenCapture(int num)
panel->emusys->emuWriteBMP(fn.GetFullPath().mb_fn_str()); panel->emusys->emuWriteBMP(fn.GetFullPath().mb_fn_str());
wxString msg; wxString msg;
msg.Printf(_("Wrote snapshot %s"), fn.GetFullPath().c_str()); msg.Printf(_("Wrote snapshot %s"), fn.GetFullPath().mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -805,7 +805,7 @@ void PrintDialog::DoSave(wxCommandEvent&)
if (scimg.SaveFile(of)) { if (scimg.SaveFile(of)) {
wxString msg; wxString msg;
msg.Printf(_("Wrote printer output to %s"), of.c_str()); msg.Printf(_("Wrote printer output to %s"), of.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
wxButton* cb = wxStaticCast(dlg->FindWindow(wxID_CANCEL), wxButton); wxButton* cb = wxStaticCast(dlg->FindWindow(wxID_CANCEL), wxButton);
@ -963,7 +963,7 @@ void systemGbPrint(uint8_t* data, int len, int pages, int feed, int pal, int con
do { do {
wxString bfn; wxString bfn;
bfn.Printf(wxT("%s-print%02d"), panel->game_name().c_str(), bfn.Printf(wxT("%s-print%02d"), panel->game_name().mb_str(),
num++); num++);
if (captureFormat == 0) if (captureFormat == 0)
@ -986,7 +986,7 @@ void systemGbPrint(uint8_t* data, int len, int pages, int feed, int pal, int con
if (ret) { if (ret) {
wxString msg; wxString msg;
msg.Printf(_("Wrote printer output to %s"), of.c_str()); msg.Printf(_("Wrote printer output to %s"), of.mb_str());
systemScreenMessage(msg); systemScreenMessage(msg);
} }
@ -1170,7 +1170,7 @@ bool debugOpenPty()
if ((pty_master = posix_openpt(O_RDWR | O_NOCTTY)) < 0 || grantpt(pty_master) < 0 || unlockpt(pty_master) < 0 || !(slave_name = ptsname(pty_master))) { if ((pty_master = posix_openpt(O_RDWR | O_NOCTTY)) < 0 || grantpt(pty_master) < 0 || unlockpt(pty_master) < 0 || !(slave_name = ptsname(pty_master))) {
wxLogError(_("Error opening pseudo tty: %s"), wxString(strerror(errno), wxLogError(_("Error opening pseudo tty: %s"), wxString(strerror(errno),
wxConvLibc) wxConvLibc)
.c_str()); .mb_str());
if (pty_master >= 0) { if (pty_master >= 0) {
close(pty_master); close(pty_master);

View File

@ -686,7 +686,7 @@ public:
wxFileName fn(memsave_fn); wxFileName fn(memsave_fn);
if (!fn.IsFileReadable()) { if (!fn.IsFileReadable()) {
wxLogError(wxT("Can't open file %s"), memsave_fn.c_str()); wxLogError(wxT("Can't open file %s"), memsave_fn.mb_str());
return; return;
} }

View File

@ -261,7 +261,7 @@ bool wxJoyKeyTextCtrl::ParseString(const wxString& s, int len, int& mod, int& ke
bool wxJoyKeyTextCtrl::FromString(const wxString& s, int& mod, int& key, int& joy) bool wxJoyKeyTextCtrl::FromString(const wxString& s, int& mod, int& key, int& joy)
{ {
return ParseString(s.c_str(), s.size(), mod, key, joy); return ParseString(s, s.size(), mod, key, joy);
} }
wxJoyKeyBinding_v wxJoyKeyTextCtrl::FromString(const wxString& s, wxChar sep) wxJoyKeyBinding_v wxJoyKeyTextCtrl::FromString(const wxString& s, wxChar sep)
@ -283,7 +283,7 @@ wxJoyKeyBinding_v wxJoyKeyTextCtrl::FromString(const wxString& s, wxChar sep)
continue; continue;
} }
if (!ParseString(s.c_str() + lastkey + 1, len - lastkey - 1, mod, key, joy)) 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 };
@ -291,7 +291,7 @@ wxJoyKeyBinding_v wxJoyKeyTextCtrl::FromString(const wxString& s, wxChar sep)
len = lastkey; len = lastkey;
} }
if (!ParseString(s.c_str(), len, mod, key, joy)) if (!ParseString(s, len, mod, key, joy))
return empty; return empty;
wxJoyKeyBinding jb = { key, mod, joy }; wxJoyKeyBinding jb = { key, mod, joy };

View File

@ -245,7 +245,7 @@ bool wxKeyTextCtrl::ParseString(const wxString& s, int len, int& mod, int& key)
bool wxKeyTextCtrl::FromString(const wxString& s, int& mod, int& key) bool wxKeyTextCtrl::FromString(const wxString& s, int& mod, int& key)
{ {
return ParseString(s.c_str(), s.size(), mod, key); return ParseString(s, s.size(), mod, key);
} }
wxAcceleratorEntry_v wxKeyTextCtrl::FromString(const wxString& s, wxChar sep) wxAcceleratorEntry_v wxKeyTextCtrl::FromString(const wxString& s, wxChar sep)
@ -264,14 +264,14 @@ wxAcceleratorEntry_v wxKeyTextCtrl::FromString(const wxString& s, wxChar sep)
continue; continue;
} }
if (!ParseString(s.c_str() + lastkey + 1, len - lastkey - 1, mod, key)) if (!ParseString(s.Mid(lastkey + 1), len - lastkey - 1, mod, key))
return empty; return empty;
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key)); ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));
len = lastkey; len = lastkey;
} }
if (!ParseString(s.c_str(), len, mod, key)) if (!ParseString(s, len, mod, key))
return empty; return empty;
ret.insert(ret.begin(), wxAcceleratorEntry(mod, key)); ret.insert(ret.begin(), wxAcceleratorEntry(mod, key));

View File

@ -19,8 +19,8 @@
#include <wx/url.h> #include <wx/url.h>
#include <wx/wfstream.h> #include <wx/wfstream.h>
#include <wx/zipstrm.h> #include <wx/zipstrm.h>
#include "wayland.h" #include "wayland.h"
#include "strutils.h"
// The built-in xrc file // The built-in xrc file
#include "builtin-xrc.h" #include "builtin-xrc.h"
@ -58,13 +58,13 @@ static void get_config_path(wxPathList& path, bool exists = true)
static bool debug_dumped = false; static bool debug_dumped = false;
if (!debug_dumped) { if (!debug_dumped) {
wxLogDebug(wxT("GetUserLocalDataDir(): %s"), stdp.GetUserLocalDataDir().c_str()); wxLogDebug(wxT("GetUserLocalDataDir(): %s"), stdp.GetUserLocalDataDir().mb_str());
wxLogDebug(wxT("GetUserDataDir(): %s"), stdp.GetUserDataDir().c_str()); wxLogDebug(wxT("GetUserDataDir(): %s"), stdp.GetUserDataDir().mb_str());
wxLogDebug(wxT("GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()): %s"), stdp.GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()).c_str()); wxLogDebug(wxT("GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()): %s"), stdp.GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()).mb_str());
wxLogDebug(wxT("GetResourcesDir(): %s"), stdp.GetResourcesDir().c_str()); wxLogDebug(wxT("GetResourcesDir(): %s"), stdp.GetResourcesDir().mb_str());
wxLogDebug(wxT("GetDataDir(): %s"), stdp.GetDataDir().c_str()); wxLogDebug(wxT("GetDataDir(): %s"), stdp.GetDataDir().mb_str());
wxLogDebug(wxT("GetLocalDataDir(): %s"), stdp.GetLocalDataDir().c_str()); wxLogDebug(wxT("GetLocalDataDir(): %s"), stdp.GetLocalDataDir().mb_str());
wxLogDebug(wxT("GetPluginsDir(): %s"), stdp.GetPluginsDir().c_str()); wxLogDebug(wxT("GetPluginsDir(): %s"), stdp.GetPluginsDir().mb_str());
debug_dumped = true; debug_dumped = true;
} }
@ -261,10 +261,8 @@ bool wxvbamApp::OnInit()
// process command-line options // process command-line options
for (int i = 0; i < pending_optset.size(); i++) { for (int i = 0; i < pending_optset.size(); i++) {
wxString p = pending_optset[i]; auto parts = str_split(pending_optset[i], wxT('='));
size_t eqat = p.find(wxT('=')); opt_set(parts[0], parts[1]);
p[eqat] = 0;
opt_set(p.c_str(), p.c_str() + eqat + 1);
} }
pending_optset.clear(); pending_optset.clear();
@ -458,7 +456,7 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
"To override, remove all but changed root node(s). " "To override, remove all but changed root node(s). "
"First found root node of correct name in any .xrc or " "First found root node of correct name in any .xrc or "
".xrs files in following search path overrides built-in:"), ".xrs files in following search path overrides built-in:"),
s.c_str()); s.mb_str());
tack_full_path(lm); tack_full_path(lm);
wxLogMessage(lm); wxLogMessage(lm);
return false; return false;
@ -483,7 +481,7 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
wxString lm; wxString lm;
lm.Printf(_("Wrote built-in override file to %s\n" lm.Printf(_("Wrote built-in override file to %s\n"
"To override, delete all but changed section. First found section is used from search path:"), "To override, delete all but changed section. First found section is used from search path:"),
s.c_str()); s.mb_str());
wxString oi = wxFileName::GetPathSeparator(); wxString oi = wxFileName::GetPathSeparator();
oi += wxT("vba-over.ini"); oi += wxT("vba-over.ini");
tack_full_path(lm, oi); tack_full_path(lm, oi);
@ -537,44 +535,41 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
bool complained = false, gotfile = false; bool complained = false, gotfile = false;
for (int i = 0; i < nparm; i++) { for (int i = 0; i < nparm; i++) {
wxString p = cl.GetParam(i); auto p = cl.GetParam(i);
size_t eqat = p.find(wxT('=')); auto parts = str_split(p, wxT('='));
if (eqat != wxString::npos) { if (parts.size() > 1) {
p[eqat] = 0; opt_set(parts[0], parts[1]);
if (!opt_set(p.c_str(), p.c_str() + eqat + 1)) {
p[eqat] = wxT('=');
eqat = wxString::npos;
} else
p[eqat] = wxT('=');
pending_optset.push_back(p); pending_optset.push_back(p);
} }
else {
if (eqat == wxString::npos) {
if (!gotfile) { if (!gotfile) {
pending_load = p; pending_load = p;
gotfile = true; gotfile = true;
} else { } else {
if (!complained) { if (!complained) {
wxFprintf(stderr, _("Bad configuration option or multiple ROM files given:\n")); wxFprintf(stderr, _("Bad configuration option or multiple ROM files given:\n"));
wxFprintf(stderr, wxT("%s\n"), pending_load.c_str()); wxFprintf(stderr, wxT("%s\n"), pending_load.mb_str());
complained = true; complained = true;
} }
wxFprintf(stderr, wxT("%s\n"), p.c_str()); wxFprintf(stderr, wxT("%s\n"), p);
} }
} }
} }
home = strdup(wxApp::argv[0].utf8_str()); home = strdup(wxString(wxApp::argv[0]).char_str());
SetHome(home); SetHome(home);
LoadConfig(); // Parse command line arguments (overrides ini) LoadConfig(); // Parse command line arguments (overrides ini)
ReadOpts(argc, (char**)argv); ReadOpts(argc, (char**)argv);
return true; return true;
} }
wxvbamApp::~wxvbamApp() {
free(home);
}
MainFrame::MainFrame() MainFrame::MainFrame()
: wxFrame() : wxFrame()
, focused(false) , focused(false)
@ -730,7 +725,7 @@ void MainFrame::update_state_ts(bool force)
if (panel->game_type() != IMAGE_UNKNOWN) { if (panel->game_type() != IMAGE_UNKNOWN) {
wxString fn; wxString fn;
fn.Printf(SAVESLOT_FMT, panel->game_name().c_str(), i + 1); fn.Printf(SAVESLOT_FMT, panel->game_name().mb_str(), i + 1);
wxFileName fp(panel->state_dir(), fn); wxFileName fp(panel->state_dir(), fn);
wxDateTime ts; // = wxInvalidDateTime wxDateTime ts; // = wxInvalidDateTime

View File

@ -44,7 +44,7 @@
#undef wxLogDebug #undef wxLogDebug
#define wxLogDebug(...) \ #define wxLogDebug(...) \
do { \ do { \
fputs(wxString::Format(wxDateTime::UNow().Format(wxT("%X")) + wxT(": Debug: ") + __VA_ARGS__).utf8_str(), VBAM_DEBUG_STREAM); \ fputs(wxString::Format(wxDateTime::UNow().Format(wxT("%X")) + wxT(": Debug: ") + __VA_ARGS__).mb_str(), VBAM_DEBUG_STREAM); \
fputc('\n', VBAM_DEBUG_STREAM); \ fputc('\n', VBAM_DEBUG_STREAM); \
} while(0) } while(0)
#endif #endif
@ -134,6 +134,9 @@ public:
return false; return false;
} }
} }
virtual ~wxvbamApp();
protected: protected:
bool using_wayland; bool using_wayland;