210 lines
13 KiB
C++
210 lines
13 KiB
C++
#include "ui/error_box.hpp"
|
|
#include "ui/nvg_util.hpp"
|
|
#include "app.hpp"
|
|
#include "i18n.hpp"
|
|
|
|
namespace sphaira::ui {
|
|
namespace {
|
|
|
|
auto GetModule(Result rc) -> const char* {
|
|
switch (R_MODULE(rc)) {
|
|
case Module_Svc: return "Svc";
|
|
case Module_Fs: return "Fs";
|
|
case Module_Os: return "Os";
|
|
case Module_Ncm: return "Ncm";
|
|
case Module_Ns: return "Ns";
|
|
case Module_Spl: return "Spl";
|
|
case Module_Applet: return "Applet";
|
|
case Module_Usb: return "Usb";
|
|
case Module_Irsensor: return "Irsensor";
|
|
case Module_Libnx: return "Libnx";
|
|
case Module_Sphaira: return "Sphaira";
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
auto GetCodeMessage(Result rc) -> const char* {
|
|
switch (rc) {
|
|
case SvcError_TimedOut: return "SvcError_TimedOut";
|
|
case SvcError_Cancelled: return "SvcError_Cancelled";
|
|
|
|
case FsError_PathNotFound: return "FsError_PathNotFound";
|
|
case FsError_PathAlreadyExists: return "FsError_PathAlreadyExists";
|
|
case FsError_TargetLocked: return "FsError_TargetLocked";
|
|
case FsError_TooLongPath: return "FsError_TooLongPath";
|
|
case FsError_InvalidCharacter: return "FsError_InvalidCharacter";
|
|
case FsError_InvalidOffset: return "FsError_InvalidOffset";
|
|
case FsError_InvalidSize: return "FsError_InvalidSize";
|
|
|
|
case Result_TransferCancelled: return "SphairaError_TransferCancelled";
|
|
case Result_StreamBadSeek: return "SphairaError_StreamBadSeek";
|
|
case Result_FsTooManyEntries: return "SphairaError_FsTooManyEntries";
|
|
case Result_FsNewPathTooLarge: return "SphairaError_FsNewPathTooLarge";
|
|
case Result_FsInvalidType: return "SphairaError_FsInvalidType";
|
|
case Result_FsEmpty: return "SphairaError_FsEmpty";
|
|
case Result_FsAlreadyRoot: return "SphairaError_FsAlreadyRoot";
|
|
case Result_FsNoCurrentPath: return "SphairaError_FsNoCurrentPath";
|
|
case Result_FsBrokenCurrentPath: return "SphairaError_FsBrokenCurrentPath";
|
|
case Result_FsIndexOutOfBounds: return "SphairaError_FsIndexOutOfBounds";
|
|
case Result_FsFsNotActive: return "SphairaError_FsFsNotActive";
|
|
case Result_FsNewPathEmpty: return "SphairaError_FsNewPathEmpty";
|
|
case Result_FsLoadingCancelled: return "SphairaError_FsLoadingCancelled";
|
|
case Result_FsBrokenRoot: return "SphairaError_FsBrokenRoot";
|
|
case Result_FsUnknownStdioError: return "SphairaError_FsUnknownStdioError";
|
|
case Result_FsReadOnly: return "SphairaError_FsReadOnly";
|
|
case Result_FsNotActive: return "SphairaError_FsNotActive";
|
|
case Result_FsFailedStdioStat: return "SphairaError_FsFailedStdioStat";
|
|
case Result_FsFailedStdioOpendir: return "SphairaError_FsFailedStdioOpendir";
|
|
case Result_NroBadMagic: return "SphairaError_NroBadMagic";
|
|
case Result_NroBadSize: return "SphairaError_NroBadSize";
|
|
case Result_AppFailedMusicDownload: return "SphairaError_AppFailedMusicDownload";
|
|
case Result_CurlFailedEasyInit: return "SphairaError_CurlFailedEasyInit";
|
|
case Result_DumpFailedNetworkUpload: return "SphairaError_DumpFailedNetworkUpload";
|
|
case Result_UnzOpen2_64: return "SphairaError_UnzOpen2_64";
|
|
case Result_UnzGetGlobalInfo64: return "SphairaError_UnzGetGlobalInfo64";
|
|
case Result_UnzLocateFile: return "SphairaError_UnzLocateFile";
|
|
case Result_UnzGoToFirstFile: return "SphairaError_UnzGoToFirstFile";
|
|
case Result_UnzGoToNextFile: return "SphairaError_UnzGoToNextFile";
|
|
case Result_UnzOpenCurrentFile: return "SphairaError_UnzOpenCurrentFile";
|
|
case Result_UnzGetCurrentFileInfo64: return "SphairaError_UnzGetCurrentFileInfo64";
|
|
case Result_UnzReadCurrentFile: return "SphairaError_UnzReadCurrentFile";
|
|
case Result_ZipOpen2_64: return "SphairaError_ZipOpen2_64";
|
|
case Result_ZipOpenNewFileInZip: return "SphairaError_ZipOpenNewFileInZip";
|
|
case Result_ZipWriteInFileInZip: return "SphairaError_ZipWriteInFileInZip";
|
|
case Result_FileBrowserFailedUpload: return "SphairaError_FileBrowserFailedUpload";
|
|
case Result_FileBrowserDirNotDaybreak: return "SphairaError_FileBrowserDirNotDaybreak";
|
|
case Result_AppstoreFailedZipDownload: return "SphairaError_AppstoreFailedZipDownload";
|
|
case Result_AppstoreFailedMd5: return "SphairaError_AppstoreFailedMd5";
|
|
case Result_AppstoreFailedParseManifest: return "SphairaError_AppstoreFailedParseManifest";
|
|
case Result_GameBadReadForDump: return "SphairaError_GameBadReadForDump";
|
|
case Result_GameEmptyMetaEntries: return "SphairaError_GameEmptyMetaEntries";
|
|
case Result_GameMultipleKeysFound: return "SphairaError_GameMultipleKeysFound";
|
|
case Result_GameNoNspEntriesBuilt: return "SphairaError_GameNoNspEntriesBuilt";
|
|
case Result_KeyMissingNcaKeyArea: return "SphairaError_KeyMissingNcaKeyArea";
|
|
case Result_KeyMissingTitleKek: return "SphairaError_KeyMissingTitleKek";
|
|
case Result_KeyMissingMasterKey: return "SphairaError_KeyMissingMasterKey";
|
|
case Result_KeyFailedDecyptETicketDeviceKey: return "SphairaError_KeyFailedDecyptETicketDeviceKey";
|
|
case Result_NcaFailedNcaHeaderHashVerify: return "SphairaError_NcaFailedNcaHeaderHashVerify";
|
|
case Result_NcaBadSigKeyGen: return "SphairaError_NcaBadSigKeyGen";
|
|
case Result_GcBadReadForDump: return "SphairaError_GcBadReadForDump";
|
|
case Result_GcEmptyGamecard: return "SphairaError_GcEmptyGamecard";
|
|
case Result_GcBadXciMagic: return "SphairaError_GcBadXciMagic";
|
|
case Result_GcBadXciRomSize: return "SphairaError_GcBadXciRomSize";
|
|
case Result_GcFailedToGetSecurityInfo: return "SphairaError_GcFailedToGetSecurityInfo";
|
|
case Result_GhdlEmptyAsset: return "SphairaError_GhdlEmptyAsset";
|
|
case Result_GhdlFailedToDownloadAsset: return "SphairaError_GhdlFailedToDownloadAsset";
|
|
case Result_GhdlFailedToDownloadAssetJson: return "SphairaError_GhdlFailedToDownloadAssetJson";
|
|
case Result_ThemezerFailedToDownloadThemeMeta: return "SphairaError_ThemezerFailedToDownloadThemeMeta";
|
|
case Result_ThemezerFailedToDownloadTheme: return "SphairaError_ThemezerFailedToDownloadTheme";
|
|
case Result_MainFailedToDownloadUpdate: return "SphairaError_MainFailedToDownloadUpdate";
|
|
case Result_UsbDsBadDeviceSpeed: return "SphairaError_UsbDsBadDeviceSpeed";
|
|
case Result_NspBadMagic: return "SphairaError_NspBadMagic";
|
|
case Result_XciBadMagic: return "SphairaError_XciBadMagic";
|
|
case Result_XciSecurePartitionNotFound: return "SphairaError_XciSecurePartitionNotFound";
|
|
case Result_EsBadTitleKeyType: return "SphairaError_EsBadTitleKeyType";
|
|
case Result_EsPersonalisedTicketDeviceIdMissmatch: return "SphairaError_EsPersonalisedTicketDeviceIdMissmatch";
|
|
case Result_EsFailedDecryptPersonalisedTicket: return "SphairaError_EsFailedDecryptPersonalisedTicket";
|
|
case Result_EsBadDecryptedPersonalisedTicketSize: return "SphairaError_EsBadDecryptedPersonalisedTicketSize";
|
|
case Result_EsInvalidTicketBadRightsId: return "SphairaError_EsInvalidTicketBadRightsId";
|
|
case Result_EsInvalidTicketFromatVersion: return "SphairaError_EsInvalidTicketFromatVersion";
|
|
case Result_EsInvalidTicketKeyType: return "SphairaError_EsInvalidTicketKeyType";
|
|
case Result_EsInvalidTicketKeyRevision: return "SphairaError_EsInvalidTicketKeyRevision";
|
|
case Result_OwoBadArgs: return "SphairaError_OwoBadArgs";
|
|
case Result_UsbCancelled: return "SphairaError_UsbCancelled";
|
|
case Result_UsbBadMagic: return "SphairaError_UsbBadMagic";
|
|
case Result_UsbBadVersion: return "SphairaError_UsbBadVersion";
|
|
case Result_UsbBadCount: return "SphairaError_UsbBadCount";
|
|
case Result_UsbBadBufferAlign: return "SphairaError_UsbBadBufferAlign";
|
|
case Result_UsbBadTransferSize: return "SphairaError_UsbBadTransferSize";
|
|
case Result_UsbEmptyTransferSize: return "SphairaError_UsbEmptyTransferSize";
|
|
case Result_UsbOverflowTransferSize: return "SphairaError_UsbOverflowTransferSize";
|
|
case Result_UsbUploadBadMagic: return "SphairaError_UsbUploadBadMagic";
|
|
case Result_UsbUploadExit: return "SphairaError_UsbUploadExit";
|
|
case Result_UsbUploadBadCount: return "SphairaError_UsbUploadBadCount";
|
|
case Result_UsbUploadBadTransferSize: return "SphairaError_UsbUploadBadTransferSize";
|
|
case Result_UsbUploadBadTotalSize: return "SphairaError_UsbUploadBadTotalSize";
|
|
case Result_UsbUploadBadCommand: return "SphairaError_UsbUploadBadCommand";
|
|
case Result_YatiContainerNotFound: return "SphairaError_YatiContainerNotFound";
|
|
case Result_YatiNcaNotFound: return "SphairaError_YatiNcaNotFound";
|
|
case Result_YatiInvalidNcaReadSize: return "SphairaError_YatiInvalidNcaReadSize";
|
|
case Result_YatiInvalidNcaSigKeyGen: return "SphairaError_YatiInvalidNcaSigKeyGen";
|
|
case Result_YatiInvalidNcaMagic: return "SphairaError_YatiInvalidNcaMagic";
|
|
case Result_YatiInvalidNcaSignature0: return "SphairaError_YatiInvalidNcaSignature0";
|
|
case Result_YatiInvalidNcaSignature1: return "SphairaError_YatiInvalidNcaSignature1";
|
|
case Result_YatiInvalidNcaSha256: return "SphairaError_YatiInvalidNcaSha256";
|
|
case Result_YatiNczSectionNotFound: return "SphairaError_YatiNczSectionNotFound";
|
|
case Result_YatiInvalidNczSectionCount: return "SphairaError_YatiInvalidNczSectionCount";
|
|
case Result_YatiNczBlockNotFound: return "SphairaError_YatiNczBlockNotFound";
|
|
case Result_YatiInvalidNczBlockVersion: return "SphairaError_YatiInvalidNczBlockVersion";
|
|
case Result_YatiInvalidNczBlockType: return "SphairaError_YatiInvalidNczBlockType";
|
|
case Result_YatiInvalidNczBlockTotal: return "SphairaError_YatiInvalidNczBlockTotal";
|
|
case Result_YatiInvalidNczBlockSizeExponent: return "SphairaError_YatiInvalidNczBlockSizeExponent";
|
|
case Result_YatiInvalidNczZstdError: return "SphairaError_YatiInvalidNczZstdError";
|
|
case Result_YatiTicketNotFound: return "SphairaError_YatiTicketNotFound";
|
|
case Result_YatiInvalidTicketBadRightsId: return "SphairaError_YatiInvalidTicketBadRightsId";
|
|
case Result_YatiCertNotFound: return "SphairaError_YatiCertNotFound";
|
|
case Result_YatiNcmDbCorruptHeader: return "SphairaError_YatiNcmDbCorruptHeader";
|
|
case Result_YatiNcmDbCorruptInfos: return "SphairaError_YatiNcmDbCorruptInfos";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ErrorBox::ErrorBox(const std::string& message) : m_message{message} {
|
|
log_write("[ERROR] %s\n", m_message.c_str());
|
|
|
|
m_pos.w = 770.f;
|
|
m_pos.h = 430.f;
|
|
m_pos.x = 255;
|
|
m_pos.y = 145;
|
|
|
|
SetAction(Button::A, Action{[this](){
|
|
SetPop();
|
|
}});
|
|
|
|
App::PlaySoundEffect(SoundEffect::SoundEffect_Error);
|
|
}
|
|
|
|
ErrorBox::ErrorBox(Result code, const std::string& message) : ErrorBox{message} {
|
|
m_code = code;
|
|
m_code_message = GetCodeMessage(code);
|
|
m_code_module = std::to_string(R_MODULE(code));
|
|
if (auto str = GetModule(code)) {
|
|
m_code_module += " (" + std::string(str) + ")";
|
|
}
|
|
log_write("[ERROR] Code: 0x%X Module: %s Description: %u\n", R_VALUE(code), m_code_module.c_str(), R_DESCRIPTION(code));
|
|
}
|
|
|
|
auto ErrorBox::Update(Controller* controller, TouchInfo* touch) -> void {
|
|
Widget::Update(controller, touch);
|
|
}
|
|
|
|
auto ErrorBox::Draw(NVGcontext* vg, Theme* theme) -> void {
|
|
gfx::dimBackground(vg);
|
|
gfx::drawRect(vg, m_pos, theme->GetColour(ThemeEntryID_POPUP));
|
|
|
|
const Vec4 box = { 455, 470, 365, 65 };
|
|
const auto center_x = m_pos.x + m_pos.w/2;
|
|
|
|
gfx::drawTextArgs(vg, center_x, 180, 63, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_ERROR), "\uE140");
|
|
if (m_code.has_value()) {
|
|
const auto code = m_code.value();
|
|
if (m_code_message.empty()) {
|
|
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "Code: 0x%X Module: %s", R_VALUE(code), m_code_module.c_str());
|
|
} else {
|
|
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "%s", m_code_message.c_str());
|
|
}
|
|
} else {
|
|
gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "An error occurred"_i18n.c_str());
|
|
}
|
|
gfx::drawTextArgs(vg, center_x, 325, 23, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT), "%s", m_message.c_str());
|
|
gfx::drawTextArgs(vg, center_x, 380, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT_INFO), "If this message appears repeatedly, please open an issue."_i18n.c_str());
|
|
gfx::drawTextArgs(vg, center_x, 415, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->GetColour(ThemeEntryID_TEXT_INFO), "https://github.com/ITotalJustice/sphaira/issues");
|
|
gfx::drawRectOutline(vg, theme, 4.f, box);
|
|
gfx::drawTextArgs(vg, center_x, box.y + box.h/2, 23, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, theme->GetColour(ThemeEntryID_TEXT_SELECTED), "OK"_i18n.c_str());
|
|
}
|
|
|
|
} // namespace sphaira::ui
|