diff --git a/desmume/src/frontend/windows/hotkey.cpp b/desmume/src/frontend/windows/hotkey.cpp index fb37bd2c8..a8f3cf754 100644 --- a/desmume/src/frontend/windows/hotkey.cpp +++ b/desmume/src/frontend/windows/hotkey.cpp @@ -159,7 +159,7 @@ void HK_ToggleCheats(int, bool justPressed) WritePrivateProfileBool("General", "cheatsDisable", CommonSettings.cheatsDisable, IniName); } -static void DoScreenshot(const char* fname) +static void DoScreenshot(const wchar_t* fname) { const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo(); @@ -169,13 +169,13 @@ static void DoScreenshot(const char* fname) { if(gpu_bpp == 15) { - NDS_WritePNG_15bpp(dispInfo.customWidth, dispInfo.customHeight * 2, (const u16*)dispInfo.masterCustomBuffer, fname); + NDS_WritePNG_15bpp(dispInfo.customWidth, dispInfo.customHeight * 2, (const u16*)dispInfo.masterCustomBuffer, wcstombs(fname).c_str()); } else { u32* swapbuf = (u32*)malloc_alignedCacheLine(dispInfo.customWidth * dispInfo.customHeight * 2 * 4); ColorspaceConvertBuffer888xTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, dispInfo.customWidth * dispInfo.customHeight * 2); - NDS_WritePNG_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight*2, swapbuf, fname); + NDS_WritePNG_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight*2, swapbuf, wcstombs(fname).c_str()); free_aligned(swapbuf); } } @@ -184,13 +184,13 @@ static void DoScreenshot(const char* fname) { if(gpu_bpp == 15) { - NDS_WriteBMP_15bpp(dispInfo.customWidth, dispInfo.customHeight * 2, (const u16*)dispInfo.masterCustomBuffer, fname); + NDS_WriteBMP_15bpp(dispInfo.customWidth, dispInfo.customHeight * 2, (const u16*)dispInfo.masterCustomBuffer, wcstombs(fname).c_str()); } else { u32* swapbuf = (u32*)malloc_alignedCacheLine(dispInfo.customWidth * dispInfo.customHeight * 2 * 4); ColorspaceConvertBuffer888xTo8888Opaque((const u32*)dispInfo.masterCustomBuffer, swapbuf, dispInfo.customWidth * dispInfo.customHeight * 2); - NDS_WriteBMP_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight *2, swapbuf, fname); + NDS_WriteBMP_32bppBuffer(dispInfo.customWidth, dispInfo.customHeight *2, swapbuf, wcstombs(fname).c_str()); free_aligned(swapbuf); } } @@ -226,7 +226,7 @@ void HK_QuickScreenShot(int param, bool justPressed) break; } - DoScreenshot(fname); + DoScreenshot(mbstowcs_locale(fname).c_str()); } void HK_PrintScreen(int param, bool justPressed) @@ -237,42 +237,45 @@ void HK_PrintScreen(int param, bool justPressed) bool unpause = NDS_Pause(false); char outFilename[MAX_PATH] = ""; + wchar_t woutFilename[MAX_PATH] = L""; - OPENFILENAME ofn; + OPENFILENAMEW ofn; ZeroMemory(&ofn,sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = MainWindow->getHWnd(); - ofn.lpstrFilter = "png file (*.png)\0*.png\0Bmp file (*.bmp)\0*.bmp\0Any file (*.*)\0*.*\0\0"; - ofn.lpstrTitle = "Print Screen Save As"; + ofn.lpstrFilter = L"png file (*.png)\0*.png\0Bmp file (*.bmp)\0*.bmp\0Any file (*.*)\0*.*\0\0"; + ofn.lpstrTitle = L"Print Screen Save As"; ofn.nMaxFile = MAX_PATH; - ofn.lpstrFile = outFilename; - ofn.lpstrDefExt = "png"; + ofn.lpstrFile = woutFilename; + ofn.lpstrDefExt = L"png"; ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST; - std::string dir = path.getpath(path.SCREENSHOTS); + std::wstring dir = mbstowcs(path.getpath(path.SCREENSHOTS)); ofn.lpstrInitialDir = dir.c_str(); path.formatname(outFilename); if(path.imageformat() == PathInfo::PNG) { strcat(outFilename, ".png"); - ofn.lpstrDefExt = "png"; + ofn.lpstrDefExt = L"png"; ofn.nFilterIndex = 1; } else if(path.imageformat() == PathInfo::BMP) { strcat(outFilename, ".bmp"); - ofn.lpstrDefExt = "bmp"; + ofn.lpstrDefExt = L"bmp"; ofn.nFilterIndex = 2; } - if(GetSaveFileName(&ofn)) - { - DoScreenshot(outFilename); + wcscpy(woutFilename,mbstowcs(outFilename).c_str()); - dir = Path::GetFileDirectoryPath(outFilename); - path.setpath(path.SCREENSHOTS, dir); - WritePrivateProfileStringW(LSECTION, SCREENSHOTKEY, mbstowcs(dir).c_str(), IniNameW); + if(GetSaveFileNameW(&ofn)) + { + DoScreenshot(woutFilename); + + dir = mbstowcs(Path::GetFileDirectoryPath(wcstombs(woutFilename))); + path.setpath(path.SCREENSHOTS, wcstombs(dir)); + WritePrivateProfileStringW(LSECTION, SCREENSHOTKEY, dir.c_str(), IniNameW); } if(unpause) NDS_UnPause(false); diff --git a/desmume/src/libretro-common/streams/file_stream.c b/desmume/src/libretro-common/streams/file_stream.c index 6d74a9a10..35539ed49 100644 --- a/desmume/src/libretro-common/streams/file_stream.c +++ b/desmume/src/libretro-common/streams/file_stream.c @@ -64,6 +64,17 @@ #include #include +#if defined(_WIN32) +wchar_t *utf8_to_wide(const char *utf8) { + int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); + wchar_t *wstr = (wchar_t *)malloc(wlen * sizeof(wchar_t)); + if (wstr) { + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, wlen); +} + return wstr; +} +#endif + struct RFILE { unsigned hints; @@ -192,7 +203,15 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len) #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { + #if defined(_WIN32) + wchar_t* w = utf8_to_wide(path); + wchar_t* wmode = utf8_to_wide(mode_str); + stream->fp = _wfopen(w, wmode); + free(w); + free(wmode); + #else stream->fp = fopen(path, mode_str); + #endif if (!stream->fp) goto error; } diff --git a/desmume/src/utils/xstring.cpp b/desmume/src/utils/xstring.cpp index 6b92f5f30..1b4a21ce4 100644 --- a/desmume/src/utils/xstring.cpp +++ b/desmume/src/utils/xstring.cpp @@ -284,6 +284,19 @@ std::string mass_replace(const std::string &source, const std::string &victim, c return answer; } +std::string wcstombs_locale(std::wstring str) +{ + #ifdef HOST_WINDOWS + int plenty = str.size()*8+1; + char *garbage = new char[plenty]; + WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),garbage,plenty,nullptr,nullptr); + std::string ret = garbage; + delete[] garbage; + return ret; + #endif + return wcstombs(str); +} + std::wstring mbstowcs_locale(std::string str) { #ifdef HOST_WINDOWS diff --git a/desmume/src/utils/xstring.h b/desmume/src/utils/xstring.h index 5741d998f..74592e740 100644 --- a/desmume/src/utils/xstring.h +++ b/desmume/src/utils/xstring.h @@ -104,10 +104,17 @@ template void putdec(EMUFILE &os, T dec) std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement); +//converts utf-8 to utf16 std::wstring mbstowcs(std::string str); + +//converts utf16 to utf-8 std::string wcstombs(std::wstring str); +//converts char* in current system locale to utf16 std::wstring mbstowcs_locale(std::string str); +//converts utf16 to char* in current system locale +std::string wcstombs_locale(std::wstring str); + #endif