diff --git a/src/frontend/qt_sdl/LANDialog.cpp b/src/frontend/qt_sdl/LANDialog.cpp
index 0a5c7449..58baf908 100644
--- a/src/frontend/qt_sdl/LANDialog.cpp
+++ b/src/frontend/qt_sdl/LANDialog.cpp
@@ -49,7 +49,7 @@ LANStartHostDialog::LANStartHostDialog(QWidget* parent) : QDialog(parent), ui(ne
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
- MPInterface::Set(MPInterface_LAN);
+ setMPInterface(MPInterface_LAN);
// TODO: remember the last setting? so this doesn't suck massively
// we could also remember the player name (and auto-init it from the firmware name or whatever)
@@ -85,7 +85,7 @@ void LANStartHostDialog::done(int r)
}
else
{
- MPInterface::Set(MPInterface_Local);
+ setMPInterface(MPInterface_Local);
}
QDialog::done(r);
@@ -97,7 +97,7 @@ LANStartClientDialog::LANStartClientDialog(QWidget* parent) : QDialog(parent), u
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
- MPInterface::Set(MPInterface_LAN);
+ setMPInterface(MPInterface_LAN);
QStandardItemModel* model = new QStandardItemModel();
ui->tvAvailableGames->setModel(model);
@@ -213,7 +213,7 @@ void LANStartClientDialog::done(int r)
else
{
lan().EndDiscovery();
- MPInterface::Set(MPInterface_Local);
+ setMPInterface(MPInterface_Local);
}
QDialog::done(r);
@@ -293,10 +293,26 @@ LANDialog::~LANDialog()
delete ui;
}
+void LANDialog::on_btnLeaveGame_clicked()
+{
+ done(QDialog::Accepted);
+}
+
void LANDialog::done(int r)
{
- // ???
- // TODO handle this situation, and provide the user a way to reopen this dialog
+ bool showwarning = true;
+ if (lan().GetNumPlayers() < 2)
+ showwarning = false;
+
+ if (showwarning)
+ {
+ if (QMessageBox::warning(this, "melonDS", "Really leave this LAN game?",
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
+ return;
+ }
+
+ lan().EndSession();
+ setMPInterface(MPInterface_Local);
QDialog::done(r);
}
diff --git a/src/frontend/qt_sdl/LANDialog.h b/src/frontend/qt_sdl/LANDialog.h
index c4b6255e..03857d79 100644
--- a/src/frontend/qt_sdl/LANDialog.h
+++ b/src/frontend/qt_sdl/LANDialog.h
@@ -104,6 +104,7 @@ protected:
void timerEvent(QTimerEvent* event) override;
private slots:
+ void on_btnLeaveGame_clicked();
void done(int r);
void doUpdatePlayerList();
diff --git a/src/frontend/qt_sdl/LANDialog.ui b/src/frontend/qt_sdl/LANDialog.ui
index e99000e4..88e9718f 100644
--- a/src/frontend/qt_sdl/LANDialog.ui
+++ b/src/frontend/qt_sdl/LANDialog.ui
@@ -11,15 +11,35 @@
- LAN SHITO
+ LAN game - melonDS
-
+
-
-
-
- STATUS PLACEHOLDER
+
+
+ 0
-
+
-
+
+
+ Leave game
+
+
+
+ -
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
-
diff --git a/src/frontend/qt_sdl/Window.cpp b/src/frontend/qt_sdl/Window.cpp
index 84cc7222..e0b76d19 100644
--- a/src/frontend/qt_sdl/Window.cpp
+++ b/src/frontend/qt_sdl/Window.cpp
@@ -749,6 +749,8 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
QObject::connect(qApp, &QApplication::applicationStateChanged, this, &MainWindow::onAppStateChanged);
onUpdateInterfaceSettings();
+
+ updateMPInterface(MPInterface::GetType());
}
MainWindow::~MainWindow()
@@ -1712,6 +1714,19 @@ void MainWindow::onNPTest()
//Netplay::StartGame();
}
+void MainWindow::updateMPInterface(MPInterfaceType type)
+{
+ // MP interface was changed, reflect it in the UI
+
+ bool enable = (type == MPInterface_Local);
+ actMPNewInstance->setEnabled(enable);
+ actLANStartHost->setEnabled(enable);
+ actLANStartClient->setEnabled(enable);
+ actNPStartHost->setEnabled(enable);
+ actNPStartClient->setEnabled(enable);
+ actNPTest->setEnabled(enable);
+}
+
bool MainWindow::lanWarning(bool host)
{
if (numEmuInstances() < 2)
diff --git a/src/frontend/qt_sdl/Window.h b/src/frontend/qt_sdl/Window.h
index 67a16ae5..1dfd680c 100644
--- a/src/frontend/qt_sdl/Window.h
+++ b/src/frontend/qt_sdl/Window.h
@@ -35,6 +35,7 @@
#include "Screen.h"
#include "Config.h"
+#include "MPInterface.h"
class EmuInstance;
@@ -125,6 +126,9 @@ public:
void osdAddMessage(unsigned int color, const char* msg);
+ // called when the MP interface is changed
+ void updateMPInterface(melonDS::MPInterfaceType type);
+
protected:
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 001d0f4f..9a9c93cb 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -205,6 +205,28 @@ void pathInit()
}
+void setMPInterface(MPInterfaceType type)
+{
+ // switch to the requested MP interface
+ MPInterface::Set(type);
+
+ // set receive timeout
+ // TODO: different settings per interface?
+ MPInterface::Get().SetRecvTimeout(Config::GetGlobalTable().GetInt("MP.RecvTimeout"));
+
+ // update UI appropriately
+ // TODO: decide how to deal with multi-window when it becomes a thing
+ for (int i = 0; i < kMaxEmuInstances; i++)
+ {
+ EmuInstance* inst = emuInstances[i];
+ if (!inst) continue;
+
+ MainWindow* win = inst->getMainWindow();
+ if (win) win->updateMPInterface(type);
+ }
+}
+
+
MelonApplication::MelonApplication(int& argc, char** argv)
: QApplication(argc, argv)
@@ -313,8 +335,7 @@ int main(int argc, char** argv)
// default MP interface type is local MP
// this will be changed if a LAN or netplay session is initiated
- MPInterface::Set(MPInterface_Local);
- MPInterface::Get().SetRecvTimeout(Config::GetGlobalTable().GetInt("MP.RecvTimeout"));
+ setMPInterface(MPInterface_Local);
NetInit();
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index 6bd07d75..77cdf4ee 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -29,6 +29,7 @@
#include "Window.h"
#include "EmuThread.h"
#include "ScreenLayout.h"
+#include "MPInterface.h"
class MelonApplication : public QApplication
{
@@ -49,4 +50,6 @@ void deleteEmuInstance(int id);
void deleteAllEmuInstances(int first = 0);
int numEmuInstances();
+void setMPInterface(melonDS::MPInterfaceType type);
+
#endif // MAIN_H
diff --git a/src/net/LAN.cpp b/src/net/LAN.cpp
index 358bb92a..ebc66fd8 100644
--- a/src/net/LAN.cpp
+++ b/src/net/LAN.cpp
@@ -17,10 +17,7 @@
*/
#include
-#include
#include
-#include
-#include
#ifdef __WIN32__
#include
@@ -107,46 +104,25 @@ LAN::LAN() noexcept : Inited(false)
// TODO make this somewhat nicer
if (enet_initialize() != 0)
{
- printf("enet shat itself :(\n");
+ Platform::Log(Platform::LogLevel::Error, "LAN: failed to initialize enet\n");
return;
}
- printf("enet init OK\n");
+ Platform::Log(Platform::LogLevel::Info, "LAN: enet initialized\n");
Inited = true;
}
LAN::~LAN() noexcept
{
- if (DiscoverySocket)
- {
- closesocket(DiscoverySocket);
- DiscoverySocket = INVALID_SOCKET;
- }
-
- while (!RXQueue.empty())
- {
- ENetPacket* packet = RXQueue.front();
- RXQueue.pop();
- enet_packet_destroy(packet);
- }
-
- for (int i = 0; i < 16; i++)
- {
- if (i == MyPlayer.ID) continue;
-
- if (RemotePeers[i])
- enet_peer_disconnect(RemotePeers[i], 0);
-
- RemotePeers[i] = nullptr;
- }
-
- enet_host_destroy(Host);
- Host = nullptr;
+ EndSession();
+ Inited = false;
enet_deinitialize();
Platform::Mutex_Free(DiscoveryMutex);
Platform::Mutex_Free(PlayersMutex);
+
+ Platform::Log(Platform::LogLevel::Info, "LAN: enet deinitialized\n");
}
@@ -281,9 +257,6 @@ bool LAN::StartHost(const char* playername, int numplayers)
Active = true;
IsHost = true;
- //if (lanDlg)
- // lanDlg->updatePlayerList();
-
StartDiscovery();
return true;
}
@@ -398,6 +371,35 @@ bool LAN::StartClient(const char* playername, const char* host)
return true;
}
+void LAN::EndSession()
+{
+ if (!Active) return;
+ if (IsHost) EndDiscovery();
+
+ Active = false;
+
+ while (!RXQueue.empty())
+ {
+ ENetPacket* packet = RXQueue.front();
+ RXQueue.pop();
+ enet_packet_destroy(packet);
+ }
+
+ for (int i = 0; i < 16; i++)
+ {
+ if (i == MyPlayer.ID) continue;
+
+ if (RemotePeers[i])
+ enet_peer_disconnect(RemotePeers[i], 0);
+
+ RemotePeers[i] = nullptr;
+ }
+
+ enet_host_destroy(Host);
+ Host = nullptr;
+ IsHost = false;
+}
+
void LAN::ProcessDiscovery()
{
@@ -631,7 +633,6 @@ void LAN::ProcessHostEvent(ENetEvent& event)
{
if (event.packet->dataLength != 1) break;
Player* player = (Player*)event.peer->data;
- //printf("HOST: PLAYER CONNECT %p\n", player);
if (!player) break;
ConnectedBitmask |= (1 << player->ID);
@@ -642,7 +643,6 @@ void LAN::ProcessHostEvent(ENetEvent& event)
{
if (event.packet->dataLength != 1) break;
Player* player = (Player*)event.peer->data;
- //printf("HOST: PLAYER DISCONNECT %p\n", player);
if (!player) break;
ConnectedBitmask &= ~(1 << player->ID);
@@ -757,7 +757,6 @@ void LAN::ProcessClientEvent(ENetEvent& event)
{
if (event.packet->dataLength != 1) break;
Player* player = (Player*)event.peer->data;
- //printf("CLIENT: PLAYER CONNECT %p\n", player);
if (!player) break;
ConnectedBitmask |= (1 << player->ID);
@@ -768,7 +767,6 @@ void LAN::ProcessClientEvent(ENetEvent& event)
{
if (event.packet->dataLength != 1) break;
Player* player = (Player*)event.peer->data;
- //printf("CLIENT: PLAYER DISCONNECT %p\n", player);
if (!player) break;
ConnectedBitmask &= ~(1 << player->ID);
@@ -796,7 +794,6 @@ void LAN::ProcessEvent(ENetEvent& event)
void LAN::ProcessLAN(int type)
{
if (!Host) return;
- //printf("Process(%d): %d %d\n", type, RXQueue.empty(), RXQueue.size());
u32 time_last = (u32)Platform::GetMSCount();
@@ -842,7 +839,7 @@ void LAN::ProcessLAN(int type)
if (event.type == ENET_EVENT_TYPE_RECEIVE && event.channelID == Chan_MP)
{
MPPacketHeader* header = (MPPacketHeader*)&event.packet->data[0];
- //printf("- enet_host_service: (%d) got MP frame, len=%d type=%08X fc=%04X\n", type, event.packet->dataLength, header->Type, *(u16*)&event.packet->data[sizeof(MPPacketHeader)+12]);
+
bool good = true;
if (event.packet->dataLength < sizeof(MPPacketHeader))
good = false;
@@ -870,7 +867,6 @@ void LAN::ProcessLAN(int type)
}
else
{
- //printf("- enet_host_service: got something else, time=%d\n", SDL_GetTicks()-time_last);
ProcessEvent(event);
}
@@ -1053,7 +1049,6 @@ u16 LAN::RecvReplies(int inst, u8* packets, u64 timestamp, u16 aidmask)
if (RXQueue.empty())
{
// no more replies available
- //printf("RecvMPReplies timeout, ret=%04X myinstmask=%04X conn=%04X aidmask=%04X\n", ret, myinstmask, ConnectedBitmask, aidmask);
return ret;
}
diff --git a/src/net/LAN.h b/src/net/LAN.h
index d507e04d..87282539 100644
--- a/src/net/LAN.h
+++ b/src/net/LAN.h
@@ -87,6 +87,7 @@ public:
void EndDiscovery();
bool StartHost(const char* player, int numplayers);
bool StartClient(const char* player, const char* host);
+ void EndSession();
std::map GetDiscoveryList();
std::vector GetPlayerList();
diff --git a/src/net/MPInterface.cpp b/src/net/MPInterface.cpp
index c92ac4fd..39d1915d 100644
--- a/src/net/MPInterface.cpp
+++ b/src/net/MPInterface.cpp
@@ -42,6 +42,7 @@ public:
std::unique_ptr MPInterface::Current(std::make_unique());
+MPInterfaceType MPInterface::CurrentType = MPInterface_Dummy;
void MPInterface::Set(MPInterfaceType type)
@@ -60,6 +61,8 @@ void MPInterface::Set(MPInterfaceType type)
Current = std::make_unique();
break;
}
+
+ CurrentType = type;
}
}
diff --git a/src/net/MPInterface.h b/src/net/MPInterface.h
index 5900a97a..eb5bef88 100644
--- a/src/net/MPInterface.h
+++ b/src/net/MPInterface.h
@@ -46,7 +46,10 @@ struct MPPacketHeader
class MPInterface
{
public:
+ virtual ~MPInterface() = default;
+
static MPInterface& Get() { return *Current; }
+ static MPInterfaceType GetType() { return CurrentType; }
static void Set(MPInterfaceType type);
[[nodiscard]] int GetRecvTimeout() const noexcept { return RecvTimeout; }
@@ -70,6 +73,7 @@ protected:
int RecvTimeout = 25;
private:
+ static MPInterfaceType CurrentType;
static std::unique_ptr Current;
};