diff --git a/src/System.h b/src/System.h index fa9a0a7b..deb1eb70 100644 --- a/src/System.h +++ b/src/System.h @@ -5,6 +5,10 @@ #define winlog log +#ifdef __LIBRETRO__ +#define utilOpenFile fopen +#endif + class SoundDriver; struct EmulatedSystem { diff --git a/src/Util.cpp b/src/Util.cpp index 5c15e7e0..b14fd983 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -72,6 +72,45 @@ bool FileExists(const char *filename) #endif } +#ifdef _WIN32 +#include + +wchar_t* utf8ToUtf16(const char *utf8) +{ + wchar_t *utf16 = nullptr; + size_t size = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL , 0); + if (size == 0) return nullptr; // error + utf16 = new wchar_t[size]; + size = MultiByteToWideChar(CP_UTF8, 0, utf8 , -1, utf16, size); + if (size == 0) { + delete[] utf16; + return nullptr; // error + } + return utf16; +} +#endif // _WIN32 + +FILE* utilOpenFile(const char *filename, const char *mode) +{ + FILE *f = NULL; +#ifdef _WIN32 + wchar_t *wfilename = utf8ToUtf16(filename); + if (!wfilename) return nullptr; + wchar_t *wmode = utf8ToUtf16(mode); + if (!wmode) { + delete[] wfilename; + return nullptr; + } + + f = _wfopen(wfilename, wmode); + delete[] wfilename; + delete[] wmode; +#else + f = fopen(filename, mode); +#endif // _WIN32 + return f; +} + // Get user-specific config dir manually. // apple: ~/Library/Application Support/ // windows: %APPDATA%/ @@ -504,10 +543,6 @@ static bool utilIsImage(const char *file) return utilIsGBAImage(file) || utilIsGBImage(file); } -#ifdef WIN32 -#include -#endif - IMAGE_TYPE utilFindType(const char *file, char (&buffer)[2048]); IMAGE_TYPE utilFindType(const char *file) @@ -590,7 +625,7 @@ uint8_t *utilLoad(const char *file, bool (*accept)(const char *), uint8_t *data, if (size > MAX_CART_SIZE) return NULL; - + uint8_t *image = data; if (image == NULL) { @@ -722,6 +757,19 @@ void utilWriteData(gzFile gzFile, variable_desc *data) } } +gzFile utilAutoGzOpen(const char *file, const char *mode) +{ +#ifdef _WIN32 + wchar_t *wfile = utf8ToUtf16(file); + if (!wfile) return nullptr; + gzFile handler = gzopen_w(wfile, mode); + delete[] wfile; + return handler; +#else + return gzopen(file, mode); +#endif +} + gzFile utilGzOpen(const char *file, const char *mode) { utilGzWriteFunc = (int(ZEXPORT *)(gzFile, void *const, unsigned int))gzwrite; @@ -729,7 +777,7 @@ gzFile utilGzOpen(const char *file, const char *mode) utilGzCloseFunc = gzclose; utilGzSeekFunc = gzseek; - return gzopen(file, mode); + return utilAutoGzOpen(file, mode); } gzFile utilMemGzOpen(char *memory, int available, const char *mode) diff --git a/src/Util.h b/src/Util.h index 5f738576..eb010df5 100644 --- a/src/Util.h +++ b/src/Util.h @@ -53,6 +53,8 @@ int utilReadIntMem(const uint8_t *&data); void utilReadMem(void *buf, const uint8_t *&data, unsigned size); void utilReadDataMem(const uint8_t *&data, variable_desc *); #else +FILE* utilOpenFile(const char *filename, const char *mode); +gzFile utilAutoGzOpen(const char *file, const char *mode); gzFile utilGzOpen(const char *file, const char *mode); gzFile utilMemGzOpen(char *memory, int available, const char *mode); int utilGzWrite(gzFile file, const voidp buffer, unsigned int len); diff --git a/src/common/ConfigManager.cpp b/src/common/ConfigManager.cpp index bfc19e82..da9bd7c5 100644 --- a/src/common/ConfigManager.cpp +++ b/src/common/ConfigManager.cpp @@ -758,7 +758,7 @@ void SaveConfigFile() if (configFile != NULL) { - FILE *f = fopen(configFile, "w"); + FILE *f = utilOpenFile(configFile, "w"); if (f == NULL) { char err_msg[4096] = "unknown error"; strncpy(err_msg, strerror(errno), 4096); @@ -896,7 +896,7 @@ int ReadOpts(int argc, char ** argv) log("Missing config file name\n"); break; } - FILE *f = fopen(optarg, "r"); + FILE *f = utilOpenFile(optarg, "r"); if (f == NULL) { log("File not found %s\n", optarg); break; diff --git a/src/common/Patch.cpp b/src/common/Patch.cpp index 546f734f..3c515390 100644 --- a/src/common/Patch.cpp +++ b/src/common/Patch.cpp @@ -145,7 +145,7 @@ static uLong computePatchCRC(FILE* f, unsigned int size) static bool patchApplyIPS(const char* patchname, uint8_t** r, int* s) { // from the IPS spec at http://zerosoft.zophar.net/ips.htm - FILE* f = fopen(patchname, "rb"); + FILE* f = utilOpenFile(patchname, "rb"); if (!f) return false; @@ -207,7 +207,7 @@ static bool patchApplyUPS(const char* patchname, uint8_t** rom, int* size) { int64_t srcCRC, dstCRC, patchCRC; - FILE* f = fopen(patchname, "rb"); + FILE* f = utilOpenFile(patchname, "rb"); if (!f) return false; @@ -297,7 +297,7 @@ static bool patchApplyBPS(const char* patchname, uint8_t** rom, int* size) { int64_t srcCRC, dstCRC, patchCRC; - FILE* f = fopen(patchname, "rb"); + FILE* f = utilOpenFile(patchname, "rb"); if (!f) return false; @@ -570,7 +570,7 @@ static bool patchApplyPPF3(FILE* f, uint8_t** rom, int* size) static bool patchApplyPPF(const char* patchname, uint8_t** rom, int* size) { - FILE* f = fopen(patchname, "rb"); + FILE* f = utilOpenFile(patchname, "rb"); if (!f) return false; diff --git a/src/common/Patch.h b/src/common/Patch.h index 1e69eb4f..302ce6e7 100644 --- a/src/common/Patch.h +++ b/src/common/Patch.h @@ -1,6 +1,7 @@ #ifndef PATCH_H #define PATCH_H +#include "../Util.h" #include "Types.h" bool applyPatch(const char *patchname, uint8_t **rom, int *size); diff --git a/src/gb/GB.cpp b/src/gb/GB.cpp index b95edc31..7966c07c 100644 --- a/src/gb/GB.cpp +++ b/src/gb/GB.cpp @@ -2860,7 +2860,7 @@ void gbReset() void gbWriteSaveMBC1(const char* name) { if (gbRam) { - FILE* gzFile = fopen(name, "wb"); + FILE* gzFile = utilOpenFile(name, "wb"); if (gzFile == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name); @@ -2879,7 +2879,7 @@ void gbWriteSaveMBC1(const char* name) void gbWriteSaveMBC2(const char* name) { if (gbRam) { - FILE* file = fopen(name, "wb"); + FILE* file = utilOpenFile(name, "wb"); if (file == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name); @@ -2898,7 +2898,7 @@ void gbWriteSaveMBC2(const char* name) void gbWriteSaveMBC3(const char* name, bool extendedSave) { if (gbRam || extendedSave) { - FILE* gzFile = fopen(name, "wb"); + FILE* gzFile = utilOpenFile(name, "wb"); if (gbRam) { if (gzFile == NULL) { @@ -2925,7 +2925,7 @@ void gbWriteSaveMBC3(const char* name, bool extendedSave) void gbWriteSaveMBC5(const char* name) { if (gbRam) { - FILE* gzFile = fopen(name, "wb"); + FILE* gzFile = utilOpenFile(name, "wb"); if (gzFile == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name); @@ -2944,7 +2944,7 @@ void gbWriteSaveMBC5(const char* name) void gbWriteSaveMBC7(const char* name) { if (gbRam) { - FILE* file = fopen(name, "wb"); + FILE* file = utilOpenFile(name, "wb"); if (file == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name); @@ -2962,7 +2962,7 @@ void gbWriteSaveMBC7(const char* name) void gbWriteSaveTAMA5(const char* name, bool extendedSave) { - FILE* gzFile = fopen(name, "wb"); + FILE* gzFile = utilOpenFile(name, "wb"); if (gzFile == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name); @@ -2991,7 +2991,7 @@ void gbWriteSaveTAMA5(const char* name, bool extendedSave) void gbWriteSaveMMM01(const char* name) { if (gbRam) { - FILE* gzFile = fopen(name, "wb"); + FILE* gzFile = utilOpenFile(name, "wb"); if (gzFile == NULL) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name); @@ -3010,7 +3010,7 @@ void gbWriteSaveMMM01(const char* name) bool gbReadSaveMBC1(const char* name) { if (gbRam) { - gzFile gzFile = gzopen(name, "rb"); + gzFile gzFile = utilAutoGzOpen(name, "rb"); if (gzFile == NULL) { return false; @@ -3052,7 +3052,7 @@ bool gbReadSaveMBC1(const char* name) bool gbReadSaveMBC2(const char* name) { if (gbRam) { - FILE* file = fopen(name, "rb"); + FILE* file = utilOpenFile(name, "rb"); if (file == NULL) { return false; @@ -3095,7 +3095,7 @@ bool gbReadSaveMBC2(const char* name) bool gbReadSaveMBC3(const char* name) { - gzFile gzFile = gzopen(name, "rb"); + gzFile gzFile = utilAutoGzOpen(name, "rb"); if (gzFile == NULL) { return false; @@ -3151,7 +3151,7 @@ bool gbReadSaveMBC3(const char* name) bool gbReadSaveMBC5(const char* name) { if (gbRam) { - gzFile gzFile = gzopen(name, "rb"); + gzFile gzFile = utilAutoGzOpen(name, "rb"); if (gzFile == NULL) { return false; @@ -3193,7 +3193,7 @@ bool gbReadSaveMBC5(const char* name) bool gbReadSaveMBC7(const char* name) { if (gbRam) { - FILE* file = fopen(name, "rb"); + FILE* file = utilOpenFile(name, "rb"); if (file == NULL) { return false; @@ -3236,7 +3236,7 @@ bool gbReadSaveMBC7(const char* name) bool gbReadSaveTAMA5(const char* name) { - gzFile gzFile = gzopen(name, "rb"); + gzFile gzFile = utilAutoGzOpen(name, "rb"); if (gzFile == NULL) { return false; @@ -3295,7 +3295,7 @@ bool gbReadSaveTAMA5(const char* name) bool gbReadSaveMMM01(const char* name) { if (gbRam) { - gzFile gzFile = gzopen(name, "rb"); + gzFile gzFile = utilAutoGzOpen(name, "rb"); if (gzFile == NULL) { return false; @@ -3489,7 +3489,7 @@ bool gbReadBatteryFile(const char* file) bool gbReadGSASnapshot(const char* fileName) { - FILE* file = fopen(fileName, "rb"); + FILE* file = utilOpenFile(fileName, "rb"); if (!file) { systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); diff --git a/src/gb/gbCheats.cpp b/src/gb/gbCheats.cpp index e75039af..2b5bd7d9 100644 --- a/src/gb/gbCheats.cpp +++ b/src/gb/gbCheats.cpp @@ -105,7 +105,7 @@ void gbCheatsSaveCheatList(const char* file) { if (gbCheatNumber == 0) return; - FILE* f = fopen(file, "wb"); + FILE* f = utilOpenFile(file, "wb"); if (f == NULL) return; int version = 1; @@ -125,7 +125,7 @@ bool gbCheatsLoadCheatList(const char* file) int count = 0; - FILE* f = fopen(file, "rb"); + FILE* f = utilOpenFile(file, "rb"); if (f == NULL) return false; @@ -396,7 +396,7 @@ void gbCheatDisable(int i) bool gbCheatReadGSCodeFile(const char* fileName) { - FILE* file = fopen(fileName, "rb"); + FILE* file = utilOpenFile(fileName, "rb"); if (!file) { systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); diff --git a/src/gba/Cheats.cpp b/src/gba/Cheats.cpp index b32c87c6..a7ae6294 100644 --- a/src/gba/Cheats.cpp +++ b/src/gba/Cheats.cpp @@ -2035,7 +2035,7 @@ void cheatsAddGSACode(const char* code, const char* desc, bool v3) bool cheatsImportGSACodeFile(const char* name, int game, bool v3) { - FILE* f = fopen(name, "rb"); + FILE* f = utilOpenFile(name, "rb"); if (!f) return false; @@ -2587,7 +2587,7 @@ void cheatsReadGame(gzFile file, int version) cheatsNumber = 0; cheatsNumber = utilReadInt(file); - + if (cheatsNumber > MAX_CHEATS) cheatsNumber = MAX_CHEATS; @@ -2674,7 +2674,7 @@ void cheatsSaveCheatList(const char* file) { if (cheatsNumber == 0) return; - FILE* f = fopen(file, "wb"); + FILE* f = utilOpenFile(file, "wb"); if (f == NULL) return; int version = 1; @@ -2691,7 +2691,7 @@ bool cheatsLoadCheatList(const char* file) int count = 0; - FILE* f = fopen(file, "rb"); + FILE* f = utilOpenFile(file, "rb"); if (f == NULL) return false; diff --git a/src/gba/GBA.cpp b/src/gba/GBA.cpp index 25c6774b..9ee87854 100644 --- a/src/gba/GBA.cpp +++ b/src/gba/GBA.cpp @@ -951,7 +951,7 @@ bool CPUReadState(const char* file) bool CPUExportEepromFile(const char* fileName) { if (eepromInUse) { - FILE* file = fopen(fileName, "wb"); + FILE* file = utilOpenFile(fileName, "wb"); if (!file) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), @@ -976,7 +976,7 @@ bool CPUExportEepromFile(const char* fileName) bool CPUWriteBatteryFile(const char* fileName) { if ((saveType) && (saveType != GBA_SAVE_NONE)) { - FILE* file = fopen(fileName, "wb"); + FILE* file = utilOpenFile(fileName, "wb"); if (!file) { systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), @@ -1011,7 +1011,7 @@ bool CPUWriteBatteryFile(const char* fileName) bool CPUReadGSASnapshot(const char* fileName) { int i; - FILE* file = fopen(fileName, "rb"); + FILE* file = utilOpenFile(fileName, "rb"); if (!file) { systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); @@ -1080,8 +1080,8 @@ bool CPUReadGSASPSnapshot(const char* fileName) const size_t footerpos = 0x42c, footersz = 4; char footer[footersz + 1], romname[namesz + 1], savename[namesz + 1]; - ; - FILE* file = fopen(fileName, "rb"); + + FILE* file = utilOpenFile(fileName, "rb"); if (!file) { systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); @@ -1134,7 +1134,7 @@ bool CPUWriteGSASnapshot(const char* fileName, const char* desc, const char* notes) { - FILE* file = fopen(fileName, "wb"); + FILE* file = utilOpenFile(fileName, "wb"); if (!file) { systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); @@ -1191,7 +1191,7 @@ bool CPUWriteGSASnapshot(const char* fileName, bool CPUImportEepromFile(const char* fileName) { - FILE* file = fopen(fileName, "rb"); + FILE* file = utilOpenFile(fileName, "rb"); if (!file) return false; @@ -1235,7 +1235,7 @@ bool CPUImportEepromFile(const char* fileName) bool CPUReadBatteryFile(const char* fileName) { - FILE* file = fopen(fileName, "rb"); + FILE* file = utilOpenFile(fileName, "rb"); if (!file) return false; @@ -1488,7 +1488,7 @@ int CPULoadRom(const char* szFile) #ifndef NO_DEBUGGER if (CPUIsELF(szFile)) { - FILE* f = fopen(szFile, "rb"); + FILE* f = utilOpenFile(szFile, "rb"); if (!f) { systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), szFile); @@ -1715,8 +1715,7 @@ const char* GetSaveDotCodeFile() void ResetLoadDotCodeFile() { - if(loadDotCodeFile) - { + if (loadDotCodeFile) { free((char*)loadDotCodeFile); } @@ -1730,8 +1729,7 @@ void SetLoadDotCodeFile(const char* szFile) void ResetSaveDotCodeFile() { - if (saveDotCodeFile) - { + if (saveDotCodeFile) { free((char*)saveDotCodeFile); } diff --git a/src/gba/ereader.cpp b/src/gba/ereader.cpp index f1ef5885..feadc5f4 100644 --- a/src/gba/ereader.cpp +++ b/src/gba/ereader.cpp @@ -236,9 +236,9 @@ void BIOS_EReader_ScanCard(int swi_num) reg[0].I = 0x301; return; } - f = fopen(loadDotCodeFile, "rb"); - //f=fopen(filebuffer,"rb"); - //f=fopen("dotcode4.raw","rb"); + f = utilOpenFile(loadDotCodeFile, "rb"); + //f=utilOpenFile(filebuffer,"rb"); + //f=utilOpenFile("dotcode4.raw","rb"); if (f == NULL) { reg[0].I = 0x303; return; @@ -502,7 +502,7 @@ void BIOS_EReader_ScanCard(int swi_num) } if (swi_num == 0xE3) { const char* loadDotCodeFile = GetLoadDotCodeFile(); - f = fopen(loadDotCodeFile, "rb+"); + f = utilOpenFile(loadDotCodeFile, "rb+"); if (f != NULL) { fwrite(dotcodedata, 1, j, f); fclose(f); @@ -510,7 +510,7 @@ void BIOS_EReader_ScanCard(int swi_num) } else { const char* saveDotCodeFile = GetSaveDotCodeFile(); if (saveDotCodeFile) { - f = fopen(saveDotCodeFile, "wb"); + f = utilOpenFile(saveDotCodeFile, "wb"); if (f != NULL) { fwrite(dotcodedata, 1, j, f); fwrite(Signature, 1, 0x28, f); diff --git a/src/wx/cmdevents.cpp b/src/wx/cmdevents.cpp index b44078d1..9fae81b1 100644 --- a/src/wx/cmdevents.cpp +++ b/src/wx/cmdevents.cpp @@ -856,7 +856,7 @@ EVT_HANDLER_MASK(SetLoadingDotCodeFile, "Load e-Reader Dot Code...", CMDEN_GBA) return; loaddotcodefile_path = dlg.GetPath(); - SetLoadDotCodeFile(loaddotcodefile_path.mb_str()); + SetLoadDotCodeFile(UTF8(loaddotcodefile_path)); } EVT_HANDLER_MASK(ResetSavingDotCodeFile, "Reset Saving e-Reader Dot Code", CMDEN_GBA) @@ -878,7 +878,7 @@ EVT_HANDLER_MASK(SetSavingDotCodeFile, "Save e-Reader Dot Code...", CMDEN_GBA) return; savedotcodefile_path = dlg.GetPath(); - SetSaveDotCodeFile(savedotcodefile_path.mb_str()); + SetSaveDotCodeFile(UTF8(savedotcodefile_path)); } static wxString batimp_path; @@ -903,10 +903,10 @@ EVT_HANDLER_MASK(ImportBatteryFile, "Import battery file...", CMDEN_GB | CMDEN_G if (ret == wxYES) { wxString msg; - if (panel->emusys->emuReadBattery(fn.mb_fn_str())) - msg.Printf(_("Loaded battery %s"), fn.c_str()); + if (panel->emusys->emuReadBattery(UTF8(fn))) + msg.Printf(_("Loaded battery %s"), fn.wc_str()); else - msg.Printf(_("Error loading battery %s"), fn.c_str()); + msg.Printf(_("Error loading battery %s"), fn.wc_str()); systemScreenMessage(msg); } @@ -936,7 +936,7 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN // FIXME: this routine will not work on big-endian systems // if the underlying file format is little-endian // (fix in gb/gbCheats.cpp) - res = gbCheatReadGSCodeFile(fn.mb_fn_str()); + res = gbCheatReadGSCodeFile(UTF8(fn)); else { // need to select game first wxFFile f(fn, wxT("rb")); @@ -1018,13 +1018,13 @@ EVT_HANDLER_MASK(ImportGamesharkCodeFile, "Import GameShark code file...", CMDEN // FIXME: this routine will not work on big-endian systems // if the underlying file format is little-endian // (fix in gba/Cheats.cpp) - res = cheatsImportGSACodeFile(fn.mb_fn_str(), game, v3); + res = cheatsImportGSACodeFile(UTF8(fn), game, v3); } if (res) - msg.Printf(_("Loaded code file %s"), fn.c_str()); + msg.Printf(_("Loaded code file %s"), fn.wc_str()); else - msg.Printf(_("Error loading code file %s"), fn.c_str()); + msg.Printf(_("Error loading code file %s"), fn.wc_str()); systemScreenMessage(msg); } @@ -1053,7 +1053,7 @@ EVT_HANDLER_MASK(ImportGamesharkActionReplaySnapshot, bool res; if (panel->game_type() == IMAGE_GB) - res = gbReadGSASnapshot(fn.mb_fn_str()); + res = gbReadGSASnapshot(UTF8(fn)); else { bool gsv = fn.size() >= 4 && wxString(fn.substr(fn.size() - 4)).IsSameAs(wxT(".gsv"), false); @@ -1061,18 +1061,18 @@ EVT_HANDLER_MASK(ImportGamesharkActionReplaySnapshot, // FIXME: this will fail on big-endian machines if // file format is little-endian // fix in GBA.cpp - res = CPUReadGSASPSnapshot(fn.mb_fn_str()); + res = CPUReadGSASPSnapshot(UTF8(fn)); else // FIXME: this will fail on big-endian machines if // file format is little-endian // fix in GBA.cpp - res = CPUReadGSASnapshot(fn.mb_fn_str()); + res = CPUReadGSASnapshot(UTF8(fn)); } if (res) - msg.Printf(_("Loaded snapshot file %s"), fn.c_str()); + msg.Printf(_("Loaded snapshot file %s"), fn.wc_str()); else - msg.Printf(_("Error loading snapshot file %s"), fn.c_str()); + msg.Printf(_("Error loading snapshot file %s"), fn.wc_str()); systemScreenMessage(msg); } @@ -1094,10 +1094,10 @@ EVT_HANDLER_MASK(ExportBatteryFile, "Export battery file...", CMDEN_GB | CMDEN_G wxString fn = dlg.GetPath(); wxString msg; - if (panel->emusys->emuWriteBattery(fn.mb_fn_str())) - msg.Printf(_("Wrote battery %s"), fn.c_str()); + if (panel->emusys->emuWriteBattery(UTF8(fn))) + msg.Printf(_("Wrote battery %s"), fn.wc_str()); else - msg.Printf(_("Error writing battery %s"), fn.c_str()); + msg.Printf(_("Error writing battery %s"), fn.wc_str()); systemScreenMessage(msg); } @@ -1138,9 +1138,9 @@ EVT_HANDLER_MASK(ExportGamesharkSnapshot, "Export GameShark snapshot...", CMDEN_ // fix in GBA.cpp if (CPUWriteGSASnapshot(fn.utf8_str(), tit->GetValue().utf8_str(), dsc->GetValue().utf8_str(), n->GetValue().utf8_str())) - msg.Printf(_("Saved snapshot file %s"), fn.c_str()); + msg.Printf(_("Saved snapshot file %s"), fn.wc_str()); else - msg.Printf(_("Error saving snapshot file %s"), fn.c_str()); + msg.Printf(_("Error saving snapshot file %s"), fn.wc_str()); systemScreenMessage(msg); } @@ -1175,12 +1175,12 @@ EVT_HANDLER_MASK(ScreenCapture, "Screen capture...", CMDEN_GB | CMDEN_GBA) } if (fmt == 0) - panel->emusys->emuWritePNG(fn.mb_fn_str()); + panel->emusys->emuWritePNG(UTF8(fn)); else - panel->emusys->emuWriteBMP(fn.mb_fn_str()); + panel->emusys->emuWriteBMP(UTF8(fn)); wxString msg; - msg.Printf(_("Wrote snapshot %s"), fn.c_str()); + msg.Printf(_("Wrote snapshot %s"), fn.wc_str()); systemScreenMessage(msg); } @@ -2208,7 +2208,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().wc_str()); } else #endif { diff --git a/src/wx/guiinit.cpp b/src/wx/guiinit.cpp index 3174b2a5..acae8331 100644 --- a/src/wx/guiinit.cpp +++ b/src/wx/guiinit.cpp @@ -246,10 +246,10 @@ public: bool cld; if (isgb) - cld = gbCheatsLoadCheatList(cheatfn.mb_fn_str()); + cld = gbCheatsLoadCheatList(UTF8(cheatfn)); else { if (cheatfn.EndsWith(wxT(".clt"))) { - cld = cheatsLoadCheatList(cheatfn.mb_fn_str()); + cld = cheatsLoadCheatList(UTF8(cheatfn)); if (cld) { *dirty = cheatfn != deffn; @@ -298,9 +298,9 @@ public: // note that there is no way to test for succes of save if (isgb) - gbCheatsSaveCheatList(cheatfn.mb_fn_str()); + gbCheatsSaveCheatList(UTF8(cheatfn)); else - cheatsSaveCheatList(cheatfn.mb_fn_str()); + cheatsSaveCheatList(UTF8(cheatfn)); if (cheatfn == deffn) *dirty = false; diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 3906d538..a0664bee 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -81,7 +81,7 @@ void GameArea::LoadGame(const wxString& name) // auto-conversion of wxCharBuffer to const char * seems broken // so save underlying wxCharBuffer (or create one of none is used) - wxCharBuffer fnb(fnfn.GetFullPath().mb_str(wxConvUTF8)); + wxCharBuffer fnb(UTF8(fnfn.GetFullPath())); const char* fn = fnb.data(); IMAGE_TYPE t = badfile ? IMAGE_UNKNOWN : utilFindType(fn); @@ -158,7 +158,7 @@ void GameArea::LoadGame(const wxString& name) if (loadpatch) { int size = rom_size; - applyPatch(pfn.GetFullPath().mb_str(), &gbRom, &size); + applyPatch(UTF8(pfn.GetFullPath()), &gbRom, &size); if (size != (int)rom_size) gbUpdateSizes(); @@ -183,7 +183,9 @@ void GameArea::LoadGame(const wxString& name) gbGetHardwareType(); bool use_bios = gbCgbMode ? useBiosFileGBC : useBiosFileGB; - const char* fn = (gbCgbMode ? gopts.gbc_bios : gopts.gb_bios).mb_str(); + + wxCharBuffer fnb(UTF8((gbCgbMode ? gopts.gbc_bios : gopts.gb_bios))); + const char* fn = fnb.data(); gbCPUInit(fn, use_bios); @@ -223,7 +225,7 @@ void GameArea::LoadGame(const wxString& name) // don't use real rom size or it might try to resize rom[] // instead, use known size of rom[] int size = 0x2000000 < rom_size ? 0x2000000 : rom_size; - applyPatch(pfn.GetFullPath().mb_str(), &rom, &size); + applyPatch(UTF8(pfn.GetFullPath()), &rom, &size); // that means we no longer really know rom_size either gbaUpdateRomSize(size); @@ -285,7 +287,7 @@ void GameArea::LoadGame(const wxString& name) rtcEnableRumble(true); - CPUInit(gopts.gba_bios.mb_fn_str(), useBiosFileGBA); + CPUInit(UTF8(gopts.gba_bios), useBiosFileGBA); if (useBiosFileGBA && !useBios) { wxLogError(_("Could not load BIOS %s"), gopts.gba_bios.mb_str()); @@ -355,9 +357,9 @@ void GameArea::LoadGame(const wxString& name) bname.append(wxT(".sav")); wxFileName bat(batdir, bname); - if (emusys->emuReadBattery(bat.GetFullPath().mb_str())) { + if (emusys->emuReadBattery(UTF8(bat.GetFullPath()))) { wxString msg; - msg.Printf(_("Loaded battery %s"), bat.GetFullPath().mb_str()); + msg.Printf(_("Loaded battery %s"), bat.GetFullPath().wc_str()); systemScreenMessage(msg); if (cpuSaveType == 0 && ovSaveType == 0 && t == IMAGE_GBA) { @@ -409,9 +411,9 @@ void GameArea::LoadGame(const wxString& name) bool cld; if (loaded == IMAGE_GB) - cld = gbCheatsLoadCheatList(cfn.GetFullPath().mb_fn_str()); + cld = gbCheatsLoadCheatList(UTF8(cfn.GetFullPath())); else - cld = cheatsLoadCheatList(cfn.GetFullPath().mb_fn_str()); + cld = cheatsLoadCheatList(UTF8(cfn.GetFullPath())); if (cld) { systemScreenMessage(_("Loaded cheats")); @@ -424,7 +426,7 @@ void GameArea::LoadGame(const wxString& name) if (gopts.link_auto) { linkMode = mf->GetConfiguredLinkMode(); - BootLink(linkMode, gopts.link_host.mb_str(wxConvUTF8), linkTimeout, linkHacks, linkNumPlayers); + BootLink(linkMode, UTF8(gopts.link_host), linkTimeout, linkHacks, linkNumPlayers); } #endif @@ -496,12 +498,12 @@ void GameArea::UnloadGame(bool destruct) if (!gbCheatNumber) wxRemoveFile(cfn.GetFullPath()); else - gbCheatsSaveCheatList(cfn.GetFullPath().mb_fn_str()); + gbCheatsSaveCheatList(UTF8(cfn.GetFullPath())); } else { if (!cheatsNumber) wxRemoveFile(cfn.GetFullPath()); else - cheatsSaveCheatList(cfn.GetFullPath().mb_fn_str()); + cheatsSaveCheatList(UTF8(cfn.GetFullPath())); } } @@ -578,14 +580,14 @@ bool GameArea::LoadState() bool GameArea::LoadState(int slot) { wxString fname; - fname.Printf(SAVESLOT_FMT, game_name().mb_str(), slot); + fname.Printf(SAVESLOT_FMT, game_name().wc_str(), slot); return LoadState(wxFileName(statedir, fname)); } bool GameArea::LoadState(const wxFileName& fname) { // FIXME: first save to backup state if not backup state - bool ret = emusys->emuReadState(fname.GetFullPath().mb_fn_str()); + bool ret = emusys->emuReadState(UTF8(fname.GetFullPath())); if (ret && num_rewind_states) { MainFrame* mf = wxGetApp().frame; @@ -612,7 +614,7 @@ bool GameArea::LoadState(const wxFileName& fname) wxString msg; msg.Printf(ret ? _("Loaded state %s") : _("Error loading state %s"), - fname.GetFullPath().mb_str()); + fname.GetFullPath().wc_str()); systemScreenMessage(msg); return ret; } @@ -625,18 +627,18 @@ bool GameArea::SaveState() bool GameArea::SaveState(int slot) { wxString fname; - fname.Printf(SAVESLOT_FMT, game_name().mb_str(), slot); + fname.Printf(SAVESLOT_FMT, game_name().wc_str(), slot); return SaveState(wxFileName(statedir, fname)); } bool GameArea::SaveState(const wxFileName& fname) { // FIXME: first copy to backup state if not backup state - bool ret = emusys->emuWriteState(fname.GetFullPath().mb_fn_str()); + bool ret = emusys->emuWriteState(UTF8(fname.GetFullPath())); wxGetApp().frame->update_state_ts(true); wxString msg; msg.Printf(ret ? _("Saved state %s") : _("Error saving state %s"), - fname.GetFullPath().mb_str()); + fname.GetFullPath().wc_str()); systemScreenMessage(msg); return ret; } @@ -662,7 +664,7 @@ void GameArea::SaveBattery() // FIXME: add option to support ring of backups // of course some games just write battery way too often for such // a thing to be useful - if (!emusys->emuWriteBattery(fn.mb_str())) + if (!emusys->emuWriteBattery(UTF8(fn))) wxLogError(_("Error writing battery %s"), fn.mb_str()); systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; @@ -1858,7 +1860,7 @@ void DrawingPanelBase::DrawArea(uint8_t** data) if (panel->osdstat.size()) drawText(todraw + outstride * (systemColorDepth != 24), outstride, - 10, 20, panel->osdstat.mb_str(), showSpeedTransparent); + 10, 20, UTF8(panel->osdstat), showSpeedTransparent); if (!disableStatusMessages && !panel->osdtext.empty()) { if (systemGetClock() - panel->osdtime < OSD_TIME) { @@ -1866,7 +1868,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; - char* buf = strdup(message.mb_str()); + char* buf = strdup(UTF8(message)); char* ptr = buf; while (nlines > 1) { @@ -2394,7 +2396,7 @@ void GameArea::StartVidRecording(const wxString& fname) recording::MediaRet ret; vid_rec.SetSampleRate(soundGetSampleRate()); - if ((ret = vid_rec.Record(fname.mb_str(), basic_width, basic_height, + if ((ret = vid_rec.Record(UTF8(fname), basic_width, basic_height, systemColorDepth)) != recording::MRET_OK) wxLogError(_("Unable to begin recording to %s (%s)"), fname.mb_str(), @@ -2425,7 +2427,7 @@ void GameArea::StartSoundRecording(const wxString& fname) recording::MediaRet ret; snd_rec.SetSampleRate(soundGetSampleRate()); - if ((ret = snd_rec.Record(fname.mb_str())) != recording::MRET_OK) + if ((ret = snd_rec.Record(UTF8(fname))) != recording::MRET_OK) wxLogError(_("Unable to begin recording to %s (%s)"), fname.mb_str(), media_err(ret)); else { diff --git a/src/wx/sys.cpp b/src/wx/sys.cpp index 2f62b292..06b41e92 100644 --- a/src/wx/sys.cpp +++ b/src/wx/sys.cpp @@ -141,7 +141,7 @@ void systemStartGameRecording(const wxString& fname) fn[fn.size() - 1] = wxT('0'); - if (!panel->emusys->emuWriteState(fn.mb_fn_str())) { + if (!panel->emusys->emuWriteState(UTF8(fn))) { wxLogError(_("Error writing game recording")); game_file.Close(); return; @@ -212,7 +212,7 @@ void systemStartGamePlayback(const wxString& fname) game_next_joypad = wxUINT32_SWAP_ON_BE(jp); fn[fn.size() - 1] = wxT('0'); - if (!panel->emusys->emuReadState(fn.mb_fn_str())) { + if (!panel->emusys->emuReadState(UTF8(fn))) { wxLogError(_("Error reading game recording")); game_file.Close(); return; @@ -442,12 +442,12 @@ void systemScreenCapture(int num) fn.Mkdir(0777, wxPATH_MKDIR_FULL); if (captureFormat == 0) - panel->emusys->emuWritePNG(fn.GetFullPath().mb_fn_str()); + panel->emusys->emuWritePNG(UTF8(fn.GetFullPath())); else // if(gopts.cap_format == 1) - panel->emusys->emuWriteBMP(fn.GetFullPath().mb_fn_str()); + panel->emusys->emuWriteBMP(UTF8(fn.GetFullPath())); wxString msg; - msg.Printf(_("Wrote snapshot %s"), fn.GetFullPath().c_str()); + msg.Printf(_("Wrote snapshot %s"), fn.GetFullPath().wc_str()); systemScreenMessage(msg); } @@ -822,7 +822,7 @@ void PrintDialog::DoSave(wxCommandEvent&) if (scimg.SaveFile(of)) { wxString msg; - msg.Printf(_("Wrote printer output to %s"), of.c_str()); + msg.Printf(_("Wrote printer output to %s"), of.wc_str()); systemScreenMessage(msg); wxButton* cb = wxStaticCast(dlg->FindWindow(wxID_CANCEL), wxButton); @@ -1001,11 +1001,11 @@ void systemGbPrint(uint8_t* data, int len, int pages, int feed, int pal, int con systemGreenShift = 5; systemBlueShift = 0; wxString of = fn.GetFullPath(); - bool ret = captureFormat == 0 ? utilWritePNGFile(of.mb_fn_str(), 160, lines, (uint8_t*)to_print) : utilWriteBMPFile(of.mb_fn_str(), 160, lines, (uint8_t*)to_print); + bool ret = captureFormat == 0 ? utilWritePNGFile(UTF8(of), 160, lines, (uint8_t*)to_print) : utilWriteBMPFile(UTF8(of), 160, lines, (uint8_t*)to_print); if (ret) { wxString msg; - msg.Printf(_("Wrote printer output to %s"), of.c_str()); + msg.Printf(_("Wrote printer output to %s"), of.wc_str()); systemScreenMessage(msg); } @@ -1040,7 +1040,7 @@ void systemGbPrint(uint8_t* data, int len, int pages, int feed, int pal, int con void systemScreenMessage(const wxString& msg) { if (wxGetApp().frame && wxGetApp().frame->IsShown()) { - wxPuts(msg); + wxPuts(UTF8(msg)); // show **something** on terminal MainFrame* f = wxGetApp().frame; GameArea* panel = f->GetPanel(); diff --git a/src/wx/wxhead.h b/src/wx/wxhead.h index bd8c35f5..60d2c89a 100644 --- a/src/wx/wxhead.h +++ b/src/wx/wxhead.h @@ -113,8 +113,12 @@ static inline void DoSetAccel(wxMenuItem* mi, wxAcceleratorEntry* acc) #define XRCCTRL(win, id, type) XRCCTRL_I(win, XRCID(id), type) #define XRCCTRL_D(win, id, type) XRCCTRL_I(win, XRCID_D(id), type) -// wxWidgets provides fn_str(), but no mb_fn_str() or equiv. -#define mb_fn_str() mb_str(wxConvFile) +// Keep a single entry point for converting wxString to UTF8. +// Use this function whenever we want to get +static inline const wxCharBuffer UTF8(wxString str) +{ + return str.mb_str(wxConvUTF8); +} // by default, only 9 recent items #define wxID_FILE10 (wxID_FILE9 + 1) diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index 76c8e517..05b31f52 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -970,7 +970,7 @@ void MainFrame::update_state_ts(bool force) if (panel->game_type() != IMAGE_UNKNOWN) { wxString fn; - fn.Printf(SAVESLOT_FMT, panel->game_name().c_str(), i + 1); + fn.Printf(SAVESLOT_FMT, panel->game_name().wc_str(), i + 1); wxFileName fp(panel->state_dir(), fn); wxDateTime ts; // = wxInvalidDateTime