Esempio n. 1
0
CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
 : m_TitleID(TitleID)
{
	Common::ReadReplacements(replacements);
	strcpy(pathData_bin, FileName);
	memcpy(SD_IV, "\x21\x67\x12\xE6\xAA\x1F\x68\x9F\x95\xC5\xA2\x23\x24\xDC\x6A\x98", 0x10);

	if (!TitleID) // Import
	{
		AES_set_decrypt_key(SDKey, 128, &m_AES_KEY);
		do
		{
			b_valid = true;
			ReadHDR();
			ReadBKHDR();
			ImportWiiSaveFiles();
			// TODO: check_sig()
			if (b_valid)
			{
				SuccessAlertT("Successfully imported save files");
				b_tryAgain = false;
			}
			else
			{
				b_tryAgain = AskYesNoT("Import failed, try again?");
			}
		} while(b_tryAgain);
	}
	else
	{
		AES_set_encrypt_key(SDKey, 128, &m_AES_KEY);
		
		if (getPaths(true))
		{
			do
			{
				b_valid = true;
				WriteHDR();
				WriteBKHDR();
				ExportWiiSaveFiles();
				do_sig();
				if (b_valid)
				{
					SuccessAlertT("Successfully exported file to %s", pathData_bin);
					b_tryAgain = false;
				}
				else
				{
					b_tryAgain = AskYesNoT("Export failed, try again?");
				}
			} while(b_tryAgain);
		}
	}
}
Esempio n. 2
0
// Display and Interface settings
void CConfigMain::DisplaySettingsChanged(wxCommandEvent& event)
{
	switch (event.GetId())
	{
	// Display - Interface
	case ID_INTERFACE_CONFIRMSTOP:
		SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop = ConfirmStop->IsChecked();
		break;
	case ID_INTERFACE_USEPANICHANDLERS:
		SConfig::GetInstance().m_LocalCoreStartupParameter.bUsePanicHandlers = UsePanicHandlers->IsChecked();
		SetEnableAlert(UsePanicHandlers->IsChecked());
		break;
	case ID_INTERFACE_ONSCREENDISPLAYMESSAGES:
		SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages = OnScreenDisplayMessages->IsChecked();
		SetEnableAlert(OnScreenDisplayMessages->IsChecked());
		break;
	case ID_INTERFACE_LANG:
		if (SConfig::GetInstance().m_InterfaceLanguage != langIds[InterfaceLang->GetSelection()])
			SuccessAlertT("You must restart Dolphin in order for the change to take effect.");
		SConfig::GetInstance().m_InterfaceLanguage = langIds[InterfaceLang->GetSelection()];
		break;
	case ID_HOTKEY_CONFIG:
		{
			HotkeyConfigDialog m_HotkeyDialog(this);
			m_HotkeyDialog.ShowModal();
		}
		// Update the GUI in case menu accelerators were changed
		main_frame->UpdateGUI();
		break;
	}
}
Esempio n. 3
0
void InterfaceConfigPane::OnInterfaceLanguageChoiceChanged(wxCommandEvent& event)
{
	if (SConfig::GetInstance().m_InterfaceLanguage != language_ids[m_interface_lang_choice->GetSelection()])
		SuccessAlertT("You must restart Dolphin in order for the change to take effect.");

	SConfig::GetInstance().m_InterfaceLanguage = language_ids[m_interface_lang_choice->GetSelection()];
}
Esempio n. 4
0
void CWiiSaveCrypted::ExportAllSaves()
{
	std::string titleFolder = File::GetUserPath(D_WIIUSER_IDX) + "title";
	std::vector<u64> titles;
	u32 pathMask = 0x00010000;
	for (int i = 0; i < 8; ++i)
	{
		File::FSTEntry FST_Temp;
		std::string folder = StringFromFormat("%s/%08x/", titleFolder.c_str(), pathMask | i);
		File::ScanDirectoryTree(folder, FST_Temp);

		for (const File::FSTEntry& entry : FST_Temp.children)
		{
			if (entry.isDirectory)
			{
				u32 gameid;
				if (AsciiToHex(entry.virtualName, gameid))
				{
					std::string bannerPath = StringFromFormat("%s%08x/data/banner.bin", folder.c_str(), gameid);
					if (File::Exists(bannerPath))
					{
						u64 titleID = (((u64)pathMask | i) << 32) | gameid;
						titles.push_back(titleID);
					}
				}
			}
		}
	}
	SuccessAlertT("Found %x save files", (unsigned int) titles.size());
	for (const u64& title : titles)
	{
		CWiiSaveCrypted* exportSave = new CWiiSaveCrypted("", title);
		delete exportSave;
	}
}
Esempio n. 5
0
CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
 : m_TitleID(TitleID)
{
	Common::ReadReplacements(replacements);
	encryptedSavePath = std::string(FileName);
	memcpy(SD_IV, "\x21\x67\x12\xE6\xAA\x1F\x68\x9F\x95\xC5\xA2\x23\x24\xDC\x6A\x98", 0x10);

	if (!TitleID) // Import
	{
		aes_setkey_dec(&m_AES_ctx, SDKey, 128);
			b_valid = true;
			ReadHDR();
			ReadBKHDR();
			ImportWiiSaveFiles();
			// TODO: check_sig()
			if (b_valid)
			{
				SuccessAlertT("Successfully imported save files");
			}
			else
			{
				PanicAlertT("Import failed");
			}
	}
	else
	{
		aes_setkey_enc(&m_AES_ctx, SDKey, 128);

		if (getPaths(true))
		{
			b_valid = true;
			WriteHDR();
			WriteBKHDR();
			ExportWiiSaveFiles();
			do_sig();
			if (b_valid)
			{
				SuccessAlertT("Successfully exported file to %s", encryptedSavePath.c_str());
			}
			else
			{
				 PanicAlertT("Export failed");
			}
		}
	}
}
Esempio n. 6
0
bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2)
{
	std::string Region(EUR_DIR);

	switch (_BootBS2)
	{
	case BOOT_DEFAULT:
		{
			bool bootDrive = cdio_is_cdrom(m_strFilename);
			// Check if the file exist, we may have gotten it from a --elf command line
			// that gave an incorrect file name
			if (!bootDrive && !File::Exists(m_strFilename))
			{
				PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str());
				return false;
			}

			std::string Extension;
			SplitPath(m_strFilename, nullptr, nullptr, &Extension);
			if (!strcasecmp(Extension.c_str(), ".gcm") ||
				!strcasecmp(Extension.c_str(), ".iso") ||
				!strcasecmp(Extension.c_str(), ".wbfs") ||
				!strcasecmp(Extension.c_str(), ".ciso") ||
				!strcasecmp(Extension.c_str(), ".gcz") ||
				bootDrive)
			{
				m_BootType = BOOT_ISO;
				std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
				if (pVolume == nullptr)
				{
					if (bootDrive)
						PanicAlertT("Could not read \"%s\".  "
								"There is no disc in the drive, or it is not a GC/Wii backup.  "
								"Please note that original GameCube and Wii discs cannot be read "
								"by most PC DVD drives.", m_strFilename.c_str());
					else
						PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.",
								m_strFilename.c_str());
					return false;
				}
				m_strName = pVolume->GetName();
				m_strUniqueID = pVolume->GetUniqueID();
				m_strRevisionSpecificUniqueID = pVolume->GetRevisionSpecificUniqueID();

				// Check if we have a Wii disc
				bWii = DiscIO::IsVolumeWiiDisc(pVolume.get());
				switch (pVolume->GetCountry())
				{
				case DiscIO::IVolume::COUNTRY_USA:
					bNTSC = true;
					Region = USA_DIR;
					break;

				case DiscIO::IVolume::COUNTRY_TAIWAN:
				case DiscIO::IVolume::COUNTRY_KOREA:
					// TODO: Should these have their own Region Dir?
				case DiscIO::IVolume::COUNTRY_JAPAN:
					bNTSC = true;
					Region = JAP_DIR;
					break;

				case DiscIO::IVolume::COUNTRY_EUROPE:
				case DiscIO::IVolume::COUNTRY_FRANCE:
				case DiscIO::IVolume::COUNTRY_ITALY:
				case DiscIO::IVolume::COUNTRY_RUSSIA:
					bNTSC = false;
					Region = EUR_DIR;
					break;

				default:
					if (PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)."
								   "\nContinue with PAL region?"))
					{
						bNTSC = false;
						Region = EUR_DIR;
						break;
					}
					else
					{
						return false;
					}
				}
			}
			else if (!strcasecmp(Extension.c_str(), ".elf"))
			{
				bWii = CBoot::IsElfWii(m_strFilename);
				Region = USA_DIR;
				m_BootType = BOOT_ELF;
				bNTSC = true;
			}
			else if (!strcasecmp(Extension.c_str(), ".dol"))
			{
				CDolLoader dolfile(m_strFilename);
				bWii = dolfile.IsWii();
				Region = USA_DIR;
				m_BootType = BOOT_DOL;
				bNTSC = true;
			}
			else if (!strcasecmp(Extension.c_str(), ".dff"))
			{
				bWii = true;
				Region = USA_DIR;
				bNTSC = true;
				m_BootType = BOOT_DFF;

				std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true));

				if (ddfFile)
				{
					bWii = ddfFile->GetIsWii();
				}
			}
			else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid())
			{
				std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
				const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename);

				if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr)
				{
					//WAD is valid yet cannot be booted. Install instead.
					u64 installed = DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_strFilename);
					if (installed)
						SuccessAlertT("The WAD has been installed successfully");
					return false; //do not boot
				}

				switch (ContentLoader.GetCountry())
				{
				case DiscIO::IVolume::COUNTRY_USA:
					bNTSC = true;
					Region = USA_DIR;
					break;

				case DiscIO::IVolume::COUNTRY_TAIWAN:
				case DiscIO::IVolume::COUNTRY_KOREA:
					// TODO: Should these have their own Region Dir?
				case DiscIO::IVolume::COUNTRY_JAPAN:
					bNTSC = true;
					Region = JAP_DIR;
					break;

				case DiscIO::IVolume::COUNTRY_EUROPE:
				case DiscIO::IVolume::COUNTRY_FRANCE:
				case DiscIO::IVolume::COUNTRY_ITALY:
				case DiscIO::IVolume::COUNTRY_RUSSIA:
					bNTSC = false;
					Region = EUR_DIR;
					break;

				default:
					bNTSC = false;
					Region = EUR_DIR;
						break;
				}

				bWii = true;
				m_BootType = BOOT_WII_NAND;

				if (pVolume)
				{
					m_strName = pVolume->GetName();
					m_strUniqueID = pVolume->GetUniqueID();
				}
				else
				{
					// null pVolume means that we are loading from nand folder (Most Likely Wii Menu)
					// if this is the second boot we would be using the Name and id of the last title
					m_strName.clear();
					m_strUniqueID.clear();
				}

				// Use the TitleIDhex for name and/or unique ID if launching from nand folder
				// or if it is not ascii characters (specifically sysmenu could potentially apply to other things)
				std::string titleidstr = StringFromFormat("%016" PRIx64, ContentLoader.GetTitleID());

				if (m_strName.empty())
				{
					m_strName = titleidstr;
				}
				if (m_strUniqueID.empty())
				{
					m_strUniqueID = titleidstr;
				}
			}
			else
			{
				PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str());
				return false;
			}
		}
		break;

	case BOOT_BS2_USA:
		Region = USA_DIR;
		m_strFilename.clear();
		bNTSC = true;
		break;

	case BOOT_BS2_JAP:
		Region = JAP_DIR;
		m_strFilename.clear();
		bNTSC = true;
		break;

	case BOOT_BS2_EUR:
		Region = EUR_DIR;
		m_strFilename.clear();
		bNTSC = false;
		break;
	}

	// Setup paths
	CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, Region, true);
	CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, Region, false);
	m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
	if (!bWii)
	{
		if (!bHLE_BS2)
		{
			m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + Region + DIR_SEP GC_IPL;
			if (!File::Exists(m_strBootROM))
				m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + Region + DIR_SEP GC_IPL;

			if (!File::Exists(m_strBootROM))
			{
				WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str());
				bHLE_BS2 = true;
			}
		}
	}
	else if (bWii && !bHLE_BS2)
	{
		WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode.");
		bHLE_BS2 = true;
	}

	return true;
}
Esempio n. 7
0
bool SConfig::AutoSetup(EBootBS2 _BootBS2)
{
	std::string set_region_dir(EUR_DIR);

	switch (_BootBS2)
	{
	case BOOT_DEFAULT:
		{
			bool bootDrive = cdio_is_cdrom(m_strFilename);
			// Check if the file exist, we may have gotten it from a --elf command line
			// that gave an incorrect file name
			if (!bootDrive && !File::Exists(m_strFilename))
			{
				PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str());
				return false;
			}

			std::string Extension;
			SplitPath(m_strFilename, nullptr, nullptr, &Extension);
			if (!strcasecmp(Extension.c_str(), ".gcm") ||
				!strcasecmp(Extension.c_str(), ".iso") ||
				!strcasecmp(Extension.c_str(), ".wbfs") ||
				!strcasecmp(Extension.c_str(), ".ciso") ||
				!strcasecmp(Extension.c_str(), ".gcz") ||
				bootDrive)
			{
				m_BootType = BOOT_ISO;
				std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
				if (pVolume == nullptr)
				{
					if (bootDrive)
						PanicAlertT("Could not read \"%s\".  "
								"There is no disc in the drive, or it is not a GC/Wii backup.  "
								"Please note that original GameCube and Wii discs cannot be read "
								"by most PC DVD drives.", m_strFilename.c_str());
					else
						PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.",
								m_strFilename.c_str());
					return false;
				}
				m_strName = pVolume->GetInternalName();
				m_strUniqueID = pVolume->GetUniqueID();
				m_revision = pVolume->GetRevision();

				// Check if we have a Wii disc
				bWii = pVolume->GetVolumeType() == DiscIO::IVolume::WII_DISC;

				const char* retrieved_region_dir = GetRegionOfCountry(pVolume->GetCountry());
				if (!retrieved_region_dir)
				{
					if (!PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)."
						"\nContinue with PAL region?"))
						return false;
					retrieved_region_dir = EUR_DIR;
				}

				set_region_dir = retrieved_region_dir;
				bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR;
			}
			else if (!strcasecmp(Extension.c_str(), ".elf"))
			{
				bWii = CBoot::IsElfWii(m_strFilename);
				// TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL.
				// This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz, without forcing all GC homebrew to 50Hz.
				// In the future, it probably makes sense to add a Region setting for homebrew somewhere in the emulator config.
				bNTSC = bWii ? false : true;
				set_region_dir = bNTSC ? USA_DIR : EUR_DIR;
				m_BootType = BOOT_ELF;
			}
			else if (!strcasecmp(Extension.c_str(), ".dol"))
			{
				CDolLoader dolfile(m_strFilename);
				bWii = dolfile.IsWii();
				// TODO: See the ELF code above.
				bNTSC = bWii ? false : true;
				set_region_dir = bNTSC ? USA_DIR : EUR_DIR;
				m_BootType = BOOT_DOL;
			}
			else if (!strcasecmp(Extension.c_str(), ".dff"))
			{
				bWii = true;
				set_region_dir = USA_DIR;
				bNTSC = true;
				m_BootType = BOOT_DFF;

				std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true));

				if (ddfFile)
				{
					bWii = ddfFile->GetIsWii();
				}
			}
			else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid())
			{
				std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
				const DiscIO::CNANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename);

				if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr)
				{
					//WAD is valid yet cannot be booted. Install instead.
					u64 installed = DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_strFilename);
					if (installed)
						SuccessAlertT("The WAD has been installed successfully");
					return false; //do not boot
				}

				const char* retrieved_region_dir = GetRegionOfCountry(ContentLoader.GetCountry());
				set_region_dir = retrieved_region_dir ? retrieved_region_dir : EUR_DIR;
				bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR;

				bWii = true;
				m_BootType = BOOT_WII_NAND;

				if (pVolume)
				{
					m_strName = pVolume->GetInternalName();
					m_strUniqueID = pVolume->GetUniqueID();
				}
				else
				{
					// null pVolume means that we are loading from nand folder (Most Likely Wii Menu)
					// if this is the second boot we would be using the Name and id of the last title
					m_strName.clear();
					m_strUniqueID.clear();
				}

				// Use the TitleIDhex for name and/or unique ID if launching from nand folder
				// or if it is not ascii characters (specifically sysmenu could potentially apply to other things)
				std::string titleidstr = StringFromFormat("%016" PRIx64, ContentLoader.GetTitleID());

				if (m_strName.empty())
				{
					m_strName = titleidstr;
				}
				if (m_strUniqueID.empty())
				{
					m_strUniqueID = titleidstr;
				}
			}
			else
			{
				PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str());
				return false;
			}
		}
		break;

	case BOOT_BS2_USA:
		set_region_dir = USA_DIR;
		m_strFilename.clear();
		bNTSC = true;
		break;

	case BOOT_BS2_JAP:
		set_region_dir = JAP_DIR;
		m_strFilename.clear();
		bNTSC = true;
		break;

	case BOOT_BS2_EUR:
		set_region_dir = EUR_DIR;
		m_strFilename.clear();
		bNTSC = false;
		break;
	}

	// Setup paths
	CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, set_region_dir, true);
	CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, set_region_dir, false);
	m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
	if (!bWii)
	{
		if (!bHLE_BS2)
		{
			m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + set_region_dir + DIR_SEP GC_IPL;
			if (!File::Exists(m_strBootROM))
				m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + set_region_dir + DIR_SEP GC_IPL;

			if (!File::Exists(m_strBootROM))
			{
				WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str());
				bHLE_BS2 = true;
			}
		}
	}
	else if (bWii && !bHLE_BS2)
	{
		WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode.");
		bHLE_BS2 = true;
	}

	return true;
}
void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
{
	int index_A = m_MemcardList[SLOT_A]->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
	int index_B = m_MemcardList[SLOT_B]->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
	int slot = SLOT_B;
	int slot2 = SLOT_A;
	std::string fileName2("");

	if (index_A != wxNOT_FOUND && page[SLOT_A]) index_A += itemsPerPage * page[SLOT_A];
	if (index_B != wxNOT_FOUND && page[SLOT_B]) index_B += itemsPerPage * page[SLOT_B];

	int index = index_B;
	switch (event.GetId())
	{
	case ID_COPYFROM_B:
		slot = SLOT_A;
		slot2 = SLOT_B;
	case ID_COPYFROM_A:
		index = slot2 ? index_B : index_A;
		index = memoryCard[slot2]->GetFileIndex(index);
		if ((index != wxNOT_FOUND))
		{
			CopyDeleteSwitch(memoryCard[slot]->CopyFrom(*memoryCard[slot2], index), slot);
		}
		break;
	case ID_FIXCHECKSUM_A:
		slot = SLOT_A;
	case ID_FIXCHECKSUM_B:
		if (memoryCard[slot]->FixChecksums() && memoryCard[slot]->Save())
		{
			SuccessAlertT("The checksum was successfully fixed");
		}
		else
		{
			PanicAlertT(E_SAVEFAILED);
		}
		break;
	case ID_CONVERTTOGCI:
		fileName2 = "convert";
	case ID_SAVEIMPORT_A:
		slot = SLOT_A;
	case ID_SAVEIMPORT_B:
	{
		wxString fileName = wxFileSelector(
			_("Select a save file to import"),
			(strcmp(DefaultIOPath.c_str(), "/Users/GC") == 0)
				? StrToWxStr("")
				: StrToWxStr(DefaultIOPath),
			wxEmptyString, wxEmptyString,
			_("GameCube Savegame files(*.gci;*.gcs;*.sav)") + wxString("|*.gci;*.gcs;*.sav|") +
			_("Native GCI files(*.gci)") + wxString("|*.gci|") +
			_("MadCatz Gameshark files(*.gcs)") + wxString("|*.gcs|") +
			_("Datel MaxDrive/Pro files(*.sav)") + wxString("|*.sav"),
			wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
		if (!fileName.empty() && !fileName2.empty())
		{
			wxString temp2 = wxFileSelector(_("Save GCI as..."),
				wxEmptyString, wxEmptyString, ".gci",
				_("GCI File(*.gci)") + wxString("|*.gci"),
				wxFD_OVERWRITE_PROMPT|wxFD_SAVE, this);

			if (temp2.empty())
				break;

			fileName2 = WxStrToStr(temp2);
		}
		if (fileName.length() > 0)
		{
			CopyDeleteSwitch(memoryCard[slot]->ImportGci(WxStrToStr(fileName), fileName2), slot);
		}
	}
	break;
	case ID_SAVEEXPORT_A:
		slot=SLOT_A;
		index = index_A;
	case ID_SAVEEXPORT_B:
		index = memoryCard[slot]->GetFileIndex(index);
		if (index != wxNOT_FOUND)
		{
			std::string gciFilename;
			if (!memoryCard[slot]->GCI_FileName(index, gciFilename))
			{
				PanicAlertT("Invalid index");
				return;
			}
			wxString fileName = wxFileSelector(
				_("Export save as..."),
				StrToWxStr(DefaultIOPath),
				StrToWxStr(gciFilename), ".gci",
				_("Native GCI files(*.gci)") + wxString("|*.gci|") +
				_("MadCatz Gameshark files(*.gcs)") + wxString("|*.gcs|") +
				_("Datel MaxDrive/Pro files(*.sav)") + wxString("|*.sav"),
				wxFD_OVERWRITE_PROMPT|wxFD_SAVE, this);

			if (fileName.length() > 0)
			{
				if (!CopyDeleteSwitch(memoryCard[slot]->ExportGci(index, WxStrToStr(fileName), ""), -1))
				{
					File::Delete(WxStrToStr(fileName));
				}
			}
		}
		break;
	case ID_EXPORTALL_A:
		slot=SLOT_A;
	case ID_EXPORTALL_B:
	{
		std::string path1, path2, mpath;
		mpath = WxStrToStr(m_MemcardPath[slot]->GetPath());
		SplitPath(mpath, &path1, &path2, nullptr);
		path1 += path2;
		File::CreateDir(path1);
		if (PanicYesNoT("Warning: This will overwrite any existing saves that are in the folder:\n"
		                "%s\nand have the same name as a file on your memcard\nContinue?", path1.c_str()))
		for (int i = 0; i < DIRLEN; i++)
		{
			CopyDeleteSwitch(memoryCard[slot]->ExportGci(i, "", path1), -1);
		}
		break;
	}
	case ID_DELETE_A:
		slot = SLOT_A;
		index = index_A;
	case ID_DELETE_B:
		index = memoryCard[slot]->GetFileIndex(index);
		if (index != wxNOT_FOUND)
		{
			CopyDeleteSwitch(memoryCard[slot]->RemoveFile(index), slot);
		}
		break;
	}
}
bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot)
{
	switch (error)
	{
	case GCS:
		SuccessAlertT("File converted to .gci");
		break;
	case SUCCESS:
		if (slot != -1)
		{
			memoryCard[slot]->FixChecksums();
			if (!memoryCard[slot]->Save()) PanicAlertT(E_SAVEFAILED);
			page[slot] = FIRSTPAGE;
			ReloadMemcard(WxStrToStr(m_MemcardPath[slot]->GetPath()), slot);
		}
		break;
	case NOMEMCARD:
		PanicAlertT("File is not recognized as a memcard");
		break;
	case OPENFAIL:
		PanicAlertT("File could not be opened\nor does not have a valid extension");
		break;
	case OUTOFBLOCKS:
		if (slot == -1)
		{
			PanicAlertT(E_UNK);
			break;
		}
		PanicAlertT("Only %d blocks available", memoryCard[slot]->GetFreeBlocks());
		break;
	case OUTOFDIRENTRIES:
		PanicAlertT("No free dir index entries");
		break;
	case LENGTHFAIL:
		PanicAlertT("Imported file has invalid length");
		break;
	case INVALIDFILESIZE:
		PanicAlertT("The save you are trying to copy has an invalid file size");
		break;
	case TITLEPRESENT:
		PanicAlertT("Memcard already has a save for this title");
		break;
	case SAVFAIL:
		PanicAlertT("Imported file has sav extension\nbut does not have a correct header");
		break;
	case GCSFAIL:
		PanicAlertT("Imported file has gsc extension\nbut does not have a correct header");
		break;
	case FAIL:
		if (slot == -1)
		{
			PanicAlertT("Export Failed");
			return false;
		}
		PanicAlertT("Invalid bat.map or dir entry");
		break;
	case WRITEFAIL:
		PanicAlertT(E_SAVEFAILED);
		break;
	case DELETE_FAIL:
		PanicAlertT("Order of files in the File Directory do not match the block order\n"
				"Right click and export all of the saves,\nand import the saves to a new memcard\n");
		break;
	default:
		PanicAlertT(E_UNK);
		break;
	}
	SetFocus();
	return true;
}
Esempio n. 10
0
void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
{
	int index_A = m_MemcardList[SLOT_A]->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
	int index_B = m_MemcardList[SLOT_B]->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
	int slot = SLOT_B;
	int slot2 = SLOT_A;
	int index = index_B;
	std::string fileName2("");

	if (index_A != wxNOT_FOUND && page[SLOT_A]) index_A += itemsPerPage * page[SLOT_A];
	if (index_B != wxNOT_FOUND && page[SLOT_B]) index_B += itemsPerPage * page[SLOT_B];

	switch (event.GetId())
	{
	case ID_COPYFROM_B:
		slot = SLOT_A;
		slot2 = SLOT_B;
	case ID_COPYFROM_A:
		index = slot2 ? index_B : index_A;
		if ((index != wxNOT_FOUND))
		{
			CopyDeleteSwitch(memoryCard[slot]->CopyFrom(*memoryCard[slot2], index), slot);
		}
		break;
	case ID_FIXCHECKSUM_A:
		slot = SLOT_A;
	case ID_FIXCHECKSUM_B:
		if (memoryCard[slot]->FixChecksums() && memoryCard[slot]->Save())
		{
			SuccessAlertT("The checksum was successfully fixed");
		}
		else PanicAlert(E_SAVEFAILED);
		break; 
	case ID_CONVERTTOGCI:
		fileName2 = "convert";
	case ID_SAVEIMPORT_A:
		slot = SLOT_A;
	case ID_SAVEIMPORT_B:
	{
		wxString fileName = wxFileSelector(
			_("Select a save file to import"),
			(strcmp(DefaultIOPath.c_str(), "/Users/GC") == 0)
				? wxString::FromAscii("")
				: wxString::From8BitData(DefaultIOPath.c_str()),
			wxEmptyString, wxEmptyString,
			_("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) +
			_("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) +
			_("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")),
			wxFD_OPEN | wxFD_FILE_MUST_EXIST);
		if (!fileName.empty() && !fileName2.empty())
		{
			wxString temp2 = wxFileSelector(_("Save GCI as..."),
				wxEmptyString, wxEmptyString, wxT(".gci"),
				_("GCI File(*.gci)") + wxString(_T("|*.gci")),
				wxFD_OVERWRITE_PROMPT|wxFD_SAVE);
			if (temp2.empty()) break;
			fileName2 = temp2.mb_str();
		}
		if (fileName.length() > 0)
		{
			CopyDeleteSwitch(memoryCard[slot]->ImportGci(fileName.mb_str(), fileName2), slot);
		}
	}
	break;
	case ID_SAVEEXPORT_A:
		slot=SLOT_A;
		index = index_A;
	case ID_SAVEEXPORT_B:
		if (index != wxNOT_FOUND)
		{
			char tempC[10 + DENTRY_STRLEN],
				 tempC2[DENTRY_STRLEN];
			memoryCard[slot]->DEntry_GameCode(index,tempC);
			memoryCard[slot]->DEntry_FileName(index,tempC2);
			sprintf(tempC, "%s_%s.gci", tempC, tempC2);
			wxString fileName = wxFileSelector(
				_("Export save as..."),
				wxString::From8BitData(DefaultIOPath.c_str()),
				wxString::From8BitData(tempC), wxT(".gci"),
				_("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) +
				_("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) +
				_("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")),
				wxFD_OVERWRITE_PROMPT|wxFD_SAVE);

			if (fileName.length() > 0)
			{
				if (!CopyDeleteSwitch(memoryCard[slot]->ExportGci(index, fileName.mb_str(), NULL), -1))
				{
					File::Delete(std::string(fileName.mb_str()));
				}
			}
		}
		break;
	case ID_EXPORTALL_A:
		slot=SLOT_A;
	case ID_EXPORTALL_B:
	{
		std::string path1, path2, mpath;
		mpath = m_MemcardPath[slot]->GetPath().mb_str();
		SplitPath(mpath, &path1, &path2, NULL);
		path1 += path2;
		File::CreateDir(path1);
		if(PanicYesNoT("Warning: This will overwrite any existing saves that are in the folder:\n"
					"%s\nand have the same name as a file on your memcard\nContinue?", path1.c_str()))
		for (int i = 0; i < DIRLEN; i++)
		{
			CopyDeleteSwitch(memoryCard[slot]->ExportGci(i, ".", &path1), -1);
		}
		break;
	}
	case ID_DELETE_A:
		slot = SLOT_A;
		index = index_A;
	case ID_DELETE_B:
		if (index != wxNOT_FOUND)
		{
			CopyDeleteSwitch(memoryCard[slot]->RemoveFile(index), slot);
		}
		break;
	}
}
Esempio n. 11
0
// This one can load both leftover map files on game discs (like Zelda), and mapfiles
// produced by SaveSymbolMap below.
// bad=true means carefully load map files that might not be from exactly the right version
bool PPCSymbolDB::LoadMap(const std::string& filename, bool bad)
{
	File::IOFile f(filename, "r");
	if (!f)
		return false;

	// four columns are used in American Mensa Academy map files and perhaps other games
	bool started = false, four_columns = false;
	int good_count = 0, bad_count = 0;

	char line[512];
	while (fgets(line, 512, f.GetHandle()))
	{
		size_t length = strlen(line);
		if (length < 4)
			continue;

		if (length == 34 && strcmp(line, "  address  Size   address  offset\n") == 0)
		{
			four_columns = true;
			continue;
		}

		char temp[256];
		sscanf(line, "%255s", temp);

		if (strcmp(temp, "UNUSED")==0) continue;
		if (strcmp(temp, ".text")==0)  {started = true; continue;};
		if (strcmp(temp, ".init")==0)  {started = true; continue;};
		if (strcmp(temp, "Starting")==0) continue;
		if (strcmp(temp, "extab")==0) continue;
		if (strcmp(temp, ".ctors")==0) break; //uh?
		if (strcmp(temp, ".dtors")==0) break;
		if (strcmp(temp, ".rodata")==0) continue;
		if (strcmp(temp, ".data")==0) continue;
		if (strcmp(temp, ".sbss")==0) continue;
		if (strcmp(temp, ".sdata")==0) continue;
		if (strcmp(temp, ".sdata2")==0) continue;
		if (strcmp(temp, "address")==0)  continue;
		if (strcmp(temp, "-----------------------")==0)  continue;
		if (strcmp(temp, ".sbss2")==0) break;
		if (temp[1] == ']') continue;

		if (!started) continue;

		u32 address, vaddress, size, offset, unknown;
		char name[512], container[512];
		if (four_columns)
		{
			// sometimes there is no unknown number, and sometimes it is because it is an entry of something else
			if (length > 37 && line[37]==' ')
			{
				unknown = 0;
				sscanf(line, "%08x %08x %08x %08x %511s", &address, &size, &vaddress, &offset, name);
				char *s = strstr(line, "(entry of ");
				if (s)
				{
					sscanf(s + 10, "%511s", container);
					char *s2 = (strchr(container, ')'));
					if (s2 && container[0]!='.')
					{
						s2[0] = '\0';
						strcat(container, "::");
						strcat(container, name);
						strcpy(name, container);
					}
				}
			}
			else
			{
				sscanf(line, "%08x %08x %08x %08x %i %511s", &address, &size, &vaddress, &offset, &unknown, name);
			}
		}
		// some entries in the table have a function name followed by " (entry of " followed by a container name, followed by ")"
		// instead of a space followed by a number followed by a space followed by a name
		else if (length > 27 && line[27] != ' ' && strstr(line, "(entry of "))
		{
			unknown = 0;
			sscanf(line, "%08x %08x %08x %511s", &address, &size, &vaddress, name);
			char *s = strstr(line, "(entry of ");
			if (s)
			{
				sscanf(s + 10, "%511s", container);
				char *s2 = (strchr(container, ')'));
				if (s2 && container[0] != '.')
				{
					s2[0] = '\0';
					strcat(container, "::");
					strcat(container, name);
					strcpy(name, container);
				}
			}
		}
		else
		{
			sscanf(line, "%08x %08x %08x %i %511s", &address, &size, &vaddress, &unknown, name);
		}

		const char *namepos = strstr(line, name);
		if (namepos != nullptr) //would be odd if not :P
			strcpy(name, namepos);
		name[strlen(name) - 1] = 0;

		// we want the function names only .... TODO: or do we really? aren't we wasting information here?
		for (size_t i = 0; i < strlen(name); i++)
		{
			if (name[i] == ' ') name[i] = 0x00;
			if (name[i] == '(') name[i] = 0x00;
		}

		// Check if this is a valid entry.
		if (strcmp(name, ".text") != 0 && strcmp(name, ".init") != 0 && strlen(name) > 0)
		{
			vaddress |= 0x80000000;
			bool good = !bad;
			if (!good)
			{
				// check for BLR before function
				u32 opcode = PowerPC::HostRead_Instruction(vaddress - 4);
				if (opcode == 0x4e800020)
				{
					// check for BLR at end of function
					opcode = PowerPC::HostRead_Instruction(vaddress + size - 4);
					if (opcode == 0x4e800020)
						good = true;
				}
			}
			if (good)
			{
				++good_count;
				AddKnownSymbol(vaddress | 0x80000000, size, name); // ST_FUNCTION
			}
			else
			{
				++bad_count;
			}
		}
	}

	Index();
	if (bad)
		SuccessAlertT("Loaded %d good functions, ignored %d bad functions.", good_count, bad_count);
	return true;
}
Esempio n. 12
0
// This one can load both leftover map files on game discs (like Zelda), and mapfiles
// produced by SaveSymbolMap below.
// bad=true means carefully load map files that might not be from exactly the right version
bool PPCSymbolDB::LoadMap(const std::string& filename, bool bad)
{
  File::IOFile f(filename, "r");
  if (!f)
    return false;

  // four columns are used in American Mensa Academy map files and perhaps other games
  bool four_columns = false;
  int good_count = 0;
  int bad_count = 0;

  char line[512];
  std::string section_name;
  while (fgets(line, 512, f.GetHandle()))
  {
    size_t length = strlen(line);
    if (length < 4)
      continue;

    if (length == 34 && strcmp(line, "  address  Size   address  offset\n") == 0)
    {
      four_columns = true;
      continue;
    }

    char temp[256];
    sscanf(line, "%255s", temp);

    if (strcmp(temp, "UNUSED") == 0)
      continue;

    // Support CodeWarrior and Dolphin map
    if (StringEndsWith(line, " section layout\n") || strcmp(temp, ".text") == 0 ||
        strcmp(temp, ".init") == 0)
    {
      section_name = temp;
      continue;
    }

    // Skip four columns' header.
    //
    // Four columns example:
    //
    // .text section layout
    //   Starting        Virtual
    //   address  Size   address
    //   -----------------------
    if (strcmp(temp, "Starting") == 0)
      continue;
    if (strcmp(temp, "address") == 0)
      continue;
    if (strcmp(temp, "-----------------------") == 0)
      continue;

    // Skip link map.
    //
    // Link map example:
    //
    // Link map of __start
    //  1] __start(func, weak) found in os.a __start.c
    //   2] __init_registers(func, local) found in os.a __start.c
    //    3] _stack_addr found as linker generated symbol
    // ...
    //           10] EXILock(func, global) found in exi.a EXIBios.c
    if (StringEndsWith(temp, "]"))
      continue;

    // TODO - Handle/Write a parser for:
    //  - Memory map
    //  - Link map
    //  - Linker generated symbols
    if (section_name.empty())
      continue;

    u32 address, vaddress, size, offset, alignment;
    char name[512], container[512];
    if (four_columns)
    {
      // sometimes there is no alignment value, and sometimes it is because it is an entry of
      // something else
      if (length > 37 && line[37] == ' ')
      {
        alignment = 0;
        sscanf(line, "%08x %08x %08x %08x %511s", &address, &size, &vaddress, &offset, name);
        char* s = strstr(line, "(entry of ");
        if (s)
        {
          sscanf(s + 10, "%511s", container);
          char* s2 = (strchr(container, ')'));
          if (s2 && container[0] != '.')
          {
            s2[0] = '\0';
            strcat(container, "::");
            strcat(container, name);
            strcpy(name, container);
          }
        }
      }
      else
      {
        sscanf(line, "%08x %08x %08x %08x %i %511s", &address, &size, &vaddress, &offset,
               &alignment, name);
      }
    }
    // some entries in the table have a function name followed by " (entry of " followed by a
    // container name, followed by ")"
    // instead of a space followed by a number followed by a space followed by a name
    else if (length > 27 && line[27] != ' ' && strstr(line, "(entry of "))
    {
      alignment = 0;
      sscanf(line, "%08x %08x %08x %511s", &address, &size, &vaddress, name);
      char* s = strstr(line, "(entry of ");
      if (s)
      {
        sscanf(s + 10, "%511s", container);
        char* s2 = (strchr(container, ')'));
        if (s2 && container[0] != '.')
        {
          s2[0] = '\0';
          strcat(container, "::");
          strcat(container, name);
          strcpy(name, container);
        }
      }
    }
    else
    {
      sscanf(line, "%08x %08x %08x %i %511s", &address, &size, &vaddress, &alignment, name);
    }

    const char* namepos = strstr(line, name);
    if (namepos != nullptr)  // would be odd if not :P
      strcpy(name, namepos);
    name[strlen(name) - 1] = 0;
    if (name[strlen(name) - 1] == '\r')
      name[strlen(name) - 1] = 0;

    // Check if this is a valid entry.
    if (strlen(name) > 0)
    {
      // Can't compute the checksum if not in RAM
      bool good = !bad && PowerPC::HostIsInstructionRAMAddress(vaddress) &&
                  PowerPC::HostIsInstructionRAMAddress(vaddress + size - 4);
      if (!good)
      {
        // check for BLR before function
        PowerPC::TryReadInstResult read_result = PowerPC::TryReadInstruction(vaddress - 4);
        if (read_result.valid && read_result.hex == 0x4e800020)
        {
          // check for BLR at end of function
          read_result = PowerPC::TryReadInstruction(vaddress + size - 4);
          good = read_result.valid && read_result.hex == 0x4e800020;
        }
      }
      if (good)
      {
        ++good_count;
        if (section_name == ".text" || section_name == ".init")
          AddKnownSymbol(vaddress, size, name, Symbol::Type::Function);
        else
          AddKnownSymbol(vaddress, size, name, Symbol::Type::Data);
      }
      else
      {
        ++bad_count;
      }
    }
  }

  Index();
  if (bad)
    SuccessAlertT("Loaded %d good functions, ignored %d bad functions.", good_count, bad_count);
  return true;
}