Skip to content

Commit

Permalink
ps2 vmc management
Browse files Browse the repository at this point in the history
fix #144
  • Loading branch information
bucanero committed Mar 13, 2024
1 parent 6117e22 commit d241a30
Show file tree
Hide file tree
Showing 10 changed files with 859 additions and 43 deletions.
Binary file added data/tag_vmc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion include/ps2mc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ typedef struct // size = 512
uint32_t unused2[7]; // 36
char name[32]; // 64
uint8_t unused3[416]; // 96
} ps2_McFsEntry;
} McFsEntry;

typedef struct
{
Expand Down
12 changes: 12 additions & 0 deletions include/saves.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ enum cmd_code_enum
CMD_RESIGN_VMP,
CMD_EXP_SAVES_VMC1,
CMD_EXP_ALL_SAVES_VMC1,
CMD_EXP_SAVES_VMC2,
CMD_EXP_ALL_SAVES_VMC2,

// Export commands
CMD_EXP_EXDATA_USB,
Expand All @@ -119,6 +121,7 @@ enum cmd_code_enum
CMD_EXP_PSV_PSU,
CMD_EXP_VM2_RAW,
CMD_EXP_VMC1SAVE,
CMD_EXP_VMC2SAVE,
CMD_EXP_VMP2MCR,

// Import commands
Expand All @@ -127,6 +130,7 @@ enum cmd_code_enum
CMD_IMP_PS2_CONFIG,
CMD_IMP_PS2VMC_USB,
CMD_IMP_VMC1SAVE,
CMD_IMP_VMC2SAVE,
CMD_IMP_MCR2VMP,
CMD_CREATE_ACT_DAT,
CMD_EXTRACT_ARCHIVE,
Expand Down Expand Up @@ -167,6 +171,7 @@ enum save_type_enum
FILE_TYPE_MCS,

// PS2 File Types
FILE_TYPE_PS2,
FILE_TYPE_PSU,
FILE_TYPE_MAX,
FILE_TYPE_CBS,
Expand Down Expand Up @@ -261,6 +266,7 @@ list_t * ReadOnlineList(const char* urlPath);
list_t * ReadBackupList(const char* userPath);
list_t * ReadTrophyList(const char* userPath);
list_t * ReadVmc1List(const char* userPath);
list_t * ReadVmc2List(const char* userPath);
void UnloadGameList(list_t * list);
char * readTextFile(const char * path, long* size);
int sortSaveList_Compare(const void* A, const void* B);
Expand All @@ -272,6 +278,7 @@ int ReadTrophies(save_entry_t * game);
int ReadOnlineSaves(save_entry_t * game);
int ReadBackupCodes(save_entry_t * bup);
int ReadVmc1Codes(save_entry_t * save);
int ReadVmc2Codes(save_entry_t * save);

int http_init(void);
void http_end(void);
Expand Down Expand Up @@ -324,4 +331,9 @@ int ps2_xps2psv(const char *save, const char *psv_path);
int ps1_psv2mcs(const char* save, const char* mcs_path);
int ps2_psv2psu(const char *save, const char* psu_path);

int vmc_export_psv(const char* save, const char* out_path);
int vmc_export_psu(const char* path, const char* output);
int vmc_import_psv(const char *input);
int vmc_import_psu(const char *input);

char* sjis2utf8(char* input);
81 changes: 80 additions & 1 deletion source/exec_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,11 @@ static void exportAllSavesVMC(const save_entry_t* save, int dev, int all)
if (!all && !(item->flags & SAVE_FLAG_SELECTED))
continue;

if (item->type & FILE_TYPE_PS1)
if (item->type == FILE_TYPE_PS1)
(saveSingleSave(outPath, save->path[strlen(save->path)+1], PS1SAVE_PSV) ? done++ : err_count++);

if (item->type == FILE_TYPE_PS2)
(vmc_export_psv(item->dir_name, outPath) ? done++ : err_count++);
}

end_progress_bar();
Expand Down Expand Up @@ -1590,6 +1593,66 @@ static void export_vmp2mcr(const save_entry_t* save)
show_message("Error exporting memory card:\n%s", save->path);
}

