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

hdd: Add option to use partitions other than +OPL #423

Merged
merged 1 commit into from
Jun 19, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ USB modes:
| "LNG" | for translation support | all |
| "CHT" | for cheats files | all |

OPL will automatically create the above directory structure the first time
you launch it and enable your favourite device. For HDD users, a 128Mb +OPL
partition will be created (you can enlarge it using uLaunchELF if you need to).
OPL will automatically create the above directory structure the first time you launch it and enable your favourite device.

For HDD users, OPL will read hdd0:__common/OPL/conf_hdd.cfg for the config entry "hdd_partition" to use as your OPL partition.
If not found a config file and a 128Mb +OPL partition will be created, you can edit the config if you wish to use/create a different partition.
All partitions created by OPL will be 128Mb (it is not recommended to enlarge partitions as it will break LBAs, instead remove and recreate manually with uLaunchELF at a larger size if needed).

## USB

Expand Down
12 changes: 2 additions & 10 deletions elfldr/elfldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <string.h>
#include <stdio.h>

static inline void _strcpy(char *dst, const char *src)
/*static inline void _strcpy(char *dst, const char *src)
{
memcpy(dst, src, strlen(src) + 1);
}
Expand All @@ -38,7 +38,7 @@ static int _strncmp(const char *s1, const char *s2, int length)
}

return 0;
}
}*/

static inline void BootError(char *filename)
{
Expand Down Expand Up @@ -101,14 +101,6 @@ int main(int argc, char *argv[])
SifLoadFileExit();
SifExitRpc();

if (_strncmp(argv[0], "pfs", 3) == 0) {
static char _argv[256];
_strcpy(_argv, "hdd0:+OPL:");
_strcat(_argv, argv[0]);

argv[0] = _argv;
}

ExecPS2((void *)exd.epc, (void *)exd.gp, argc, argv);
} else {
SifExitRpc();
Expand Down
2 changes: 2 additions & 0 deletions include/hddsupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,6 @@ void hddInit();
item_list_t *hddGetObject(int initOnly);
void hddLoadModules(void);

extern char gOPLPart[128];

#endif
1 change: 1 addition & 0 deletions include/opl.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ extern int gDefaultDevice;

extern int gEnableWrite;

extern char *gHDDPrefix;
//These prefixes are relative to the device's name (meaning that they do not include the device name).
extern char gBDMPrefix[32];
extern char gETHPrefix[32];
Expand Down
113 changes: 90 additions & 23 deletions src/hddsupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static unsigned char hddModulesLoaded = 0;
static char *hddPrefix = "pfs0:";
static hdl_games_list_t hddGames;

const char *oplPart = "hdd0:+OPL";
char gOPLPart[128];

// forward declaration
static item_list_t hddGameList;
Expand All @@ -42,13 +42,13 @@ static void hddInitModules(void)

// update Themes
char path[256];
sprintf(path, "%sTHM", hddPrefix);
sprintf(path, "%sTHM", gHDDPrefix);
thmAddElements(path, "/", 1);

sprintf(path, "%sLNG", hddPrefix);
sprintf(path, "%sLNG", gHDDPrefix);
lngAddLanguages(path, "/", hddGameList.mode);

sbCreateFolders(hddPrefix, 0);
sbCreateFolders(gHDDPrefix, 0);
}

// HD Pro Kit is mapping the 1st word in ROM0 seg as a main ATA controller,
Expand Down Expand Up @@ -93,16 +93,76 @@ static int hddCheckHDProKit(void)
#define PFS_ZONE_SIZE 8192
#define PFS_FRAGMENT 0x00000000

static int CreateOPLPartition(const char *oplPart, const char *mountpoint)
static void hddCheckOPLFolder(const char *mountPoint)
{
DIR *dir;
char path[32];

sprintf(path, "%sOPL", mountPoint);

dir = opendir(path);
if (dir == NULL)
mkdir(path, 0777);
else
closedir(dir);
}

