Commit Graph
498 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 a8a63fa11d sceNetAdhoc: Start socket IDs over at 1 after sceNetAdhocTerm
A PSP hands out socket IDs from 1 again after sceNetAdhocTerm and
sceNetAdhocInit (net/adhoc/socketids, recorded on a PSP). We kept
counting up. Pangya: Fantasy Golf tears down the network between its
room and the round, and then keeps using socket 1 without looking at
what PdpCreate returned, so every send and receive failed with
INVALID_SOCKET_ID and each player saw the other as "Off-line".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:35 +01:00
Henrik RydgårdandClaude Opus 5.5 0d686c1a95 sceNetAdhocGameMode: Send the master every period, changed or not
A PSP sends its master every 12 ms after the initial sync, and a peer's
replica reports each one as an update. PPSSPP only sent a master that
had changed, so a replica polled until updated waited for the next
change. Also take every packet waiting each period, not one: every
member sends each period. Measured in pspautotests
net/adhoc/pair/gamemodesync.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:14 +01:00
Henrik RydgårdandClaude Opus 5.5 478d10ff19 sceNetAdhoc: A PTP connection only gives up with data outstanding
When the peer has left, a PSP drops the connection once data sent to it
has gone unacknowledged for (rexmt_cnt + 1) * rexmt_int. A connection
that only receives never fails. Count from the first data the peer
couldn't acknowledge: sent after it left, or within 10 ms before
(pspautotests net/adhoc/pair/vanishtiming).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:14 +01:00
Henrik RydgårdandClaude Opus 5.5 8bb1f8462f sceNetAdhoc: A PTP connection is established as soon as it's up
GetPtpStat only looked at a connection in progress 33 ms after the last
connect attempt, and PollSocket reported CONNECT 1 ms after it whether
the connection was up or not. On a PSP both show it the moment it's up,
about 5 ms after the connect (pspautotests net/adhoc/pair/ptpconnect).
The old timings were tuned for GvG Next Plus, Bleach and Fate; Fate's
network match still works.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:14 +01:00
Henrik RydgårdandClaude Opus 5.5 3c9c01048a sceNetAdhocctl: Time GAMEMODE and leaving game mode as a PSP does
GAMEMODE comes 4.38 s after CreateEnterGameMode, or 1.35 s after
JoinEnterGameMode or the last member's arrival, whichever is later,
instead of a fixed 2 s after the last member (plus 60 ms for a member,
a workaround for Pocket Pool). DISCONNECT comes 650 ms after
ExitGameMode. Measured in pspautotests net/adhoc/pair/gamemodetiming.

A member that joins early still gets GAMEMODE before the host: it
doesn't know when the host entered game mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:14 +01:00
Henrik RydgårdandClaude Opus 5.5 08c76b8b25 sceNetAdhocGameMode: Create master and replicas as a PSP does
pspautotests net/adhoc/pair/gamemode:
- CreateMaster with size 0 fails with INVALID_DATALEN.
- CreateReplica for a MAC that isn't in the game mode group fails with
  0x80410D13. PPSSPP made one, and then blocked the thread forever
  waiting to sync with it.
- CreateReplica for the same MAC again gives ALREADY_CREATED. The check
  compared the pointer instead of the MAC, so it never matched.
- A replica's ID is the member's place in the member list, host first:
  the client's replica of the host is 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:14 +01:00
Henrik RydgårdandClaude Opus 5.5 60a49ccfd2 Ad hoc: Use the PSP's measured times instead of guessed ones
Where pspautotests net/adhoc/timing or net/adhoc/pair/timing measured
a value, use it:

- Call costs: PdpSend 21 us (10 broadcast), PtpSend 122, PtpFlush 196,
  GetPdpStat 1, GetPtpStat 2, PollSocket 18, GetScanInfo 2, GetPeerList
  and MatchingGetMembers 4 (no longer a 100 us reschedule),
  MatchingStart 416 instead of 30 ms, sceNetAdhocctlTerm 154,
  sceNetAdhocTerm 10 and sceNetTerm 209 instead of 10 ms each,
  GameModeUpdateMaster 80, UpdateReplica 9.
