From adf2743464161adc74130822e82285fac4b1e075 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sat, 9 Mar 2019 14:11:04 +0100 Subject: [PATCH] Implement CDFS and custom file descriptor support --- Makefile.ps2 | 16 +- frontend/drivers/platform_ps2.c | 24 ++ gfx/drivers/ps2_gfx.c | 2 +- libretro-common/features/features_cpu.c | 1 + libretro-common/include/retro_miscellaneous.h | 2 +- libretro-common/vfs/vfs_implementation.c | 7 +- ps2/compat_files/cd.c | 323 ++++++++++++++++++ ps2/compat_files/murmur3.c | 317 +++++++++++++++++ ps2/compat_files/ps2_descriptor.c | 189 ++++++++++ ps2/compat_files/ps2_devices.c | 8 + ps2/compat_files/ps2_hashtable.c | 159 +++++++++ ps2/include/cd.h | 40 +++ ps2/include/murmur3.h | 29 ++ ps2/include/ps2_descriptor.h | 59 ++++ ps2/include/ps2_devices.h | 1 + ps2/include/ps2_hashtable.h | 45 +++ ps2/irx/Makefile | 14 +- 17 files changed, 1224 insertions(+), 12 deletions(-) create mode 100644 ps2/compat_files/cd.c create mode 100755 ps2/compat_files/murmur3.c create mode 100644 ps2/compat_files/ps2_descriptor.c create mode 100644 ps2/compat_files/ps2_hashtable.c create mode 100644 ps2/include/cd.h create mode 100755 ps2/include/murmur3.h create mode 100644 ps2/include/ps2_descriptor.h create mode 100644 ps2/include/ps2_hashtable.h diff --git a/Makefile.ps2 b/Makefile.ps2 index f4061c70bb..881f950860 100644 --- a/Makefile.ps2 +++ b/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 diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index 34b5d3a755..8cc839c79a 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -27,8 +27,11 @@ #include #include #include +#include +#include #include #include +#include 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), diff --git a/gfx/drivers/ps2_gfx.c b/gfx/drivers/ps2_gfx.c index 40a197ec3f..381848be92 100644 --- a/gfx/drivers/ps2_gfx.c +++ b/gfx/drivers/ps2_gfx.c @@ -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) { diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index e247e46a02..7b3283f124 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -68,6 +68,7 @@ #if defined(PS2) #include #include +#include #endif #if defined(__PSL1GHT__) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 814bdef923..3893416ee4 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -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" diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index b791fa0d6f..09bdca60d5 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -52,6 +52,7 @@ # endif # if defined(PS2) # include +# include # endif # include # include @@ -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) diff --git a/ps2/compat_files/cd.c b/ps2/compat_files/cd.c new file mode 100644 index 0000000000..4369139720 --- /dev/null +++ b/ps2/compat_files/cd.c @@ -0,0 +1,323 @@ +#include +#include +#include +#include +#include +#include +#include +//#include +#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); + } +} + + diff --git a/ps2/compat_files/murmur3.c b/ps2/compat_files/murmur3.c new file mode 100755 index 0000000000..8abd92bca7 --- /dev/null +++ b/ps2/compat_files/murmur3.c @@ -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; +} + +/*-----------------------------------------------------------------------------*/ + diff --git a/ps2/compat_files/ps2_descriptor.c b/ps2/compat_files/ps2_descriptor.c new file mode 100644 index 0000000000..3c95c16905 --- /dev/null +++ b/ps2/compat_files/ps2_descriptor.c @@ -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 . + */ + +#include + +#include +#include +#include +#include + +#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; +} diff --git a/ps2/compat_files/ps2_devices.c b/ps2/compat_files/ps2_devices.c index 08a071bd96..63a6eeadd6 100644 --- a/ps2/compat_files/ps2_devices.c +++ b/ps2/compat_files/ps2_devices.c @@ -16,12 +16,15 @@ #include #include +#include +#include #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)) diff --git a/ps2/compat_files/ps2_hashtable.c b/ps2/compat_files/ps2_hashtable.c new file mode 100644 index 0000000000..abeaa86d3c --- /dev/null +++ b/ps2/compat_files/ps2_hashtable.c @@ -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 . + */ + +#include + +#include +#include +#include + +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; +} diff --git a/ps2/include/cd.h b/ps2/include/cd.h new file mode 100644 index 0000000000..31a050063d --- /dev/null +++ b/ps2/include/cd.h @@ -0,0 +1,40 @@ +#ifndef CD_H +#define CD_H + +#include +#include +#include + +#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 diff --git a/ps2/include/murmur3.h b/ps2/include/murmur3.h new file mode 100755 index 0000000000..555659f620 --- /dev/null +++ b/ps2/include/murmur3.h @@ -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 + +#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_ */ diff --git a/ps2/include/ps2_descriptor.h b/ps2/include/ps2_descriptor.h new file mode 100644 index 0000000000..5a4f0fcbd3 --- /dev/null +++ b/ps2/include/ps2_descriptor.h @@ -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 . + */ + +#ifndef PS2_DESCRIPTOR_H +#define PS2_DESCRIPTOR_H + +#include +#include + +#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 */ diff --git a/ps2/include/ps2_devices.h b/ps2/include/ps2_devices.h index deab4ec0d2..a2bc283572 100644 --- a/ps2/include/ps2_devices.h +++ b/ps2/include/ps2_devices.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, diff --git a/ps2/include/ps2_hashtable.h b/ps2/include/ps2_hashtable.h new file mode 100644 index 0000000000..2b3d86a50f --- /dev/null +++ b/ps2/include/ps2_hashtable.h @@ -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 . + */ + +#ifndef PS2_HASHTABLE_H +#define PS2_HASHTABLE_H + +#include +#include + +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 diff --git a/ps2/irx/Makefile b/ps2/irx/Makefile index 49cb342c2b..0328ccc8c1 100644 --- a/ps2/irx/Makefile +++ b/ps2/irx/Makefile @@ -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