Cheats: Implement D4/D5/D6 code types

This commit is contained in:
Connor McLaughlin 2020-12-06 15:47:00 +10:00
parent fd6462263f
commit ea9829946d
10 changed files with 103 additions and 3 deletions

View file

@ -127,6 +127,12 @@ void AnalogController::SetButtonState(s32 button_code, bool pressed)
SetButtonState(static_cast<Button>(button_code), pressed); SetButtonState(static_cast<Button>(button_code), pressed);
} }
u32 AnalogController::GetButtonStateBits() const
{
// flip bits, native data is active low
return m_button_state ^ 0xFFFF;
}
u32 AnalogController::GetVibrationMotorCount() const u32 AnalogController::GetVibrationMotorCount() const
{ {
return NUM_MOTORS; return NUM_MOTORS;

View file

@ -61,6 +61,7 @@ public:
void SetAxisState(s32 axis_code, float value) override; void SetAxisState(s32 axis_code, float value) override;
void SetButtonState(s32 button_code, bool pressed) override; void SetButtonState(s32 button_code, bool pressed) override;
u32 GetButtonStateBits() const override;
void ResetTransferState() override; void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override; bool Transfer(const u8 data_in, u8* data_out) override;

View file

@ -100,6 +100,11 @@ void AnalogJoystick::SetButtonState(s32 button_code, bool pressed)
SetButtonState(static_cast<Button>(button_code), pressed); SetButtonState(static_cast<Button>(button_code), pressed);
} }
u32 AnalogJoystick::GetButtonStateBits() const
{
return m_button_state ^ 0xFFFF;
}
void AnalogJoystick::ResetTransferState() void AnalogJoystick::ResetTransferState()
{ {
m_transfer_state = TransferState::Idle; m_transfer_state = TransferState::Idle;

View file

@ -59,6 +59,7 @@ public:
void SetAxisState(s32 axis_code, float value) override; void SetAxisState(s32 axis_code, float value) override;
void SetButtonState(s32 button_code, bool pressed) override; void SetButtonState(s32 button_code, bool pressed) override;
u32 GetButtonStateBits() const override;
void ResetTransferState() override; void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override; bool Transfer(const u8 data_in, u8* data_out) override;

View file

@ -6,9 +6,11 @@
#include "common/log.h" #include "common/log.h"
#include "common/string.h" #include "common/string.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "controller.h"
#include "cpu_code_cache.h" #include "cpu_code_cache.h"
#include "cpu_core.h" #include "cpu_core.h"
#include "host_interface.h" #include "host_interface.h"
#include "system.h"
#include <cctype> #include <cctype>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
@ -95,6 +97,47 @@ static void DoMemoryWrite(PhysicalMemoryAddress address, T value)
} }
} }
static u32 GetControllerButtonBits()
{
static constexpr std::array<u16, 16> button_mapping = {{
0x0100, // Select
0x0200, // L3
0x0400, // R3
0x0800, // Start
0x1000, // Up
0x2000, // Right
0x4000, // Down
0x8000, // Left
0x0001, // L2
0x0002, // R2
0x0004, // L1
0x0008, // R1
0x0010, // Triangle
0x0020, // Circle
0x0040, // Cross
0x0080, // Square
}};
u32 bits = 0;
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
{
Controller* controller = System::GetController(i);
if (!controller)
continue;
bits |= controller->GetButtonStateBits();
}
u32 translated_bits = 0;
for (u32 i = 0, bit = 1; i < static_cast<u32>(button_mapping.size()); i++, bit <<= 1)
{
if (bits & bit)
translated_bits |= button_mapping[i];
}
return translated_bits;
}
CheatList::CheatList() = default; CheatList::CheatList() = default;
CheatList::~CheatList() = default; CheatList::~CheatList() = default;
@ -921,12 +964,39 @@ void CheatCode::Apply() const
} }
break; break;
case InstructionCode::SkipIfNotEqual16: // C0 case InstructionCode::CompareButtons: // D4
{
if (inst.value16 == GetControllerButtonBits())
index++;
else
index += 2;
}
break;
case InstructionCode::SkipIfNotEqual16: // C0
case InstructionCode::SkipIfButtonsNotEqual: // D5
case InstructionCode::SkipIfButtonsEqual: // D6
{ {
const u16 value = DoMemoryRead<u16>(inst.address);
index++; index++;
if (value == inst.value16) bool activate_codes;
switch (inst.code)
{
case InstructionCode::SkipIfNotEqual16: // C0
activate_codes = (DoMemoryRead<u16>(inst.address) == inst.value16);
break;
case InstructionCode::SkipIfButtonsNotEqual: // D5
activate_codes = (GetControllerButtonBits() == inst.value16);
break;
case InstructionCode::SkipIfButtonsEqual: // D6
activate_codes = (GetControllerButtonBits() != inst.value16);
break;
default:
activate_codes = false;
break;
}
if (activate_codes)
{ {
// execute following instructions // execute following instructions
continue; continue;

View file

@ -31,6 +31,9 @@ struct CheatCode
Increment8 = 0x20, Increment8 = 0x20,
Decrement8 = 0x21, Decrement8 = 0x21,
SkipIfNotEqual16 = 0xC0, SkipIfNotEqual16 = 0xC0,
SkipIfButtonsNotEqual = 0xD5,
SkipIfButtonsEqual = 0xD6,
CompareButtons = 0xD4,
CompareEqual16 = 0xD0, CompareEqual16 = 0xD0,
CompareNotEqual16 = 0xD1, CompareNotEqual16 = 0xD1,
CompareLess16 = 0xD2, CompareLess16 = 0xD2,

View file

@ -30,6 +30,11 @@ void Controller::SetAxisState(s32 axis_code, float value) {}
void Controller::SetButtonState(s32 button_code, bool pressed) {} void Controller::SetButtonState(s32 button_code, bool pressed) {}
u32 Controller::GetButtonStateBits() const
{
return 0;
}
u32 Controller::GetVibrationMotorCount() const u32 Controller::GetVibrationMotorCount() const
{ {
return 0; return 0;

View file

@ -51,6 +51,9 @@ public:
/// Changes the specified button state. /// Changes the specified button state.
virtual void SetButtonState(s32 button_code, bool pressed); virtual void SetButtonState(s32 button_code, bool pressed);
/// Returns a bitmask of the current button states, 1 = on.
virtual u32 GetButtonStateBits() const;
/// Returns the number of vibration motors. /// Returns the number of vibration motors.
virtual u32 GetVibrationMotorCount() const; virtual u32 GetVibrationMotorCount() const;

View file

@ -55,6 +55,11 @@ void DigitalController::SetButtonState(s32 button_code, bool pressed)
SetButtonState(static_cast<Button>(button_code), pressed); SetButtonState(static_cast<Button>(button_code), pressed);
} }
u32 DigitalController::GetButtonStateBits() const
{
return m_button_state ^ 0xFFFF;
}
void DigitalController::ResetTransferState() void DigitalController::ResetTransferState()
{ {
m_transfer_state = TransferState::Idle; m_transfer_state = TransferState::Idle;

View file

@ -47,6 +47,7 @@ public:
void SetAxisState(s32 axis_code, float value) override; void SetAxisState(s32 axis_code, float value) override;
void SetButtonState(s32 button_code, bool pressed) override; void SetButtonState(s32 button_code, bool pressed) override;
u32 GetButtonStateBits() const override;
void ResetTransferState() override; void ResetTransferState() override;
bool Transfer(const u8 data_in, u8* data_out) override; bool Transfer(const u8 data_in, u8* data_out) override;