- Game mode data goes out every 12 ms, not every 0.5 ms.
- DISCONNECT comes 640 ms after ExitGameMode, not 105 ms.
- CONNECT after a Join no longer waits for a peer: a PSP delivers it
  before the host shows up in the peer list.

Several of the old values were tuned for particular games (BattleZone's
frame rate, Fate Unlimited Codes and Bleach through PollSocket), and
may have been making up for other differences that are fixed now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:13 +01:00
Henrik RydgårdandClaude Opus 5.5 f449129dec sceNetAdhoc: Time a vanished peer's timeouts as a PSP does
A PSP checks a PTP connection's oldest unacknowledged data every
rexmt_int, counting from when the connection was established, and drops
the connection at the first check where that data is older than
(rexmt_cnt + 1) * rexmt_int. A matching peer times out keepalive_int *
init_count after its last keepalive, checked all the time instead of on
the console's own keepalive tick, which could add up to an interval.
Both measured with several settings in pspautotests
net/adhoc/pair/vanishtiming; DATA_TIMEOUT already matched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 ee86058ec7 sceNetAdhocctl: Leave the console out of its own peer lookups; give groups their own BSSID
From the basic and lifecycle pair tests, recorded on two PSPs:

- GetNameByAddr for the console's own MAC gives NO_ENTRY, and
  GetAddrByName doesn't find the console itself.
- GetPeerInfo with a size too small for the entry gives INVALID_BUFLEN.
- A PTP connection accepted over the relay reports the peer's port as
  the game sees it, not the relay's offset port.
- The built-in server makes up a locally administered BSSID for each
  group, which stays when the creator leaves. It was the MAC of the
  oldest member.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 4197f2326a sceNetAdhoc: A console that leaves the network goes quiet, as on a PSP
The vanish pair test (recorded on two PSPs) now passes on both sides,
over the relay:

- From the Disconnect call, a console's PDP and PTP sends succeed and go
  nowhere, and nothing reaches it.
- A PTP connection to a peer that has left the group fails with
  DISCONNECTED after rexmt_int * rexmt_cnt. Relay sockets now get their
  retry settings (and are zeroed), and an accepted one counts as
  connected.
- Matching data to a peer that has left gets DATA_TIMEOUT after the
  retransmissions instead of a DATA_ACK.
- The matching timeout for a silent peer is keepalive_int * init_count,
  plus MATCHING_TIMEOUT_EXTRA_US (0) to tune for internet latency. It
  was (keepalive + rexmt) * count + 500ms, later than a PSP's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 fa51700d58 sceNetAdhocctl: Fail entering game mode the way a PSP does
On a PSP (pspautotests net/adhoc/gamemode):
- a JoinEnterGameMode whose host never shows up gets ERROR with TIMEOUT
  when its timeout runs out, and is out of the group afterwards. The
  joiner's GAMEMODE, queued as soon as the server answered and held
  until the host appeared, came after 5 s anyway;
- a CreateEnterGameMode whose first member isn't this console returns
  0 and reports INVALID_ADDR;
- in a normal group, CreateEnterGameMode reports ALREADY_CONNECTED and
  stays in the group, and ExitGameMode returns INVALID_IBSS;
- ExitGameMode outside game mode returns 0 with no event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 1e3e9c7251 sceNetAdhocctl: Send Create, Connect and Scan without the 10 ms wait
On a PSP they return within about 30 µs (pspautotests net/adhoc/timing).
They waited 10 ms before trying to send the request; now the first try is
right away, and the call returns once it's sent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 a2897c5b65 sceNetAdhocctl: Deliver CONNECT, SCAN and DISCONNECT at the PSP's times
A PSP delivers CONNECT 1.1 s after a Create, 0.53 s after a Join and
3.5-4 s after a Connect (which looks for the group first), SCAN 1.0 s
after a Scan and DISCONNECT 105 ms after a Disconnect, and the state
changes along with the event (pspautotests net/adhoc/timing and
net/adhoc/pair/timing). Deliver them then, counting from the request in
emulated time, or later if the server's answer takes longer. This
replaces the delays tuned for Dissidia 012, GTA: VCS and Tekken 5, and
Disconnect no longer blocks for 16.7 ms (Tekken 6): it returns at once,
as on a PSP.

Since the state now changes later, a Disconnect can come while a Create
is still pending. Keep track of whether the server has us in a group, so
the Disconnect still reaches it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 5021e3ccc1 sceNetAdhocctlInit: Don't wait for the login to the server
On a PSP, Init returns at once and a Create, Connect or Scan right after
it works (pspautotests net/adhoc/ctlinit). The login now runs on in the
background, and those requests wait for it, as they already did when it
was lost. The first login no longer resets the busy flag, which would
have cleared it for a request already waiting on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 a276f00dd0 proAdhoc: Run the adhocctl client from a CoreTiming event
The friendFinder thread is replaced by friendFinderPoll(), which a
CoreTiming event calls every millisecond of emulated time on the CPU
thread. It handles everything the server has sent since the last poll,
instead of one event every 10 ms, and pings it at the same real-time
interval. Resolving the server and logging in, which can take seconds,
run on a thread of their own; the poll starts it and takes over the
session when it's done.

Everything else about the client is unchanged, including sceNetAdhocctlInit
waiting for the login. The savestate section goes to version 11 for the
poll event; older states get it scheduled on load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 db7c9ede34 sceNetAdhocctlGetPeerInfo: NO_ENTRY for the local MAC
The console itself isn't in its peer list, and a PSP returns NO_ENTRY
for it (pspautotests net/adhoc/adhocctl).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 874080ced2 sceNetAdhocDiscover: Go through the states a PSP goes through
With nobody to find (pspautotests net/adhoc/discover): InitStart leaves
the result field alone and fails with 0x80411301 while running,
adhocctl enters the DISCOVER state after the first Update, and after a
Stop adhocctl goes back to DISCONNECTED with a DISCONNECT event, then
the status becomes COMPLETED with the result cancelled. RequestSuspend
while discovering fails with 0x80411303 instead of cancelling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 48c9bf9988 sceNetAdhocPdpRecv: Don't copy a datagram that doesn't fit
With a buffer smaller than the next datagram, a PSP returns
NOT_ENOUGH_SPACE with the datagram's size, copies nothing, and keeps
the datagram for the next call (pspautotests net/adhoc/pdp). The first
bytes were copied into the buffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 d9ac972915 sceNetAdhocPtpSend, PtpRecv: DISCONNECTED once the peer has gone
After a Recv has found the peer gone, a PSP keeps returning
DISCONNECTED for Send and Recv on that socket, not NOT_CONNECTED
(pspautotests net/adhoc/ptp).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 1649bd2072 sceNetAdhocPtpOpen: Accept the broadcast address as the destination
A PSP creates the socket (pspautotests net/adhoc/ptp); connecting it
just never succeeds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 dc450f79b3 sceNetAdhoc: Hand out socket IDs in increasing order, like the PSP
A PSP numbers adhoc sockets in increasing order instead of reusing the
lowest free ID, and a PDP or PTP create that fails its address or port
check, or finds the PDP port in use, uses up an ID too (pspautotests
net/adhoc/pdp and net/adhoc/ptp). Find free slots starting after the last
one handed out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 97b18b95bb sceNetAdhocPollSocket: Report what a PSP reports
On a PSP (pspautotests net/adhoc/poll):
- a PTP listener reports SEND and FLUSH, and ACCEPT with a connection
  waiting;
