mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Core/CheatSearch: Implement cheat searching functionality.
This commit is contained in:
219
Source/Core/Core/CheatSearch.h
Normal file
219
Source/Core/Core/CheatSearch.h
Normal file
@ -0,0 +1,219 @@
|
||||
// Copyright 2021 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Result.h"
|
||||
#include "Core/PowerPC/MMU.h"
|
||||
|
||||
namespace Cheats
|
||||
{
|
||||
enum class CompareType
|
||||
{
|
||||
Equal,
|
||||
NotEqual,
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Greater,
|
||||
GreaterOrEqual,
|
||||
};
|
||||
|
||||
enum class FilterType
|
||||
{
|
||||
CompareAgainstSpecificValue,
|
||||
CompareAgainstLastValue,
|
||||
DoNotFilter,
|
||||
};
|
||||
|
||||
enum class DataType
|
||||
{
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
S8,
|
||||
S16,
|
||||
S32,
|
||||
S64,
|
||||
F32,
|
||||
F64,
|
||||
};
|
||||
|
||||
struct SearchValue
|
||||
{
|
||||
std::variant<u8, u16, u32, u64, s8, s16, s32, s64, float, double> m_value;
|
||||
};
|
||||
|
||||
enum class SearchResultValueState : u8
|
||||
{
|
||||
ValueFromPhysicalMemory,
|
||||
ValueFromVirtualMemory,
|
||||
AddressNotAccessible,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SearchResult
|
||||
{
|
||||
T m_value;
|
||||
SearchResultValueState m_value_state;
|
||||
u32 m_address;
|
||||
|
||||
bool IsValueValid() const
|
||||
{
|
||||
return m_value_state == SearchResultValueState::ValueFromPhysicalMemory ||
|
||||
m_value_state == SearchResultValueState::ValueFromVirtualMemory;
|
||||
}
|
||||
};
|
||||
|
||||
struct MemoryRange
|
||||
{
|
||||
u32 m_start;
|
||||
u64 m_length;
|
||||
|
||||
MemoryRange(u32 start, u64 length) : m_start(start), m_length(length) {}
|
||||
};
|
||||
|
||||
enum class SearchErrorCode
|
||||
{
|
||||
Success,
|
||||
|
||||
// No emulation is currently active.
|
||||
NoEmulationActive,
|
||||
|
||||
// The parameter set given to the search function is bogus.
|
||||
InvalidParameters,
|
||||
|
||||
// This is returned if PowerPC::RequestedAddressSpace::Virtual is given but the MSR.DR flag is
|
||||
// currently off in the emulated game.
|
||||
VirtualAddressesCurrentlyNotAccessible,
|
||||
};
|
||||
|
||||
// Returns the corresponding DataType enum for the value currently held by the given SearchValue.
|
||||
DataType GetDataType(const SearchValue& value);
|
||||
|
||||
// Converts the given value to a std::vector<u8>, regardless of the actual stored value type.
|
||||
// Returned array is in big endian byte order, so it can be copied directly into emulated memory for
|
||||
// patches or action replay codes.
|
||||
std::vector<u8> GetValueAsByteVector(const SearchValue& value);
|
||||
|
||||
// Do a new search across the given memory region in the given address space, only keeping values
|
||||
// for which the given validator returns true.
|
||||
template <typename T>
|
||||
Common::Result<SearchErrorCode, std::vector<SearchResult<T>>>
|
||||
NewSearch(const std::vector<MemoryRange>& memory_ranges,
|
||||
PowerPC::RequestedAddressSpace address_space, bool aligned,
|
||||
const std::function<bool(const T& value)>& validator);
|
||||
|
||||
// Refresh the values for the given results in the given address space, only keeping values for
|
||||
// which the given validator returns true.
|
||||
template <typename T>
|
||||
Common::Result<SearchErrorCode, std::vector<SearchResult<T>>>
|
||||
NextSearch(const std::vector<SearchResult<T>>& previous_results,
|
||||
PowerPC::RequestedAddressSpace address_space,
|
||||
const std::function<bool(const T& new_value, const T& old_value)>& validator);
|
||||
|
||||
class CheatSearchSessionBase
|
||||
{
|
||||
public:
|
||||
virtual ~CheatSearchSessionBase();
|
||||
|
||||
// Set the value comparison operation used by subsequent searches.
|
||||
virtual void SetCompareType(CompareType compare_type) = 0;
|
||||
|
||||
// Set the filtering value target used by subsequent searches.
|
||||
virtual void SetFilterType(FilterType filter_type) = 0;
|
||||
|
||||
// Set the value of the CompareAgainstSpecificValue filter used by subsequent searches.
|
||||
virtual bool SetValueFromString(const std::string& value_as_string) = 0;
|
||||
|
||||
// Resets the search results, causing the next search to act as a new search.
|
||||
virtual void ResetResults() = 0;
|
||||
|
||||
// Run either a new search or a next search based on the current state of this session.
|
||||
virtual SearchErrorCode RunSearch() = 0;
|
||||
|
||||
virtual size_t GetMemoryRangeCount() = 0;
|
||||
virtual MemoryRange GetMemoryRange(size_t index) = 0;
|
||||
virtual PowerPC::RequestedAddressSpace GetAddressSpace() = 0;
|
||||
virtual DataType GetDataType() = 0;
|
||||
virtual bool GetAligned() = 0;
|
||||
|
||||
virtual size_t GetResultCount() const = 0;
|
||||
virtual size_t GetValidValueCount() const = 0;
|
||||
virtual u32 GetResultAddress(size_t index) const = 0;
|
||||
virtual SearchValue GetResultValueAsSearchValue(size_t index) const = 0;
|
||||
virtual std::string GetResultValueAsString(size_t index, bool hex) const = 0;
|
||||
virtual SearchResultValueState GetResultValueState(size_t index) const = 0;
|
||||
virtual bool WasFirstSearchDone() const = 0;
|
||||
|
||||
// Create a complete copy of this search session.
|
||||
virtual std::unique_ptr<CheatSearchSessionBase> Clone() const = 0;
|
||||
|
||||
// Create a partial copy of this search session. Only the results with the passed indices are
|
||||
// copied. This is useful if you want to run a next search on only partial result data of a
|
||||
// previous search.
|
||||
virtual std::unique_ptr<CheatSearchSessionBase>
|
||||
ClonePartial(const std::vector<size_t>& result_indices) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CheatSearchSession : public CheatSearchSessionBase
|
||||
{
|
||||
public:
|
||||
CheatSearchSession(std::vector<MemoryRange> memory_ranges,
|
||||
PowerPC::RequestedAddressSpace address_space, bool aligned);
|
||||
CheatSearchSession(const CheatSearchSession& session);
|
||||
CheatSearchSession(CheatSearchSession&& session);
|
||||
CheatSearchSession& operator=(const CheatSearchSession& session);
|
||||
CheatSearchSession& operator=(CheatSearchSession&& session);
|
||||
~CheatSearchSession() override;
|
||||
|
||||
void SetCompareType(CompareType compare_type) override;
|
||||
void SetFilterType(FilterType filter_type) override;
|
||||
bool SetValueFromString(const std::string& value_as_string) override;
|
||||
|
||||
void ResetResults() override;
|
||||
SearchErrorCode RunSearch() override;
|
||||
|
||||
size_t GetMemoryRangeCount() override;
|
||||
MemoryRange GetMemoryRange(size_t index) override;
|
||||
PowerPC::RequestedAddressSpace GetAddressSpace() override;
|
||||
DataType GetDataType() override;
|
||||
bool GetAligned() override;
|
||||
|
||||
size_t GetResultCount() const override;
|
||||
size_t GetValidValueCount() const override;
|
||||
u32 GetResultAddress(size_t index) const override;
|
||||
T GetResultValue(size_t index) const;
|
||||
SearchValue GetResultValueAsSearchValue(size_t index) const override;
|
||||
std::string GetResultValueAsString(size_t index, bool hex) const override;
|
||||
SearchResultValueState GetResultValueState(size_t index) const override;
|
||||
bool WasFirstSearchDone() const override;
|
||||
|
||||
std::unique_ptr<CheatSearchSessionBase> Clone() const override;
|
||||
std::unique_ptr<CheatSearchSessionBase>
|
||||
ClonePartial(const std::vector<size_t>& result_indices) const override;
|
||||
|
||||
private:
|
||||
std::vector<SearchResult<T>> m_search_results;
|
||||
std::vector<MemoryRange> m_memory_ranges;
|
||||
PowerPC::RequestedAddressSpace m_address_space;
|
||||
CompareType m_compare_type = CompareType::Equal;
|
||||
FilterType m_filter_type = FilterType::DoNotFilter;
|
||||
std::optional<T> m_value = std::nullopt;
|
||||
bool m_aligned;
|
||||
bool m_first_search_done = false;
|
||||
};
|
||||
|
||||
std::unique_ptr<CheatSearchSessionBase> MakeSession(std::vector<MemoryRange> memory_ranges,
|
||||
PowerPC::RequestedAddressSpace address_space,
|
||||
bool aligned, DataType data_type);
|
||||
} // namespace Cheats
|
Reference in New Issue
Block a user