Duckstation/src/core/cheats.h
2020-09-09 23:44:02 +10:00

96 lines
2 KiB
C++

#pragma once
#include "common/bitfield.h"
#include "types.h"
#include <optional>
#include <string>
#include <vector>
struct CheatCode
{
enum class InstructionCode : u8
{
ConstantWrite8 = 0x30,
ConstantWrite16 = 0x80,
Increment16 = 0x10,
Decrement16 = 0x11,
Increment8 = 0x20,
Decrement8 = 0x21,
CompareEqual16 = 0xD0,
CompareNotEqual16 = 0xD1,
CompareLess16 = 0xD2,
CompareGreater16 = 0xD3,
CompareEqual8 = 0xE0,
CompareNotEqual8 = 0xE1,
CompareLess8 = 0xE2,
CompareGreater8 = 0xE3,
Slide = 0x50
};
union Instruction
{
u64 bits;
struct
{
u32 second;
u32 first;
};
BitField<u64, InstructionCode, 32 + 24, 8> code;
BitField<u64, u32, 32, 24> address;
BitField<u64, u16, 0, 16> value16;
BitField<u64, u8, 0, 8> value8;
};
std::string description;
std::vector<Instruction> instructions;
bool enabled;
ALWAYS_INLINE bool Valid() const { return !instructions.empty() && !description.empty(); }
void Apply() const;
};
class CheatList final
{
public:
enum class Format
{
Autodetect,
PCSXR,
Libretro,
Count
};
CheatList();
~CheatList();
ALWAYS_INLINE const CheatCode& GetCode(u32 i) const { return m_codes[i]; }
ALWAYS_INLINE CheatCode& GetCode(u32 i) { return m_codes[i]; }
ALWAYS_INLINE u32 GetCodeCount() const { return static_cast<u32>(m_codes.size()); }
ALWAYS_INLINE bool IsCodeEnabled(u32 index) const { return m_codes[index].enabled; }
void AddCode(CheatCode cc);
void RemoveCode(u32 i);
u32 GetEnabledCodeCount() const;
void EnableCode(u32 index);
void DisableCode(u32 index);
void SetCodeEnabled(u32 index, bool state);
static std::optional<Format> DetectFileFormat(const char* filename);
bool LoadFromFile(const char* filename, Format format);
bool LoadFromPCSXRFile(const char* filename);
bool LoadFromLibretroFile(const char* filename);
bool SaveToPCSXRFile(const char* filename);
void Apply();
void ApplyCode(u32 index);
private:
std::vector<CheatCode> m_codes;
};