From b5111232aa13952f58ed1b3b3525ea825662b95c Mon Sep 17 00:00:00 2001 From: Sean Hoyt Date: Sun, 1 Mar 2026 10:50:48 -0600 Subject: 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 --- Minecraft.Client/Extrax64Stubs.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'Minecraft.Client/Extrax64Stubs.cpp') diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 334f0123..f6ad76c1 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -197,7 +197,15 @@ bool IQNetPlayer::IsHost() { return this == &IQNet::m_player[0]; } bool IQNetPlayer::IsGuest() { return false; } bool IQNetPlayer::IsLocal() { return true; } PlayerUID IQNetPlayer::GetXuid() { return INVALID_XUID; } -LPCWSTR IQNetPlayer::GetGamertag() { static const wchar_t *test = L"stub"; return test; } +LPCWSTR IQNetPlayer::GetGamertag() +{ + static wchar_t tags[4][16]; + int idx = GetUserIndex(); + if(idx < 0 || idx >= 4) idx = 0; + mbstowcs(tags[idx], ProfileManager.GetGamertag(idx), 15); + tags[idx][15] = L'\0'; + return tags[idx]; +} int IQNetPlayer::GetSessionIndex() { return 0; } bool IQNetPlayer::IsTalking() { return false; } bool IQNetPlayer::IsMutedByLocalUser(DWORD dwUserIndex) { return false; } @@ -487,8 +495,22 @@ char fakeGamerTag[32] = "PlayerName"; void SetFakeGamertag(char *name){ strcpy_s(fakeGamerTag, name); } char* C_4JProfile::GetGamertag(int iPad){ return fakeGamerTag; } #else -char* C_4JProfile::GetGamertag(int iPad){ return "PlayerName"; } -wstring C_4JProfile::GetDisplayName(int iPad){ return L"PlayerName"; } +char* C_4JProfile::GetGamertag(int iPad) +{ + static char tags[4][16] = { "Player 1", "Player 2", "Player 3", "Player 4" }; + if(iPad >= 0 && iPad < 4) return tags[iPad]; + return tags[0]; +} +wstring C_4JProfile::GetDisplayName(int iPad) +{ + switch(iPad) + { + case 1: return L"Player 2"; + case 2: return L"Player 3"; + case 3: return L"Player 4"; + default: return L"Player 1"; + } +} #endif bool C_4JProfile::IsFullVersion() { return s_bProfileIsFullVersion; } void C_4JProfile::SetSignInChangeCallback(void ( *Func)(LPVOID, bool, unsigned int),LPVOID lpParam) {} -- cgit v1.2.3