lay base for supporting different MP interfaces

This commit is contained in:
Arisotura 2024-08-07 13:19:46 +02:00
parent 0ad1fa8514
commit bdbcd9c351
9 changed files with 109 additions and 42 deletions

View File

@ -39,7 +39,7 @@
#include "Config.h"
#include "Platform.h"
#include "Net.h"
#include "LocalMP.h"
#include "MPInterface.h"
#include "NDS.h"
#include "DSi.h"
@ -62,7 +62,6 @@ using namespace melonDS::Platform;
MainWindow* topWindow = nullptr;
const string kWifiSettingsPath = "wfcsettings.bin";
extern LocalMP localMp;
extern Net net;
@ -121,7 +120,7 @@ EmuInstance::~EmuInstance()
deleting = true;
deleteAllWindows();
localMp.End(instanceID);
MPInterface::Get().End(instanceID);
emuThread->emuExit();
emuThread->wait();

View File

@ -38,7 +38,7 @@
#include "main.h"
#include "CameraManager.h"
#include "Net.h"
#include "LocalMP.h"
#include "MPInterface.h"
#include "SPI_Firmware.h"
#ifdef __WIN32__
@ -47,7 +47,7 @@
#endif // __WIN32__
extern CameraManager* camManager[2];
extern melonDS::LocalMP localMp;
extern melonDS::Net net;
namespace melonDS::Platform
@ -458,55 +458,55 @@ 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);
MPInterface::Get().Begin(inst);
}
void MP_End(void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
localMp.End(inst);
MPInterface::Get().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 MPInterface::Get().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 MPInterface::Get().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 MPInterface::Get().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 MPInterface::Get().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 MPInterface::Get().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 MPInterface::Get().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 MPInterface::Get().RecvReplies(inst, data, timestamp, aidmask);
}

View File

@ -72,7 +72,7 @@
#include "Config.h"
#include "version.h"
#include "Savestate.h"
#include "LocalMP.h"
#include "MPInterface.h"
#include "LANDialog.h"
//#include "main_shaders.h"
@ -88,7 +88,6 @@ using namespace melonDS;
extern CameraManager* camManager[2];
extern bool camStarted[2];
extern LocalMP localMp;
QString NdsRomMimeType = "application/x-nintendo-ds-rom";
@ -1886,7 +1885,7 @@ void MainWindow::onMPSettingsFinished(int res)
{
emuInstance->mpAudioMode = globalCfg.GetInt("MP.AudioMode");
emuInstance->audioMute();
localMp.SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
MPInterface::Get().SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
emuThread->emuUnpause();
}

View File

@ -22,18 +22,14 @@
#include <string.h>
#include <optional>
#include <vector>
#include <string>
#include <algorithm>
#include <QProcess>
#include <QApplication>
#include <QStyle>
#include <QMessageBox>
#include <QMenuBar>
#include <QMimeDatabase>
#include <QFileDialog>
#include <QInputDialog>
#include <QPaintEvent>
#include <QPainter>
#include <QKeyEvent>
#include <QMimeData>
@ -57,24 +53,14 @@
#include "duckstation/gl/context.h"
#include "main.h"
#include "CheatsDialog.h"
#include "DateTimeDialog.h"
#include "EmuSettingsDialog.h"
#include "InputConfig/InputConfigDialog.h"
#include "VideoSettingsDialog.h"
#include "ROMInfoDialog.h"
#include "RAMInfoDialog.h"
#include "PowerManagement/PowerManagementDialog.h"
#include "version.h"
#include "Config.h"
#include "DSi.h"
#include "EmuInstance.h"
#include "ArchiveUtil.h"
#include "CameraManager.h"
#include "LocalMP.h"
#include "MPInterface.h"
#include "Net.h"
#include "CLI.h"
@ -95,10 +81,11 @@ EmuInstance* emuInstances[kMaxEmuInstances];
CameraManager* camManager[2];
bool camStarted[2];
LocalMP localMp;
std::optional<LibPCap> pcap;
Net net;
void NetInit()
{
Config::Table cfg = Config::GetGlobalTable();
@ -321,7 +308,11 @@ int main(int argc, char** argv)
}
}
// localMp is initialized at this point
// 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"));
NetInit();
createEmuInstance();

View File

