From 827c1e643643babc8f8a4638f10d51a101189850 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 18 Aug 2022 23:28:52 +0200 Subject: [PATCH] move local-MP comm to its own module instead of cramping Platform.cpp --- src/ARM.cpp | 16 +- src/NDS.cpp | 9 - src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/LocalMP.cpp | 473 +++++++++++++++++++++++++++++ src/frontend/qt_sdl/LocalMP.h | 37 +++ src/frontend/qt_sdl/Platform.cpp | 388 +---------------------- 6 files changed, 527 insertions(+), 397 deletions(-) create mode 100644 src/frontend/qt_sdl/LocalMP.cpp create mode 100644 src/frontend/qt_sdl/LocalMP.h diff --git a/src/ARM.cpp b/src/ARM.cpp index 66fe5130..e19cb002 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -42,6 +42,8 @@ // // MUL/MLA seems to take 1I on ARM9 + + u32 ARM::ConditionTable[16] = { 0xF0F0, // EQ @@ -768,20 +770,6 @@ void ARMv4::Execute() AddCycles_C(); } - //if (R[15]==0x02300ECE) printf("PISSBOURF: %08X\n", R[0]); - // R7=3807D20 - /*if (R[15]==0x02301172 && (R[0]&0x2800)==0x2800) - { - printf("SENSE. %08X\n", R[7]); - for (int i = 0; i < 16; i++) printf("%02X ", NDS::ARM7Read8(R[7]+i)); - for (int i = 0; i < 16; i++) printf("%02X ", NDS::ARM7Read8(R[7]+0x10+i)); - for (int i = 0; i < 16; i++) printf("%02X ", NDS::ARM7Read8(R[7]+0x20+i)); - for (int i = 0; i < 16; i++) printf("%02X ", NDS::ARM7Read8(R[7]+0x30+i)); - printf("\n"); - }*/ - // printf("FENETRE. %04X, %08X\n", R[0], R[7]); - //if (R[15]==0x0230CEFE) printf("SET SHITTY PACKET FLAGS %04X (%04X/%04X)\n", R[3], NDS::ARM7Read16(0x04808094), NDS::ARM7Read16(0x04808098)); - // TODO optimize this shit!!! if (Halted) { diff --git a/src/NDS.cpp b/src/NDS.cpp index 9cfcad60..7c77ca4c 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -2425,15 +2425,6 @@ u8 ARM7Read8(u32 addr) u16 ARM7Read16(u32 addr) { - /*if (addr == (0x03807D38+0x28)) - { - if (ARM7Read16(0x03807D38+0xC)==0x228) - printf("!!!! READING PISSY HEADER %08X\n", NDS::GetPC(1)); - }*/ - /*if ((!(addr&0x10000000)) && (addr<0x04000000)) - if (ARM7Read16(0x10000000|(addr-0x1C))==0x228) - printf("!!!! READING PISSY HEADER %08X\n", NDS::GetPC(1)); - if(addr&0x10000000) addr&=0x0FFFFFFF;*/ if (addr < 0x00004000) { if (ARM7->R[15] >= 0x00004000) diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 3089c32f..d317e139 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -25,6 +25,7 @@ set(SOURCES_QT_SDL Input.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 new file mode 100644 index 00000000..0a439bbb --- /dev/null +++ b/src/frontend/qt_sdl/LocalMP.cpp @@ -0,0 +1,473 @@ +/* + 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__ + #define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK + #include + #include + //#include // FUCK THAT SHIT + #include + #include + #include + #define dup _dup + #define socket_t SOCKET + #define sockaddr_t SOCKADDR +#else + #include + #include + #include + #include + + #define socket_t int + #define sockaddr_t struct sockaddr + #define closesocket close +#endif + +#include +#include +#include + +#include "Config.h" +#include "LocalMP.h" +#include "SPI.h" + + +#ifndef INVALID_SOCKET + #define INVALID_SOCKET (socket_t)-1 +#endif + +extern u16 zanf; + +namespace LocalMP +{ + +u32 MPUniqueID; +socket_t MPSocket[2]; +sockaddr_t MPSendAddr[2]; +u8 PacketBuffer[2048]; + +struct MPQueueHeader +{ + u16 NumInstances; + u16 InstanceBitmask; + u32 SyncWriteOffset; + u32 PacketWriteOffset; +}; + +QSharedMemory* MPQueue; +QSystemSemaphore* MPQueueSem[16]; +u32 SyncReadOffset; +u32 PacketReadOffset; + +#define NIFI_VER 2 + + + +void _logpacket(bool tx, u8* data, int len) +{return; + char path[256]; + sprintf(path, "framelog_%08X.log", MPUniqueID); + static FILE* f = nullptr; + if (!f) f = fopen(path, "a"); + + /*fprintf(f, "---- %s PACKET LEN=%d ----\n", tx?"SENDING":"RECEIVING", len); + + for (int y = 0; y < len; y+=16) + { + fprintf(f, "%04X: ", y); + int linelen = 16; + if ((y+linelen) > len) linelen = len-y; + for (int x = 0; x < linelen; x++) + { + fprintf(f, " %02X", data[y+x]); + } + fprintf(f, "\n"); + } + + fprintf(f, "-------------------------------------\n\n\n");*/ + + fprintf(f, "%s PACKET: LEN=%0.4d FC=%04X SN=%04X CL=%04X/%04X\n", tx?"TX":"RX", + len, *(u16*)&data[12], *(u16*)&data[12+22], *(u16*)&data[12+24], *(u16*)&data[12+26]); + fflush(f); +} + +bool Init() +{ + int opt_true = 1; + int res0, res1; + +#ifdef __WIN32__ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) + { + return false; + } +#endif // __WIN32__ + + MPSocket[0] = socket(AF_INET, SOCK_DGRAM, 0); + if (MPSocket[0] < 0) + { + return false; + } + + MPSocket[1] = socket(AF_INET, SOCK_DGRAM, 0); + if (MPSocket[1] < 0) + { + closesocket(MPSocket[0]); + MPSocket[0] = INVALID_SOCKET; + return false; + } + + res0 = setsockopt(MPSocket[0], SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); + res1 = setsockopt(MPSocket[1], SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); + if (res0 < 0 || res1 < 0) + { + closesocket(MPSocket[0]); + MPSocket[0] = INVALID_SOCKET; + closesocket(MPSocket[1]); + MPSocket[1] = INVALID_SOCKET; + return false; + } + +#if defined(BSD) || defined(__APPLE__) + res0 = setsockopt(MPSocket[0], SOL_SOCKET, SO_REUSEPORT, (const char*)&opt_true, sizeof(int)); + res0 = setsockopt(MPSocket[1], SOL_SOCKET, SO_REUSEPORT, (const char*)&opt_true, sizeof(int)); + if (res0 < 0 || res1 < 0) + { + closesocket(MPSocket[0]); + MPSocket[0] = INVALID_SOCKET; + closesocket(MPSocket[1]); + MPSocket[1] = INVALID_SOCKET; + return false; + } +#endif + + sockaddr_t saddr; + saddr.sa_family = AF_INET; + *(u32*)&saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); + *(u16*)&saddr.sa_data[0] = htons(7064); + res0 = bind(MPSocket[0], &saddr, sizeof(sockaddr_t)); + *(u16*)&saddr.sa_data[0] = htons(7065); + res1 = bind(MPSocket[1], &saddr, sizeof(sockaddr_t)); + if (res0 < 0 || res1 < 0) + { + closesocket(MPSocket[0]); + MPSocket[0] = INVALID_SOCKET; + closesocket(MPSocket[1]); + MPSocket[1] = INVALID_SOCKET; + return false; + } + + res0 = setsockopt(MPSocket[0], SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); + res1 = setsockopt(MPSocket[1], SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); + if (res0 < 0 || res1 < 0) + { + closesocket(MPSocket[0]); + MPSocket[0] = INVALID_SOCKET; + closesocket(MPSocket[1]); + MPSocket[1] = INVALID_SOCKET; + return false; + } + + MPSendAddr[0].sa_family = AF_INET; + *(u32*)&MPSendAddr[0].sa_data[2] = htonl(INADDR_BROADCAST); + *(u16*)&MPSendAddr[0].sa_data[0] = htons(7064); + + MPSendAddr[1].sa_family = AF_INET; + *(u32*)&MPSendAddr[1].sa_data[2] = htonl(INADDR_BROADCAST); + *(u16*)&MPSendAddr[1].sa_data[0] = htons(7065); + + u8* mac = SPI_Firmware::GetWifiMAC(); + MPUniqueID = *(u32*)&mac[0]; + MPUniqueID ^= *(u32*)&mac[2]; + printf("local MP unique ID: %08X\n", MPUniqueID); + + return true; + + /*MPQueue = new QSharedMemory("melonNIFI"); + + if (!MPQueue->attach()) + { + printf("sharedmem doesn't exist. creating\n"); + if (!MPQueue->create(65536)) + { + printf("sharedmem create failed :(\n"); + return false; + } + + MPQueue->lock(); + memset(MPQueue->data(), 0, MPQueue->size()); + MPQueueHeader* header = (MPQueueHeader*)MPQueue->data(); + header->NumInstances = 1; + header->InstanceBitmask = 0x0001; + header->SyncWriteOffset = 0x0010; + header->PacketWriteOffset = 0x0100; + MPQueue->unlock(); + } + printf("sharedmem good\n");*/ + + + + return true; +} + +void DeInit() +{ + if (MPSocket[0] >= 0) + closesocket(MPSocket[0]); + if (MPSocket[1] >= 0) + closesocket(MPSocket[1]); + +#ifdef __WIN32__ + WSACleanup(); +#endif // __WIN32__ +} + +int SendPacket(u8* data, int len) +{ + if (MPSocket[0] < 0) + return 0; + + if (len > 2048-12) + { + printf("MP_SendPacket: error: packet too long (%d)\n", len); + return 0; + } + + *(u32*)&PacketBuffer[0] = htonl(0x4946494E); // NIFI + PacketBuffer[4] = NIFI_VER; + PacketBuffer[5] = 0; + *(u16*)&PacketBuffer[6] = htons(len); + *(u32*)&PacketBuffer[8] = MPUniqueID; + memcpy(&PacketBuffer[12], data, len); + + _logpacket(true, data, len); + + int slen = sendto(MPSocket[0], (const char*)PacketBuffer, len+12, 0, &MPSendAddr[0], sizeof(sockaddr_t)); + if (slen < 12) return 0; + return slen - 12; +} + +int RecvPacket(u8* data, bool block) +{ + if (MPSocket[0] < 0) + return 0; + + fd_set fd; + struct timeval tv; + + for (;;) + { + FD_ZERO(&fd); + FD_SET(MPSocket[0], &fd); + tv.tv_sec = 0; + //tv.tv_usec = block ? 5000 : 0; + tv.tv_usec = block ? 500*1000 : 0; + + if (!select(MPSocket[0]+1, &fd, 0, 0, &tv)) + { + return 0; + } + + sockaddr_t fromAddr; + socklen_t fromLen = sizeof(sockaddr_t); + int rlen = recvfrom(MPSocket[0], (char*)PacketBuffer, 2048, 0, &fromAddr, &fromLen); + if (rlen < 12+24) + { + continue; + } + rlen -= 12; + + if (ntohl(*(u32*)&PacketBuffer[0]) != 0x4946494E) + { + continue; + } + + if (PacketBuffer[4] != NIFI_VER || PacketBuffer[5] != 0) + { + continue; + } + + if (ntohs(*(u16*)&PacketBuffer[6]) != rlen) + { + continue; + } + + if (*(u32*)&PacketBuffer[8] == MPUniqueID) + { + continue; + } + + zanf = *(u16*)&PacketBuffer[12+6]; + _logpacket(false, &PacketBuffer[12], rlen); + + memcpy(data, &PacketBuffer[12], rlen); + return rlen; + } +} + +bool SendSync(u16 clientmask, u16 type, u64 val) +{ + u8 syncbuf[32]; + + if (MPSocket[1] < 0) + return false; + + int len = 16; + *(u32*)&syncbuf[0] = htonl(0x4946494E); // NIFI + syncbuf[4] = NIFI_VER; + syncbuf[5] = 1; + *(u16*)&syncbuf[6] = htons(len); + *(u16*)&syncbuf[8] = htons(type); + *(u16*)&syncbuf[10] = htons(clientmask); + *(u32*)&syncbuf[12] = MPUniqueID; + *(u32*)&syncbuf[16] = htonl((u32)val); + *(u32*)&syncbuf[20] = htonl((u32)(val>>32)); + + int slen = sendto(MPSocket[1], (const char*)syncbuf, len+8, 0, &MPSendAddr[1], sizeof(sockaddr_t)); + return slen == len+8; +} + +bool WaitSync(u16 clientmask, u16* type, u64* val) +{ + u8 syncbuf[32]; + + if (MPSocket[1] < 0) + return false; + + fd_set fd; + struct timeval tv; + + for (;;) + { + FD_ZERO(&fd); + FD_SET(MPSocket[1], &fd); + tv.tv_sec = 0; + tv.tv_usec = 500*1000; + + if (!select(MPSocket[1]+1, &fd, 0, 0, &tv)) + {printf("sync fail\n"); + return false; + } + + sockaddr_t fromAddr; + socklen_t fromLen = sizeof(sockaddr_t); + int rlen = recvfrom(MPSocket[1], (char*)syncbuf, 32, 0, &fromAddr, &fromLen); + if (rlen != 8+16) + continue; + rlen -= 8; + + if (ntohl(*(u32*)&syncbuf[0]) != 0x4946494E) + continue; + + if (syncbuf[4] != NIFI_VER || syncbuf[5] != 1) + continue; + + if (ntohs(*(u16*)&syncbuf[6]) != rlen) + continue; + + if (*(u32*)&syncbuf[12] == MPUniqueID) + continue; + + u16 clientval = ntohs(*(u16*)&syncbuf[10]); + if (!(clientmask & clientval)) + continue; + + // check the sync val, it should be ahead of the current sync val + u64 syncval = ntohl(*(u32*)&syncbuf[16]) | (((u64)ntohl(*(u32*)&syncbuf[20])) << 32); + //if (syncval <= curval) + // continue; + + if (type) *type = ntohs(*(u16*)&syncbuf[8]); + if (val) *val = syncval; + + return true; + } +} + +u16 WaitMultipleSyncs(u16 type, u16 clientmask, u64 curval) +{ + u8 syncbuf[32]; + + if (!clientmask) + return 0; + + if (MPSocket[1] < 0) + return 0; + + fd_set fd; + struct timeval tv; + + for (;;) + { + FD_ZERO(&fd); + FD_SET(MPSocket[1], &fd); + tv.tv_sec = 0; + tv.tv_usec = 500*1000; + + if (!select(MPSocket[1]+1, &fd, 0, 0, &tv)) + {printf("[sync3] nope :(\n"); + return clientmask; + } + + sockaddr_t fromAddr; + socklen_t fromLen = sizeof(sockaddr_t); + int rlen = recvfrom(MPSocket[1], (char*)syncbuf, 32, 0, &fromAddr, &fromLen); + if (rlen != 8+16) + continue; + rlen -= 8; + + if (ntohl(*(u32*)&syncbuf[0]) != 0x4946494E) + continue; + + if (syncbuf[4] != NIFI_VER || syncbuf[5] != 1) + continue; +//printf("[sync3] atleast header is good\n"); + if (ntohs(*(u16*)&syncbuf[6]) != rlen) + continue; + + if (*(u32*)&syncbuf[12] == MPUniqueID) + continue; + + if (ntohs(*(u16*)&syncbuf[8]) != type) + continue; + + u16 clientval = ntohs(*(u16*)&syncbuf[10]); + //printf("[sync3] good rlen/type %04X %04X, clientmask=%04X \n", ntohs(*(u16*)&syncbuf[6]), ntohs(*(u16*)&syncbuf[8]), clientval); + if (!(clientmask & clientval)) + continue; + + // check the sync val, it should be ahead of the current sync val + u64 syncval = ntohl(*(u32*)&syncbuf[12]) | (((u64)ntohl(*(u32*)&syncbuf[16])) << 32); + //if (syncval <= curval) + // continue; +//printf("[sync3] good\n"); + clientmask &= ~clientval; + //if (!clientmask) + return 0; + } + + return clientmask; +} + +} + diff --git a/src/frontend/qt_sdl/LocalMP.h b/src/frontend/qt_sdl/LocalMP.h new file mode 100644 index 00000000..c0b7e814 --- /dev/null +++ b/src/frontend/qt_sdl/LocalMP.h @@ -0,0 +1,37 @@ +/* + 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(); +int SendPacket(u8* data, int len); +int RecvPacket(u8* data, bool block); +bool SendSync(u16 clientmask, u16 type, u64 val); +bool WaitSync(u16 clientmask, u16* type, u64* val); +u16 WaitMultipleSyncs(u16 type, u16 clientmask, u64 curval); + +} + +#endif // LOCALMP_H diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 4c3c714b..4397d7cf 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -20,28 +20,7 @@ #include #include -#ifdef __WIN32__ - #define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK - #include - #include - //#include // FUCK THAT SHIT - #include - #include - #include - #define dup _dup - #define socket_t SOCKET - #define sockaddr_t SOCKADDR -#else - #include - #include - #include - #include - - #define socket_t int - #define sockaddr_t struct sockaddr - #define closesocket close -#endif - +#include #include #include #include @@ -55,30 +34,16 @@ #include "ROMManager.h" #include "LAN_Socket.h" #include "LAN_PCap.h" -#include "SPI.h" -#include - -#ifndef INVALID_SOCKET - #define INVALID_SOCKET (socket_t)-1 -#endif +#include "LocalMP.h" std::string EmuDirectory; void emuStop(); -extern u16 zanf; namespace Platform { -u32 MPUniqueID; -socket_t MPSocket[2]; -sockaddr_t MPSendAddr[2]; -u8 PacketBuffer[2048]; - -#define NIFI_VER 2 - - void Init(int argc, char** argv) { #if defined(__WIN32__) || defined(PORTABLE) @@ -374,6 +339,11 @@ bool Mutex_TryLock(Mutex* mutex) return ((QMutex*) mutex)->try_lock(); } +void Sleep(u64 usecs) +{ + QThread::usleep(usecs); +} + void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen) { @@ -388,365 +358,40 @@ void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen } -void _logpacket(bool tx, u8* data, int len) -{return; - char path[256]; - sprintf(path, "framelog_%08X.log", MPUniqueID); - static FILE* f = nullptr; - if (!f) f = fopen(path, "a"); - - /*fprintf(f, "---- %s PACKET LEN=%d ----\n", tx?"SENDING":"RECEIVING", len); - - for (int y = 0; y < len; y+=16) - { - fprintf(f, "%04X: ", y); - int linelen = 16; - if ((y+linelen) > len) linelen = len-y; - for (int x = 0; x < linelen; x++) - { - fprintf(f, " %02X", data[y+x]); - } - fprintf(f, "\n"); - } - - fprintf(f, "-------------------------------------\n\n\n");*/ - - fprintf(f, "%s PACKET: LEN=%0.4d FC=%04X SN=%04X CL=%04X/%04X\n", tx?"TX":"RX", - len, *(u16*)&data[12], *(u16*)&data[12+22], *(u16*)&data[12+24], *(u16*)&data[12+26]); - fflush(f); -} bool MP_Init() { - int opt_true = 1; - int res0, res1; - -#ifdef __WIN32__ - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) - { - return false; - } -#endif // __WIN32__ - - MPSocket[0] = socket(AF_INET, SOCK_DGRAM, 0); - if (MPSocket[0] < 0) - { - return false; - } - - MPSocket[1] = socket(AF_INET, SOCK_DGRAM, 0); - if (MPSocket[1] < 0) - { - closesocket(MPSocket[0]); - MPSocket[0] = INVALID_SOCKET; - return false; - } - - res0 = setsockopt(MPSocket[0], SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); - res1 = setsockopt(MPSocket[1], SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); - if (res0 < 0 || res1 < 0) - { - closesocket(MPSocket[0]); - MPSocket[0] = INVALID_SOCKET; - closesocket(MPSocket[1]); - MPSocket[1] = INVALID_SOCKET; - return false; - } - -#if defined(BSD) || defined(__APPLE__) - res0 = setsockopt(MPSocket[0], SOL_SOCKET, SO_REUSEPORT, (const char*)&opt_true, sizeof(int)); - res0 = setsockopt(MPSocket[1], SOL_SOCKET, SO_REUSEPORT, (const char*)&opt_true, sizeof(int)); - if (res0 < 0 || res1 < 0) - { - closesocket(MPSocket[0]); - MPSocket[0] = INVALID_SOCKET; - closesocket(MPSocket[1]); - MPSocket[1] = INVALID_SOCKET; - return false; - } -#endif - - sockaddr_t saddr; - saddr.sa_family = AF_INET; - *(u32*)&saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); - *(u16*)&saddr.sa_data[0] = htons(7064); - res0 = bind(MPSocket[0], &saddr, sizeof(sockaddr_t)); - *(u16*)&saddr.sa_data[0] = htons(7065); - res1 = bind(MPSocket[1], &saddr, sizeof(sockaddr_t)); - if (res0 < 0 || res1 < 0) - { - closesocket(MPSocket[0]); - MPSocket[0] = INVALID_SOCKET; - closesocket(MPSocket[1]); - MPSocket[1] = INVALID_SOCKET; - return false; - } - - res0 = setsockopt(MPSocket[0], SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); - res1 = setsockopt(MPSocket[1], SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); - if (res0 < 0 || res1 < 0) - { - closesocket(MPSocket[0]); - MPSocket[0] = INVALID_SOCKET; - closesocket(MPSocket[1]); - MPSocket[1] = INVALID_SOCKET; - return false; - } - - MPSendAddr[0].sa_family = AF_INET; - *(u32*)&MPSendAddr[0].sa_data[2] = htonl(INADDR_BROADCAST); - *(u16*)&MPSendAddr[0].sa_data[0] = htons(7064); - - MPSendAddr[1].sa_family = AF_INET; - *(u32*)&MPSendAddr[1].sa_data[2] = htonl(INADDR_BROADCAST); - *(u16*)&MPSendAddr[1].sa_data[0] = htons(7065); - - u8* mac = SPI_Firmware::GetWifiMAC(); - MPUniqueID = *(u32*)&mac[0]; - MPUniqueID ^= *(u32*)&mac[2]; - printf("local MP unique ID: %08X\n", MPUniqueID); - - return true; + return LocalMP::Init(); } void MP_DeInit() { - if (MPSocket[0] >= 0) - closesocket(MPSocket[0]); - if (MPSocket[1] >= 0) - closesocket(MPSocket[1]); - -#ifdef __WIN32__ - WSACleanup(); -#endif // __WIN32__ + return LocalMP::DeInit(); } int MP_SendPacket(u8* data, int len) { - if (MPSocket[0] < 0) - return 0; - - if (len > 2048-12) - { - printf("MP_SendPacket: error: packet too long (%d)\n", len); - return 0; - } - - *(u32*)&PacketBuffer[0] = htonl(0x4946494E); // NIFI - PacketBuffer[4] = NIFI_VER; - PacketBuffer[5] = 0; - *(u16*)&PacketBuffer[6] = htons(len); - *(u32*)&PacketBuffer[8] = MPUniqueID; - memcpy(&PacketBuffer[12], data, len); - - _logpacket(true, data, len); - - int slen = sendto(MPSocket[0], (const char*)PacketBuffer, len+12, 0, &MPSendAddr[0], sizeof(sockaddr_t)); - if (slen < 12) return 0; - return slen - 12; + return LocalMP::SendPacket(data, len); } int MP_RecvPacket(u8* data, bool block) { - if (MPSocket[0] < 0) - return 0; - - fd_set fd; - struct timeval tv; - - for (;;) - { - FD_ZERO(&fd); - FD_SET(MPSocket[0], &fd); - tv.tv_sec = 0; - //tv.tv_usec = block ? 5000 : 0; - tv.tv_usec = block ? 500*1000 : 0; - - if (!select(MPSocket[0]+1, &fd, 0, 0, &tv)) - { - return 0; - } - - sockaddr_t fromAddr; - socklen_t fromLen = sizeof(sockaddr_t); - int rlen = recvfrom(MPSocket[0], (char*)PacketBuffer, 2048, 0, &fromAddr, &fromLen); - if (rlen < 12+24) - { - continue; - } - rlen -= 12; - - if (ntohl(*(u32*)&PacketBuffer[0]) != 0x4946494E) - { - continue; - } - - if (PacketBuffer[4] != NIFI_VER || PacketBuffer[5] != 0) - { - continue; - } - - if (ntohs(*(u16*)&PacketBuffer[6]) != rlen) - { - continue; - } - - if (*(u32*)&PacketBuffer[8] == MPUniqueID) - { - continue; - } - - zanf = *(u16*)&PacketBuffer[12+6]; - _logpacket(false, &PacketBuffer[12], rlen); - - memcpy(data, &PacketBuffer[12], rlen); - return rlen; - } + return LocalMP::RecvPacket(data, block); } bool MP_SendSync(u16 clientmask, u16 type, u64 val) { - u8 syncbuf[32]; - - if (MPSocket[1] < 0) - return false; - - int len = 16; - *(u32*)&syncbuf[0] = htonl(0x4946494E); // NIFI - syncbuf[4] = NIFI_VER; - syncbuf[5] = 1; - *(u16*)&syncbuf[6] = htons(len); - *(u16*)&syncbuf[8] = htons(type); - *(u16*)&syncbuf[10] = htons(clientmask); - *(u32*)&syncbuf[12] = MPUniqueID; - *(u32*)&syncbuf[16] = htonl((u32)val); - *(u32*)&syncbuf[20] = htonl((u32)(val>>32)); - - int slen = sendto(MPSocket[1], (const char*)syncbuf, len+8, 0, &MPSendAddr[1], sizeof(sockaddr_t)); - return slen == len+8; + return LocalMP::SendSync(clientmask, type, val); } bool MP_WaitSync(u16 clientmask, u16* type, u64* val) { - u8 syncbuf[32]; - - if (MPSocket[1] < 0) - return false; - - fd_set fd; - struct timeval tv; - - for (;;) - { - FD_ZERO(&fd); - FD_SET(MPSocket[1], &fd); - tv.tv_sec = 0; - tv.tv_usec = 500*1000; - - if (!select(MPSocket[1]+1, &fd, 0, 0, &tv)) - {printf("sync fail\n"); - return false; - } - - sockaddr_t fromAddr; - socklen_t fromLen = sizeof(sockaddr_t); - int rlen = recvfrom(MPSocket[1], (char*)syncbuf, 32, 0, &fromAddr, &fromLen); - if (rlen != 8+16) - continue; - rlen -= 8; - - if (ntohl(*(u32*)&syncbuf[0]) != 0x4946494E) - continue; - - if (syncbuf[4] != NIFI_VER || syncbuf[5] != 1) - continue; - - if (ntohs(*(u16*)&syncbuf[6]) != rlen) - continue; - - if (*(u32*)&syncbuf[12] == MPUniqueID) - continue; - - u16 clientval = ntohs(*(u16*)&syncbuf[10]); - if (!(clientmask & clientval)) - continue; - - // check the sync val, it should be ahead of the current sync val - u64 syncval = ntohl(*(u32*)&syncbuf[16]) | (((u64)ntohl(*(u32*)&syncbuf[20])) << 32); - //if (syncval <= curval) - // continue; - - if (type) *type = ntohs(*(u16*)&syncbuf[8]); - if (val) *val = syncval; - - return true; - } + return LocalMP::WaitSync(clientmask, type, val); } u16 MP_WaitMultipleSyncs(u16 type, u16 clientmask, u64 curval) { - u8 syncbuf[32]; - - if (!clientmask) - return 0; - - if (MPSocket[1] < 0) - return 0; - - fd_set fd; - struct timeval tv; - - for (;;) - { - FD_ZERO(&fd); - FD_SET(MPSocket[1], &fd); - tv.tv_sec = 0; - tv.tv_usec = 500*1000; - - if (!select(MPSocket[1]+1, &fd, 0, 0, &tv)) - {printf("[sync3] nope :(\n"); - return clientmask; - } - - sockaddr_t fromAddr; - socklen_t fromLen = sizeof(sockaddr_t); - int rlen = recvfrom(MPSocket[1], (char*)syncbuf, 32, 0, &fromAddr, &fromLen); - if (rlen != 8+16) - continue; - rlen -= 8; - - if (ntohl(*(u32*)&syncbuf[0]) != 0x4946494E) - continue; - - if (syncbuf[4] != NIFI_VER || syncbuf[5] != 1) - continue; -//printf("[sync3] atleast header is good\n"); - if (ntohs(*(u16*)&syncbuf[6]) != rlen) - continue; - - if (*(u32*)&syncbuf[12] == MPUniqueID) - continue; - - if (ntohs(*(u16*)&syncbuf[8]) != type) - continue; - - u16 clientval = ntohs(*(u16*)&syncbuf[10]); - //printf("[sync3] good rlen/type %04X %04X, clientmask=%04X \n", ntohs(*(u16*)&syncbuf[6]), ntohs(*(u16*)&syncbuf[8]), clientval); - if (!(clientmask & clientval)) - continue; - - // check the sync val, it should be ahead of the current sync val - u64 syncval = ntohl(*(u32*)&syncbuf[12]) | (((u64)ntohl(*(u32*)&syncbuf[16])) << 32); - //if (syncval <= curval) - // continue; -//printf("[sync3] good\n"); - clientmask &= ~clientval; - //if (!clientmask) - return 0; - } - - return clientmask; + return LocalMP::WaitMultipleSyncs(type, clientmask, curval); } @@ -794,9 +439,4 @@ int LAN_RecvPacket(u8* data) return LAN_Socket::RecvPacket(data); } -void Sleep(u64 usecs) -{ - QThread::usleep(usecs); -} - }