MCPcopy Create free account
hub / github.com/PCSX2/pcsx2 / Freeze

Method Freeze

pcsx2/SIO/Pad/Pad.cpp:554–636  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

552}
553
554bool Pad::Freeze(StateWrapper& sw)
555{
556 if (sw.IsReading())
557 {
558 if (!sw.DoMarker("PAD"))
559 {
560 Console.Error("PAD state is invalid! Leaving the current state in place.");
561 return false;
562 }
563
564 for (u32 unifiedSlot = 0; unifiedSlot < NUM_CONTROLLER_PORTS; unifiedSlot++)
565 {
566 PadBase* currentPad = GetPad(unifiedSlot);
567 ControllerType statePadType;
568
569 sw.Do(&statePadType);
570
571 if (sw.HasError())
572 return false;
573
574 if (!currentPad)
575 {
576 pxAssertMsg(false, fmt::format("Pad::Freeze (on read) Existing Pad {0} was nullptr", unifiedSlot).c_str());
577 }
578 // If the currently configured pad is of a different type than the pad which was used during the savestate...
579 else if (currentPad->GetType() != statePadType)
580 {
581 const ControllerType currentPadType = currentPad->GetType();
582
583 const auto& [port, slot] = sioConvertPadToPortAndSlot(unifiedSlot);
584 Host::AddIconOSDMessage(fmt::format("UnfreezePad{}Changed", unifiedSlot), ICON_FA_GAMEPAD,
585 //: {0} and {1} are the port and multitap slot, {2} and {3} are controller types (e.g. "DualShock 2", "Jogcon")
586 fmt::format(TRANSLATE_FS("Pad",
587 "Controller port {0}, slot {1} has a {2} connected, but the save state has a "
588 "{3}.\nEjecting {2} and replacing it with {3}."),
589 port, slot,
590 GetControllerTypeName(currentPad ? currentPad->GetType() : Pad::ControllerType::NotConnected),
591 GetControllerTypeName(statePadType)));
592
593 // Run the freeze, using a new pad instance of the old type just so we make sure all those attributes
594 // from the state are read out and we aren't going to run into some sort of consistency problem.
595 currentPad = CreatePad(unifiedSlot, statePadType);
596
597 if (currentPad)
598 {
599 currentPad->Freeze(sw);
600
601 // Now immediately discard whatever malformed pad state we just created, and replace it with a fresh pad loaded
602 // using whatever the current user settings are. Savestates are, by definition, never going to occur in the middle
603 // of a transfer between SIO2 and the peripheral, since they aren't captured until the VM is at a point where everything
604 // is "stoppable". For all intents and purposes, by the time a savestate is captured, the IOP is "done" and there is no
605 // "pending work" left hanging in SIO2 or the pads. So there is nothing actually lost from just throwing the pad away and making a new one here.
606 currentPad = CreatePad(unifiedSlot, currentPadType, Pad::DEFAULT_EJECT_TICKS);
607 }
608 else
609 {
610 pxAssertMsg(false, fmt::format("Pad::Freeze (on read) State Pad {0} was nullptr", unifiedSlot).c_str());
611 }

Callers

nothing calls this directly

Calls 9

IsReadingMethod · 0.80
DoMarkerMethod · 0.80
formatFunction · 0.50
ErrorMethod · 0.45
DoMethod · 0.45
HasErrorMethod · 0.45
c_strMethod · 0.45
GetTypeMethod · 0.45

Tested by

no test coverage detected