| 321 | } |
| 322 | |
| 323 | void exportIPS32Patch() { |
| 324 | auto provider = ImHexApi::Provider::get(); |
| 325 | |
| 326 | auto patches = Patches::fromProvider(provider); |
| 327 | if (!patches.has_value()) { |
| 328 | handleIPSError(patches.error()); |
| 329 | return; |
| 330 | } |
| 331 | |
| 332 | // Make sure there's no patch at address 0x45454F46 because that would cause the patch to contain the sequence "*EOF" which signals the end of the patch |
| 333 | if (!patches->get().contains(0x45454F45) && patches->get().contains(0x45454F46)) { |
| 334 | u8 value = 0; |
| 335 | provider->read(0x45454F45, &value, sizeof(u8)); |
| 336 | patches->get().at(0x45454F45) = value; |
| 337 | } |
| 338 | |
| 339 | TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [patches](auto &) { |
| 340 | auto data = patches->toIPS32Patch(); |
| 341 | |
| 342 | TaskManager::doLater([data] { |
| 343 | fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) { |
| 344 | auto file = wolv::io::File(path, wolv::io::File::Mode::Create); |
| 345 | if (!file.isValid()) { |
| 346 | ui::ToastError::open("hex.builtin.menu.file.export.ips.popup.export_error"_lang); |
| 347 | return; |
| 348 | } |
| 349 | |
| 350 | if (data.has_value()) { |
| 351 | const std::vector<u8>& bytes = data.value(); |
| 352 | file.writeVector(bytes); |
| 353 | EventPatchCreated::post(bytes.data(), bytes.size(), PatchKind::IPS32); |
| 354 | } else { |
| 355 | handleIPSError(data.error()); |
| 356 | } |
| 357 | }); |
| 358 | }); |
| 359 | }); |
| 360 | } |
| 361 | |
| 362 | } |
| 363 | |