mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
Implement CDFS and custom file descriptor support
This commit is contained in:
parent
da86549b8e
commit
adf2743464
16
Makefile.ps2
16
Makefile.ps2
@ -5,12 +5,15 @@ HAVE_LOGGER = 0
|
||||
HAVE_FILE_LOGGER = 0
|
||||
HAVE_THREADS = 0
|
||||
BIG_STACK = 0
|
||||
MUTE_WARNINGS = 0
|
||||
MUTE_WARNINGS = 1
|
||||
PS2_IP = 192.168.1.150
|
||||
|
||||
TARGET = retroarchps2.elf
|
||||
TARGET_RELEASE = retroarchps2-release.elf
|
||||
|
||||
# Lib CDVD
|
||||
CDVD_DIR = ps2/libcdvd
|
||||
|
||||
# Compile the IRXs first
|
||||
IRX_DIR = ps2/irx
|
||||
IRX_FILES = $(wildcard ps2/irx/*.c)
|
||||
@ -27,7 +30,7 @@ ifeq ($(MUTE_WARNINGS), 1)
|
||||
DISABLE_WARNINGS := -Wno-sign-compare -Wno-unused -Wno-parentheses
|
||||
endif
|
||||
|
||||
INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include
|
||||
INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include -I$(CDVD_DIR)/ee
|
||||
INCDIR += -Ips2 -Ips2/include -Ilibretro-common/include
|
||||
INCDIR += -Ideps -Ideps/stb -Ideps/libz -Ideps/7zip -Ideps/pthreads -Ideps/pthreads/platform/ps2 -Ideps/pthreads/platform/helper
|
||||
GPVAL = -G0
|
||||
@ -38,8 +41,9 @@ RARCH_DEFINES += -DPS2 -DUSE_IOP_CTYPE_MACRO -D_MIPS_ARCH_R5900 -DHAVE_ZLIB -DHA
|
||||
RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER
|
||||
|
||||
LIBDIR =
|
||||
LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L.
|
||||
LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio -lpatches -lpoweroff
|
||||
LDFLAGS += -L$(PS2SDK)/ports/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ee/lib -L$(CDVD_DIR)/lib -L.
|
||||
LIBS += -lretro_ps2 -lgskit -ldmakit -lgskit_toolkit -laudsrv -lmf -lpadx -lmtap -lmc -lhdd -lsdl -lfileXio
|
||||
LIBS += -lcdvdfs -lpatches -lpoweroff
|
||||
|
||||
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
@ -64,9 +68,11 @@ CFLAGS += $(RARCH_DEFINES)
|
||||
EE_OBJS += $(IRX_DIR)/freemtap_irx.o $(IRX_DIR)/freepad_irx.o $(IRX_DIR)/freesio2_irx.o $(IRX_DIR)/iomanX_irx.o
|
||||
EE_OBJS += $(IRX_DIR)/fileXio_irx.o $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o $(IRX_DIR)/usbd_irx.o
|
||||
EE_OBJS += $(IRX_DIR)/usbhdfsd_irx.o $(IRX_DIR)/freesd_irx.o $(IRX_DIR)/audsrv_irx.o $(IRX_DIR)/poweroff_irx.o
|
||||
EE_OBJS += $(IRX_DIR)/cdvd_irx.o
|
||||
|
||||
# Missing objecst on the PS2SDK
|
||||
EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o
|
||||
EE_OBJS += ps2/compat_files/compat_ctype.o ps2/compat_files/time.o ps2/compat_files/ps2_devices.o
|
||||
EE_OBJS += ps2/compat_files/cd.o ps2/compat_files/ps2_hashtable.o ps2/compat_files/murmur3.o ps2/compat_files/ps2_descriptor.o
|
||||
|
||||
#EE_OBJS = griffin/griffin.o bootstrap/ps2/kernel_functions.o
|
||||
EE_OBJS += griffin/griffin.o
|
||||
|
@ -27,8 +27,11 @@
|
||||
#include <libmtap.h>
|
||||
#include <audsrv.h>
|
||||
#include <libpad.h>
|
||||
#include <cdvd_rpc.h>
|
||||
#include <cd.h>
|
||||
#include <ps2_devices.h>
|
||||
#include <ps2_irx_variables.h>
|
||||
#include <ps2_descriptor.h>
|
||||
|
||||
char eboot_path[512];
|
||||
char user_path[512];
|
||||
@ -180,6 +183,9 @@ static void frontend_ps2_init(void *data)
|
||||
SifExecModuleBuffer(&freesd_irx, size_freesd_irx, 0, NULL, NULL);
|
||||
SifExecModuleBuffer(&audsrv_irx, size_audsrv_irx, 0, NULL, NULL);
|
||||
|
||||
/* CDVD */
|
||||
SifExecModuleBuffer(&cdvd_irx, size_cdvd_irx, 0, NULL, NULL);
|
||||
|
||||
if (mcInit(MC_TYPE_XMC)) {
|
||||
RARCH_ERR("mcInit library not initalizated\n");
|
||||
}
|
||||
@ -201,6 +207,16 @@ static void frontend_ps2_init(void *data)
|
||||
RARCH_ERR("mtapPortOpen library not initalizated\n");
|
||||
}
|
||||
|
||||
/* Initializes CDVD library */
|
||||
if (CDVD_Init() != 1) {
|
||||
RARCH_ERR("CDVD_Init library not initalizated\n");
|
||||
}
|
||||
if (cdInit(CDVD_INIT_INIT) != 1) {
|
||||
RARCH_ERR("cdInit library not initalizated\n");
|
||||
}
|
||||
|
||||
_init_ps2_io();
|
||||
|
||||
/* Prepare device */
|
||||
getcwd(cwd, sizeof(cwd));
|
||||
bootDeviceID=getBootDeviceID(cwd);
|
||||
@ -219,6 +235,9 @@ static void frontend_ps2_deinit(void *data)
|
||||
verbosity_disable();
|
||||
command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL);
|
||||
#endif
|
||||
_free_ps2_io();
|
||||
cdInit(CDVD_INIT_EXIT);
|
||||
CDVD_Stop();
|
||||
padEnd();
|
||||
audsrv_quit();
|
||||
fileXioExit();
|
||||
@ -333,6 +352,11 @@ static int frontend_ps2_parse_drive_list(void *data, bool load_content)
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
menu_entries_append_enum(list,
|
||||
rootDevicePath(BOOT_DEVICE_CDFS),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
menu_entries_append_enum(list,
|
||||
rootDevicePath(BOOT_DEVICE_MASS),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
|
@ -172,7 +172,7 @@ static void prim_texture(GSGLOBAL *gsGlobal, GSTEXTURE *texture, int zPosition,
|
||||
GS_TEXT);
|
||||
}
|
||||
|
||||
static void clearVRAMIfNeeded(ps2_video_t *ps2, void *frame, int width, int height)
|
||||
static void clearVRAMIfNeeded(ps2_video_t *ps2, const void *frame, int width, int height)
|
||||
{
|
||||
if (!ps2->clearVRAM) {
|
||||
if(frame && frame != RETRO_HW_FRAME_BUFFER_VALID) {
|
||||
|
@ -68,6 +68,7 @@
|
||||
#if defined(PS2)
|
||||
#include <kernel.h>
|
||||
#include <timer.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(__PSL1GHT__)
|
||||
|
@ -166,7 +166,7 @@ typedef struct
|
||||
# endif
|
||||
# endif
|
||||
#elif PS2
|
||||
# define PRI_SIZET "lu"
|
||||
# define PRI_SIZET "u"
|
||||
#else
|
||||
# if (SIZE_MAX == 0xFFFF)
|
||||
# define PRI_SIZET "hu"
|
||||
|
@ -52,6 +52,7 @@
|
||||
# endif
|
||||
# if defined(PS2)
|
||||
# include <fileXio_rpc.h>
|
||||
# include <cd.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
@ -1045,7 +1046,7 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool i
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
rdir->directory = sceIoDopen(name);
|
||||
#elif defined(PS2)
|
||||
rdir->directory = fileXioDopen(name);
|
||||
rdir->directory = newfileXioDopen(name);
|
||||
#elif defined(_3DS)
|
||||
rdir->directory = !string_is_empty(name) ? opendir(name) : NULL;
|
||||
rdir->entry = NULL;
|
||||
@ -1088,7 +1089,7 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir)
|
||||
return (sceIoDread(rdir->directory, &rdir->entry) > 0);
|
||||
#elif defined(PS2)
|
||||
iox_dirent_t record;
|
||||
int ret = fileXioDread(rdir->directory, &record);
|
||||
int ret = newfileXioDread(rdir->directory, &record);
|
||||
rdir->entry = record;
|
||||
return ( ret > 0);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
@ -1186,7 +1187,7 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir)
|
||||
#elif defined(VITA) || defined(PSP)
|
||||
sceIoDclose(rdir->directory);
|
||||
#elif defined(PS2)
|
||||
fileXioDclose(rdir->directory);
|
||||
newfileXioDclose(rdir->directory);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
rdir->error = cellFsClosedir(rdir->directory);
|
||||
#elif defined(ORBIS)
|
||||
|
323
ps2/compat_files/cd.c
Normal file
323
ps2/compat_files/cd.c
Normal file
@ -0,0 +1,323 @@
|
||||
#include <stdio.h>
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
#include <string.h>
|
||||
#include <sifrpc.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <cdvd_rpc.h>
|
||||
//#include <SMS_CDVD.h>
|
||||
#include "cd.h"
|
||||
|
||||
#include "ps2_devices.h"
|
||||
#include "ps2_descriptor.h"
|
||||
|
||||
#define CD_SERVER_INIT 0x80000592
|
||||
#define CD_SERVER_SCMD 0x80000593
|
||||
#define CD_SCMD_GETDISCTYPE 0x03
|
||||
|
||||
static SifRpcClientData_t clientInit __attribute__ ((aligned(64)));
|
||||
static u32 initMode __attribute__ ((aligned(64)));
|
||||
static s32 cdThreadId = 0;
|
||||
static s32 bindSearchFile = -1;
|
||||
static s32 bindDiskReady = -1;
|
||||
static s32 bindInit = -1;
|
||||
static s32 bindNCmd = -1;
|
||||
static s32 bindSCmd = -1;
|
||||
static s32 nCmdSemaId = -1; // n-cmd semaphore id
|
||||
static s32 sCmdSemaId = -1; // s-cmd semaphore id
|
||||
static s32 callbackSemaId = -1; // callback semaphore id
|
||||
static s32 cdDebug = 0;
|
||||
static s32 sCmdNum = 0;
|
||||
static SifRpcClientData_t clientSCmd __attribute__ ((aligned(64)));
|
||||
static u8 sCmdRecvBuff[48] __attribute__ ((aligned(64)));
|
||||
static volatile s32 cbSema = 0;
|
||||
static ee_thread_status_t cdThreadParam;
|
||||
static s32 callbackThreadId = 0;
|
||||
volatile s32 cdCallbackNum __attribute__ ((aligned(64)));
|
||||
|
||||
static void cdSemaInit(void);
|
||||
static s32 cdCheckSCmd(s32 cur_cmd);
|
||||
static s32 cdSyncS(s32 mode);
|
||||
static void cdSemaExit(void);
|
||||
|
||||
s32 cdInit(s32 mode)
|
||||
{
|
||||
s32 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 s32 cdCheckSCmd(s32 cur_cmd)
|
||||
{
|
||||
s32 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 s32 cdSyncS(s32 mode)
|
||||
{
|
||||
if (mode == 0) {
|
||||
if (cdDebug > 0)
|
||||
printf("S cmd wait\n");
|
||||
while (SifCheckStatRpc(&clientSCmd))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
return SifCheckStatRpc(&clientSCmd);
|
||||
}
|
||||
|
||||
CdvdDiscType_t cdGetDiscType(void)
|
||||
{
|
||||
if (cdCheckSCmd(CD_SCMD_GETDISCTYPE) == 0)
|
||||
return 0;
|
||||
|
||||
if (SifCallRpc(&clientSCmd, CD_SCMD_GETDISCTYPE, 0, 0, 0, sCmdRecvBuff, 4, 0, 0) < 0) {
|
||||
SignalSema(sCmdSemaId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SignalSema(sCmdSemaId);
|
||||
return *(s32 *) UNCACHED_SEG(sCmdRecvBuff);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int first_file_index;
|
||||
|
||||
static int comp_entries_by_filename(const void *elem1, const void *elem2)
|
||||
{
|
||||
return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename);
|
||||
}
|
||||
|
||||
static inline char* strzncpy(char *d, const char *s, size_t l)
|
||||
{
|
||||
d[0] = 0; return strncat(d, s, l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int listcdvd(const char *path, entries *FileEntry)
|
||||
{
|
||||
static struct TocEntry TocEntryList[FILEENTRY_SIZE];
|
||||
char dir[1025];
|
||||
int i, n, t;
|
||||
|
||||
strcpy(dir, &path[5]);
|
||||
// Directories first...
|
||||
|
||||
CDVD_FlushCache();
|
||||
n = CDVD_GetDir(dir, NULL, CDVD_GET_DIRS_ONLY, TocEntryList, FILEENTRY_SIZE, dir);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (TocEntryList[i].fileProperties & 0x02 && (!strcmp(
|
||||
TocEntryList[i].filename, ".") || !strcmp(
|
||||
TocEntryList[i].filename, "..")))
|
||||
continue; // Skip pseudopaths "." and ".."
|
||||
|
||||
FileEntry[t].dircheck = 1;
|
||||
strcpy(FileEntry[t].filename, TocEntryList[i].filename);
|
||||
strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63);
|
||||
t++;
|
||||
|
||||
if (t >= FILEENTRY_SIZE - 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(FileEntry, t, sizeof(entries), comp_entries_by_filename);
|
||||
first_file_index = t;
|
||||
|
||||
// Now files only
|
||||
|
||||
CDVD_FlushCache();
|
||||
n = CDVD_GetDir(dir, NULL, CDVD_GET_FILES_ONLY, TocEntryList, FILEENTRY_SIZE, dir);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (TocEntryList[i].fileProperties & 0x02 && (!strcmp(
|
||||
TocEntryList[i].filename, ".") || !strcmp(
|
||||
TocEntryList[i].filename, "..")))
|
||||
continue; // Skip pseudopaths "." and ".."
|
||||
|
||||
FileEntry[t].dircheck = 0;
|
||||
strcpy(FileEntry[t].filename, TocEntryList[i].filename);
|
||||
strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63);
|
||||
t++;
|
||||
|
||||
if (t >= FILEENTRY_SIZE - 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(FileEntry + first_file_index, t - first_file_index, sizeof(entries), comp_entries_by_filename);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int fileXioCDDread(int fd, iox_dirent_t *dirent)
|
||||
{
|
||||
DescriptorTranslation *descriptor = __ps2_fd_grab(fd);
|
||||
if (descriptor->current_folder_position == -1) {
|
||||
descriptor->current_folder_position = 0;
|
||||
descriptor->items = listcdvd(descriptor->path, descriptor->FileEntry);
|
||||
printf("Items in cdfs %i\n", descriptor->items);
|
||||
}
|
||||
|
||||
if (descriptor->current_folder_position < descriptor->items) {
|
||||
strcpy(dirent->name, descriptor->FileEntry[descriptor->current_folder_position].filename);
|
||||
if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) {
|
||||
dirent->stat.mode = FIO_S_IFDIR;
|
||||
}
|
||||
printf("Reading files from CDVD %s\n", dirent->name);
|
||||
descriptor->current_folder_position++;
|
||||
} else {
|
||||
descriptor->current_folder_position = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int newfileXioDopen(const char *name)
|
||||
{
|
||||
enum BootDeviceIDs deviceID = getBootDeviceID(name);
|
||||
int fd;
|
||||
if (deviceID == BOOT_DEVICE_CDFS) {
|
||||
fd = __ps2_acquire_descriptor();
|
||||
DescriptorTranslation *descriptor = __ps2_fd_grab(fd);
|
||||
strcpy(descriptor->path, name);
|
||||
} else {
|
||||
fd = fileXioDopen(name);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int newfileXioDclose(int fd)
|
||||
{
|
||||
// if (is_fd_valid(fd)) {
|
||||
// int res = __ps2_release_descriptor(fd);
|
||||
// printf("Releassssinggggg %i\n", res);
|
||||
// return res;
|
||||
// } else {
|
||||
return fileXioDclose(fd);
|
||||
// }
|
||||
}
|
||||
|
||||
int newfileXioDread(int fd, iox_dirent_t *dirent)
|
||||
{
|
||||
if (is_fd_valid(fd)) {
|
||||
return fileXioCDDread(fd, dirent);
|
||||
} else {
|
||||
return fileXioDread(fd, dirent);
|
||||
}
|
||||
}
|
||||
|
||||
|
317
ps2/compat_files/murmur3.c
Executable file
317
ps2/compat_files/murmur3.c
Executable file
@ -0,0 +1,317 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
|
||||
// Note - The x86 and x64 versions do _not_ produce the same results, as the
|
||||
// algorithms are optimized for their respective platforms. You can still
|
||||
// compile and run any of them on any platform, but your performance with the
|
||||
// non-native version will be less than optimal.
|
||||
|
||||
#include "murmur3.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Platform-specific functions and macros
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#else
|
||||
#define FORCE_INLINE inline
|
||||
#endif
|
||||
|
||||
static FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r )
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r )
|
||||
{
|
||||
return (x << r) | (x >> (64 - r));
|
||||
}
|
||||
|
||||
#define ROTL32(x,y) rotl32(x,y)
|
||||
#define ROTL64(x,y) rotl64(x,y)
|
||||
|
||||
#define BIG_CONSTANT(x) (x##LLU)
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Block read - if your platform needs to do endian-swapping or can only
|
||||
handle aligned reads, do the conversion here
|
||||
*/
|
||||
|
||||
#define getblock(p, i) (p[i])
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Finalization mix - force all bits of a hash block to avalanche */
|
||||
|
||||
static FORCE_INLINE uint32_t fmix32 ( uint32_t h )
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/*----------*/
|
||||
|
||||
static FORCE_INLINE uint64_t fmix64 ( uint64_t k )
|
||||
{
|
||||
k ^= k >> 33;
|
||||
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
|
||||
k ^= k >> 33;
|
||||
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
|
||||
k ^= k >> 33;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
void MurmurHash3_x86_32( const void * key, int len,
|
||||
uint32_t seed, void * out )
|
||||
{
|
||||
const uint8_t * data = (const uint8_t*)key;
|
||||
const int nblocks = len / 4;
|
||||
int i;
|
||||
|
||||
uint32_t h1 = seed;
|
||||
|
||||
uint32_t c1 = 0xcc9e2d51;
|
||||
uint32_t c2 = 0x1b873593;
|
||||
|
||||
/*----------*/
|
||||
/* body */
|
||||
|
||||
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
|
||||
|
||||
for(i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = getblock(blocks,i);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL32(k1,15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = ROTL32(h1,13);
|
||||
h1 = h1*5+0xe6546b64;
|
||||
}
|
||||
|
||||
/*----------*/
|
||||
/* tail */
|
||||
|
||||
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
|
||||
|
||||
uint32_t k1 = 0;
|
||||
|
||||
switch(len & 3)
|
||||
{
|
||||
case 3: k1 ^= tail[2] << 16;
|
||||
case 2: k1 ^= tail[1] << 8;
|
||||
case 1: k1 ^= tail[0];
|
||||
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
};
|
||||
|
||||
/*----------*/
|
||||
/* finalization */
|
||||
|
||||
h1 ^= len;
|
||||
|
||||
h1 = fmix32(h1);
|
||||
|
||||
*(uint32_t*)out = h1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
void MurmurHash3_x86_128 ( const void * key, const int len,
|
||||
uint32_t seed, void * out )
|
||||
{
|
||||
const uint8_t * data = (const uint8_t*)key;
|
||||
const int nblocks = len / 16;
|
||||
int i;
|
||||
|
||||
uint32_t h1 = seed;
|
||||
uint32_t h2 = seed;
|
||||
uint32_t h3 = seed;
|
||||
uint32_t h4 = seed;
|
||||
|
||||
uint32_t c1 = 0x239b961b;
|
||||
uint32_t c2 = 0xab0e9789;
|
||||
uint32_t c3 = 0x38b34ae5;
|
||||
uint32_t c4 = 0xa1e38b93;
|
||||
|
||||
/*----------*/
|
||||
/* body */
|
||||
|
||||
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
|
||||
|
||||
for(i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = getblock(blocks,i*4+0);
|
||||
uint32_t k2 = getblock(blocks,i*4+1);
|
||||
uint32_t k3 = getblock(blocks,i*4+2);
|
||||
uint32_t k4 = getblock(blocks,i*4+3);
|
||||
|
||||
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
|
||||
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
|
||||
|
||||
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
||||
|
||||
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
|
||||
|
||||
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
||||
|
||||
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
|
||||
|
||||
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
||||
|
||||
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
|
||||
}
|
||||
|
||||
/*----------*/
|
||||
/* tail */
|
||||
|
||||
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
|
||||
|
||||
uint32_t k1 = 0;
|
||||
uint32_t k2 = 0;
|
||||
uint32_t k3 = 0;
|
||||
uint32_t k4 = 0;
|
||||
|
||||
switch(len & 15)
|
||||
{
|
||||
case 15: k4 ^= tail[14] << 16;
|
||||
case 14: k4 ^= tail[13] << 8;
|
||||
case 13: k4 ^= tail[12] << 0;
|
||||
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
||||
|
||||
case 12: k3 ^= tail[11] << 24;
|
||||
case 11: k3 ^= tail[10] << 16;
|
||||
case 10: k3 ^= tail[ 9] << 8;
|
||||
case 9: k3 ^= tail[ 8] << 0;
|
||||
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
||||
|
||||
case 8: k2 ^= tail[ 7] << 24;
|
||||
case 7: k2 ^= tail[ 6] << 16;
|
||||
case 6: k2 ^= tail[ 5] << 8;
|
||||
case 5: k2 ^= tail[ 4] << 0;
|
||||
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
||||
|
||||
case 4: k1 ^= tail[ 3] << 24;
|
||||
case 3: k1 ^= tail[ 2] << 16;
|
||||
case 2: k1 ^= tail[ 1] << 8;
|
||||
case 1: k1 ^= tail[ 0] << 0;
|
||||
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
};
|
||||
|
||||
/*----------*/
|
||||
/* finalization */
|
||||
|
||||
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
|
||||
|
||||
h1 += h2; h1 += h3; h1 += h4;
|
||||
h2 += h1; h3 += h1; h4 += h1;
|
||||
|
||||
h1 = fmix32(h1);
|
||||
h2 = fmix32(h2);
|
||||
h3 = fmix32(h3);
|
||||
h4 = fmix32(h4);
|
||||
|
||||
h1 += h2; h1 += h3; h1 += h4;
|
||||
h2 += h1; h3 += h1; h4 += h1;
|
||||
|
||||
((uint32_t*)out)[0] = h1;
|
||||
((uint32_t*)out)[1] = h2;
|
||||
((uint32_t*)out)[2] = h3;
|
||||
((uint32_t*)out)[3] = h4;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
void MurmurHash3_x64_128( const void * key, const int len,
|
||||
const uint32_t seed, void * out )
|
||||
{
|
||||
const uint8_t * data = (const uint8_t*)key;
|
||||
const int nblocks = len / 16;
|
||||
int i;
|
||||
|
||||
uint64_t h1 = seed;
|
||||
uint64_t h2 = seed;
|
||||
|
||||
uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
|
||||
uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
|
||||
|
||||
/*----------*/
|
||||
/* body */
|
||||
|
||||
const uint64_t * blocks = (const uint64_t *)(data);
|
||||
|
||||
for(i = 0; i < nblocks; i++)
|
||||
{
|
||||
uint64_t k1 = getblock(blocks,i*2+0);
|
||||
uint64_t k2 = getblock(blocks,i*2+1);
|
||||
|
||||
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
|
||||
h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
|
||||
|
||||
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
|
||||
h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
|
||||
}
|
||||
|
||||
/*----------*/
|
||||
/* tail */
|
||||
|
||||
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
|
||||
|
||||
uint64_t k1 = 0;
|
||||
uint64_t k2 = 0;
|
||||
|
||||
switch(len & 15)
|
||||
{
|
||||
case 15: k2 ^= (uint64_t)(tail[14]) << 48;
|
||||
case 14: k2 ^= (uint64_t)(tail[13]) << 40;
|
||||
case 13: k2 ^= (uint64_t)(tail[12]) << 32;
|
||||
case 12: k2 ^= (uint64_t)(tail[11]) << 24;
|
||||
case 11: k2 ^= (uint64_t)(tail[10]) << 16;
|
||||
case 10: k2 ^= (uint64_t)(tail[ 9]) << 8;
|
||||
case 9: k2 ^= (uint64_t)(tail[ 8]) << 0;
|
||||
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
|
||||
case 8: k1 ^= (uint64_t)(tail[ 7]) << 56;
|
||||
case 7: k1 ^= (uint64_t)(tail[ 6]) << 48;
|
||||
case 6: k1 ^= (uint64_t)(tail[ 5]) << 40;
|
||||
case 5: k1 ^= (uint64_t)(tail[ 4]) << 32;
|
||||
case 4: k1 ^= (uint64_t)(tail[ 3]) << 24;
|
||||
case 3: k1 ^= (uint64_t)(tail[ 2]) << 16;
|
||||
case 2: k1 ^= (uint64_t)(tail[ 1]) << 8;
|
||||
case 1: k1 ^= (uint64_t)(tail[ 0]) << 0;
|
||||
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
};
|
||||
|
||||
/*----------*/
|
||||
/* finalization */
|
||||
|
||||
h1 ^= len; h2 ^= len;
|
||||
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
h1 = fmix64(h1);
|
||||
h2 = fmix64(h2);
|
||||
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
((uint64_t*)out)[0] = h1;
|
||||
((uint64_t*)out)[1] = h2;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
189
ps2/compat_files/ps2_descriptor.c
Normal file
189
ps2/compat_files/ps2_descriptor.c
Normal file
@ -0,0 +1,189 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* * You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ps2_descriptor.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
#include <string.h>
|
||||
#include <fileXio_rpc.h>
|
||||
|
||||
#define SCE_ERRNO_MASK 0xFF
|
||||
|
||||
DescriptorTranslation *__ps2_fdmap[MAX_OPEN_FILES];
|
||||
DescriptorTranslation __ps2_fdmap_pool[MAX_OPEN_FILES];
|
||||
|
||||
static int _lock_sema_id = -1;
|
||||
static inline int _lock(void)
|
||||
{
|
||||
return(WaitSema(_lock_sema_id));
|
||||
}
|
||||
|
||||
static inline int _unlock(void)
|
||||
{
|
||||
return(SignalSema(_lock_sema_id));
|
||||
}
|
||||
|
||||
void _init_ps2_io(void) {
|
||||
int ret;
|
||||
ee_sema_t sp;
|
||||
|
||||
memset(__ps2_fdmap, 0, sizeof(__ps2_fdmap));
|
||||
memset(__ps2_fdmap_pool, 0, sizeof(__ps2_fdmap_pool));
|
||||
|
||||
sp.init_count = 1;
|
||||
sp.max_count = 1;
|
||||
sp.option = 0;
|
||||
_lock_sema_id = CreateSema(&sp);
|
||||
|
||||
}
|
||||
|
||||
void _free_ps2_io(void) {
|
||||
_lock();
|
||||
_unlock();
|
||||
if(_lock_sema_id >= 0) DeleteSema(_lock_sema_id);
|
||||
}
|
||||
|
||||
int __ps2_acquire_descriptor(void)
|
||||
{
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
_lock();
|
||||
|
||||
// get free descriptor
|
||||
// only allocate descriptors after stdin/stdout/stderr -> aka 0/1/2
|
||||
for (fd = 1; fd < MAX_OPEN_FILES; ++fd)
|
||||
{
|
||||
if (__ps2_fdmap[fd] == NULL)
|
||||
{
|
||||
// get free pool
|
||||
for (i = 0; i < MAX_OPEN_FILES; ++i)
|
||||
{
|
||||
if (__ps2_fdmap_pool[i].ref_count == 0)
|
||||
{
|
||||
__ps2_fdmap[fd] = &__ps2_fdmap_pool[i];
|
||||
__ps2_fdmap[fd]->ref_count = 1;
|
||||
__ps2_fdmap[fd]->current_folder_position = -1;
|
||||
__ps2_fdmap[fd]->FileEntry = calloc(sizeof(entries), FILEENTRY_SIZE);
|
||||
_unlock();
|
||||
return MAX_OPEN_FILES - fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // no mores descriptors available...
|
||||
_unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __ps2_release_descriptor(int fd)
|
||||
{
|
||||
DescriptorTranslation *map = NULL;
|
||||
int res = -1;
|
||||
|
||||
_lock();
|
||||
|
||||
if (is_fd_valid(fd) && __ps2_fd_drop(__ps2_fdmap[MAX_OPEN_FILES - fd]) >= 0)
|
||||
{
|
||||
/* Correct fd value */
|
||||
fd = MAX_OPEN_FILES - fd;
|
||||
free(__ps2_fdmap[fd]->FileEntry);
|
||||
__ps2_fdmap[fd] = NULL;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
_unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
int __ps2_duplicate_descriptor(int fd)
|
||||
{
|
||||
int fd2 = -1;
|
||||
|
||||
_lock();
|
||||
|
||||
if (is_fd_valid(fd))
|
||||
{
|
||||
/* Correct fd value */
|
||||
fd = MAX_OPEN_FILES - fd;
|
||||
// get free descriptor
|
||||
// only allocate descriptors after stdin/stdout/stderr -> aka 0/1/2
|
||||
for (fd2 = 0; fd2 < MAX_OPEN_FILES; ++fd2)
|
||||
{
|
||||
if (__ps2_fdmap[fd2] == NULL)
|
||||
{
|
||||
__ps2_fdmap[fd2] = __ps2_fdmap[fd];
|
||||
__ps2_fdmap[fd2]->ref_count++;
|
||||
_unlock();
|
||||
return fd2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_unlock();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int __ps2_descriptor_ref_count(int fd)
|
||||
{
|
||||
int res = 0;
|
||||
/* Correct fd value */
|
||||
fd = MAX_OPEN_FILES - fd;
|
||||
|
||||
_lock();
|
||||
res = __ps2_fdmap[fd]->ref_count;
|
||||
_unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
DescriptorTranslation *__ps2_fd_grab(int fd)
|
||||
{
|
||||
DescriptorTranslation *map = NULL;
|
||||
|
||||
_lock();
|
||||
|
||||
if (is_fd_valid(fd))
|
||||
{
|
||||
/* Correct fd value */
|
||||
fd = MAX_OPEN_FILES - fd;
|
||||
map = __ps2_fdmap[fd];
|
||||
|
||||
if (map)
|
||||
map->ref_count++;
|
||||
}
|
||||
|
||||
_unlock();
|
||||
return map;
|
||||
}
|
||||
|
||||
int __ps2_fd_drop(DescriptorTranslation *map)
|
||||
{
|
||||
_lock();
|
||||
|
||||
if (map->ref_count == 1)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
map->ref_count--;
|
||||
memset(map, 0, sizeof(DescriptorTranslation));
|
||||
}
|
||||
else
|
||||
{
|
||||
map->ref_count--;
|
||||
}
|
||||
|
||||
_unlock();
|
||||
return 0;
|
||||
}
|
@ -16,12 +16,15 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
#include <string.h>
|
||||
#include <fileXio_rpc.h>
|
||||
|
||||
#define DEVICE_SLASH "/"
|
||||
|
||||
#define DEVICE_MC0 "mc0:"
|
||||
#define DEVICE_MC1 "mc1:"
|
||||
#define DEVICE_CDROM "cdrom0:"
|
||||
#define DEVICE_CDFS "cdfs:"
|
||||
#define DEVICE_MASS "mass:"
|
||||
#define DEVICE_MASS0 "mass0:"
|
||||
#define DEVICE_HDD "hdd:"
|
||||
@ -40,6 +43,7 @@
|
||||
|
||||
#define DEVICE_MC0_PATH DEVICE_MC0 DEVICE_SLASH
|
||||
#define DEVICE_MC1_PATH DEVICE_MC1 DEVICE_SLASH
|
||||
#define DEVICE_CDFS_PATH DEVICE_CDFS DEVICE_SLASH
|
||||
#define DEVICE_CDROM_PATH DEVICE_CDROM DEVICE_SLASH
|
||||
#define DEVICE_MASS_PATH DEVICE_MASS DEVICE_SLASH
|
||||
#define DEVICE_MASS0_PATH DEVICE_MASS0 DEVICE_SLASH
|
||||
@ -67,6 +71,8 @@ char *rootDevicePath(enum BootDeviceIDs device_id)
|
||||
return DEVICE_MC1_PATH;
|
||||
case BOOT_DEVICE_CDROM:
|
||||
return DEVICE_CDROM_PATH;
|
||||
case BOOT_DEVICE_CDFS:
|
||||
return DEVICE_CDFS_PATH;
|
||||
case BOOT_DEVICE_MASS:
|
||||
return DEVICE_MASS_PATH;
|
||||
case BOOT_DEVICE_MASS0:
|
||||
@ -110,6 +116,8 @@ enum BootDeviceIDs getBootDeviceID(char *path)
|
||||
return BOOT_DEVICE_MC1;
|
||||
else if (!strncmp(path, DEVICE_CDROM, 7))
|
||||
return BOOT_DEVICE_CDROM;
|
||||
else if (!strncmp(path, DEVICE_CDFS, 5))
|
||||
return BOOT_DEVICE_CDFS;
|
||||
else if (!strncmp(path, DEVICE_MASS, 5))
|
||||
return BOOT_DEVICE_MASS;
|
||||
else if (!strncmp(path, DEVICE_MASS0, 6))
|
||||
|
159
ps2/compat_files/ps2_hashtable.c
Normal file
159
ps2/compat_files/ps2_hashtable.c
Normal file
@ -0,0 +1,159 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* * You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ps2_hashtable.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <murmur3.h>
|
||||
|
||||
HashTable *crb_hashtable_create(uint32_t _size) {
|
||||
HashTable *tbl = malloc(sizeof(HashTable));
|
||||
tbl->size = 0;
|
||||
tbl->capacity = 0;
|
||||
tbl->table = NULL;
|
||||
return tbl;
|
||||
}
|
||||
|
||||
void crb_hashtable_destroy(HashTable **_tbl) {
|
||||
if (_tbl == NULL || *_tbl == NULL) return;
|
||||
|
||||
if ((*_tbl)->table != NULL) {
|
||||
free((*_tbl)->table);
|
||||
(*_tbl)->table = NULL;
|
||||
}
|
||||
|
||||
free(*_tbl);
|
||||
|
||||
*_tbl = NULL;
|
||||
}
|
||||
|
||||
void crb_hashtable_grow(HashTable *_tbl) {
|
||||
unsigned int oldCapacity;
|
||||
struct table_entry **oldTable;
|
||||
unsigned int i;
|
||||
|
||||
if (_tbl == NULL) return;
|
||||
|
||||
oldCapacity = _tbl->capacity;
|
||||
if (_tbl->capacity > 0) {
|
||||
_tbl->capacity *= 2;
|
||||
} else {
|
||||
_tbl->capacity = 32;
|
||||
}
|
||||
oldTable = _tbl->table;
|
||||
_tbl->table = calloc(_tbl->capacity, sizeof(struct table_entry*));
|
||||
for (i = 0; i < oldCapacity; i++) {
|
||||
if (oldTable[i] != NULL) {
|
||||
crb_hashtable_insert(_tbl, oldTable[i]->key, oldTable[i]->value);
|
||||
free(oldTable[i]);
|
||||
}
|
||||
}
|
||||
free(oldTable);
|
||||
}
|
||||
|
||||
void crb_hashtable_hash(const char *_key, uint32_t *hash) {
|
||||
MurmurHash3_x86_32(_key, strlen(_key), 0, hash);
|
||||
}
|
||||
|
||||
bool crb_hashtable_insert(HashTable *_tbl, const char *_key, void *_data) {
|
||||
struct table_entry *entry, *next_entry;
|
||||
uint32_t index;
|
||||
|
||||
if (_tbl == NULL || _key == NULL || _data == NULL) return false;
|
||||
|
||||
if (_tbl->size == _tbl->capacity) {
|
||||
crb_hashtable_grow(_tbl);
|
||||
}
|
||||
|
||||
entry = malloc(sizeof(struct table_entry));
|
||||
if (entry == NULL) return false;
|
||||
crb_hashtable_hash(_key, &entry->hash);
|
||||
index = entry->hash % _tbl->capacity;
|
||||
entry->key = strdup(_key);
|
||||
entry->value = _data;
|
||||
entry->next = NULL;
|
||||
|
||||
if (_tbl->table[index] == NULL) {
|
||||
_tbl->table[index] = entry;
|
||||
} else {
|
||||
next_entry = _tbl->table[index];
|
||||
while (next_entry != NULL) {
|
||||
if (next_entry->next == NULL) {
|
||||
next_entry->next = entry;
|
||||
break;
|
||||
}
|
||||
next_entry = next_entry->next;
|
||||
}
|
||||
}
|
||||
_tbl->size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void *crb_hashtable_find(HashTable *_tbl, const char *_key) {
|
||||
uint32_t hash;
|
||||
struct table_entry *entry;
|
||||
|
||||
if (_tbl == NULL || _key == NULL) return NULL;
|
||||
|
||||
crb_hashtable_hash(_key, &hash);
|
||||
|
||||
for (entry = _tbl->table[hash % _tbl->capacity]; entry != NULL; entry = entry->next) {
|
||||
if (strcmp(_key, entry->key) == 0) return entry->value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *crb_hashtable_remove(HashTable *_tbl, const char *_key) {
|
||||
uint32_t hash;
|
||||
struct table_entry *entry, *sibling;
|
||||
bool top = true;
|
||||
void *data;
|
||||
|
||||
if (_tbl == NULL || _key == NULL) return NULL;
|
||||
|
||||
crb_hashtable_hash(_key, &hash);
|
||||
|
||||
for (entry = _tbl->table[hash % _tbl->capacity]; entry != NULL; sibling = entry, entry = entry->next) {
|
||||
if (strcmp(_key, entry->key) == 0) {
|
||||
break;
|
||||
} else {
|
||||
top = false;
|
||||
}
|
||||
}
|
||||
if (entry != NULL) {
|
||||
data = entry->value;
|
||||
if (top) {
|
||||
if (entry->next != NULL) {
|
||||
_tbl->table[hash % _tbl->capacity] = entry->next;
|
||||
} else {
|
||||
_tbl->table[hash % _tbl->capacity] = NULL;
|
||||
}
|
||||
} else {
|
||||
if (entry->next != NULL) {
|
||||
sibling->next = entry->next;
|
||||
} else {
|
||||
sibling->next = NULL;
|
||||
}
|
||||
}
|
||||
free(entry->key);
|
||||
free(entry);
|
||||
entry = NULL;
|
||||
_tbl->size--;
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
40
ps2/include/cd.h
Normal file
40
ps2/include/cd.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef CD_H
|
||||
#define CD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fileXio_rpc.h>
|
||||
#include <fileXio.h>
|
||||
|
||||
#define CDVD_INIT_INIT 0x00
|
||||
#define CDVD_INIT_NOCHECK 0x01
|
||||
#define CDVD_INIT_EXIT 0x05
|
||||
|
||||
typedef enum {
|
||||
CDVD_TYPE_NODISK = 0x00, // No Disc inserted
|
||||
CDVD_TYPE_DETECT, // Detecting disc type
|
||||
CDVD_TYPE_DETECT_CD,
|
||||
CDVD_TYPE_DETECT_DVDSINGLE,
|
||||
CDVD_TYPE_DETECT_DVDDUAL,
|
||||
CDVD_TYPE_UNKNOWN, // Unknown disc type
|
||||
|
||||
CDVD_TYPE_PS1CD = 0x10, // PS1 CD with no CDDA tracks
|
||||
CDVD_TYPE_PS1CDDA, // PS1 CD with CDDA tracks
|
||||
CDVD_TYPE_PS2CD, // PS2 CD with no CDDA tracks
|
||||
CDVD_TYPE_PS2CDDA, // PS2 CD with CDDA tracks
|
||||
CDVD_TYPE_PS2DVD, // PS2 DVD
|
||||
|
||||
CDVD_TYPE_CDDA = 0xFD, // CDDA
|
||||
CDVD_TYPE_DVDVIDEO, // DVD Video
|
||||
CDVD_TYPE_ILLEGAL, // Illegal disk type
|
||||
} CdvdDiscType_t;
|
||||
|
||||
s32 cdInit(s32);
|
||||
CdvdDiscType_t cdGetDiscType(void);
|
||||
|
||||
|
||||
|
||||
|
||||
int newfileXioDopen(const char *name);
|
||||
int newfileXioDread(int fd, iox_dirent_t *dirent);
|
||||
|
||||
#endif
|
29
ps2/include/murmur3.h
Executable file
29
ps2/include/murmur3.h
Executable file
@ -0,0 +1,29 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the
|
||||
// public domain. The author hereby disclaims copyright to this source
|
||||
// code.
|
||||
|
||||
#ifndef _MURMURHASH3_H_
|
||||
#define _MURMURHASH3_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
void MurmurHash3_x86_32(const void *key, int len, uint32_t seed, void *out);
|
||||
|
||||
void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out);
|
||||
|
||||
void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MURMURHASH3_H_ */
|
59
ps2/include/ps2_descriptor.h
Normal file
59
ps2/include/ps2_descriptor.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* * You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PS2_DESCRIPTOR_H
|
||||
#define PS2_DESCRIPTOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cd.h>
|
||||
|
||||
#define MAX_OPEN_FILES 256
|
||||
#define FILEENTRY_SIZE 2048
|
||||
|
||||
typedef struct {
|
||||
char displayname[64];
|
||||
int dircheck;
|
||||
char filename[256];
|
||||
} entries;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char path[256];
|
||||
int ref_count;
|
||||
int items;
|
||||
int current_folder_position;
|
||||
entries *FileEntry;
|
||||
} DescriptorTranslation;
|
||||
|
||||
extern DescriptorTranslation *__ps2_fdmap[];
|
||||
|
||||
void _init_ps2_io(void);
|
||||
void _free_ps2_io(void);
|
||||
|
||||
int __ps2_acquire_descriptor(void);
|
||||
int __ps2_release_descriptor(int fd);
|
||||
int __ps2_duplicate_descriptor(int fd);
|
||||
int __ps2_descriptor_ref_count(int fd);
|
||||
DescriptorTranslation *__ps2_fd_grab(int fd);
|
||||
int __ps2_fd_drop(DescriptorTranslation *fdmap);
|
||||
|
||||
static inline int is_fd_valid(int fd)
|
||||
{
|
||||
/* Correct fd value */
|
||||
fd = MAX_OPEN_FILES - fd;
|
||||
|
||||
return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL);
|
||||
}
|
||||
|
||||
#endif /* PS2_DESCRIPTOR_H */
|
@ -22,6 +22,7 @@ enum BootDeviceIDs{
|
||||
BOOT_DEVICE_MC0 = 0,
|
||||
BOOT_DEVICE_MC1,
|
||||
BOOT_DEVICE_CDROM,
|
||||
BOOT_DEVICE_CDFS,
|
||||
BOOT_DEVICE_MASS,
|
||||
BOOT_DEVICE_MASS0,
|
||||
BOOT_DEVICE_HDD,
|
||||
|
45
ps2/include/ps2_hashtable.h
Normal file
45
ps2/include/ps2_hashtable.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2018 - Francisco Javier Trujillo Mata - fjtrujy
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
* * You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PS2_HASHTABLE_H
|
||||
#define PS2_HASHTABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct table_entry {
|
||||
char *key;
|
||||
void *value;
|
||||
uint32_t hash;
|
||||
struct table_entry *next;
|
||||
};
|
||||
|
||||
struct hash_table {
|
||||
uint32_t capacity;
|
||||
uint32_t size;
|
||||
struct table_entry **table;
|
||||
};
|
||||
|
||||
typedef struct hash_table HashTable;
|
||||
|
||||
HashTable *crb_hashtable_create(uint32_t _size);
|
||||
void crb_hashtable_destroy(HashTable **_tbl);
|
||||
|
||||
void crb_hashtable_grow(HashTable *_tbl);
|
||||
void crb_hashtable_hash(const char *_key, uint32_t *hash);
|
||||
bool crb_hashtable_insert(HashTable *_tbl, const char *_key, void *_data);
|
||||
void *crb_hashtable_find(HashTable *_tbl, const char *_key);
|
||||
void *crb_hashtable_remove(HashTable *_tbl, const char *_key);
|
||||
|
||||
#endif
|
@ -2,20 +2,30 @@
|
||||
EE_BIN2C = bin2c
|
||||
IRX_DIR = $(PS2SDK)/iop/irx
|
||||
|
||||
#Specific folder for cdvd.irx
|
||||
LIBCDVD_DIR = ../libcdvd
|
||||
LIBCDVD_IRX_DIR = $(LIBCDVD_DIR)/lib
|
||||
|
||||
#IRX modules
|
||||
# IRX modules - modules have to be in IRX_DIR
|
||||
IRX_FILES += freemtap.irx freepad.irx freesio2.irx iomanX.irx fileXio.irx mcman.irx mcserv.irx usbd.irx usbhdfsd.irx
|
||||
IRX_FILES += freesd.irx audsrv.irx poweroff.irx
|
||||
IRX_FILES += freesd.irx audsrv.irx poweroff.irx cdvd.irx
|
||||
IRX_C_FILES = $(IRX_FILES:.irx=_irx.c)
|
||||
|
||||
# Specific file name and output per IRX Module
|
||||
%.irx:
|
||||
$(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx)
|
||||
if [[ "$(@)" == "cdvd.irx" ]]; then \
|
||||
$(MAKE) -C $(LIBCDVD_DIR); \
|
||||
$(EE_BIN2C) $(LIBCDVD_IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx); \
|
||||
else \
|
||||
$(EE_BIN2C) $(IRX_DIR)/$@ $(@:.irx=_irx.c) $(@:.irx=_irx); \
|
||||
fi
|
||||
|
||||
all: $(IRX_FILES)
|
||||
|
||||
clean:
|
||||
rm -f $(IRX_C_FILES)
|
||||
$(MAKE) -C $(LIBCDVD_DIR) clean
|
||||
|
||||
#Include preferences
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
|
Loading…
x
Reference in New Issue
Block a user