From a687a61c76fc301155aed9f594c2e44456c9af62 Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@zdoom.fake>
Date: Sat, 27 Jun 2009 01:36:10 +0000
Subject: [PATCH] - Attaching and detaching joysticks once again updates the
 joystick menu.

SVN r1684 (trunk)
---
 docs/rh-log.txt       |  1 +
 src/m_menu.h          |  1 +
 src/m_options.cpp     | 24 +++++++++---
 src/win32/i_dijoy.cpp | 89 ++++++++++---------------------------------
 4 files changed, 42 insertions(+), 73 deletions(-)

diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index f1d9a2781..44e0f3baa 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,4 +1,5 @@
 June 26, 2009
+- Attaching and detaching joysticks once again updates the joystick menu.
 - Added joystick axis -> button mapping.
 
 June 26, 2009  (Changes by Graf Zahl)
diff --git a/src/m_menu.h b/src/m_menu.h
index ab0770601..76c3fd5bd 100644
--- a/src/m_menu.h
+++ b/src/m_menu.h
@@ -119,6 +119,7 @@ typedef enum {
 } itemtype;
 
 struct IJoystickConfig;
+void UpdateJoystickMenu(IJoystickConfig *selected);
 
 struct menuitem_t
 {
diff --git a/src/m_options.cpp b/src/m_options.cpp
index 1f2998a37..622bb1c12 100644
--- a/src/m_options.cpp
+++ b/src/m_options.cpp
@@ -291,7 +291,6 @@ menu_t MouseMenu =
 
 #define SELECTED_JOYSTICK	(Joysticks[JoystickItems[1].a.joyselection])
 EXTERN_CVAR (Bool, use_joystick)
-void UpdateJoystickMenu();
 
 #if 0
 EXTERN_CVAR (Float, joy_speedmultiplier)
@@ -2460,7 +2459,7 @@ void M_OptResponder (event_t *ev)
 				{
 					item->a.joyselection = item->e.joyvalues->Size() - 1;
 				}
-				UpdateJoystickMenu();
+				UpdateJoystickMenu(NULL);
 				S_Sound(CHAN_VOICE|CHAN_UI, "menu/change", 1, ATTN_NONE);
 				break;
 
@@ -2666,7 +2665,7 @@ void M_OptResponder (event_t *ev)
 				{
 					item->a.joyselection = 0;
 				}
-				UpdateJoystickMenu();
+				UpdateJoystickMenu(NULL);
 				S_Sound(CHAN_VOICE | CHAN_UI, "menu/change", 1, ATTN_NONE);
 				break;
 
@@ -3092,7 +3091,7 @@ CCMD (menu_mouse)
 	MouseOptions ();
 }
 
-void UpdateJoystickMenu ()
+void UpdateJoystickMenu(IJoystickConfig *selected)
 {
 	int i;
 	menuitem_t item = { whitetext };
@@ -3109,6 +3108,21 @@ void UpdateJoystickMenu ()
 	}
 	JoystickItems.Clear();
 	I_GetJoysticks(Joysticks);
+	if ((unsigned)itemnum >= Joysticks.Size())
+	{
+		itemnum = Joysticks.Size() - 1;
+	}
+	if (selected != NULL)
+	{
+		for (i = 0; (unsigned)i < Joysticks.Size(); ++i)
+		{
+			if (Joysticks[i] == selected)
+			{
+				itemnum = i;
+				break;
+			}
+		}
+	}
 	if (Joysticks.Size() == 0)
 	{
 		item.type = redtext;
@@ -3269,7 +3283,7 @@ void UpdateJoystickMenu ()
 
 static void JoystickOptions ()
 {
-	UpdateJoystickMenu ();
+	UpdateJoystickMenu (NULL);
 	M_SwitchMenu (&JoystickMenu);
 }
 
diff --git a/src/win32/i_dijoy.cpp b/src/win32/i_dijoy.cpp
index a05172888..d43b41c55 100644
--- a/src/win32/i_dijoy.cpp
+++ b/src/win32/i_dijoy.cpp
@@ -217,7 +217,7 @@ protected:
 	};
 	TArray<FDInputJoystick *> Devices;
 
