From 591cec315ea2da2d32d17f9a824463078afb8a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 27 Oct 2026 17:44:33 +0100 Subject: [PATCH] sceNetAdhocMatching: Put the game workarounds behind compat flags CancelTarget on a MAC that isn't a peer, and Start on a context ID that doesn't exist, faked success for every game. On the PSP they fail with UNKNOWN_TARGET and INVALID_ID (pspautotests net/adhoc/matching). Only the games they were added for keep them now: MatchingCancelUnknownTargetSucceeds for Soulcalibur: Broken Destiny, and MatchingStartUnknownIdSucceeds for GTA: Vice City Stories. Co-Authored-By: Claude Opus 5.5 --- Core/Compatibility.cpp | 2 ++ Core/Compatibility.h | 2 ++ Core/HLE/sceNetAdhocMatching.cpp | 17 +++++++++++------ assets/compat.ini | 20 ++++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 9d9bc2098f..b93ca87d44 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -171,6 +171,8 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "ColorPickingDrawSyncReadback", &flags_.ColorPickingDrawSyncReadback); CheckSetting(iniFile, gameID, "SeparateLogicOpDraws", &flags_.SeparateLogicOpDraws); CheckSetting(iniFile, gameID, "SnapHalfPixelSprites", &flags_.SnapHalfPixelSprites); + CheckSetting(iniFile, gameID, "MatchingCancelUnknownTargetSucceeds", &flags_.MatchingCancelUnknownTargetSucceeds); + CheckSetting(iniFile, gameID, "MatchingStartUnknownIdSucceeds", &flags_.MatchingStartUnknownIdSucceeds); CheckSetting(iniFile, gameID, "FixedFramebuffer", &flags_.FixedFramebuffer); CheckSetting(iniFile, gameID, "NativeResolutionFramebuffer", &flags_.NativeResolutionFramebuffer); } diff --git a/Core/Compatibility.h b/Core/Compatibility.h index a700a736aa..ba428d5884 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -137,6 +137,8 @@ struct CompatFlags { bool ColorPickingDrawSyncReadback; bool SeparateLogicOpDraws; bool SnapHalfPixelSprites; + bool MatchingCancelUnknownTargetSucceeds; + bool MatchingStartUnknownIdSucceeds; CompatFramebuffer FixedFramebuffer; uint32_t NativeResolutionFramebuffer; }; diff --git a/Core/HLE/sceNetAdhocMatching.cpp b/Core/HLE/sceNetAdhocMatching.cpp index 7676ce3590..ba00688b9c 100644 --- a/Core/HLE/sceNetAdhocMatching.cpp +++ b/Core/HLE/sceNetAdhocMatching.cpp @@ -17,6 +17,7 @@ #include "Core/HLE/sceNetAdhocMatching.h" +#include "Core/System.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/NetAdhocCommon.h" @@ -1882,8 +1883,11 @@ int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int SceNetAdhocMatchingContext* item = findMatchingContext(matchingId); if (item == NULL) { - // return SCE_NET_ADHOC_MATCHING_ERROR_INVALID_ID; //Faking success to prevent GTA:VCS from stuck unable to choose host/join menu - return hleLogDebug(Log::sceNet, 0); + // GTA: VCS gets stuck unable to choose host/join otherwise. + if (PSP_CoreParameter().compat.flags().MatchingStartUnknownIdSucceeds) { + return hleLogDebug(Log::sceNet, 0, "faking success"); + } + return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_INVALID_ID, "invalid id"); } if (item->running) { @@ -2132,10 +2136,11 @@ int NetAdhocMatching_CancelTargetWithOpt(int matchingId, const char* macAddress, SceNetAdhocMatchingMemberInternal* peer = findPeer(context, (SceNetEtherAddr*)target); if (peer == NULL) { - // Peer not found - //return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_UNKNOWN_TARGET, "adhocmatching unknown target"); - // Faking success to prevent the game (ie. Soul Calibur) to repeatedly calling this function when the other player is disconnected - return hleLogDebug(Log::sceNet, 0); + // Soulcalibur: Broken Destiny calls this over and over when the other player has gone, unless it succeeds. + if (PSP_CoreParameter().compat.flags().MatchingCancelUnknownTargetSucceeds) { + return hleLogDebug(Log::sceNet, 0, "faking success"); + } + return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_UNKNOWN_TARGET, "adhocmatching unknown target"); } // Valid Peer Mode diff --git a/assets/compat.ini b/assets/compat.ini index 67f4143157..13ec14f43d 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -2276,3 +2276,23 @@ POPS00000 = true # are moved back half a pixel, which draws the same at 1x. Above 1x they otherwise cover half a pixel more # and read their neighbours' texels: seams between tiles. The PS1 emulator draws its sprites like that. POPS00000 = true + +[MatchingCancelUnknownTargetSucceeds] +# sceNetAdhocMatchingCancelTarget(WithOpt) on a MAC that isn't a peer succeeds instead of failing with +# UNKNOWN_TARGET, as the PSP does. Soulcalibur: Broken Destiny calls it over and over once the other +# player has gone, unless it succeeds. +ULUS10457 = true +ULES01298 = true +ULJS00202 = true + +[MatchingStartUnknownIdSucceeds] +# sceNetAdhocMatchingStart on a context ID that doesn't exist succeeds instead of failing with INVALID_ID, +# as the PSP does. GTA: Vice City Stories gets stuck unable to choose host or join otherwise. +ULUS10160 = true +ULES00502 = true +ULES00503 = true +ULJM05297 = true +ULJM05395 = true +ULJM05884 = true +NPJH50827 = true +ULET00417 = true