static void export_vmc2save(const save_entry_t* save, int type, int dst_id)
{
int ret = 0;
char outPath[256];
struct tm t;

_set_dest_path(outPath, dst_id, (type == FILE_TYPE_PSV) ? PSV_SAVES_PATH_USB : PS2_IMP_PATH_USB);
mkdirs(outPath);
if (type != FILE_TYPE_PSV)
{
// build file path
gmtime_r(&(time_t){time(NULL)}, &t);
sprintf(strrchr(outPath, '/'), "/%s_%d-%02d-%02d_%02d%02d%02d.psu", save->title_id,
t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}

switch (type)
{
case FILE_TYPE_PSV:
ret = vmc_export_psv(save->dir_name, outPath);
break;

case FILE_TYPE_PSU:
ret = vmc_export_psu(save->dir_name, outPath);
break;

default:
break;
}

if (ret)
show_message("Save successfully exported to:\n%s", outPath);
else
show_message("Error exporting save:\n%s", save->path);
}

static void import_save2vmc(const char* src, int type)
{
int ret = 0;

switch (type)
{
case FILE_TYPE_PSV:
ret = vmc_import_psv(src);
break;

case FILE_TYPE_PSU:
ret = vmc_import_psu(src);
break;

default:
break;
}

if (ret)
show_message("Successfully imported to VMC:\n%s", src);
else
show_message("Error importing save:\n%s", src);
}

void execCodeCommand(code_entry_t* code, const char* codecmd)
{
switch (codecmd[0])
Expand Down Expand Up @@ -1784,6 +1847,22 @@ void execCodeCommand(code_entry_t* code, const char* codecmd)
code->activated = 0;
break;

case CMD_EXP_SAVES_VMC2:
case CMD_EXP_ALL_SAVES_VMC2:
exportAllSavesVMC(selected_entry, codecmd[1], codecmd[0] == CMD_EXP_ALL_SAVES_VMC2);
code->activated = 0;
break;

case CMD_EXP_VMC2SAVE:
export_vmc2save(selected_entry, code->options[0].id, codecmd[1]);
code->activated = 0;
break;

case CMD_IMP_VMC2SAVE:
import_save2vmc(code->file, codecmd[1]);
code->activated = 0;
break;

case CMD_IMP_MCR2VMP:
import_mcr2vmp(selected_entry, code->options[0].name[code->options[0].sel]);
code->activated = 0;
Expand Down
13 changes: 13 additions & 0 deletions source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ save_list_t vmc1_saves = {
.UpdatePath = &update_vmc_path,
};

/*
* PS2 VMC list
*/
save_list_t vmc2_saves = {
.icon_id = cat_usb_png_index,
.title = "PS2 Virtual Memory Card",
.list = NULL,
.path = "",
.ReadList = &ReadVmc2List,
.ReadCodes = &ReadVmc2Codes,
.UpdatePath = &update_vmc_path,
};

static void release_all(void)
{
if(inited & INITED_CALLBACK)
Expand Down
45 changes: 25 additions & 20 deletions source/mcio.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ static int Card_GetSpecs(uint16_t *pagesize, uint16_t *blocksize, int32_t *cards

// check for non-ECC images
*flags = mcdi->cardflags & ((vmc_size % 0x800000 == 0) ? ~CF_USE_ECC : 0xFF);
*pagesize = read_le_uint16((uint8_t*)&mcdi->pagesize);
*blocksize = read_le_uint16((uint8_t*)&mcdi->blocksize);
append_le_uint16((uint8_t*)pagesize, read_le_uint16((uint8_t*)&mcdi->pagesize));
append_le_uint16((uint8_t*)blocksize, read_le_uint16((uint8_t*)&mcdi->blocksize));
*cardsize = read_le_uint32((uint8_t*)&mcdi->clusters_per_card) * read_le_uint16((uint8_t*)&mcdi->pages_per_cluster);

return sceMcResSucceed;
Expand Down Expand Up @@ -2585,8 +2585,9 @@ static int Card_FileOpen(const char *filename, int flags)
fh->fsindex = cacheDir.fsindex;

if (r == 0) {
uint16_t dircache_mode = read_le_uint16((uint8_t *)&mcio_dircache[1].mode);

if ((wrflag != 0) && ((mcio_dircache[1].mode & sceMcFileAttrWriteable) == 0))
if ((wrflag != 0) && ((dircache_mode & sceMcFileAttrWriteable) == 0))
return sceMcResDeniedPermit;

r = Card_ReadDirEntry(cacheDir.cluster, 0, &fse2);
Expand All @@ -2596,20 +2597,20 @@ static int Card_FileOpen(const char *filename, int flags)
fh->parent_cluster = read_le_uint32((uint8_t *)&fse2->cluster);
fh->parent_fsindex = read_le_uint32((uint8_t *)&fse2->dir_entry);

if ((mcio_dircache[1].mode & sceMcFileAttrSubdir) != 0) {
if ((mcio_dircache[1].mode & sceMcFileAttrReadable) == 0)
if ((dircache_mode & sceMcFileAttrSubdir) != 0) {
if ((dircache_mode & sceMcFileAttrReadable) == 0)
return sceMcResDeniedPermit;

if ((flags & sceMcFileAttrSubdir) == 0)
return sceMcResNotFile;

fh->freeclink = mcio_dircache[1].cluster;
fh->freeclink = read_le_uint32((uint8_t *)&mcio_dircache[1].cluster);
fh->rdflag = 0;
fh->wrflag = 0;
fh->unknown1 = 0;
fh->drdflag = 1;
fh->status = 1;
fh->filesize = mcio_dircache[1].length;
fh->filesize = read_le_uint32((uint8_t *)&mcio_dircache[1].length);
fh->clink = fh->freeclink;

return fd;
Expand Down Expand Up @@ -2641,8 +2642,8 @@ static int Card_FileOpen(const char *filename, int flags)
cacheDir.maxent = cacheDir.fsindex;
}
else {
fh->freeclink = mcio_dircache[1].cluster;
fh->filesize = mcio_dircache[1].length;
fh->freeclink = read_le_uint32((uint8_t *)&mcio_dircache[1].cluster);
fh->filesize = read_le_uint32((uint8_t *)&mcio_dircache[1].length);
fh->clink = fh->freeclink;

if (fh->rdflag != 0)
Expand All @@ -2651,7 +2652,7 @@ static int Card_FileOpen(const char *filename, int flags)
fh->rdflag = 0;

if (fh->wrflag != 0)
fh->wrflag = (mcio_dircache[1].mode >> 1) & sceMcFileAttrReadable;
fh->wrflag = (dircache_mode >> 1) & sceMcFileAttrReadable;
else
fh->wrflag = 0;

Expand All @@ -2670,20 +2671,22 @@ static int Card_FileOpen(const char *filename, int flags)
return r;

memcpy((void *)&mcio_dircache[2], (void *)fse1, sizeof(struct MCFsEntry));
uint32_t dircache_length = read_le_uint32((uint8_t *)&mcio_dircache[2].length);
uint32_t dircache_cluster = read_le_uint32((uint8_t *)&mcio_dircache[2].cluster);

i = -1;
if (mcio_dircache[2].length == (uint32_t) cacheDir.maxent) {
if (dircache_length == (uint32_t) cacheDir.maxent) {

int32_t cluster_size = (int32_t)read_le_uint32((uint8_t *)&mcdi->cluster_size);

fsindex = mcio_dircache[2].length / (cluster_size >> 9);
fsoffset = mcio_dircache[2].length % (cluster_size >> 9);
fsindex = dircache_length / (cluster_size >> 9);
fsoffset = dircache_length % (cluster_size >> 9);

if (fsoffset == 0) {
fat_index = mcio_dircache[2].cluster;
fat_index = dircache_cluster;
i = fsindex;

if ((mcio_dircache[2].cluster == 0) && (i >= 2)) {
if ((dircache_cluster == 0) && (i >= 2)) {
if (read_le_uint32((uint8_t *)&mcio_fatcache.entry[i-1]) >= 0) {
fat_index = read_le_uint32((uint8_t *)&mcio_fatcache.entry[i-1]);
i = 1;
Expand Down Expand Up @@ -2727,7 +2730,8 @@ static int Card_FileOpen(const char *filename, int flags)

i = -1;

mcio_dircache[2].length++;
dircache_length++;
append_le_uint32((uint8_t *)&mcio_dircache[2].length, dircache_length);
}

do {
Expand All @@ -2754,7 +2758,7 @@ static int Card_FileOpen(const char *filename, int flags)

mcio_getmcrtime(&mcio_dircache[2].modified);

r = Card_ReadDirEntry(mcio_dircache[2].cluster, cacheDir.maxent, &fse2);
r = Card_ReadDirEntry(dircache_cluster, cacheDir.maxent, &fse2);
if (r != sceMcResSucceed)
return r;

Expand All @@ -2781,7 +2785,7 @@ static int Card_FileOpen(const char *filename, int flags)
append_le_uint32((uint8_t *)&fse2->cluster, mcfree);
append_le_uint32((uint8_t *)&fse2->length, 2);

r = Card_CreateDirEntry(mcio_dircache[2].cluster, cacheDir.maxent, mcfree, (struct sceMcStDateTime *)&fse2->created);
r = Card_CreateDirEntry(dircache_cluster, cacheDir.maxent, mcfree, (struct sceMcStDateTime *)&fse2->created);
if (r != sceMcResSucceed)
return -46;

Expand All @@ -2807,7 +2811,7 @@ static int Card_FileOpen(const char *filename, int flags)

append_le_uint16((uint8_t *)&fse2->mode, fmode);
append_le_uint32((uint8_t *)&fse2->cluster, -1);
fh->cluster = mcio_dircache[2].cluster;
fh->cluster = dircache_cluster;
fh->status = 1;
fh->fsindex = cacheDir.maxent;

Expand Down Expand Up @@ -3462,8 +3466,9 @@ int mcio_mcGetInfo(int *pagesize, int *blocksize, int *cardsize, int *cardflags)
if (Card_GetSpecs(&_pagesize, &_blocksize, &_cardsize, &_cardflags) != sceMcResSucceed)
return r;

_pagesize = read_le_uint16((uint8_t *)&_pagesize);
*pagesize = (int)_pagesize;
*blocksize = (int)_blocksize;
*blocksize = (int)read_le_uint16((uint8_t *)&_blocksize);
*cardsize = (int)_cardsize * _pagesize;
*cardflags = (int)_cardflags;

Expand Down
Loading

0 comments on commit d241a30

Please sign in to comment.