1
0
mirror of synced 2025-01-11 22:02:17 +01:00
BioTheWolff 2dcaf2c77b
fix: Various achievements issues (Edit the Hex, ROM Hacks) (#1985)
### Problem description
As described in #1846:
- the `Edit the Hex` achievement doesn't unlock when it should
- the `ROM Hacks` achievement is not using event-driven architecture
(the functions call `unlockAchievement` themselves)

### Implementation description
Firstly, for the `Edit the Hex` achievement:
- replaced the old event listener on `EventPatchCreated` with a listener
on `EventProviderDataModified`, which picks up bytes changes
- ensured the provider data change comes from a File provider, else
unlocking the achievement wouldn't make sense
- *Note*: a discovered side effect is that the "Fill" function modifies
the provider byte per byte (with a for loop)
- there is no use in testing the size of the data change, as it is
always 1 byte
- the Fill function could probably be reworked to fill in whole regions
at a time?

About the `ROM Hacks` achievement:
- implemented the new, still unused `EventPatchCreated` event.
- signal signature is `const unsigned char *, u64, const IPSKind`:
buffer pointer, buffer size, and IPS kind (IPS/IPS32)
- make use of the `::post` and `::subscribe` methods on said event to
unlock the achievement
- **WARNING::behaviour change**: the event's `post` signal has been
moved in the success branch of the IPS generation condition, meaning
that achievement will only unlock if IPS patch export has worked. I felt
it would make more sense than unlocking an achievement on an error, if
there was any to raise.

---------

Signed-off-by: BioTheWolff <47079795+BioTheWolff@users.noreply.github.com>
2024-12-06 00:36:42 +01:00

47 lines
1.1 KiB
C++

#pragma once
#include <hex.hpp>
#include <map>
#include <vector>
#include <wolv/utils/expected.hpp>
namespace hex {
namespace prv {
class Provider;
}
enum class IPSError {
AddressOutOfRange,
PatchTooLarge,
InvalidPatchHeader,
InvalidPatchFormat,
MissingEOF
};
enum class PatchKind {
IPS,
IPS32
};
class Patches {
public:
Patches() = default;
Patches(std::map<u64, u8> &&patches) : m_patches(std::move(patches)) {}
static wolv::util::Expected<Patches, IPSError> fromProvider(hex::prv::Provider *provider);
static wolv::util::Expected<Patches, IPSError> fromIPSPatch(const std::vector<u8> &ipsPatch);
static wolv::util::Expected<Patches, IPSError> fromIPS32Patch(const std::vector<u8> &ipsPatch);
wolv::util::Expected<std::vector<u8>, IPSError> toIPSPatch() const;
wolv::util::Expected<std::vector<u8>, IPSError> toIPS32Patch() const;
const auto& get() const { return m_patches; }
auto& get() { return m_patches; }
private:
std::map<u64, u8> m_patches;
};
}