diff --git a/Makefile.ps2 b/Makefile.ps2 index 369a66198d..7f11a362ba 100644 --- a/Makefile.ps2 +++ b/Makefile.ps2 @@ -1,12 +1,12 @@ BUILD_PRX = 0 -DEBUG = 0 +DEBUG = 1 HAVE_KERNEL_PRX = 0 HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 1 HAVE_THREADS = 0 BIG_STACK = 0 WHOLE_ARCHIVE_LINK = 0 -PS2_IP = 192.168.2.150 +PS2_IP = 192.168.1.150 #Configuration for IRX EE_BIN2O = bin2o @@ -31,16 +31,16 @@ INCDIR = -I$(PS2DEV)/gsKit/include -I$(PS2SDK)/ports/include 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 -CFLAGS = $(OPTIMIZE_LV) -ffast-math -fsingle-precision-constant +CFLAGS = $(OPTIMIZE_LV) -ffast-math -fsingle-precision-constant ASFLAGS = $(CFLAGS) RARCH_DEFINES += -DPS2 -DUSE_IOP_CTYPE_MACRO -D_MIPS_ARCH_R5900 -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DWANT_ZLIB -RARCH_DEFINES += -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_IMAGEVIEWER -DHAVE_7ZIP -DHAVE_CC_RESAMPLER +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. -s LIBS += $(WHOLE_START) -lretro_ps2 $(WHOLE_END) -LIBS += -lgskit -ldmakit -lpad -lmc -lhdd -lsdl -lc -lfileXio -lpatches -lpoweroff -ldebug -lc +LIBS += -lgskit -ldmakit -laudsrv -lpad -lmc -lhdd -lsdl -lc -lfileXio -lpatches -lpoweroff -lc #IRX modules # IRX modules - modules have to be in IRX_DIR diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 4baaf7b753..abe89485af 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -122,6 +122,9 @@ static const audio_driver_t *audio_drivers[] = { #if defined(PSP) || defined(VITA) &audio_psp, #endif +#if defined(PS2) + &audio_ps2, +#endif #ifdef _3DS &audio_ctr_csnd, &audio_ctr_dsp, diff --git a/audio/drivers/ps2_audio.c b/audio/drivers/ps2_audio.c new file mode 100644 index 0000000000..5874e1fa1b --- /dev/null +++ b/audio/drivers/ps2_audio.c @@ -0,0 +1,275 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2014-2017 - Francisco Javier Trujillo Mata + * + * 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 +#include + +#include +#include + +#include "../audio_driver.h" + +typedef struct ps2_audio +{ + bool nonblocking; + + fifo_buffer_t* buffer; + + volatile bool running; + + int worker_thread; + + int lock; + int cond_lock; + +} ps2_audio_t; + +static ps2_audio_t *backup_ps2; +static u8 audioThreadStack[512 * 16] __attribute__ ((aligned(16))); + +#define AUDIO_OUT_BUFFER 2 * 1024 +#define AUDIO_BUFFER 64 * 1024 + + +static void audioMainLoop(void *data) +{ + ps2_audio_t* ps2 = backup_ps2; + + char out_tmp[AUDIO_OUT_BUFFER]; + + while (ps2->running) + { + WaitSema(ps2->lock); + if (fifo_read_avail(ps2->buffer) >= sizeof(out_tmp)) { + fifo_read(ps2->buffer, out_tmp, sizeof(out_tmp)); + } else { + memset(out_tmp, 0, sizeof(out_tmp)); + } + iSignalSema(ps2->lock); + iSignalSema(ps2->cond_lock); + + int ret; + audsrv_wait_audio(sizeof(out_tmp)); + ret = audsrv_play_audio(out_tmp, sizeof(out_tmp)); + } + + audsrv_stop_audio(); + ExitDeleteThread(); +} + + +static void audioCreateThread(ps2_audio_t *ps2) { + int ret; + ee_thread_t thread; + + thread.func=&audioMainLoop; + thread.stack=audioThreadStack; + thread.stack_size=sizeof(audioThreadStack); + thread.gp_reg=&_gp; + thread.initial_priority=0x50; + thread.attr=thread.option=0; + + /*Backup the PS2 content to be used in the thread */ + backup_ps2 = ps2; + + ps2->running = true; + ps2->worker_thread = CreateThread(&thread); + if (ps2->worker_thread >= 0) { + ret = StartThread(ps2->worker_thread, NULL); + if (ret < 0) { + printf("sound_init: StartThread returned %d\n", ret); + } + } else { + printf("CreateThread failed: %d\n", ps2->worker_thread); + } +} + +static void audioStopNDeleteThread(ps2_audio_t *ps2) { + ps2->running = false; + if (ps2->worker_thread) { + ps2->worker_thread = 0; + } +} + + +static void audioConfigure(ps2_audio_t *ps2, unsigned rate) { + int err; + struct audsrv_fmt_t format; + format.bits = 16; + format.freq = rate; + format.channels = 2; + + err = audsrv_set_format(&format); + if (err) { + printf("set format returned %d\n", err); + printf("audsrv returned error string: %s\n", audsrv_get_error_string()); + } + + audsrv_set_volume(MAX_VOLUME); +} + +static void audioCreateSemas(ps2_audio_t *ps2) { + ee_sema_t lock_info; + lock_info.max_count = 1; + lock_info.init_count = 1; + lock_info.option = 0; + ps2->lock = CreateSema(&lock_info); + + ee_sema_t cond_lock_info; + cond_lock_info.init_count = 1; + cond_lock_info.max_count = 1; + cond_lock_info.option = 0; + ps2->cond_lock = CreateSema(&cond_lock_info); +} + +static void *ps2_audio_init(const char *device, + unsigned rate, unsigned latency, + unsigned block_frames, + unsigned *new_rate) +{ + ps2_audio_t *ps2 = (ps2_audio_t*)calloc(1, sizeof(ps2_audio_t)); + + if (!ps2) + return NULL; + + ps2->buffer = fifo_new(AUDIO_BUFFER); + audioConfigure(ps2, rate); + audioCreateSemas(ps2); + audioCreateThread(ps2); + + return ps2; +} + +static void ps2_audio_free(void *data) +{ + ps2_audio_t* ps2 = (ps2_audio_t*)data; + if(!ps2) + return; + + if(ps2->running){ + audioStopNDeleteThread(ps2); + + if (ps2->lock) { + iDeleteSema(ps2->lock); + ps2->lock = 0; + } + + if (ps2->cond_lock) { + iDeleteSema(ps2->cond_lock); + ps2->cond_lock = 0; + } + + } + fifo_free(ps2->buffer); + free(ps2); +} + +static ssize_t ps2_audio_write(void *data, const void *buf, size_t size) +{ + ps2_audio_t* ps2 = (ps2_audio_t*)data; + + if (!ps2->running) + return -1; + + if (ps2->nonblocking) + { + if (fifo_write_avail(ps2->buffer) < size) + return 0; + } + + while (fifo_write_avail(ps2->buffer) < size) { + WaitSema(ps2->cond_lock); + } + + WaitSema(ps2->lock); + fifo_write(ps2->buffer, buf, size); + iSignalSema(ps2->lock); + + return size; +} + +static bool ps2_audio_alive(void *data) +{ + bool alive = false; + + ps2_audio_t* ps2 = (ps2_audio_t*)data; + if (ps2) { + alive = ps2->running; + } + + return alive; +} + +static bool ps2_audio_stop(void *data) +{ + bool stop = true; + ps2_audio_t* ps2 = (ps2_audio_t*)data; + + if (ps2) { + audioStopNDeleteThread(ps2); + audsrv_stop_audio(); + } + + return stop; +} + +static bool ps2_audio_start(void *data, bool is_shutdown) +{ + bool start = true; + ps2_audio_t* ps2 = (ps2_audio_t*)data; + + if(ps2) { + if (!ps2->running && !ps2->worker_thread) { + audioCreateThread(ps2); + } + } + + return start; +} + +static void ps2_audio_set_nonblock_state(void *data, bool toggle) +{ + ps2_audio_t* ps2 = (ps2_audio_t*)data; + if (ps2) { + ps2->nonblocking = toggle; + } +} + +static bool ps2_audio_use_float(void *data) +{ + (void)data; + return false; +} + +audio_driver_t audio_ps2 = { + ps2_audio_init, + ps2_audio_write, + ps2_audio_stop, + ps2_audio_start, + ps2_audio_alive, + ps2_audio_set_nonblock_state, + ps2_audio_free, + ps2_audio_use_float, + "ps2", + NULL, + NULL, + NULL, + NULL +}; diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index ca7411bb45..fe3355bc21 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -20,12 +20,11 @@ #include #include #include -#include -#include #include #include #include #include +#include enum BootDeviceIDs{ @@ -306,6 +305,7 @@ static void frontend_ps2_init(void *data) SifInitRpc(0); sbv_patch_enable_lmb(); + // I/O Files SifExecModuleBuffer(iomanX_irx_start, iomanX_irx_size, 0, NULL, NULL); SifExecModuleBuffer(fileXio_irx_start, fileXio_irx_size, 0, NULL, NULL); @@ -314,18 +314,21 @@ static void frontend_ps2_init(void *data) SifLoadModule("rom0:MCSERV", 0, NULL); SifLoadModule("rom0:PADMAN", 0, NULL); + // USB SifExecModuleBuffer(usbd_irx_start, usbd_irx_size, 0, NULL, NULL); SifExecModuleBuffer(usbhdfsd_irx_start, usbhdfsd_irx_size, 0, NULL, NULL); + + // Audio SifExecModuleBuffer(freesd_irx_start, freesd_irx_size, 0, NULL, NULL); SifExecModuleBuffer(audsrv_irx_start, audsrv_irx_size, 0, NULL, NULL); - fileXioInit(); - audsrv_init(); - SDL_Init(SDL_INIT_TIMER); + //Initializes audsrv library + if(audsrv_init()) { + RARCH_ERR("audsrv library not initalizated\n"); + } -retro_sleep(100); #if defined(HAVE_FILE_LOGGER) retro_main_log_file_init("retroarch.log"); diff --git a/griffin/griffin.c b/griffin/griffin.c index b101226120..0b264e5952 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -773,7 +773,7 @@ AUDIO #elif defined(PSP) || defined(VITA) #include "../audio/drivers/psp_audio.c" #elif defined(PS2) -// #include "../audio/drivers/ps2_audio.c" +#include "../audio/drivers/ps2_audio.c" #elif defined(_3DS) #include "../audio/drivers/ctr_csnd_audio.c" #include "../audio/drivers/ctr_dsp_audio.c" diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index 4721e7259e..9c2caef54f 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -294,7 +294,7 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns */ /* TODO: this is only useful for a few platforms, find which and add ifdef */ stream->fp = fp; -#if !defined(PS2) +#if !defined(PS2) // TODO: PS2 IMPROVEMENT stream->buf = (char*)calloc(1, 0x4000); setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000); #endif