@@ -71,6 +71,18 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
7171 if (ImGui::Button (_ (" Save memory card to file" ))) {
7272 g_emulator->m_sio ->SaveMcd (m_selectedCard);
7373 }
74+ ImGui::SameLine ();
75+ {
76+ const int otherCard = (m_selectedCard == 1 ) ? 2 : 1 ;
77+ const auto copyButtonText = fmt::format (_ (" Copy all to card {}" ), otherCard);
78+ if (ImGui::Button (copyButtonText.c_str ())) {
79+ const auto source = PCSX ::g_emulator->m_sio ->GetMcdData (m_selectedCard);
80+ auto dest = PCSX ::g_emulator->m_sio ->GetMcdData (otherCard);
81+
82+ std::memcpy (dest, source, PCSX ::SIO ::MCD_SIZE );
83+ }
84+ }
85+
7486 ImGui::SliderInt (" Icon size" , &m_iconSize, 16 , 512 );
7587
7688 static const char * cardNames[] = {_ (" Memory card 1" ), _ (" Memory card 2" )};
@@ -89,10 +101,12 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
89101 ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV;
90102 PCSX ::SIO ::McdBlock block; // The current memory card block we're looking into
91103
92- if (ImGui::BeginTable (" Memory card information" , 4 , flags)) {
104+ if (ImGui::BeginTable (" Memory card information" , 6 , flags)) {
93105 ImGui::TableSetupColumn (" Block number" );
94106 ImGui::TableSetupColumn (" Icon" );
95107 ImGui::TableSetupColumn (" Title" );
108+ ImGui::TableSetupColumn (" ID" );
109+ ImGui::TableSetupColumn (" Filename" );
96110 ImGui::TableSetupColumn (" Action" );
97111 ImGui::TableHeadersRow ();
98112
@@ -121,6 +135,10 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
121135 ImGui::TableSetColumnIndex (2 );
122136 ImGui::Text (block.Title );
123137 ImGui::TableSetColumnIndex (3 );
138+ ImGui::Text (block.ID );
139+ ImGui::TableSetColumnIndex (4 );
140+ ImGui::Text (" %s (%dKB)" , block.Name , block.Filesize / 1024 );
141+ ImGui::TableSetColumnIndex (5 );
124142
125143 // We have to suffix the action button names with ##number because Imgui
126144 // can't handle multiple buttons with the same name well
@@ -169,6 +187,15 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
169187 }
170188
171189 if (ImGui::BeginPopupModal (m_pendingAction.popupText .c_str ())) {
190+ if (ImGui::BeginCombo (_ (" Destination card" ), cardNames[m_pendingAction.targetCard - 1 ])) {
191+ for (unsigned i = 0 ; i < 2 ; i++) {
192+ if (ImGui::Selectable (cardNames[i], m_pendingAction.targetCard == i + 1 )) {
193+ m_pendingAction.targetCard = i + 1 ;
194+ }
195+ }
196+ ImGui::EndCombo ();
197+ }
198+
172199 if (ImGui::InputText (_ (" Block" ), m_pendingAction.textInput , sizeof (m_pendingAction.textInput ),
173200 ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_EnterReturnsTrue)) {
174201 performAction ();
@@ -210,22 +237,35 @@ void PCSX::Widgets::MemcardManager::performAction() {
210237 }
211238
212239 switch (m_pendingAction.type ) {
213- case Actions::Move: {
214- for (auto i = 0 ; i < PCSX ::SIO ::MCD_BLOCK_SIZE ; i++) {
215- dest[i] = source[i];
216- source[i] = 0 ;
217- }
218- } break ;
240+ case Actions::Move:
241+ std::memcpy (dest, source, PCSX ::SIO ::MCD_BLOCK_SIZE ); // Copy source to dest
242+ PCSX ::g_emulator->m_sio ->FormatMcdBlock (m_selectedCard, sourceBlock); // Format source
243+ break ;
244+
245+ case Actions::Copy: {
246+ const uint8_t * sourceFrame = data1 + sourceBlock * PCSX ::SIO ::MCD_SECT_SIZE ;
247+ uint8_t * destFrame = data2 + destBlock * PCSX ::SIO ::MCD_SECT_SIZE ;
219248
220- case Actions::Copy:
249+ // Copy directory frame for source block to directory frame for dest block
250+ std::memcpy (destFrame, sourceFrame, PCSX ::SIO ::MCD_SECT_SIZE );
251+ // Copy source block to dest block
221252 std::memcpy (dest, source, PCSX ::SIO ::MCD_BLOCK_SIZE );
222- break ;
253+ } break ;
223254
224255 case Actions::Swap: {
256+ uint8_t * sourceFrame = data1 + sourceBlock * PCSX ::SIO ::MCD_SECT_SIZE ;
257+ uint8_t * destFrame = data2 + destBlock * PCSX ::SIO ::MCD_SECT_SIZE ;
258+
259+ // Swap the memory card blocks
225260 for (auto i = 0 ; i < PCSX ::SIO ::MCD_BLOCK_SIZE ; i++) {
226261 std::swap (dest[i], source[i]);
227262 }
228- }
263+
264+ // Swap the directory frames for the blocks
265+ for (auto i = 0 ; i < PCSX ::SIO ::MCD_SECT_SIZE ; i++) {
266+ std::swap (sourceFrame[i], destFrame[i]);
267+ }
268+ } break ;
229269 }
230270
231271 m_pendingAction.type = Actions::None; // Cancel action
0 commit comments