diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index d1e3c38237..df196830a7 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -20,6 +20,8 @@ #include #include +#include "common/FileSystem.h" + #include "CdRom.h" #include "CDVD.h" #include "CDVD_internal.h" @@ -111,34 +113,28 @@ static int mg_BIToffset(u8* buffer) static void cdvdGetMechaVer(u8* ver) { - wxFileName mecfile(EmuConfig.FullpathToBios()); - mecfile.SetExt(L"mec"); - const wxString fname(mecfile.GetFullPath()); - - // Likely a bad idea to go further - if (mecfile.IsDir()) - throw Exception::CannotCreateStream(fname); - - - if (Path::GetFileSize(fname) < 4) + std::string mecfile(FileSystem::ReplaceExtension(EmuConfig.FullpathToBios(), "mec")); + auto fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "rb"); + if (!fp || FileSystem::FSize64(fp.get()) < 4) { Console.Warning("MEC File Not Found, creating substitute..."); - wxFFile fp(fname, L"wb"); - if (!fp.IsOpened()) - throw Exception::CannotCreateStream(fname); + fp.reset(); + fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "w+b"); + if (!fp) + { + Console.Error("Failed to read/write NVM/MEC file. Check your BIOS setup/permission settings."); + return; + } u8 version[4] = {0x3, 0x6, 0x2, 0x0}; - fp.Write(version, sizeof(version)); + std::fwrite(version, sizeof(version), 1, fp.get()); + FileSystem::FSeek64(fp.get(), 0, SEEK_SET); } - wxFFile fp(fname, L"rb"); - if (!fp.IsOpened()) - throw Exception::CannotCreateStream(fname); - - size_t ret = fp.Read(ver, 4); + auto ret = std::fread(ver, 1, 4, fp.get()); if (ret != 4) - Console.Error(L"Failed to read from %s. Did only %zu/4 bytes", WX_STR(fname), ret); + Console.Error("Failed to read from %s. Did only %zu/4 bytes", mecfile.c_str(), ret); } NVMLayout* getNvmLayout() @@ -153,14 +149,10 @@ NVMLayout* getNvmLayout() return nvmLayout; } -static void cdvdCreateNewNVM(const wxString& filename) +static void cdvdCreateNewNVM(std::FILE* fp) { - wxFFile fp(filename, L"wb"); - if (!fp.IsOpened()) - throw Exception::CannotCreateStream(filename); - - u8 zero[1024] = {0}; - fp.Write(zero, sizeof(zero)); + u8 zero[1024] = { 0 }; + std::fwrite(zero, sizeof(zero), 1, fp); // Write NVM ILink area with dummy data (Age of Empires 2) // Also write language data defaulting to English (Guitar Hero 2) @@ -168,36 +160,34 @@ static void cdvdCreateNewNVM(const wxString& filename) NVMLayout* nvmLayout = getNvmLayout(); u8 ILinkID_Data[8] = {0x00, 0xAC, 0xFF, 0xFF, 0xFF, 0xFF, 0xB9, 0x86}; - fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, ilinkId))); - fp.Write(ILinkID_Data, sizeof(ILinkID_Data)); + std::fseek(fp, *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, ilinkId)), SEEK_SET); + std::fwrite(ILinkID_Data, sizeof(ILinkID_Data), 1, fp); u8 biosLanguage[16]; memcpy(biosLanguage, &biosLangDefaults[BiosRegion][0], 16); // Config sections first 16 bytes are generally blank expect the last byte which is PS1 mode stuff // So let's ignore that and just write the PS2 mode stuff - fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10); - fp.Write(biosLanguage, sizeof(biosLanguage)); - - fp.Close(); + std::fseek(fp, *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET); + std::fwrite(biosLanguage, sizeof(biosLanguage), 1, fp); } -// Throws Exception::CannotCreateStream if the file cannot be opened for reading, or cannot -// be created for some reason. static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read) { - wxFileName nvmfile(EmuConfig.FullpathToBios()); - nvmfile.SetExt(L"nvm"); - const wxString fname(nvmfile.GetFullPath()); - - // Likely a bad idea to go further - if (nvmfile.IsDir()) - throw Exception::CannotCreateStream(fname); - - if (Path::GetFileSize(fname) < 1024) + std::string nvmfile(FileSystem::ReplaceExtension(EmuConfig.FullpathToBios(), "nvm")); + auto fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "r+b"); + if (!fp || FileSystem::FSize64(fp.get()) < 1024) { - Console.Warning("NVM File Not Found, creating substitute..."); + fp.reset(); + fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "w+b"); + if (!fp) + { + Console.Error("Failed to open NVM file '%s' for writing", nvmfile.c_str()); + if (read) + std::memset(buffer, 0, bytes); + return; + } - cdvdCreateNewNVM(fname); + cdvdCreateNewNVM(fp.get()); } else { @@ -205,38 +195,29 @@ static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read) u8 zero[16] = {0}; NVMLayout* nvmLayout = getNvmLayout(); - wxFFile fp(fname, L"r+b"); - if (!fp.IsOpened()) - throw Exception::CannotCreateStream(fname); - - fp.Seek(*(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10); - fp.Read(LanguageParams, 16); - - fp.Close(); + std::fseek(fp.get(), *(s32*)(((u8*)nvmLayout) + offsetof(NVMLayout, config1)) + 0x10, SEEK_SET); + std::fread(LanguageParams, 16, 1, fp.get()); if (memcmp(LanguageParams, zero, sizeof(LanguageParams)) == 0) { Console.Warning("Language Parameters missing, filling in defaults"); - cdvdCreateNewNVM(fname); + FileSystem::FSeek64(fp.get(), 0, SEEK_SET); + cdvdCreateNewNVM(fp.get()); } } - wxFFile fp(fname, L"r+b"); - if (!fp.IsOpened()) - throw Exception::CannotCreateStream(fname); - - fp.Seek(offset); + std::fseek(fp.get(), offset, SEEK_SET); size_t ret; if (read) - ret = fp.Read(buffer, bytes); + ret = std::fread(buffer, 1, bytes, fp.get()); else - ret = fp.Write(buffer, bytes); + ret = std::fwrite(buffer, 1, bytes, fp.get()); if (ret != bytes) Console.Error(L"Failed to %s %s. Did only %zu/%zu bytes", - read ? L"read from" : L"write to", WX_STR(fname), ret, bytes); + read ? L"read from" : L"write to", nvmfile.c_str(), ret, bytes); } static void cdvdReadNVM(u8* dst, int offset, int bytes) @@ -1996,7 +1977,6 @@ static __fi void fail_pol_cal() static void cdvdWrite16(u8 rt) // SCOMMAND { - try { // cdvdTN diskInfo; // cdvdTD trackInfo; @@ -2655,12 +2635,6 @@ static void cdvdWrite16(u8 rt) // SCOMMAND cdvd.ParamP = 0; cdvd.ParamC = 0; } - catch (Exception::CannotCreateStream&) - { - Cpu->ThrowException(Exception::RuntimeError() - .SetDiagMsg(L"Failed to read/write NVM/MEC file.") - .SetUserMsg(pxE(L"Failed to read/write NVM/MEC file. Check your BIOS setup/permission settings."))); - } } static __fi void cdvdWrite17(u8 rt) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 8b4366a41c..cb5e2b0b24 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -598,7 +598,7 @@ struct Pcsx2Config void LoadSaveMemcards(SettingsWrapper& wrap); // TODO: Make these std::string when we remove wxFile... - wxString FullpathToBios() const; + std::string FullpathToBios() const; wxString FullpathToMcd(uint slot) const; bool MultitapEnabled(uint port) const; diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index dcde47acc1..384f9d927a 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -850,7 +850,8 @@ void eeMemoryReserve::Reset() vtlb_VMap(0x00000000,0x00000000,0x20000000); vtlb_VMapUnmap(0x20000000,0x60000000); - LoadBIOS(); + if (!LoadBIOS()) + pxFailRel("Failed to load BIOS"); } void eeMemoryReserve::Decommit() diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 1916289795..cfea9e5624 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -645,9 +645,9 @@ bool Pcsx2Config::MultitapEnabled(uint port) const return (port == 0) ? MultitapPort0_Enabled : MultitapPort1_Enabled; } -wxString Pcsx2Config::FullpathToBios() const +std::string Pcsx2Config::FullpathToBios() const { - return Path::Combine(EmuFolders::Bios, StringUtil::UTF8StringToWxString(BaseFilenames.Bios)); + return StringUtil::wxStringToUTF8String(Path::Combine(EmuFolders::Bios, StringUtil::UTF8StringToWxString(BaseFilenames.Bios))); } wxString Pcsx2Config::FullpathToMcd(uint slot) const diff --git a/pcsx2/SaveState.cpp b/pcsx2/SaveState.cpp index ff843540f3..540e0fe8a1 100644 --- a/pcsx2/SaveState.cpp +++ b/pcsx2/SaveState.cpp @@ -107,8 +107,8 @@ wxString SaveStateBase::GetSavestateFolder( int slot, bool isSavingOrLoading ) else { // Still inside the BIOS/not running a game (why would anyone want to do this?) - wxString biosString = (pxsFmt(L"BIOS (%s v%u.%u)", WX_STR(biosZone), (BiosVersion >> 8), BiosVersion & 0xff)); - serialName = biosString; + const std::string biosString(StringUtil::StdStringFromFormat("BIOS (%s v%u.%u)", BiosZone.c_str(), (BiosVersion >> 8), BiosVersion & 0xff)); + serialName = StringUtil::UTF8StringToWxString(biosString); CRCvalue = L"None"; } @@ -183,11 +183,8 @@ SaveStateBase& SaveStateBase::FreezeBios() u32 bioscheck = BiosChecksum; char biosdesc[256]; - - pxToUTF8 utf8(BiosDescription); - memzero( biosdesc ); - memcpy( biosdesc, utf8, std::min( sizeof(biosdesc), utf8.Length() ) ); + memcpy( biosdesc, BiosDescription.c_str(), std::min( sizeof(biosdesc), BiosDescription.length() ) ); Freeze( bioscheck ); Freeze( biosdesc ); @@ -197,9 +194,9 @@ SaveStateBase& SaveStateBase::FreezeBios() Console.Newline(); Console.Indent(1).Error( "Warning: BIOS Version Mismatch, savestate may be unstable!" ); Console.Indent(2).Error( - "Current BIOS: %ls (crc=0x%08x)\n" + "Current BIOS: %s (crc=0x%08x)\n" "Savestate BIOS: %s (crc=0x%08x)\n", - BiosDescription.wx_str(), BiosChecksum, + BiosDescription.c_str(), BiosChecksum, biosdesc, bioscheck ); } diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index e59a0aef88..54d5c30712 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -38,6 +38,7 @@ #endif #include "common/IniInterface.h" +#include "common/FileSystem.h" #include "common/StringUtil.h" #include "common/AppTrait.h" @@ -75,61 +76,15 @@ std::unique_ptr g_Conf; WindowInfo g_gs_window_info; -// Returns a string message telling the user to consult guides for obtaining a legal BIOS. -// This message is in a function because it's used as part of several dialogs in PCSX2 (there -// are multiple variations on the BIOS and BIOS folder checks). -wxString BIOS_GetMsg_Required() +static bool CheckForBIOS() { - return pxE(L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain a BIOS from an actual PS2 unit that you own (borrowing doesn't count). Please consult the FAQs and Guides for further instructions." - ); -} + if (FileSystem::FileExists(g_Conf->EmuOptions.FullpathToBios().c_str())) + return true; -class BIOSLoadErrorEvent : public pxExceptionEvent -{ - typedef pxExceptionEvent _parent; + wxString error = pxE(L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain a BIOS from an actual PS2 unit that you own (borrowing doesn't count). Please consult the FAQs and Guides for further instructions."); -public: - BIOSLoadErrorEvent(BaseException* ex = NULL) : _parent(ex) {} - BIOSLoadErrorEvent(const BaseException& ex) : _parent(ex) {} - - virtual ~BIOSLoadErrorEvent() = default; - virtual BIOSLoadErrorEvent *Clone() const { return new BIOSLoadErrorEvent(*this); } - -protected: - void InvokeEvent(); - -}; - -static bool HandleBIOSError(BaseException& ex) -{ - if (!pxDialogExists(L"Dialog:" + Dialogs::SysConfigDialog::GetNameStatic())) - { - if (!Msgbox::OkCancel(ex.FormatDisplayMessage() + L"\n\n" + BIOS_GetMsg_Required() - + L"\n\n" + _("Press Ok to go to the BIOS Configuration Panel."), _("PS2 BIOS Error"))) - return false; - } - else - { - Msgbox::Alert(ex.FormatDisplayMessage() + L"\n\n" + BIOS_GetMsg_Required(), _("PS2 BIOS Error")); - } - - g_Conf->ComponentsTabName = L"BIOS"; - - return AppOpenModalDialog(L"BIOS") != wxID_CANCEL; -} - -void BIOSLoadErrorEvent::InvokeEvent() -{ - if (!m_except) return; - - ScopedExcept deleteMe(m_except); - m_except = NULL; - - if (!HandleBIOSError(*deleteMe)) - { - Console.Warning("User canceled BIOS configuration."); - Msgbox::Alert(_("Warning! Valid BIOS has not been selected. PCSX2 may be inoperable.")); - } + Msgbox::Alert(error, _("PS2 BIOS Error")); + return false; } // Allows for activating menu actions from anywhere in PCSX2. @@ -562,19 +517,6 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& Exit(); } // ---------------------------------------------------------------------------- - catch( Exception::BiosLoadFailed& ex ) - { - // Commandline 'nogui' users will not receive an error message, but at least PCSX2 will - // terminate properly. - GSFrame* gsframe = wxGetApp().GetGsFramePtr(); - gsframe->Close(); - - Console.Error(ex.FormatDiagnosticMessage()); - - if (wxGetApp().HasGUI()) - AddIdleEvent(BIOSLoadErrorEvent(ex)); - } - // ---------------------------------------------------------------------------- catch( Exception::SaveStateLoadError& ex) { // Saved state load failed prior to the system getting corrupted (ie, file not found @@ -1007,6 +949,9 @@ protected: // fresh VM with the requested sources. void Pcsx2App::SysExecute() { + if (!CheckForBIOS()) + return; + SysExecutorThread.PostEvent( new SysExecEvent_Execute() ); } @@ -1015,6 +960,9 @@ void Pcsx2App::SysExecute() // sources. void Pcsx2App::SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override ) { + if (!CheckForBIOS()) + return; + SysExecutorThread.PostEvent( new SysExecEvent_Execute(cdvdsrc, elf_override) ); #ifndef DISABLE_RECORDING if (g_Conf->EmuOptions.EnableRecordingTools) diff --git a/pcsx2/gui/Panels/BiosSelectorPanel.cpp b/pcsx2/gui/Panels/BiosSelectorPanel.cpp index 176bcdaad2..7ee8b766c7 100644 --- a/pcsx2/gui/Panels/BiosSelectorPanel.cpp +++ b/pcsx2/gui/Panels/BiosSelectorPanel.cpp @@ -170,12 +170,13 @@ bool Panels::BiosSelectorPanel::ValidateEnumerationStatus() void Panels::BiosSelectorPanel::EnumThread::ExecuteTaskInThread() { + u32 region, version; + std::string description, zone; for (size_t i = 0; i < m_parent.m_BiosList->GetCount(); ++i) { - wxString description; - if (!IsBIOS((*m_parent.m_BiosList)[i], description)) + if (!IsBIOS((*m_parent.m_BiosList)[i].ToUTF8().data(), version, description, region, zone)) continue; - Result.emplace_back(std::move(description), i); + Result.emplace_back(StringUtil::UTF8StringToWxString(description), i); } wxCommandEvent done(pxEvt_BiosEnumerationFinished); @@ -204,7 +205,7 @@ void Panels::BiosSelectorPanel::OnEnumComplete(wxCommandEvent& evt) if (m_EnumeratorThread.get() != enumThread || m_BiosList->size() < enumThread->Result.size()) return; - const wxString currentBios(g_Conf->EmuOptions.FullpathToBios()); + const wxString currentBios(StringUtil::UTF8StringToWxString(g_Conf->EmuOptions.FullpathToBios())); m_ComboBox->Clear(); // Clear the "Enumerating BIOSes..." for (const std::pair& result : enumThread->Result) diff --git a/pcsx2/ps2/BiosTools.cpp b/pcsx2/ps2/BiosTools.cpp index 5e3ff7f55f..cc169367c0 100644 --- a/pcsx2/ps2/BiosTools.cpp +++ b/pcsx2/ps2/BiosTools.cpp @@ -14,15 +14,15 @@ */ #include "PrecompiledHeader.h" + +#include + +#include "common/FileSystem.h" +#include "common/StringUtil.h" + #include "Common.h" #include "BiosTools.h" - -#include "common/pxStreams.h" -#include "wx/ffile.h" - #include "Config.h" -#include "wx/mstream.h" -#include "wx/wfstream.h" #define DIRENTRY_SIZE 16 @@ -41,97 +41,82 @@ struct romdir #pragma pack(pop) -static_assert( sizeof(romdir) == DIRENTRY_SIZE, "romdir struct not packed to 16 bytes" ); +static_assert(sizeof(romdir) == DIRENTRY_SIZE, "romdir struct not packed to 16 bytes"); u32 BiosVersion; u32 BiosChecksum; u32 BiosRegion; -wxString biosZone; bool NoOSD; bool AllowParams1; bool AllowParams2; -wxString BiosDescription; +std::string BiosDescription; +std::string BiosZone; BiosDebugInformation CurrentBiosInformation; -// -------------------------------------------------------------------------------------- -// Exception::BiosLoadFailed (implementations) -// -------------------------------------------------------------------------------------- -Exception::BiosLoadFailed::BiosLoadFailed( const wxString& filename ) -{ - StreamName = filename; -} - -// This method throws a BadStream exception if the bios information chould not be obtained. -// (indicating that the file is invalid, incomplete, corrupted, or plain naughty). -static void LoadBiosVersion( pxInputStream& fp, u32& version, wxString& description, u32& region, wxString& zoneStr ) +static bool LoadBiosVersion(std::FILE* fp, u32& version, std::string& description, u32& region, std::string& zone) { uint i; romdir rd; - for (i=0; i<512*1024; i++) + for (i = 0; i < 512 * 1024; i++) { - fp.Read( rd ); - if (strncmp( rd.fileName, "RESET", 5 ) == 0) + if (std::fread(&rd, sizeof(rd), 1, fp) != 1) + return false; + + if (std::strncmp(rd.fileName, "RESET", 5) == 0) break; /* found romdir */ } - if (i == 512*1024) - { - throw Exception::BadStream( fp.GetStreamName() ) - .SetDiagMsg(L"BIOS version check failed: 'RESET' tag could not be found.") - .SetUserMsg(_("The selected BIOS file is not a valid PS2 BIOS. Please re-configure.")); - } + s64 fileOffset = 0; + s64 fileSize = FileSystem::FSize64(fp); + bool foundRomVer = false; - uint fileOffset = 0; - - while(strlen(rd.fileName) > 0) + while (strlen(rd.fileName) > 0) { if (strcmp(rd.fileName, "ROMVER") == 0) { - char romver[14+1]; // ascii version loaded from disk. + char romver[14 + 1] = {}; // ascii version loaded from disk. - wxFileOffset filetablepos = fp.Tell(); - fp.Seek( fileOffset ); - fp.Read( &romver, 14 ); - fp.Seek( filetablepos ); //go back - - romver[14] = 0; - - const char zonefail[2] = { romver[4], '\0' }; // the default "zone" (unknown code) - const char* zone = zonefail; - - switch(romver[4]) + s64 pos = FileSystem::FTell64(fp); + if (FileSystem::FSeek64(fp, fileOffset, SEEK_SET) == 0) { - case 'T': zone = "T10K"; region = 0; break; - case 'X': zone = "Test"; region = 1; break; - case 'J': zone = "Japan"; region = 2; break; - case 'A': zone = "USA"; region = 3; break; - case 'E': zone = "Europe"; region = 4; break; - case 'H': zone = "HK"; region = 5; break; - case 'P': zone = "Free"; region = 6; break; - case 'C': zone = "China"; region = 7; break; + std::fread(romver, 14, 1, fp); + FileSystem::FSeek64(fp, pos, SEEK_SET); //go back } - char vermaj[3] = { romver[0], romver[1], 0 }; - char vermin[3] = { romver[2], romver[3], 0 }; + switch (romver[4]) + { + // clang-format off + case 'T': zone = "T10K"; region = 0; break; + case 'X': zone = "Test"; region = 1; break; + case 'J': zone = "Japan"; region = 2; break; + case 'A': zone = "USA"; region = 3; break; + case 'E': zone = "Europe"; region = 4; break; + case 'H': zone = "HK"; region = 5; break; + case 'P': zone = "Free"; region = 6; break; + case 'C': zone = "China"; region = 7; break; + // clang-format on + default: + zone.clear(); + zone += romver[4]; + break; + } - FastFormatUnicode result; - result.Write( "%-7s v%s.%s(%c%c/%c%c/%c%c%c%c) %s", - zone, + char vermaj[3] = {romver[0], romver[1], 0}; + char vermin[3] = {romver[2], romver[3], 0}; + + description = StringUtil::StdStringFromFormat("%-7s v%s.%s(%c%c/%c%c/%c%c%c%c) %s", + zone.c_str(), vermaj, vermin, - romver[12], romver[13], // day - romver[10], romver[11], // month - romver[6], romver[7], romver[8], romver[9], // year! - (romver[5]=='C') ? "Console" : (romver[5]=='D') ? "Devel" : "" - ); + romver[12], romver[13], // day + romver[10], romver[11], // month + romver[6], romver[7], romver[8], romver[9], // year! + (romver[5] == 'C') ? "Console" : (romver[5] == 'D') ? "Devel" : + ""); version = strtol(vermaj, (char**)NULL, 0) << 8; - version|= strtol(vermin, (char**)NULL, 0); - - Console.WriteLn(L"Bios Found: %ls", result.c_str()); - - description = result.c_str(); - zoneStr = fromUTF8(zone); + version |= strtol(vermin, (char**)NULL, 0); + foundRomVer = true; } if ((rd.fileSize % 0x10) == 0) @@ -139,36 +124,30 @@ static void LoadBiosVersion( pxInputStream& fp, u32& version, wxString& descript else fileOffset += (rd.fileSize + 0x10) & 0xfffffff0; - fp.Read( rd ); + if (std::fread(&rd, sizeof(rd), 1, fp) != 1) + break; } fileOffset -= ((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize; - if (description.IsEmpty()) - throw Exception::BadStream( fp.GetStreamName() ) - .SetDiagMsg(L"BIOS version check failed: 'ROMDIR' tag could not be found.") - .SetUserMsg(_("The selected BIOS file is not a valid PS2 BIOS. Please re-configure.")); + if (!foundRomVer) + return false; - wxFileOffset fileSize = fp.Length(); if (fileSize < (int)fileOffset) { - description += pxsFmt( L" %d%%", ((fileSize*100) / (int)fileOffset) ); + description += StringUtil::StdStringFromFormat(" %d%%", ((fileSize * 100) / (int)fileOffset)); // we force users to have correct bioses, // not that lame scph10000 of 513KB ;-) } + + return true; } -static void LoadBiosVersion( pxInputStream& fp, u32& version, wxString& description, u32& region ) +template +void ChecksumIt(u32& result, const u8 (&srcdata)[_size]) { - wxString zoneStr; - LoadBiosVersion( fp,version, description, region, zoneStr ); -} - -template< size_t _size > -void ChecksumIt( u32& result, const u8 (&srcdata)[_size] ) -{ - pxAssume( (_size & 3) == 0 ); - for( size_t i=0; i<_size/4; ++i ) + pxAssume((_size & 3) == 0); + for (size_t i = 0; i < _size / 4; ++i) result ^= ((u32*)srcdata)[i]; } @@ -179,66 +158,48 @@ void ChecksumIt( u32& result, const u8 (&srcdata)[_size] ) // Parameters: // ext - extension of the sub-component to load. Valid options are rom1, rom2, AND erom. // -template< size_t _size > -static void LoadExtraRom( const wxChar* ext, u8 (&dest)[_size] ) +template +static void LoadExtraRom(const char* ext, u8 (&dest)[_size]) { - wxString Bios1; - s64 filesize = 0; - // Try first a basic extension concatenation (normally results in something like name.bin.rom1) - const wxString Bios( EmuConfig.FullpathToBios() ); - Bios1.Printf( L"%s.%s", WX_STR(Bios), ext); + const std::string Bios(EmuConfig.FullpathToBios()); + std::string Bios1(StringUtil::StdStringFromFormat("%s.%s", Bios.c_str(), ext)); - try + s64 filesize; + if ((filesize = FileSystem::GetPathFileSize(Bios1.c_str())) <= 0) { - if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 ) + // Try the name properly extensioned next (name.rom1) + Bios1 = FileSystem::ReplaceExtension(Bios, ext); + if ((filesize = FileSystem::GetPathFileSize(Bios1.c_str())) <= 0) { - // Try the name properly extensioned next (name.rom1) - Bios1 = Path::ReplaceExtension( Bios, ext ); - if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 ) - { - Console.WriteLn( Color_Gray, L"BIOS %s module not found, skipping...", ext ); - return; - } - } - - wxFile fp( Bios1 ); - fp.Read( dest, std::min( _size, filesize ) ); - - // Checksum for ROM1, ROM2, EROM? Rama says no, Gigaherz says yes. I'm not sure either way. --air - //ChecksumIt( BiosChecksum, dest ); - } - catch (Exception::BadStream& ex) - { - // If any of the secondary roms fail,its a non-critical error. - // Log it, but don't make a big stink. 99% of games and stuff will - // still work fine. - - Console.Warning(L"BIOS Warning: %s could not be read (permission denied?)", ext); - Console.Indent().WriteLn(L"Details: %s", WX_STR(ex.FormatDiagnosticMessage())); - Console.Indent().WriteLn(L"File size: %llu", filesize); - } -} - -static void LoadIrx( const std::string& filename, u8* dest ) -{ - s64 filesize = 0; - try - { - wxString wname = fromUTF8(filename); - wxFile irx(wname); - if( (filesize=Path::GetFileSize( wname ) ) <= 0 ) { - Console.Warning("IRX Warning: %s could not be read", filename.c_str()); + Console.WriteLn(Color_Gray, "BIOS %s module not found, skipping...", ext); return; } + } - irx.Read( dest, filesize ); - } - catch (Exception::BadStream& ex) + auto fp = FileSystem::OpenManagedCFile(Bios1.c_str(), "rb"); + if (!fp || std::fread(dest, static_cast(std::min(_size, filesize)), 1, fp.get()) != 1) { - Console.Warning("IRX Warning: %s could not be read", filename.c_str()); - Console.Indent().WriteLn(L"Details: %s", WX_STR(ex.FormatDiagnosticMessage())); + Console.Warning("BIOS Warning: %s could not be read (permission denied?)", ext); + return; } + // Checksum for ROM1, ROM2, EROM? Rama says no, Gigaherz says yes. I'm not sure either way. --air + //ChecksumIt( BiosChecksum, dest ); +} + +static void LoadIrx(const std::string& filename, u8* dest, size_t maxSize) +{ + auto fp = FileSystem::OpenManagedCFile(filename.c_str(), "rb"); + if (fp) + { + const s64 filesize = FileSystem::FSize64(fp.get()); + const s64 readSize = std::min(filesize, static_cast(maxSize)); + if (std::fread(dest, readSize, 1, fp.get()) == 1) + return; + } + + Console.Warning("IRX Warning: %s could not be read", filename.c_str()); + return; } // Loads the configured bios rom file into PS2 memory. PS2 memory must be allocated prior to @@ -251,83 +212,66 @@ static void LoadIrx( const std::string& filename, u8* dest ) // Exceptions: // BadStream - Thrown if the primary bios file (usually .bin) is not found, corrupted, etc. // -void LoadBIOS() +bool LoadBIOS() { - pxAssertDev( eeMem->ROM != NULL, "PS2 system memory has not been initialized yet." ); + pxAssertDev(eeMem->ROM != NULL, "PS2 system memory has not been initialized yet."); - try + if (EmuConfig.BaseFilenames.Bios.empty()) + return false; + + const std::string Bios(EmuConfig.FullpathToBios()); + auto fp = FileSystem::OpenManagedCFile(Bios.c_str(), "rb"); + if (!fp) + return false; + + const s64 filesize = FileSystem::FSize64(fp.get()); + if (filesize <= 0) + return false; + + LoadBiosVersion(fp.get(), BiosVersion, BiosDescription, BiosRegion, BiosZone); + + if (FileSystem::FSeek64(fp.get(), 0, SEEK_SET) || + std::fread(eeMem->ROM, static_cast(std::min(Ps2MemSize::Rom, filesize)), 1, fp.get()) != 1) { - wxString Bios( EmuConfig.FullpathToBios() ); - if( EmuConfig.BaseFilenames.Bios.empty() ) - throw Exception::FileNotFound( Bios ) - .SetDiagMsg(L"BIOS has not been configured, or the configuration has been corrupted.") - .SetUserMsg(_("The PS2 BIOS could not be loaded. The BIOS has not been configured, or the configuration has been corrupted. Please re-configure.")); - - s64 filesize = Path::GetFileSize( Bios ); - if( filesize <= 0 ) - { - throw Exception::FileNotFound( Bios ) - .SetDiagMsg(L"Configured BIOS file does not exist, or has a file size of zero.") - .SetUserMsg(_("The configured BIOS file does not exist. Please re-configure.")); - } - - BiosChecksum = 0; - - wxFFile fp( Bios , "rb"); - fp.Read( eeMem->ROM, std::min( Ps2MemSize::Rom, filesize ) ); - - // If file is less than 2mb it doesn't have an OSD (Devel consoles) - // So skip HLEing OSDSys Param stuff - if (filesize < 2465792) - NoOSD = true; - else - NoOSD = false; - - ChecksumIt( BiosChecksum, eeMem->ROM ); - - pxInputStream memfp( Bios, new wxMemoryInputStream( eeMem->ROM, sizeof(eeMem->ROM) ) ); - LoadBiosVersion( memfp, BiosVersion, BiosDescription, BiosRegion, biosZone ); - - Console.SetTitle( pxsFmt( L"Running BIOS (%s v%u.%u)", - WX_STR(biosZone), BiosVersion >> 8, BiosVersion & 0xff - )); - - //injectIRX("host.irx"); //not fully tested; still buggy - - LoadExtraRom( L"rom1", eeMem->ROM1 ); - LoadExtraRom( L"rom2", eeMem->ROM2 ); - LoadExtraRom( L"erom", eeMem->EROM ); - - if (EmuConfig.CurrentIRX.length() > 3) - LoadIrx(EmuConfig.CurrentIRX, &eeMem->ROM[0x3C0000]); - - CurrentBiosInformation.threadListAddr = 0; - } - catch (Exception::BadStream& ex) - { - // Rethrow as a Bios Load Failure, so that the user interface handling the exceptions - // can respond to it appropriately. - throw Exception::BiosLoadFailed( ex.StreamName ) - .SetDiagMsg( ex.DiagMsg() ) - .SetUserMsg( ex.UserMsg() ); + return false; } + + // If file is less than 2mb it doesn't have an OSD (Devel consoles) + // So skip HLEing OSDSys Param stuff + if (filesize < 2465792) + NoOSD = true; + else + NoOSD = false; + + BiosChecksum = 0; + ChecksumIt(BiosChecksum, eeMem->ROM); + +#ifndef PCSX2_CORE + Console.SetTitle(StringUtil::UTF8StringToWxString(StringUtil::StdStringFromFormat("Running BIOS (%s v%u.%u)", + BiosZone.c_str(), BiosVersion >> 8, BiosVersion & 0xff))); +#endif + + //injectIRX("host.irx"); //not fully tested; still buggy + + LoadExtraRom("rom1", eeMem->ROM1); + LoadExtraRom("rom2", eeMem->ROM2); + LoadExtraRom("erom", eeMem->EROM); + + if (EmuConfig.CurrentIRX.length() > 3) + LoadIrx(EmuConfig.CurrentIRX, &eeMem->ROM[0x3C0000], sizeof(eeMem->ROM) - 0x3C0000); + + CurrentBiosInformation.threadListAddr = 0; + return true; } -bool IsBIOS(const wxString& filename, wxString& description) +bool IsBIOS(const char* filename, u32& version, std::string& description, u32& region, std::string& zone) { - wxFileName Bios( EmuFolders::Bios + filename ); - pxInputStream inway( filename, new wxFFileInputStream( filename ) ); + const std::string bios_path(Path::Combine(EmuFolders::Bios, wxString::FromUTF8(filename)).ToStdString()); + const auto fp = FileSystem::OpenManagedCFile(filename, "rb"); + if (!fp) + return false; - if (!inway.IsOk()) return false; // FPS2BIOS is smaller and of variable size //if (inway.Length() < 512*1024) return false; - - try { - u32 version; - u32 region; - LoadBiosVersion( inway, version, description, region ); - return true; - } catch( Exception::BadStream& ) { } - - return false; // fail quietly + return LoadBiosVersion(fp.get(), version, description, region, zone); } diff --git a/pcsx2/ps2/BiosTools.h b/pcsx2/ps2/BiosTools.h index e8513d0f5b..be8d84cf1f 100644 --- a/pcsx2/ps2/BiosTools.h +++ b/pcsx2/ps2/BiosTools.h @@ -14,19 +14,7 @@ */ #pragma once - -namespace Exception -{ - class BiosLoadFailed : public BadStream - { - DEFINE_EXCEPTION_COPYTORS( BiosLoadFailed, FileNotFound ) - DEFINE_EXCEPTION_MESSAGES( BiosLoadFailed ) - DEFINE_STREAM_EXCEPTION_ACCESSORS( BiosLoadFailed ) - - public: - BiosLoadFailed( const wxString& streamName ); - }; -} +#include const u32 ThreadListInstructions[3] = { @@ -47,7 +35,8 @@ extern bool NoOSD; // Used for HLE OSD Config Params extern bool AllowParams1; extern bool AllowParams2; extern u32 BiosChecksum; -extern wxString BiosDescription; -extern wxString biosZone; -extern void LoadBIOS(); -extern bool IsBIOS(const wxString& filename, wxString& description); +extern std::string BiosDescription; +extern std::string BiosZone; +extern bool LoadBIOS(); +extern bool IsBIOS(const char* filename, u32& version, std::string& description, u32& region, std::string& zone); +