lay base for supporting different MP interfaces
This commit is contained in:
parent
0ad1fa8514
commit
bdbcd9c351
|
@ -39,7 +39,7 @@
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Net.h"
|
#include "Net.h"
|
||||||
#include "LocalMP.h"
|
#include "MPInterface.h"
|
||||||
|
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "DSi.h"
|
#include "DSi.h"
|
||||||
|
@ -62,7 +62,6 @@ using namespace melonDS::Platform;
|
||||||
MainWindow* topWindow = nullptr;
|
MainWindow* topWindow = nullptr;
|
||||||
|
|
||||||
const string kWifiSettingsPath = "wfcsettings.bin";
|
const string kWifiSettingsPath = "wfcsettings.bin";
|
||||||
extern LocalMP localMp;
|
|
||||||
extern Net net;
|
extern Net net;
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,7 +120,7 @@ EmuInstance::~EmuInstance()
|
||||||
deleting = true;
|
deleting = true;
|
||||||
deleteAllWindows();
|
deleteAllWindows();
|
||||||
|
|
||||||
localMp.End(instanceID);
|
MPInterface::Get().End(instanceID);
|
||||||
|
|
||||||
emuThread->emuExit();
|
emuThread->emuExit();
|
||||||
emuThread->wait();
|
emuThread->wait();
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "CameraManager.h"
|
#include "CameraManager.h"
|
||||||
#include "Net.h"
|
#include "Net.h"
|
||||||
#include "LocalMP.h"
|
#include "MPInterface.h"
|
||||||
#include "SPI_Firmware.h"
|
#include "SPI_Firmware.h"
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
#endif // __WIN32__
|
#endif // __WIN32__
|
||||||
|
|
||||||
extern CameraManager* camManager[2];
|
extern CameraManager* camManager[2];
|
||||||
extern melonDS::LocalMP localMp;
|
|
||||||
extern melonDS::Net net;
|
extern melonDS::Net net;
|
||||||
|
|
||||||
namespace melonDS::Platform
|
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)
|
void MP_Begin(void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||||
localMp.Begin(inst);
|
MPInterface::Get().Begin(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP_End(void* userdata)
|
void MP_End(void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||||
localMp.End(inst);
|
MPInterface::Get().End(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MP_SendPacket(u8* data, int len, u64 timestamp, void* userdata)
|
int MP_SendPacket(u8* data, int len, u64 timestamp, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
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 MP_RecvPacket(u8* data, u64* timestamp, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
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 MP_SendCmd(u8* data, int len, u64 timestamp, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
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 MP_SendReply(u8* data, int len, u64 timestamp, u16 aid, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
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 MP_SendAck(u8* data, int len, u64 timestamp, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
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 MP_RecvHostPacket(u8* data, u64* timestamp, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
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)
|
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask, void* userdata)
|
||||||
{
|
{
|
||||||
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
int inst = ((EmuInstance*)userdata)->getInstanceID();
|
||||||
return localMp.RecvReplies(inst, data, timestamp, aidmask);
|
return MPInterface::Get().RecvReplies(inst, data, timestamp, aidmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "Savestate.h"
|
#include "Savestate.h"
|
||||||
#include "LocalMP.h"
|
#include "MPInterface.h"
|
||||||
#include "LANDialog.h"
|
#include "LANDialog.h"
|
||||||
|
|
||||||
//#include "main_shaders.h"
|
//#include "main_shaders.h"
|
||||||
|
@ -88,7 +88,6 @@ using namespace melonDS;
|
||||||
|
|
||||||
extern CameraManager* camManager[2];
|
extern CameraManager* camManager[2];
|
||||||
extern bool camStarted[2];
|
extern bool camStarted[2];
|
||||||
extern LocalMP localMp;
|
|
||||||
|
|
||||||
|
|
||||||
QString NdsRomMimeType = "application/x-nintendo-ds-rom";
|
QString NdsRomMimeType = "application/x-nintendo-ds-rom";
|
||||||
|
@ -1886,7 +1885,7 @@ void MainWindow::onMPSettingsFinished(int res)
|
||||||
{
|
{
|
||||||
emuInstance->mpAudioMode = globalCfg.GetInt("MP.AudioMode");
|
emuInstance->mpAudioMode = globalCfg.GetInt("MP.AudioMode");
|
||||||
emuInstance->audioMute();
|
emuInstance->audioMute();
|
||||||
localMp.SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
|
MPInterface::Get().SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
|
||||||
|
|
||||||
emuThread->emuUnpause();
|
emuThread->emuUnpause();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,18 +22,14 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QStyle>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QMimeDatabase>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QPaintEvent>
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
@ -57,24 +53,14 @@
|
||||||
#include "duckstation/gl/context.h"
|
#include "duckstation/gl/context.h"
|
||||||
|
|
||||||
#include "main.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 "version.h"
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "DSi.h"
|
|
||||||
|
|
||||||
#include "EmuInstance.h"
|
#include "EmuInstance.h"
|
||||||
#include "ArchiveUtil.h"
|
#include "ArchiveUtil.h"
|
||||||
#include "CameraManager.h"
|
#include "CameraManager.h"
|
||||||
#include "LocalMP.h"
|
#include "MPInterface.h"
|
||||||
#include "Net.h"
|
#include "Net.h"
|
||||||
|
|
||||||
#include "CLI.h"
|
#include "CLI.h"
|
||||||
|
@ -95,10 +81,11 @@ EmuInstance* emuInstances[kMaxEmuInstances];
|
||||||
|
|
||||||
CameraManager* camManager[2];
|
CameraManager* camManager[2];
|
||||||
bool camStarted[2];
|
bool camStarted[2];
|
||||||
LocalMP localMp;
|
|
||||||
std::optional<LibPCap> pcap;
|
std::optional<LibPCap> pcap;
|
||||||
Net net;
|
Net net;
|
||||||
|
|
||||||
|
|
||||||
void NetInit()
|
void NetInit()
|
||||||
{
|
{
|
||||||
Config::Table cfg = Config::GetGlobalTable();
|
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();
|
NetInit();
|
||||||
|
|
||||||
createEmuInstance();
|
createEmuInstance();
|
||||||
|
|
|
@ -5,6 +5,7 @@ add_library(net-utils STATIC
|
||||||
PacketDispatcher.cpp
|
PacketDispatcher.cpp
|
||||||
LocalMP.cpp
|
LocalMP.cpp
|
||||||
MPInterface.h
|
MPInterface.h
|
||||||
|
MPInterface.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(net-utils PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
target_include_directories(net-utils PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "LocalMP.h"
|
#include "LocalMP.h"
|
||||||
#include "Platform.h"
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
using namespace melonDS;
|
using namespace melonDS;
|
||||||
using namespace melonDS::Platform;
|
using namespace melonDS::Platform;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
#include "MPInterface.h"
|
||||||
|
|
||||||
namespace melonDS
|
namespace melonDS
|
||||||
{
|
{
|
||||||
|
@ -46,7 +47,7 @@ constexpr u32 kPacketQueueSize = 0x10000;
|
||||||
constexpr u32 kReplyQueueSize = 0x10000;
|
constexpr u32 kReplyQueueSize = 0x10000;
|
||||||
constexpr u32 kMaxFrameSize = 0x948;
|
constexpr u32 kMaxFrameSize = 0x948;
|
||||||
|
|
||||||
class LocalMP
|
class LocalMP : public MPInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LocalMP() noexcept;
|
LocalMP() noexcept;
|
||||||
|
@ -56,8 +57,7 @@ public:
|
||||||
LocalMP& operator=(LocalMP&& other) = delete;
|
LocalMP& operator=(LocalMP&& other) = delete;
|
||||||
~LocalMP() noexcept;
|
~LocalMP() noexcept;
|
||||||
|
|
||||||
[[nodiscard]] int GetRecvTimeout() const noexcept { return RecvTimeout; }
|
void Process() {}
|
||||||
void SetRecvTimeout(int timeout) noexcept { RecvTimeout = timeout; }
|
|
||||||
|
|
||||||
void Begin(int inst);
|
void Begin(int inst);
|
||||||
void End(int inst);
|
void End(int inst);
|
||||||
|
@ -69,11 +69,13 @@ public:
|
||||||
int SendAck(int inst, u8* data, int len, u64 timestamp);
|
int SendAck(int inst, u8* data, int len, u64 timestamp);
|
||||||
int RecvHostPacket(int inst, u8* data, u64* timestamp);
|
int RecvHostPacket(int inst, u8* data, u64* timestamp);
|
||||||
u16 RecvReplies(int inst, u8* data, u64 timestamp, u16 aidmask);
|
u16 RecvReplies(int inst, u8* data, u64 timestamp, u16 aidmask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FIFORead(int inst, int fifo, void* buf, int len) noexcept;
|
void FIFORead(int inst, int fifo, void* buf, int len) noexcept;
|
||||||
void FIFOWrite(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 SendPacketGeneric(int inst, u32 type, u8* packet, int len, u64 timestamp) noexcept;
|
||||||
int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp) noexcept;
|
int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp) noexcept;
|
||||||
|
|
||||||
Platform::Mutex* MPQueueLock;
|
Platform::Mutex* MPQueueLock;
|
||||||
MPStatusData MPStatus {};
|
MPStatusData MPStatus {};
|
||||||
u8 MPPacketQueue[kPacketQueueSize] {};
|
u8 MPPacketQueue[kPacketQueueSize] {};
|
||||||
|
@ -81,8 +83,6 @@ private:
|
||||||
u32 PacketReadOffset[16] {};
|
u32 PacketReadOffset[16] {};
|
||||||
u32 ReplyReadOffset[16] {};
|
u32 ReplyReadOffset[16] {};
|
||||||
|
|
||||||
int RecvTimeout = 25;
|
|
||||||
|
|
||||||
int LastHostID = -1;
|
int LastHostID = -1;
|
||||||
Platform::Semaphore* SemPool[32] {};
|
Platform::Semaphore* SemPool[32] {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,17 +19,33 @@
|
||||||
#ifndef MPINTERFACE_H
|
#ifndef MPINTERFACE_H
|
||||||
#define MPINTERFACE_H
|
#define MPINTERFACE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace melonDS
|
namespace melonDS
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO: provision for excluding unwanted interfaces at compile time
|
||||||
|
enum MPInterfaceType
|
||||||
|
{
|
||||||
|
MPInterface_Dummy = -1,
|
||||||
|
MPInterface_Local,
|
||||||
|
MPInterface_LAN,
|
||||||
|
MPInterface_Netplay,
|
||||||
|
};
|
||||||
|
|
||||||
class MPInterface
|
class MPInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static MPInterface& Get() { return *Current; }
|
||||||
|
static void Set(MPInterfaceType type);
|
||||||
|
|
||||||
[[nodiscard]] int GetRecvTimeout() const noexcept { return RecvTimeout; }
|
[[nodiscard]] int GetRecvTimeout() const noexcept { return RecvTimeout; }
|
||||||
void SetRecvTimeout(int timeout) noexcept { RecvTimeout = timeout; }
|
void SetRecvTimeout(int timeout) noexcept { RecvTimeout = timeout; }
|
||||||
|
|
||||||
|
// function called every video frame
|
||||||
|
virtual void Process() = 0;
|
||||||
|
|
||||||
virtual void Begin(int inst) = 0;
|
virtual void Begin(int inst) = 0;
|
||||||
virtual void End(int inst) = 0;
|
virtual void End(int inst) = 0;
|
||||||
|
|
||||||
|
@ -43,6 +59,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int RecvTimeout = 25;
|
int RecvTimeout = 25;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::unique_ptr<MPInterface> Current;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue