diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index 0aa438ff..c6dfc158 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -38,6 +38,7 @@ #include "EmuInstance.h" #include "Config.h" #include "Platform.h" +#include "LocalMP.h" #include "NDS.h" #include "DSi.h" @@ -99,6 +100,8 @@ EmuInstance::~EmuInstance() { // TODO window cleanup and shit? + LocalMP::End(instanceID); + emuThread->emuExit(); emuThread->wait(); delete emuThread; diff --git a/src/frontend/qt_sdl/LocalMP.cpp b/src/frontend/qt_sdl/LocalMP.cpp index 7ea98686..e59613ce 100644 --- a/src/frontend/qt_sdl/LocalMP.cpp +++ b/src/frontend/qt_sdl/LocalMP.cpp @@ -33,6 +33,8 @@ #include #include +#include +#include #include "Config.h" #include "LocalMP.h" @@ -47,17 +49,12 @@ using Platform::LogLevel; namespace LocalMP { -u32 MPUniqueID; -u8 PacketBuffer[2048]; - -struct MPQueueHeader +struct MPStatusData { - u16 NumInstances; - u16 InstanceBitmask; // bitmask of all instances present u16 ConnectedBitmask; // bitmask of which instances are ready to send/receive packets u32 PacketWriteOffset; u32 ReplyWriteOffset; - u16 MPHostInstanceID; // instance ID from which the last CMD frame was sent + u16 MPHostinst; // instance ID from which the last CMD frame was sent u16 MPReplyBitmask; // bitmask of which clients replied in time }; @@ -70,23 +67,15 @@ struct MPPacketHeader u64 Timestamp; }; -struct MPSync -{ - u32 Magic; - u32 SenderID; - u16 ClientMask; - u16 Type; - u64 Timestamp; -}; - -QSharedMemory* MPQueue; -int InstanceID; -u32 PacketReadOffset; -u32 ReplyReadOffset; +QMutex MPQueueLock; +MPStatusData MPStatus; +u8* MPQueue = nullptr; +u32 PacketReadOffset[16]; +u32 ReplyReadOffset[16]; const u32 kQueueSize = 0x20000; const u32 kMaxFrameSize = 0x800; -const u32 kPacketStart = sizeof(MPQueueHeader); +const u32 kPacketStart = 0; const u32 kReplyStart = kQueueSize / 2; const u32 kPacketEnd = kReplyStart; const u32 kReplyEnd = kQueueSize; @@ -96,204 +85,57 @@ int RecvTimeout; int LastHostID; -// we need to come up with our own abstraction layer for named semaphores -// because QSystemSemaphore doesn't support waiting with a timeout -// and, as such, is unsuitable to our needs - -#ifdef __WIN32__ - -bool SemInited[32]; -HANDLE SemPool[32]; +QSemaphore SemPool[32]; void SemPoolInit() { for (int i = 0; i < 32; i++) { - SemPool[i] = INVALID_HANDLE_VALUE; - SemInited[i] = false; + SemPool[i].acquire(SemPool[i].available()); } } -void SemDeinit(int num); - -void SemPoolDeinit() -{ - for (int i = 0; i < 32; i++) - SemDeinit(i); -} - -bool SemInit(int num) -{ - if (SemInited[num]) - return true; - - char semname[64]; - sprintf(semname, "Local\\melonNIFI_Sem%02d", num); - - HANDLE sem = CreateSemaphoreA(nullptr, 0, 64, semname); - SemPool[num] = sem; - SemInited[num] = true; - return sem != INVALID_HANDLE_VALUE; -} - -void SemDeinit(int num) -{ - if (SemPool[num] != INVALID_HANDLE_VALUE) - { - CloseHandle(SemPool[num]); - SemPool[num] = INVALID_HANDLE_VALUE; - } - - SemInited[num] = false; -} - bool SemPost(int num) { - SemInit(num); - return ReleaseSemaphore(SemPool[num], 1, nullptr) != 0; -} - -bool SemWait(int num, int timeout) -{ - return WaitForSingleObject(SemPool[num], timeout) == WAIT_OBJECT_0; -} - -void SemReset(int num) -{ - while (WaitForSingleObject(SemPool[num], 0) == WAIT_OBJECT_0); -} - -#else - -bool SemInited[32]; -sem_t* SemPool[32]; - -void SemPoolInit() -{ - for (int i = 0; i < 32; i++) - { - SemPool[i] = SEM_FAILED; - SemInited[i] = false; - } -} - -void SemDeinit(int num); - -void SemPoolDeinit() -{ - for (int i = 0; i < 32; i++) - SemDeinit(i); -} - -bool SemInit(int num) -{ - if (SemInited[num]) - return true; - - char semname[64]; - sprintf(semname, "/melonNIFI_Sem%02d", num); - - sem_t* sem = sem_open(semname, O_CREAT, 0644, 0); - SemPool[num] = sem; - SemInited[num] = true; - return sem != SEM_FAILED; -} - -void SemDeinit(int num) -{ - if (SemPool[num] != SEM_FAILED) - { - sem_close(SemPool[num]); - SemPool[num] = SEM_FAILED; - } - - SemInited[num] = false; -} - -bool SemPost(int num) -{ - SemInit(num); - return sem_post(SemPool[num]) == 0; + SemPool[num].release(1); + return true; } bool SemWait(int num, int timeout) { if (!timeout) - return sem_trywait(SemPool[num]) == 0; + return SemPool[num].tryAcquire(1); - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_nsec += timeout * 1000000; - long sec = ts.tv_nsec / 1000000000; - ts.tv_nsec -= sec * 1000000000; - ts.tv_sec += sec; - - return sem_timedwait(SemPool[num], &ts) == 0; + return SemPool[num].tryAcquire(1, timeout); } void SemReset(int num) { - while (sem_trywait(SemPool[num]) == 0); + SemPool[num].acquire(SemPool[num].available()); } -#endif - bool Init() { - MPQueue = new QSharedMemory("melonNIFI"); + MPQueueLock.lock(); - if (!MPQueue->attach()) - { - Log(LogLevel::Info, "MP sharedmem doesn't exist. creating\n"); - if (!MPQueue->create(kQueueSize)) - { - Log(LogLevel::Error, "MP sharedmem create failed :( (%d)\n", MPQueue->error()); - delete MPQueue; - MPQueue = nullptr; - return false; - } + MPQueue = new u8[kQueueSize]; + memset(MPQueue, 0, kQueueSize); + memset(&MPStatus, 0, sizeof(MPStatus)); + memset(PacketReadOffset, 0, sizeof(PacketReadOffset)); + memset(ReplyReadOffset, 0, sizeof(ReplyReadOffset)); - MPQueue->lock(); - memset(MPQueue->data(), 0, MPQueue->size()); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - header->PacketWriteOffset = kPacketStart; - header->ReplyWriteOffset = kReplyStart; - MPQueue->unlock(); - } - - MPQueue->lock(); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - - u16 mask = header->InstanceBitmask; - for (int i = 0; i < 16; i++) - { - if (!(mask & (1<InstanceBitmask |= (1<ConnectedBitmask |= (1 << i); - break; - } - } - header->NumInstances++; - - PacketReadOffset = header->PacketWriteOffset; - ReplyReadOffset = header->ReplyWriteOffset; - - MPQueue->unlock(); + MPQueueLock.unlock(); // prepare semaphores // semaphores 0-15: regular frames; semaphore I is posted when instance I needs to process a new frame // semaphores 16-31: MP replies; semaphore I is posted when instance I needs to process a new MP reply SemPoolInit(); - SemInit(InstanceID); - SemInit(16+InstanceID); LastHostID = -1; - Log(LogLevel::Info, "MP comm init OK, instance ID %d\n", InstanceID); + Log(LogLevel::Info, "MP comm init OK\n"); RecvTimeout = 25; @@ -302,23 +144,6 @@ bool Init() void DeInit() { - if (MPQueue) - { - MPQueue->lock(); - if (MPQueue->data() != nullptr) - { - MPQueueHeader *header = (MPQueueHeader *) MPQueue->data(); - header->ConnectedBitmask &= ~(1 << InstanceID); - header->InstanceBitmask &= ~(1 << InstanceID); - header->NumInstances--; - } - MPQueue->unlock(); - - SemPoolDeinit(); - - MPQueue->detach(); - } - delete MPQueue; MPQueue = nullptr; } @@ -328,44 +153,42 @@ void SetRecvTimeout(int timeout) RecvTimeout = timeout; } -void Begin() +void Begin(int inst) { if (!MPQueue) return; - MPQueue->lock(); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - PacketReadOffset = header->PacketWriteOffset; - ReplyReadOffset = header->ReplyWriteOffset; - SemReset(InstanceID); - SemReset(16+InstanceID); - header->ConnectedBitmask |= (1 << InstanceID); - MPQueue->unlock(); + + MPQueueLock.lock(); + PacketReadOffset[inst] = MPStatus.PacketWriteOffset; + ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset; + SemReset(inst); + SemReset(16+inst); + MPStatus.ConnectedBitmask |= (1 << inst); + MPQueueLock.unlock(); } -void End() +void End(int inst) { if (!MPQueue) return; - MPQueue->lock(); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - //SemReset(InstanceID); - //SemReset(16+InstanceID); - header->ConnectedBitmask &= ~(1 << InstanceID); - MPQueue->unlock(); + + MPQueueLock.lock(); + MPStatus.ConnectedBitmask &= ~(1 << inst); + MPQueueLock.unlock(); } -void FIFORead(int fifo, void* buf, int len) +void FIFORead(int inst, int fifo, void* buf, int len) { - u8* data = (u8*)MPQueue->data(); + u8* data = MPQueue; u32 offset, start, end; if (fifo == 0) { - offset = PacketReadOffset; + offset = PacketReadOffset[inst]; start = kPacketStart; end = kPacketEnd; } else { - offset = ReplyReadOffset; + offset = ReplyReadOffset[inst]; start = kReplyStart; end = kReplyEnd; } @@ -383,25 +206,24 @@ void FIFORead(int fifo, void* buf, int len) offset += len; } - if (fifo == 0) PacketReadOffset = offset; - else ReplyReadOffset = offset; + if (fifo == 0) PacketReadOffset[inst] = offset; + else ReplyReadOffset[inst] = offset; } -void FIFOWrite(int fifo, void* buf, int len) +void FIFOWrite(int inst, int fifo, void* buf, int len) { - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; + u8* data = MPQueue; u32 offset, start, end; if (fifo == 0) { - offset = header->PacketWriteOffset; + offset = MPStatus.PacketWriteOffset; start = kPacketStart; end = kPacketEnd; } else { - offset = header->ReplyWriteOffset; + offset = MPStatus.ReplyWriteOffset; start = kReplyStart; end = kReplyEnd; } @@ -419,53 +241,51 @@ void FIFOWrite(int fifo, void* buf, int len) offset += len; } - if (fifo == 0) header->PacketWriteOffset = offset; - else header->ReplyWriteOffset = offset; + if (fifo == 0) MPStatus.PacketWriteOffset = offset; + else MPStatus.ReplyWriteOffset = offset; } -int SendPacketGeneric(u32 type, u8* packet, int len, u64 timestamp) +int SendPacketGeneric(int inst, u32 type, u8* packet, int len, u64 timestamp) { if (!MPQueue) return 0; - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; + MPQueueLock.lock(); - u16 mask = header->ConnectedBitmask; + u16 mask = MPStatus.ConnectedBitmask; // TODO: check if the FIFO is full! MPPacketHeader pktheader; pktheader.Magic = 0x4946494E; - pktheader.SenderID = InstanceID; + pktheader.SenderID = inst; pktheader.Type = type; pktheader.Length = len; pktheader.Timestamp = timestamp; type &= 0xFFFF; int nfifo = (type == 2) ? 1 : 0; - FIFOWrite(nfifo, &pktheader, sizeof(pktheader)); + FIFOWrite(inst, nfifo, &pktheader, sizeof(pktheader)); if (len) - FIFOWrite(nfifo, packet, len); + FIFOWrite(inst, nfifo, packet, len); if (type == 1) { // NOTE: this is not guarded against, say, multiple multiplay games happening on the same machine // we would need to pass the packet's SenderID through the wifi module for that - header->MPHostInstanceID = InstanceID; - header->MPReplyBitmask = 0; - ReplyReadOffset = header->ReplyWriteOffset; - SemReset(16 + InstanceID); + MPStatus.MPHostinst = inst; + MPStatus.MPReplyBitmask = 0; + ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset; + SemReset(16 + inst); } else if (type == 2) { - header->MPReplyBitmask |= (1 << InstanceID); + MPStatus.MPReplyBitmask |= (1 << inst); } - MPQueue->unlock(); + MPQueueLock.unlock(); if (type == 2) { - SemPost(16 + header->MPHostInstanceID); + SemPost(16 + MPStatus.MPHostinst); } else { @@ -479,84 +299,82 @@ int SendPacketGeneric(u32 type, u8* packet, int len, u64 timestamp) return len; } -int RecvPacketGeneric(u8* packet, bool block, u64* timestamp) +int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp) { if (!MPQueue) return 0; for (;;) { - if (!SemWait(InstanceID, block ? RecvTimeout : 0)) + if (!SemWait(inst, block ? RecvTimeout : 0)) { return 0; } - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; + MPQueueLock.lock(); MPPacketHeader pktheader; - FIFORead(0, &pktheader, sizeof(pktheader)); + FIFORead(inst, 0, &pktheader, sizeof(pktheader)); if (pktheader.Magic != 0x4946494E) { Log(LogLevel::Warn, "PACKET FIFO OVERFLOW\n"); - PacketReadOffset = header->PacketWriteOffset; - SemReset(InstanceID); - MPQueue->unlock(); + PacketReadOffset[inst] = MPStatus.PacketWriteOffset; + SemReset(inst); + MPQueueLock.unlock(); return 0; } - if (pktheader.SenderID == InstanceID) + if (pktheader.SenderID == inst) { // skip this packet - PacketReadOffset += pktheader.Length; - if (PacketReadOffset >= kPacketEnd) - PacketReadOffset += kPacketStart - kPacketEnd; + PacketReadOffset[inst] += pktheader.Length; + if (PacketReadOffset[inst] >= kPacketEnd) + PacketReadOffset[inst] += kPacketStart - kPacketEnd; - MPQueue->unlock(); + MPQueueLock.unlock(); continue; } if (pktheader.Length) { - FIFORead(0, packet, pktheader.Length); + FIFORead(inst, 0, packet, pktheader.Length); if (pktheader.Type == 1) LastHostID = pktheader.SenderID; } if (timestamp) *timestamp = pktheader.Timestamp; - MPQueue->unlock(); + MPQueueLock.unlock(); return pktheader.Length; } } -int SendPacket(u8* packet, int len, u64 timestamp) +int SendPacket(int inst, u8* packet, int len, u64 timestamp) { - return SendPacketGeneric(0, packet, len, timestamp); + return SendPacketGeneric(inst, 0, packet, len, timestamp); } -int RecvPacket(u8* packet, u64* timestamp) +int RecvPacket(int inst, u8* packet, u64* timestamp) { - return RecvPacketGeneric(packet, false, timestamp); + return RecvPacketGeneric(inst, packet, false, timestamp); } -int SendCmd(u8* packet, int len, u64 timestamp) +int SendCmd(int inst, u8* packet, int len, u64 timestamp) { - return SendPacketGeneric(1, packet, len, timestamp); + return SendPacketGeneric(inst, 1, packet, len, timestamp); } -int SendReply(u8* packet, int len, u64 timestamp, u16 aid) +int SendReply(int inst, u8* packet, int len, u64 timestamp, u16 aid) { - return SendPacketGeneric(2 | (aid<<16), packet, len, timestamp); + return SendPacketGeneric(inst, 2 | (aid<<16), packet, len, timestamp); } -int SendAck(u8* packet, int len, u64 timestamp) +int SendAck(int inst, u8* packet, int len, u64 timestamp) { - return SendPacketGeneric(3, packet, len, timestamp); + return SendPacketGeneric(inst, 3, packet, len, timestamp); } -int RecvHostPacket(u8* packet, u64* timestamp) +int RecvHostPacket(int inst, u8* packet, u64* timestamp) { if (!MPQueue) return -1; @@ -564,33 +382,30 @@ int RecvHostPacket(u8* packet, u64* timestamp) { // check if the host is still connected - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - u16 curinstmask = header->ConnectedBitmask; - MPQueue->unlock(); + MPQueueLock.lock(); + u8* data = MPQueue; + u16 curinstmask = MPStatus.ConnectedBitmask; + MPQueueLock.unlock(); if (!(curinstmask & (1 << LastHostID))) return -1; } - return RecvPacketGeneric(packet, true, timestamp); + return RecvPacketGeneric(inst, packet, true, timestamp); } -u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask) +u16 RecvReplies(int inst, u8* packets, u64 timestamp, u16 aidmask) { if (!MPQueue) return 0; u16 ret = 0; - u16 myinstmask = (1 << InstanceID); + u16 myinstmask = (1 << inst); u16 curinstmask; { - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - curinstmask = header->ConnectedBitmask; - MPQueue->unlock(); + //MPQueueLock.lock(); + curinstmask = MPStatus.ConnectedBitmask; + //MPQueueLock.unlock(); } // if all clients have left: return early @@ -599,44 +414,42 @@ u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask) for (;;) { - if (!SemWait(16+InstanceID, RecvTimeout)) + if (!SemWait(16+inst, RecvTimeout)) { // no more replies available return ret; } - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; + MPQueueLock.lock(); MPPacketHeader pktheader; - FIFORead(1, &pktheader, sizeof(pktheader)); + FIFORead(inst, 1, &pktheader, sizeof(pktheader)); if (pktheader.Magic != 0x4946494E) { Log(LogLevel::Warn, "REPLY FIFO OVERFLOW\n"); - ReplyReadOffset = header->ReplyWriteOffset; - SemReset(16+InstanceID); - MPQueue->unlock(); + ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset; + SemReset(16+inst); + MPQueueLock.unlock(); return 0; } - if ((pktheader.SenderID == InstanceID) || // packet we sent out (shouldn't happen, but hey) + if ((pktheader.SenderID == inst) || // packet we sent out (shouldn't happen, but hey) (pktheader.Timestamp < (timestamp - 32))) // stale packet { // skip this packet - ReplyReadOffset += pktheader.Length; - if (ReplyReadOffset >= kReplyEnd) - ReplyReadOffset += kReplyStart - kReplyEnd; + ReplyReadOffset[inst] += pktheader.Length; + if (ReplyReadOffset[inst] >= kReplyEnd) + ReplyReadOffset[inst] += kReplyStart - kReplyEnd; - MPQueue->unlock(); + MPQueueLock.unlock(); continue; } if (pktheader.Length) { u32 aid = (pktheader.Type >> 16); - FIFORead(1, &packets[(aid-1)*1024], pktheader.Length); + FIFORead(inst, 1, &packets[(aid-1)*1024], pktheader.Length); ret |= (1 << aid); } @@ -646,11 +459,11 @@ u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask) { // all the clients have sent their reply - MPQueue->unlock(); + MPQueueLock.unlock(); return ret; } - MPQueue->unlock(); + MPQueueLock.unlock(); } } diff --git a/src/frontend/qt_sdl/LocalMP.h b/src/frontend/qt_sdl/LocalMP.h index e7b4188a..dcf69807 100644 --- a/src/frontend/qt_sdl/LocalMP.h +++ b/src/frontend/qt_sdl/LocalMP.h @@ -30,16 +30,16 @@ void DeInit(); void SetRecvTimeout(int timeout); -void Begin(); -void End(); +void Begin(int inst); +void End(int inst); -int SendPacket(u8* data, int len, u64 timestamp); -int RecvPacket(u8* data, u64* timestamp); -int SendCmd(u8* data, int len, u64 timestamp); -int SendReply(u8* data, int len, u64 timestamp, u16 aid); -int SendAck(u8* data, int len, u64 timestamp); -int RecvHostPacket(u8* data, u64* timestamp); -u16 RecvReplies(u8* data, u64 timestamp, u16 aidmask); +int SendPacket(int inst, u8* data, int len, u64 timestamp); +int RecvPacket(int inst, u8* data, u64* timestamp); +int SendCmd(int inst, u8* data, int len, u64 timestamp); +int SendReply(int inst, u8* data, int len, u64 timestamp, u16 aid); +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); } diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index f1af2935..c80bdbcc 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -50,12 +50,6 @@ extern CameraManager* camManager[2]; -void emuStop(); - -// TEMP -//#include "main.h" -//extern MainWindow* mainWindow; - namespace melonDS::Platform { @@ -454,65 +448,65 @@ void WriteDateTime(int year, int month, int day, int hour, int minute, int secon bool MP_Init(void* userdata) { - //return LocalMP::Init(); return true; } void MP_DeInit(void* userdata) { - //return LocalMP::DeInit(); } void MP_Begin(void* userdata) { - //return LocalMP::Begin(); + int inst = ((EmuInstance*)userdata)->getInstanceID(); + LocalMP::Begin(inst); } void MP_End(void* userdata) { - //return LocalMP::End(); + int inst = ((EmuInstance*)userdata)->getInstanceID(); + LocalMP::End(inst); } int MP_SendPacket(u8* data, int len, u64 timestamp, void* userdata) { - //return LocalMP::SendPacket(data, len, timestamp); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::SendPacket(inst, data, len, timestamp); } int MP_RecvPacket(u8* data, u64* timestamp, void* userdata) { - //return LocalMP::RecvPacket(data, timestamp); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::RecvPacket(inst, data, timestamp); } int MP_SendCmd(u8* data, int len, u64 timestamp, void* userdata) { - //return LocalMP::SendCmd(data, len, timestamp); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::SendCmd(inst, data, len, timestamp); } int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid, void* userdata) { - //return LocalMP::SendReply(data, len, timestamp, aid); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::SendReply(inst, data, len, timestamp, aid); } int MP_SendAck(u8* data, int len, u64 timestamp, void* userdata) { - //return LocalMP::SendAck(data, len, timestamp); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::SendAck(inst, data, len, timestamp); } int MP_RecvHostPacket(u8* data, u64* timestamp, void* userdata) { - //return LocalMP::RecvHostPacket(data, timestamp); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::RecvHostPacket(inst, data, timestamp); } u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask, void* userdata) { - //return LocalMP::RecvReplies(data, timestamp, aidmask); - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return LocalMP::RecvReplies(inst, data, timestamp, aidmask); } bool LAN_Init(void* userdata) diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8dd5cb43..658baa81 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -74,6 +74,7 @@ #include "EmuInstance.h" #include "ArchiveUtil.h" #include "CameraManager.h" +#include "LocalMP.h" #include "CLI.h" @@ -266,6 +267,8 @@ int main(int argc, char** argv) } } + LocalMP::Init(); + /* mainWindow = new MainWindow(); if (options->fullscreen) ToggleFullscreen(mainWindow); @@ -318,6 +321,8 @@ int main(int argc, char** argv) // but with this we make extra sure they are all deleted deleteAllEmuInstances(); + LocalMP::DeInit(); + //AudioInOut::DeInit(); delete camManager[0]; delete camManager[1];