mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-24 14:49:53 -06:00
more WIP
This commit is contained in:
@ -371,6 +371,15 @@ void SetActive(bool active)
|
|||||||
Buffer->unlock();
|
Buffer->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 GetInstanceBitmask()
|
||||||
|
{
|
||||||
|
Buffer->lock();
|
||||||
|
BufferHeader* header = (BufferHeader*)Buffer->data();
|
||||||
|
u16 ret = header->InstanceBitmask;
|
||||||
|
Buffer->unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<int fifo> void FIFORead(void* buf, int len)
|
template<int fifo> void FIFORead(void* buf, int len)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,8 @@ enum
|
|||||||
{
|
{
|
||||||
Cmd_Pause = 1,
|
Cmd_Pause = 1,
|
||||||
|
|
||||||
|
Cmd_SetupNetplayMirror,
|
||||||
|
|
||||||
Cmd_MAX
|
Cmd_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,6 +46,8 @@ void MPEnd();
|
|||||||
|
|
||||||
void SetActive(bool active);
|
void SetActive(bool active);
|
||||||
|
|
||||||
|
u16 GetInstanceBitmask();
|
||||||
|
|
||||||
void ProcessCommands();
|
void ProcessCommands();
|
||||||
bool SendCommand(u16 recipients, u16 command, u16 len, void* data);
|
bool SendCommand(u16 recipients, u16 command, u16 len, void* data);
|
||||||
bool SendCommandU8(u16 recipients, u16 command, u8 arg);
|
bool SendCommandU8(u16 recipients, u16 command, u8 arg);
|
||||||
|
@ -24,9 +24,11 @@
|
|||||||
#include <enet/enet.h>
|
#include <enet/enet.h>
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "IPC.h"
|
||||||
#include "Netplay.h"
|
#include "Netplay.h"
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
|
|
||||||
@ -137,7 +139,9 @@ void NetplayDialog::doUpdatePlayerList(Netplay::Player* players, int num)
|
|||||||
model->clear();
|
model->clear();
|
||||||
model->setRowCount(num);
|
model->setRowCount(num);
|
||||||
|
|
||||||
const QStringList header = {"#", "Player", "Status", "Ping"};
|
// TODO: remove IP column in final product
|
||||||
|
|
||||||
|
const QStringList header = {"#", "Player", "Status", "Ping", "IP"};
|
||||||
model->setHorizontalHeaderLabels(header);
|
model->setHorizontalHeaderLabels(header);
|
||||||
|
|
||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
@ -161,6 +165,11 @@ void NetplayDialog::doUpdatePlayerList(Netplay::Player* players, int num)
|
|||||||
|
|
||||||
// TODO: ping
|
// TODO: ping
|
||||||
model->setItem(i, 3, new QStandardItem("x"));
|
model->setItem(i, 3, new QStandardItem("x"));
|
||||||
|
|
||||||
|
char ip[32];
|
||||||
|
u32 addr = player->Address;
|
||||||
|
sprintf(ip, "%d.%d.%d.%d", addr&0xFF, (addr>>8)&0xFF, (addr>>16)&0xFF, addr>>24);
|
||||||
|
model->setItem(i, 4, new QStandardItem(ip));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,13 +179,16 @@ namespace Netplay
|
|||||||
|
|
||||||
bool Active;
|
bool Active;
|
||||||
bool IsHost;
|
bool IsHost;
|
||||||
|
bool IsMirror;
|
||||||
|
|
||||||
ENetHost* Host;
|
ENetHost* Host;
|
||||||
|
ENetHost* MirrorHost;
|
||||||
|
|
||||||
Player Players[16];
|
Player Players[16];
|
||||||
int NumPlayers;
|
int NumPlayers;
|
||||||
|
|
||||||
Player TempPlayer; // holds client player info temporarily
|
Player MyPlayer;
|
||||||
|
u32 HostAddress;
|
||||||
|
|
||||||
struct InputFrame
|
struct InputFrame
|
||||||
{
|
{
|
||||||
@ -187,14 +199,13 @@ struct InputFrame
|
|||||||
std::queue<InputFrame> InputQueue;
|
std::queue<InputFrame> InputQueue;
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
bool Init()
|
||||||
{
|
{
|
||||||
Active = false;
|
Active = false;
|
||||||
IsHost = false;
|
IsHost = false;
|
||||||
|
IsMirror = false;
|
||||||
Host = nullptr;
|
Host = nullptr;
|
||||||
|
MirrorHost = nullptr;
|
||||||
|
|
||||||
memset(Players, 0, sizeof(Players));
|
memset(Players, 0, sizeof(Players));
|
||||||
NumPlayers = 0;
|
NumPlayers = 0;
|
||||||
@ -211,6 +222,8 @@ bool Init()
|
|||||||
|
|
||||||
void DeInit()
|
void DeInit()
|
||||||
{
|
{
|
||||||
|
// TODO: cleanup resources properly!!
|
||||||
|
|
||||||
enet_deinitialize();
|
enet_deinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,10 +246,26 @@ void StartHost(const char* playername, int port)
|
|||||||
player->ID = 0;
|
player->ID = 0;
|
||||||
strncpy(player->Name, playername, 31);
|
strncpy(player->Name, playername, 31);
|
||||||
player->Status = 2;
|
player->Status = 2;
|
||||||
|
player->Address = 0x0100007F;
|
||||||
NumPlayers = 1;
|
NumPlayers = 1;
|
||||||
|
memcpy(&MyPlayer, player, sizeof(Player));
|
||||||
|
|
||||||
|
HostAddress = 0x0100007F;
|
||||||
|
|
||||||
|
ENetAddress mirroraddr;
|
||||||
|
mirroraddr.host = ENET_HOST_ANY;
|
||||||
|
mirroraddr.port = port + 1;
|
||||||
|
|
||||||
|
MirrorHost = enet_host_create(&mirroraddr, 16, 1, 0, 0);
|
||||||
|
if (!MirrorHost)
|
||||||
|
{
|
||||||
|
printf("mirror host shat itself :(\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Active = true;
|
Active = true;
|
||||||
IsHost = true;
|
IsHost = true;
|
||||||
|
IsMirror = false;
|
||||||
|
|
||||||
netplayDlg->updatePlayerList(Players, NumPlayers);
|
netplayDlg->updatePlayerList(Players, NumPlayers);
|
||||||
}
|
}
|
||||||
@ -280,17 +309,79 @@ void StartClient(const char* playername, const char* host, int port)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* player = &TempPlayer;
|
Player* player = &MyPlayer;
|
||||||
memset(player, 0, sizeof(Player));
|
memset(player, 0, sizeof(Player));
|
||||||
player->ID = 0;
|
player->ID = 0;
|
||||||
strncpy(player->Name, playername, 31);
|
strncpy(player->Name, playername, 31);
|
||||||
player->Status = 3;
|
player->Status = 3;
|
||||||
|
|
||||||
|
HostAddress = addr.host;
|
||||||
|
|
||||||
Active = true;
|
Active = true;
|
||||||
IsHost = false;
|
IsHost = false;
|
||||||
|
IsMirror = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u32 PlayerAddress(int id)
|
||||||
|
{
|
||||||
|
if (id < 0 || id > 16) return 0;
|
||||||
|
|
||||||
|
u32 ret = Players[id].Address;
|
||||||
|
if (ret == 0x0100007F) ret = HostAddress;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SpawnMirrorInstance(Player* player)
|
||||||
|
{
|
||||||
|
u16 curmask = IPC::GetInstanceBitmask();
|
||||||
|
|
||||||
|
QProcess newinst;
|
||||||
|
newinst.setProgram(QApplication::applicationFilePath());
|
||||||
|
newinst.setArguments(QApplication::arguments().mid(1, QApplication::arguments().length()-1));
|
||||||
|
|
||||||
|
#ifdef __WIN32__
|
||||||
|
newinst.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
|
||||||
|
{
|
||||||
|
args->flags |= CREATE_NEW_CONSOLE;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!newinst.startDetached())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// try to determine the ID of the new instance
|
||||||
|
|
||||||
|
int newid = -1;
|
||||||
|
for (int tries = 0; tries < 10; tries++)
|
||||||
|
{
|
||||||
|
QThread::usleep(100 * 1000);
|
||||||
|
|
||||||
|
u16 newmask = IPC::GetInstanceBitmask();
|
||||||
|
if (newmask == curmask) continue;
|
||||||
|
|
||||||
|
newmask &= ~curmask;
|
||||||
|
for (int id = 0; id < 32; id++)
|
||||||
|
{
|
||||||
|
if (newmask & (1 << id))
|
||||||
|
{
|
||||||
|
newid = id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newid == -1) return false;
|
||||||
|
|
||||||
|
// setup that instance
|
||||||
|
printf("netplay: spawned mirror instance for player %d with ID %d, configuring\n", player->ID, newid);
|
||||||
|
|
||||||
|
IPC::SendCommand(1<<newid, IPC::Cmd_SetupNetplayMirror, sizeof(Player), player);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void StartGame()
|
void StartGame()
|
||||||
{
|
{
|
||||||
if (!IsHost)
|
if (!IsHost)
|
||||||
@ -338,6 +429,7 @@ void ProcessHost()
|
|||||||
|
|
||||||
Players[id].ID = id;
|
Players[id].ID = id;
|
||||||
Players[id].Status = 3;
|
Players[id].Status = 3;
|
||||||
|
Players[id].Address = event.peer->address.host;
|
||||||
event.peer->data = &Players[id];
|
event.peer->data = &Players[id];
|
||||||
NumPlayers++;
|
NumPlayers++;
|
||||||
}
|
}
|
||||||
@ -375,6 +467,7 @@ void ProcessHost()
|
|||||||
}
|
}
|
||||||
|
|
||||||
player.Status = 1;
|
player.Status = 1;
|
||||||
|
player.Address = event.peer->address.host;
|
||||||
memcpy(hostside, &player, sizeof(Player));
|
memcpy(hostside, &player, sizeof(Player));
|
||||||
|
|
||||||
// broadcast updated player list
|
// broadcast updated player list
|
||||||
@ -425,10 +518,10 @@ void ProcessClient()
|
|||||||
if (event.packet->dataLength != 2) break;
|
if (event.packet->dataLength != 2) break;
|
||||||
|
|
||||||
// send player information
|
// send player information
|
||||||
TempPlayer.ID = data[1];printf("host assigned ID: %d\n", data[1]);
|
MyPlayer.ID = data[1];
|
||||||
u8 cmd[1+sizeof(Player)];
|
u8 cmd[1+sizeof(Player)];
|
||||||
cmd[0] = 0x02;
|
cmd[0] = 0x02;
|
||||||
memcpy(&cmd[1], &TempPlayer, sizeof(Player));
|
memcpy(&cmd[1], &MyPlayer, sizeof(Player));
|
||||||
ENetPacket* pkt = enet_packet_create(cmd, 1+sizeof(Player), ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket* pkt = enet_packet_create(cmd, 1+sizeof(Player), ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_peer_send(event.peer, 0, pkt);
|
enet_peer_send(event.peer, 0, pkt);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ struct Player
|
|||||||
int ID;
|
int ID;
|
||||||
char Name[32];
|
char Name[32];
|
||||||
int Status; // 0=no player 1=normal 2=host 3=connecting
|
int Status; // 0=no player 1=normal 2=host 3=connecting
|
||||||
|
u32 Address;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -129,6 +130,9 @@ void DeInit();
|
|||||||
|
|
||||||
void StartHost(const char* player, int port);
|
void StartHost(const char* player, int port);
|
||||||
void StartClient(const char* player, const char* host, int port);
|
void StartClient(const char* player, const char* host, int port);
|
||||||
|
void StartMirror(const Player* player);
|
||||||
|
|
||||||
|
u32 PlayerAddress(int id);
|
||||||
|
|
||||||
void StartGame();
|
void StartGame();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user