Commit 02b3defc authored by Rafael Kitover's avatar Rafael Kitover
Browse files

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.
parent fa9afa4e
......@@ -54,7 +54,7 @@ And the following development libraries:
- [SDL](https://www.libsdl.org/)2 (required)
- [SFML](https://www.sfml-dev.org/) (optional, for link)
- 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
to (usually 2 or 3).
......
......@@ -422,6 +422,7 @@ SET( SRC_WX
panel.cpp
viewsupt.cpp
wayland.cpp
strutils.cpp
widgets/keyedit.cpp
widgets/joyedit.cpp
widgets/sdljoy.cpp
......
......@@ -547,7 +547,7 @@ EVT_HANDLER_MASK(RomInformation, "ROM information...", CMDEN_GB | CMDEN_GBA)
s.Printf(wxT("%02x"), gbRom[0x14b]);
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);
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);
setlabs("GameCode", rom[0xac], 4);
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);
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;
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
msg.Printf(_("Error loading battery %s"), fn.c_str());
msg.Printf(_("Error loading battery %s"), fn.mb_str());
systemScreenMessage(msg);
}
......@@ -902,7 +902,7 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN
wxFFile f(fn, wxT("rb"));
if (!f.IsOpened()) {
wxLogError(_("Cannot open file %s"), fn.c_str());
wxLogError(_("Cannot open file %s"), fn.mb_str());
return;
}
......@@ -912,7 +912,7 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN
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)) {
wxLogError(_("Unsupported code file %s"), fn.c_str());
wxLogError(_("Unsupported code file %s"), fn.mb_str());
return;
}
......@@ -982,9 +982,9 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN
}
if (res)
msg.Printf(_("Loaded code file %s"), fn.c_str());
msg.Printf(_("Loaded code file %s"), fn.mb_str());
else
msg.Printf(_("Error loading code file %s"), fn.c_str());
msg.Printf(_("Error loading code file %s"), fn.mb_str());
systemScreenMessage(msg);
}
......@@ -1030,9 +1030,9 @@ EVT_HANDLER_MASK(ImportGamesharkActionReplaySnapshot,
}
if (res)
msg.Printf(_("Loaded snapshot file %s"), fn.c_str());
msg.Printf(_("Loaded snapshot file %s"), fn.mb_str());
else
msg.Printf(_("Error loading snapshot file %s"), fn.c_str());
msg.Printf(_("Error loading snapshot file %s"), fn.mb_str());
systemScreenMessage(msg);
}
......@@ -1055,9 +1055,9 @@ EVT_HANDLER_MASK(ExportBatteryFile, "Export battery file...", CMDEN_GB | CMDEN_G
wxString msg;
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
msg.Printf(_("Error writing battery %s"), fn.c_str());
msg.Printf(_("Error writing battery %s"), fn.mb_str());
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
// little-endian
// fix in GBA.cpp
if (CPUWriteGSASnapshot(fn.mb_fn_str(), tit->GetValue().utf8_str(),
dsc->GetValue().utf8_str(), n->GetValue().utf8_str()))
msg.Printf(_("Saved snapshot file %s"), fn.c_str());
if (CPUWriteGSASnapshot(fn.mb_str(), tit->GetValue().mb_str(),
dsc->GetValue().mb_str(), n->GetValue().mb_str()))
msg.Printf(_("Saved snapshot file %s"), fn.mb_str());
else
msg.Printf(_("Error saving snapshot file %s"), fn.c_str());
msg.Printf(_("Error saving snapshot file %s"), fn.mb_str());
systemScreenMessage(msg);
}
......@@ -1140,7 +1140,7 @@ EVT_HANDLER_MASK(ScreenCapture, "Screen capture...", CMDEN_GB | CMDEN_GBA)
panel->emusys->emuWriteBMP(fn.mb_fn_str());
wxString msg;
msg.Printf(_("Wrote snapshot %s"), fn.c_str());
msg.Printf(_("Wrote snapshot %s"), fn.mb_str());
systemScreenMessage(msg);
}
......@@ -1936,7 +1936,7 @@ void MainFrame::GDBBreak()
if (!debugOpenPty())
return;
msg.Printf(_("Waiting for connection at %s"), debugGetSlavePty().c_str());
msg.Printf(_("Waiting for connection at %s"), debugGetSlavePty().mb_str());
} else
#endif
{
......
......@@ -110,10 +110,10 @@ public:
char host[length];
GetLinkServerHost(host, length);
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 {
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
......@@ -1802,7 +1802,7 @@ public:
// to put the plugins... it depends on where program was
// installed, and of course OS
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);
ch->Hide();
txt->Hide();
......@@ -2298,7 +2298,7 @@ void CheckThrowXRCError(T pointer, const wxString& name)
std::string errormessage = "Unable to load a \"";
errormessage += typeid(pointer).name();
errormessage += "\" from the builtin xrc file: ";
errormessage += name.utf8_str();
errormessage += name.mb_str();
throw std::runtime_error(errormessage);
}
}
......@@ -2661,9 +2661,9 @@ bool MainFrame::BindControls()
if (a->GetFlags() == e->GetFlags() && a->GetKeyCode() == e->GetKeyCode()) {
if (e->GetMenuItem()) {
wxLogInfo(_("Duplicate menu accelerator: %s for %s and %s; keeping first"),
wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(),
e->GetMenuItem()->GetItemLabelText().c_str(),
mi->GetItemLabelText().c_str());
wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).mb_str(),
e->GetMenuItem()->GetItemLabelText().mb_str(),
mi->GetItemLabelText().mb_str());
delete a;
a = 0;
} else {
......@@ -2675,8 +2675,8 @@ bool MainFrame::BindControls()
break;
wxLogInfo(_("Menu accelerator %s for %s overrides default for %s ; keeping menu"),
wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).c_str(),
mi->GetItemLabelText().c_str(),
wxKeyTextCtrl::ToString(a->GetFlags(), a->GetKeyCode()).mb_str(),
mi->GetItemLabelText().mb_str(),
cmdtab[cmd].cmd);
}
......@@ -2781,7 +2781,7 @@ bool MainFrame::BindControls()
for (int i = 0; i < checkable_mi.size(); i++)
if (!checkable_mi[i].boolopt && !checkable_mi[i].intopt) {
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 = NULL;
}
......
#include "../common/ConfigManager.h"
#include "wxvbam.h"
#include <algorithm>
#include <string>
#include <vector>
#include <wx/display.h>
#include "strutils.h"
/*
disableSfx(F) -> cpuDisableSfx
......@@ -21,15 +20,15 @@
}
#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) \
{ \
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) \
{ \
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) \
{ \
......@@ -333,31 +332,6 @@ bool opt_lt(const opt_desc& opt1, const opt_desc& opt2)
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/*)
void load_opts()
......@@ -389,7 +363,7 @@ void load_opts()
for (cont = cfg->GetFirstEntry(s, grp_idx); cont;
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);
}
......@@ -427,7 +401,7 @@ void load_opts()
for (cont = cfg->GetFirstGroup(e, key_idx); cont;
cont = cfg->GetNextGroup(e, key_idx)) {
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);
s.resize(poff2);
}
......@@ -442,7 +416,7 @@ void load_opts()
if (i == NUM_KEYS) {
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);
s.resize(poff2);
}
......@@ -454,7 +428,7 @@ void load_opts()
} else {
s.append(wxT('/'));
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);
s.resize(poff);
}
......@@ -464,23 +438,23 @@ void load_opts()
cont = cfg->GetNextEntry(e, entry_idx)) {
// kb options come from a different list
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)) {
s.append(wxT('/'));
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);
s.resize(poff);
}
} else {
s.append(wxT('/'));
s.append(e);
const opt_desc dummy = { s.c_str() };
const opt_desc dummy = { s };
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")) {
//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);
}
......@@ -507,13 +481,13 @@ void load_opts()
if (opt.stropt) {
opt.curstr = *opt.stropt;
} 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;
bool gotit = cfg->Read(opt.opt, &s); s.MakeLower();
if (gotit && !s.empty()) {
const std::size_t found_pos = enum_idx(enum_opts, s);
const bool matched = found_pos != wxNOT_FOUND;
const auto found_pos = vec_find(enum_opts, s);
const bool matched = found_pos != wxNOT_FOUND;
if (!matched) {
opt.curint = 0;
......@@ -560,7 +534,7 @@ void load_opts()
wxString optn;
optn.Printf(wxT("GB/Palette%d"), i);
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);
wxString entry;
......@@ -605,7 +579,7 @@ void load_opts()
gopts.joykey_bindings[i][j] = wxJoyKeyTextCtrl::FromString(s);
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 {
s = wxJoyKeyTextCtrl::ToString(gopts.joykey_bindings[i][j]);
cfg->Write(optname, s);
......@@ -626,7 +600,7 @@ void load_opts()
wxAcceleratorEntry_v val = wxKeyTextCtrl::FromString(s);
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 {
for (int j = 0; j < val.size(); j++)
val[j].Set(val[j].GetFlags(), val[j].GetKeyCode(),
......@@ -662,7 +636,7 @@ void update_opts()
} else if (!opt.enumvals.empty()) {
if (*opt.intopt != opt.curint) {
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]);
}
......@@ -683,7 +657,7 @@ void update_opts()
for (int i = 0; i < 3; i++) {
wxString optn;
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);
wxString val;
wxString entry;
......@@ -727,7 +701,7 @@ void update_opts()
for (bool cont = cfg->GetFirstEntry(s, entry_idx); cont;
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);
int i;
......@@ -793,9 +767,9 @@ bool opt_set(const wxString& name, const wxString& val)
} else if (!opt->enumvals.empty()) {
wxString s = val; s.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;
if (!matched) {
......@@ -863,7 +837,7 @@ bool opt_set(const wxString& name, const wxString& val)
if (name.Find(wxT('/')) == wxNOT_FOUND)
return false;
auto parts = split(name, wxT("/"));
auto parts = str_split(name, wxT("/"));
if (parts[0] != wxT("Keyboard")) {
const cmditem parts_1 = { parts[1] };
......
......@@ -81,7 +81,7 @@ void GameArea::LoadGame(const wxString& name)
if (t == IMAGE_UNKNOWN) {
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);
dlg.ShowModal();
return;
......@@ -138,7 +138,7 @@ void GameArea::LoadGame(const wxString& name)
if (t == IMAGE_GB) {
if (!gbLoadRom(fn)) {
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);
dlg.ShowModal();
return;
......@@ -188,7 +188,7 @@ void GameArea::LoadGame(const wxString& name)
gbCPUInit(fn, use_bios);
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
// user to do it
}
......@@ -211,7 +211,7 @@ void GameArea::LoadGame(const wxString& name)
{
if (!(rom_size = CPULoadRom(fn))) {
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);
dlg.ShowModal();
return;
......@@ -285,7 +285,7 @@ void GameArea::LoadGame(const wxString& name)
CPUInit(gopts.gba_bios.mb_fn_str(), useBiosFileGBA);
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
// user to do it
}
......@@ -354,7 +354,7 @@ void GameArea::LoadGame(const wxString& name)
if (emusys->emuReadBattery(fnb.data())) {
wxString msg;
msg.Printf(_("Loaded battery %s"), bat.GetFullPath().c_str());
msg.Printf(_("Loaded battery %s"), bat.GetFullPath().mb_str());
systemScreenMessage(msg);
if (cpuSaveType == 0 && ovSaveType == 0 && t == IMAGE_GBA) {
......@@ -570,7 +570,7 @@ bool GameArea::LoadState()
bool GameArea::LoadState(int slot)
{
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));
}
......@@ -604,7 +604,7 @@ bool GameArea::LoadState(const wxFileName& fname)
wxString msg;
msg.Printf(ret ? _("Loaded state %s") : _("Error loading state %s"),
fname.GetFullPath().c_str());
fname.GetFullPath().mb_str());
systemScreenMessage(msg);
return ret;
}
......@@ -617,7 +617,7 @@ bool GameArea::SaveState()
bool GameArea::SaveState(int slot)
{
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));
}
......@@ -628,7 +628,7 @@ bool GameArea::SaveState(const wxFileName& fname)
wxGetApp().frame->update_state_ts(true);
wxString msg;
msg.Printf(ret ? _("Saved state %s") : _("Error saving state %s"),
fname.GetFullPath().c_str());
fname.GetFullPath().mb_str());
systemScreenMessage(msg);
return ret;
}
......@@ -659,9 +659,9 @@ void GameArea::SaveBattery(bool quiet)
// of course some games just write battery way too often for such
// a thing to be useful
if (emusys->emuWriteBattery(fnb.data()))
msg.Printf(_("Wrote battery %s"), fn.c_str());
msg.Printf(_("Wrote battery %s"), fn.mb_str());
else
msg.Printf(_("Error writing battery %s"), fn.c_str());
msg.Printf(_("Error writing battery %s"), fn.mb_str());
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
......@@ -1782,7 +1782,7 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
if (panel->osdstat.size())
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 (systemGetClock() - panel->osdtime < OSD_TIME) {
......@@ -1790,7 +1790,7 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
int linelen = std::ceil(width * scale - 20) / 8;
int nlines = (message.size() + linelen - 1) / linelen;
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* ptr = &buf[0];
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,
systemColorDepth))
!= 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));
else {
MainFrame* mf = wxGetApp().frame;
......@@ -2293,7 +2293,7 @@ void GameArea::StartSoundRecording(const wxString& fname)
MediaRet ret;
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));
else {
MainFrame* mf = wxGetApp().frame;
......
#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);
}
#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
......@@ -44,7 +44,7 @@ void systemMessage(int id, const char* fmt, ...)
va_list args;
// auto-conversion of wxCharBuffer to const char * seems broken
// 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) {
buf = (char*)malloc(buflen);
......@@ -71,7 +71,7 @@ void systemMessage(int id, const char* fmt, ...)
exit(1);
}
wxLogError(wxT("%s"), wxString(buf, wxConvLibc).c_str());
wxLogError(wxT("%s"), wxString(buf, wxConvLibc).mb_str());
}
static int frames = 0;
......@@ -128,8 +128,8 @@ void systemStartGameRecording(const wxString& fname)
uint32_t version = 1;
if (!game_file.Open(fn.c_str(), wxT("wb")) || game_file.Write(&version, sizeof(version)) != sizeof(version)) {
wxLogError(_("Cannot open output file %s"), fname.c_str());
if (!game_file.Open(fn, wxT("wb")) || game_file.Write(&version, sizeof(version)) != sizeof(version)) {
wxLogError(_("Cannot open output file %s"), fname.mb_str());
return;
}
......@@ -189,8 +189,8 @@ void systemStartGamePlayback(const wxString& fname)