- a connected PTP socket reports SEND, CONNECT and FLUSH, and RECV with
  data waiting;
- a connection whose peer has closed reports DISCONNECT alone, and the
  call returns EXCEPTION_EVENT;
- an unknown ID puts INVALID in the first entry;
- a blocking poll with nothing to report by its timeout returns TIMEOUT,
  and one that hits a disconnected socket or the poll alert returns at
  once.

A connection PtpOpen started counts as connected once it's up. Sockets
still connecting keep PPSSPP's own events (Fate Unlimited Codes,
Bleach), and a refused connect still isn't reported, since PPSSPP keeps
retrying it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 0d089972a3 sceNetAdhoc: Socket alerts don't stop calls that can complete at once
On a PSP (pspautotests net/adhoc/alerts), PtpConnect on a connected
socket and PtpFlush with nothing left to send return 0 with their alerts
set, and the poll alert reports ALERT alone in revents. A connection
PtpOpen started counts as connected once it's up, even if no call has
looked at it since.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 7e44dc7e8d sceNetAdhocPdpCreate: Give port 0 a port in 0x1000-0x7FFF
On a PSP, a PDP socket created on port 0 gets a free port between
0x1000 and 0x7FFF (pspautotests net/adhoc/limits). The host picked
one instead, usually 0x8000 or above once the port offset was taken
off. Pick it the way PtpOpen already does for PTP, and try another if
the host port is taken. Port 0 still doesn't become the fixed port the
offset alone would give (Phantasy Star Portable 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:05 +01:00
Henrik RydgårdandClaude Opus 5.5 b40c427807 Built-in relay: Pump every millisecond
Every message through the relay waited for the next pump, every 8 ms,
or 100 ms while nobody was connected, which is when a game's first
connection comes in. That was most of what a round trip took once the
emulators stopped running in frame bursts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:33:14 +01:00
Henrik RydgårdandClaude Opus 5.5 fc9a3d3a39 sceNetAdhoc: Give the built-in relay the port its client connects to
aemu_postoffice's default happens to match, but nothing tied the two.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:48:47 +01:00
Henrik RydgårdandClaude Opus 5.5 5e92e0e02a sceNetAdhoc: Fix the built-in relay's thread
Join the old relay thread before starting a new one (assigning to a
joinable std::thread terminates), don't map the UPnP port when another
relay already has it, sleep the intended interval (the elapsed time was
subtracted the wrong way round), use one worker per pool, and guard the
log helper against empty messages. Drop the warning that the built-in
server doesn't support relay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:56:56 +01:00
Katharine Chui 92b00eb28a fix code formatting 2026-10-28 13:56:56 +01:00
Katharine Chui 7af6661cf0 add upnp call around relay server loop 2026-10-28 13:56:56 +01:00
Katharine Chui c8a9ed025a start aemu_postoffice relay with built-in adhoc server 2026-10-28 13:56:56 +01:00
Henrik RydgårdandClaude Opus 5.5 e0a6a662f4 sceNet, sceNetAdhoc: Cite the tests for behaviour that's the PSP's
Several comments called PSP behaviour a workaround for one game: PDP
send and receive returning 0 and writing the length back, Scan while
connected reporting ALREADY_CONNECTED, PtpOpen connecting by itself,
connecting a connected socket returning 0, PtpAccept's optional peer
address and port, the malloc stat's pool size, and matching dropping
hellos from a host mid-join. The pspautotests recorded on PSPs show the
PSP does all of these, so say that, and keep the games as examples.

Also bumps pspautotests for the new adhocctl Disconnect events and the
pair/matching3 test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:52:55 +01:00
Henrik RydgårdandClaude Opus 5.5 58d73cbbc6 sceNetAdhoc, adhocctl: Check arguments like the PSP
From the net/adhoc pspautotests (pdp, ptp, poll, limits, adhocctl,
gamemode), recorded on PSPs:

- PDP and PTP: NULL pointers and nonzero flags give INVALID_ARG, before
  the socket ID is checked. Zero and multicast addresses give
  INVALID_ADDR, ports 0 and 65535 INVALID_PORT, and send lengths over
  65523 or NULL data INVALID_DATALEN. A length of 0 sends nothing and
  succeeds. Zero buffer sizes, retransmit settings and backlogs are
  accepted. PdpRecv takes a NULL sender address or port. Running out of
  socket IDs gives SOCKET_ID_NOT_AVAIL, and out-of-range IDs on
  delete/close INVALID_SOCKET_ID. PollSocket rejects flags other than
  NONBLOCK.
- adhocctl: Init checks its stack size, priority and ad hoc ID;
  AddHandler needs Init, allows the same function twice and takes at most
  4 handlers; DelHandler on an unknown ID gives ID_NOT_FOUND; bad group
  names give adhocctl's INVALID_ARG; GetParameter and GetPeerList fail
  outside a group.
- Game mode: a NULL group name and a bad minimum are rejected,
  GetGameModeInfo fails outside game mode, and the entry timeout reports
  adhocctl's TIMEOUT.

The DBZ Shin Budokai 2 workaround that replaces the game's local MAC with
ours stays, so another console's MAC is still accepted when creating a
socket.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:52:22 +01:00
Henrik RydgårdandClaude Opus 5.5 a4fe8e8f17 sceNetAdhoc: Don't fault on NULL pointers the PSP accepts
sceNetAdhocPdpSend with NULL data and a length of 0, sceNetAdhocPdpRecv
with a NULL sender MAC or port, and sceNetAdhocPtpSend with a NULL length
pointer all raised a memory exception before the call ran, which stopped
the game. On a PSP the first two succeed and the last returns INVALID_ARG
(net/adhoc/pdp and net/adhoc/ptp in pspautotests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Katharine Chui 262416ad90 fix adhocctl regression by restoring wrongly removed logic
- 23efd22efb : Fix Stuck issue on some games (Dissidia 012, Full Auto 2, etc) when Failed to connect to Adhoc Server (faked success)
- 7ec860c24f : Adhoc: Stop waiting for a login that has already failed
2026-10-27 15:02:04 +01:00
Katharine Chui 07190a820d adhoc load state bring up adhoc before adhocctl and bring down adhoc after adhocctl 2026-10-21 18:13:40 +02:00
Katharine Chui c086eab2ed spin down aemu_postoffice during netAdhocInited -> !netAdhocInited load state transition 2026-10-21 16:22:57 +02:00
Katharine Chui 23dadb11bf fix savestate enet thread handling again 2026-10-21 15:39:32 +02:00
Katharine Chui 8474ca35b6 guard built-in server warnings with isLocalServer 2026-10-21 14:29:16 +02:00
Katharine Chui 3662d69fb0 restore port offset hint on udp bind failure 2026-10-21 14:19:55 +02:00
Katharine Chui b8297795ef fix relay + built-in server warning reading stale serverHasRelay 2026-10-21 14:19:55 +02:00
Katharine Chui 3c35584f47 join aemuPostofficeEnetThread if active during load state 2026-10-21 14:19:55 +02:00
Katharine Chui 880158cfdb initial enet mode for adhocctl & aemu_postoffice relay 2026-10-21 14:19:54 +02:00
Henrik RydgårdandClaude Opus 5.5 7dd1475ed7 HLE: Pass the MIPSState to syscalls and their implementations
HLEFunc and ReplaceFunc now take the MIPSState they run on. The dispatch
paths (both interpreters and every JIT backend) pass in the state they
belong to, and CallSyscall*, hleFinishSyscall and the HLE mips call
machinery use it instead of currentMIPS.

The wrappers in FunctionWrappers.h take the function as `auto` and call it
through HLECall, which also accepts an implementation with an extra leading
MIPSState * parameter and passes the state to it. Any other signature still
fails to compile, as before. PARAM/RETURN now refer to a local `mips`.

The HLE functions (and replacement functions) that used currentMIPS now take
the state that way. Callers outside a syscall's own frame - CoreTiming
events, the adhoc matching thread, dialogs, PPGe, the debugger UIs - pass
currentMIPS or &mipsr4k explicitly. The kernel's thread internals still use
currentMIPS.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 15:45:14 +02:00
Henrik RydgårdandClaude Opus 5.5 16a03f16e8 Adhoc: Restore the inited flags from savestates
Loading a savestate kept the current session's netAdhocInited,
netAdhocctlInited and matching-inited flags rather than the saved ones.
Loaded into a fresh boot, a state saved with adhocctl initialized (but not
connected) then failed every adhocctl call with NOT_INITIALIZED. MGS Peace
Walker shuts ad hoc down before a cutscene and retried
sceNetAdhocctlDisconnect forever, leaving the screen black.

Take the flags from the state, and bring the host side in line: start the
friendFinder and log in again when the state has adhocctl up and we don't,
stop it in the opposite case. Also save the product code, which that login
sends.

Also add a game.state.save debugger command, used to reproduce this.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 09:15:51 +02:00
Henrik RydgårdandClaude Opus 5.5 19e4b77be4 Android: Ask for the local network permission for ad hoc, UPnP and servers
Part of #21585

Android 17 blocks LAN traffic in both directions (TCP and UDP, including
broadcast and multicast) without ACCESS_LOCAL_NETWORK. Ask for it when
networking, the built-in ad hoc server, UPnP, share-on-startup or the
remote debugger gets turned on, when a game initializes ad hoc with
networking enabled, and at startup if a server is set to start then.

A denied ad hoc send fails with EPERM, which the games never see, so show
a message for it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 20:44:05 +02:00
Henrik RydgårdandClaude Opus 5.5 7ec860c24f Adhoc: Stop waiting for a login that has already failed
sceNetAdhocctlInit waits until the friend finder has logged into the adhoc
server, polling in emulated time but giving up only after 5s of wall time.
The friend finder makes one attempt per login request, and it too waited
the full 5s on a connection that had already been refused, because it
only looked for success. Now it checks the socket error and gives up at
once, and records the failure so the wait ends with it.

In headless, which runs far ahead of real time, Gods Eater Burst sat in
this wait for its whole run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 12:37:48 -06:00
Henrik RydgårdandClaude Opus 5.5 2cd84012d0 Adhoc: Fix shutdown hanging when it comes right after adhoc init
The friend finder thread set friendFinderRunning itself, after a DNS
lookup of the adhoc server. A shutdown in that window cleared the flag
first; the thread then set it again, looped forever, and the join in
NetAdhocctl_Term() never returned. Gods Eater Burst hit this in about one
headless run in six. The flag is now set before the thread is created,
and a finished thread is joined before a new one replaces it, which
would otherwise call std::terminate.

The built-in adhoc server thread had the same race, behind its check for
an existing server, and gets the same fix.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:58:42 -06:00
Henrik RydgårdandClaude Opus 5.5 639e57c2bd Savestate: Keep pending adhocctl requests, so a waiting Init survives a load
With WLAN on and no server reachable, sceNetAdhocctlInit keeps its thread
waiting for the login. The load dropped the request, and the wait ended in
BUSY, which Init can't retry. Splinter Cell then ran its failure path with
a deleted event flag. Also stop freeing matching event buffers into the
restored allocator, and take the event lock when clearing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 09:34:06 -06:00
Henrik Rydgård 11c6111027 Only show the relay mode notification if networking is enabled 2026-09-19 13:02:44 -06:00
Henrik Rydgård c5e4d0d90d Rename the get-memory-pointer functions to make it clear where CPU exceptions can happen. 2026-08-12 14:06:16 +02:00