From d032c40a58b84b01a98dd34a86bbff2e02dc27f2 Mon Sep 17 00:00:00 2001 From: sulokuTDCmago Date: Thu, 18 Oct 2012 00:01:45 -0700 Subject: [PATCH] - Added a new wilcard for importing savegames, which basically shows all saves (gci, gcs and sav). This is set as default (I really got frustrated of having to change the type every single time when making tests for GCMM, and I think it makes more sense at user level to just show all saves regardless the format) - In icon retrieving I removed the "format check" as it shouldn't really matter to have mixed icon formats. Also removed the "Time splitters hack" as there's no reason for it since we are only checking the last 3 bits and I'm pretty sure having bits 1 and 2 set is the same as having them unset. - Icon retrieving uses AnimSpeed as stop signal (every icon must have an speed set, the first speed that is 0 means there are no more icons) - Also, in icon retrieving I added support for "blank frames"(Luigi's Mansion and Pikmin that I know of). With this the base for icon animation is complete. - Fixed PSOIII savegame patch which was wrong before. Signed-off-by: LPFaint99 --- Source/Core/Common/Src/ColorUtil.cpp | 2 +- Source/Core/Core/Src/HW/GCMemcard.cpp | 80 +++++++++++++++----- Source/Core/Core/Src/HW/GCMemcard.h | 6 +- Source/Core/DolphinWX/Src/MemcardManager.cpp | 1 + 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/Source/Core/Common/Src/ColorUtil.cpp b/Source/Core/Common/Src/ColorUtil.cpp index 52ffec0803..5e5143549a 100644 --- a/Source/Core/Common/Src/ColorUtil.cpp +++ b/Source/Core/Common/Src/ColorUtil.cpp @@ -31,7 +31,7 @@ const int lut3to8[] = { 0x00,0x24,0x48,0x6D,0x91,0xB6,0xDA,0xFF }; u32 Decode5A3(u16 val) { - const u32 bg_color = 0x00000000; + const u32 bg_color = 0xFFFFFFFF; int r, g, b, a; diff --git a/Source/Core/Core/Src/HW/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp index 381f942925..9b72a0313c 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.cpp +++ b/Source/Core/Core/Src/HW/GCMemcard.cpp @@ -473,11 +473,20 @@ std::string GCMemcard::DEntry_IconFmt(u8 index) const return format; } -u16 GCMemcard::DEntry_AnimSpeed(u8 index) const +std::string GCMemcard::DEntry_AnimSpeed(u8 index) const { if (!m_valid || index > DIRLEN) - return 0xFF; - return BE16(CurrentDir->Dir[index].AnimSpeed); + return ""; + int x = CurrentDir->Dir[index].AnimSpeed[0]; + std::string speed; + for(int i = 0; i < 16; i++) + { + if (i == 8) x = CurrentDir->Dir[index].AnimSpeed[1]; + speed.push_back((x & 0x80) ? '1' : '0'); + x = x << 1; + } + speed.push_back(0); + return speed; } std::string GCMemcard::DEntry_Permissions(u8 index) const @@ -1086,15 +1095,18 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const // To ensure only one type of icon is used // Sonic Heroes it the only game I have seen that tries to use a CI8 and RGB5A3 icon - int fmtCheck = 0; + //int fmtCheck = 0; int formats = BE16(CurrentDir->Dir[index].IconFmt); int fdelays = BE16(CurrentDir->Dir[index].AnimSpeed); int flags = CurrentDir->Dir[index].BIFlags; - // Timesplitters 2 is the only game that I see this in + // Timesplitters 2 and 3 is the only game that I see this in // May be a hack - if (flags == 0xFB) flags = ~flags; + //if (flags == 0xFB) flags = ~flags; + // Batten Kaitos has 0x65 as flag too. Everything but the first 3 bytes seems irrelevant. + // Something similar happens with Wario Ware Inc. AnimSpeed + int bnrFormat = (flags&3); u32 DataOffset = BE32(CurrentDir->Dir[index].ImageOffset); @@ -1110,7 +1122,6 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const switch (bnrFormat) { case 1: - case 3: animData += 96*32 + 2*256; // image+palette break; case 2: @@ -1122,40 +1133,48 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const u8* data[8]; int frames = 0; - for (int i = 0; i < 8; i++) { fmts[i] = (formats >> (2*i))&3; - delays[i] = ((fdelays >> (2*i))&3) << 2; + delays[i] = ((fdelays >> (2*i))&3); data[i] = animData; - if (!fmtCheck) fmtCheck = fmts[i]; - if (fmtCheck == fmts[i]) + if (!delays[i]) + { + //First icon_speed = 0 indicates there aren't any more icons + break; + } + //If speed is set there is an icon (it can be a "blank frame") + frames++; + if (fmts[i] != 0) { switch (fmts[i]) { case CI8SHARED: // CI8 with shared palette animData += 32*32; - frames++; break; case RGB5A3: // RGB5A3 animData += 32*32*2; - frames++; break; case CI8: // CI8 with own palette animData += 32*32 + 2*256; - frames++; break; } } } u16* sharedPal = (u16*)(animData); + int j = 0; for (int i = 0; i < 8; i++) { - if (fmtCheck == fmts[i]) + if (!delays[i]) + { + //First icon_speed = 0 indicates there aren't any more icons + break; + } + if (fmts[i] != 0) { switch (fmts[i]) { @@ -1165,6 +1184,7 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const break; case RGB5A3: // RGB5A3 decode5A3image(buffer, (u16*)(data[i]), 32, 32); + buffer += 32*32; break; case CI8: // CI8 with own palette u16 *paldata = (u16*)(data[i] + 32*32); @@ -1173,6 +1193,33 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const break; } } + else + { + //Speed is set but there's no actual icon + //This is used to reduce animation speed in Pikmin and Luigi's Mansion for example + //These "blank frames" show the next icon + for(j=i; j<8;++j) + { + if (fmts[j] != 0) + { + switch (fmts[j]) + { + case CI8SHARED: // CI8 with shared palette + decodeCI8image(buffer,data[j],sharedPal,32,32); + break; + case RGB5A3: // RGB5A3 + decode5A3image(buffer, (u16*)(data[j]), 32, 32); + buffer += 32*32; + break; + case CI8: // CI8 with own palette + u16 *paldata = (u16*)(data[j] + 32*32); + decodeCI8image(buffer, data[j], paldata, 32, 32); + buffer += 32*32; + break; + } + } + } + } } return frames; @@ -1269,7 +1316,6 @@ void GCMemcard::FormatInternal(GCMC_Header &GCP) calc_checksumsBE((u16*)p_bat_backup+2, 0xFFE, &p_bat_backup->Checksum, &p_bat_backup->Checksum_Inv); } - void GCMemcard::CARD_GetSerialNo(u32 *serial1,u32 *serial2) { u32 serial[8]; @@ -1349,7 +1395,7 @@ s32 GCMemcard::PSO_MakeSaveGameValid(DEntry& direntry, std::vector &Fi if (strcmp((char*)direntry.Filename,"PSO_SYSTEM")!=0) { // check for PSO3 system file - if (strcmp((char*)&FileBuffer[0].block[0x08],"PSO3_SYSTEM")==0) + if (strcmp((char*)direntry.Filename,"PSO3_SYSTEM")==0) { // PSO3 data block size adjustment pso3offset = 0x10; diff --git a/Source/Core/Core/Src/HW/GCMemcard.h b/Source/Core/Core/Src/HW/GCMemcard.h index d2de93effb..557187b384 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.h +++ b/Source/Core/Core/Src/HW/GCMemcard.h @@ -116,8 +116,8 @@ private: // bits 0 and 1: image format // 00 no banner // 01 CI8 banner - // 01 RGB5A3 banner - // 11 ? maybe ==01? haven't seen it + // 10 RGB5A3 banner + // 11 ? maybe ==00? Time Splitters 2 and 3 have it and don't have banner // u8 Filename[DENTRY_STRLEN]; //0x08 0x20 filename u8 ModTime[4]; //0x28 0x04 Time of file's last modification in seconds since 12am, January 1st, 2000 @@ -213,7 +213,7 @@ public: u32 DEntry_ModTime(u8 index) const; u32 DEntry_ImageOffset(u8 index) const; std::string DEntry_IconFmt(u8 index) const; - u16 DEntry_AnimSpeed(u8 index) const; + std::string DEntry_AnimSpeed(u8 index) const; std::string DEntry_Permissions(u8 index) const; u8 DEntry_CopyCounter(u8 index) const; // get first block for file diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp index bf47a23c53..76c77a0543 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.cpp +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -520,6 +520,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) ? wxString::FromAscii("") : wxString::From8BitData(DefaultIOPath.c_str()), wxEmptyString, wxEmptyString, + _("GameCube Savegame files(*.gci;*.gcs;*.sav)") + wxString(wxT("|*.gci;*.gcs;*.sav|")) + _("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) + _("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) + _("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")),