Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ps1 vmc support #186

Merged
merged 8 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions include/ps1card.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <inttypes.h>

#define PS1CARD_MAX_SLOTS 15
#define PS1CARD_HEADER_SIZE 128
#define PS1CARD_BLOCK_SIZE 8192
#define PS1CARD_SIZE 131072

enum ps1card_type
{
PS1CARD_NULL,
PS1CARD_RAW,
PS1CARD_GME,
PS1CARD_VGS,
PS1CARD_VMP,
PS1CARD_MCX,
};

enum ps1save_type
{
PS1SAVE_NULL,
PS1SAVE_AR,
PS1SAVE_MCS,
PS1SAVE_RAW,
PS1SAVE_PSV,
};

enum ps1block_type
{
PS1BLOCK_FORMATTED,
PS1BLOCK_INITIAL,
PS1BLOCK_MIDDLELINK,
PS1BLOCK_ENDLINK,
PS1BLOCK_DELETED_INITIAL,
PS1BLOCK_DELETED_MIDDLELINK,
PS1BLOCK_DELETED_ENDLINK,
PS1BLOCK_CORRUPTED,
};

typedef struct ps1McData
{
uint8_t* headerData; //Memory Card header data (128 bytes each)
uint8_t* saveData; //Memory Card save data (8192 bytes each)
uint32_t iconPalette[16]; //Memory Card icon palette data
uint8_t iconData[3][256]; //Memory Card icon data, 3 icons per slot, (16*16px icons)
uint8_t iconFrames; //Number of icon frames
uint8_t saveType; //Type of the save (0 - formatted, 1 - initial, 2 - middle link, 3 - end link, 4 - deleted initial, 5 - deleted middle link, 6 - deleted end link, 7 - corrupted)
uint16_t saveRegion; //Region of the save (16 bit value, ASCII representation: BA - America, BE - Europe, BI - Japan)
char saveProdCode[11]; //Product code of the save
char saveIdentifier[9]; //Identifier string of the save
int saveSize; //Size of the save in Bytes
char saveName[21]; //Name of the save
char saveTitle[65]; //Title of the save data (in Shift-JIS format)
} ps1mcData_t;

//Open Memory Card from the given filename (return error message if operation is not sucessful)
int openMemoryCard(const char* fileName, int fixData);

//Open memory card from the given byte stream
int openMemoryCardStream(const uint8_t* memCardData, int dataSize, int fixData);

//Save (export) Memory Card to a given byte stream
uint8_t* saveMemoryCardStream(int fixData);

//Save Memory Card to the given filename
int saveMemoryCard(const char* fileName, int memoryCardType, int fixData);

//Format a complete Memory Card
void formatMemoryCard(void);

//Import single save to the Memory Card
int openSingleSave(const char* fileName, int* requiredSlots);

//Save single save to the given filename
int saveSingleSave(const char* fileName, int slotNumber, int singleSaveType);

//Get icon data as bytes
uint8_t* getIconRGBA(int slotNumber, int frame);

//Set icon data to saveData
void setIconBytes(int slotNumber, uint8_t* iconBytes);

//Return all bytes of the specified save
uint8_t* getSaveBytes(int slotNumber, uint32_t* saveLen);

//Toggle deleted/undeleted status
void toggleDeleteSave(int slotNumber);

//Format save
int formatSave(int slotNumber);

//Get Memory Card data
ps1mcData_t* getMemoryCardData(void);
24 changes: 17 additions & 7 deletions include/saves.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@
#define PS2_SAVES_PATH_HDD "ps2emu2_savedata/"
#define PSP_SAVES_PATH_HDD "minis_savedata/"

#define PS1_IMP_PATH_USB "PS1/SAVEDATA/"
#define PS2_IMP_PATH_USB "PS2/SAVEDATA/"

#define SAVES_PATH_USB0 USB0_PATH PS4_SAVES_PATH_USB
#define SAVES_PATH_USB1 USB1_PATH PS4_SAVES_PATH_USB

Expand All @@ -54,7 +51,7 @@
#define EXP_PSV_PATH_USB1 USB1_PATH PSV_SAVES_PATH_USB

#define VMC_PS2_PATH_USB "PS2/VMC/"
#define VMC_PS2_PATH_HDD "/dev_hdd0/savedata/vmc/"
#define VMC_PS1_PATH_USB "PS1/VMC/"

#define IMP_PS2VMC_PATH_USB USB_PATH "PS2/VMC/"
#define IMPORT_RAP_PATH_USB USB_PATH PS3_LICENSE_PATH
Expand Down Expand Up @@ -115,8 +112,11 @@ enum cmd_code_enum
// Export commands
CMD_EXP_KEYSTONE,
CMD_EXP_PS2_VM2,
CMD_EXP_PS2_RAW,
CMD_EXP_VMC2SAVE,
CMD_EXP_VM2_RAW,
CMD_EXP_VMC1SAVE,
CMD_EXP_PS1_VMP,
CMD_EXP_PS1_VM1,
CMD_EXP_DATABASE,
CMD_DB_REBUILD,
CMD_DB_DEL_FIX,
Expand All @@ -126,6 +126,7 @@ enum cmd_code_enum
CMD_IMP_KEYSTONE,
CMD_IMP_DATABASE,
CMD_IMP_VMC2SAVE,
CMD_IMP_VMC1SAVE,
CMD_CREATE_ACT_DAT,
CMD_EXTRACT_ARCHIVE,
CMD_URL_DOWNLOAD,
Expand Down Expand Up @@ -159,11 +160,15 @@ enum save_type_enum
FILE_TYPE_NULL,
FILE_TYPE_MENU,
FILE_TYPE_PS4,
FILE_TYPE_PSV,
FILE_TYPE_TRP,
FILE_TYPE_VMC,

