mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-01 14:31:54 +00:00
Start adding netplay compat layer for legacy stuff.
This commit is contained in:
parent
e6f2aa81f7
commit
03a892c7f2
3
Makefile
3
Makefile
@ -38,6 +38,9 @@ endif
|
||||
|
||||
ifeq ($(HAVE_NETPLAY), 1)
|
||||
OBJ += netplay.o
|
||||
ifeq ($(HAVE_SOCKET_LEGACY), 1)
|
||||
OBJ += netplay_compat.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RSOUND), 1)
|
||||
|
50
netplay.c
50
netplay.c
@ -33,8 +33,10 @@
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#ifndef SSNES_CONSOLE
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "netplay.h"
|
||||
#include "general.h"
|
||||
@ -44,6 +46,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "netplay_compat.h"
|
||||
|
||||
// Checks if input port/index is controlled by netplay or not.
|
||||
static bool netplay_is_alive(netplay_t *handle);
|
||||
|
||||
@ -59,18 +63,6 @@ static void netplay_set_spectate_input(netplay_t *handle, int16_t input);
|
||||
static bool netplay_send_cmd(netplay_t *handle, uint32_t cmd, const void *data, size_t size);
|
||||
static bool netplay_get_cmd(netplay_t *handle);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Woohoo, Winsock has headers from the STONE AGE! :D
|
||||
#define close(x) closesocket(x)
|
||||
#define CONST_CAST (const char*)
|
||||
#define NONCONST_CAST (char*)
|
||||
#else
|
||||
#define CONST_CAST
|
||||
#define NONCONST_CAST
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define PREV_PTR(x) ((x) == 0 ? handle->buffer_size - 1 : (x) - 1)
|
||||
#define NEXT_PTR(x) ((x + 1) % handle->buffer_size)
|
||||
|
||||
@ -218,13 +210,17 @@ static void log_connection(const struct sockaddr_storage *their_addr,
|
||||
{
|
||||
const struct sockaddr_storage *storage;
|
||||
const struct sockaddr_in *v4;
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
const struct sockaddr_in6 *v6;
|
||||
#endif
|
||||
} u;
|
||||
u.storage = their_addr;
|
||||
|
||||
const char *str = NULL;
|
||||
char buf_v4[INET_ADDRSTRLEN] = {0};
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
char buf_v6[INET6_ADDRSTRLEN] = {0};
|
||||
#endif
|
||||
|
||||
if (their_addr->ss_family == AF_INET)
|
||||
{
|
||||
@ -237,6 +233,7 @@ static void log_connection(const struct sockaddr_storage *their_addr,
|
||||
getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), buf_v4, sizeof(buf_v4),
|
||||
NULL, 0, NI_NUMERICHOST);
|
||||
}
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
else if (their_addr->ss_family == AF_INET6)
|
||||
{
|
||||
str = buf_v6;
|
||||
@ -248,6 +245,7 @@ static void log_connection(const struct sockaddr_storage *their_addr,
|
||||
getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6),
|
||||
buf_v6, sizeof(buf_v6), NULL, 0, NI_NUMERICHOST);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (str)
|
||||
{
|
||||
@ -262,7 +260,7 @@ static bool init_tcp_socket(netplay_t *handle, const char *server, uint16_t port
|
||||
{
|
||||
struct addrinfo hints, *res = NULL;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
#ifdef _WIN32 // Lolol, no AF_UNSPEC, wtf.
|
||||
#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY)
|
||||
hints.ai_family = AF_INET;
|
||||
#else
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
@ -354,7 +352,7 @@ static bool init_udp_socket(netplay_t *handle, const char *server, uint16_t port
|
||||
{
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
#ifdef _WIN32 // Lolol, no AF_UNSPEC, wtf.
|
||||
#if defined(_WIN32) || defined(HAVE_SOCKET_LEGACY)
|
||||
hints.ai_family = AF_INET;
|
||||
#else
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
@ -398,8 +396,13 @@ static bool init_udp_socket(netplay_t *handle, const char *server, uint16_t port
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_socket(netplay_t *handle, const char *server, uint16_t port)
|
||||
// Platform specific socket library init.
|
||||
static bool init_network(void)
|
||||
{
|
||||
static bool inited = false;
|
||||
if (inited)
|
||||
return true;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
@ -411,13 +414,20 @@ static bool init_socket(netplay_t *handle, const char *server, uint16_t port)
|
||||
signal(SIGPIPE, SIG_IGN); // Do not like SIGPIPE killing our app :(
|
||||
#endif
|
||||
|
||||
inited = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_socket(netplay_t *handle, const char *server, uint16_t port)
|
||||
{
|
||||
if (!init_network())
|
||||
return false;
|
||||
|
||||
if (!init_tcp_socket(handle, server, port, handle->spectate))
|
||||
return false;
|
||||
if (!handle->spectate)
|
||||
{
|
||||
if (!init_udp_socket(handle, server, port))
|
||||
return false;
|
||||
}
|
||||
if (!handle->spectate && !init_udp_socket(handle, server, port))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
103
netplay_compat.c
Normal file
103
netplay_compat.c
Normal file
@ -0,0 +1,103 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "netplay_compat.h"
|
||||
|
||||
#undef getaddrinfo
|
||||
#undef freeaddrinfo
|
||||
#undef sockaddr_storage
|
||||
#undef addrinfo
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif defined(_XBOX)
|
||||
#include <Xtl.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#define addrinfo addrinfo_ssnes__
|
||||
|
||||
int getaddrinfo_ssnes__(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info));
|
||||
if (!info)
|
||||
return -1;
|
||||
|
||||
info->ai_family = PF_INET;
|
||||
info->ai_socktype = hints->ai_socktype;
|
||||
|
||||
struct sockaddr_in *in_addr = calloc(1, sizeof(*in_addr));
|
||||
if (!in_addr)
|
||||
{
|
||||
free(info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
info->ai_addrlen = sizeof(*in_addr);
|
||||
|
||||
in_addr->sin_family = AF_INET;
|
||||
in_addr->sin_port = htons(strtoul(service, NULL, 0));
|
||||
|
||||
if (!node && (hints->ai_flags & AI_PASSIVE))
|
||||
in_addr->sin_addr.s_addr = INADDR_ANY;
|
||||
else if (node && isdigit(*node))
|
||||
in_addr->sin_addr.s_addr = inet_addr(node);
|
||||
else if (node && !isdigit(*node))
|
||||
{
|
||||
struct hostent *host = gethostbyname(node);
|
||||
if (!host || !host->h_addr_list[0])
|
||||
goto error;
|
||||
|
||||
in_addr->sin_addr.s_addr = inet_addr(host->h_addr_list[0]);
|
||||
}
|
||||
else
|
||||
goto error;
|
||||
|
||||
info->ai_addr = (struct sockaddr*)in_addr;
|
||||
*res = info;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(in_addr);
|
||||
free(info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void freeaddrinfo_ssnes__(struct addrinfo *res)
|
||||
{
|
||||
free(res->ai_addr);
|
||||
free(res);
|
||||
}
|
||||
|
83
netplay_compat.h
Normal file
83
netplay_compat.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES 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.
|
||||
*
|
||||
* SSNES 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 SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NETPLAY_COMPAT_H__
|
||||
#define NETPLAY_COMPAT_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Woohoo, Winsock has headers from the STONE AGE! :D
|
||||
#define close(x) closesocket(x)
|
||||
#define CONST_CAST (const char*)
|
||||
#define NONCONST_CAST (char*)
|
||||
|
||||
#else
|
||||
|
||||
#define CONST_CAST
|
||||
#define NONCONST_CAST
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#define close(x) socketclose(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Compatibility layer for legacy or incomplete BSD socket implementations.
|
||||
// Only for IPv4. Mostly useful for the consoles which do not support
|
||||
// anything reasonably modern on the socket API side of things.
|
||||
|
||||
#ifdef HAVE_SOCKET_LEGACY
|
||||
|
||||
#define sockaddr_storage sockaddr_in
|
||||
#define addrinfo addrinfo_ssnes__
|
||||
#define getaddrinfo(serv, port, hints, res) getaddrinfo_ssnes__(serv, port, hints, res)
|
||||
#define freeaddrinfo(res) freeaddrinfo_ssnes__(res)
|
||||
|
||||
struct addrinfo
|
||||
{
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
struct sockaddr *ai_addr;
|
||||
char *ai_canonname;
|
||||
struct addrinfo *ai_next;
|
||||
};
|
||||
|
||||
int getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
|
||||
void freeaddrinfo(struct addrinfo *res);
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
#define AI_PASSIVE 1
|
||||
#endif
|
||||
|
||||
#define ss_family sin_family
|
||||
|
||||
// gai_strerror() not used, so we skip that.
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -33,7 +33,18 @@ fi
|
||||
|
||||
check_lib THREADS -lpthread pthread_create
|
||||
check_lib DYLIB $DYLIB dlopen
|
||||
|
||||
check_lib NETPLAY -lc socket
|
||||
if [ $HAVE_NETPLAY = yes ]; then
|
||||
HAVE_GETADDRINFO=auto
|
||||
check_lib GETADDRINFO -lc getaddrinfo
|
||||
if [ $HAVE_GETADDRINFO = yes ]; then
|
||||
HAVE_SOCKET_LEGACY=no
|
||||
else
|
||||
HAVE_SOCKET_LEGACY=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
check_lib GETOPT_LONG -lc getopt_long
|
||||
|
||||
if [ $HAVE_DYLIB = no ] && [ $HAVE_DYNAMIC = yes ]; then
|
||||
@ -124,7 +135,7 @@ check_pkgconf PYTHON python3
|
||||
add_define_make OS $OS
|
||||
|
||||
# Creates config.mk and config.h.
|
||||
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM X264RGB"
|
||||
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM X264RGB"
|
||||
create_config_make config.mk $VARS
|
||||
create_config_header config.h $VARS
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user