Skip to content

Commit ac181e8

Browse files
committed
[SIO & Memcard Manager] Pay more attention to memcard directory frame, finishing touches
1 parent b1459ad commit ac181e8

3 files changed

Lines changed: 70 additions & 19 deletions

File tree

src/core/sio.cc

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ void PCSX::SIO::GetMcdBlockInfo(int mcd, int block, McdBlock *Info) {
796796
for (int i = 0; i < Info->IconCount; i++) {
797797
uint16_t *icon = &Info->Icon[i * 16 * 16];
798798
ptr = data + block * MCD_BLOCK_SIZE + 128 + 128 * i; // icon data
799-
799+
800800
// Fetch each pixel, store it in the icon array in ABBBBBGGGGGRRRRR with the alpha bit set to 1
801801
for (x = 0; x < 16 * 16; x++) {
802802
const uint8_t entry = (uint8_t)*ptr;
@@ -806,14 +806,24 @@ void PCSX::SIO::GetMcdBlockInfo(int mcd, int block, McdBlock *Info) {
806806
}
807807
}
808808

809-
ptr = data + block * 128;
810-
811-
Info->Flags = *ptr;
812-
813-
ptr += 0xa;
814-
strncpy(Info->ID, ptr, 12);
815-
ptr += 12;
816-
strncpy(Info->Name, ptr, 16);
809+
810+
// Parse directory frame info
811+
const auto directoryFrame = (uint8_t *)data + block * MCD_SECT_SIZE;
812+
Info->Flags = directoryFrame[0];
813+
std::strncpy(Info->ID, (const char*) &directoryFrame[0xa], 12);
814+
std::strncpy(Info->Name, (const char*) &directoryFrame[0x16], 16);
815+
g_system->printf("ID: %s\nName: %s\n", Info->ID, Info->Name);
816+
817+
const uint32_t fileSize =
818+
directoryFrame[0x4] | (directoryFrame[0x5] << 8) | (directoryFrame[0x6] << 16) | (directoryFrame[0x7] << 24);
819+
Info->Filesize = fileSize;
820+
821+
// Check if the block is marked as free in the directory frame and adjust the name/filename if so
822+
if (Info->Flags == 0xa0) {
823+
std::strcpy(Info->Title, "Free Block");
824+
std::strcpy(Info->Name, "Empty File");
825+
Info->Filesize = 0;
826+
}
817827
}
818828

819829
char *PCSX::SIO::GetMcdData(int mcd) {

src/core/sio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class SIO {
138138
char sTitle[48 * 2 + 1]; // Title in Shift-JIS
139139
char ID[12 + 1];
140140
char Name[16 + 1];
141+
uint32_t Filesize;
141142
uint32_t IconCount;
142143
uint16_t Icon[16 * 16 * 3];
143144
uint8_t Flags;

src/gui/widgets/memcard_manager.cc

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)