diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 8c7b6bb578..18a3575086 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -130,6 +130,9 @@ bool TryParse(const std::string &str, u32 *const output) if (!endptr || *endptr) return false; + if (value == ULONG_MAX && errno == ERANGE) + return false; + *output = value; return true; } diff --git a/Source/Core/Core/Src/PatchEngine.cpp b/Source/Core/Core/Src/PatchEngine.cpp index 22aa517752..6528ad6752 100644 --- a/Source/Core/Core/Src/PatchEngine.cpp +++ b/Source/Core/Core/Src/PatchEngine.cpp @@ -59,6 +59,7 @@ std::vector discList; void LoadPatchSection(const char *section, std::vector &patches, IniFile &ini) { std::vector lines; + if (!ini.GetLines(section, lines)) return; @@ -67,12 +68,14 @@ void LoadPatchSection(const char *section, std::vector &patches, IniFile for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { std::string line = *iter; + if (line.size()) { if (line[0] == '+' || line[0] == '$') { // Take care of the previous code - if (currentPatch.name.size()) patches.push_back(currentPatch); + if (currentPatch.name.size()) + patches.push_back(currentPatch); currentPatch.entries.clear(); // Set active and name @@ -85,12 +88,15 @@ void LoadPatchSection(const char *section, std::vector &patches, IniFile } std::string::size_type loc = line.find_first_of('=', 0); + if (loc != std::string::npos) line[loc] = ':'; std::vector items; SplitString(line, ':', items); - if (items.size() >= 3) { + + if (items.size() >= 3) + { PatchEntry pE; bool success = true; success &= TryParse(items[0], &pE.address); @@ -103,7 +109,9 @@ void LoadPatchSection(const char *section, std::vector &patches, IniFile } } } - if (currentPatch.name.size()) patches.push_back(currentPatch); + + if (currentPatch.name.size() && currentPatch.entries.size()) + patches.push_back(currentPatch); } static void LoadDiscList(const char *section, std::vector &_discList, IniFile &ini) { diff --git a/Source/Core/Core/Src/PatchEngine.h b/Source/Core/Core/Src/PatchEngine.h index 6fa215b911..9b029f943f 100644 --- a/Source/Core/Core/Src/PatchEngine.h +++ b/Source/Core/Core/Src/PatchEngine.h @@ -53,6 +53,27 @@ void LoadPatchSection(const char *section, std::vector &patches, IniFile void LoadPatches(const char *gameID); void ApplyFramePatches(); void ApplyARPatches(); + +inline int GetPatchTypeCharLength(PatchType type) +{ + int size = 8; + switch (type) + { + case PatchEngine::PATCH_8BIT: + size = 2; + break; + + case PatchEngine::PATCH_16BIT: + size = 4; + break; + + case PatchEngine::PATCH_32BIT: + size = 8; + break; + } + return size; +} + } // namespace #endif //_PATCHENGINE_H diff --git a/Source/Core/DolphinWX/Src/PatchAddEdit.cpp b/Source/Core/DolphinWX/Src/PatchAddEdit.cpp index 1cc85286c0..7d521006d3 100644 --- a/Source/Core/DolphinWX/Src/PatchAddEdit.cpp +++ b/Source/Core/DolphinWX/Src/PatchAddEdit.cpp @@ -71,7 +71,7 @@ void CPatchAddEdit::CreateGUIControls(int _selection) EditPatchType->SetSelection((int)tempEntries.at(0).type); wxStaticText* EditPatchValueText = new wxStaticText(this, ID_EDITPATCH_VALUE_TEXT, _("Value:")); EditPatchValue = new wxTextCtrl(this, ID_EDITPATCH_VALUE); - EditPatchValue->SetValue(wxString::Format(wxT("%08X"), tempEntries.at(0).value)); + EditPatchValue->SetValue(wxString::Format(wxT("%0*X"), PatchEngine::GetPatchTypeCharLength(tempEntries.at(0).type), tempEntries.at(0).value)); wxButton *EntryAdd = new wxButton(this, ID_ENTRY_ADD, _("Add")); EntryRemove = new wxButton(this, ID_ENTRY_REMOVE, _("Remove")); if ((int)tempEntries.size() <= 1) @@ -105,7 +105,8 @@ void CPatchAddEdit::CreateGUIControls(int _selection) void CPatchAddEdit::ChangeEntry(wxSpinEvent& event) { - SaveEntryData(itCurEntry); + if (!UpdateTempEntryData(itCurEntry)) + return; itCurEntry = tempEntries.end() - event.GetPosition() - 1; currentItem = (int)tempEntries.size() - event.GetPosition(); @@ -114,7 +115,8 @@ void CPatchAddEdit::ChangeEntry(wxSpinEvent& event) void CPatchAddEdit::SavePatchData(wxCommandEvent& event) { - SaveEntryData(itCurEntry); + if (!UpdateTempEntryData(itCurEntry)) + return; if (selection == -1) { @@ -141,7 +143,8 @@ void CPatchAddEdit::AddRemoveEntry(wxCommandEvent& event) { case ID_ENTRY_ADD: { - SaveEntryData(itCurEntry); + if (!UpdateTempEntryData(itCurEntry)) + break; PatchEngine::PatchEntry peEmptyEntry(PatchEngine::PATCH_8BIT, 0x00000000, 0x00000000); ++itCurEntry; @@ -188,16 +191,38 @@ void CPatchAddEdit::UpdateEntryCtrls(PatchEngine::PatchEntry pE) (int)tempEntries.size())); EditPatchOffset->SetValue(wxString::Format(wxT("%08X"), pE.address)); EditPatchType->SetSelection(pE.type); - EditPatchValue->SetValue(wxString::Format(wxT("%08X"), pE.value)); + EditPatchValue->SetValue(wxString::Format(wxT("%0*X"), + PatchEngine::GetPatchTypeCharLength(pE.type), pE.value)); } -void CPatchAddEdit::SaveEntryData(std::vector::iterator iterEntry) +bool CPatchAddEdit::UpdateTempEntryData(std::vector::iterator iterEntry) { unsigned long value; + bool parsed_ok = true; if (EditPatchOffset->GetValue().ToULong(&value, 16)) (*iterEntry).address = value; - (*iterEntry).type = (PatchEngine::PatchType) EditPatchType->GetSelection(); + else + parsed_ok = false; + + PatchEngine::PatchType tempType = + (*iterEntry).type = (PatchEngine::PatchType)EditPatchType->GetSelection(); + if (EditPatchValue->GetValue().ToULong(&value, 16)) + { (*iterEntry).value = value; + if (tempType == PatchEngine::PATCH_8BIT && value > 0xff) + parsed_ok = false; + else if (tempType == PatchEngine::PATCH_16BIT && value > 0xffff) + parsed_ok = false; + } + else + parsed_ok = false; + + if (!parsed_ok) + { + PanicAlertT("Unable to create patch from given values.\nEntry not modified."); + } + + return parsed_ok; } diff --git a/Source/Core/DolphinWX/Src/PatchAddEdit.h b/Source/Core/DolphinWX/Src/PatchAddEdit.h index 023ceb0f13..1945d5e330 100644 --- a/Source/Core/DolphinWX/Src/PatchAddEdit.h +++ b/Source/Core/DolphinWX/Src/PatchAddEdit.h @@ -62,7 +62,7 @@ class CPatchAddEdit : public wxDialog void SavePatchData(wxCommandEvent& event); void AddRemoveEntry(wxCommandEvent& event); void UpdateEntryCtrls(PatchEngine::PatchEntry pE); - void SaveEntryData(std::vector::iterator iterEntry); + bool UpdateTempEntryData(std::vector::iterator iterEntry); int selection, currentItem; std::vector tempEntries;