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:
@@ -1564,7 +1564,31 @@ void Minecraft::run_middle()
|
||||
// 4J Stu - This doesn't make any sense with the way we handle XboxOne users
|
||||
#ifndef _DURANGO
|
||||
// did we just get input from a player who doesn't exist? They'll be wanting to join the game then
|
||||
#ifdef _WINDOWS64
|
||||
// The 4J toggle system is unreliable here: UIController::handleInput() calls
|
||||
// ButtonPressed for every ACTION_MENU_* mapped button (which covers all physical
|
||||
// buttons) before run_middle() runs. Bypass it with raw XInput and own edge detection.
|
||||
// A latch counter keeps startJustPressed active for ~120 frames after the rising edge
|
||||
// so the detection window is large enough to be caught reliably.
|
||||
static WORD s_prevXButtons[XUSER_MAX_COUNT] = {};
|
||||
static int s_startPressLatch[XUSER_MAX_COUNT] = {};
|
||||
XINPUT_STATE xstate_join;
|
||||
memset(&xstate_join, 0, sizeof(xstate_join));
|
||||
WORD xCurButtons = 0;
|
||||
if (XInputGetState(i, &xstate_join) == ERROR_SUCCESS)
|
||||
{
|
||||
xCurButtons = xstate_join.Gamepad.wButtons;
|
||||
if ((xCurButtons & XINPUT_GAMEPAD_START) != 0 && (s_prevXButtons[i] & XINPUT_GAMEPAD_START) == 0)
|
||||
s_startPressLatch[i] = 120; // rising edge: latch for ~120 frames (~2s at 60fps)
|
||||
else if (s_startPressLatch[i] > 0)
|
||||
s_startPressLatch[i]--;
|
||||
s_prevXButtons[i] = xCurButtons;
|
||||
}
|
||||
bool startJustPressed = s_startPressLatch[i] > 0;
|
||||
bool tryJoin = !pause && !ui.IsIgnorePlayerJoinMenuDisplayed(ProfileManager.GetPrimaryPad()) && g_NetworkManager.SessionHasSpace() && xCurButtons != 0;
|
||||
#else
|
||||
bool tryJoin = !pause && !ui.IsIgnorePlayerJoinMenuDisplayed(ProfileManager.GetPrimaryPad()) && g_NetworkManager.SessionHasSpace() && RenderManager.IsHiDef() && InputManager.ButtonPressed(i);
|
||||
#endif
|
||||
#ifdef __ORBIS__
|
||||
// Check for remote play
|
||||
tryJoin = tryJoin && InputManager.IsLocalMultiplayerAvailable();
|
||||
@@ -1592,6 +1616,8 @@ void Minecraft::run_middle()
|
||||
// did we just get input from a player who doesn't exist? They'll be wanting to join the game then
|
||||
#ifdef __ORBIS__
|
||||
if(InputManager.ButtonPressed(i, ACTION_MENU_A))
|
||||
#elif defined _WINDOWS64
|
||||
if(startJustPressed)
|
||||
#else
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_PAUSEMENU))
|
||||
#endif
|
||||
@@ -1599,7 +1625,11 @@ void Minecraft::run_middle()
|
||||
// Let them join
|
||||
|
||||
// are they signed in?
|
||||
#ifdef _WINDOWS64
|
||||
if(ProfileManager.IsSignedIn(i) || (g_NetworkManager.IsLocalGame() && InputManager.IsPadConnected(i)))
|
||||
#else
|
||||
if(ProfileManager.IsSignedIn(i))
|
||||
#endif
|
||||
{
|
||||
// if this is a local game, then the player just needs to be signed in
|
||||
if( g_NetworkManager.IsLocalGame() || (ProfileManager.IsSignedInLive(i) && ProfileManager.AllowedToPlayMultiplayer(i) ) )
|
||||
|
||||
Reference in New Issue
Block a user