From 4905673d054aa42db9c9904877d50449a8c7b414 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 11 Mar 2023 21:24:52 +0100 Subject: [PATCH] Arisotura pls clean up after yourself --- src/Platform.h | 2 - src/Wifi.cpp | 6 - src/frontend/qt_sdl/CMakeLists.txt | 1 - src/frontend/qt_sdl/LocalMP.cpp | 628 ----------------------------- src/frontend/qt_sdl/LocalMP.h | 45 --- src/frontend/qt_sdl/Platform.cpp | 21 - src/frontend/qt_sdl/main.cpp | 2 - 7 files changed, 705 deletions(-) delete mode 100644 src/frontend/qt_sdl/LocalMP.cpp delete mode 100644 src/frontend/qt_sdl/LocalMP.h diff --git a/src/Platform.h b/src/Platform.h index 91da4c1e..d816ab1f 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -336,8 +336,6 @@ void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen // local multiplayer comm interface // packet type: DS-style TX header (12 bytes) + original 802.11 frame -bool MP_Init(); -void MP_DeInit(); void MP_Begin(); void MP_End(); int MP_SendPacket(u8* data, int len, u64 timestamp); diff --git a/src/Wifi.cpp b/src/Wifi.cpp index fa05a651..e597bee6 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -150,12 +150,8 @@ u64 RXTimestamp; bool Init() { - //MPInited = false; //LANInited = false; - Platform::MP_Init(); - MPInited = true; - Platform::LAN_Init(); LANInited = true; @@ -166,8 +162,6 @@ bool Init() void DeInit() { - if (MPInited) - Platform::MP_DeInit(); if (LANInited) Platform::LAN_DeInit(); diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index c3e86dcb..9fd99e47 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -28,7 +28,6 @@ set(SOURCES_QT_SDL IPC.cpp LAN_PCap.cpp LAN_Socket.cpp - LocalMP.cpp OSD.cpp OSD_shaders.h font.h diff --git a/src/frontend/qt_sdl/LocalMP.cpp b/src/frontend/qt_sdl/LocalMP.cpp deleted file mode 100644 index 291cb11a..00000000 --- a/src/frontend/qt_sdl/LocalMP.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/* - Copyright 2016-2022 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 -#include -#include - -#ifdef __WIN32__ - #include -#else - #include - #include - #include - #ifdef __APPLE__ - #include "sem_timedwait.h" - #endif -#endif - -#include -#include - -#include "Config.h" -#include "LocalMP.h" -#include "Platform.h" - -using Platform::Log; -using Platform::LogLevel; - -namespace LocalMP -{ - -u32 MPUniqueID; -u8 PacketBuffer[2048]; - -struct MPQueueHeader -{ - 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 MPReplyBitmask; // bitmask of which clients replied in time -}; - -struct MPPacketHeader -{ - u32 Magic; - u32 SenderID; - u32 Type; // 0=regular 1=CMD 2=reply 3=ack - u32 Length; - u64 Timestamp; -}; - -QSharedMemory* MPQueue; -int InstanceID; -u32 PacketReadOffset; -u32 ReplyReadOffset; - -const u32 kQueueSize = 0x20000; -const u32 kMaxFrameSize = 0x800; -const u32 kPacketStart = sizeof(MPQueueHeader); -const u32 kReplyStart = kQueueSize / 2; -const u32 kPacketEnd = kReplyStart; -const u32 kReplyEnd = kQueueSize; - -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]; - -void SemPoolInit() -{ - for (int i = 0; i < 32; i++) - { - SemPool[i] = INVALID_HANDLE_VALUE; - 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, "Local\\melonNIFI_Sem%02d", num); - - HANDLE sem = CreateSemaphore(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; -} - -bool SemWait(int num, int timeout) -{ - if (!timeout) - return sem_trywait(SemPool[num]) == 0; - - 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; -} - -void SemReset(int num) -{ - while (sem_trywait(SemPool[num]) == 0); -} - -#endif - - -bool Init() -{ - MPQueue = new QSharedMemory("melonNIFI"); - - if (!MPQueue->attach()) - { - Log(LogLevel::Info, "MP sharedmem doesn't exist. creating\n"); - if (!MPQueue->create(kQueueSize)) - { - Log(LogLevel::Error, "MP sharedmem create failed :(\n"); - return false; - } - - 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(); - - // 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); - - RecvTimeout = 25; - - return true; -} - -void DeInit() -{ - MPQueue->lock(); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - header->ConnectedBitmask &= ~(1 << InstanceID); - header->InstanceBitmask &= ~(1 << InstanceID); - header->NumInstances--; - MPQueue->unlock(); - - SemPoolDeinit(); - - MPQueue->detach(); - delete MPQueue; -} - -void SetRecvTimeout(int timeout) -{ - RecvTimeout = timeout; -} - -void Begin() -{ - MPQueue->lock(); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - PacketReadOffset = header->PacketWriteOffset; - ReplyReadOffset = header->ReplyWriteOffset; - SemReset(InstanceID); - SemReset(16+InstanceID); - header->ConnectedBitmask |= (1 << InstanceID); - MPQueue->unlock(); -} - -void End() -{ - MPQueue->lock(); - MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); - //SemReset(InstanceID); - //SemReset(16+InstanceID); - header->ConnectedBitmask &= ~(1 << InstanceID); - MPQueue->unlock(); -} - -void FIFORead(int fifo, void* buf, int len) -{ - u8* data = (u8*)MPQueue->data(); - - u32 offset, start, end; - if (fifo == 0) - { - offset = PacketReadOffset; - start = kPacketStart; - end = kPacketEnd; - } - else - { - offset = ReplyReadOffset; - start = kReplyStart; - end = kReplyEnd; - } - - if ((offset + len) >= end) - { - u32 part1 = end - offset; - memcpy(buf, &data[offset], part1); - memcpy(&((u8*)buf)[part1], &data[start], len - part1); - offset = start + len - part1; - } - else - { - memcpy(buf, &data[offset], len); - offset += len; - } - - if (fifo == 0) PacketReadOffset = offset; - else ReplyReadOffset = offset; -} - -void FIFOWrite(int fifo, void* buf, int len) -{ - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - - u32 offset, start, end; - if (fifo == 0) - { - offset = header->PacketWriteOffset; - start = kPacketStart; - end = kPacketEnd; - } - else - { - offset = header->ReplyWriteOffset; - start = kReplyStart; - end = kReplyEnd; - } - - if ((offset + len) >= end) - { - u32 part1 = end - offset; - memcpy(&data[offset], buf, part1); - memcpy(&data[start], &((u8*)buf)[part1], len - part1); - offset = start + len - part1; - } - else - { - memcpy(&data[offset], buf, len); - offset += len; - } - - if (fifo == 0) header->PacketWriteOffset = offset; - else header->ReplyWriteOffset = offset; -} - -int SendPacketGeneric(u32 type, u8* packet, int len, u64 timestamp) -{ - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - - u16 mask = header->ConnectedBitmask; - - // TODO: check if the FIFO is full! - - MPPacketHeader pktheader; - pktheader.Magic = 0x4946494E; - pktheader.SenderID = InstanceID; - pktheader.Type = type; - pktheader.Length = len; - pktheader.Timestamp = timestamp; - - type &= 0xFFFF; - int nfifo = (type == 2) ? 1 : 0; - FIFOWrite(nfifo, &pktheader, sizeof(pktheader)); - if (len) - FIFOWrite(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); - } - else if (type == 2) - { - header->MPReplyBitmask |= (1 << InstanceID); - } - - MPQueue->unlock(); - - if (type == 2) - { - SemPost(16 + header->MPHostInstanceID); - } - else - { - for (int i = 0; i < 16; i++) - { - if (mask & (1<lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - - MPPacketHeader pktheader; - FIFORead(0, &pktheader, sizeof(pktheader)); - - if (pktheader.Magic != 0x4946494E) - { - Log(LogLevel::Warn, "PACKET FIFO OVERFLOW\n"); - PacketReadOffset = header->PacketWriteOffset; - SemReset(InstanceID); - MPQueue->unlock(); - return 0; - } - - if (pktheader.SenderID == InstanceID) - { - // skip this packet - PacketReadOffset += pktheader.Length; - if (PacketReadOffset >= kPacketEnd) - PacketReadOffset += kPacketStart - kPacketEnd; - - MPQueue->unlock(); - continue; - } - - if (pktheader.Length) - { - FIFORead(0, packet, pktheader.Length); - - if (pktheader.Type == 1) - LastHostID = pktheader.SenderID; - } - - if (timestamp) *timestamp = pktheader.Timestamp; - MPQueue->unlock(); - return pktheader.Length; - } -} - -int SendPacket(u8* packet, int len, u64 timestamp) -{ - return SendPacketGeneric(0, packet, len, timestamp); -} - -int RecvPacket(u8* packet, u64* timestamp) -{ - return RecvPacketGeneric(packet, false, timestamp); -} - - -int SendCmd(u8* packet, int len, u64 timestamp) -{ - return SendPacketGeneric(1, packet, len, timestamp); -} - -int SendReply(u8* packet, int len, u64 timestamp, u16 aid) -{ - return SendPacketGeneric(2 | (aid<<16), packet, len, timestamp); -} - -int SendAck(u8* packet, int len, u64 timestamp) -{ - return SendPacketGeneric(3, packet, len, timestamp); -} - -int RecvHostPacket(u8* packet, u64* timestamp) -{ - if (LastHostID != -1) - { - // 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(); - - if (!(curinstmask & (1 << LastHostID))) - return -1; - } - - return RecvPacketGeneric(packet, true, timestamp); -} - -u16 RecvReplies(u8* packets, u64 timestamp, u16 aidmask) -{ - u16 ret = 0; - u16 myinstmask = (1 << InstanceID); - u16 curinstmask; - - { - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - curinstmask = header->ConnectedBitmask; - MPQueue->unlock(); - } - - // if all clients have left: return early - if ((myinstmask & curinstmask) == curinstmask) - return 0; - - for (;;) - { - if (!SemWait(16+InstanceID, RecvTimeout)) - { - // no more replies available - return ret; - } - - MPQueue->lock(); - u8* data = (u8*)MPQueue->data(); - MPQueueHeader* header = (MPQueueHeader*)&data[0]; - - MPPacketHeader pktheader; - FIFORead(1, &pktheader, sizeof(pktheader)); - - if (pktheader.Magic != 0x4946494E) - { - Log(LogLevel::Warn, "REPLY FIFO OVERFLOW\n"); - ReplyReadOffset = header->ReplyWriteOffset; - SemReset(16+InstanceID); - MPQueue->unlock(); - return 0; - } - - if ((pktheader.SenderID == InstanceID) || // 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; - - MPQueue->unlock(); - continue; - } - - if (pktheader.Length) - { - u32 aid = (pktheader.Type >> 16); - FIFORead(1, &packets[(aid-1)*1024], pktheader.Length); - ret |= (1 << aid); - } - - myinstmask |= (1 << pktheader.SenderID); - if (((myinstmask & curinstmask) == curinstmask) || - ((ret & aidmask) == aidmask)) - { - // all the clients have sent their reply - - MPQueue->unlock(); - return ret; - } - - MPQueue->unlock(); - } -} - -} - diff --git a/src/frontend/qt_sdl/LocalMP.h b/src/frontend/qt_sdl/LocalMP.h deleted file mode 100644 index 51dfcb93..00000000 --- a/src/frontend/qt_sdl/LocalMP.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2016-2022 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/. -*/ - -#ifndef LOCALMP_H -#define LOCALMP_H - -#include "types.h" - -namespace LocalMP -{ - -bool Init(); -void DeInit(); - -void SetRecvTimeout(int timeout); - -void Begin(); -void End(); - -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); - -} - -#endif // LOCALMP_H diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index d6993482..04df5438 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -37,7 +37,6 @@ #include "CameraManager.h" #include "LAN_Socket.h" #include "LAN_PCap.h" -#include "LocalMP.h" #include "IPC.h" #include "OSD.h" @@ -530,68 +529,48 @@ void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen -bool MP_Init() -{ - //return LocalMP::Init(); - return true; -} - -void MP_DeInit() -{ - //return LocalMP::DeInit(); -} - void MP_Begin() { - //return LocalMP::Begin(); return IPC::MPBegin(); } void MP_End() { - //return LocalMP::End(); return IPC::MPEnd(); } int MP_SendPacket(u8* data, int len, u64 timestamp) { - //return LocalMP::SendPacket(data, len, timestamp); return IPC::SendMPPacket(data, len, timestamp); } int MP_RecvPacket(u8* data, u64* timestamp) { - //return LocalMP::RecvPacket(data, timestamp); return IPC::RecvMPPacket(data, timestamp); } int MP_SendCmd(u8* data, int len, u64 timestamp) { - //return LocalMP::SendCmd(data, len, timestamp); return IPC::SendMPCmd(data, len, timestamp); } int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid) { - //return LocalMP::SendReply(data, len, timestamp, aid); return IPC::SendMPReply(data, len, timestamp, aid); } int MP_SendAck(u8* data, int len, u64 timestamp) { - //return LocalMP::SendAck(data, len, timestamp); return IPC::SendMPAck(data, len, timestamp); } int MP_RecvHostPacket(u8* data, u64* timestamp) { - //return LocalMP::RecvHostPacket(data, timestamp); return IPC::RecvMPHostPacket(data, timestamp); } u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask) { - //return LocalMP::RecvReplies(data, timestamp, aidmask); return IPC::RecvMPReplies(data, timestamp, aidmask); } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 1295def0..82961132 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -88,7 +88,6 @@ #include "Wifi.h" #include "Platform.h" #include "IPC.h" -#include "LocalMP.h" #include "Config.h" #include "DSi_I2C.h" @@ -2969,7 +2968,6 @@ void MainWindow::onOpenMPSettings() void MainWindow::onMPSettingsFinished(int res) { AudioInOut::AudioMute(mainWindow); - //LocalMP::SetRecvTimeout(Config::MPRecvTimeout); IPC::SetMPRecvTimeout(Config::MPRecvTimeout); emuThread->emuUnpause();