// PS1 File Types
FILE_TYPE_PS1,
FILE_TYPE_PSX,
FILE_TYPE_MCS,

// Misc
FILE_TYPE_ZIP,
FILE_TYPE_SQL,
FILE_TYPE_NET,
Expand All @@ -179,7 +184,7 @@ enum save_type_enum
FILE_TYPE_MAX,
FILE_TYPE_CBS,
FILE_TYPE_XPS,
FILE_TYPE_VM2,
FILE_TYPE_PSV,
};

enum char_flag_enum
Expand Down Expand Up @@ -259,6 +264,7 @@ list_t * ReadUserList(const char* userPath);
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);
Expand All @@ -270,6 +276,7 @@ int ReadCodes(save_entry_t * save);
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);
Expand Down Expand Up @@ -319,5 +326,8 @@ int ps2_xps2psv(const char *save, const char *psv_path);
int ps2_cbs2psv(const char *save, const char *psv_path);
int ps2_max2psv(const char *save, const char *psv_path);

int psv_resign(const char *src_psv);
int vmp_resign(const char *src_vmp);

char* sjis2utf8(char* input);
uint8_t* getIconPS2(const char* folder, const char* iconfile);
50 changes: 44 additions & 6 deletions source/exec_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "util.h"
#include "sfo.h"
#include "mcio.h"
#include "ps1card.h"

static char host_buf[256];

Expand Down Expand Up @@ -750,7 +751,7 @@ static void exportAllSavesVMC(const save_entry_t* save, int dev, int all)
list_t *list = ((void**)save->dir_name)[0];

init_progress_bar("Exporting all VMC saves...");
_set_dest_path(outPath, dev, PS1_IMP_PATH_USB);
_set_dest_path(outPath, dev, PS1_SAVES_PATH_USB);
mkdirs(outPath);

LOG("Exporting all saves from '%s' to %s...", save->path, outPath);
Expand All @@ -760,8 +761,8 @@ 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)
// (saveSingleSave(outPath, save->dir_name[0], PS1SAVE_PSV) ? done++ : err_count++);
if (item->type == FILE_TYPE_PS1)
(saveSingleSave(outPath, save->dir_name[0], PS1SAVE_PSV) ? done++ : err_count++);

if (item->type == FILE_TYPE_PS2)
(vmc_export_psv(item->dir_name, outPath) ? done++ : err_count++);
Expand All @@ -772,13 +773,35 @@ static void exportAllSavesVMC(const save_entry_t* save, int dev, int all)
show_message("%d/%d Saves exported to\n%s", done, done+err_count, outPath);
}

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

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

if (saveSingleSave(outPath, save->dir_name[0], type))
show_message("Save successfully exported to:\n%s", outPath);
else
show_message("Error exporting save:\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);
_set_dest_path(outPath, dst_id, (type == FILE_TYPE_PSV) ? PSV_SAVES_PATH_USB : PS2_SAVES_PATH_USB);
mkdirs(outPath);
if (type != FILE_TYPE_PSV)
{
Expand Down Expand Up @@ -851,7 +874,7 @@ static void deleteVmcSave(const save_entry_t* save)
if (!show_dialog(DIALOG_TYPE_YESNO, "Do you want to delete %s?", save->dir_name))
return;

if ((save->flags & SAVE_FLAG_PS1) ? /*formatSave(save->dir_name[0])*/0 : vmc_delete_save(save->dir_name))
if ((save->flags & SAVE_FLAG_PS1) ? formatSave(save->dir_name[0]) : vmc_delete_save(save->dir_name))
show_message("Save successfully deleted:\n%s", save->dir_name);
else
show_message("Error! Couldn't delete save:\n%s", save->dir_name);
Expand Down Expand Up @@ -1444,11 +1467,26 @@ void execCodeCommand(code_entry_t* code, const char* codecmd)
break;

case CMD_EXP_PS2_VM2:
case CMD_EXP_VM2_RAW:
case CMD_EXP_PS2_RAW:
exportVM2raw(code->file, codecmd[1], codecmd[0] == CMD_EXP_PS2_VM2);
code->activated = 0;
break;

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

case CMD_IMP_VMC1SAVE:
if (openSingleSave(code->file, (int*) host_buf))
show_message("Save successfully imported:\n%s", code->file);
else
show_message("Error! Couldn't import save:\n%s", code->file);

selected_entry->flags |= SAVE_FLAG_UPDATED;
code->activated = 0;
break;

default:
break;
}
Expand Down
13 changes: 13 additions & 0 deletions source/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ save_list_t user_backup = {
.UpdatePath = NULL,
};

/*
* PS1 VMC list
*/
save_list_t vmc1_saves = {
.icon_id = cat_usb_png_index,
.title = "PS1 Virtual Memory Card",
.list = NULL,
.path = "",
.ReadList = &ReadVmc1List,
.ReadCodes = &ReadVmc1Codes,
.UpdatePath = &update_vmc_path,
};

/*
* PS2 VMC list
*/
Expand Down
Loading