static void hddFindOPLPartition(void)
{
static config_set_t *config;
char name[64];
int fd, ret = 0;

fileXioUmount(hddPrefix);

ret = fileXioMount("pfs0:", "hdd0:__common", FIO_MT_RDWR);
if (ret == 0) {
fd = open("pfs0:OPL/conf_hdd.cfg", O_RDONLY);
if (fd >= 0) {
config = configAlloc(0, NULL, "pfs0:OPL/conf_hdd.cfg");
configRead(config);

configGetStrCopy(config, "hdd_partition", name, sizeof(name));
snprintf(gOPLPart, sizeof(gOPLPart), "hdd0:%s", name);

configFree(config);
close(fd);

fileXioUmount(hddPrefix);
return;
}

hddCheckOPLFolder(hddPrefix);

fd = open("pfs0:OPL/conf_hdd.cfg", O_CREAT | O_TRUNC | O_WRONLY);
if (fd >= 0) {
config = configAlloc(0, NULL, "pfs0:OPL/conf_hdd.cfg");
configRead(config);

configSetStr(config, "hdd_partition", "+OPL");
configWrite(config);

configFree(config);
close(fd);
}
}

snprintf(gOPLPart, sizeof(gOPLPart), "hdd0:+OPL");
fileXioUmount(hddPrefix);

return;
}