@ -5,6 +5,7 @@ add_library(net-utils STATIC
PacketDispatcher.cpp
LocalMP.cpp
MPInterface.h
MPInterface.cpp
)
target_include_directories(net-utils PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")

View File

@ -19,8 +19,6 @@
#include <cstring>
#include "LocalMP.h"
#include "Platform.h"
#include "types.h"
using namespace melonDS;
using namespace melonDS::Platform;

View File

@ -21,6 +21,7 @@
#include "types.h"
#include "Platform.h"
#include "MPInterface.h"
namespace melonDS
{
@ -46,7 +47,7 @@ constexpr u32 kPacketQueueSize = 0x10000;
constexpr u32 kReplyQueueSize = 0x10000;
constexpr u32 kMaxFrameSize = 0x948;
class LocalMP
class LocalMP : public MPInterface
{
public:
LocalMP() noexcept;
@ -56,8 +57,7 @@ public:
LocalMP& operator=(LocalMP&& other) = delete;
~LocalMP() noexcept;
[[nodiscard]] int GetRecvTimeout() const noexcept { return RecvTimeout; }
void SetRecvTimeout(int timeout) noexcept { RecvTimeout = timeout; }
void Process() {}
void Begin(int inst);
void End(int inst);
@ -69,11 +69,13 @@ public:
int SendAck(int inst, u8* data, int len, u64 timestamp);
int RecvHostPacket(int inst, u8* data, u64* timestamp);
u16 RecvReplies(int inst, u8* data, u64 timestamp, u16 aidmask);
private:
void FIFORead(int inst, int fifo, void* buf, int len) noexcept;
void FIFOWrite(int inst, int fifo, void* buf, int len) noexcept;
int SendPacketGeneric(int inst, u32 type, u8* packet, int len, u64 timestamp) noexcept;
int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp) noexcept;
Platform::Mutex* MPQueueLock;
MPStatusData MPStatus {};
u8 MPPacketQueue[kPacketQueueSize] {};
@ -81,8 +83,6 @@ private:
u32 PacketReadOffset[16] {};
u32 ReplyReadOffset[16] {};
int RecvTimeout = 25;
int LastHostID = -1;
Platform::Semaphore* SemPool[32] {};
};

60
src/net/MPInterface.cpp Normal file
View File

@ -0,0 +1,60 @@
/*
Copyright 2016-2024 melonDS team
This file is part of melonDS.
melonDS 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 Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include "MPInterface.h"
#include "LocalMP.h"
namespace melonDS
{
class DummyMP : public MPInterface
{
public:
void Process() override {}
void Begin(int inst) override {}
void End(int inst) override {}
int SendPacket(int inst, u8* data, int len, u64 timestamp) override { return 0; }
int RecvPacket(int inst, u8* data, u64* timestamp) override { return 0; }
int SendCmd(int inst, u8* data, int len, u64 timestamp) override { return 0; }
int SendReply(int inst, u8* data, int len, u64 timestamp, u16 aid) override { return 0; }
int SendAck(int inst, u8* data, int len, u64 timestamp) override { return 0; }
int RecvHostPacket(int inst, u8* data, u64* timestamp) override { return 0; }
u16 RecvReplies(int inst, u8* data, u64 timestamp, u16 aidmask) override { return 0; }
};
std::unique_ptr<MPInterface> MPInterface::Current(std::make_unique<DummyMP>());
void MPInterface::Set(MPInterfaceType type)
{
switch (type)
{
case MPInterface_Local:
Current = std::make_unique<LocalMP>();
break;
default:
Current = std::make_unique<DummyMP>();
break;
}
}
}

View File

@ -19,17 +19,33 @@
#ifndef MPINTERFACE_H
#define MPINTERFACE_H
#include <memory>
#include "types.h"
namespace melonDS
{
// TODO: provision for excluding unwanted interfaces at compile time
enum MPInterfaceType
{
MPInterface_Dummy = -1,
MPInterface_Local,
MPInterface_LAN,
MPInterface_Netplay,
};
class MPInterface
{
public:
static MPInterface& Get() { return *Current; }
static void Set(MPInterfaceType type);
[[nodiscard]] int GetRecvTimeout() const noexcept { return RecvTimeout; }
void SetRecvTimeout(int timeout) noexcept { RecvTimeout = timeout; }
// function called every video frame
virtual void Process() = 0;
virtual void Begin(int inst) = 0;
virtual void End(int inst) = 0;
@ -43,6 +59,9 @@ public:
protected:
int RecvTimeout = 25;
private:
static std::unique_ptr<MPInterface> Current;
};
}