[PS2] CDFS Improvements
This commit is contained in:
parent
88ea33bbd2
commit
b1846ee449
|
@ -27,6 +27,7 @@
|
||||||
#include <libmtap.h>
|
#include <libmtap.h>
|
||||||
#include <audsrv.h>
|
#include <audsrv.h>
|
||||||
#include <libpad.h>
|
#include <libpad.h>
|
||||||
|
#include <libcdvd-common.h>
|
||||||
#include <cdvd_rpc.h>
|
#include <cdvd_rpc.h>
|
||||||
#include <fileXio_cdvd.h>
|
#include <fileXio_cdvd.h>
|
||||||
#include <ps2_devices.h>
|
#include <ps2_devices.h>
|
||||||
|
@ -208,12 +209,11 @@ static void frontend_ps2_init(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initializes CDVD library */
|
/* Initializes CDVD library */
|
||||||
|
/* SCECdINoD init without check for a disc. Reduces risk of a lockup if the drive is in a erroneous state. */
|
||||||
|
sceCdInit(SCECdINoD);
|
||||||
if (CDVD_Init() != 1) {
|
if (CDVD_Init() != 1) {
|
||||||
RARCH_ERR("CDVD_Init library not initalizated\n");
|
RARCH_ERR("CDVD_Init library not initalizated\n");
|
||||||
}
|
}
|
||||||
if (cdInit(CDVD_INIT_INIT) != 1) {
|
|
||||||
RARCH_ERR("cdInit library not initalizated\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
_init_ps2_io();
|
_init_ps2_io();
|
||||||
|
|
||||||
|
@ -236,7 +236,6 @@ static void frontend_ps2_deinit(void *data)
|
||||||
command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL);
|
command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL);
|
||||||
#endif
|
#endif
|
||||||
_free_ps2_io();
|
_free_ps2_io();
|
||||||
cdInit(CDVD_INIT_EXIT);
|
|
||||||
CDVD_Stop();
|
CDVD_Stop();
|
||||||
padEnd();
|
padEnd();
|
||||||
audsrv_quit();
|
audsrv_quit();
|
||||||
|
|
|
@ -2,168 +2,79 @@
|
||||||
#include <tamtypes.h>
|
#include <tamtypes.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sifrpc.h>
|
#include <sifrpc.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <cdvd_rpc.h>
|
#include <cdvd_rpc.h>
|
||||||
#include <fileXio_cdvd.h>
|
#include <fileXio_cdvd.h>
|
||||||
|
#include <libcdvd-common.h>
|
||||||
#include "ps2_devices.h"
|
#include "ps2_devices.h"
|
||||||
#include "ps2_descriptor.h"
|
#include "ps2_descriptor.h"
|
||||||
|
|
||||||
#define CD_SERVER_INIT 0x80000592
|
/* I dont know why but this line is totally needed */
|
||||||
#define CD_SERVER_SCMD 0x80000593
|
|
||||||
#define CD_SCMD_GETDISCTYPE 0x03
|
|
||||||
|
|
||||||
static SifRpcClientData_t clientInit __attribute__ ((aligned(64)));
|
static SifRpcClientData_t clientInit __attribute__ ((aligned(64)));
|
||||||
static u32 initMode __attribute__ ((aligned(64)));
|
|
||||||
static int cdThreadId = 0;
|
|
||||||
static int bindSearchFile = -1;
|
|
||||||
static int bindDiskReady = -1;
|
|
||||||
static int bindInit = -1;
|
|
||||||
static int bindNCmd = -1;
|
|
||||||
static int bindSCmd = -1;
|
|
||||||
static int nCmdSemaId = -1; // n-cmd semaphore id
|
|
||||||
static int sCmdSemaId = -1; // s-cmd semaphore id
|
|
||||||
static int callbackSemaId = -1; // callback semaphore id
|
|
||||||
static int cdDebug = 0;
|
|
||||||
static int sCmdNum = 0;
|
|
||||||
static SifRpcClientData_t clientSCmd __attribute__ ((aligned(64)));
|
|
||||||
static u8 sCmdRecvBuff[48] __attribute__ ((aligned(64)));
|
|
||||||
static volatile int cbSema = 0;
|
|
||||||
static ee_thread_status_t cdThreadParam;
|
|
||||||
static int callbackThreadId = 0;
|
|
||||||
volatile int cdCallbackNum __attribute__ ((aligned(64)));
|
|
||||||
|
|
||||||
static void cdSemaInit(void);
|
|
||||||
static int cdCheckSCmd(int cur_cmd);
|
|
||||||
static int cdSyncS(int mode);
|
|
||||||
static void cdSemaExit(void);
|
|
||||||
|
|
||||||
static int first_file_index;
|
|
||||||
|
|
||||||
int cdInit(int mode)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (cdSyncS(1))
|
|
||||||
return 0;
|
|
||||||
SifInitRpc(0);
|
|
||||||
cdThreadId = GetThreadId();
|
|
||||||
bindSearchFile = -1;
|
|
||||||
bindNCmd = -1;
|
|
||||||
bindSCmd = -1;
|
|
||||||
bindDiskReady = -1;
|
|
||||||
bindInit = -1;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (SifBindRpc(&clientInit, CD_SERVER_INIT, 0) >= 0)
|
|
||||||
if (clientInit.server != 0) break;
|
|
||||||
i = 0x10000;
|
|
||||||
while (i--);
|
|
||||||
}
|
|
||||||
|
|
||||||
bindInit = 0;
|
|
||||||
initMode = mode;
|
|
||||||
SifWriteBackDCache(&initMode, 4);
|
|
||||||
if (SifCallRpc(&clientInit, 0, 0, &initMode, 4, 0, 0, 0, 0) < 0)
|
|
||||||
return 0;
|
|
||||||
if (mode == CDVD_INIT_EXIT) {
|
|
||||||
cdSemaExit();
|
|
||||||
nCmdSemaId = -1;
|
|
||||||
sCmdSemaId = -1;
|
|
||||||
callbackSemaId = -1;
|
|
||||||
} else {
|
|
||||||
cdSemaInit();
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cdSemaExit(void)
|
|
||||||
{
|
|
||||||
if (callbackThreadId) {
|
|
||||||
cdCallbackNum = -1;
|
|
||||||
SignalSema(callbackSemaId);
|
|
||||||
}
|
|
||||||
DeleteSema(nCmdSemaId);
|
|
||||||
DeleteSema(sCmdSemaId);
|
|
||||||
DeleteSema(callbackSemaId);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cdSemaInit(void)
|
|
||||||
{
|
|
||||||
struct t_ee_sema semaParam;
|
|
||||||
|
|
||||||
// return if both semaphores are already inited
|
|
||||||
if (nCmdSemaId != -1 && sCmdSemaId != -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
semaParam.init_count = 1;
|
|
||||||
semaParam.max_count = 1;
|
|
||||||
semaParam.option = 0;
|
|
||||||
nCmdSemaId = CreateSema(&semaParam);
|
|
||||||
sCmdSemaId = CreateSema(&semaParam);
|
|
||||||
|
|
||||||
semaParam.init_count = 0;
|
|
||||||
callbackSemaId = CreateSema(&semaParam);
|
|
||||||
|
|
||||||
cbSema = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cdCheckSCmd(int cur_cmd)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
cdSemaInit();
|
|
||||||
if (PollSema(sCmdSemaId) != sCmdSemaId) {
|
|
||||||
if (cdDebug > 0)
|
|
||||||
printf("Scmd fail sema cur_cmd:%d keep_cmd:%d\n", cur_cmd, sCmdNum);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
sCmdNum = cur_cmd;
|
|
||||||
ReferThreadStatus(cdThreadId, &cdThreadParam);
|
|
||||||
if (cdSyncS(1)) {
|
|
||||||
SignalSema(sCmdSemaId);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SifInitRpc(0);
|
|
||||||
if (bindSCmd >= 0)
|
|
||||||
return 1;
|
|
||||||
while (1) {
|
|
||||||
if (SifBindRpc(&clientSCmd, CD_SERVER_SCMD, 0) < 0) {
|
|
||||||
if (cdDebug > 0)
|
|
||||||
printf("Libcdvd bind err S cmd\n");
|
|
||||||
}
|
|
||||||
if (clientSCmd.server != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
i = 0x10000;
|
|
||||||
while (i--)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
bindSCmd = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cdSyncS(int mode)
|
|
||||||
{
|
|
||||||
if (mode == 0) {
|
|
||||||
if (cdDebug > 0)
|
|
||||||
printf("S cmd wait\n");
|
|
||||||
while (SifCheckStatRpc(&clientSCmd))
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return SifCheckStatRpc(&clientSCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int comp_entries_by_filename(const void *elem1, const void *elem2)
|
static int comp_entries_by_filename(const void *elem1, const void *elem2)
|
||||||
{
|
{
|
||||||
return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename);
|
return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char* strzncpy(char *d, const char *s, size_t l)
|
static int ps2_cdDiscValid(void) //returns 1 if disc valid, else returns 0
|
||||||
{
|
{
|
||||||
d[0] = 0; return strncat(d, s, l);
|
int cdmode = sceCdGetDiskType();
|
||||||
|
|
||||||
|
switch (cdmode) {
|
||||||
|
case SCECdPSCD:
|
||||||
|
case SCECdPSCDDA:
|
||||||
|
case SCECdPS2CD:
|
||||||
|
case SCECdPS2CDDA:
|
||||||
|
case SCECdPS2DVD:
|
||||||
|
case SCECdCDDA:
|
||||||
|
case SCECdDVDV:
|
||||||
|
return 1;
|
||||||
|
case SCECdNODISC:
|
||||||
|
case SCECdDETCT:
|
||||||
|
case SCECdDETCTCD:
|
||||||
|
case SCECdDETCTDVDS:
|
||||||
|
case SCECdDETCTDVDD:
|
||||||
|
case SCECdUNKNOWN:
|
||||||
|
case SCECdIllegalMedia:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 cd_Timer(void)
|
||||||
|
{
|
||||||
|
return (clock() / (CLOCKS_PER_SEC / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ps2_cdStop(void)
|
||||||
|
{
|
||||||
|
CDVD_Stop();
|
||||||
|
sceCdSync(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prepareCDVD(void)
|
||||||
|
{
|
||||||
|
u64 wait_start;
|
||||||
|
int cdmode = sceCdGetDiskType();
|
||||||
|
|
||||||
|
if (sceCdGetDiskType() <= SCECdUNKNOWN) {
|
||||||
|
wait_start = cd_Timer();
|
||||||
|
while ((cd_Timer() < wait_start + 500) && !ps2_cdDiscValid()) {
|
||||||
|
if (cdmode == SCECdNODISC)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (cdmode == SCECdNODISC)
|
||||||
|
return 0;
|
||||||
|
if ((cdmode < SCECdPSCD) || (cdmode > SCECdPS2DVD)) {
|
||||||
|
ps2_cdStop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int listcdvd(const char *path, entries *FileEntry)
|
static int listcdvd(const char *path, entries *FileEntry)
|
||||||
|
@ -172,6 +83,7 @@ static int listcdvd(const char *path, entries *FileEntry)
|
||||||
char dir[1025];
|
char dir[1025];
|
||||||
int i, n;
|
int i, n;
|
||||||
int t = 0;
|
int t = 0;
|
||||||
|
int first_file_index;
|
||||||
|
|
||||||
strcpy(dir, &path[5]);
|
strcpy(dir, &path[5]);
|
||||||
// Directories first...
|
// Directories first...
|
||||||
|
@ -187,7 +99,6 @@ static int listcdvd(const char *path, entries *FileEntry)
|
||||||
|
|
||||||
FileEntry[t].dircheck = 1;
|
FileEntry[t].dircheck = 1;
|
||||||
strcpy(FileEntry[t].filename, TocEntryList[i].filename);
|
strcpy(FileEntry[t].filename, TocEntryList[i].filename);
|
||||||
strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63);
|
|
||||||
t++;
|
t++;
|
||||||
|
|
||||||
if (t >= FILEENTRY_SIZE - 2) {
|
if (t >= FILEENTRY_SIZE - 2) {
|
||||||
|
@ -211,7 +122,6 @@ static int listcdvd(const char *path, entries *FileEntry)
|
||||||
|
|
||||||
FileEntry[t].dircheck = 0;
|
FileEntry[t].dircheck = 0;
|
||||||
strcpy(FileEntry[t].filename, TocEntryList[i].filename);
|
strcpy(FileEntry[t].filename, TocEntryList[i].filename);
|
||||||
strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63);
|
|
||||||
t++;
|
t++;
|
||||||
|
|
||||||
if (t >= FILEENTRY_SIZE - 2) {
|
if (t >= FILEENTRY_SIZE - 2) {
|
||||||
|
@ -227,15 +137,13 @@ static int listcdvd(const char *path, entries *FileEntry)
|
||||||
static int fileXioCDDread(int fd, iox_dirent_t *dirent)
|
static int fileXioCDDread(int fd, iox_dirent_t *dirent)
|
||||||
{
|
{
|
||||||
DescriptorTranslation *descriptor = __ps2_fd_grab(fd);
|
DescriptorTranslation *descriptor = __ps2_fd_grab(fd);
|
||||||
if (descriptor->current_folder_position == -1) {
|
|
||||||
descriptor->current_folder_position = 0;
|
|
||||||
descriptor->items = listcdvd(descriptor->path, descriptor->FileEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptor->current_folder_position < descriptor->items) {
|
if (descriptor && descriptor->current_folder_position < descriptor->items) {
|
||||||
strcpy(dirent->name, descriptor->FileEntry[descriptor->current_folder_position].filename);
|
strcpy(dirent->name, descriptor->FileEntry[descriptor->current_folder_position].filename);
|
||||||
if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) {
|
if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) {
|
||||||
dirent->stat.mode = FIO_S_IFDIR;
|
dirent->stat.mode = FIO_S_IFDIR;
|
||||||
|
} else {
|
||||||
|
dirent->stat.mode = FIO_S_IFREG;
|
||||||
}
|
}
|
||||||
descriptor->current_folder_position++;
|
descriptor->current_folder_position++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,14 +154,25 @@ static int fileXioCDDread(int fd, iox_dirent_t *dirent)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fileXioCDDopen(const char *name)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
if (prepareCDVD()){
|
||||||
|
fd = __ps2_acquire_descriptor();
|
||||||
|
DescriptorTranslation *descriptor = __ps2_fd_grab(fd);
|
||||||
|
descriptor->current_folder_position = 0;
|
||||||
|
descriptor->items = listcdvd(name, descriptor->FileEntry);
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ps2fileXioDopen(const char *name)
|
int ps2fileXioDopen(const char *name)
|
||||||
{
|
{
|
||||||
enum BootDeviceIDs deviceID = getBootDeviceID((char *)name);
|
enum BootDeviceIDs deviceID = getBootDeviceID((char *)name);
|
||||||
int fd;
|
int fd = -1;
|
||||||
if (deviceID == BOOT_DEVICE_CDFS) {
|
if (deviceID == BOOT_DEVICE_CDFS) {
|
||||||
fd = __ps2_acquire_descriptor();
|
fd = fileXioCDDopen(name);
|
||||||
DescriptorTranslation *descriptor = __ps2_fd_grab(fd);
|
|
||||||
strcpy(descriptor->path, name);
|
|
||||||
} else {
|
} else {
|
||||||
fd = fileXioDopen(name);
|
fd = fileXioDopen(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ static int __ps2_fd_drop(DescriptorTranslation *map)
|
||||||
if (map->ref_count == 1)
|
if (map->ref_count == 1)
|
||||||
{
|
{
|
||||||
map->ref_count--;
|
map->ref_count--;
|
||||||
|
map->current_folder_position = -1;
|
||||||
free(map->FileEntry);
|
free(map->FileEntry);
|
||||||
memset(map, 0, sizeof(DescriptorTranslation));
|
memset(map, 0, sizeof(DescriptorTranslation));
|
||||||
}
|
}
|
||||||
|
@ -57,7 +58,7 @@ int is_fd_valid(int fd)
|
||||||
/* Correct fd value */
|
/* Correct fd value */
|
||||||
fd = MAX_OPEN_FILES - fd;
|
fd = MAX_OPEN_FILES - fd;
|
||||||
|
|
||||||
return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL);
|
return (fd >= 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _init_ps2_io(void) {
|
void _init_ps2_io(void) {
|
||||||
|
|
|
@ -22,14 +22,12 @@
|
||||||
#define FILEENTRY_SIZE 2048
|
#define FILEENTRY_SIZE 2048
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char displayname[64];
|
int dircheck;
|
||||||
int dircheck;
|
char filename[256];
|
||||||
char filename[256];
|
|
||||||
} entries;
|
} entries;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char path[256];
|
|
||||||
int ref_count;
|
int ref_count;
|
||||||
int items;
|
int items;
|
||||||
int current_folder_position;
|
int current_folder_position;
|
||||||
|
|
Loading…
Reference in New Issue