static int hddCreateOPLPartition(const char *name)
{
int formatArg[3] = {PFS_ZONE_SIZE, 0x2d66, PFS_FRAGMENT};
int fd, result;
char cmd[43];
char cmd[140];

sprintf(cmd, "%s,,,128M,PFS", oplPart);
sprintf(cmd, "%s,,,128M,PFS", name);
KrahJohlito marked this conversation as resolved.
Show resolved Hide resolved
if ((fd = open(cmd, O_CREAT | O_TRUNC | O_WRONLY)) >= 0) {
close(fd);
result = fileXioFormat(mountpoint, oplPart, (const char *)&formatArg, sizeof(formatArg));
result = fileXioFormat(hddPrefix, name, (const char *)&formatArg, sizeof(formatArg));
} else {
result = fd;
}
Expand Down Expand Up @@ -168,11 +228,18 @@ void hddLoadModules(void)

LOG("HDDSUPPORT modules loaded\n");

ret = fileXioMount(hddPrefix, oplPart, FIO_MT_RDWR);
hddFindOPLPartition();

ret = fileXioMount(hddPrefix, gOPLPart, FIO_MT_RDWR);
if (ret == -ENOENT) {
//Attempt to create the partition.
if ((CreateOPLPartition(oplPart, hddPrefix)) >= 0)
fileXioMount(hddPrefix, oplPart, FIO_MT_RDWR);
if ((hddCreateOPLPartition(gOPLPart)) >= 0)
fileXioMount(hddPrefix, gOPLPart, FIO_MT_RDWR);
}

if (gOPLPart[5] != '+') {
hddCheckOPLFolder(hddPrefix);
gHDDPrefix = "pfs0:OPL/";
AKuHAK marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down Expand Up @@ -279,7 +346,7 @@ static void hddLaunchGame(int id, config_set_t *configSet)
configGetVMC(configSet, vmc_name[1], sizeof(vmc_name[1]), 1);

if (vmc_name[0][0] || vmc_name[1][0]) {
nparts = hddGetPartitionInfo(oplPart, parts);
nparts = hddGetPartitionInfo(gOPLPart, parts);
if (nparts > 0 && nparts <= 5) {
for (i = 0; i < nparts; i++) {
hdd_vmc_infos.parts[i].start = parts[i].start;
Expand All @@ -301,15 +368,15 @@ static void hddLaunchGame(int id, config_set_t *configSet)
if (vmc_name[vmc_id][0]) {
have_error = 1;
hdd_vmc_infos.active = 0;
if (sysCheckVMC(hddPrefix, "/", vmc_name[vmc_id], 0, &vmc_superblock) > 0) {
if (sysCheckVMC(gHDDPrefix, "/", vmc_name[vmc_id], 0, &vmc_superblock) > 0) {
hdd_vmc_infos.flags = vmc_superblock.mc_flag & 0xFF;
hdd_vmc_infos.flags |= 0x100;
hdd_vmc_infos.specs.page_size = vmc_superblock.page_size;
hdd_vmc_infos.specs.block_size = vmc_superblock.pages_per_block;
hdd_vmc_infos.specs.card_size = vmc_superblock.pages_per_cluster * vmc_superblock.clusters_per_card;

// Check vmc inode block chain (write operation can cause damage)
snprintf(vmc_path, sizeof(vmc_path), "%sVMC/%s.bin", hddPrefix, vmc_name[vmc_id]);
snprintf(vmc_path, sizeof(vmc_path), "%sVMC/%s.bin", gHDDPrefix, vmc_name[vmc_id]);
if ((nparts = hddGetFileBlockInfo(vmc_path, parts, blocks, 11)) > 0) {
have_error = 0;
hdd_vmc_infos.active = 1;
Expand Down Expand Up @@ -380,7 +447,7 @@ static void hddLaunchGame(int id, config_set_t *configSet)

sbPrepare(NULL, configSet, size_irx, irx, &i);

if ((result = sbLoadCheats(hddPrefix, game->startup)) < 0) {
if ((result = sbLoadCheats(gHDDPrefix, game->startup)) < 0) {
switch (result) {
case -ENOENT:
guiWarning(_l(_STR_NO_CHEATS_FOUND), 10);
Expand Down Expand Up @@ -414,7 +481,7 @@ static config_set_t *hddGetConfig(int id)
char path[256];
hdl_game_info_t *game = &hddGames.games[id];

snprintf(path, sizeof(path), "%sCFG/%s.cfg", hddPrefix, game->startup);
snprintf(path, sizeof(path), "%sCFG/%s.cfg", gHDDPrefix, game->startup);
config_set_t *config = configAlloc(0, NULL, path);
configRead(config); //Does not matter if the config file exists or not.

Expand All @@ -431,7 +498,7 @@ static int hddGetImage(char *folder, int isRelative, char *value, char *suffix,
{
char path[256];
if (isRelative)
snprintf(path, sizeof(path), "%s%s/%s_%s", hddPrefix, folder, value, suffix);
snprintf(path, sizeof(path), "%s%s/%s_%s", gHDDPrefix, folder, value, suffix);
else
snprintf(path, sizeof(path), "%s%s_%s", folder, value, suffix);
return texDiscoverLoad(resultTex, path, -1, psm);
Expand Down Expand Up @@ -459,7 +526,7 @@ static void hddCleanUp(int exception)

static int hddCheckVMC(char *name, int createSize)
{
return sysCheckVMC(hddPrefix, "/", name, createSize, NULL);
return sysCheckVMC(gHDDPrefix, "/", name, createSize, NULL);
}

//This may be called, even if hddInit() was not.
Expand Down Expand Up @@ -500,7 +567,7 @@ static int hddLoadGameListCache(hdl_games_list_t *cache)

hddFreeHDLGamelist(cache);

sprintf(filename, "%s/games.bin", hddPrefix);
sprintf(filename, "%sgames.bin", gHDDPrefix);
file = fopen(filename, "rb");
if (file != NULL) {
fseek(file, 0, SEEK_END);
Expand Down Expand Up @@ -573,7 +640,7 @@ static int hddUpdateGameListCache(hdl_games_list_t *cache, hdl_games_list_t *gam
return 0;
LOG("hddUpdateGameListCache: caching new game list.\n");

sprintf(filename, "%s/games.bin", hddPrefix);
sprintf(filename, "%sgames.bin", gHDDPrefix);
if (game_list->count > 0) {
file = fopen(filename, "wb");
if (file != NULL) {
Expand All @@ -593,17 +660,17 @@ static int hddUpdateGameListCache(hdl_games_list_t *cache, hdl_games_list_t *gam

static void hddGetAppsPath(char *path, int max)
{
snprintf(path, max, "%s/APPS", hddPrefix);
snprintf(path, max, "%sAPPS", gHDDPrefix);
}

static void hddGetLegacyAppsPath(char *path, int max)
{
snprintf(path, max, "%sconf_apps.cfg", hddPrefix);
snprintf(path, max, "%sconf_apps.cfg", gHDDPrefix);
}

static void hddGetLegacyAppsInfo(char *path, int max, char *name)
{
snprintf(path, max, "%sCFG/%s.cfg", hddPrefix, name);
snprintf(path, max, "%sCFG/%s.cfg", gHDDPrefix, name);
}

static item_list_t hddGameList = {
Expand Down
15 changes: 10 additions & 5 deletions src/opl.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ static opl_io_module_t list_support[MODE_COUNT];

// Global data
char *gBaseMCDir;
char *gHDDPrefix;
int ps2_ip_use_dhcp;
int ps2_ip[4];
int ps2_netmask[4];
Expand Down Expand Up @@ -723,13 +724,16 @@ static int checkLoadConfigBDM(int types)
static int checkLoadConfigHDD(int types)
{
int value;
char path[64];

hddLoadModules();
value = open("pfs0:conf_opl.cfg", O_RDONLY);

snprintf(path, sizeof(path), "%sconf_opl.cfg", gHDDPrefix);
value = open(path, O_RDONLY);
if (value >= 0) {
close(value);
configEnd();
configInit("pfs0:");
configInit(gHDDPrefix);
value = configReadMulti(types);
config_set_t *configOPL = configGetByType(CONFIG_OPL);
configSetInt(configOPL, CONFIG_OPL_HDD_MODE, START_MODE_AUTO);
Expand Down Expand Up @@ -781,11 +785,11 @@ static int tryAlternateDevice(int types)
configInit("mass0:");
} else {
// No? Check if the save location on the HDD is available.
dir = opendir("pfs0:");
dir = opendir(gHDDPrefix);
if (dir != NULL) {
closedir(dir);
configEnd();
configInit("pfs0:");
configInit(gHDDPrefix);
}
}
showCfgPopup = 0;
Expand Down Expand Up @@ -912,7 +916,7 @@ static int trySaveConfigHDD(int types)
hddLoadModules();
//Check that the formatted & usable HDD is connected.
if (hddCheck() == 0) {
configSetMove("pfs0:");
configSetMove(gHDDPrefix);
return configWriteMulti(types);
}

Expand Down Expand Up @@ -1525,6 +1529,7 @@ static void setDefaults(void)
clearIOModuleT(&list_support[APP_MODE]);

gBaseMCDir = "mc?:OPL";
gHDDPrefix = "pfs0:";

ps2_ip_use_dhcp = 1;
gETHOpMode = ETH_OP_MODE_AUTO;
Expand Down
13 changes: 11 additions & 2 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "include/opl.h"
#include "include/gui.h"
#include "include/ethsupport.h"
#include "include/hddsupport.h"
#include "include/util.h"
#include "include/pad.h"
#include "include/system.h"
Expand Down Expand Up @@ -858,7 +859,9 @@ int sysExecElf(const char *path)
elf_pheader_t *eph;
void *pdata;
int i;
char *elf_argv[1];
char *elf_argv[2];
char argv[256];
int elf_argc = 1;

// NB: ELFLDR.ELF is embedded
boot_elf = (u8 *)&elfldr_elf;
Expand Down Expand Up @@ -888,10 +891,16 @@ int sysExecElf(const char *path)

elf_argv[0] = (char *)path;

if (strncmp(path, "pfs", 3) == 0) {
snprintf(argv, sizeof(argv), "%s:%s", gOPLPart, elf_argv[0]);
elf_argv[1] = argv;
elf_argc++;
}

FlushCache(0);
FlushCache(2);

ExecPS2((void *)eh->entry, NULL, 1, elf_argv);
ExecPS2((void *)eh->entry, NULL, elf_argc, elf_argv);

return 0;
}
Expand Down