support Wx built with --enable-stl #134

When Wx is built with --enable-stl, wxString to wxChar*/char* implicit
conversions and vice-versa no longer work.

Change all wxChar* data members to wxString and change all pointer
arithmetic code (mostly in opts.cpp, cmdevents.cpp and
widgets/joyedit.cpp) to use wxString methods instead.

Also make mostly minor changes in various other files for all of this to
work.
This commit is contained in:
Rafael Kitover 2017-09-10 15:44:18 -07:00
parent 142dbc0aca
commit f5cb7b2b40
18 changed files with 171 additions and 152 deletions

View File

@ -274,7 +274,7 @@ EVT_HANDLER(wxID_FILE10, "Load recent ROM 10")
} }
static const struct rom_maker { static const struct rom_maker {
const wxChar *code, *name; const wxString code, name;
} makers[] = { } makers[] = {
{ wxT("01"), wxT("Nintendo") }, { wxT("01"), wxT("Nintendo") },
{ wxT("02"), wxT("Rocket Games") }, { wxT("02"), wxT("Rocket Games") },
@ -503,7 +503,7 @@ static bool maker_lt(const rom_maker& r1, const rom_maker& r2)
return wxStrcmp(r1.code, r2.code) < 0; return wxStrcmp(r1.code, r2.code) < 0;
} }
void SetDialogLabel(wxDialog* dlg, wxChar* id, wxString ts, size_t l) void SetDialogLabel(wxDialog* dlg, const wxString& id, wxString ts, size_t l)
{ {
ts.Replace(wxT("&"), wxT("&&"), true); ts.Replace(wxT("&"), wxT("&&"), true);
(dynamic_cast<wxControl*>((*dlg).FindWindow(wxXmlResource::GetXRCID(id))))->SetLabel(ts); (dynamic_cast<wxControl*>((*dlg).FindWindow(wxXmlResource::GetXRCID(id))))->SetLabel(ts);
@ -557,7 +557,7 @@ EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB | CMDEN_GBA)
setlab("MakerName"); setlab("MakerName");
setblab("UnitCode", gbRom[0x146]); setblab("UnitCode", gbRom[0x146]);
const wxChar* type; wxString type;
switch (gbRom[0x147]) { switch (gbRom[0x147]) {
case 0x00: case 0x00:
@ -1187,15 +1187,15 @@ EVT_HANDLER_MASK(RecordSoundStartRecording, "Start sound recording...", CMDEN_NS
sound_path = GetGamePath(gopts.recording_dir); sound_path = GetGamePath(gopts.recording_dir);
wxString def_name = panel->game_name(); wxString def_name = panel->game_name();
const wxChar* extoff = sound_exts.c_str(); wxString extoff = sound_exts;
for (int i = 0; i < sound_extno; i++) { for (int i = 0; i < sound_extno; i++) {
extoff = wxStrchr(extoff, wxT('|')) + 1; extoff = extoff.Mid(extoff.Find(wxT('|')) + 1);
extoff = wxStrchr(extoff, wxT('|')) + 1; extoff = extoff.Mid(extoff.Find(wxT('|')) + 1);
} }
extoff = wxStrchr(extoff, wxT('|')) + 2; // skip * extoff = extoff.Mid(extoff.Find(wxT('|')) + 2); // skip *
def_name += wxString(extoff, wxStrcspn(extoff, wxT(";|"))); def_name += extoff.Left(wxStrcspn(extoff, wxT(";|")));
wxFileDialog dlg(this, _("Select output file"), sound_path, def_name, wxFileDialog dlg(this, _("Select output file"), sound_path, def_name,
sound_exts, wxFD_SAVE | wxFD_OVERWRITE_PROMPT); sound_exts, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
dlg.SetFilterIndex(sound_extno); dlg.SetFilterIndex(sound_extno);
@ -1260,15 +1260,15 @@ EVT_HANDLER_MASK(RecordAVIStartRecording, "Start video recording...", CMDEN_NVRE
vid_path = GetGamePath(gopts.recording_dir); vid_path = GetGamePath(gopts.recording_dir);
wxString def_name = panel->game_name(); wxString def_name = panel->game_name();
const wxChar* extoff = vid_exts.c_str(); wxString extoff = vid_exts;
for (int i = 0; i < vid_extno; i++) { for (int i = 0; i < vid_extno; i++) {
extoff = wxStrchr(extoff, wxT('|')) + 1; extoff = extoff.Mid(extoff.Find(wxT('|')) + 1);
extoff = wxStrchr(extoff, wxT('|')) + 1; extoff = extoff.Mid(extoff.Find(wxT('|')) + 1);
} }
extoff = wxStrchr(extoff, wxT('|')) + 2; // skip * extoff = extoff.Mid(extoff.Find(wxT('|')) + 2); // skip *
def_name += wxString(extoff, wxStrcspn(extoff, wxT(";|"))); def_name += extoff.Left(wxStrcspn(extoff, wxT(";|")));
wxFileDialog dlg(this, _("Select output file"), vid_path, def_name, wxFileDialog dlg(this, _("Select output file"), vid_path, def_name,
vid_exts, wxFD_SAVE | wxFD_OVERWRITE_PROMPT); vid_exts, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
dlg.SetFilterIndex(vid_extno); dlg.SetFilterIndex(vid_extno);

View File

@ -96,7 +96,7 @@ bool DirectSound::init(long sampleRate)
if (gopts.audio_dev.empty()) if (gopts.audio_dev.empty())
dev = DSDEVID_DefaultPlayback; dev = DSDEVID_DefaultPlayback;
else else
CLSIDFromString(const_cast<wxChar*>(gopts.audio_dev.wx_str()), &dev); CLSIDFromString(gopts.audio_dev.wc_str(), &dev);
pDirectSound->Initialize(&dev); pDirectSound->Initialize(&dev);

View File

@ -1117,7 +1117,7 @@ void MainFrame::OAMViewer()
namespace Viewers { namespace Viewers {
static int ptype = 0; static int ptype = 0;
static wxString pdir; static wxString pdir;
void savepal(wxWindow* parent, const uint8_t* data, int ncols, const wxChar* type) void savepal(wxWindow* parent, const uint8_t* data, int ncols, const wxString type)
{ {
// no attempt is made here to translate the palette type name // no attempt is made here to translate the palette type name
// it's just a suggested name, anyway // it's just a suggested name, anyway

View File

@ -2292,7 +2292,19 @@ public:
///////////////////////////// /////////////////////////////
//Check if a pointer from the XRC file is valid. If it's not, throw an error telling the user. //Check if a pointer from the XRC file is valid. If it's not, throw an error telling the user.
template <typename T> template <typename T>
void CheckThrowXRCError(T pointer, std::string name) void CheckThrowXRCError(T pointer, const wxString& name)
{
if (pointer == NULL) {
std::string errormessage = "Unable to load a \"";
errormessage += typeid(pointer).name();
errormessage += "\" from the builtin xrc file: ";
errormessage += name.utf8_str();
throw std::runtime_error(errormessage);
}
}
template <typename T>
void CheckThrowXRCError(T pointer, const char* name)
{ {
if (pointer == NULL) { if (pointer == NULL) {
std::string errormessage = "Unable to load a \""; std::string errormessage = "Unable to load a \"";
@ -2302,6 +2314,7 @@ void CheckThrowXRCError(T pointer, std::string name)
throw std::runtime_error(errormessage); throw std::runtime_error(errormessage);
} }
} }
wxDialog* MainFrame::LoadXRCDialog(const char* name) wxDialog* MainFrame::LoadXRCDialog(const char* name)
{ {
wxString dname = wxString::FromUTF8(name); wxString dname = wxString::FromUTF8(name);
@ -2347,7 +2360,15 @@ T* SafeXRCCTRL(wxWindow* parent, const char* name)
wxString dname = wxString::FromUTF8(name); wxString dname = wxString::FromUTF8(name);
//This is needed to work around a bug in XRCCTRL //This is needed to work around a bug in XRCCTRL
wxString Ldname = dname; wxString Ldname = dname;
T* output = XRCCTRL(*parent, dname, T); T* output = XRCCTRL_D(*parent, dname, T);
CheckThrowXRCError(output, name);
return output;
}
template <typename T>
T* SafeXRCCTRL(wxWindow* parent, const wxString& name)
{
T* output = XRCCTRL_D(*parent, name, T);
CheckThrowXRCError(output, name); CheckThrowXRCError(output, name);
return output; return output;
} }
@ -3214,7 +3235,7 @@ bool MainFrame::BindControls()
// "Unable to load dialog GameBoyConfig from resources", this is // "Unable to load dialog GameBoyConfig from resources", this is
// probably the reason. // probably the reason.
pn.Printf(wxT("cp%d"), i + 1); pn.Printf(wxT("cp%d"), i + 1);
wxWindow* w = SafeXRCCTRL<wxWindow>(d, ToString(pn).c_str()); wxWindow* w = SafeXRCCTRL<wxWindow>(d, pn);
GBColorConfigHandler[i].p = w; GBColorConfigHandler[i].p = w;
GBColorConfigHandler[i].pno = i; GBColorConfigHandler[i].pno = i;
wxFarRadio* cb = SafeXRCCTRL<wxFarRadio>(w, "UsePalette"); wxFarRadio* cb = SafeXRCCTRL<wxFarRadio>(w, "UsePalette");
@ -3231,7 +3252,7 @@ bool MainFrame::BindControls()
for (int j = 0; j < 8; j++) { for (int j = 0; j < 8; j++) {
wxString s; wxString s;
s.Printf(wxT("Color%d"), j); s.Printf(wxT("Color%d"), j);
wxColourPickerCtrl* cp = SafeXRCCTRL<wxColourPickerCtrl>(w, ToString(s).c_str()); wxColourPickerCtrl* cp = SafeXRCCTRL<wxColourPickerCtrl>(w, s);
GBColorConfigHandler[i].cp[j] = cp; GBColorConfigHandler[i].cp[j] = cp;
cp->SetValidator(wxColorValidator(&systemGbPalette[i * 8 + j])); cp->SetValidator(wxColorValidator(&systemGbPalette[i * 8 + j]));
} }
@ -3433,7 +3454,7 @@ bool MainFrame::BindControls()
// "Unable to load dialog JoypadConfig from resources", this is // "Unable to load dialog JoypadConfig from resources", this is
// probably the reason. // probably the reason.
pn.Printf(wxT("joy%d"), i + 1); pn.Printf(wxT("joy%d"), i + 1);
wxWindow* w = SafeXRCCTRL<wxWindow>(joyDialog, ToString(pn).c_str()); wxWindow* w = SafeXRCCTRL<wxWindow>(joyDialog, pn);
wxFarRadio* cb; wxFarRadio* cb;
cb = SafeXRCCTRL<wxFarRadio>(w, "DefaultConfig"); cb = SafeXRCCTRL<wxFarRadio>(w, "DefaultConfig");
@ -3447,7 +3468,7 @@ bool MainFrame::BindControls()
for (int j = 0; j < NUM_KEYS; j++) { for (int j = 0; j < NUM_KEYS; j++) {
wxJoyKeyTextCtrl* tc = XRCCTRL_D(*w, joynames[j], wxJoyKeyTextCtrl); wxJoyKeyTextCtrl* tc = XRCCTRL_D(*w, joynames[j], wxJoyKeyTextCtrl);
CheckThrowXRCError(tc, ToString(joynames[j])); CheckThrowXRCError(tc, joynames[j]);
wxWindow* p = tc->GetParent(); wxWindow* p = tc->GetParent();
if (p == prevp) if (p == prevp)

View File

@ -3,9 +3,9 @@
struct IOData { struct IOData {
uint16_t* address; uint16_t* address;
uint16_t offset; uint16_t offset;
const wxChar* name; const wxString name;
uint16_t write; uint16_t write;
const wxChar* bits[16]; wxString bits[16];
}; };
/* const */ IOData ioregs[] = // not const so tranlation can be done once /* const */ IOData ioregs[] = // not const so tranlation can be done once

View File

@ -1,6 +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>
/* /*
@ -19,15 +21,15 @@
} }
#define INTOPT(c, n, d, v, min, max) \ #define INTOPT(c, n, d, v, min, max) \
{ \ { \
wxT(c), (n), d, NULL, &v, NULL, min, max \ wxT(c), (n), d, NULL, &v, "", min, max \
} }
#define DOUBLEOPT(c, n, d, v, min, max) \ #define DOUBLEOPT(c, n, d, v, min, max) \
{ \ { \
wxT(c), (n), d, NULL, NULL, NULL, min, max, NULL, &v \ wxT(c), (n), d, NULL, NULL, "", min, max, NULL, &v \
} }
#define BOOLOPT(c, n, d, v) \ #define BOOLOPT(c, n, d, v) \
{ \ { \
wxT(c), (n), d, NULL, NULL, NULL, 0, 0, &v \ wxT(c), (n), d, NULL, NULL, "", 0, 0, &v \
} }
#define ENUMOPT(c, n, d, v, e) \ #define ENUMOPT(c, n, d, v, e) \
{ \ { \
@ -117,7 +119,7 @@ const int num_def_accels = sizeof(default_accels) / sizeof(default_accels[0]);
// Note: this must match GUI widget names or GUI won't work // Note: this must match GUI widget names or GUI won't work
// This table's order determines tab order as well // This table's order determines tab order as well
const wxChar* const joynames[NUM_KEYS] = { const wxString joynames[NUM_KEYS] = {
wxT("Up"), wxT("Down"), wxT("Left"), wxT("Right"), wxT("Up"), wxT("Down"), wxT("Left"), wxT("Right"),
wxT("A"), wxT("B"), wxT("L"), wxT("R"), wxT("A"), wxT("B"), wxT("L"), wxT("R"),
wxT("Select"), wxT("Start"), wxT("Select"), wxT("Start"),
@ -331,6 +333,31 @@ 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()
@ -479,51 +506,34 @@ void load_opts()
if (opt.stropt) { if (opt.stropt) {
opt.curstr = *opt.stropt; opt.curstr = *opt.stropt;
} else if (opt.enumvals) { } else if (!opt.enumvals.empty()) {
opt.curint = *opt.intopt; auto enum_opts = split(opt.enumvals.MakeLower(), wxT("|"));
bool gotit = cfg->Read(opt.opt, &s); opt.curint = *opt.intopt;
const wxChar* ev = opt.enumvals; bool gotit = cfg->Read(opt.opt, &s); s.MakeLower();
if (gotit && s.size()) { if (gotit && !s.empty()) {
// wx provides no case-insensitive Find() const std::size_t found_pos = enum_idx(enum_opts, s);
s.MakeLower(); const bool matched = found_pos != wxNOT_FOUND;
for (; (ev = wxStrstr(ev, (const wxChar*)s.c_str())); ev++) { if (!matched) {
if (ev != opt.enumvals && ev[-1] != wxT('|'))
continue;
if (!ev[s.size()] || ev[s.size()] == wxT('|'))
break;
}
if (!ev) {
opt.curint = 0; opt.curint = 0;
ev = opt.enumvals; const wxString ev = opt.enumvals;
const wxChar* evx = wxGetTranslation(ev); const wxString evx = wxGetTranslation(ev);
bool isx = wxStrcmp(ev, evx) != 0; bool isx = wxStrcmp(ev, evx) != 0;
// technically, the translation for this string could incorproate // technically, the translation for this string could incorproate
// the equals sign if necessary instead of doing it this way // the equals sign if necessary instead of doing it this way
wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"), wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"),
s.c_str(), opt.opt, ev, s, opt.opt, ev,
isx ? wxT(" = ") : wxT(""), isx ? wxT(" = ") : wxT(""),
isx ? evx : wxT("")); isx ? evx : wxT(""));
s = wxString(ev, wxStrchr(ev, wxT('|')) - ev); // write first option
cfg->Write(opt.opt, s); cfg->Write(opt.opt, enum_opts[0]);
} else { } else
const wxChar* ev2; opt.curint = found_pos;
for (ev2 = opt.enumvals, opt.curint = 0; ev2 != ev; opt.curint++)
ev2 = wxStrchr(ev2, wxT('|')) + 1;
}
*opt.intopt = opt.curint; *opt.intopt = opt.curint;
} else { } else {
for (int i = 0; i != opt.curint; i++) cfg->Write(opt.opt, enum_opts[opt.curint]);
ev = wxStrchr(ev, wxT('|')) + 1;
const wxChar* ev2 = wxStrchr(ev, wxT('|'));
s = ev2 ? wxString(ev, ev2 - ev) : wxString(ev);
cfg->Write(opt.opt, s);
} }
} else if (opt.intopt) { } else if (opt.intopt) {
cfg->Read(opt.opt, &opt.curint, *opt.intopt); cfg->Read(opt.opt, &opt.curint, *opt.intopt);
@ -649,17 +659,12 @@ void update_opts()
opt.curstr = *opt.stropt; opt.curstr = *opt.stropt;
cfg->Write(opt.opt, opt.curstr); cfg->Write(opt.opt, opt.curstr);
} }
} else if (opt.enumvals) { } else if (!opt.enumvals.empty()) {
if (*opt.intopt != opt.curint) { if (*opt.intopt != opt.curint) {
opt.curint = *opt.intopt; opt.curint = *opt.intopt;
const wxChar* ev = opt.enumvals; auto enum_opts = split(opt.enumvals.MakeLower(), wxT("|"));
for (int i = 0; i != opt.curint; i++) cfg->Write(opt.opt, enum_opts[opt.curint]);
ev = wxStrchr(ev, wxT('|')) + 1;
const wxChar* ev2 = wxStrchr(ev, wxT('|'));
wxString s = ev2 ? wxString(ev, ev2 - ev) : wxString(ev);
cfg->Write(opt.opt, s);
} }
} else if (opt.intopt) { } else if (opt.intopt) {
if (*opt.intopt != opt.curint) if (*opt.intopt != opt.curint)
@ -771,7 +776,7 @@ void update_opts()
cfg->Flush(); cfg->Flush();
} }
bool opt_set(const wxChar* name, const wxChar* val) bool opt_set(const wxString& name, const wxString& val)
{ {
const opt_desc dummy = { name }; const opt_desc dummy = { name };
const opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt); const opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
@ -780,41 +785,30 @@ bool opt_set(const wxChar* name, const wxChar* val)
if (opt->stropt) if (opt->stropt)
*opt->stropt = wxString(val); *opt->stropt = wxString(val);
else if (opt->boolopt) { else if (opt->boolopt) {
if (!*val || val[1] || (*val != wxT('0') && *val != wxT('1'))) if (!(val == wxT('0') || val == wxT('1')))
wxLogWarning(_("Invalid flag option %s - %s ignored"), wxLogWarning(_("Invalid flag option %s - %s ignored"),
name, val); name, val);
else else
*opt->boolopt = *val == wxT('1'); *opt->boolopt = val == wxT('1');
} else if (opt->enumvals) { } else if (!opt->enumvals.empty()) {
wxString s(val); wxString s = val; s.MakeLower();
s.MakeLower(); wxString ev = opt->enumvals; ev.MakeLower();
const wxChar* ev; auto enum_opts = split(ev, wxT("|"));
for (ev = opt->enumvals; (ev = wxStrstr(ev, (const wxChar*)s.c_str())); ev++) { const std::size_t found_pos = enum_idx(enum_opts, s);
if (ev != opt->enumvals && ev[-1] != wxT('|')) const bool matched = found_pos != wxNOT_FOUND;
continue;
if (!ev[s.size()] || ev[s.size()] == wxT('|')) if (!matched) {
break; const wxString evx = wxGetTranslation(opt->enumvals);
}
if (!ev) {
const wxChar* evx = wxGetTranslation(opt->enumvals);
bool isx = wxStrcmp(opt->enumvals, evx) != 0; bool isx = wxStrcmp(opt->enumvals, evx) != 0;
// technically, the translation for this string could incorproate // technically, the translation for this string could incorproate
// the equals sign if necessary instead of doing it this way // the equals sign if necessary instead of doing it this way
wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"), wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"),
s.c_str(), opt->opt, opt->enumvals, s, opt->opt, opt->enumvals,
isx ? wxT(" = ") : wxT(""), isx ? wxT(" = ") : wxT(""),
isx ? evx : wxT("")); isx ? evx : wxT(""));
} else { } else {
const wxChar* ev2; *opt->intopt = found_pos;
int val;
for (ev2 = opt->enumvals, val = 0; ev2 != ev; val++)
ev2 = wxStrchr(ev2, wxT('|')) + 1;
*opt->intopt = val;
} }
} else if (opt->intopt) { } else if (opt->intopt) {
const wxString s(val); const wxString s(val);
@ -866,33 +860,33 @@ bool opt_set(const wxChar* name, const wxChar* val)
return true; return true;
} else { } else {
const wxChar* slat = wxStrchr(name, wxT('/')); if (name.Find(wxT('/')) == wxNOT_FOUND)
if (!slat)
return false; return false;
if (!wxStrncmp(name, wxT("Keyboard"), (int)(slat - name))) { auto parts = split(name, wxT("/"));
const cmditem dummy2 = { slat + 1 };
cmditem* cmd = std::lower_bound(&cmdtab[0], &cmdtab[ncmds], dummy2, cmditem_lt);
if (cmd == &cmdtab[ncmds] || wxStrcmp(slat + 1, cmd->cmd)) if (parts[0] != wxT("Keyboard")) {
const cmditem parts_1 = { parts[1] };
cmditem* cmd = std::lower_bound(&cmdtab[0], &cmdtab[ncmds], parts_1, cmditem_lt);
if (cmd == &cmdtab[ncmds] || wxStrcmp(parts[1], cmd->cmd))
return false; return false;
for (wxAcceleratorEntry_v::iterator i = gopts.accels.begin(); for (auto i = gopts.accels.begin(); i < gopts.accels.end(); ++i)
i < gopts.accels.end(); ++i)
if (i->GetCommand() == cmd->cmd_id) { if (i->GetCommand() == cmd->cmd_id) {
wxAcceleratorEntry_v::iterator j; auto j = i;
for (j = i; j < gopts.accels.end(); ++j) for (; j < gopts.accels.end(); ++j)
if (j->GetCommand() != cmd->cmd_id) if (j->GetCommand() != cmd->cmd_id)
break; break;
gopts.accels.erase(i, j); gopts.accels.erase(i, j);
break; break;
} }
if (*val) { if (!val.empty()) {
wxAcceleratorEntry_v aval = wxKeyTextCtrl::FromString(val); auto aval = wxKeyTextCtrl::FromString(val);
for (int i = 0; i < aval.size(); i++) for (int i = 0; i < aval.size(); i++)
aval[i].Set(aval[i].GetFlags(), aval[i].GetKeyCode(), aval[i].Set(aval[i].GetFlags(), aval[i].GetKeyCode(),
@ -905,24 +899,24 @@ bool opt_set(const wxChar* name, const wxChar* val)
} }
return true; return true;
} else if (!wxStrncmp(name, wxT("Joypad"), (int)(slat - name))) { } else if (!wxStrncmp(name, wxT("Joypad"), wxStrlen(wxT("Joypad")))) {
if (slat[1] < wxT('1') || slat[1] > wxT('4') || slat[2] != wxT('/')) if (parts[1] < wxT('1') || parts[1] > wxT('4') || parts.size() < 3)
return false; return false;
int jno = slat[1] - wxT('1'); int jno = parts[1][0] - wxT('1');
int kno; int kno;
for (kno = 0; kno < NUM_KEYS; kno++) for (kno = 0; kno < NUM_KEYS; kno++)
if (!wxStrcmp(joynames[kno], slat + 3)) if (!wxStrcmp(joynames[kno], parts[2]))
break; break;
if (kno == NUM_KEYS) if (kno == NUM_KEYS)
return false; return false;
if (!*val) if (val.empty())
gopts.joykey_bindings[jno][kno].clear(); gopts.joykey_bindings[jno][kno].clear();
else { else {
wxJoyKeyBinding_v b = wxJoyKeyTextCtrl::FromString(val); auto b = wxJoyKeyTextCtrl::FromString(val);
if (!b.size()) if (!b.size())
wxLogWarning(_("Invalid key binding %s for %s"), val, name); wxLogWarning(_("Invalid key binding %s for %s"), val, name);

View File

@ -2,7 +2,7 @@
#define WX_OPTS_H #define WX_OPTS_H
#define NUM_KEYS 21 #define NUM_KEYS 21
extern const wxChar* const joynames[NUM_KEYS]; extern const wxString joynames[NUM_KEYS];
extern wxJoyKeyBinding defkeys[NUM_KEYS * 2]; // keyboard + joystick defaults extern wxJoyKeyBinding defkeys[NUM_KEYS * 2]; // keyboard + joystick defaults
extern struct opts_t { extern struct opts_t {
@ -84,12 +84,12 @@ extern struct opts_t {
} gopts; } gopts;
extern struct opt_desc { extern struct opt_desc {
const wxChar* opt; wxString opt;
const char* cmd; const char* cmd;
const wxChar* desc; wxString desc;
wxString* stropt; wxString* stropt;
int* intopt; int* intopt;
const wxChar* enumvals; wxString enumvals;
double min, max; double min, max;
bool* boolopt; bool* boolopt;
double* doubleopt; double* doubleopt;
@ -112,6 +112,6 @@ void load_opts();
// will detect changes and write config if necessary // will detect changes and write config if necessary
void update_opts(); void update_opts();
// returns true if option name correct; prints error if val invalid // returns true if option name correct; prints error if val invalid
bool opt_set(const wxChar* name, const wxChar* val); bool opt_set(const wxString& name, const wxString& val);
#endif /* WX_OPTS_H */ #endif /* WX_OPTS_H */

View File

@ -1,4 +1,5 @@
#include <cmath> #include <cmath>
#include <cstring>
#include <wx/dcbuffer.h> #include <wx/dcbuffer.h>
#include <SDL_joystick.h> #include <SDL_joystick.h>
@ -1785,11 +1786,14 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
if (!disableStatusMessages && !panel->osdtext.empty()) { if (!disableStatusMessages && !panel->osdtext.empty()) {
if (systemGetClock() - panel->osdtime < OSD_TIME) { if (systemGetClock() - panel->osdtime < OSD_TIME) {
std::string message = ToString(panel->osdtext); wxString message = panel->osdtext;
int linelen = std::ceil(width * scale - 20) / 8; int linelen = std::ceil(width * scale - 20) / 8;
int nlines = (message.length() + linelen - 1) / linelen; int nlines = (message.size() + linelen - 1) / linelen;
int cury = height - 14 - nlines * 10; int cury = height - 14 - nlines * 10;
char* ptr = const_cast<char*>(message.c_str()); const char* msg_data = message.utf8_str();
char buf[message.size() + 1];
char* ptr = &buf[0];
std::strncpy(ptr, msg_data, message.size() + 1);
while (nlines > 1) { while (nlines > 1) {
char lchar = ptr[linelen]; char lchar = ptr[linelen];
@ -2223,7 +2227,7 @@ void DXDrawingPanel::DrawArea(wxWindowDC& dc)
#endif #endif
#ifndef NO_FFMPEG #ifndef NO_FFMPEG
static const wxChar* media_err(MediaRet ret) static const wxString media_err(MediaRet ret)
{ {
switch (ret) { switch (ret) {
case MRET_OK: case MRET_OK:

View File

@ -354,7 +354,7 @@ public:
baddialog(); baddialog();
addr->Clear(); addr->Clear();
const wxChar* longline = lline; wxString longline = lline;
int lwidth = 0; int lwidth = 0;
for (int i = 0; i < NUM_IOREGS; i++) { for (int i = 0; i < NUM_IOREGS; i++) {
@ -470,14 +470,14 @@ public:
Update(sel); Update(sel);
} }
static const wxChar* lline; static wxString lline;
wxChoice* addr; wxChoice* addr;
wxControl* val; wxControl* val;
wxCheckBox* bit[16]; wxCheckBox* bit[16];
wxControl* bitlab[16]; wxControl* bitlab[16];
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
const wxChar* IOViewer::lline = NULL; wxString IOViewer::lline;
BEGIN_EVENT_TABLE(IOViewer, Viewer) BEGIN_EVENT_TABLE(IOViewer, Viewer)
EVT_BUTTON(XRCID("Refresh"), IOViewer::RefreshEv) EVT_BUTTON(XRCID("Refresh"), IOViewer::RefreshEv)
EVT_BUTTON(wxID_APPLY, IOViewer::Apply) EVT_BUTTON(wxID_APPLY, IOViewer::Apply)
@ -500,7 +500,7 @@ void MainFrame::IOViewer()
} while (0) } while (0)
LogDialog::LogDialog() LogDialog::LogDialog()
{ {
const wxChar* dname = wxT("Logging"); const wxString dname = wxT("Logging");
if (!wxXmlResource::Get()->LoadDialog(this, wxGetApp().frame, dname)) if (!wxXmlResource::Get()->LoadDialog(this, wxGetApp().frame, dname))
baddialog(); baddialog();
@ -625,7 +625,7 @@ public:
Goto(0); Goto(0);
// initialize load/save support dialog already // initialize load/save support dialog already
{ {
const wxChar* dname = wxT("MemSelRegion"); const wxString dname = wxT("MemSelRegion");
selregion = wxXmlResource::Get()->LoadDialog(this, dname); selregion = wxXmlResource::Get()->LoadDialog(this, dname);
if (!selregion) if (!selregion)

View File

@ -21,7 +21,7 @@ void Viewer::CloseDlg(wxCloseEvent& ev)
Destroy(); Destroy();
} }
Viewer::Viewer(const wxChar* name) Viewer::Viewer(const wxString& name)
: wxDialog() : wxDialog()
, auto_update(false) , auto_update(false)
{ {
@ -1075,7 +1075,7 @@ EVT_LEFT_UP(GfxPanel::Click)
EVT_MOTION(GfxPanel::MouseMove) EVT_MOTION(GfxPanel::MouseMove)
END_EVENT_TABLE() END_EVENT_TABLE()
GfxViewer::GfxViewer(const wxChar* dname, int maxw, int maxh) GfxViewer::GfxViewer(const wxString& dname, int maxw, int maxh)
: Viewer(dname) : Viewer(dname)
, image(maxw, maxh) , image(maxw, maxh)
{ {

View File

@ -25,7 +25,7 @@ namespace Viewers {
class Viewer : public wxDialog { class Viewer : public wxDialog {
public: public:
void CloseDlg(wxCloseEvent& ev); void CloseDlg(wxCloseEvent& ev);
Viewer(const wxChar* name); Viewer(const wxString& name);
virtual ~Viewer() virtual ~Viewer()
{ {
} }
@ -46,7 +46,7 @@ public:
} }
protected: protected:
const wxChar* dname; wxString dname;
void SetAutoUpdate(wxCommandEvent& ev) void SetAutoUpdate(wxCommandEvent& ev)
{ {
auto_update = ev.IsChecked(); auto_update = ev.IsChecked();
@ -372,7 +372,7 @@ END_DECLARE_EVENT_TYPES()
// this is what actually manages the GfxPanel // this is what actually manages the GfxPanel
class GfxViewer : public Viewer { class GfxViewer : public Viewer {
public: public:
GfxViewer(const wxChar* dname, int maxw, int maxh); GfxViewer(const wxString& dname, int maxw, int maxh);
void ChangeBMP(); void ChangeBMP();
void BMPSize(int w, int h); void BMPSize(int w, int h);

View File

@ -189,17 +189,17 @@ static wxCriticalSection recs;
// wx provides no atoi for wxChar // wx provides no atoi for wxChar
// this is not a universal function; assumes valid number // this is not a universal function; assumes valid number
static int simple_atoi(const wxChar* s, int len) static int simple_atoi(const wxString& s, int len)
{ {
int ret = 0; int ret = 0;
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
ret = ret * 10 + s[i] - wxT('0'); ret = ret * 10 + (int)(s[i] - wxT('0'));
return ret; return ret;
} }
static bool ParseJoy(const wxChar* s, int len, int& mod, int& key, int& joy) static bool ParseJoy(const wxString& s, int len, int& mod, int& key, int& joy)
{ {
mod = key = joy = 0; mod = key = joy = 0;
@ -212,24 +212,24 @@ static bool ParseJoy(const wxChar* s, int len, int& mod, int& key, int& joy)
if (!joyre.Matches(s) || !joyre.GetMatch(&b, &l) || b) if (!joyre.Matches(s) || !joyre.GetMatch(&b, &l) || b)
return false; return false;
const wxChar* p = s + l; const wxString p = s.Mid(l);
int alen = len - l; int alen = len - l;
joyre.GetMatch(&b, &l, 1); joyre.GetMatch(&b, &l, 1);
joy = simple_atoi(s + b, l); joy = simple_atoi(s.Mid(b), l);
#define is_ctrl(re) re.Matches(p) && re.GetMatch(&b, &l) && l == alen && !b #define is_ctrl(re) re.Matches(p) && re.GetMatch(&b, &l) && l == alen && !b
if (is_ctrl(axre)) { if (is_ctrl(axre)) {
axre.GetMatch(&b, &l, 1); axre.GetMatch(&b, &l, 1);
key = simple_atoi(p + b, l); key = simple_atoi(p.Mid(b), l);
axre.GetMatch(&b, &l, 2); axre.GetMatch(&b, &l, 2);
mod = p[b] == wxT('+') ? WXJB_AXIS_PLUS : WXJB_AXIS_MINUS; mod = p[b] == wxT('+') ? WXJB_AXIS_PLUS : WXJB_AXIS_MINUS;
} else if (is_ctrl(butre)) { } else if (is_ctrl(butre)) {
butre.GetMatch(&b, &l, 1); butre.GetMatch(&b, &l, 1);
key = simple_atoi(p + b, l); key = simple_atoi(p.Mid(b), l);
mod = WXJB_BUTTON; mod = WXJB_BUTTON;
} else if (is_ctrl(hatre)) { } else if (is_ctrl(hatre)) {
hatre.GetMatch(&b, &l, 1); hatre.GetMatch(&b, &l, 1);
key = simple_atoi(p + 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) else if (hatre.GetMatch(&b, &l, n) && l > 0) mod = WXJB_HAT_##d
if (0) if (0)
@ -251,7 +251,7 @@ static bool ParseJoy(const wxChar* s, int len, int& mod, int& key, int& joy)
return true; return true;
} }
bool wxJoyKeyTextCtrl::ParseString(const wxChar* s, int len, int& mod, int& key, int& joy) bool wxJoyKeyTextCtrl::ParseString(const wxString& s, int len, int& mod, int& key, int& joy)
{ {
if (ParseJoy(s, len, mod, key, joy)) if (ParseJoy(s, len, mod, key, joy))
return true; return true;

View File

@ -165,7 +165,7 @@ wxString wxKeyTextCtrl::ToString(wxAcceleratorEntry_v keys, wxChar sep)
return ret; return ret;
} }
bool wxKeyTextCtrl::ParseString(const wxChar* 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;
@ -173,7 +173,7 @@ bool wxKeyTextCtrl::ParseString(const wxChar* s, int len, int& mod, int& key)
return false; return false;
wxString a = wxT('\t'); wxString a = wxT('\t');
a.append(s, len); a.Append(s.Left(len));
wxAcceleratorEntry ae; wxAcceleratorEntry ae;
#ifndef __WXMAC__ #ifndef __WXMAC__
#define check_meta(str) \ #define check_meta(str) \

View File

@ -57,7 +57,7 @@ public:
// returns empty array on parse errors // returns empty array on parse errors
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 wxChar* s, int len, int& mod, int& key, int& joy); static bool ParseString(const wxString& s, int len, int& mod, int& key, int& joy);
protected: protected:
void OnJoy(wxSDLJoyEvent&); void OnJoy(wxSDLJoyEvent&);

View File

@ -62,7 +62,7 @@ public:
// returns empty array on parse errors // returns empty array on parse errors
static wxAcceleratorEntry_v FromString(const wxString& s, wxChar sep = wxT(',')); static wxAcceleratorEntry_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 wxChar* s, int len, int& mod, int& key); static bool ParseString(const wxString& s, int len, int& mod, int& key);
protected: protected:
void OnKeyDown(wxKeyEvent&); void OnKeyDown(wxKeyEvent&);

View File

@ -350,7 +350,7 @@ void wxBoolEnHandler::Disable(wxCommandEvent& ev)
ev.Skip(); ev.Skip();
} }
static const wxChar* /* const */ val_hexdigits_s[] = { static const wxString val_hexdigits_s[] = {
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"), wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
wxT("7"), wxT("8"), wxT("9"), wxT("A"), wxT("B"), wxT("C"), wxT("D"), wxT("7"), wxT("8"), wxT("9"), wxT("A"), wxT("B"), wxT("C"), wxT("D"),
wxT("E"), wxT("F"), wxT("a"), wxT("b"), wxT("c"), wxT("d"), wxT("e"), wxT("E"), wxT("F"), wxT("a"), wxT("b"), wxT("c"), wxT("d"), wxT("e"),
@ -360,7 +360,7 @@ static const wxChar* /* const */ val_hexdigits_s[] = {
const wxArrayString val_hexdigits(sizeof(val_hexdigits_s) / sizeof(val_hexdigits_s[0]), const wxArrayString val_hexdigits(sizeof(val_hexdigits_s) / sizeof(val_hexdigits_s[0]),
val_hexdigits_s); val_hexdigits_s);
static const wxChar* /* const */ val_sigdigits_s[] = { static const wxString val_sigdigits_s[] = {
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"), wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
wxT("7"), wxT("8"), wxT("9"), wxT("-"), wxT("+") wxT("7"), wxT("8"), wxT("9"), wxT("-"), wxT("+")
}; };
@ -368,7 +368,7 @@ static const wxChar* /* const */ val_sigdigits_s[] = {
const wxArrayString val_sigdigits(sizeof(val_sigdigits_s) / sizeof(val_sigdigits_s[0]), const wxArrayString val_sigdigits(sizeof(val_sigdigits_s) / sizeof(val_sigdigits_s[0]),
val_sigdigits_s); val_sigdigits_s);
static const wxChar* /* const */ val_unsdigits_s[] = { static const wxString val_unsdigits_s[] = {
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"), wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
wxT("7"), wxT("8"), wxT("9") wxT("7"), wxT("8"), wxT("9")
}; };

View File

@ -503,10 +503,10 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
for (int i = 0; i < num_opts; i++) { for (int i = 0; i < num_opts; i++) {
wxPrintf(wxT("%s (%s"), opts[i].opt, wxPrintf(wxT("%s (%s"), opts[i].opt,
opts[i].boolopt ? (const wxChar*)wxT("flag") : opts[i].stropt ? (const wxChar*)wxT("string") : opts[i].enumvals ? opts[i].enumvals : opts[i].intopt ? (const wxChar*)wxT("int") : opts[i].doubleopt ? (const wxChar*)wxT("decimal") : (const wxChar*)wxT("string")); opts[i].boolopt ? wxT("flag") : opts[i].stropt ? wxT("string") : !opts[i].enumvals.empty() ? opts[i].enumvals : (wxString)(opts[i].intopt ? wxT("int") : opts[i].doubleopt ? wxT("decimal") : wxT("string")));
if (opts[i].enumvals) { if (!opts[i].enumvals.empty()) {
const wxChar* evx = wxGetTranslation(opts[i].enumvals); const wxString evx = wxGetTranslation(opts[i].enumvals);
if (wxStrcmp(evx, opts[i].enumvals)) if (wxStrcmp(evx, opts[i].enumvals))
wxPrintf(wxT(" = %s"), evx); wxPrintf(wxT(" = %s"), evx);
@ -514,7 +514,7 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
wxPrintf(wxT(")\n\t%s\n\n"), opts[i].desc); wxPrintf(wxT(")\n\t%s\n\n"), opts[i].desc);
if (opts[i].enumvals) if (!opts[i].enumvals.empty())
opts[i].enumvals = wxGetTranslation(opts[i].enumvals); opts[i].enumvals = wxGetTranslation(opts[i].enumvals);
} }
@ -568,7 +568,7 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
} }
} }
home = strdup((const char*)wxApp::argv[0]); home = strdup(wxApp::argv[0].utf8_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);

View File

@ -632,7 +632,7 @@ void systemScreenMessage(const wxString& msg);
// sorted by cmd field for binary searching // sorted by cmd field for binary searching
// filled in by copy-events.cmake // filled in by copy-events.cmake
extern struct cmditem { extern struct cmditem {
const wxChar *cmd, *name; const wxString cmd, name;
int cmd_id; int cmd_id;
int mask_flags; // if non-0, one of the flags must be turned on in win int mask_flags; // if non-0, one of the flags must be turned on in win
// to enable this command // to enable this command