get things in a startable state
This commit is contained in:
parent
a35865620f
commit
a985478979
|
@ -24,18 +24,11 @@
|
||||||
#include <enet/enet.h>
|
#include <enet/enet.h>
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
#include "NDS.h"
|
|
||||||
#include "NDSCart.h"
|
|
||||||
#include "main.h"
|
|
||||||
//#include "IPC.h"
|
|
||||||
#include "NetplayDialog.h"
|
#include "NetplayDialog.h"
|
||||||
//#include "Input.h"
|
|
||||||
//#include "ROMManager.h"
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Savestate.h"
|
#include "main.h"
|
||||||
#include "Platform.h"
|
#include "Netplay.h"
|
||||||
|
|
||||||
#include "ui_NetplayStartHostDialog.h"
|
#include "ui_NetplayStartHostDialog.h"
|
||||||
#include "ui_NetplayStartClientDialog.h"
|
#include "ui_NetplayStartClientDialog.h"
|
||||||
|
@ -44,8 +37,9 @@
|
||||||
using namespace melonDS;
|
using namespace melonDS;
|
||||||
|
|
||||||
|
|
||||||
extern EmuThread* emuThread;
|
NetplayDialog* netplayDlg = nullptr;
|
||||||
NetplayDialog* netplayDlg;
|
|
||||||
|
#define netplay() ((Netplay&)MPInterface::Get())
|
||||||
|
|
||||||
|
|
||||||
NetplayStartHostDialog::NetplayStartHostDialog(QWidget* parent) : QDialog(parent), ui(new Ui::NetplayStartHostDialog)
|
NetplayStartHostDialog::NetplayStartHostDialog(QWidget* parent) : QDialog(parent), ui(new Ui::NetplayStartHostDialog)
|
||||||
|
@ -53,6 +47,8 @@ NetplayStartHostDialog::NetplayStartHostDialog(QWidget* parent) : QDialog(parent
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
setMPInterface(MPInterface_Netplay);
|
||||||
|
|
||||||
ui->txtPort->setText("8064");
|
ui->txtPort->setText("8064");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +68,11 @@ void NetplayStartHostDialog::done(int r)
|
||||||
|
|
||||||
netplayDlg = NetplayDialog::openDlg(parentWidget());
|
netplayDlg = NetplayDialog::openDlg(parentWidget());
|
||||||
|
|
||||||
Netplay::StartHost(player.c_str(), port);
|
netplay().StartHost(player.c_str(), port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setMPInterface(MPInterface_Local);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::done(r);
|
QDialog::done(r);
|
||||||
|
@ -84,6 +84,8 @@ NetplayStartClientDialog::NetplayStartClientDialog(QWidget* parent) : QDialog(pa
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
setMPInterface(MPInterface_Netplay);
|
||||||
|
|
||||||
ui->txtPort->setText("8064");
|
ui->txtPort->setText("8064");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +106,11 @@ void NetplayStartClientDialog::done(int r)
|
||||||
|
|
||||||
netplayDlg = NetplayDialog::openDlg(parentWidget());
|
netplayDlg = NetplayDialog::openDlg(parentWidget());
|
||||||
|
|
||||||
Netplay::StartClient(player.c_str(), host.c_str(), port);
|
netplay().StartClient(player.c_str(), host.c_str(), port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setMPInterface(MPInterface_Local);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::done(r);
|
QDialog::done(r);
|
||||||
|
@ -119,50 +125,55 @@ NetplayDialog::NetplayDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Netp
|
||||||
QStandardItemModel* model = new QStandardItemModel();
|
QStandardItemModel* model = new QStandardItemModel();
|
||||||
ui->tvPlayerList->setModel(model);
|
ui->tvPlayerList->setModel(model);
|
||||||
|
|
||||||
connect(this, &NetplayDialog::sgUpdatePlayerList, this, &NetplayDialog::doUpdatePlayerList);
|
timerID = startTimer(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetplayDialog::~NetplayDialog()
|
NetplayDialog::~NetplayDialog()
|
||||||
{
|
{
|
||||||
|
killTimer(timerID);
|
||||||
|
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetplayDialog::done(int r)
|
void NetplayDialog::done(int r)
|
||||||
{
|
{
|
||||||
// ???
|
// TODO
|
||||||
|
|
||||||
QDialog::done(r);
|
QDialog::done(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetplayDialog::updatePlayerList(Netplay::Player* players, int num)
|
void NetplayDialog::timerEvent(QTimerEvent *event)
|
||||||
{
|
{
|
||||||
emit sgUpdatePlayerList(players, num);
|
doUpdatePlayerList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetplayDialog::doUpdatePlayerList(Netplay::Player* players, int num)
|
void NetplayDialog::doUpdatePlayerList()
|
||||||
{
|
{
|
||||||
|
auto playerlist = netplay().GetPlayerList();
|
||||||
|
int numplayers = playerlist.size();
|
||||||
|
auto maxplayers = netplay().GetMaxPlayers();
|
||||||
|
|
||||||
QStandardItemModel* model = (QStandardItemModel*)ui->tvPlayerList->model();
|
QStandardItemModel* model = (QStandardItemModel*)ui->tvPlayerList->model();
|
||||||
|
|
||||||
model->clear();
|
model->clear();
|
||||||
model->setRowCount(num);
|
model->setRowCount(numplayers);
|
||||||
|
|
||||||
// TODO: remove IP column in final product
|
// TODO: remove IP column in final product
|
||||||
|
|
||||||
const QStringList header = {"#", "Player", "Status", "Ping", "IP"};
|
const QStringList header = {"#", "Player", "Status", "Ping", "IP"};
|
||||||
model->setHorizontalHeaderLabels(header);
|
model->setHorizontalHeaderLabels(header);
|
||||||
|
|
||||||
for (int i = 0; i < num; i++)
|
int i = 0;
|
||||||
|
for (const auto& player : playerlist)
|
||||||
{
|
{
|
||||||
Netplay::Player* player = &players[i];
|
QString id = QString("%0").arg(player.ID+1);
|
||||||
|
|
||||||
QString id = QString("%0").arg(player->ID+1);
|
|
||||||
model->setItem(i, 0, new QStandardItem(id));
|
model->setItem(i, 0, new QStandardItem(id));
|
||||||
|
|
||||||
QString name = player->Name;
|
QString name = player.Name;
|
||||||
model->setItem(i, 1, new QStandardItem(name));
|
model->setItem(i, 1, new QStandardItem(name));
|
||||||
|
|
||||||
QString status;
|
QString status;
|
||||||
switch (player->Status)
|
switch (player.Status)
|
||||||
{
|
{
|
||||||
case 1: status = ""; break;
|
case 1: status = ""; break;
|
||||||
case 2: status = "Host"; break;
|
case 2: status = "Host"; break;
|
||||||
|
@ -174,8 +185,10 @@ void NetplayDialog::doUpdatePlayerList(Netplay::Player* players, int num)
|
||||||
model->setItem(i, 3, new QStandardItem("x"));
|
model->setItem(i, 3, new QStandardItem("x"));
|
||||||
|
|
||||||
char ip[32];
|
char ip[32];
|
||||||
u32 addr = player->Address;
|
u32 addr = player.Address;
|
||||||
sprintf(ip, "%d.%d.%d.%d", addr&0xFF, (addr>>8)&0xFF, (addr>>16)&0xFF, addr>>24);
|
sprintf(ip, "%d.%d.%d.%d", addr&0xFF, (addr>>8)&0xFF, (addr>>16)&0xFF, addr>>24);
|
||||||
model->setItem(i, 4, new QStandardItem(ip));
|
model->setItem(i, 4, new QStandardItem(ip));
|
||||||
|
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,18 +94,17 @@ public:
|
||||||
return dlg;
|
return dlg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePlayerList(Netplay::Player* players, int num);
|
protected:
|
||||||
|
void timerEvent(QTimerEvent* event) override;
|
||||||
signals:
|
|
||||||
void sgUpdatePlayerList(Netplay::Player* players, int num);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void done(int r);
|
void done(int r);
|
||||||
|
|
||||||
void doUpdatePlayerList(Netplay::Player* players, int num);
|
void doUpdatePlayerList();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::NetplayDialog* ui;
|
Ui::NetplayDialog* ui;
|
||||||
|
int timerID;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NETPLAYDIALOG_H
|
#endif // NETPLAYDIALOG_H
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
#include "Savestate.h"
|
#include "Savestate.h"
|
||||||
#include "MPInterface.h"
|
#include "MPInterface.h"
|
||||||
#include "LANDialog.h"
|
#include "LANDialog.h"
|
||||||
|
#include "NetplayDialog.h"
|
||||||
|
|
||||||
//#include "main_shaders.h"
|
//#include "main_shaders.h"
|
||||||
|
|
||||||
|
@ -1705,14 +1706,14 @@ void MainWindow::onLANStartClient()
|
||||||
|
|
||||||
void MainWindow::onNPStartHost()
|
void MainWindow::onNPStartHost()
|
||||||
{
|
{
|
||||||
//Netplay::StartHost();
|
if (!netplayWarning(true)) return;
|
||||||
//NetplayStartHostDialog::openDlg(this);
|
NetplayStartHostDialog::openDlg(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onNPStartClient()
|
void MainWindow::onNPStartClient()
|
||||||
{
|
{
|
||||||
//Netplay::StartClient();
|
if (!netplayWarning(false)) return;
|
||||||
//NetplayStartClientDialog::openDlg(this);
|
NetplayStartClientDialog::openDlg(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onNPTest()
|
void MainWindow::onNPTest()
|
||||||
|
@ -1752,6 +1753,15 @@ bool MainWindow::lanWarning(bool host)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MainWindow::netplayWarning(bool host)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
// * if a game is running it needs to be closed
|
||||||
|
// * if multiple instances are open they need to be closed
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onOpenEmuSettings()
|
void MainWindow::onOpenEmuSettings()
|
||||||
{
|
{
|
||||||
emuThread->emuPause();
|
emuThread->emuPause();
|
||||||
|
|
|
@ -242,6 +242,7 @@ private:
|
||||||
void createScreenPanel();
|
void createScreenPanel();
|
||||||
|
|
||||||
bool lanWarning(bool host);
|
bool lanWarning(bool host);
|
||||||
|
bool netplayWarning(bool host);
|
||||||
|
|
||||||
bool showOSD;
|
bool showOSD;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ LocalMP::~LocalMP() noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex_Free(MPQueueLock);
|
Mutex_Free(MPQueueLock);
|
||||||
|
|
||||||
|
Log(LogLevel::Info, "MP comm deinited\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMP::Begin(int inst)
|
void LocalMP::Begin(int inst)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "MPInterface.h"
|
#include "MPInterface.h"
|
||||||
#include "LocalMP.h"
|
#include "LocalMP.h"
|
||||||
#include "LAN.h"
|
#include "LAN.h"
|
||||||
|
#include "Netplay.h"
|
||||||
|
|
||||||
namespace melonDS
|
namespace melonDS
|
||||||
{
|
{
|
||||||
|
@ -47,6 +48,8 @@ MPInterfaceType MPInterface::CurrentType = MPInterface_Dummy;
|
||||||
|
|
||||||
void MPInterface::Set(MPInterfaceType type)
|
void MPInterface::Set(MPInterfaceType type)
|
||||||
{
|
{
|
||||||
|
Current = nullptr;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case MPInterface_Local:
|
case MPInterface_Local:
|
||||||
|
@ -57,6 +60,10 @@ void MPInterface::Set(MPInterfaceType type)
|
||||||
Current = std::make_unique<LAN>();
|
Current = std::make_unique<LAN>();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MPInterface_Netplay:
|
||||||
|
Current = std::make_unique<Netplay>();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Current = std::make_unique<DummyMP>();
|
Current = std::make_unique<DummyMP>();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,95 +33,83 @@
|
||||||
#include "Savestate.h"
|
#include "Savestate.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
|
||||||
using namespace melonDS;
|
|
||||||
|
|
||||||
namespace Netplay
|
namespace melonDS
|
||||||
{
|
{
|
||||||
|
|
||||||
bool Active;
|
const u32 kLocalhost = 0x0100007F;
|
||||||
bool IsHost;
|
|
||||||
bool IsMirror;
|
|
||||||
|
|
||||||
ENetHost* Host;
|
|
||||||
ENetHost* MirrorHost;
|
|
||||||
|
|
||||||
Player Players[16];
|
|
||||||
int NumPlayers;
|
|
||||||
|
|
||||||
Player MyPlayer;
|
|
||||||
u32 HostAddress;
|
|
||||||
bool Lag;
|
|
||||||
|
|
||||||
int NumMirrorClients;
|
|
||||||
|
|
||||||
struct InputFrame
|
|
||||||
{
|
|
||||||
u32 FrameNum;
|
|
||||||
u32 KeyMask;
|
|
||||||
u32 Touching;
|
|
||||||
u32 TouchX, TouchY;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::queue<InputFrame> InputQueue;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
Blob_CartROM = 0,
|
|
||||||
Blob_CartSRAM,
|
|
||||||
Blob_InitState,
|
|
||||||
|
|
||||||
Blob_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
const u32 kChunkSize = 0x10000;
|
|
||||||
u8 ChunkBuffer[0x10 + kChunkSize];
|
|
||||||
u8* Blobs[Blob_MAX];
|
|
||||||
u32 BlobLens[Blob_MAX];
|
|
||||||
int CurBlobType;
|
|
||||||
u32 CurBlobLen;
|
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
Netplay::Netplay() noexcept : LocalMP(), Inited(false)
|
||||||
{
|
{
|
||||||
Active = false;
|
Active = false;
|
||||||
IsHost = false;
|
IsHost = false;
|
||||||
IsMirror = false;
|
|
||||||
Host = nullptr;
|
Host = nullptr;
|
||||||
MirrorHost = nullptr;
|
|
||||||
Lag = false;
|
Lag = false;
|
||||||
|
|
||||||
|
PlayersMutex = Platform::Mutex_Create();
|
||||||
|
|
||||||
|
memset(RemotePeers, 0, sizeof(RemotePeers));
|
||||||
memset(Players, 0, sizeof(Players));
|
memset(Players, 0, sizeof(Players));
|
||||||
NumPlayers = 0;
|
NumPlayers = 0;
|
||||||
|
MaxPlayers = 0;
|
||||||
|
|
||||||
NumMirrorClients = 0;
|
// TODO make this somewhat nicer
|
||||||
|
if (enet_initialize() != 0)
|
||||||
for (int i = 0; i < Blob_MAX; i++)
|
|
||||||
{
|
{
|
||||||
Blobs[i] = nullptr;
|
Platform::Log(Platform::LogLevel::Error, "Netplay: failed to initialize enet\n");
|
||||||
BlobLens[i] = 0;
|
return;
|
||||||
}
|
|
||||||
CurBlobType = -1;
|
|
||||||
CurBlobLen = 0;
|
|
||||||
|
|
||||||
/*if (enet_initialize() != 0)
|
|
||||||
{
|
|
||||||
printf("enet shat itself :(\n");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("enet init OK\n");*/
|
Platform::Log(Platform::LogLevel::Info, "Netplay: enet initialized\n");
|
||||||
return true;
|
Inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeInit()
|
Netplay::~Netplay()
|
||||||
{
|
{
|
||||||
// TODO: cleanup resources properly!!
|
EndSession();
|
||||||
|
|
||||||
//enet_deinitialize();
|
Inited = false;
|
||||||
|
enet_deinitialize();
|
||||||
|
|
||||||
|
Platform::Mutex_Free(PlayersMutex);
|
||||||
|
|
||||||
|
Platform::Log(Platform::LogLevel::Info, "Netplay: enet deinitialized\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StartHost(const char* playername, int port)
|
std::vector<Netplay::Player> Netplay::GetPlayerList()
|
||||||
|
{
|
||||||
|
Platform::Mutex_Lock(PlayersMutex);
|
||||||
|
|
||||||
|
std::vector<Player> ret;
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
if (Players[i].Status == Player_None) continue;
|
||||||
|
|
||||||
|
// make a copy of the player entry, fix up the address field
|
||||||
|
Player newp = Players[i];
|
||||||
|
if (newp.ID == MyPlayer.ID)
|
||||||
|
{
|
||||||
|
newp.IsLocalPlayer = true;
|
||||||
|
newp.Address = kLocalhost;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newp.IsLocalPlayer = false;
|
||||||
|
if (newp.Status == Player_Host)
|
||||||
|
newp.Address = HostAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push_back(newp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Platform::Mutex_Unlock(PlayersMutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Netplay::StartHost(const char* playername, int port)
|
||||||
{
|
{
|
||||||
ENetAddress addr;
|
ENetAddress addr;
|
||||||
addr.host = ENET_HOST_ANY;
|
addr.host = ENET_HOST_ANY;
|
||||||
|
@ -131,7 +119,7 @@ void StartHost(const char* playername, int port)
|
||||||
if (!Host)
|
if (!Host)
|
||||||
{
|
{
|
||||||
printf("host shat itself :(\n");
|
printf("host shat itself :(\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* player = &Players[0];
|
Player* player = &Players[0];
|
||||||
|
@ -145,7 +133,7 @@ void StartHost(const char* playername, int port)
|
||||||
|
|
||||||
HostAddress = 0x0100007F;
|
HostAddress = 0x0100007F;
|
||||||
|
|
||||||
NumMirrorClients = 0;
|
/*NumMirrorClients = 0;
|
||||||
|
|
||||||
ENetAddress mirroraddr;
|
ENetAddress mirroraddr;
|
||||||
mirroraddr.host = ENET_HOST_ANY;
|
mirroraddr.host = ENET_HOST_ANY;
|
||||||
|
@ -155,23 +143,24 @@ printf("host mirror host connecting to %08X:%d\n", mirroraddr.host, mirroraddr.p
|
||||||
if (!MirrorHost)
|
if (!MirrorHost)
|
||||||
{
|
{
|
||||||
printf("mirror host shat itself :(\n");
|
printf("mirror host shat itself :(\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
Active = true;
|
Active = true;
|
||||||
IsHost = true;
|
IsHost = true;
|
||||||
IsMirror = false;
|
//IsMirror = false;
|
||||||
|
|
||||||
//netplayDlg->updatePlayerList(Players, NumPlayers);
|
//netplayDlg->updatePlayerList(Players, NumPlayers);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartClient(const char* playername, const char* host, int port)
|
bool Netplay::StartClient(const char* playername, const char* host, int port)
|
||||||
{
|
{
|
||||||
Host = enet_host_create(nullptr, 1, 1, 0, 0);
|
Host = enet_host_create(nullptr, 1, 1, 0, 0);
|
||||||
if (!Host)
|
if (!Host)
|
||||||
{
|
{
|
||||||
printf("client shat itself :(\n");
|
printf("client shat itself :(\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("client created, connecting (%s, %s:%d)\n", playername, host, port);
|
printf("client created, connecting (%s, %s:%d)\n", playername, host, port);
|
||||||
|
@ -183,7 +172,7 @@ void StartClient(const char* playername, const char* host, int port)
|
||||||
if (!peer)
|
if (!peer)
|
||||||
{
|
{
|
||||||
printf("connect shat itself :(\n");
|
printf("connect shat itself :(\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
|
@ -201,7 +190,7 @@ void StartClient(const char* playername, const char* host, int port)
|
||||||
{
|
{
|
||||||
printf("connection failed\n");
|
printf("connection failed\n");
|
||||||
enet_peer_reset(peer);
|
enet_peer_reset(peer);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* player = &MyPlayer;
|
Player* player = &MyPlayer;
|
||||||
|
@ -214,10 +203,17 @@ void StartClient(const char* playername, const char* host, int port)
|
||||||
|
|
||||||
Active = true;
|
Active = true;
|
||||||
IsHost = false;
|
IsHost = false;
|
||||||
IsMirror = false;
|
//IsMirror = false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartMirror(const Player* player)
|
void Netplay::EndSession()
|
||||||
|
{
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void Netplay::StartMirror(const Player* player)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Blob_MAX; i++)
|
for (int i = 0; i < Blob_MAX; i++)
|
||||||
{
|
{
|
||||||
|
@ -275,7 +271,7 @@ void StartMirror(const Player* player)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u32 PlayerAddress(int id)
|
u32 Netplay::PlayerAddress(int id)
|
||||||
{
|
{
|
||||||
if (id < 0 || id > 16) return 0;
|
if (id < 0 || id > 16) return 0;
|
||||||
|
|
||||||
|
@ -285,9 +281,9 @@ u32 PlayerAddress(int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SpawnMirrorInstance(Player player)
|
bool Netplay::SpawnMirrorInstance(Player player)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
u16 curmask = IPC::GetInstanceBitmask();
|
u16 curmask = IPC::GetInstanceBitmask();
|
||||||
|
|
||||||
QProcess newinst;
|
QProcess newinst;
|
||||||
|
@ -336,11 +332,11 @@ bool SpawnMirrorInstance(Player player)
|
||||||
if (player.Address == 0x0100007F) player.Address = HostAddress;
|
if (player.Address == 0x0100007F) player.Address = HostAddress;
|
||||||
// calls Netplay::StartMirror()
|
// calls Netplay::StartMirror()
|
||||||
//IPC::SendCommand(1<<newid, IPC::Cmd_SetupNetplayMirror, sizeof(Player), &player);
|
//IPC::SendCommand(1<<newid, IPC::Cmd_SetupNetplayMirror, sizeof(Player), &player);
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendBlobToMirrorClients(int type, u32 len, u8* data)
|
bool Netplay::SendBlobToMirrorClients(int type, u32 len, u8* data)
|
||||||
{
|
{
|
||||||
u8* buf = ChunkBuffer;
|
u8* buf = ChunkBuffer;
|
||||||
|
|
||||||
|
@ -381,7 +377,7 @@ bool SendBlobToMirrorClients(int type, u32 len, u8* data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecvBlobFromMirrorHost(ENetPeer* peer, ENetPacket* pkt)
|
void Netplay::RecvBlobFromMirrorHost(ENetPeer* peer, ENetPacket* pkt)
|
||||||
{
|
{
|
||||||
u8* buf = pkt->data;
|
u8* buf = pkt->data;
|
||||||
if (buf[0] == 0x01)
|
if (buf[0] == 0x01)
|
||||||
|
@ -463,7 +459,7 @@ printf("[MC] finish blob type=%d len=%d\n", type, len);
|
||||||
if (pkt->dataLength != 2) return;
|
if (pkt->dataLength != 2) return;
|
||||||
|
|
||||||
bool res = false;
|
bool res = false;
|
||||||
#if 0
|
|
||||||
// reset
|
// reset
|
||||||
NDS::SetConsoleType(buf[1]);
|
NDS::SetConsoleType(buf[1]);
|
||||||
NDS::EjectCart();
|
NDS::EjectCart();
|
||||||
|
@ -488,10 +484,10 @@ printf("[MC] finish blob type=%d len=%d\n", type, len);
|
||||||
|
|
||||||
//LoadCheats();
|
//LoadCheats();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// load initial state
|
// load initial state
|
||||||
// TODO: terrible hack!!
|
// TODO: terrible hack!!
|
||||||
#if 0
|
|
||||||
FILE* f = Platform::OpenFile("netplay2.mln", "wb");
|
FILE* f = Platform::OpenFile("netplay2.mln", "wb");
|
||||||
fwrite(Blobs[Blob_InitState], BlobLens[Blob_InitState], 1, f);
|
fwrite(Blobs[Blob_InitState], BlobLens[Blob_InitState], 1, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -513,7 +509,6 @@ printf("[MC] finish blob type=%d len=%d\n", type, len);
|
||||||
printf("[MC] state loaded, PC=%08X/%08X\n", NDS::GetPC(0), NDS::GetPC(1));
|
printf("[MC] state loaded, PC=%08X/%08X\n", NDS::GetPC(0), NDS::GetPC(1));
|
||||||
ENetPacket* resp = enet_packet_create(buf, 1, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket* resp = enet_packet_create(buf, 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_peer_send(peer, 1, resp);
|
enet_peer_send(peer, 1, resp);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (buf[0] == 0x05)
|
else if (buf[0] == 0x05)
|
||||||
{
|
{
|
||||||
|
@ -522,11 +517,12 @@ printf("[MC] state loaded, PC=%08X/%08X\n", NDS::GetPC(0), NDS::GetPC(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncMirrorClients()
|
|
||||||
|
void Netplay::SyncMirrorClients()
|
||||||
{
|
{
|
||||||
printf("[MIRROR HOST] syncing clients\n");
|
printf("[MIRROR HOST] syncing clients\n");
|
||||||
|
|
||||||
#if 0
|
|
||||||
SendBlobToMirrorClients(Blob_CartSRAM, NDSCart::GetSaveMemoryLength(), NDSCart::GetSaveMemory());
|
SendBlobToMirrorClients(Blob_CartSRAM, NDSCart::GetSaveMemoryLength(), NDSCart::GetSaveMemory());
|
||||||
|
|
||||||
// send initial state
|
// send initial state
|
||||||
|
@ -586,10 +582,11 @@ void SyncMirrorClients()
|
||||||
//enet_host_flush(MirrorHost);
|
//enet_host_flush(MirrorHost);
|
||||||
|
|
||||||
StartLocal();
|
StartLocal();
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartGame()
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Netplay::StartGame()
|
||||||
{
|
{
|
||||||
if (!IsHost)
|
if (!IsHost)
|
||||||
{
|
{
|
||||||
|
@ -600,7 +597,7 @@ void StartGame()
|
||||||
// spawn mirror instances as needed
|
// spawn mirror instances as needed
|
||||||
for (int i = 1; i < NumPlayers; i++)
|
for (int i = 1; i < NumPlayers; i++)
|
||||||
{
|
{
|
||||||
SpawnMirrorInstance(Players[i]);
|
//SpawnMirrorInstance(Players[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//SyncMirrorClients();
|
//SyncMirrorClients();
|
||||||
|
@ -623,7 +620,7 @@ void StartGame()
|
||||||
//StartLocal();
|
//StartLocal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartLocal()
|
void Netplay::StartLocal()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
@ -641,7 +638,7 @@ void StartLocal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ProcessHost()
|
void Netplay::ProcessHost()
|
||||||
{
|
{
|
||||||
if (!Host) return;
|
if (!Host) return;
|
||||||
|
|
||||||
|
@ -730,7 +727,7 @@ void ProcessHost()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessClient()
|
void Netplay::ProcessClient()
|
||||||
{
|
{
|
||||||
if (!Host) return;
|
if (!Host) return;
|
||||||
|
|
||||||
|
@ -764,7 +761,7 @@ void ProcessClient()
|
||||||
NumMirrorClients = 0;
|
NumMirrorClients = 0;
|
||||||
|
|
||||||
// create mirror host
|
// create mirror host
|
||||||
ENetAddress mirroraddr;
|
/*ENetAddress mirroraddr;
|
||||||
mirroraddr.host = ENET_HOST_ANY;
|
mirroraddr.host = ENET_HOST_ANY;
|
||||||
mirroraddr.port = 8064+1 + data[1]; // FIXME!!!!
|
mirroraddr.port = 8064+1 + data[1]; // FIXME!!!!
|
||||||
printf("client mirror host connecting to %08X:%d\n", mirroraddr.host, mirroraddr.port);
|
printf("client mirror host connecting to %08X:%d\n", mirroraddr.host, mirroraddr.port);
|
||||||
|
@ -773,7 +770,7 @@ printf("client mirror host connecting to %08X:%d\n", mirroraddr.host, mirroraddr
|
||||||
{
|
{
|
||||||
printf("mirror host shat itself :(\n");
|
printf("mirror host shat itself :(\n");
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// send player information
|
// send player information
|
||||||
MyPlayer.ID = data[1];
|
MyPlayer.ID = data[1];
|
||||||
|
@ -804,11 +801,11 @@ printf("client mirror host connecting to %08X:%d\n", mirroraddr.host, mirroraddr
|
||||||
case 0x04: // start game
|
case 0x04: // start game
|
||||||
{
|
{
|
||||||
// spawn mirror instances as needed
|
// spawn mirror instances as needed
|
||||||
for (int i = 0; i < NumPlayers; i++)
|
/*for (int i = 0; i < NumPlayers; i++)
|
||||||
{
|
{
|
||||||
if (i != MyPlayer.ID)
|
if (i != MyPlayer.ID)
|
||||||
SpawnMirrorInstance(Players[i]);
|
SpawnMirrorInstance(Players[i]);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//SyncMirrorClients();
|
//SyncMirrorClients();
|
||||||
printf("bourf\n");
|
printf("bourf\n");
|
||||||
|
@ -826,10 +823,11 @@ printf("birf\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessMirrorHost()
|
#if 0
|
||||||
|
void Netplay::ProcessMirrorHost()
|
||||||
{
|
{
|
||||||
if (!MirrorHost) return;
|
if (!MirrorHost) return;
|
||||||
#if 0
|
|
||||||
bool block = false;
|
bool block = false;
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
while (enet_host_service(MirrorHost, &event, block ? 5000 : 0) > 0)
|
while (enet_host_service(MirrorHost, &event, block ? 5000 : 0) > 0)
|
||||||
|
@ -915,13 +913,12 @@ void ProcessMirrorHost()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessMirrorClient()
|
void Netplay::ProcessMirrorClient()
|
||||||
{
|
{
|
||||||
if (!MirrorHost) return;
|
if (!MirrorHost) return;
|
||||||
#if 0
|
|
||||||
bool block = false;
|
bool block = false;
|
||||||
if (emuThread->emuIsRunning())// && NDS::NumFrames > 4)
|
if (emuThread->emuIsRunning())// && NDS::NumFrames > 4)
|
||||||
{
|
{
|
||||||
|
@ -982,16 +979,16 @@ printf("mirror client lag notify: %d\n", lag);
|
||||||
|
|
||||||
if (block) break;
|
if (block) break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ProcessFrame()
|
void Netplay::ProcessFrame()
|
||||||
{
|
{
|
||||||
if (IsMirror)
|
/*if (IsMirror)
|
||||||
{
|
{
|
||||||
ProcessMirrorClient();
|
ProcessMirrorClient();
|
||||||
}
|
}
|
||||||
else
|
else*/
|
||||||
{
|
{
|
||||||
if (IsHost)
|
if (IsHost)
|
||||||
{
|
{
|
||||||
|
@ -1002,11 +999,12 @@ void ProcessFrame()
|
||||||
ProcessClient();
|
ProcessClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessMirrorHost();
|
//ProcessMirrorHost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessInput()
|
#if 0
|
||||||
|
void Netplay::ProcessInput()
|
||||||
{
|
{
|
||||||
// netplay input processing
|
// netplay input processing
|
||||||
//
|
//
|
||||||
|
@ -1022,7 +1020,7 @@ void ProcessInput()
|
||||||
// apply each input to the frame it's assigned to
|
// apply each input to the frame it's assigned to
|
||||||
// before running a frame, we need to wait to have received input for it
|
// before running a frame, we need to wait to have received input for it
|
||||||
// TODO: alert host if we are running too far behind
|
// TODO: alert host if we are running too far behind
|
||||||
#if 0
|
|
||||||
if (!IsMirror)
|
if (!IsMirror)
|
||||||
{
|
{
|
||||||
u32 lag = 4; // TODO: make configurable!!
|
u32 lag = 4; // TODO: make configurable!!
|
||||||
|
@ -1078,7 +1076,13 @@ void ProcessInput()
|
||||||
else NDS::ReleaseScreen();
|
else NDS::ReleaseScreen();
|
||||||
|
|
||||||
InputQueue.pop();
|
InputQueue.pop();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void Netplay::Process()
|
||||||
|
{
|
||||||
|
ProcessFrame();
|
||||||
|
LocalMP::Process();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,39 +19,93 @@
|
||||||
#ifndef NETPLAY_H
|
#ifndef NETPLAY_H
|
||||||
#define NETPLAY_H
|
#define NETPLAY_H
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include <enet/enet.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "Platform.h"
|
||||||
|
#include "LocalMP.h"
|
||||||
|
|
||||||
namespace Netplay
|
namespace melonDS
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Player
|
// since netplay relies on local MP comm locally,
|
||||||
|
// we extend the LocalMP class to reuse its functionality
|
||||||
|
class Netplay : public LocalMP
|
||||||
{
|
{
|
||||||
int ID;
|
public:
|
||||||
char Name[32];
|
Netplay() noexcept;
|
||||||
int Status; // 0=no player 1=normal 2=host 3=connecting
|
Netplay(const Netplay&) = delete;
|
||||||
melonDS::u32 Address;
|
Netplay& operator=(const Netplay&) = delete;
|
||||||
|
Netplay(Netplay&& other) = delete;
|
||||||
|
Netplay& operator=(Netplay&& other) = delete;
|
||||||
|
~Netplay() noexcept;
|
||||||
|
|
||||||
|
enum PlayerStatus
|
||||||
|
{
|
||||||
|
Player_None = 0, // no player in this entry
|
||||||
|
Player_Client, // game client
|
||||||
|
Player_Host, // game host
|
||||||
|
Player_Connecting, // player still connecting
|
||||||
|
Player_Disconnected, // player disconnected
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Player
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
char Name[32];
|
||||||
|
int Status; // 0=no player 1=normal 2=host 3=connecting
|
||||||
|
u32 Address;
|
||||||
|
bool IsLocalPlayer;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool StartHost(const char* player, int port);
|
||||||
|
bool StartClient(const char* player, const char* host, int port);
|
||||||
|
void EndSession();
|
||||||
|
|
||||||
|
std::vector<Player> GetPlayerList();
|
||||||
|
int GetNumPlayers() { return NumPlayers; }
|
||||||
|
int GetMaxPlayers() { return MaxPlayers; }
|
||||||
|
|
||||||
|
void Process() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Inited;
|
||||||
|
bool Active;
|
||||||
|
bool IsHost;
|
||||||
|
|
||||||
|
ENetHost* Host;
|
||||||
|
ENetPeer* RemotePeers[16];
|
||||||
|
|
||||||
|
Player Players[16];
|
||||||
|
int NumPlayers;
|
||||||
|
int MaxPlayers;
|
||||||
|
Platform::Mutex* PlayersMutex;
|
||||||
|
|
||||||
|
Player MyPlayer;
|
||||||
|
u32 HostAddress;
|
||||||
|
bool Lag;
|
||||||
|
|
||||||
|
int NumMirrorClients;
|
||||||
|
|
||||||
|
struct InputFrame
|
||||||
|
{
|
||||||
|
u32 FrameNum;
|
||||||
|
u32 KeyMask;
|
||||||
|
u32 Touching;
|
||||||
|
u32 TouchX, TouchY;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::queue<InputFrame> InputQueue;
|
||||||
|
|
||||||
|
void StartGame();
|
||||||
|
void StartLocal();
|
||||||
|
void ProcessHost();
|
||||||
|
void ProcessClient();
|
||||||
|
void ProcessFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern bool Active;
|
|
||||||
|
|
||||||
bool Init();
|
|
||||||
void DeInit();
|
|
||||||
|
|
||||||
void StartHost(const char* player, int port);
|
|
||||||
void StartClient(const char* player, const char* host, int port);
|
|
||||||
void StartMirror(const Player* player);
|
|
||||||
|
|
||||||
melonDS::u32 PlayerAddress(int id);
|
|
||||||
|
|
||||||
void StartGame();
|
|
||||||
void StartLocal();
|
|
||||||
|
|
||||||
void StartGame();
|
|
||||||
|
|
||||||
void ProcessFrame();
|
|
||||||
void ProcessInput();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NETPLAY_H
|
#endif // NETPLAY_H
|
||||||
|
|
Loading…
Reference in New Issue