-	void EnumDevices();
+	FDInputJoystick *EnumDevices();
 
 	static BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
 	static int STACK_ARGS NameSort(const void *a, const void *b);
@@ -1120,76 +1120,22 @@ void FDInputJoystickManager::GetDevices(TArray<IJoystickConfig *> &sticks)
 
 bool FDInputJoystickManager::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
 {
-	if (message != WM_DEVICECHANGE ||
-		(wParam != DBT_DEVNODES_CHANGED &&
+	if (message != WM_DEVICECHANGE)
+	{
+		return false;
+	}
+#ifdef _DEBUG
+	char out[64];
+	mysnprintf(out, countof(out), "WM_DEVICECHANGE wParam=%d\n", wParam);
+	OutputDebugString(out);
+#endif
+	if ((wParam != DBT_DEVNODES_CHANGED &&
 		 wParam != DBT_DEVICEARRIVAL &&
 		 wParam != DBT_CONFIGCHANGED))
 	{
 		return false;
 	}
-	EnumDevices();
-#if 0
-	unsigned int i;
-	TArray<GUID> oldjoys;
-
-	for (i = 0; i < JoystickNames.Size(); ++i)
-	{
-		oldjoys.Push (JoystickNames[i].ID);
-	}
-
-	DI_EnumJoy ();
-
-	// If a new joystick was added and the joystick menu is open,
-	// switch to it.
-	if (menuactive != MENU_Off && CurrentMenu == &JoystickMenu)
-	{
-		for (i = 0; i < JoystickNames.Size(); ++i)
-		{
-			bool wasListed = false;
-
-			for (unsigned int j = 0; j < oldjoys.Size(); ++j)
-			{
-				if (oldjoys[j] == JoystickNames[i].ID)
-				{
-					wasListed = true;
-					break;
-				}
-			}
-			if (!wasListed)
-			{
-				joy_guid = JoystickNames[i].ID;
-				break;
-			}
-		}
-	}
-
-	// If the current joystick was removed,
-	// try to switch to a different one.
-	if (g_pJoy != NULL)
-	{
-		DIDEVICEINSTANCE inst = { sizeof(DIDEVICEINSTANCE), };
-
-		if (SUCCEEDED(g_pJoy->GetDeviceInfo (&inst)))
-		{
-			for (i = 0; i < JoystickNames.Size(); ++i)
-			{
-				if (JoystickNames[i].ID == inst.guidInstance)
-				{
-					break;
-				}
-			}
-			if (i == JoystickNames.Size ())
-			{
-				DI_InitJoy ();
-			}
-		}
-	}
-	else
-	{
-		DI_InitJoy ();
-	}
-	UpdateJoystickMenu ();
-#endif
+	UpdateJoystickMenu(EnumDevices());
 	// Return false so that other devices can handle this too if they want.
 	return false;
 }
@@ -1340,12 +1286,14 @@ int FDInputJoystickManager::NameSort(const void *a, const void *b)
 // FDInputJoystickManager :: EnumDevices
 //
 // Find out what DirectInput game controllers are on the system and create
-// FDInputJoystick objects for them.
+// FDInputJoystick objects for them. May return a pointer to the first new
+// device found.
 //
 //===========================================================================
 
-void FDInputJoystickManager::EnumDevices()
+FDInputJoystick *FDInputJoystickManager::EnumDevices()
 {
+	FDInputJoystick *newone = NULL;
 	TArray<Enumerator> controllers;
 	unsigned i, j, k;
 
@@ -1406,6 +1354,10 @@ void FDInputJoystickManager::EnumDevices()
 			{
 				device->Marked = true;
 				Devices.Push(device);
+				if (newone == NULL)
+				{
+					newone = device;
+				}
 			}
 		}
 	}
@@ -1426,6 +1378,7 @@ void FDInputJoystickManager::EnumDevices()
 		}
 	}
 	Devices.Resize(i);
+	return newone;
 }
 
 //===========================================================================