diff --git a/neo/framework/Session.cpp b/neo/framework/Session.cpp index 609c178e..837f7f52 100644 --- a/neo/framework/Session.cpp +++ b/neo/framework/Session.cpp @@ -1447,6 +1447,9 @@ void idSessionLocal::UnloadMap() { } mapSpawned = false; + + // DG: that state needs to be reset now + Sys_SetInteractiveIngameGuiActive( false, NULL ); } /* diff --git a/neo/framework/UsercmdGen.cpp b/neo/framework/UsercmdGen.cpp index b212223f..a64a4984 100644 --- a/neo/framework/UsercmdGen.cpp +++ b/neo/framework/UsercmdGen.cpp @@ -890,12 +890,15 @@ static float joyAxisToMouseDelta(float axis, float deadzone) return ret; } +extern bool D3_IN_interactiveIngameGuiActive; // from sys/events.cpp void idUsercmdGenLocal::JoystickFakeMouse(float axis_x, float axis_y, float deadzone) { - float x = joyAxisToMouseDelta(axis_x, deadzone); - float y = joyAxisToMouseDelta(axis_y, deadzone); - continuousMouseX += x; - continuousMouseY += y; + if ( D3_IN_interactiveIngameGuiActive ) { + float x = joyAxisToMouseDelta(axis_x, deadzone); + float y = joyAxisToMouseDelta(axis_y, deadzone); + continuousMouseX += x; + continuousMouseY += y; + } } /* diff --git a/neo/framework/UsercmdGen.h b/neo/framework/UsercmdGen.h index 17e88fe8..c9e9ecae 100644 --- a/neo/framework/UsercmdGen.h +++ b/neo/framework/UsercmdGen.h @@ -96,8 +96,8 @@ public: signed char rightmove; // left/right movement signed char upmove; // up/down movement short angles[3]; // view angles - short mx; // mouse delta x - short my; // mouse delta y + short mx; // mouse delta x - DG: not really delta, but from continuousMouseX which accumulates + short my; // mouse delta y - DG: same but from continuousMouseY signed char impulse; // impulse command byte flags; // additional flags int sequence; // just for debugging diff --git a/neo/sys/events.cpp b/neo/sys/events.cpp index 986e9400..8d7fffca 100644 --- a/neo/sys/events.cpp +++ b/neo/sys/events.cpp @@ -899,7 +899,7 @@ void Sys_GrabMouseCursor(bool grabIt) { GLimp_GrabInput(flags); } -static bool interactiveGuiActive = false; + /* =============== Sys_SetInteractiveIngameGuiActive @@ -910,12 +910,42 @@ left mouse button in that case, so "clicking" with gamepad in the PDA (and ingame GUIs) works as expected. Not set for proper menus like main menu etc - the gamepad hacks for that are in idUserInterfaceLocal::HandleEvent(). +Call with ui = NULL to clear the state. I hope this won't explode in my face :-p =============== - */ -void Sys_SetInteractiveIngameGuiActive(bool active) +*/ +bool D3_IN_interactiveIngameGuiActive = false; +void Sys_SetInteractiveIngameGuiActive( bool active, idUserInterface* ui ) { - interactiveGuiActive = active; + static idList lastuis; + if ( ui == NULL ) { + // special case for clearing + D3_IN_interactiveIngameGuiActive = false; + lastuis.Clear(); + return; + } + int idx = lastuis.FindIndex( ui ); + + if ( sessLocal.GetActiveMenu() == NULL && active ) { + // add ui to lastuis, if it has been activated and no proper menu + // (like main menu) is currently open + lastuis.Append( ui ); + } else if ( idx != -1 ) { + // if the UI is in lastuis and has been deactivated, or there + // is a proper menu opened, remove it from the list. + // this both handles the regular deactivate case and also works around + // main-menu-in-multiplayer weirdness: that menu calls idUserInterface::Activate() + // with activate = true twice, but on first call sessLocal.GetActiveMenu() is NULL + // so we want to remove it once we realize that it really is a "proper" menu after all. + // And because it's possible that we have an ingame UI focussed while opening + // the multiplayer-main-menu, we keep a list of lastuis, instead of just one, + // so D3_IN_interactiveIngameGuiActive remains true in that case + // (the ingame UI is still in the list) + + lastuis.RemoveIndex( idx ); + } + + D3_IN_interactiveIngameGuiActive = lastuis.Num() != 0; } @@ -1247,7 +1277,7 @@ sysEvent_t Sys_GetEvent() { if ( ev.cbutton.button == SDL_CONTROLLER_BUTTON_START ) { res.evValue = K_ESCAPE; return res; - } else if( ev.cbutton.button == SDL_CONTROLLER_BUTTON_A && interactiveGuiActive && sessLocal.GetActiveMenu() == NULL ) { + } else if( ev.cbutton.button == SDL_CONTROLLER_BUTTON_A && D3_IN_interactiveIngameGuiActive && sessLocal.GetActiveMenu() == NULL ) { // ugly hack: currently an interactive ingame GUI (with a cursor) is active/focused // so pretend that the gamepads A (south) button is the left mouse button // so it can be used for "clicking".. diff --git a/neo/sys/sys_public.h b/neo/sys/sys_public.h index e20ab923..9c32f9f9 100644 --- a/neo/sys/sys_public.h +++ b/neo/sys/sys_public.h @@ -251,7 +251,8 @@ void Sys_GrabMouseCursor( bool grabIt ); // DG: added this for an ungodly hack for gamepad support // active = true means "currently a GUI with a cursor is active/focused" // active = false means "that GUI is not active anymore" -void Sys_SetInteractiveIngameGuiActive(bool active); +class idUserInterface; +void Sys_SetInteractiveIngameGuiActive( bool active, idUserInterface* ui ); void Sys_ShowWindow( bool show ); bool Sys_IsWindowVisible( void ); diff --git a/neo/ui/UserInterface.cpp b/neo/ui/UserInterface.cpp index c8b3e167..58379b87 100644 --- a/neo/ui/UserInterface.cpp +++ b/neo/ui/UserInterface.cpp @@ -118,6 +118,9 @@ void idUserInterfaceManagerLocal::EndLevelLoad() { } } } + + // DG: this should probably be reset at this point + Sys_SetInteractiveIngameGuiActive( false, NULL ); } void idUserInterfaceManagerLocal::Reload( bool all ) { @@ -582,11 +585,10 @@ const char *idUserInterfaceLocal::Activate(bool activate, int _time) { time = _time; active = activate; if ( desktop ) { - // FIXME: this works ok, mostly, except in multiplayer, where this function - // is called twice with activate=true, and the first time GetActiveMenu() returns NULL, the second time not - if(interactive && sessLocal.GetActiveMenu() == NULL) { - Sys_SetInteractiveIngameGuiActive(activate); - } + // DG: added this hack for gamepad input + if ( interactive ) { + Sys_SetInteractiveIngameGuiActive( activate, this ); + } // DG end activateStr = ""; desktop->Activate( activate, activateStr ); return activateStr;