here have more code

This commit is contained in:
Arisotura 2021-10-27 02:00:53 +02:00
parent 6cb2faff89
commit 81623e5b22
4 changed files with 185 additions and 147 deletions

View File

@ -461,8 +461,6 @@ void ARM::UpdateMode(u32 oldmode, u32 newmode)
break;
}
#undef SWAP
if (Num == 0)
{
/*if ((newmode & 0x1F) == 0x10)

View File

@ -25,20 +25,17 @@
namespace fs = std::filesystem;
FATStorage::FATStorage()
FATStorage::FATStorage(std::string filename, u64 size, bool readonly, std::string sourcedir)
{
printf("FATStorage begin\n");
//bool res = Build("dldi", 0x20000000, "melonDLDI.bin");
bool res = Build("dldi", 0x3F000000, "melonDLDI.bin");
printf("FATStorage result: %d\n", res);
ReadOnly = readonly;
Load(filename, size, sourcedir);
File = nullptr;
}
FATStorage::~FATStorage()
{
printf("SAVING DLDI SHIT\n");
Save("dldi");
if (!ReadOnly) Save();
}
@ -47,7 +44,6 @@ bool FATStorage::Open()
File = Platform::OpenLocalFile(FilePath.c_str(), "r+b");
if (!File)
{
File = nullptr;
return false;
}
}
@ -66,6 +62,7 @@ u32 FATStorage::ReadSectors(u32 start, u32 num, u8* data)
u32 FATStorage::WriteSectors(u32 start, u32 num, u8* data)
{
if (ReadOnly) return 0;
return WriteSectorsInternal(File, FileSize, start, num, data);
}
@ -349,7 +346,7 @@ void FATStorage::ExportDirectory(std::string path, std::string outbase, int leve
FF_DIR dir;
FF_FILINFO info;
FRESULT res;
printf("EXPORTING DIRECTORY %s (base %s level %d)\n", path.c_str(), outbase.c_str(), level);
std::string fullpath = "0:/" + path;
res = f_opendir(&dir, fullpath.c_str());
if (res != FR_OK) return;
@ -383,7 +380,7 @@ printf("EXPORTING DIRECTORY %s (base %s level %d)\n", path.c_str(), outbase.c_st
else
{
bool doexport = false;
printf("- FILE %s ATTRIB %08X\n", fullpath.c_str(), info.fattrib);
if (FileIndex.count(fullpath) < 1)
{
doexport = true;
@ -410,7 +407,6 @@ printf("- FILE %s ATTRIB %08X\n", fullpath.c_str(), info.fattrib);
if (doexport)
{
printf("EXPORTING FILE 0:/%s TO %s/%s\n", fullpath.c_str(), outbase.c_str(), fullpath.c_str());
fs::file_time_type modtime;
if (ExportFile("0:/"+fullpath, outbase+"/"+fullpath, modtime))
{
@ -447,7 +443,7 @@ bool FATStorage::DeleteHostDirectory(std::string path, std::string outbase, int
std::vector<std::string> filedeletelist;
std::vector<std::string> dirdeletelist;
printf("-- PURGING HOST DIRECTORY %s (base %s) LEVEL=%d\n", path.c_str(), outbase.c_str(), level);
int outlen = outbase.length();
for (auto& entry : fs::directory_iterator(outbase + "/" + path))
{
@ -462,7 +458,7 @@ printf("-- PURGING HOST DIRECTORY %s (base %s) LEVEL=%d\n", path.c_str(), outbas
if (innerpath[i] == '\\')
innerpath[i] = '/';
}
printf("---- ENTRY %s (%d)\n", innerpath.c_str(), entry.is_directory());
if (entry.is_directory())
{
dirdeletelist.push_back(innerpath);
@ -495,14 +491,14 @@ printf("---- ENTRY %s (%d)\n", innerpath.c_str(), entry.is_directory());
{
std::string fullpath = outbase + "/" + path;
printf("DELETING DIR ITSELF: %s\n", fullpath.c_str());
std::error_code err;
fs::permissions(fullpath,
fs::perms::owner_read | fs::perms::owner_write,
fs::perm_options::add,
err);
if (!fs::remove(fullpath)){printf("DICKPILE %d\n", errno);
return false;}
if (!fs::remove(fullpath))
return false;
DirIndex.erase(path);
}
@ -542,7 +538,7 @@ void FATStorage::ExportChanges(std::string outbase)
for (const auto& key : deletelist)
{
std::string fullpath = outbase + "/" + key;
printf("DELETING FILE %s\n", fullpath.c_str());
std::error_code err;
fs::permissions(fullpath,
fs::perms::owner_read | fs::perms::owner_write,
@ -575,7 +571,6 @@ void FATStorage::ExportChanges(std::string outbase)
for (const auto& key : deletelist)
{
printf("DELETING DIRECTORY %s\n", key.c_str());
DeleteHostDirectory(key, outbase, 0);
}
@ -593,8 +588,7 @@ bool FATStorage::CanFitFile(u32 len)
if (res != FR_OK) return false;
u32 clustersize = fs->csize * 0x200;
printf("CHECK IF FILE CAN FIT: len=%d, clus=%d, num=%d, free=%d\n",
len, clustersize, (len + clustersize - 1) / clustersize, freeclusters);
len = (len + clustersize - 1) / clustersize;
return (freeclusters >= len);
}
@ -668,7 +662,7 @@ void FATStorage::CleanupDirectory(std::string sourcedir, std::string path, int l
FF_DIR dir;
FF_FILINFO info;
FRESULT res;
printf("CLEANING UP DIRECTORY %s (level=%d)\n", path.c_str(), level);
std::string fullpath = "0:/" + path;
res = f_opendir(&dir, fullpath.c_str());
if (res != FR_OK) return;
@ -684,9 +678,7 @@ printf("CLEANING UP DIRECTORY %s (level=%d)\n", path.c_str(), level);
if (!info.fname[0]) break;
std::string fullpath = path + info.fname;
printf("FOUND ENTRY %s %08X (%d/%d, %d)\n",
fullpath.c_str(), info.fattrib, FileIndex.count(fullpath), DirIndex.count(fullpath),
fs::exists(sourcedir+"/"+fullpath));
if (info.fattrib & AM_DIR)
{
if (DirIndex.count(fullpath) < 1)
@ -778,131 +770,144 @@ bool FATStorage::ImportFile(std::string path, std::string in)
return true;
}
bool FATStorage::BuildSubdirectory(const char* sourcedir, const char* path, int level)
bool FATStorage::ImportDirectory(std::string sourcedir)
{
if (level >= 32)
// remove whatever isn't in the index
CleanupDirectory(sourcedir, "", 0);
int srclen = sourcedir.length();
// iterate through the host directory:
// * directories will be added if they aren't in the index
// * files will be added if they aren't in the index, or if the size or last-modified-date don't match
for (auto& entry : fs::recursive_directory_iterator(sourcedir))
{
printf("FATStorage::BuildSubdirectory: too many subdirectory levels, skipping\n");
return false;
}
std::string fullpath = entry.path().string();
std::string innerpath = fullpath.substr(srclen);
if (innerpath[0] == '/' || innerpath[0] == '\\')
innerpath = innerpath.substr(1);
if (level == 0)
{
// remove whatever isn't in the index
CleanupDirectory(sourcedir, "", 0);
int srclen = strlen(sourcedir);
// iterate through the host directory:
// * directories will be added if they aren't in the index
// * files will be added if they aren't in the index, or if the size or last-modified-date don't match
for (auto& entry : fs::recursive_directory_iterator(sourcedir))
int ilen = innerpath.length();
for (int i = 0; i < ilen; i++)
{
std::string fullpath = entry.path().string();
std::string innerpath = fullpath.substr(srclen);
if (innerpath[0] == '/' || innerpath[0] == '\\')
innerpath = innerpath.substr(1);
int ilen = innerpath.length();
for (int i = 0; i < ilen; i++)
{
if (innerpath[i] == '\\')
innerpath[i] = '/';
}
bool readonly = (entry.status().permissions() & fs::perms::owner_write) == fs::perms::none;
//std::chrono::duration<s64> bourf(lastmodified_raw);
//printf("DORP: %016llX\n", bourf.count());
if (entry.is_directory())
{
if (DirIndex.count(innerpath) < 1)
{
DirIndexEntry ientry;
ientry.Path = innerpath;
ientry.IsReadOnly = readonly;
innerpath = "0:/" + innerpath;
FRESULT res = f_mkdir(innerpath.c_str());
if (res == FR_OK)
{
DirIndex[ientry.Path] = ientry;
printf("IMPORTING DIR %s (FROM %s), %d\n", innerpath.c_str(), fullpath.c_str(), readonly);
}
}
}
else if (entry.is_regular_file())
{
u64 filesize = entry.file_size();
auto lastmodified = entry.last_write_time();
s64 lastmodified_raw = std::chrono::duration_cast<std::chrono::seconds>(lastmodified.time_since_epoch()).count();
bool import = false;
if (FileIndex.count(innerpath) < 1)
{
import = true;
}
else
{
FileIndexEntry& chk = FileIndex[innerpath];
if (chk.Size != filesize) import = true;
if (chk.LastModified != lastmodified_raw) import = true;
}
if (import)
{
FileIndexEntry ientry;
ientry.Path = innerpath;
ientry.IsReadOnly = readonly;
ientry.Size = filesize;
ientry.LastModified = lastmodified_raw;
innerpath = "0:/" + innerpath;
if (ImportFile(innerpath, fullpath))
{
FF_FILINFO finfo;
f_stat(innerpath.c_str(), &finfo);
ientry.LastModifiedInternal = (finfo.fdate << 16) | finfo.ftime;
FileIndex[ientry.Path] = ientry;
printf("IMPORTING FILE %s (FROM %s), %d\n", innerpath.c_str(), fullpath.c_str(), readonly);
}
}
}
f_chmod(innerpath.c_str(), readonly?AM_RDO:0, AM_RDO);
if (innerpath[i] == '\\')
innerpath[i] = '/';
}
SaveIndex();
bool readonly = (entry.status().permissions() & fs::perms::owner_write) == fs::perms::none;
return false;
if (entry.is_directory())
{
if (DirIndex.count(innerpath) < 1)
{
DirIndexEntry ientry;
ientry.Path = innerpath;
ientry.IsReadOnly = readonly;
innerpath = "0:/" + innerpath;
FRESULT res = f_mkdir(innerpath.c_str());
if (res == FR_OK)
{
DirIndex[ientry.Path] = ientry;
}
}
}
else if (entry.is_regular_file())
{
u64 filesize = entry.file_size();
auto lastmodified = entry.last_write_time();
s64 lastmodified_raw = std::chrono::duration_cast<std::chrono::seconds>(lastmodified.time_since_epoch()).count();
bool import = false;
if (FileIndex.count(innerpath) < 1)
{
import = true;
}
else
{
FileIndexEntry& chk = FileIndex[innerpath];
if (chk.Size != filesize) import = true;
if (chk.LastModified != lastmodified_raw) import = true;
}
if (import)
{
FileIndexEntry ientry;
ientry.Path = innerpath;
ientry.IsReadOnly = readonly;
ientry.Size = filesize;
ientry.LastModified = lastmodified_raw;
innerpath = "0:/" + innerpath;
if (ImportFile(innerpath, fullpath))
{
FF_FILINFO finfo;
f_stat(innerpath.c_str(), &finfo);
ientry.LastModifiedInternal = (finfo.fdate << 16) | finfo.ftime;
FileIndex[ientry.Path] = ientry;
}
}
}
f_chmod(innerpath.c_str(), readonly?AM_RDO:0, AM_RDO);
}
SaveIndex();
return false;
return true;
}
bool FATStorage::Build(const char* sourcedir, u64 size, const char* filename)
u64 FATStorage::GetDirectorySize(std::string sourcedir)
{
u64 ret = 0;
u32 csize = 0x1000; // this is an estimate
for (auto& entry : fs::recursive_directory_iterator(sourcedir))
{
if (entry.is_directory())
{
ret += csize;
}
else if (entry.is_regular_file())
{
u64 filesize = entry.file_size();
filesize = (filesize + (csize-1)) & ~(csize-1);
ret += filesize;
}
}
return ret;
}
bool FATStorage::Load(std::string filename, u64 size, std::string sourcedir)
{
FilePath = filename;
FileSize = size;
SourceDir = sourcedir;
bool hasdir = !sourcedir.empty();
// 'auto' size management: (size=0)
// * if an index exists: the size from the index is used
// * if no index, and an image file exists: the file size is used
// * if no image: if sourcing from a directory, size is calculated from that
// with a 64MB extra, otherwise size is defaulted to 512MB
bool isnew = false;
FF_File = Platform::OpenLocalFile(filename, "r+b");
FF_File = Platform::OpenLocalFile(filename.c_str(), "r+b");
if (!FF_File)
{
FF_File = Platform::OpenLocalFile(filename, "w+b");
FF_File = Platform::OpenLocalFile(filename.c_str(), "w+b");
if (!FF_File)
return false;
isnew = true;
}
printf("IMAGE FILE NEW: %d\n", isnew);
IndexPath = FilePath + ".idx";
if (isnew)
{
@ -911,29 +916,58 @@ bool FATStorage::Build(const char* sourcedir, u64 size, const char* filename)
SaveIndex();
}
else
{
LoadIndex();
printf("INDEX SIZE %016llX\n", FileSize);
if (FileSize == 0)
{
fseek(FF_File, 0, SEEK_END);
FileSize = ftell(FF_File);
}
}
FF_FileSize = size;
ff_disk_open(FF_ReadStorage, FF_WriteStorage, (LBA_t)(size>>9));
FRESULT res;
FATFS fs;
bool needformat = false;
FATFS fs;
FRESULT res;
res = f_mount(&fs, "0:", 1);
if (res != FR_OK)
if (FileSize == 0)
{
needformat = true;
}
else if (size != FileSize)
else
{
printf("VOLUME NEEDS REFORMATTING BECAUSE SIZE CHANGED (%016llX != %016llX)\n", size, FileSize);
needformat = true;
FF_FileSize = FileSize;
ff_disk_open(FF_ReadStorage, FF_WriteStorage, (LBA_t)(FF_FileSize>>9));
res = f_mount(&fs, "0:", 1);
if (res != FR_OK)
{
needformat = true;
}
else if (size > 0 && size != FileSize)
{
needformat = true;
}
}
if (needformat)
{
FileSize = size;
if (FileSize == 0)
{
if (hasdir)
{
FileSize = GetDirectorySize(sourcedir);
FileSize += 0x4000000ULL; // 64MB leeway
}
else
FileSize = 0x20000000ULL; // 512MB
}
printf("CREATING IMAGE FILE WITH SIZE %016llX\n", FileSize);
FF_FileSize = FileSize;
ff_disk_close();
ff_disk_open(FF_ReadStorage, FF_WriteStorage, (LBA_t)(FF_FileSize>>9));
DirIndex.clear();
FileIndex.clear();
SaveIndex();
@ -943,7 +977,7 @@ bool FATStorage::Build(const char* sourcedir, u64 size, const char* filename)
// FAT type: we force it to FAT32 for any volume that is 1GB or more
// libfat attempts to determine the FAT type from the volume size and other parameters
// which can lead to it trying to interpret a FAT16 volume as FAT32
if (size >= 0x40000000ULL)
if (FileSize >= 0x40000000ULL)
fsopt.fmt = FM_FAT32;
else
fsopt.fmt = FM_FAT;
@ -959,9 +993,12 @@ bool FATStorage::Build(const char* sourcedir, u64 size, const char* filename)
if (res == FR_OK)
res = f_mount(&fs, "0:", 1);
}
printf("USING IMAGE FILE WITH SIZE %016llX\n", FileSize);
if (res == FR_OK)
BuildSubdirectory(sourcedir, "", 0);
{
if (hasdir)
ImportDirectory(sourcedir);
}
f_unmount("0:");
@ -972,7 +1009,7 @@ bool FATStorage::Build(const char* sourcedir, u64 size, const char* filename)
return true;
}
bool FATStorage::Save(std::string sourcedir)
bool FATStorage::Save()
{
FF_File = Platform::OpenLocalFile(FilePath.c_str(), "r+b");
if (!FF_File)
@ -995,7 +1032,7 @@ bool FATStorage::Save(std::string sourcedir)
return false;
}
ExportChanges("dldi");
ExportChanges(SourceDir);
SaveIndex();

View File

@ -31,7 +31,7 @@
class FATStorage
{
public:
FATStorage();
FATStorage(std::string filename, u64 size, bool readonly, std::string sourcedir);
~FATStorage();
bool Open();
@ -43,6 +43,8 @@ public:
private:
std::string FilePath;
std::string IndexPath;
std::string SourceDir;
bool ReadOnly;
FILE* File;
u64 FileSize;
@ -67,10 +69,11 @@ private:
bool DeleteDirectory(std::string path, int level);
void CleanupDirectory(std::string sourcedir, std::string path, int level);
bool ImportFile(std::string path, std::string in);
bool BuildSubdirectory(const char* sourcedir, const char* path, int level);
bool ImportDirectory(std::string sourcedir);
u64 GetDirectorySize(std::string sourcedir);
bool Build(const char* sourcedir, u64 size, const char* filename);
bool Save(std::string sourcedir);
bool Load(std::string filename, u64 size, std::string sourcedir);
bool Save();
typedef struct
{

View File

@ -1168,7 +1168,7 @@ CartHomebrew::CartHomebrew(u8* rom, u32 len, u32 chipid) : CartCommon(rom, len,
if (true)
{
ApplyDLDIPatch(melonDLDI, sizeof(melonDLDI), true);
SD = new FATStorage();
SD = new FATStorage("melonDLDI.bin", 0, false, "dldi");
SD->Open();
}
else