From 7fa6a796be7848e0f6688c81f6bc42c95bd9016f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Tue, 29 Sep 2015 00:40:53 +0200 Subject: [PATCH] (Vita) First Networking Code and Download Overlays --- Makefile.griffin | 5 +- frontend/drivers/platform_psp.c | 7 ++ libretro-common/include/net/net_compat.h | 37 ++++++- libretro-common/net/net_compat.c | 122 ++++++++++++++++++++++- libretro-common/net/net_http.c | 7 +- 5 files changed, 173 insertions(+), 5 deletions(-) diff --git a/Makefile.griffin b/Makefile.griffin index 7b193c6e79..591c2c6d11 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -203,7 +203,7 @@ else ifeq ($(platform), vita) EXT_INTER_TARGET := $(TARGET_NAME)_$(platform).elf MACHDEP := -DVITA PLATCFLAGS := -O3 -mfloat-abi=hard -ffast-math -fsingle-precision-constant - LIBS += -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub \ + LIBS += -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\ -lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub -lUVLoader_stub \ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lz -lm -lc @@ -219,6 +219,9 @@ else ifeq ($(platform), vita) HAVE_RPNG := 1 HAVE_ZLIB := 1 HAVE_VITA2D := 1 + HAVE_NETWORKING := 1 + HAVE_NETPLAY := 1 + HAVE_OVERLAY := 1 RARCH_CONSOLE = 1 endif diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index c7619479a6..5abb14d045 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -95,6 +95,8 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[], #endif RARCH_LOG("port dir: [%s]\n", g_defaults.dir.port); + fill_pathname_join(g_defaults.dir.core_assets, g_defaults.dir.port, + "downloads", sizeof(g_defaults.dir.core_assets)); fill_pathname_join(g_defaults.dir.assets, g_defaults.dir.port, "media", sizeof(g_defaults.dir.assets)); fill_pathname_join(g_defaults.dir.core, g_defaults.dir.port, @@ -116,6 +118,11 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[], fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.port, "remaps", sizeof(g_defaults.dir.remap)); +#ifdef VITA + fill_pathname_join(g_defaults.dir.overlay, g_defaults.dir.core, + "overlays", sizeof(g_defaults.dir.overlay)); +#endif + #ifdef VITA params = (struct rarch_main_wrap*)params_data; params->verbose = true; diff --git a/libretro-common/include/net/net_compat.h b/libretro-common/include/net/net_compat.h index dde91f3a51..857e98af6e 100644 --- a/libretro-common/include/net/net_compat.h +++ b/libretro-common/include/net/net_compat.h @@ -59,7 +59,41 @@ #define sockaddr_in SceNetSockaddrIn #define sockaddr SceNetSockaddr #define sendto sceNetSendto +#define recvfrom sceNetRecvfrom +#define socket(a,b,c) sceNetSocket("unknown",a,b,c) +#define bind sceNetBind +#define accept sceNetAccept +#define setsockopt sceNetSetsockopt +#define connect sceNetConnect +#define listen sceNetListen +#define send sceNetSend +#define recv sceNetRecv #define MSG_DONTWAIT PSP2_NET_MSG_DONTWAIT +#define AF_INET PSP2_NET_AF_INET +#define AF_UNSPEC 0 +#define INADDR_ANY PSP2_NET_INADDR_ANY +#define INADDR_NONE 0xffffffff +#define SOCK_STREAM PSP2_NET_SOCK_STREAM +#define SOCK_DGRAM PSP2_NET_SOCK_DGRAM +#define SOL_SOCKET PSP2_NET_SOL_SOCKET +#define SO_REUSEADDR PSP2_NET_SO_REUSEADDR +#define SO_SNDBUF PSP2_NET_SO_SNDBUF +#define SO_SNDTIMEO PSP2_NET_SO_SNDTIMEO +#define SO_NBIO PSP2_NET_SO_NBIO +#define htonl sceNetHtonl +#define ntohl sceNetNtohl +#define htons sceNetHtons +#define socklen_t unsigned int + +struct hostent +{ + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; + char *h_addr; +}; #else #include @@ -114,6 +148,8 @@ static INLINE bool isagain(int bytes) if (WSAGetLastError() != WSAEWOULDBLOCK) return false; return true; +#elif defined(VITA) + return (bytes<0 && (bytes == PSP2_NET_ERROR_EAGAIN || bytes == PSP2_NET_ERROR_EWOULDBLOCK)); #else return (bytes < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)); #endif @@ -203,4 +239,3 @@ bool network_init(void); void network_deinit(void); #endif - diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index ec33d74360..8a1b5e5b0e 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -21,6 +21,81 @@ #include +#if defined(VITA) +static void *_net_compat_net_memory = NULL; +#define COMPAT_NET_INIT_SIZE 512*1024 +#define INET_ADDRSTRLEN sizeof(struct sockaddr_in) +#define MAX_NAME 512 + +typedef uint32_t in_addr_t; + +struct in_addr { + in_addr_t s_addr; +}; + +char *inet_ntoa(struct SceNetInAddr in) +{ + static char ip_addr[INET_ADDRSTRLEN+1]; + + if(sceNetInetNtop(AF_INET, &in, ip_addr, INET_ADDRSTRLEN) == NULL) + { + strcpy(ip_addr, "Invalid"); + } + + return ip_addr; +} + +struct SceNetInAddr inet_aton(const char * ip_addr) +{ + SceNetInAddr inaddr; + + sceNetInetPton(AF_INET, ip_addr, &inaddr); + return inaddr; +} + +unsigned int inet_addr(const char *cp) +{ + return inet_aton(cp).s_addr; +} + +struct hostent *gethostbyname(const char *name) +{ + static struct hostent ent; + static char sname[MAX_NAME] = ""; + static struct SceNetInAddr saddr = { 0 }; + static char *addrlist[2] = { (char *) &saddr, NULL }; + int rid; + + + int err; + rid = sceNetResolverCreate("resolver", NULL, 0); + if(rid < 0) + { + return NULL; + } + + err = sceNetResolverStartNtoa(rid, name, &saddr, 0,0,0); + sceNetResolverDestroy(rid); + if(err < 0) + { + return NULL; + } + + addrlist[0]=inet_ntoa(saddr); + ent.h_name = sname; + ent.h_aliases = 0; + ent.h_addrtype = AF_INET; + ent.h_length = sizeof(struct in_addr); + ent.h_addr_list = addrlist; + ent.h_addr = addrlist[0]; + + return &ent; +} + +int rarch_epoll_fd; + +#endif + int getaddrinfo_rarch(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) @@ -87,7 +162,7 @@ void freeaddrinfo_rarch(struct addrinfo *res) bool socket_nonblock(int fd) { -#if defined(__CELLOS_LV2__) +#if defined(__CELLOS_LV2__) || defined(VITA) int i = 1; setsockopt(fd, SOL_SOCKET, SO_NBIO, &i, sizeof(int)); return true; @@ -106,6 +181,8 @@ int socket_close(int fd) return closesocket(fd); #elif defined(__CELLOS_LV2__) return socketclose(fd); +#elif defined(VITA) + return sceNetSocketClose(fd); #else return close(fd); #endif @@ -116,6 +193,20 @@ int socket_select(int nfds, fd_set *readfs, fd_set *writefds, { #if defined(__CELLOS_LV2__) return socketselect(nfds, readfs, writefds, errorfds, timeout); +#elif defined(VITA) + SceNetEpollEvent ev = {0}; + ev.events = PSP2_NET_EPOLLIN | PSP2_NET_EPOLLHUP; + ev.data.fd = nfds; + + int i = 0; + if((i = sceNetEpollControl(rarch_epoll_fd, PSP2_NET_EPOLL_CTL_ADD, nfds, &ev))){ + int ret = sceNetEpollWait(rarch_epoll_fd, &ev, 1, 0); + sceNetEpollControl(rarch_epoll_fd, PSP2_NET_EPOLL_CTL_DEL, nfds, NULL); + return ret; + }else{ + return 0; + } + #else return select(nfds, readfs, writefds, errorfds, timeout); #endif @@ -180,6 +271,27 @@ bool network_init(void) #elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) cellSysmoduleLoadModule(CELL_SYSMODULE_NET); sys_net_initialize_network(); +#elif defined(VITA) + SceNetInitParam initparam; + /* Init Net */ + if (sceNetShowNetstat() == PSP2_NET_ERROR_ENOTINIT) { + _net_compat_net_memory = malloc(COMPAT_NET_INIT_SIZE); + + initparam.memory = _net_compat_net_memory; + initparam.size = COMPAT_NET_INIT_SIZE; + initparam.flags = 0; + + sceNetInit(&initparam); + //printf("sceNetInit(): 0x%08X\n", ret); + + /* Init NetCtl */ + sceNetCtlInit(); + } else { + //printf("Net is already initialized.\n"); + } + + rarch_epoll_fd = sceNetEpollCreate("epoll", 0); + //printf("Epoll %x\n",rarch_epoll_fd); #else signal(SIGPIPE, SIG_IGN); /* Do not like SIGPIPE killing our app. */ #endif @@ -200,5 +312,13 @@ void network_deinit(void) #elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) sys_net_finalize_network(); cellSysmoduleUnloadModule(CELL_SYSMODULE_NET); +#elif defined(VITA) + sceNetCtlTerm(); + sceNetTerm(); + + if (_net_compat_net_memory) { + free(_net_compat_net_memory); + _net_compat_net_memory = NULL; + } #endif } diff --git a/libretro-common/net/net_http.c b/libretro-common/net/net_http.c index 4e73a69107..9f94465525 100644 --- a/libretro-common/net/net_http.c +++ b/libretro-common/net/net_http.c @@ -68,7 +68,9 @@ static int net_http_new_socket(const char *domain, int port) { int fd; #ifndef _WIN32 +#ifndef VITA struct timeval timeout; +#endif #endif struct addrinfo hints, *addr = NULL; char portstr[16] = {0}; @@ -79,7 +81,7 @@ static int net_http_new_socket(const char *domain, int port) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; - + if (getaddrinfo_rarch(domain, portstr, &hints, &addr) < 0) return -1; if (!addr) @@ -88,11 +90,12 @@ static int net_http_new_socket(const char *domain, int port) fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); #ifndef _WIN32 +#ifndef VITA timeout.tv_sec=4; timeout.tv_usec=0; setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof timeout); #endif - +#endif if (connect(fd, addr->ai_addr, addr->ai_addrlen) != 0) { freeaddrinfo_rarch(addr);