mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-08 21:47:42 +00:00
Work on CMemoryCardDriver
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include "CSimplePool.hpp"
|
||||
#include "CGameState.hpp"
|
||||
#include "GuiSys/CStringTable.hpp"
|
||||
#include "CCRC32.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
@@ -132,6 +134,199 @@ bool CMemoryCardSys::InitializePump()
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMemoryCardSys::CCardFileInfo::LockBannerToken(ResId bannerTxtr, CSimplePool& sp)
|
||||
{
|
||||
x3c_bannerTex = bannerTxtr;
|
||||
x40_bannerTok.emplace(sp.GetObj({FOURCC('TXTR'), bannerTxtr}, m_texParam));
|
||||
}
|
||||
|
||||
CMemoryCardSys::CCardFileInfo::Icon::Icon(ResId id, u32 speed, CSimplePool& sp, const CVParamTransfer& cv)
|
||||
: x0_id(id), x4_speed(speed), x8_tex(sp.GetObj({FOURCC('TXTR'), id}, cv)) {}
|
||||
|
||||
void CMemoryCardSys::CCardFileInfo::LockIconToken(ResId iconTxtr, u32 speed, CSimplePool& sp)
|
||||
{
|
||||
x50_iconToks.emplace_back(iconTxtr, speed, sp, m_texParam);
|
||||
}
|
||||
|
||||
u32 CMemoryCardSys::CCardFileInfo::CalculateBannerDataSize() const
|
||||
{
|
||||
u32 ret = 68;
|
||||
if (x3c_bannerTex != -1)
|
||||
{
|
||||
if ((*x40_bannerTok)->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3)
|
||||
ret = 6212;
|
||||
else
|
||||
ret = 3652;
|
||||
}
|
||||
|
||||
bool paletteTex = false;
|
||||
for (const Icon& icon : x50_iconToks)
|
||||
{
|
||||
if (icon.x8_tex->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3)
|
||||
ret += 2048;
|
||||
else
|
||||
{
|
||||
ret += 1024;
|
||||
paletteTex = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (paletteTex)
|
||||
ret += 512;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 CMemoryCardSys::CCardFileInfo::CalculateTotalDataSize() const
|
||||
{
|
||||
return (CalculateBannerDataSize() + xf4_saveBuffer.size() + 8191) & ~8191;
|
||||
}
|
||||
|
||||
void CMemoryCardSys::CCardFileInfo::BuildCardBuffer()
|
||||
{
|
||||
u32 bannerSz = CalculateBannerDataSize();
|
||||
x104_cardBuffer.resize((bannerSz + xf4_saveBuffer.size() + 8191) & ~8191);
|
||||
|
||||
CMemoryOutStream w(x104_cardBuffer.data(), x104_cardBuffer.size());
|
||||
w.writeUint32Big(0);
|
||||
char name[64];
|
||||
strncpy(name, x28_name2.data(), 64);
|
||||
w.writeBytes(name, 64);
|
||||
WriteBannerData(w);
|
||||
WriteIconData(w);
|
||||
memmove(x104_cardBuffer.data() + bannerSz, xf4_saveBuffer.data(), xf4_saveBuffer.size());
|
||||
reinterpret_cast<u32&>(*x104_cardBuffer.data()) =
|
||||
hecl::SBig(CCRC32::Calculate(x104_cardBuffer.data() + 4, x104_cardBuffer.size() - 4));
|
||||
|
||||
xf4_saveBuffer.clear();
|
||||
}
|
||||
|
||||
void CMemoryCardSys::CCardFileInfo::WriteBannerData(CMemoryOutStream& out) const
|
||||
{
|
||||
if (x3c_bannerTex != -1)
|
||||
{
|
||||
const TLockedToken<CTexture>& tex = *x40_bannerTok;
|
||||
u32 bufSz;
|
||||
ETexelFormat fmt;
|
||||
std::unique_ptr<u8[]> palette;
|
||||
std::unique_ptr<u8[]> texels = tex->BuildMemoryCardTex(bufSz, fmt, palette);
|
||||
|
||||
if (fmt == ETexelFormat::RGB5A3)
|
||||
out.writeBytes(texels.get(), 6144);
|
||||
else
|
||||
out.writeBytes(texels.get(), 3072);
|
||||
|
||||
if (fmt == ETexelFormat::C8)
|
||||
out.writeBytes(palette.get(), 512);
|
||||
}
|
||||
}
|
||||
|
||||
void CMemoryCardSys::CCardFileInfo::WriteIconData(CMemoryOutStream& out) const
|
||||
{
|
||||
std::unique_ptr<u8[]> palette;
|
||||
for (const Icon& icon : x50_iconToks)
|
||||
{
|
||||
u32 bufSz;
|
||||
ETexelFormat fmt;
|
||||
std::unique_ptr<u8[]> texels = icon.x8_tex->BuildMemoryCardTex(bufSz, fmt, palette);
|
||||
|
||||
if (fmt == ETexelFormat::RGB5A3)
|
||||
out.writeBytes(texels.get(), 2048);
|
||||
else
|
||||
out.writeBytes(texels.get(), 1024);
|
||||
}
|
||||
if (palette)
|
||||
out.writeBytes(palette.get(), 512);
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::CCardFileInfo::PumpCardTransfer()
|
||||
{
|
||||
if (x0_status == EStatus::Standby)
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
else if (x0_status == EStatus::Transferring)
|
||||
{
|
||||
ECardResult result = CMemoryCardSys::GetResultCode(GetCardPort());
|
||||
if (result != ECardResult::CARD_RESULT_BUSY)
|
||||
x104_cardBuffer.clear();
|
||||
if (result != ECardResult::CARD_RESULT_READY)
|
||||
return result;
|
||||
x0_status = EStatus::Done;
|
||||
CARDStat stat = {};
|
||||
result = GetStatus(stat);
|
||||
if (result != ECardResult::CARD_RESULT_READY)
|
||||
return result;
|
||||
result = CMemoryCardSys::SetStatus(GetCardPort(), GetFileNo(), stat);
|
||||
if (result != ECardResult::CARD_RESULT_READY)
|
||||
return result;
|
||||
return ECardResult::CARD_RESULT_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECardResult result = CMemoryCardSys::GetResultCode(GetCardPort());
|
||||
if (result == ECardResult::CARD_RESULT_READY)
|
||||
x0_status = EStatus::Standby;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::CCardFileInfo::GetStatus(CARDStat& stat) const
|
||||
{
|
||||
ECardResult result = CMemoryCardSys::GetStatus(GetCardPort(), GetFileNo(), stat);
|
||||
if (result != ECardResult::CARD_RESULT_READY)
|
||||
return result;
|
||||
|
||||
stat.SetCommentAddr(4);
|
||||
stat.SetIconAddr(68);
|
||||
|
||||
u32 bannerFmt;
|
||||
if (x3c_bannerTex != -1)
|
||||
{
|
||||
if ((*x40_bannerTok)->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3)
|
||||
bannerFmt = 2;
|
||||
else
|
||||
bannerFmt = 1;
|
||||
}
|
||||
else
|
||||
bannerFmt = 0;
|
||||
stat.SetBannerFormat(bannerFmt);
|
||||
|
||||
int idx = 0;
|
||||
for (const Icon& icon : x50_iconToks)
|
||||
{
|
||||
stat.SetIconFormat(icon.x8_tex->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3 ? 2 : 1, idx);
|
||||
stat.SetIconSpeed(icon.x4_speed, idx);
|
||||
++idx;
|
||||
}
|
||||
if (idx < 8)
|
||||
{
|
||||
stat.SetIconFormat(0, idx);
|
||||
stat.SetIconSpeed(0, idx);
|
||||
}
|
||||
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::CCardFileInfo::CreateFile()
|
||||
{
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::CCardFileInfo::Write()
|
||||
{
|
||||
BuildCardBuffer();
|
||||
//DCStoreRange(info.x104_cardBuffer.data(), info.x104_cardBuffer.size());
|
||||
//CARDWriteAsync(&info.x4_info, info.x104_cardBuffer.data(), info.x104_cardBuffer.size(), 0, 0);
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::CCardFileInfo::Close()
|
||||
{
|
||||
EMemoryCardPort port = GetCardPort();
|
||||
//CARDClose(port);
|
||||
x4_info.chan = port;
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::CardProbeResults CMemoryCardSys::CardProbe(EMemoryCardPort port)
|
||||
{
|
||||
return {};
|
||||
@@ -167,6 +362,11 @@ CMemoryCardSys::ECardResult CMemoryCardSys::GetStatus(EMemoryCardPort port, int
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::SetStatus(EMemoryCardPort port, int fileNo, const CARDStat& stat)
|
||||
{
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::DeleteFile(EMemoryCardPort port, const char* name)
|
||||
{
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
@@ -177,4 +377,14 @@ CMemoryCardSys::ECardResult CMemoryCardSys::FastDeleteFile(EMemoryCardPort port,
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::Rename(EMemoryCardPort port, const char* oldName, const char* newName)
|
||||
{
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
CMemoryCardSys::ECardResult CMemoryCardSys::FormatCard(EMemoryCardPort port)
|
||||
{
|
||||
return ECardResult::CARD_RESULT_READY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user