mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
Controller: Always preserve internal state when loading/resuming
Fixes analog mode getting disabled when loading state.
This commit is contained in:
parent
b78a6045fc
commit
47f0720b93
|
@ -45,9 +45,9 @@ void AnalogController::Reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnalogController::DoState(StateWrapper& sw)
|
bool AnalogController::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
if (!Controller::DoState(sw))
|
if (!Controller::DoState(sw, apply_input_state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const bool old_analog_mode = m_analog_mode;
|
const bool old_analog_mode = m_analog_mode;
|
||||||
|
@ -57,7 +57,12 @@ bool AnalogController::DoState(StateWrapper& sw)
|
||||||
sw.DoEx(&m_legacy_rumble_unlocked, 44, false);
|
sw.DoEx(&m_legacy_rumble_unlocked, 44, false);
|
||||||
sw.Do(&m_configuration_mode);
|
sw.Do(&m_configuration_mode);
|
||||||
sw.Do(&m_command_param);
|
sw.Do(&m_command_param);
|
||||||
sw.DoEx(&m_button_state, 44, static_cast<u16>(0xFFFF));
|
|
||||||
|
u16 button_state = m_button_state;
|
||||||
|
sw.DoEx(&button_state, 44, static_cast<u16>(0xFFFF));
|
||||||
|
if (apply_input_state)
|
||||||
|
m_button_state = button_state;
|
||||||
|
|
||||||
sw.Do(&m_state);
|
sw.Do(&m_state);
|
||||||
|
|
||||||
sw.DoEx(&m_rumble_config, 45, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF});
|
sw.DoEx(&m_rumble_config, 45, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF});
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
bool DoState(StateWrapper& sw) override;
|
bool DoState(StateWrapper& sw, bool ignore_input_state) override;
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -26,16 +26,26 @@ void AnalogJoystick::Reset()
|
||||||
m_transfer_state = TransferState::Idle;
|
m_transfer_state = TransferState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnalogJoystick::DoState(StateWrapper& sw)
|
bool AnalogJoystick::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
if (!Controller::DoState(sw))
|
if (!Controller::DoState(sw, apply_input_state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const bool old_analog_mode = m_analog_mode;
|
const bool old_analog_mode = m_analog_mode;
|
||||||
|
|
||||||
sw.Do(&m_analog_mode);
|
sw.Do(&m_analog_mode);
|
||||||
sw.Do(&m_button_state);
|
|
||||||
sw.Do(&m_axis_state);
|
u16 button_state = m_button_state;
|
||||||
|
auto axis_state = m_axis_state;
|
||||||
|
sw.Do(&button_state);
|
||||||
|
sw.Do(&axis_state);
|
||||||
|
|
||||||
|
if (apply_input_state)
|
||||||
|
{
|
||||||
|
m_button_state = button_state;
|
||||||
|
m_axis_state = axis_state;
|
||||||
|
}
|
||||||
|
|
||||||
sw.Do(&m_transfer_state);
|
sw.Do(&m_transfer_state);
|
||||||
|
|
||||||
if (sw.IsReading() && (old_analog_mode != m_analog_mode))
|
if (sw.IsReading() && (old_analog_mode != m_analog_mode))
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
bool DoState(StateWrapper& sw) override;
|
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -13,7 +13,7 @@ Controller::~Controller() = default;
|
||||||
|
|
||||||
void Controller::Reset() {}
|
void Controller::Reset() {}
|
||||||
|
|
||||||
bool Controller::DoState(StateWrapper& sw)
|
bool Controller::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
return !sw.HasError();
|
return !sw.HasError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
virtual std::optional<s32> GetButtonCodeByName(std::string_view button_name) const;
|
virtual std::optional<s32> GetButtonCodeByName(std::string_view button_name) const;
|
||||||
|
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
virtual bool DoState(StateWrapper& sw);
|
virtual bool DoState(StateWrapper& sw, bool apply_input_state);
|
||||||
|
|
||||||
// Resets all state for the transferring to/from the device.
|
// Resets all state for the transferring to/from the device.
|
||||||
virtual void ResetTransferState();
|
virtual void ResetTransferState();
|
||||||
|
|
|
@ -27,12 +27,16 @@ void DigitalController::Reset()
|
||||||
m_transfer_state = TransferState::Idle;
|
m_transfer_state = TransferState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DigitalController::DoState(StateWrapper& sw)
|
bool DigitalController::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
if (!Controller::DoState(sw))
|
if (!Controller::DoState(sw, apply_input_state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sw.Do(&m_button_state);
|
u16 button_state = m_button_state;
|
||||||
|
sw.Do(&button_state);
|
||||||
|
if (apply_input_state)
|
||||||
|
m_button_state = apply_input_state;
|
||||||
|
|
||||||
sw.Do(&m_transfer_state);
|
sw.Do(&m_transfer_state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
bool DoState(StateWrapper& sw) override;
|
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -34,14 +34,24 @@ void NamcoGunCon::Reset()
|
||||||
m_transfer_state = TransferState::Idle;
|
m_transfer_state = TransferState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NamcoGunCon::DoState(StateWrapper& sw)
|
bool NamcoGunCon::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
if (!Controller::DoState(sw))
|
if (!Controller::DoState(sw, apply_input_state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sw.Do(&m_button_state);
|
u16 button_state = m_button_state;
|
||||||
sw.Do(&m_position_x);
|
u16 position_x = m_position_x;
|
||||||
sw.Do(&m_position_y);
|
u16 position_y = m_position_y;
|
||||||
|
sw.Do(&button_state);
|
||||||
|
sw.Do(&position_x);
|
||||||
|
sw.Do(&position_y);
|
||||||
|
if (apply_input_state)
|
||||||
|
{
|
||||||
|
m_button_state = button_state;
|
||||||
|
m_position_x = position_x;
|
||||||
|
m_position_y = position_y;
|
||||||
|
}
|
||||||
|
|
||||||
sw.Do(&m_transfer_state);
|
sw.Do(&m_transfer_state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
bool DoState(StateWrapper& sw) override;
|
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||||
void LoadSettings(const char* section) override;
|
void LoadSettings(const char* section) override;
|
||||||
bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale) override;
|
bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale) override;
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,16 @@ void NeGcon::Reset()
|
||||||
m_transfer_state = TransferState::Idle;
|
m_transfer_state = TransferState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NeGcon::DoState(StateWrapper& sw)
|
bool NeGcon::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
if (!Controller::DoState(sw))
|
if (!Controller::DoState(sw, apply_input_state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sw.Do(&m_button_state);
|
u16 button_state = m_button_state;
|
||||||
|
sw.Do(&button_state);
|
||||||
|
if (apply_input_state)
|
||||||
|
m_button_state = button_state;
|
||||||
|
|
||||||
sw.Do(&m_transfer_state);
|
sw.Do(&m_transfer_state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
bool DoState(StateWrapper& sw) override;
|
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -71,7 +71,7 @@ bool Pad::DoState(StateWrapper& sw)
|
||||||
if (state_controller_type != ControllerType::None)
|
if (state_controller_type != ControllerType::None)
|
||||||
{
|
{
|
||||||
m_controllers[i] = Controller::Create(state_controller_type, i);
|
m_controllers[i] = Controller::Create(state_controller_type, i);
|
||||||
if (!sw.DoMarker("Controller") || !m_controllers[i]->DoState(sw))
|
if (!sw.DoMarker("Controller") || !m_controllers[i]->DoState(sw, false))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ bool Pad::DoState(StateWrapper& sw)
|
||||||
std::unique_ptr<Controller> dummy_controller = Controller::Create(state_controller_type, i);
|
std::unique_ptr<Controller> dummy_controller = Controller::Create(state_controller_type, i);
|
||||||
if (dummy_controller)
|
if (dummy_controller)
|
||||||
{
|
{
|
||||||
if (!sw.DoMarker("Controller") || !dummy_controller->DoState(sw))
|
if (!sw.DoMarker("Controller") || !dummy_controller->DoState(sw, true))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,23 +98,40 @@ bool Pad::DoState(StateWrapper& sw)
|
||||||
{
|
{
|
||||||
if (m_controllers[i])
|
if (m_controllers[i])
|
||||||
{
|
{
|
||||||
if (!sw.DoMarker("Controller") || !m_controllers[i]->DoState(sw))
|
if (!sw.DoMarker("Controller") || !m_controllers[i]->DoState(sw, true))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// we still need to read the save state controller state
|
|
||||||
if (state_controller_type != ControllerType::None)
|
if (state_controller_type != ControllerType::None)
|
||||||
{
|
{
|
||||||
|
if (controller_type != state_controller_type)
|
||||||
|
{
|
||||||
|
g_host_interface->AddFormattedOSDMessage(
|
||||||
|
10.0f,
|
||||||
|
g_host_interface->TranslateString("OSDMessage", "Ignoring mismatched controller type %s in port %u."),
|
||||||
|
Settings::GetControllerTypeName(state_controller_type), i + 1u);
|
||||||
|
|
||||||
|
// we still need to read the save state controller state
|
||||||
std::unique_ptr<Controller> dummy_controller = Controller::Create(state_controller_type, i);
|
std::unique_ptr<Controller> dummy_controller = Controller::Create(state_controller_type, i);
|
||||||
if (dummy_controller)
|
if (dummy_controller)
|
||||||
{
|
{
|
||||||
if (!sw.DoMarker("Controller") || !dummy_controller->DoState(sw))
|
if (!sw.DoMarker("Controller") || !dummy_controller->DoState(sw, true))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we still need to load some things from the state, e.g. configuration mode, analog mode
|
||||||
|
if (m_controllers[i])
|
||||||
|
{
|
||||||
|
if (!sw.DoMarker("Controller") || !m_controllers[i]->DoState(sw, false))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool card_present = static_cast<bool>(m_memory_cards[i]);
|
bool card_present = static_cast<bool>(m_memory_cards[i]);
|
||||||
|
|
|
@ -37,14 +37,24 @@ void PlayStationMouse::Reset()
|
||||||
m_transfer_state = TransferState::Idle;
|
m_transfer_state = TransferState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayStationMouse::DoState(StateWrapper& sw)
|
bool PlayStationMouse::DoState(StateWrapper& sw, bool apply_input_state)
|
||||||
{
|
{
|
||||||
if (!Controller::DoState(sw))
|
if (!Controller::DoState(sw, apply_input_state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sw.Do(&m_button_state);
|
u16 button_state = m_button_state;
|
||||||
sw.Do(&m_delta_x);
|
u8 delta_x = m_delta_x;
|
||||||
sw.Do(&m_delta_y);
|
u8 delta_y = m_delta_y;
|
||||||
|
sw.Do(&button_state);
|
||||||
|
sw.Do(&delta_x);
|
||||||
|
sw.Do(&delta_y);
|
||||||
|
if (apply_input_state)
|
||||||
|
{
|
||||||
|
m_button_state = button_state;
|
||||||
|
m_delta_x = delta_x;
|
||||||
|
m_delta_y = delta_y;
|
||||||
|
}
|
||||||
|
|
||||||
sw.Do(&m_transfer_state);
|
sw.Do(&m_transfer_state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
bool DoState(StateWrapper& sw) override;
|
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue