1717 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
1818 ***************************************************************************/
1919
20+ #include " gui/widgets/memcard_manager.h"
21+
2022#include < algorithm>
2123#include < cstdlib>
24+
2225#include " core/system.h"
2326#include " fmt/format.h"
24- #include " gui/widgets/memcard_manager.h"
2527
2628#define STB_IMAGE_WRITE_IMPLEMENTATION
2729#include " stb/stb_image_write.h"
@@ -93,7 +95,7 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
9395 ImGui::SliderInt (" Icon size" , &m_iconSize, 16 , 512 );
9496 ImGui::SameLine ();
9597 if (ImGui::Checkbox (" Draw Pockestation icons" , &m_drawPocketstationIcons)) {
96- glDeleteTextures (15 , m_iconTextures); // Recreate our textures to fit our new format
98+ glDeleteTextures (15 , m_iconTextures); // Recreate our textures to fit our new format
9799 initTextures ();
98100 }
99101
@@ -110,9 +112,9 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
110112 }
111113
112114 static constexpr ImGuiTableFlags flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable |
113- ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
114- ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV;
115- PCSX ::SIO ::McdBlock block; // The current memory card block we're looking into
115+ ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
116+ ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV;
117+ PCSX ::SIO ::McdBlock block; // The current memory card block we're looking into
116118
117119 if (ImGui::BeginTable (" Memory card information" , 6 , flags)) {
118120 ImGui::TableSetupColumn (" Block number" );
@@ -147,15 +149,15 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
147149 g_emulator->m_sio ->FormatMcdBlock (m_selectedCard, i);
148150 }
149151 ImGui::SameLine ();
150-
152+
151153 buttonName = fmt::format (_ (" Copy##{}" ), i);
152154 if (ImGui::SmallButton (buttonName.c_str ())) {
153155 action = Actions::Copy;
154156 selectedBlock = i;
155157 m_pendingAction.popupText = fmt::format (" Choose block to copy block {} to" , selectedBlock);
156158 }
157159 ImGui::SameLine ();
158-
160+
159161 buttonName = fmt::format (_ (" Move##{}" ), i);
160162 if (ImGui::SmallButton (buttonName.c_str ())) {
161163 action = Actions::Move;
@@ -187,11 +189,11 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
187189
188190 if (action != Actions::None) {
189191 m_pendingAction.type = action;
190- m_pendingAction.targetCard = m_selectedCard; // Default to current card as the target for the action
192+ m_pendingAction.targetCard = m_selectedCard; // Default to current card as the target for the action
191193 m_pendingAction.sourceBlock = selectedBlock;
192194 ImGui::OpenPopup (m_pendingAction.popupText .c_str ());
193195 }
194-
196+
195197 ImGui::SetNextWindowPos (ImVec2 (600 , 600 ), ImGuiCond_FirstUseEver);
196198 ImGui::SetNextWindowSize (ImVec2 (200 , 200 ), ImGuiCond_FirstUseEver);
197199 if (ImGui::BeginPopupModal (m_pendingAction.popupText .c_str ())) {
@@ -209,7 +211,7 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
209211 performAction ();
210212 ImGui::CloseCurrentPopup ();
211213 } else if (ImGui::Button (" Cancel" )) {
212- m_pendingAction.type = Actions::None; // Cancel action
214+ m_pendingAction.type = Actions::None; // Cancel action
213215 ImGui::CloseCurrentPopup ();
214216 }
215217
@@ -222,7 +224,7 @@ bool PCSX::Widgets::MemcardManager::draw(const char* title) {
222224}
223225
224226void PCSX::Widgets::MemcardManager::drawIcon (int blockNumber, const PCSX ::SIO ::McdBlock& block) {
225- int currentFrame = 0 ; // 1st frame = 0, 2nd frame = 1, 3rd frame = 2 and so on
227+ int currentFrame = 0 ; // 1st frame = 0, 2nd frame = 1, 3rd frame = 2 and so on
226228 const auto texture = m_iconTextures[blockNumber - 1 ];
227229 glBindTexture (GL_TEXTURE_2D , texture);
228230
@@ -243,8 +245,8 @@ void PCSX::Widgets::MemcardManager::drawIcon(int blockNumber, const PCSX::SIO::M
243245 getPocketstationIcon (pixels, blockNumber);
244246 glTexSubImage2D (GL_TEXTURE_2D , 0 , 0 , 0 , 32 , 32 , GL_RGBA , GL_UNSIGNED_BYTE , pixels);
245247 }
246-
247- ImGui::Image (( void *) texture, ImVec2 (m_iconSize, m_iconSize));
248+
249+ ImGui::Image (reinterpret_cast <ImTextureID*>( texture) , ImVec2 (m_iconSize, m_iconSize));
248250}
249251
250252// Perform the pending memory card action (Move, copy, swap)
@@ -258,15 +260,15 @@ void PCSX::Widgets::MemcardManager::performAction() {
258260 auto source = data1 + sourceBlock * PCSX ::SIO ::MCD_BLOCK_SIZE ;
259261 auto dest = data2 + destBlock * PCSX ::SIO ::MCD_BLOCK_SIZE ;
260262
261- if (destBlock > 15 ) { // Invalid block number, do nothing
263+ if (destBlock > 15 ) { // Invalid block number, do nothing
262264 m_pendingAction.type = Actions::None;
263265 return ;
264266 }
265267
266268 switch (m_pendingAction.type ) {
267269 case Actions::Move:
268- std::memcpy (dest, source, PCSX ::SIO ::MCD_BLOCK_SIZE ); // Copy source to dest
269- PCSX ::g_emulator->m_sio ->FormatMcdBlock (m_selectedCard, sourceBlock); // Format source
270+ std::memcpy (dest, source, PCSX ::SIO ::MCD_BLOCK_SIZE ); // Copy source to dest
271+ PCSX ::g_emulator->m_sio ->FormatMcdBlock (m_selectedCard, sourceBlock); // Format source
270272 break ;
271273
272274 case Actions::Copy: {
@@ -295,7 +297,7 @@ void PCSX::Widgets::MemcardManager::performAction() {
295297 } break ;
296298 }
297299
298- m_pendingAction.type = Actions::None; // Cancel action
300+ m_pendingAction.type = Actions::None; // Cancel action
299301}
300302
301303// Extract the pocketstation icon from the block indicated by blockNumber into the pixels array (In RGBA8888)
@@ -326,11 +328,28 @@ void PCSX::Widgets::MemcardManager::getPocketstationIcon(uint32_t* pixels, int b
326328}
327329
328330void PCSX::Widgets::MemcardManager::exportPNG (int blockNumber, const PCSX ::SIO ::McdBlock& block) {
331+ const auto filename = fmt::format (" icon{}.png" , blockNumber);
332+
329333 if (m_drawPocketstationIcons) {
330334 uint32_t pixels[32 * 32 ];
331335 getPocketstationIcon (pixels, blockNumber);
332336
333- const auto filename = fmt::format (" icon{}.png" , blockNumber);
334- stbi_write_png (filename.c_str (), 32 , 32 , 4 , pixels, 128 ); // Stride = 32 pixels, 4 bytes each, so 128
337+ stbi_write_png (filename.c_str (), 32 , 32 , 4 , pixels, 128 ); // Stride = 32 pixels, 4 bytes each, so 128
338+ } else { // PSX memcard icons - currently always dumps the 1st frame of the icon
339+ const auto toColor8 = [](uint8_t color5) {
340+ int color8 = (color5 << 3 ) | (color5 >> 2 );
341+ return color8;
342+ };
343+
344+ uint32_t pixels[16 * 16 ];
345+ for (auto i = 0 ; i < 16 * 16 ; i++) { // Convert pixels from RGB555 to RGBA8888 to give to stbi_write_png
346+ const uint16_t pixel = block.Icon [i]; // Pixel in RGB555
347+ const int red = toColor8 (pixel & 0x1F );
348+ const int green = toColor8 ((pixel >> 5 ) & 0x1F );
349+ const int blue = toColor8 ((pixel >> 10 ) & 0x1F );
350+
351+ pixels[i] = 0xff000000 | (blue << 16 ) | (green << 8 ) | red;
352+ }
353+ stbi_write_png (filename.c_str (), 16 , 16 , 4 , pixels, 64 );
335354 }
336355}
0 commit comments