mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-13 18:30:32 +00:00
Merge pull request #13179 from hrydgard/platform-fixes-ANR2ME
Socket inconsistency platform fixes - broken out from #13123
This commit is contained in:
commit
7a6ffdb173
@ -955,7 +955,10 @@ static ConfigSetting controlSettings[] = {
|
||||
static ConfigSetting networkSettings[] = {
|
||||
ConfigSetting("EnableWlan", &g_Config.bEnableWlan, false, true, true),
|
||||
ConfigSetting("EnableAdhocServer", &g_Config.bEnableAdhocServer, false, true, true),
|
||||
ConfigSetting("proAdhocServer", &g_Config.proAdhocServer, "myneighborsushicat.com", true, true),
|
||||
ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true),
|
||||
ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true),
|
||||
ConfigSetting("MinTimeout", &g_Config.iMinTimeout, 1, true, true),
|
||||
|
||||
ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, true, true),
|
||||
ConfigSetting("ChatButtonPosition",&g_Config.iChatButtonPosition,BOTTOM_LEFT,true,true),
|
||||
@ -995,9 +998,7 @@ static ConfigSetting systemParamSettings[] = {
|
||||
ReportedConfigSetting("PSPModel", &g_Config.iPSPModel, &DefaultPSPModel, true, true),
|
||||
ReportedConfigSetting("PSPFirmwareVersion", &g_Config.iFirmwareVersion, PSP_DEFAULT_FIRMWARE, true, true),
|
||||
ConfigSetting("NickName", &g_Config.sNickName, "PPSSPP", true, true),
|
||||
ConfigSetting("proAdhocServer", &g_Config.proAdhocServer, "myneighborsushicat.com", true, true),
|
||||
ConfigSetting("MacAddress", &g_Config.sMACAddress, "", true, true),
|
||||
ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true),
|
||||
ReportedConfigSetting("Language", &g_Config.iLanguage, &DefaultSystemParamLanguage, true, true),
|
||||
ConfigSetting("ParamTimeFormat", &g_Config.iTimeFormat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR, true, true),
|
||||
ConfigSetting("ParamDateFormat", &g_Config.iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD, true, true),
|
||||
|
@ -396,9 +396,7 @@ public:
|
||||
|
||||
// SystemParam
|
||||
std::string sNickName;
|
||||
std::string proAdhocServer;
|
||||
std::string sMACAddress;
|
||||
int iPortOffset;
|
||||
int iLanguage;
|
||||
int iTimeFormat;
|
||||
int iDateFormat;
|
||||
@ -410,9 +408,12 @@ public:
|
||||
bool bSavedataUpgrade;
|
||||
|
||||
// Networking
|
||||
std::string proAdhocServer;
|
||||
bool bEnableWlan;
|
||||
bool bEnableAdhocServer;
|
||||
bool bEnableUPnP;
|
||||
int iPortOffset;
|
||||
int iMinTimeout;
|
||||
int iWlanAdhocChannel;
|
||||
bool bWlanPowerSave;
|
||||
bool bEnableNetworkChat;
|
||||
|
@ -42,7 +42,8 @@
|
||||
#include "proAdhoc.h"
|
||||
#include "i18n/i18n.h"
|
||||
|
||||
uint16_t portOffset = g_Config.iPortOffset;
|
||||
uint16_t portOffset;
|
||||
uint32_t minSocketTimeoutUS;
|
||||
uint32_t fakePoolSize = 0;
|
||||
SceNetAdhocMatchingContext * contexts = NULL;
|
||||
int one = 1;
|
||||
@ -75,6 +76,7 @@ int newChat = 0;
|
||||
bool isLocalServer = false;
|
||||
sockaddr LocalhostIP;
|
||||
sockaddr LocalIP;
|
||||
int defaultWlanChannel = 1;
|
||||
|
||||
bool isLocalMAC(const SceNetEtherAddr * addr) {
|
||||
SceNetEtherAddr saddr;
|
||||
@ -215,8 +217,8 @@ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC) {
|
||||
void changeBlockingMode(int fd, int nonblocking) {
|
||||
unsigned long on = 1;
|
||||
unsigned long off = 0;
|
||||
#ifdef _WIN32
|
||||
if (nonblocking){
|
||||
#if defined(_WIN32)
|
||||
if (nonblocking) {
|
||||
// Change to Non-Blocking Mode
|
||||
ioctlsocket(fd, FIONBIO, &on);
|
||||
}
|
||||
@ -224,14 +226,31 @@ void changeBlockingMode(int fd, int nonblocking) {
|
||||
// Change to Blocking Mode
|
||||
ioctlsocket(fd, FIONBIO, &off);
|
||||
}
|
||||
// If they have O_NONBLOCK, use the POSIX way to do it. On POSIX sockets Error code would be EINPROGRESS instead of EAGAIN
|
||||
//#elif defined(O_NONBLOCK)
|
||||
#else
|
||||
if(nonblocking == 1) fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
// Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5.
|
||||
if (flags == -1)
|
||||
flags = 0;
|
||||
if (nonblocking) {
|
||||
// Set Non-Blocking Flag
|
||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
else {
|
||||
// Get Flags
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
// Remove Non-Blocking Flag
|
||||
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
// Otherwise, use the old way of doing it (UNIX way). On UNIX sockets Error code would be EAGAIN instead of EINPROGRESS
|
||||
/*#else
|
||||
if (nonblocking) {
|
||||
// Change to Non - Blocking Mode
|
||||
ioctl(fd, FIONBIO, (char*)&on);
|
||||
}
|
||||
else {
|
||||
// Change to Blocking Mode
|
||||
ioctl(fd, FIONBIO, (char*)&off);
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1221,7 +1240,7 @@ int friendFinder(){
|
||||
}*/
|
||||
|
||||
// Update User BSSID
|
||||
//parameter.bssid.mac_addr = packet->mac; // The MAC address in this packet seems to Always be the First player joining the Group (group Creator?), Shouldn't it be it self?
|
||||
//parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address
|
||||
// Notify Event Handlers
|
||||
//notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0);
|
||||
// Change State
|
||||
@ -1398,7 +1417,8 @@ int friendFinder(){
|
||||
group->bssid.mac_addr = packet->mac;
|
||||
|
||||
// Set group parameters
|
||||
group->channel = parameter.channel;
|
||||
// Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?)
|
||||
group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel;
|
||||
group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode;
|
||||
|
||||
// Link into Group List
|
||||
@ -1613,6 +1633,16 @@ uint16_t getLocalPort(int sock) {
|
||||
return ntohs(localAddr.sin_port);
|
||||
}
|
||||
|
||||
int getSockMaxSize(int udpsock) {
|
||||
#if !defined(SO_MAX_MSG_SIZE)
|
||||
#define SO_MAX_MSG_SIZE 0x2003
|
||||
#endif
|
||||
int n = 1500; // Typical MTU size as default
|
||||
socklen_t m = sizeof(n);
|
||||
getsockopt(udpsock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&n, &m);
|
||||
return n;
|
||||
}
|
||||
|
||||
int getSockBufferSize(int sock, int opt) { // opt = SO_RCVBUF/SO_SNDBUF
|
||||
int n = 16384;
|
||||
socklen_t m = sizeof(n);
|
||||
@ -1625,22 +1655,49 @@ int setSockBufferSize(int sock, int opt, int size) { // opt = SO_RCVBUF/SO_SNDBU
|
||||
return setsockopt(sock, SOL_SOCKET, opt, (char *)&n, sizeof(n));
|
||||
}
|
||||
|
||||
int setSockTimeout(int sock, int opt, unsigned long timeout_usec) { // opt = SO_SNDTIMEO/SO_RCVTIMEO
|
||||
if (timeout_usec > 0 && timeout_usec < minSocketTimeoutUS) timeout_usec = minSocketTimeoutUS; // Override timeout for high latency multiplayer
|
||||
#if defined(_WIN32)
|
||||
unsigned long optval = timeout_usec / 1000UL;
|
||||
if (timeout_usec > 0 && optval == 0) optval = 1; // Since there are games that use 100 usec timeout, we should set it to minimum value on Windows (1 msec) instead of using 0 (0 = indefinitely timeout)
|
||||
#elif defined(__APPLE__)
|
||||
struct timeval optval;
|
||||
optval.tv_sec = static_cast<long>(timeout_usec) / 1000000L;
|
||||
optval.tv_usec = static_cast<long>(timeout_usec) % 1000000L;
|
||||
#else
|
||||
struct timeval optval = { static_cast<long>(timeout_usec) / 1000000L, static_cast<long>(timeout_usec) % 1000000L };
|
||||
#endif
|
||||
return setsockopt(sock, SOL_SOCKET, opt, (char*)&optval, sizeof(optval));
|
||||
}
|
||||
|
||||
int getSockNoDelay(int tcpsock) {
|
||||
int opt = 0;
|
||||
socklen_t optlen = sizeof(opt);
|
||||
getsockopt(tcpsock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, &optlen);
|
||||
return opt;
|
||||
}
|
||||
|
||||
int setSockNoDelay(int tcpsock, int flag) {
|
||||
int opt = flag;
|
||||
return setsockopt(tcpsock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
|
||||
}
|
||||
|
||||
#if !defined(TCP_KEEPIDLE)
|
||||
#define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS
|
||||
#endif
|
||||
int setSockKeepAlive(int sock, bool keepalive, const int keepcnt, const int keepidle, const int keepinvl) {
|
||||
int setSockKeepAlive(int sock, bool keepalive, const int keepinvl, const int keepcnt, const int keepidle) {
|
||||
int optval = keepalive ? 1 : 0;
|
||||
int optlen = sizeof(optval);
|
||||
int result = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, optlen);
|
||||
if (result == 0 && keepalive) {
|
||||
if (getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&optval, (socklen_t*)&optlen) == 0 && optval == SOCK_STREAM) {
|
||||
optlen = sizeof(optval);
|
||||
optval = keepidle; //180 sec
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&optval, optlen);
|
||||
optval = keepinvl; //60 sec
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&optval, optlen);
|
||||
optval = keepcnt; //20
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (char*)&optval, optlen);
|
||||
optval = keepidle; //180
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&optval, optlen);
|
||||
optval = keepinvl; //60
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&optval, optlen);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -1757,8 +1814,9 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
|
||||
memset(¶meter, 0, sizeof(parameter));
|
||||
strncpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN);
|
||||
parameter.nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0;
|
||||
parameter.channel = g_Config.iWlanAdhocChannel; // Fake Channel, 0 = Auto where JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11)
|
||||
if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = 1;
|
||||
parameter.channel = g_Config.iWlanAdhocChannel;
|
||||
// Assign a Valid Channel when connected to AP/AdhocGroup if it's Auto. JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11)
|
||||
if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = defaultWlanChannel; // Faked Active channel to default channel
|
||||
getLocalMac(¶meter.bssid.mac_addr);
|
||||
|
||||
// Default ProductId
|
||||
|
@ -65,6 +65,7 @@
|
||||
#undef EINPROGRESS
|
||||
#undef EISCONN
|
||||
#undef EALREADY
|
||||
#undef ETIMEDOUT
|
||||
#define errno WSAGetLastError()
|
||||
#define ECONNABORTED WSAECONNABORTED
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
@ -73,12 +74,13 @@
|
||||
#define EINPROGRESS WSAEWOULDBLOCK
|
||||
#define EISCONN WSAEISCONN
|
||||
#define EALREADY WSAEALREADY
|
||||
#define ETIMEDOUT WSAETIMEDOUT
|
||||
inline bool connectInProgress(int errcode){ return (errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == WSAEALREADY); }
|
||||
#else
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKET_ERROR -1
|
||||
#define closesocket close
|
||||
inline bool connectInProgress(int errcode){ return (errcode == EINPROGRESS || errcode == EALREADY); }
|
||||
inline bool connectInProgress(int errcode){ return (errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EALREADY); }
|
||||
#endif
|
||||
|
||||
#ifndef POLL_ERR
|
||||
@ -240,10 +242,10 @@ typedef struct SceNetAdhocctlNickname {
|
||||
uint8_t data[ADHOCCTL_NICKNAME_LEN];
|
||||
} PACK SceNetAdhocctlNickname;
|
||||
|
||||
// Active Virtual Network Information
|
||||
// Active Virtual Network Information (Adhoc Group Host/Creator's device info, similar to AP?)
|
||||
typedef struct SceNetAdhocctlParameter {
|
||||
s32_le channel;
|
||||
SceNetAdhocctlGroupName group_name;
|
||||
SceNetAdhocctlGroupName group_name; // This group name is probably similar to SSID name on AP
|
||||
SceNetAdhocctlBSSId bssid;
|
||||
SceNetAdhocctlNickname nickname;
|
||||
} PACK SceNetAdhocctlParameter;
|
||||
@ -841,9 +843,11 @@ extern SceNetAdhocPdpStat * pdp[255];
|
||||
extern SceNetAdhocPtpStat * ptp[255];
|
||||
|
||||
extern uint16_t portOffset;
|
||||
extern uint32_t minSocketTimeoutUS;
|
||||
extern bool isLocalServer;
|
||||
extern sockaddr LocalhostIP; // Used to differentiate localhost IP on multiple-instance
|
||||
extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN)
|
||||
extern int defaultWlanChannel; // Default WLAN Channel for Auto, JPCSP uses 11
|
||||
|
||||
extern uint32_t fakePoolSize;
|
||||
extern SceNetAdhocMatchingContext * contexts;
|
||||
@ -1155,6 +1159,11 @@ int getActivePeerCount(const bool excludeTimedout = true);
|
||||
int getLocalIp(sockaddr_in * SocketAddress);
|
||||
uint32_t getLocalIp(int sock);
|
||||
|
||||
/*
|
||||
* Get UDP Socket Max Message Size
|
||||
*/
|
||||
int getSockMaxSize(int udpsock);
|
||||
|
||||
/*
|
||||
* Get Socket Buffer Size (opt = SO_RCVBUF/SO_SNDBUF)
|
||||
*/
|
||||
@ -1165,10 +1174,25 @@ int getSockBufferSize(int sock, int opt);
|
||||
*/
|
||||
int setSockBufferSize(int sock, int opt, int size);
|
||||
|
||||
/*
|
||||
* Set Socket TimeOut (opt = SO_SNDTIMEO/SO_RCVTIMEO)
|
||||
*/
|
||||
int setSockTimeout(int sock, int opt, unsigned long timeout_usec);
|
||||
|
||||
/*
|
||||
* Get TCP Socket TCP_NODELAY (Nagle Algo)
|
||||
*/
|
||||
int getSockNoDelay(int tcpsock);
|
||||
|
||||
/*
|
||||
* Set TCP Socket TCP_NODELAY (Nagle Algo)
|
||||
*/
|
||||
int setSockNoDelay(int tcpsock, int flag);
|
||||
|
||||
/*
|
||||
* Set Socket KeepAlive (opt = SO_KEEPALIVE)
|
||||
*/
|
||||
int setSockKeepAlive(int sock, bool keepalive, const int keepcnt = 20, const int keepidle = 180, const int keepinvl = 60);
|
||||
int setSockKeepAlive(int sock, bool keepalive, const int keepinvl = 60, const int keepcnt = 20, const int keepidle = 180);
|
||||
|
||||
/**
|
||||
* Return the Number of Players with the chosen Nickname in the Local Users current Network
|
||||
|
@ -37,6 +37,7 @@
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
@ -476,6 +477,8 @@ const char * strcpyxml(char * out, const char * in, uint32_t size);
|
||||
// Function Prototypes
|
||||
void interrupt(int sig);
|
||||
void enable_address_reuse(int fd);
|
||||
void enable_keepalive(int fd);
|
||||
void change_nodelay_mode(int fd, int flag);
|
||||
void change_blocking_mode(int fd, int nonblocking);
|
||||
int create_listen_socket(uint16_t port);
|
||||
int server_loop(int server);
|
||||
@ -1743,6 +1746,17 @@ void enable_keepalive(int fd)
|
||||
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(on));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change TCP Socket TCP_NODELAY (Nagle Algo) mode
|
||||
* @param fd Socket
|
||||
* @param nonblocking 1 for Nonblocking, 0 for Blocking
|
||||
*/
|
||||
void change_nodelay_mode(int fd, int flag)
|
||||
{
|
||||
int opt = flag;
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change Socket Blocking Mode
|
||||
* @param fd Socket
|
||||
@ -1799,6 +1813,9 @@ int create_listen_socket(uint16_t port)
|
||||
// Make Socket Nonblocking
|
||||
change_blocking_mode(fd, 1);
|
||||
|
||||
// Make TCP Socket send immediately
|
||||
change_nodelay_mode(fd, 1);
|
||||
|
||||
// Prepare Local Address Information
|
||||
struct sockaddr_in local;
|
||||
memset(&local, 0, sizeof(local));
|
||||
|
@ -112,10 +112,13 @@ static void __ResetInitNetLib() {
|
||||
netInetInited = false;
|
||||
|
||||
memset(&netMallocStat, 0, sizeof(netMallocStat));
|
||||
memset(¶meter, 0, sizeof(parameter));
|
||||
}
|
||||
|
||||
void __NetInit() {
|
||||
// Windows: Assuming WSAStartup already called beforehand
|
||||
portOffset = g_Config.iPortOffset;
|
||||
minSocketTimeoutUS = g_Config.iMinTimeout * 1000UL;
|
||||
|
||||
InitLocalhostIP();
|
||||
|
||||
@ -149,8 +152,6 @@ void __NetShutdown() {
|
||||
g_PortManager.Restore();
|
||||
g_PortManager.Deinit();
|
||||
}
|
||||
|
||||
//PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset
|
||||
}
|
||||
|
||||
static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) {
|
||||
@ -251,6 +252,8 @@ static u32 sceNetTerm() {
|
||||
FreeUser(netThread1Addr);
|
||||
FreeUser(netThread2Addr);
|
||||
|
||||
// Give time to make sure everything are cleaned up
|
||||
hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1091,7 +1091,7 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) {
|
||||
// Exchange Adhoc Channel
|
||||
// sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL, &buf[discovered].channel);
|
||||
|
||||
// Fake Channel Number 1 on Automatic Channel
|
||||
// Fake Channel Number 1 on Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?)
|
||||
buf[discovered].channel = group->channel; //parameter.channel
|
||||
|
||||
// Increase Discovery Counter
|
||||
|
@ -104,6 +104,7 @@ bool PortManager::Init(const unsigned int timeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_leaseDuration = "43200"; // 12 hours
|
||||
m_InitState = UPNP_INITSTATE_BUSY;
|
||||
urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls));
|
||||
@ -165,6 +166,7 @@ bool PortManager::Init(const unsigned int timeout) {
|
||||
RefreshPortList();
|
||||
return true;
|
||||
}
|
||||
|
||||
ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %i) or No UPnP device detected", error);
|
||||
auto n = GetI18NCategory("Networking");
|
||||
host->NotifyUserMessage(n->T("Unable to find UPnP device"), 6.0f, 0x0000ff);
|
||||
|
@ -692,7 +692,14 @@ void GameSettingsScreen::CreateViews() {
|
||||
networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server")));
|
||||
networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)")));
|
||||
networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress);
|
||||
static const char* wlanChannels[] = { "Auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" };
|
||||
auto wlanChannelChoice = networkingSettings->Add(new PopupMultiChoice(&g_Config.iWlanAdhocChannel, gr->T("WLAN Channel"), wlanChannels, 0, ARRAY_SIZE(wlanChannels), gr->GetName(), screenManager()));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wlanChannelChoice->HideChoice(i+2);
|
||||
wlanChannelChoice->HideChoice(i+7);
|
||||
}
|
||||
networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset(0 = PSP compatibility)"), 100, screenManager()));
|
||||
networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency communication in milliseconds)"), 100, screenManager()));
|
||||
|
||||
networkingSettings->Add(new ItemHeader(n->T("Chat")));
|
||||
networkingSettings->Add(new CheckBox(&g_Config.bEnableNetworkChat, n->T("Enable network chat", "Enable network chat")));
|
||||
|
Loading…
x
Reference in New Issue
Block a user