feat: Windows64 local multiplayer support (#13)

- Skip QuadrantSignin (profile selector) on Windows64 in both LoadMenu
  and CreateWorldMenu, proceeding directly to local play since Xbox Live
  stubs always return true for IsSignedInLive()
- Fix IsLocalMultiplayerAvailable() to not require IsHiDef() on Windows64
- Allow pad-connected players to join without a profile sign-in check
- Fix ghost RemotePlayer creation by scanning all local player slots and
  matching on server-assigned player index rather than controller slot,
  fixing P3/P4 ghost entities when joining out of controller order
- Give each player a unique name (Player 1-4) based on controller index
  instead of a single shared stub name
- Use raw XInput (XInputGetState) for secondary controller join detection,
  bypassing the 4J toggle system which consumes all button presses before
  game logic runs; uses a 120-frame latch for a reliable detection window
- Add .gitignore for Visual Studio build artifacts and output directories
This commit is contained in:
Sean Hoyt
2026-03-01 10:50:48 -06:00
committed by GitHub
parent d5707899db
commit b5111232aa
7 changed files with 95 additions and 5 deletions

View File

@@ -723,7 +723,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
// Some remote players could actually be local players that are already added
for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
// need to use the XUID here
// need to use the XUID here
PlayerUID playerXUIDOnline = INVALID_XUID, playerXUIDOffline = INVALID_XUID;
ProfileManager.GetXUID(idx,&playerXUIDOnline,true);
ProfileManager.GetXUID(idx,&playerXUIDOffline,false);
@@ -734,6 +734,21 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
return;
}
}
#ifdef _WINDOWS64
// On Windows64 all XUIDs are INVALID_XUID so the XUID check above never fires.
// packet->m_playerIndex is the server-assigned sequential index (set via LoginPacket),
// NOT the controller slot — so we must scan all local player slots and match by
// their stored server index rather than using it directly as an array subscript.
for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
if(minecraft->localplayers[idx] != NULL &&
minecraft->localplayers[idx]->getPlayerIndex() == packet->m_playerIndex)
{
app.DebugPrintf("AddPlayerPacket received for local player (controller %d, server index %d), skipping RemotePlayer creation\n", idx, packet->m_playerIndex);
return;
}
}
#endif
double x = packet->x / 32.0;
double y = packet->y / 32.0;