mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-25 07:10:00 -06:00
Refactor network implementations to be more reusable and less buggy (#2107)
encapsulate network interfaces
This commit is contained in:
@ -163,6 +163,10 @@ endif()
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..")
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../net")
|
||||
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../net/libslirp/src")
|
||||
get_target_property(SLIRP_BINARY_DIR slirp BINARY_DIR)
|
||||
target_include_directories(melonDS PUBLIC "${SLIRP_BINARY_DIR}") # for libslirp-version.h
|
||||
if (USE_QT6)
|
||||
target_include_directories(melonDS PUBLIC ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
else()
|
||||
|
@ -62,6 +62,8 @@ using namespace melonDS::Platform;
|
||||
MainWindow* topWindow = nullptr;
|
||||
|
||||
const string kWifiSettingsPath = "wfcsettings.bin";
|
||||
extern LocalMP localMp;
|
||||
extern Net net;
|
||||
|
||||
|
||||
EmuInstance::EmuInstance(int inst) : instanceID(inst),
|
||||
@ -97,7 +99,7 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
|
||||
audioInit();
|
||||
inputInit();
|
||||
|
||||
Net::RegisterInstance(instanceID);
|
||||
net.RegisterInstance(instanceID);
|
||||
|
||||
emuThread = new EmuThread(this);
|
||||
|
||||
@ -116,14 +118,13 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
|
||||
EmuInstance::~EmuInstance()
|
||||
{
|
||||
// TODO window cleanup and shit?
|
||||
|
||||
LocalMP::End(instanceID);
|
||||
localMp.End(instanceID);
|
||||
|
||||
emuThread->emuExit();
|
||||
emuThread->wait();
|
||||
delete emuThread;
|
||||
|
||||
Net::UnregisterInstance(instanceID);
|
||||
net.UnregisterInstance(instanceID);
|
||||
|
||||
audioDeInit();
|
||||
inputDeInit();
|
||||
|
@ -47,7 +47,8 @@
|
||||
#endif // __WIN32__
|
||||
|
||||
extern CameraManager* camManager[2];
|
||||
|
||||
extern melonDS::LocalMP localMp;
|
||||
extern melonDS::Net net;
|
||||
|
||||
namespace melonDS::Platform
|
||||
{
|
||||
@ -457,69 +458,69 @@ void WriteDateTime(int year, int month, int day, int hour, int minute, int secon
|
||||
void MP_Begin(void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
LocalMP::Begin(inst);
|
||||
localMp.Begin(inst);
|
||||
}
|
||||
|
||||
void MP_End(void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
LocalMP::End(inst);
|
||||
localMp.End(inst);
|
||||
}
|
||||
|
||||
int MP_SendPacket(u8* data, int len, u64 timestamp, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::SendPacket(inst, data, len, timestamp);
|
||||
return localMp.SendPacket(inst, data, len, timestamp);
|
||||
}
|
||||
|
||||
int MP_RecvPacket(u8* data, u64* timestamp, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::RecvPacket(inst, data, timestamp);
|
||||
return localMp.RecvPacket(inst, data, timestamp);
|
||||
}
|
||||
|
||||
int MP_SendCmd(u8* data, int len, u64 timestamp, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::SendCmd(inst, data, len, timestamp);
|
||||
return localMp.SendCmd(inst, data, len, timestamp);
|
||||
}
|
||||
|
||||
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::SendReply(inst, data, len, timestamp, aid);
|
||||
return localMp.SendReply(inst, data, len, timestamp, aid);
|
||||
}
|
||||
|
||||
int MP_SendAck(u8* data, int len, u64 timestamp, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::SendAck(inst, data, len, timestamp);
|
||||
return localMp.SendAck(inst, data, len, timestamp);
|
||||
}
|
||||
|
||||
int MP_RecvHostPacket(u8* data, u64* timestamp, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::RecvHostPacket(inst, data, timestamp);
|
||||
return localMp.RecvHostPacket(inst, data, timestamp);
|
||||
}
|
||||
|
||||
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return LocalMP::RecvReplies(inst, data, timestamp, aidmask);
|
||||
return localMp.RecvReplies(inst, data, timestamp, aidmask);
|
||||
}
|
||||
|
||||
|
||||
int Net_SendPacket(u8* data, int len, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
Net::SendPacket(data, len, inst);
|
||||
net.SendPacket(data, len, inst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Net_RecvPacket(u8* data, void* userdata)
|
||||
{
|
||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||
return Net::RecvPacket(data, inst);
|
||||
return net.RecvPacket(data, inst);
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,11 +37,14 @@
|
||||
#define PCAP_NAME "libpcap"
|
||||
#endif
|
||||
|
||||
extern std::optional<melonDS::LibPCap> pcap;
|
||||
extern melonDS::Net net;
|
||||
|
||||
WifiSettingsDialog* WifiSettingsDialog::currentDlg = nullptr;
|
||||
|
||||
bool WifiSettingsDialog::needsReset = false;
|
||||
|
||||
void NetInit();
|
||||
|
||||
WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WifiSettingsDialog)
|
||||
{
|
||||
@ -51,8 +54,12 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne
|
||||
emuInstance = ((MainWindow*)parent)->getEmuInstance();
|
||||
auto& cfg = emuInstance->getGlobalConfig();
|
||||
|
||||
Net::DeInit();
|
||||
haspcap = Net_PCap::InitAdapterList();
|
||||
if (!pcap)
|
||||
pcap = melonDS::LibPCap::New();
|
||||
|
||||
haspcap = pcap.has_value();
|
||||
if (pcap)
|
||||
adapters = pcap->GetAdapters();
|
||||
|
||||
ui->rbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)");
|
||||
|
||||
@ -60,13 +67,13 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne
|
||||
ui->lblAdapterIP->setText("(none)");
|
||||
|
||||
int sel = 0;
|
||||
for (int i = 0; i < Net_PCap::NumAdapters; i++)
|
||||
for (int i = 0; i < adapters.size(); i++)
|
||||
{
|
||||
Net_PCap::AdapterData* adapter = &Net_PCap::Adapters[i];
|
||||
melonDS::AdapterData& adapter = adapters[i];
|
||||
|
||||
ui->cbxDirectAdapter->addItem(QString(adapter->FriendlyName));
|
||||
ui->cbxDirectAdapter->addItem(QString(adapter.FriendlyName));
|
||||
|
||||
if (!strncmp(adapter->DeviceName, cfg.GetString("LAN.Device").c_str(), 128))
|
||||
if (!strncmp(adapter.DeviceName, cfg.GetString("LAN.Device").c_str(), 128))
|
||||
sel = i;
|
||||
}
|
||||
ui->cbxDirectAdapter->setCurrentIndex(sel);
|
||||
@ -96,24 +103,23 @@ void WifiSettingsDialog::done(int r)
|
||||
cfg.SetBool("LAN.DirectMode", ui->rbDirectMode->isChecked());
|
||||
|
||||
int sel = ui->cbxDirectAdapter->currentIndex();
|
||||
if (sel < 0 || sel >= Net_PCap::NumAdapters) sel = 0;
|
||||
if (Net_PCap::NumAdapters < 1)
|
||||
if (sel < 0 || sel >= adapters.size()) sel = 0;
|
||||
if (adapters.empty())
|
||||
{
|
||||
cfg.SetString("LAN.Device", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg.SetString("LAN.Device", Net_PCap::Adapters[sel].DeviceName);
|
||||
cfg.SetString("LAN.Device", adapters[sel].DeviceName);
|
||||
}
|
||||
|
||||
Config::Save();
|
||||
}
|
||||
|
||||
Net_PCap::DeInit();
|
||||
Config::Table cfg = Config::GetGlobalTable();
|
||||
bool direct = cfg.GetBool("LAN.DirectMode");
|
||||
std::string devicename = cfg.GetString("LAN.Device");
|
||||
Net::Init(direct, devicename.c_str());
|
||||
|
||||
NetInit();
|
||||
|
||||
QDialog::done(r);
|
||||
|
||||
@ -134,10 +140,9 @@ void WifiSettingsDialog::on_cbxDirectAdapter_currentIndexChanged(int sel)
|
||||
{
|
||||
if (!haspcap) return;
|
||||
|
||||
if (sel < 0 || sel >= Net_PCap::NumAdapters) return;
|
||||
if (Net_PCap::NumAdapters < 1) return;
|
||||
if (sel < 0 || sel >= adapters.size() || adapters.empty()) return;
|
||||
|
||||
Net_PCap::AdapterData* adapter = &Net_PCap::Adapters[sel];
|
||||
melonDS::AdapterData* adapter = &adapters[sel];
|
||||
char tmp[64];
|
||||
|
||||
sprintf(tmp, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
|
@ -20,6 +20,8 @@
|
||||
#define WIFISETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <vector>
|
||||
#include "Net_PCap.h"
|
||||
|
||||
namespace Ui { class WifiSettingsDialog; }
|
||||
class WifiSettingsDialog;
|
||||
@ -68,6 +70,7 @@ private:
|
||||
bool haspcap;
|
||||
|
||||
void updateAdapterControls();
|
||||
std::vector<melonDS::AdapterData> adapters;
|
||||
};
|
||||
|
||||
#endif // WIFISETTINGSDIALOG_H
|
||||
|
@ -87,6 +87,7 @@ using namespace melonDS;
|
||||
|
||||
extern CameraManager* camManager[2];
|
||||
extern bool camStarted[2];
|
||||
extern LocalMP localMp;
|
||||
|
||||
|
||||
QString NdsRomMimeType = "application/x-nintendo-ds-rom";
|
||||
@ -1832,7 +1833,7 @@ void MainWindow::onMPSettingsFinished(int res)
|
||||
{
|
||||
emuInstance->mpAudioMode = globalCfg.GetInt("MP.AudioMode");
|
||||
emuInstance->audioMute();
|
||||
LocalMP::SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
|
||||
localMp.SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
|
||||
|
||||
emuThread->emuUnpause();
|
||||
}
|
||||
|
@ -79,6 +79,9 @@
|
||||
|
||||
#include "CLI.h"
|
||||
|
||||
#include "Net_PCap.h"
|
||||
#include "Net_Slirp.h"
|
||||
|
||||
using namespace melonDS;
|
||||
|
||||
QString* systemThemeName;
|
||||
@ -92,6 +95,38 @@ EmuInstance* emuInstances[kMaxEmuInstances];
|
||||
|
||||
CameraManager* camManager[2];
|
||||
bool camStarted[2];
|
||||
LocalMP localMp;
|
||||
std::optional<LibPCap> pcap;
|
||||
Net net;
|
||||
|
||||
void NetInit()
|
||||
{
|
||||
Config::Table cfg = Config::GetGlobalTable();
|
||||
if (cfg.GetBool("LAN.DirectMode"))
|
||||
{
|
||||
if (!pcap)
|
||||
pcap = LibPCap::New();
|
||||
|
||||
if (pcap)
|
||||
{
|
||||
std::string devicename = cfg.GetString("LAN.Device");
|
||||
std::unique_ptr<Net_PCap> netPcap = pcap->Open(devicename, [](const u8* data, int len) {
|
||||
net.RXEnqueue(data, len);
|
||||
});
|
||||
|
||||
if (netPcap)
|
||||
{
|
||||
net.SetDriver(std::move(netPcap));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
net.SetDriver(std::make_unique<Net_Slirp>([](const u8* data, int len) {
|
||||
net.RXEnqueue(data, len);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool createEmuInstance()
|
||||
@ -273,13 +308,8 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
LocalMP::Init();
|
||||
{
|
||||
Config::Table cfg = Config::GetGlobalTable();
|
||||
bool direct = cfg.GetBool("LAN.DirectMode");
|
||||
std::string devicename = cfg.GetString("LAN.Device");
|
||||
Net::Init(direct, devicename.c_str());
|
||||
}
|
||||
// localMp is initialized at this point
|
||||
NetInit();
|
||||
|
||||
createEmuInstance();
|
||||
|
||||
@ -316,9 +346,6 @@ int main(int argc, char** argv)
|
||||
// but with this we make extra sure they are all deleted
|
||||
deleteAllEmuInstances();
|
||||
|
||||
LocalMP::DeInit();
|
||||
Net::DeInit();
|
||||
|
||||
delete camManager[0];
|
||||
delete camManager[1];
|
||||
|
||||
|
Reference in New Issue
Block a user