2020-09-09 12:11:28 +00:00
|
|
|
#pragma once
|
|
|
|
#include "common/bitfield.h"
|
|
|
|
#include "types.h"
|
|
|
|
#include <optional>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
struct CheatCode
|
|
|
|
{
|
|
|
|
enum class InstructionCode : u8
|
|
|
|
{
|
2020-09-28 10:09:14 +00:00
|
|
|
Nop = 0x00,
|
2020-09-09 12:11:28 +00:00
|
|
|
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,
|
2020-09-28 10:24:58 +00:00
|
|
|
Slide = 0x50,
|
|
|
|
MemoryCopy = 0xC2
|
2020-09-09 12:11:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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()); }
|
2020-09-09 13:44:02 +00:00
|
|
|
ALWAYS_INLINE bool IsCodeEnabled(u32 index) const { return m_codes[index].enabled; }
|
2020-09-09 12:11:28 +00:00
|
|
|
|
|
|
|
void AddCode(CheatCode cc);
|
2020-09-25 11:16:33 +00:00
|
|
|
void SetCode(u32 index, CheatCode cc);
|
2020-09-09 12:11:28 +00:00
|
|
|
void RemoveCode(u32 i);
|
|
|
|
|
2020-09-09 13:44:02 +00:00
|
|
|
u32 GetEnabledCodeCount() const;
|
|
|
|
void EnableCode(u32 index);
|
|
|
|
void DisableCode(u32 index);
|
|
|
|
void SetCodeEnabled(u32 index, bool state);
|
|
|
|
|
2020-09-09 12:11:28 +00:00
|
|
|
static std::optional<Format> DetectFileFormat(const char* filename);
|
2020-09-25 11:16:33 +00:00
|
|
|
static bool ParseLibretroCheat(CheatCode* cc, const char* line);
|
2020-09-09 12:11:28 +00:00
|
|
|
|
|
|
|
bool LoadFromFile(const char* filename, Format format);
|
|
|
|
bool LoadFromPCSXRFile(const char* filename);
|
|
|
|
bool LoadFromLibretroFile(const char* filename);
|
|
|
|
|
|
|
|
bool SaveToPCSXRFile(const char* filename);
|
|
|
|
|
|
|
|
void Apply();
|
|
|
|
|
2020-09-09 13:44:02 +00:00
|
|
|
void ApplyCode(u32 index);
|
|
|
|
|
2020-09-09 12:11:28 +00:00
|
|
|
private:
|
|
|
|
std::vector<CheatCode> m_codes;
|
|
|
|
};
|