ggpo: report UDP bind error. Better error reporting for net init
fix ggpo lib warnings
This commit is contained in:
parent
699dcdaf5b
commit
a6248905a0
|
@ -113,7 +113,8 @@ typedef struct GGPOLocalEndpoint {
|
||||||
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_PLAYER_DISCONNECTED, 9) \
|
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_PLAYER_DISCONNECTED, 9) \
|
||||||
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_TOO_MANY_SPECTATORS, 10) \
|
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_TOO_MANY_SPECTATORS, 10) \
|
||||||
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INVALID_REQUEST, 11) \
|
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INVALID_REQUEST, 11) \
|
||||||
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INPUT_SIZE_DIFF, 12)
|
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INPUT_SIZE_DIFF, 12) \
|
||||||
|
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_NETWORK_ERROR, 13)
|
||||||
|
|
||||||
#define GGPO_ERRORLIST_ENTRY(name, value) name = value,
|
#define GGPO_ERRORLIST_ENTRY(name, value) name = value,
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -18,13 +18,14 @@ Peer2PeerBackend::Peer2PeerBackend(GGPOSessionCallbacks *cb,
|
||||||
uint16 localport,
|
uint16 localport,
|
||||||
int num_players,
|
int num_players,
|
||||||
int input_size) :
|
int input_size) :
|
||||||
_num_players(num_players),
|
|
||||||
_input_size(input_size),
|
|
||||||
_sync(_local_connect_status),
|
_sync(_local_connect_status),
|
||||||
_disconnect_timeout(DEFAULT_DISCONNECT_TIMEOUT),
|
_endpoints(nullptr),
|
||||||
_disconnect_notify_start(DEFAULT_DISCONNECT_NOTIFY_START),
|
|
||||||
_num_spectators(0),
|
_num_spectators(0),
|
||||||
_next_spectator_frame(0)
|
_input_size(input_size),
|
||||||
|
_num_players(num_players),
|
||||||
|
_next_spectator_frame(0),
|
||||||
|
_disconnect_timeout(DEFAULT_DISCONNECT_TIMEOUT),
|
||||||
|
_disconnect_notify_start(DEFAULT_DISCONNECT_NOTIFY_START)
|
||||||
{
|
{
|
||||||
_callbacks = *cb;
|
_callbacks = *cb;
|
||||||
_synchronizing = true;
|
_synchronizing = true;
|
||||||
|
@ -47,7 +48,7 @@ Peer2PeerBackend::Peer2PeerBackend(GGPOSessionCallbacks *cb,
|
||||||
|
|
||||||
_endpoints = new UdpProtocol[_num_players];
|
_endpoints = new UdpProtocol[_num_players];
|
||||||
memset(_local_connect_status, 0, sizeof(_local_connect_status));
|
memset(_local_connect_status, 0, sizeof(_local_connect_status));
|
||||||
for (int i = 0; i < ARRAY_SIZE(_local_connect_status); i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(_local_connect_status); i++) {
|
||||||
_local_connect_status[i].last_frame = -1;
|
_local_connect_status[i].last_frame = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +387,9 @@ Peer2PeerBackend::OnUdpProtocolPeerEvent(UdpProtocol::Event &evt, int queue)
|
||||||
case UdpProtocol::Event::Disconnected:
|
case UdpProtocol::Event::Disconnected:
|
||||||
DisconnectPlayer(QueueToPlayerHandle(queue));
|
DisconnectPlayer(QueueToPlayerHandle(queue));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,17 +400,14 @@ Peer2PeerBackend::OnUdpProtocolSpectatorEvent(UdpProtocol::Event &evt, int queue
|
||||||
GGPOPlayerHandle handle = QueueToSpectatorHandle(queue);
|
GGPOPlayerHandle handle = QueueToSpectatorHandle(queue);
|
||||||
OnUdpProtocolEvent(evt, handle);
|
OnUdpProtocolEvent(evt, handle);
|
||||||
|
|
||||||
GGPOEvent info;
|
if (evt.type == UdpProtocol::Event::Disconnected)
|
||||||
|
{
|
||||||
switch (evt.type) {
|
|
||||||
case UdpProtocol::Event::Disconnected:
|
|
||||||
_spectators[queue].Disconnect();
|
_spectators[queue].Disconnect();
|
||||||
|
|
||||||
|
GGPOEvent info;
|
||||||
info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
|
info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
|
||||||
info.u.disconnected.player = handle;
|
info.u.disconnected.player = handle;
|
||||||
_callbacks.on_event(&info);
|
_callbacks.on_event(&info);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +449,9 @@ Peer2PeerBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt, GGPOPlayerHandle h
|
||||||
info.u.connection_resumed.player = handle;
|
info.u.connection_resumed.player = handle;
|
||||||
_callbacks.on_event(&info);
|
_callbacks.on_event(&info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,12 +155,17 @@ SpectatorBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UdpProtocol::Event::Input:
|
case UdpProtocol::Event::Input:
|
||||||
GameInput& input = evt.u.input.input;
|
{
|
||||||
|
GameInput& input = evt.u.input.input;
|
||||||
|
|
||||||
_host.SetLocalFrameNumber(input.frame);
|
_host.SetLocalFrameNumber(input.frame);
|
||||||
_host.SendInputAck();
|
_host.SendInputAck();
|
||||||
_inputs[input.frame % SPECTATOR_FRAME_BUFFER_SIZE] = input;
|
_inputs[input.frame % SPECTATOR_FRAME_BUFFER_SIZE] = input;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,12 @@ void
|
||||||
Udp::Init(uint16 port, Poll *poll, Callbacks *callbacks)
|
Udp::Init(uint16 port, Poll *poll, Callbacks *callbacks)
|
||||||
{
|
{
|
||||||
_callbacks = callbacks;
|
_callbacks = callbacks;
|
||||||
|
poll->RegisterLoop(this);
|
||||||
_poll = poll;
|
|
||||||
_poll->RegisterLoop(this);
|
|
||||||
|
|
||||||
Log("binding udp socket to port %d.\n", port);
|
Log("binding udp socket to port %d.\n", port);
|
||||||
_socket = CreateSocket(port, 0);
|
_socket = CreateSocket(port, 0);
|
||||||
|
if (_socket == INVALID_SOCKET)
|
||||||
|
throw GGPOException("Socket creation or bind failed", GGPO_ERRORCODE_NETWORK_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -53,7 +53,6 @@ protected:
|
||||||
|
|
||||||
// state management
|
// state management
|
||||||
Callbacks *_callbacks;
|
Callbacks *_callbacks;
|
||||||
Poll *_poll;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,24 +22,24 @@ static const int UDP_SHUTDOWN_TIMER = 5000;
|
||||||
static const int MAX_SEQ_DISTANCE = (1 << 15);
|
static const int MAX_SEQ_DISTANCE = (1 << 15);
|
||||||
|
|
||||||
UdpProtocol::UdpProtocol() :
|
UdpProtocol::UdpProtocol() :
|
||||||
_local_frame_advantage(0),
|
_udp(NULL),
|
||||||
_remote_frame_advantage(0),
|
|
||||||
_queue(-1),
|
|
||||||
_magic_number(0),
|
_magic_number(0),
|
||||||
|
_queue(-1),
|
||||||
_remote_magic_number(0),
|
_remote_magic_number(0),
|
||||||
|
_connected(false),
|
||||||
_packets_sent(0),
|
_packets_sent(0),
|
||||||
_bytes_sent(0),
|
_bytes_sent(0),
|
||||||
_stats_start_time(0),
|
_stats_start_time(0),
|
||||||
|
_local_frame_advantage(0),
|
||||||
|
_remote_frame_advantage(0),
|
||||||
_last_send_time(0),
|
_last_send_time(0),
|
||||||
_shutdown_timeout(0),
|
_shutdown_timeout(0),
|
||||||
|
_disconnect_event_sent(false),
|
||||||
_disconnect_timeout(0),
|
_disconnect_timeout(0),
|
||||||
_disconnect_notify_start(0),
|
_disconnect_notify_start(0),
|
||||||
_disconnect_notify_sent(false),
|
_disconnect_notify_sent(false),
|
||||||
_disconnect_event_sent(false),
|
|
||||||
_connected(false),
|
|
||||||
_next_send_seq(0),
|
_next_send_seq(0),
|
||||||
_next_recv_seq(0),
|
_next_recv_seq(0)
|
||||||
_udp(NULL)
|
|
||||||
{
|
{
|
||||||
_last_sent_input.init(-1, NULL, 1);
|
_last_sent_input.init(-1, NULL, 1);
|
||||||
_last_received_input.init(-1, NULL, 1);
|
_last_received_input.init(-1, NULL, 1);
|
||||||
|
@ -47,7 +47,7 @@ UdpProtocol::UdpProtocol() :
|
||||||
|
|
||||||
memset(&_state, 0, sizeof _state);
|
memset(&_state, 0, sizeof _state);
|
||||||
memset(_peer_connect_status, 0, sizeof(_peer_connect_status));
|
memset(_peer_connect_status, 0, sizeof(_peer_connect_status));
|
||||||
for (int i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
|
||||||
_peer_connect_status[i].last_frame = -1;
|
_peer_connect_status[i].last_frame = -1;
|
||||||
}
|
}
|
||||||
memset(&_peer_addr, 0, sizeof _peer_addr);
|
memset(&_peer_addr, 0, sizeof _peer_addr);
|
||||||
|
@ -123,7 +123,7 @@ UdpProtocol::SendPendingOutput()
|
||||||
msg->u.input.start_frame = _pending_output.front().frame;
|
msg->u.input.start_frame = _pending_output.front().frame;
|
||||||
msg->u.input.input_size = (uint8)_pending_output.front().size;
|
msg->u.input.input_size = (uint8)_pending_output.front().size;
|
||||||
|
|
||||||
ASSERT(last.frame == -1 || last.frame + 1 == msg->u.input.start_frame);
|
ASSERT(last.frame == -1 || last.frame + 1 == (int)msg->u.input.start_frame);
|
||||||
for (j = 0; j < _pending_output.size(); j++) {
|
for (j = 0; j < _pending_output.size(); j++) {
|
||||||
GameInput ¤t = _pending_output.item(j);
|
GameInput ¤t = _pending_output.item(j);
|
||||||
if (memcmp(current.bits, last.bits, current.size) != 0) {
|
if (memcmp(current.bits, last.bits, current.size) != 0) {
|
||||||
|
@ -249,7 +249,10 @@ UdpProtocol::OnLoopPoll(void *cookie)
|
||||||
_udp = NULL;
|
_udp = NULL;
|
||||||
_shutdown_timeout = 0;
|
_shutdown_timeout = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -455,11 +458,8 @@ UdpProtocol::LogMsg(const char *prefix, UdpMsg *msg)
|
||||||
void
|
void
|
||||||
UdpProtocol::LogEvent(const char *prefix, const UdpProtocol::Event &evt)
|
UdpProtocol::LogEvent(const char *prefix, const UdpProtocol::Event &evt)
|
||||||
{
|
{
|
||||||
switch (evt.type) {
|
if (evt.type == UdpProtocol::Event::Synchronzied)
|
||||||
case UdpProtocol::Event::Synchronzied:
|
|
||||||
Log("%s (event: Synchronzied).\n", prefix);
|
Log("%s (event: Synchronzied).\n", prefix);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -545,7 +545,7 @@ UdpProtocol::OnInput(UdpMsg *msg, int len)
|
||||||
* of the network.
|
* of the network.
|
||||||
*/
|
*/
|
||||||
UdpMsg::connect_status* remote_status = msg->u.input.peer_connect_status;
|
UdpMsg::connect_status* remote_status = msg->u.input.peer_connect_status;
|
||||||
for (int i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
|
||||||
ASSERT(remote_status[i].last_frame >= _peer_connect_status[i].last_frame);
|
ASSERT(remote_status[i].last_frame >= _peer_connect_status[i].last_frame);
|
||||||
_peer_connect_status[i].disconnected = _peer_connect_status[i].disconnected || remote_status[i].disconnected;
|
_peer_connect_status[i].disconnected = _peer_connect_status[i].disconnected || remote_status[i].disconnected;
|
||||||
_peer_connect_status[i].last_frame = MAX(_peer_connect_status[i].last_frame, remote_status[i].last_frame);
|
_peer_connect_status[i].last_frame = MAX(_peer_connect_status[i].last_frame, remote_status[i].last_frame);
|
||||||
|
@ -734,7 +734,7 @@ UdpProtocol::PumpSendQueue()
|
||||||
// should really come up with a gaussian distributation based on the configured
|
// should really come up with a gaussian distributation based on the configured
|
||||||
// value, but this will do for now.
|
// value, but this will do for now.
|
||||||
int jitter = (_send_latency * 2 / 3) + ((rand() % _send_latency) / 3);
|
int jitter = (_send_latency * 2 / 3) + ((rand() % _send_latency) / 3);
|
||||||
if (Platform::GetCurrentTimeMS() < _send_queue.front().queue_time + jitter) {
|
if ((int)Platform::GetCurrentTimeMS() < _send_queue.front().queue_time + jitter) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -754,7 +754,7 @@ UdpProtocol::PumpSendQueue()
|
||||||
}
|
}
|
||||||
_send_queue.pop();
|
_send_queue.pop();
|
||||||
}
|
}
|
||||||
if (_oo_packet.msg && _oo_packet.send_time < Platform::GetCurrentTimeMS()) {
|
if (_oo_packet.msg && _oo_packet.send_time < (int)Platform::GetCurrentTimeMS()) {
|
||||||
Log("sending rogue oop!");
|
Log("sending rogue oop!");
|
||||||
_udp->SendTo((char *)_oo_packet.msg, _oo_packet.msg->PacketSize(), 0,
|
_udp->SendTo((char *)_oo_packet.msg, _oo_packet.msg->PacketSize(), 0,
|
||||||
(struct sockaddr *)&_oo_packet.dest_addr, sizeof _oo_packet.dest_addr);
|
(struct sockaddr *)&_oo_packet.dest_addr, sizeof _oo_packet.dest_addr);
|
||||||
|
|
|
@ -375,7 +375,7 @@ void startSession(int localPort, int localPlayerNum)
|
||||||
{
|
{
|
||||||
WARN_LOG(NETWORK, "GGPO start sync session failed: %d", result);
|
WARN_LOG(NETWORK, "GGPO start sync session failed: %d", result);
|
||||||
ggpoSession = nullptr;
|
ggpoSession = nullptr;
|
||||||
return;
|
throw FlycastException("GGPO start sync session failed");
|
||||||
}
|
}
|
||||||
ggpo_idle(ggpoSession, 0);
|
ggpo_idle(ggpoSession, 0);
|
||||||
ggpo::localPlayerNum = localPlayerNum;
|
ggpo::localPlayerNum = localPlayerNum;
|
||||||
|
@ -413,7 +413,7 @@ void startSession(int localPort, int localPlayerNum)
|
||||||
{
|
{
|
||||||
WARN_LOG(NETWORK, "GGPO start session failed: %d", result);
|
WARN_LOG(NETWORK, "GGPO start session failed: %d", result);
|
||||||
ggpoSession = nullptr;
|
ggpoSession = nullptr;
|
||||||
return;
|
throw FlycastException("GGPO network initialization failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// automatically disconnect clients after 3000 ms and start our count-down timer
|
// automatically disconnect clients after 3000 ms and start our count-down timer
|
||||||
|
@ -429,7 +429,7 @@ void startSession(int localPort, int localPlayerNum)
|
||||||
{
|
{
|
||||||
WARN_LOG(NETWORK, "GGPO cannot add local player: %d", result);
|
WARN_LOG(NETWORK, "GGPO cannot add local player: %d", result);
|
||||||
stopSession();
|
stopSession();
|
||||||
return;
|
throw FlycastException("GGPO cannot add local player");
|
||||||
}
|
}
|
||||||
ggpo_set_frame_delay(ggpoSession, localPlayer, config::GGPODelay.get());
|
ggpo_set_frame_delay(ggpoSession, localPlayer, config::GGPODelay.get());
|
||||||
|
|
||||||
|
@ -458,6 +458,7 @@ void startSession(int localPort, int localPlayerNum)
|
||||||
{
|
{
|
||||||
WARN_LOG(NETWORK, "GGPO cannot add remote player: %d", result);
|
WARN_LOG(NETWORK, "GGPO cannot add remote player: %d", result);
|
||||||
stopSession();
|
stopSession();
|
||||||
|
throw FlycastException("GGPO cannot add remote player");
|
||||||
}
|
}
|
||||||
DEBUG_LOG(NETWORK, "GGPO session started");
|
DEBUG_LOG(NETWORK, "GGPO session started");
|
||||||
#endif
|
#endif
|
||||||
|
@ -616,11 +617,16 @@ std::future<bool> startNetwork()
|
||||||
miniupnp.Init();
|
miniupnp.Init();
|
||||||
miniupnp.AddPortMapping(SERVER_PORT, false);
|
miniupnp.AddPortMapping(SERVER_PORT, false);
|
||||||
|
|
||||||
if (config::ActAsServer)
|
try {
|
||||||
startSession(SERVER_PORT, 0);
|
if (config::ActAsServer)
|
||||||
else
|
startSession(SERVER_PORT, 0);
|
||||||
// Use SERVER_PORT-1 as local port if connecting to ourselves
|
else
|
||||||
startSession(config::NetworkServer.get().empty() || config::NetworkServer.get() == "127.0.0.1" ? SERVER_PORT - 1 : SERVER_PORT, 1);
|
// Use SERVER_PORT-1 as local port if connecting to ourselves
|
||||||
|
startSession(config::NetworkServer.get().empty() || config::NetworkServer.get() == "127.0.0.1" ? SERVER_PORT - 1 : SERVER_PORT, 1);
|
||||||
|
} catch (...) {
|
||||||
|
miniupnp.Term();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
while (!synchronized && active())
|
while (!synchronized && active())
|
||||||
|
|
|
@ -49,6 +49,7 @@ bool MiniUPnP::Init()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wanAddress[0] = 0;
|
wanAddress[0] = 0;
|
||||||
|
initialized = true;
|
||||||
if (UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddress) != 0)
|
if (UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddress) != 0)
|
||||||
WARN_LOG(NETWORK, "Cannot determine external IP address");
|
WARN_LOG(NETWORK, "Cannot determine external IP address");
|
||||||
DEBUG_LOG(NETWORK, "MiniUPnP: public IP is %s", wanAddress);
|
DEBUG_LOG(NETWORK, "MiniUPnP: public IP is %s", wanAddress);
|
||||||
|
@ -57,12 +58,15 @@ bool MiniUPnP::Init()
|
||||||
|
|
||||||
void MiniUPnP::Term()
|
void MiniUPnP::Term()
|
||||||
{
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return;
|
||||||
DEBUG_LOG(NETWORK, "MiniUPnP::Term");
|
DEBUG_LOG(NETWORK, "MiniUPnP::Term");
|
||||||
for (const auto& port : mappedPorts)
|
for (const auto& port : mappedPorts)
|
||||||
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.first.c_str(),
|
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.first.c_str(),
|
||||||
port.second ? "TCP" : "UDP", nullptr);
|
port.second ? "TCP" : "UDP", nullptr);
|
||||||
mappedPorts.clear();
|
mappedPorts.clear();
|
||||||
FreeUPNPUrls(&urls);
|
FreeUPNPUrls(&urls);
|
||||||
|
initialized = false;
|
||||||
DEBUG_LOG(NETWORK, "MiniUPnP: terminated");
|
DEBUG_LOG(NETWORK, "MiniUPnP: terminated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ private:
|
||||||
char lanAddress[32];
|
char lanAddress[32];
|
||||||
char wanAddress[32];
|
char wanAddress[32];
|
||||||
std::vector<std::pair<std::string, bool>> mappedPorts;
|
std::vector<std::pair<std::string, bool>> mappedPorts;
|
||||||
|
bool initialized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -2194,15 +2194,22 @@ static void gui_network_start()
|
||||||
|
|
||||||
if (networkStatus.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
if (networkStatus.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
||||||
{
|
{
|
||||||
if (networkStatus.get())
|
try {
|
||||||
{
|
if (networkStatus.get())
|
||||||
gui_state = GuiState::Closed;
|
{
|
||||||
ImGui::Text("STARTING...");
|
gui_state = GuiState::Closed;
|
||||||
}
|
ImGui::Text("STARTING...");
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
|
{
|
||||||
|
gui_state = GuiState::Main;
|
||||||
|
emu.unloadGame();
|
||||||
|
}
|
||||||
|
} catch (const FlycastException& e) {
|
||||||
|
NetworkHandshake::instance->stop();
|
||||||
gui_state = GuiState::Main;
|
gui_state = GuiState::Main;
|
||||||
settings.content.path.clear();
|
emu.unloadGame();
|
||||||
|
error_msg = e.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2219,9 +2226,12 @@ static void gui_network_start()
|
||||||
if (ImGui::Button("Cancel", ImVec2(100.f * scaling, 0.f)))
|
if (ImGui::Button("Cancel", ImVec2(100.f * scaling, 0.f)))
|
||||||
{
|
{
|
||||||
NetworkHandshake::instance->stop();
|
NetworkHandshake::instance->stop();
|
||||||
networkStatus.get();
|
try {
|
||||||
|
networkStatus.get();
|
||||||
|
} catch (const FlycastException& e) {
|
||||||
|
}
|
||||||
gui_state = GuiState::Main;
|
gui_state = GuiState::Main;
|
||||||
settings.content.path.clear();
|
emu.unloadGame();
|
||||||
}
|
}
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue