Merge remote-tracking branch 'upstream/master' into jump-after-writeback

This commit is contained in:
Jaklyy
2024-07-17 21:42:21 -04:00
221 changed files with 210 additions and 122 deletions

18
.gitattributes vendored Normal file
View File

@ -0,0 +1,18 @@
# Vendored Dependencies
src/frontend/glad/** linguist-vendored
src/frontend/qt_sdl/gif-h/** linguist-vendored
src/frontend/qt_sdl/toml/** linguist-vendored
src/net/libslirp/** linguist-vendored
src/net/pcap/** linguist-vendored
src/sha1/** linguist-vendored
src/teakra/** linguist-vendored
src/tiny-AES-c/** linguist-vendored
src/xxhash/** linguist-vendored
# A handful of custom files embedded in the vendored dependencies
## Ad-hoc CMakeLists.txt for melonDS
!src/net/libslirp/src/CMakeLists.txt -linguist-vendored
## glib stub
!src/net/libslirp/src/glib/** -linguist-vendored

View File

@ -7,8 +7,8 @@ endif()
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/DefaultBuildFlags.cmake") set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/DefaultBuildFlags.cmake")
option(USE_VCPKG "Use vcpkg for dependency packages" OFF) option(USE_VCPKG "Use vcpkg for dependency packages" OFF)
if (USE_VCPKG) if (USE_VCPKG)

View File

@ -1507,7 +1507,7 @@ void SoftRenderer::ApplySpriteMosaicX()
u32* objLine = OBJLine[CurUnit->Num]; u32* objLine = OBJLine[CurUnit->Num];
u8* curOBJXMosaicTable = MosaicTable[CurUnit->OBJMosaicSize[1]].data(); u8* curOBJXMosaicTable = MosaicTable[CurUnit->OBJMosaicSize[0]].data();
u32 lastcolor = objLine[0]; u32 lastcolor = objLine[0];

View File

@ -256,6 +256,9 @@ Semaphore* Semaphore_Create();
void Semaphore_Free(Semaphore* sema); void Semaphore_Free(Semaphore* sema);
void Semaphore_Reset(Semaphore* sema); void Semaphore_Reset(Semaphore* sema);
void Semaphore_Wait(Semaphore* sema); void Semaphore_Wait(Semaphore* sema);
/// Waits for the semaphore to be signaled, or until the timeout (in milliseconds) expires.
/// If the timeout is 0, then don't wait; return immediately if the semaphore is not signaled.
bool Semaphore_TryWait(Semaphore* sema, int timeout_ms = 0);
void Semaphore_Post(Semaphore* sema, int count = 1); void Semaphore_Post(Semaphore* sema, int count = 1);
struct Mutex; struct Mutex;

View File

@ -80,6 +80,7 @@ void Firmware::WifiAccessPoint::UpdateChecksum()
Firmware::ExtendedWifiAccessPoint::ExtendedWifiAccessPoint() Firmware::ExtendedWifiAccessPoint::ExtendedWifiAccessPoint()
{ {
memset(Bytes, 0, sizeof(Bytes));
Data.Base = WifiAccessPoint(); Data.Base = WifiAccessPoint();
UpdateChecksum(); UpdateChecksum();
@ -93,6 +94,7 @@ void Firmware::ExtendedWifiAccessPoint::UpdateChecksum()
Firmware::FirmwareHeader::FirmwareHeader(int consoletype) Firmware::FirmwareHeader::FirmwareHeader(int consoletype)
{ {
memset(Bytes, 0, sizeof(Bytes));
if (consoletype == 1) if (consoletype == 1)
{ {
ConsoleType = FirmwareConsoleType::DSi; ConsoleType = FirmwareConsoleType::DSi;
@ -156,7 +158,7 @@ void Firmware::FirmwareHeader::UpdateChecksum()
Firmware::UserData::UserData() Firmware::UserData::UserData()
{ {
memset(Bytes, 0, 0x74); memset(Bytes, 0, sizeof(Bytes));
Version = 5; Version = 5;
BirthdayMonth = 1; BirthdayMonth = 1;
BirthdayDay = 1; BirthdayDay = 1;
@ -273,7 +275,8 @@ Firmware::Firmware(const u8* data, u32 length) : FirmwareBuffer(nullptr), Firmwa
if (data) if (data)
{ {
FirmwareBuffer = new u8[FirmwareBufferLength]; FirmwareBuffer = new u8[FirmwareBufferLength];
memcpy(FirmwareBuffer, data, FirmwareBufferLength); memset(FirmwareBuffer, 0, FirmwareBufferLength);
memcpy(FirmwareBuffer, data, std::min(length, FirmwareBufferLength));
FirmwareMask = FirmwareBufferLength - 1; FirmwareMask = FirmwareBufferLength - 1;
} }
} }
@ -345,7 +348,7 @@ const Firmware::UserData& Firmware::GetEffectiveUserData() const {
if (userdata0ChecksumOk && userdata1ChecksumOk) if (userdata0ChecksumOk && userdata1ChecksumOk)
{ {
return userdata[0].UpdateCounter > userdata[1].UpdateCounter ? userdata[0] : userdata[1]; return userdata[0].UpdateCounter >= userdata[1].UpdateCounter ? userdata[0] : userdata[1];
} }
else if (userdata0ChecksumOk) else if (userdata0ChecksumOk)
{ {
@ -368,7 +371,7 @@ Firmware::UserData& Firmware::GetEffectiveUserData() {
if (userdata0ChecksumOk && userdata1ChecksumOk) if (userdata0ChecksumOk && userdata1ChecksumOk)
{ {
return userdata[0].UpdateCounter > userdata[1].UpdateCounter ? userdata[0] : userdata[1]; return userdata[0].UpdateCounter >= userdata[1].UpdateCounter ? userdata[0] : userdata[1];
} }
else if (userdata0ChecksumOk) else if (userdata0ChecksumOk)
{ {

View File

@ -1 +0,0 @@
../IN_ndp/ndp.pcap

View File

@ -1 +0,0 @@
../IN_udp/DNS_freedesktop_1-1-1-1.pcap

View File

@ -1 +0,0 @@
../IN_dhcp/dhcp.pkt

View File

@ -1 +0,0 @@
../IN_dhcp/dhcp_capture.pcap

View File

@ -1 +0,0 @@
../IN_icmp/icmp_capture.pcap

View File

@ -1 +0,0 @@
../IN_tcp/nc-10.0.2.2-8080.pcap

View File

@ -1 +0,0 @@
../IN_tcp/nc-ident.pcap

View File

@ -1 +0,0 @@
../IN_icmp/ping_10-0-2-2.pcap

View File

@ -1 +0,0 @@
../IN_tcp/tcp_qemucapt.pcap

View File

@ -1 +0,0 @@
../IN_tftp/tftp-get-blah.pkt

View File

@ -1 +0,0 @@
../IN_tftp/tftp_capture.pcap

View File

@ -1 +0,0 @@
../IN_tftp/tftp_get_libslirp-txt.pcap

View File

@ -1 +0,0 @@
../IN_udp6/DNS_freedesktop_1-1-1-1.pcap

View File

@ -1 +0,0 @@
../IN_icmp6/icmp_capture.pcap

View File

@ -1 +0,0 @@
../IN_icmp6/ping_10-0-2-2.pcap

View File

@ -1 +0,0 @@
../IN_tcp6/tcp_qemucapt.pcap

View File

@ -1 +0,0 @@
../IN_udp6/tftp_capture.pcap

View File

@ -1 +0,0 @@
../IN_udp6/tftp_get_libslirp-txt.pcap

View File

@ -1 +0,0 @@
IN_tcp

View File

@ -1 +0,0 @@
IN_tcp

View File

@ -1 +0,0 @@
IN_tcp6

View File

@ -1 +0,0 @@
IN_tcp6

View File

@ -1 +0,0 @@
IN_udp

View File

@ -1 +0,0 @@
../IN_dhcp/dhcp.pkt

View File

@ -1 +0,0 @@
../IN_dhcp/dhcp_capture.pcap

View File

@ -1 +0,0 @@
../IN_tftp/tftp-get-blah.pkt

View File

@ -1 +0,0 @@
../IN_tftp/tftp_capture.pcap

View File

@ -1 +0,0 @@
../IN_tftp/tftp_get_libslirp-txt.pcap

View File

@ -1 +0,0 @@
IN_udp6

View File

@ -1 +0,0 @@
../IN_tftp6/tftp_capture.pcap

View File

@ -1 +0,0 @@
../IN_tftp6/tftp_get_libslirp-txt.pcap

View File

@ -103,7 +103,11 @@ AudioSettingsDialog::AudioSettingsDialog(QWidget* parent) : QDialog(parent), ui(
grpMicMode->addButton(ui->rbMicExternal, micInputType_External); grpMicMode->addButton(ui->rbMicExternal, micInputType_External);
grpMicMode->addButton(ui->rbMicNoise, micInputType_Noise); grpMicMode->addButton(ui->rbMicNoise, micInputType_Noise);
grpMicMode->addButton(ui->rbMicWav, micInputType_Wav); grpMicMode->addButton(ui->rbMicWav, micInputType_Wav);
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
connect(grpMicMode, SIGNAL(buttonClicked(int)), this, SLOT(onChangeMicMode(int))); connect(grpMicMode, SIGNAL(buttonClicked(int)), this, SLOT(onChangeMicMode(int)));
#else
connect(grpMicMode, SIGNAL(idClicked(int)), this, SLOT(onChangeMicMode(int)));
#endif
grpMicMode->button(mictype)->setChecked(true); grpMicMode->button(mictype)->setChecked(true);
ui->txtMicWavPath->setText(cfg.GetQString("Mic.WavPath")); ui->txtMicWavPath->setText(cfg.GetQString("Mic.WavPath"));

View File

@ -31,11 +31,6 @@ set(SOURCES_QT_SDL
ROMInfoDialog.cpp ROMInfoDialog.cpp
RAMInfoDialog.cpp RAMInfoDialog.cpp
TitleManagerDialog.cpp TitleManagerDialog.cpp
PacketDispatcher.cpp
Net.cpp
Net_PCap.cpp
Net_Slirp.cpp
LocalMP.cpp
OSD_shaders.h OSD_shaders.h
font.h font.h
Platform.cpp Platform.cpp
@ -93,16 +88,11 @@ add_compile_definitions(ARCHIVE_SUPPORT_ENABLED)
add_executable(melonDS ${SOURCES_QT_SDL}) add_executable(melonDS ${SOURCES_QT_SDL})
option(USE_SYSTEM_LIBSLIRP "Use system libslirp instead of the bundled version" OFF) add_subdirectory("../../net"
if (USE_SYSTEM_LIBSLIRP) "${CMAKE_BINARY_DIR}/net"
pkg_check_modules(Slirp REQUIRED IMPORTED_TARGET slirp) )
target_link_libraries(melonDS PRIVATE PkgConfig::Slirp)
else() target_link_libraries(melonDS PRIVATE net-utils)
add_subdirectory("../libslirp"
"${CMAKE_BINARY_DIR}/libslirp"
EXCLUDE_FROM_ALL)
target_link_libraries(melonDS PRIVATE slirp)
endif()
if (WIN32) if (WIN32)
target_link_libraries(melonDS PUBLIC opengl32) target_link_libraries(melonDS PUBLIC opengl32)
@ -121,6 +111,8 @@ elseif (APPLE)
find_library(COCOA_LIB Cocoa) find_library(COCOA_LIB Cocoa)
target_link_libraries(melonDS PRIVATE ${COCOA_LIB}) target_link_libraries(melonDS PRIVATE ${COCOA_LIB})
endif() endif()
find_library(OPENGL_LIB OpenGL)
target_link_libraries(melonDS PRIVATE ${OPENGL_LIB})
target_sources(melonDS PRIVATE target_sources(melonDS PRIVATE
../duckstation/gl/context_agl.mm ../duckstation/gl/context_agl.mm
) )

View File

@ -92,7 +92,7 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
mpAudioMode = globalCfg.GetInt("MP.AudioMode"); mpAudioMode = globalCfg.GetInt("MP.AudioMode");
nds = nullptr; nds = nullptr;
updateConsole(nullptr, nullptr); //updateConsole(nullptr, nullptr);
audioInit(); audioInit();
inputInit(); inputInit();
@ -518,7 +518,7 @@ std::string EmuInstance::getEffectiveFirmwareSavePath()
{ {
if (!globalCfg.GetBool("Emu.ExternalBIOSEnable")) if (!globalCfg.GetBool("Emu.ExternalBIOSEnable"))
{ {
return kWifiSettingsPath; return GetLocalFilePath(kWifiSettingsPath);
} }
if (consoleType == 1) if (consoleType == 1)
{ {
@ -1110,7 +1110,7 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB
}; };
auto jitargs = jitopt.GetBool("Enable") ? std::make_optional(_jitargs) : std::nullopt; auto jitargs = jitopt.GetBool("Enable") ? std::make_optional(_jitargs) : std::nullopt;
#else #else
optional<JITArsg> jitargs = std::nullopt; optional<JITArgs> jitargs = std::nullopt;
#endif #endif
#ifdef GDBSTUB_ENABLED #ifdef GDBSTUB_ENABLED
@ -1261,7 +1261,7 @@ void EmuInstance::reset()
} }
else else
{ {
newsave = kWifiSettingsPath + instanceFileSuffix(); newsave = GetLocalFilePath(kWifiSettingsPath + instanceFileSuffix());
} }
if (oldsave != newsave) if (oldsave != newsave)

View File

@ -40,13 +40,21 @@ int EmuInstance::audioGetNumSamplesOut(int outlen)
void EmuInstance::audioResample(s16* inbuf, int inlen, s16* outbuf, int outlen, int volume) void EmuInstance::audioResample(s16* inbuf, int inlen, s16* outbuf, int outlen, int volume)
{ {
float res_incr = inlen / (float)outlen; float res_incr = inlen / (float)outlen;
float res_timer = 0; float res_timer = -0.5;
int res_pos = 0; int res_pos = 0;
for (int i = 0; i < outlen; i++) for (int i = 0; i < outlen; i++)
{ {
outbuf[i*2 ] = (inbuf[res_pos*2 ] * volume) >> 8; s16 l1 = inbuf[res_pos * 2];
outbuf[i*2+1] = (inbuf[res_pos*2+1] * volume) >> 8; s16 l2 = inbuf[res_pos * 2 + 2];
s16 r1 = inbuf[res_pos * 2 + 1];
s16 r2 = inbuf[res_pos * 2 + 3];
float l = (float) l1 + ((l2 - l1) * res_timer);
float r = (float) r1 + ((r2 - r1) * res_timer);
outbuf[i*2 ] = (s16) (((s32) round(l) * volume) >> 8);
outbuf[i*2+1] = (s16) (((s32) round(r) * volume) >> 8);
res_timer += res_incr; res_timer += res_incr;
while (res_timer >= 1.0) while (res_timer >= 1.0)

View File

@ -351,6 +351,14 @@ void Semaphore_Wait(Semaphore* sema)
((QSemaphore*) sema)->acquire(); ((QSemaphore*) sema)->acquire();
} }
bool Semaphore_TryWait(Semaphore* sema, int timeout_ms)
{
if (!timeout_ms)
return ((QSemaphore*)sema)->tryAcquire(1);
return ((QSemaphore*)sema)->tryAcquire(1, timeout_ms);
}
void Semaphore_Post(Semaphore* sema, int count) void Semaphore_Post(Semaphore* sema, int count)
{ {
((QSemaphore*) sema)->release(count); ((QSemaphore*) sema)->release(count);

View File

@ -276,8 +276,13 @@ void ScreenPanel::tabletEvent(QTabletEvent* event)
case QEvent::TabletPress: case QEvent::TabletPress:
case QEvent::TabletMove: case QEvent::TabletMove:
{ {
#if QT_VERSION_MAJOR == 6
int x = event->position().x();
int y = event->position().y();
#else
int x = event->x(); int x = event->x();
int y = event->y(); int y = event->y();
#endif
if (layout.GetTouchCoords(x, y, event->type()==QEvent::TabletMove)) if (layout.GetTouchCoords(x, y, event->type()==QEvent::TabletMove))
{ {
@ -302,15 +307,26 @@ void ScreenPanel::tabletEvent(QTabletEvent* event)
void ScreenPanel::touchEvent(QTouchEvent* event) void ScreenPanel::touchEvent(QTouchEvent* event)
{ {
#if QT_VERSION_MAJOR == 6
if (event->device()->type() == QInputDevice::DeviceType::TouchPad)
return;
#endif
event->accept(); event->accept();
switch(event->type()) switch(event->type())
{ {
case QEvent::TouchBegin: case QEvent::TouchBegin:
case QEvent::TouchUpdate: case QEvent::TouchUpdate:
#if QT_VERSION_MAJOR == 6
if (event->points().length() > 0)
{
QPointF lastPosition = event->points().first().lastPosition();
#else
if (event->touchPoints().length() > 0) if (event->touchPoints().length() > 0)
{ {
QPointF lastPosition = event->touchPoints().first().lastPos(); QPointF lastPosition = event->touchPoints().first().lastPos();
#endif
int x = (int)lastPosition.x(); int x = (int)lastPosition.x();
int y = (int)lastPosition.y(); int y = (int)lastPosition.y();

View File

@ -397,7 +397,11 @@ TitleImportDialog::TitleImportDialog(QWidget* parent, QString& apppath, const DS
grpTmdSource = new QButtonGroup(this); grpTmdSource = new QButtonGroup(this);
grpTmdSource->addButton(ui->rbTmdFromFile, 0); grpTmdSource->addButton(ui->rbTmdFromFile, 0);
grpTmdSource->addButton(ui->rbTmdFromNUS, 1); grpTmdSource->addButton(ui->rbTmdFromNUS, 1);
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
connect(grpTmdSource, SIGNAL(buttonClicked(int)), this, SLOT(onChangeTmdSource(int))); connect(grpTmdSource, SIGNAL(buttonClicked(int)), this, SLOT(onChangeTmdSource(int)));
#else
connect(grpTmdSource, SIGNAL(idClicked(int)), this, SLOT(onChangeTmdSource(int)));
#endif
grpTmdSource->button(0)->setChecked(true); grpTmdSource->button(0)->setChecked(true);
} }

View File

@ -25,6 +25,7 @@
#include "main.h" #include "main.h"
#include "Net.h" #include "Net.h"
#include "Net_PCap.h"
#include "WifiSettingsDialog.h" #include "WifiSettingsDialog.h"
#include "ui_WifiSettingsDialog.h" #include "ui_WifiSettingsDialog.h"
@ -109,7 +110,10 @@ void WifiSettingsDialog::done(int r)
} }
Net_PCap::DeInit(); Net_PCap::DeInit();
Net::Init(); Config::Table cfg = Config::GetGlobalTable();
bool direct = cfg.GetBool("LAN.DirectMode");
std::string devicename = cfg.GetString("LAN.Device");
Net::Init(direct, devicename.c_str());
QDialog::done(r); QDialog::done(r);

View File

@ -274,7 +274,12 @@ int main(int argc, char** argv)
} }
LocalMP::Init(); LocalMP::Init();
Net::Init(); {
Config::Table cfg = Config::GetGlobalTable();
bool direct = cfg.GetBool("LAN.DirectMode");
std::string devicename = cfg.GetString("LAN.Device");
Net::Init(direct, devicename.c_str());
}
createEmuInstance(); createEmuInstance();

20
src/net/CMakeLists.txt Normal file
View File

@ -0,0 +1,20 @@
add_library(net-utils STATIC
Net.cpp
Net_PCap.cpp
Net_Slirp.cpp
PacketDispatcher.cpp
LocalMP.cpp
)
target_include_directories(net-utils PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(net-utils PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
option(USE_SYSTEM_LIBSLIRP "Use system libslirp instead of the bundled version" OFF)
if (USE_SYSTEM_LIBSLIRP)
pkg_check_modules(Slirp REQUIRED IMPORTED_TARGET slirp)
target_link_libraries(net-utils PRIVATE PkgConfig::Slirp)
else()
add_subdirectory(libslirp EXCLUDE_FROM_ALL)
target_link_libraries(net-utils PRIVATE slirp)
endif()

View File

@ -17,11 +17,10 @@
*/ */
#include <cstring> #include <cstring>
#include <QMutex>
#include <QSemaphore>
#include "LocalMP.h" #include "LocalMP.h"
#include "Platform.h" #include "Platform.h"
#include "types.h"
using namespace melonDS; using namespace melonDS;
using namespace melonDS::Platform; using namespace melonDS::Platform;
@ -54,7 +53,7 @@ const u32 kPacketQueueSize = 0x10000;
const u32 kReplyQueueSize = 0x10000; const u32 kReplyQueueSize = 0x10000;
const u32 kMaxFrameSize = 0x948; const u32 kMaxFrameSize = 0x948;
QMutex MPQueueLock; Mutex* MPQueueLock;
MPStatusData MPStatus; MPStatusData MPStatus;
u8 MPPacketQueue[kPacketQueueSize]; u8 MPPacketQueue[kPacketQueueSize];
u8 MPReplyQueue[kReplyQueueSize]; u8 MPReplyQueue[kReplyQueueSize];
@ -66,39 +65,37 @@ int RecvTimeout;
int LastHostID; int LastHostID;
QSemaphore SemPool[32]; Semaphore* SemPool[32];
void SemPoolInit() void SemPoolInit()
{ {
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
SemPool[i].acquire(SemPool[i].available()); SemPool[i] = Semaphore_Create();
} }
} }
bool SemPost(int num) bool SemPost(int num)
{ {
SemPool[num].release(1); Semaphore_Post(SemPool[num]);
return true; return true;
} }
bool SemWait(int num, int timeout) bool SemWait(int num, int timeout)
{ {
if (!timeout) return Semaphore_TryWait(SemPool[num], timeout);
return SemPool[num].tryAcquire(1);
return SemPool[num].tryAcquire(1, timeout);
} }
void SemReset(int num) void SemReset(int num)
{ {
SemPool[num].acquire(SemPool[num].available()); Semaphore_Reset(SemPool[num]);
} }
bool Init() bool Init()
{ {
MPQueueLock.lock(); MPQueueLock = Mutex_Create();
Mutex_Lock(MPQueueLock);
memset(MPPacketQueue, 0, kPacketQueueSize); memset(MPPacketQueue, 0, kPacketQueueSize);
memset(MPReplyQueue, 0, kReplyQueueSize); memset(MPReplyQueue, 0, kReplyQueueSize);
@ -106,7 +103,7 @@ bool Init()
memset(PacketReadOffset, 0, sizeof(PacketReadOffset)); memset(PacketReadOffset, 0, sizeof(PacketReadOffset));
memset(ReplyReadOffset, 0, sizeof(ReplyReadOffset)); memset(ReplyReadOffset, 0, sizeof(ReplyReadOffset));
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
// prepare semaphores // prepare semaphores
// semaphores 0-15: regular frames; semaphore I is posted when instance I needs to process a new frame // semaphores 0-15: regular frames; semaphore I is posted when instance I needs to process a new frame
@ -125,6 +122,13 @@ bool Init()
void DeInit() void DeInit()
{ {
for (int i = 0; i < 32; i++)
{
Semaphore_Free(SemPool[i]);
SemPool[i] = nullptr;
}
Mutex_Free(MPQueueLock);
} }
void SetRecvTimeout(int timeout) void SetRecvTimeout(int timeout)
@ -134,20 +138,20 @@ void SetRecvTimeout(int timeout)
void Begin(int inst) void Begin(int inst)
{ {
MPQueueLock.lock(); Mutex_Lock(MPQueueLock);
PacketReadOffset[inst] = MPStatus.PacketWriteOffset; PacketReadOffset[inst] = MPStatus.PacketWriteOffset;
ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset; ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset;
SemReset(inst); SemReset(inst);
SemReset(16+inst); SemReset(16+inst);
MPStatus.ConnectedBitmask |= (1 << inst); MPStatus.ConnectedBitmask |= (1 << inst);
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
} }
void End(int inst) void End(int inst)
{ {
MPQueueLock.lock(); Mutex_Lock(MPQueueLock);
MPStatus.ConnectedBitmask &= ~(1 << inst); MPStatus.ConnectedBitmask &= ~(1 << inst);
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
} }
void FIFORead(int inst, int fifo, void* buf, int len) void FIFORead(int inst, int fifo, void* buf, int len)
@ -228,7 +232,7 @@ int SendPacketGeneric(int inst, u32 type, u8* packet, int len, u64 timestamp)
return 0; return 0;
} }
MPQueueLock.lock(); Mutex_Lock(MPQueueLock);
u16 mask = MPStatus.ConnectedBitmask; u16 mask = MPStatus.ConnectedBitmask;
@ -261,7 +265,7 @@ int SendPacketGeneric(int inst, u32 type, u8* packet, int len, u64 timestamp)
MPStatus.MPReplyBitmask |= (1 << inst); MPStatus.MPReplyBitmask |= (1 << inst);
} }
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
if (type == 2) if (type == 2)
{ {
@ -288,7 +292,7 @@ int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp)
return 0; return 0;
} }
MPQueueLock.lock(); Mutex_Lock(MPQueueLock);
MPPacketHeader pktheader; MPPacketHeader pktheader;
FIFORead(inst, 0, &pktheader, sizeof(pktheader)); FIFORead(inst, 0, &pktheader, sizeof(pktheader));
@ -298,7 +302,7 @@ int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp)
Log(LogLevel::Warn, "PACKET FIFO OVERFLOW\n"); Log(LogLevel::Warn, "PACKET FIFO OVERFLOW\n");
PacketReadOffset[inst] = MPStatus.PacketWriteOffset; PacketReadOffset[inst] = MPStatus.PacketWriteOffset;
SemReset(inst); SemReset(inst);
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
return 0; return 0;
} }
@ -309,7 +313,7 @@ int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp)
if (PacketReadOffset[inst] >= kPacketQueueSize) if (PacketReadOffset[inst] >= kPacketQueueSize)
PacketReadOffset[inst] -= kPacketQueueSize; PacketReadOffset[inst] -= kPacketQueueSize;
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
continue; continue;
} }
@ -322,7 +326,7 @@ int RecvPacketGeneric(int inst, u8* packet, bool block, u64* timestamp)
} }
if (timestamp) *timestamp = pktheader.Timestamp; if (timestamp) *timestamp = pktheader.Timestamp;
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
return pktheader.Length; return pktheader.Length;
} }
} }
@ -388,7 +392,7 @@ u16 RecvReplies(int inst, u8* packets, u64 timestamp, u16 aidmask)
return ret; return ret;
} }
MPQueueLock.lock(); Mutex_Lock(MPQueueLock);
MPPacketHeader pktheader; MPPacketHeader pktheader;
FIFORead(inst, 1, &pktheader, sizeof(pktheader)); FIFORead(inst, 1, &pktheader, sizeof(pktheader));
@ -398,7 +402,7 @@ u16 RecvReplies(int inst, u8* packets, u64 timestamp, u16 aidmask)
Log(LogLevel::Warn, "REPLY FIFO OVERFLOW\n"); Log(LogLevel::Warn, "REPLY FIFO OVERFLOW\n");
ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset; ReplyReadOffset[inst] = MPStatus.ReplyWriteOffset;
SemReset(16+inst); SemReset(16+inst);
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
return 0; return 0;
} }
@ -410,7 +414,7 @@ u16 RecvReplies(int inst, u8* packets, u64 timestamp, u16 aidmask)
if (ReplyReadOffset[inst] >= kReplyQueueSize) if (ReplyReadOffset[inst] >= kReplyQueueSize)
ReplyReadOffset[inst] -= kReplyQueueSize; ReplyReadOffset[inst] -= kReplyQueueSize;
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
continue; continue;
} }
@ -427,11 +431,11 @@ u16 RecvReplies(int inst, u8* packets, u64 timestamp, u16 aidmask)
{ {
// all the clients have sent their reply // all the clients have sent their reply
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
return ret; return ret;
} }
MPQueueLock.unlock(); Mutex_Unlock(MPQueueLock);
} }
} }

View File

@ -18,11 +18,11 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <QMutex>
#include "Net.h" #include "Net.h"
#include "Net_PCap.h"
#include "Net_Slirp.h"
#include "PacketDispatcher.h" #include "PacketDispatcher.h"
#include "Platform.h" #include "Platform.h"
#include "Config.h"
using namespace melonDS; using namespace melonDS;
@ -38,18 +38,17 @@ bool DirectMode;
PacketDispatcher Dispatcher; PacketDispatcher Dispatcher;
bool Init() bool Init(bool direct, const char* devicename)
{ {
if (Inited) DeInit(); if (Inited) DeInit();
Dispatcher.clear(); Dispatcher.clear();
Config::Table cfg = Config::GetGlobalTable(); DirectMode = direct;
DirectMode = cfg.GetBool("LAN.DirectMode");
bool ret = false; bool ret = false;
if (DirectMode) if (DirectMode)
ret = Net_PCap::Init(); ret = Net_PCap::Init(devicename);
else else
ret = Net_Slirp::Init(); ret = Net_Slirp::Init();

View File

@ -20,14 +20,16 @@
#define NET_H #define NET_H
#include "types.h" #include "types.h"
#include "Net_PCap.h"
#include "Net_Slirp.h"
namespace Net namespace Net
{ {
using namespace melonDS; using namespace melonDS;
bool Init(); ///
/// @param direct Whether to use direct or indirect mode
/// @param devicename The name of the network device to use; ignored if direct is false
/// @return true if initialization succeeded
bool Init(bool direct, const char* devicename);
void DeInit(); void DeInit();
void RegisterInstance(int inst); void RegisterInstance(int inst);

View File

@ -19,9 +19,8 @@
#include <string.h> #include <string.h>
#include <pcap/pcap.h> #include <pcap/pcap.h>
#include "Net.h" #include "Net.h"
#include "Config.h" #include "Net_PCap.h"
#include "Platform.h" #include "Platform.h"
#include "main.h"
#ifdef __WIN32__ #ifdef __WIN32__
#include <iphlpapi.h> #include <iphlpapi.h>
@ -299,7 +298,7 @@ bool InitAdapterList()
return true; return true;
} }
bool Init() bool Init(std::string_view devicename)
{ {
if (!PCapLib) PCapAdapter = nullptr; if (!PCapLib) PCapAdapter = nullptr;
if (PCapAdapter) pcap_close(PCapAdapter); if (PCapAdapter) pcap_close(PCapAdapter);
@ -307,12 +306,10 @@ bool Init()
InitAdapterList(); InitAdapterList();
// open pcap device // open pcap device
Config::Table cfg = Config::GetGlobalTable();
std::string devicename = cfg.GetString("LAN.Device");
PCapAdapterData = &Adapters[0]; PCapAdapterData = &Adapters[0];
for (int i = 0; i < NumAdapters; i++) for (int i = 0; i < NumAdapters; i++)
{ {
if (!strncmp(Adapters[i].DeviceName, devicename.c_str(), 128)) if (!strncmp(Adapters[i].DeviceName, devicename.data(), 128))
PCapAdapterData = &Adapters[i]; PCapAdapterData = &Adapters[i];
} }

View File

@ -19,6 +19,7 @@
#ifndef NET_PCAP_H #ifndef NET_PCAP_H
#define NET_PCAP_H #define NET_PCAP_H
#include <string_view>
#include "types.h" #include "types.h"
namespace Net_PCap namespace Net_PCap
@ -41,7 +42,7 @@ extern int NumAdapters;
bool InitAdapterList(); bool InitAdapterList();
bool Init(); bool Init(std::string_view devicename);
void DeInit(); void DeInit();
int SendPacket(u8* data, int len); int SendPacket(u8* data, int len);

View File

@ -31,7 +31,7 @@ struct PacketHeader
const u32 kPacketMagic = 0x4B504C4D; const u32 kPacketMagic = 0x4B504C4D;
PacketDispatcher::PacketDispatcher() PacketDispatcher::PacketDispatcher() : mutex(Platform::Mutex_Create())
{ {
instanceMask = 0; instanceMask = 0;
memset(packetQueues, 0, sizeof(packetQueues)); memset(packetQueues, 0, sizeof(packetQueues));
@ -39,34 +39,34 @@ PacketDispatcher::PacketDispatcher()
PacketDispatcher::~PacketDispatcher() PacketDispatcher::~PacketDispatcher()
{ {
// Platform::Mutex_Free(mutex);
} }
void PacketDispatcher::registerInstance(int inst) void PacketDispatcher::registerInstance(int inst)
{ {
mutex.lock(); Mutex_Lock(mutex);
instanceMask |= (1 << inst); instanceMask |= (1 << inst);
packetQueues[inst] = new PacketQueue(); packetQueues[inst] = new PacketQueue();
mutex.unlock(); Mutex_Unlock(mutex);
} }
void PacketDispatcher::unregisterInstance(int inst) void PacketDispatcher::unregisterInstance(int inst)
{ {
mutex.lock(); Mutex_Lock(mutex);
instanceMask &= ~(1 << inst); instanceMask &= ~(1 << inst);
delete packetQueues[inst]; delete packetQueues[inst];
mutex.unlock(); Mutex_Unlock(mutex);
} }
void PacketDispatcher::clear() void PacketDispatcher::clear()
{ {
mutex.lock(); Mutex_Lock(mutex);
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
if (!(instanceMask & (1 << i))) if (!(instanceMask & (1 << i)))
@ -75,7 +75,7 @@ void PacketDispatcher::clear()
PacketQueue* queue = packetQueues[i]; PacketQueue* queue = packetQueues[i];
queue->Clear(); queue->Clear();
} }
mutex.unlock(); Mutex_Unlock(mutex);
} }
@ -99,7 +99,7 @@ void PacketDispatcher::sendPacket(const void* header, int headerlen, const void*
int totallen = sizeof(phdr) + headerlen + datalen; int totallen = sizeof(phdr) + headerlen + datalen;
mutex.lock(); Mutex_Lock(mutex);
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
if (!(recv_mask & (1 << i))) if (!(recv_mask & (1 << i)))
@ -119,7 +119,7 @@ void PacketDispatcher::sendPacket(const void* header, int headerlen, const void*
if (headerlen) queue->Write(header, headerlen); if (headerlen) queue->Write(header, headerlen);
if (datalen) queue->Write(data, datalen); if (datalen) queue->Write(data, datalen);
} }
mutex.unlock(); Mutex_Unlock(mutex);
} }
bool PacketDispatcher::recvPacket(void *header, int *headerlen, void *data, int *datalen, int receiver) bool PacketDispatcher::recvPacket(void *header, int *headerlen, void *data, int *datalen, int receiver)
@ -127,19 +127,19 @@ bool PacketDispatcher::recvPacket(void *header, int *headerlen, void *data, int
if ((!header) && (!data)) return false; if ((!header) && (!data)) return false;
if (receiver < 0 || receiver > 15) return false; if (receiver < 0 || receiver > 15) return false;
mutex.lock(); Mutex_Lock(mutex);
PacketQueue* queue = packetQueues[receiver]; PacketQueue* queue = packetQueues[receiver];
PacketHeader phdr; PacketHeader phdr;
if (!queue->Read(&phdr, sizeof(phdr))) if (!queue->Read(&phdr, sizeof(phdr)))
{ {
mutex.unlock(); Mutex_Unlock(mutex);
return false; return false;
} }
if (phdr.magic != kPacketMagic) if (phdr.magic != kPacketMagic)
{ {
mutex.unlock(); Mutex_Unlock(mutex);
return false; return false;
} }
@ -157,6 +157,6 @@ bool PacketDispatcher::recvPacket(void *header, int *headerlen, void *data, int
else queue->Skip(phdr.dataLength); else queue->Skip(phdr.dataLength);
} }
mutex.unlock(); Mutex_Unlock(mutex);
return true; return true;
} }

View File

@ -19,7 +19,7 @@
#ifndef PACKETDISPATCHER_H #ifndef PACKETDISPATCHER_H
#define PACKETDISPATCHER_H #define PACKETDISPATCHER_H
#include <QMutex> #include "Platform.h"
#include "types.h" #include "types.h"
#include "FIFO.h" #include "FIFO.h"
@ -40,7 +40,7 @@ public:
bool recvPacket(void* header, int* headerlen, void* data, int* datalen, int receiver); bool recvPacket(void* header, int* headerlen, void* data, int* datalen, int receiver);
private: private:
QMutex mutex; melonDS::Platform::Mutex* mutex;
melonDS::u16 instanceMask; melonDS::u16 instanceMask;
PacketQueue* packetQueues[16]; PacketQueue* packetQueues[16];
}; };

View File

@ -0,0 +1 @@
../IN_ndp/ndp.pcap

View File

@ -0,0 +1 @@
../IN_udp/DNS_freedesktop_1-1-1-1.pcap

View File

@ -0,0 +1 @@
../IN_dhcp/dhcp.pkt

View File

@ -0,0 +1 @@
../IN_dhcp/dhcp_capture.pcap

View File

@ -0,0 +1 @@
../IN_icmp/icmp_capture.pcap

View File

@ -0,0 +1 @@
../IN_tcp/nc-10.0.2.2-8080.pcap

View File

@ -0,0 +1 @@
../IN_tcp/nc-ident.pcap

View File

@ -0,0 +1 @@
../IN_icmp/ping_10-0-2-2.pcap

View File

@ -0,0 +1 @@
../IN_tcp/tcp_qemucapt.pcap

View File

@ -0,0 +1 @@
../IN_tftp/tftp-get-blah.pkt

View File

@ -0,0 +1 @@
../IN_tftp/tftp_capture.pcap

View File

@ -0,0 +1 @@
../IN_tftp/tftp_get_libslirp-txt.pcap

View File

@ -0,0 +1 @@
../IN_udp6/DNS_freedesktop_1-1-1-1.pcap

View File

@ -0,0 +1 @@
../IN_icmp6/icmp_capture.pcap

View File

@ -0,0 +1 @@
../IN_icmp6/ping_10-0-2-2.pcap

View File

@ -0,0 +1 @@
../IN_tcp6/tcp_qemucapt.pcap

View File

@ -0,0 +1 @@
../IN_udp6/tftp_capture.pcap

View File

@ -0,0 +1 @@
../IN_udp6/tftp_get_libslirp-txt.pcap

1
src/net/libslirp/fuzzing/IN_tcp-d vendored Normal file
View File

@ -0,0 +1 @@
IN_tcp

1
src/net/libslirp/fuzzing/IN_tcp-h vendored Normal file
View File

@ -0,0 +1 @@
IN_tcp

1
src/net/libslirp/fuzzing/IN_tcp6-d vendored Normal file
View File

@ -0,0 +1 @@
IN_tcp6

1
src/net/libslirp/fuzzing/IN_tcp6-h vendored Normal file
View File

@ -0,0 +1 @@
IN_tcp6

Some files were not shown because too many files have changed in this diff Show More