diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml
index b1414c4f3f68cebc1c3f55878cfec898a945a8b8..acf2676b9667a71ad30da0941adc7347c7f93e10 100644
--- a/indra/newview/app_settings/settings_alchemy.xml
+++ b/indra/newview/app_settings/settings_alchemy.xml
@@ -2066,5 +2066,159 @@
             <key>Value</key>
             <integer>2</integer>
         </map>
+        <key>BlackDragonControls</key>
+        <map>
+            <key>Comment</key>
+            <string>Use BlackDragon style joystick controls</string>
+            <key>Persist</key>
+            <integer>1</integer>
+            <key>Type</key>
+            <string>Boolean</string>
+            <key>Value</key>
+            <integer>0</integer>
+        </map>
+		<key>JoystickButtonFlycam</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>7</integer>
+		</map>
+		<key>JoystickButtonJump</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>0</integer>
+		</map>
+		<key>JoystickButtonFly</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>2</integer>
+		</map>
+		<key>JoystickButtonCrouch</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>1</integer>
+		</map>
+		<key>JoystickButtonRunToggle</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>8</integer>
+		</map>
+		<key>JoystickButtonMouselook</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>9</integer>
+		</map>
+		<key>JoystickButtonZoomIn</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>4</integer>
+		</map>
+		<key>JoystickButtonZoomOut</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>5</integer>
+		</map>
+		<key>JoystickButtonZoomDefault</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>6</integer>
+		</map>
+		<key>JoystickButtonRollLeft</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>-1</integer>
+		</map>
+		<key>JoystickButtonRollRight</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>-1</integer>
+		</map>
+		<key>JoystickButtonRollDefault</key>
+		<map>
+		  <key>Comment</key>
+		  <string>Test</string>
+		  <key>Persist</key>
+		  <integer>1</integer>
+		  <key>Type</key>
+		  <string>S32</string>
+		  <key>Value</key>
+		  <integer>-1</integer>
+		</map>
+		<key>JoystickInvertPitch</key>
+		  <map>
+			<key>Comment</key>
+			<string>Invert pitch axis in all joystick modes.</string>
+			<key>Persist</key>
+			<integer>1</integer>
+			<key>Type</key>
+			<string>Boolean</string>
+			<key>Value</key>
+			<integer>0</integer>
+		  </map>
 	</map>
 </llsd>
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 09763b7bb5a2da12a77d03abad37f528c1f3dfd1..03e587e38eea87ca46551b3a7c45cfb20c7708c9 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -134,6 +134,15 @@ void LLFloaterJoystick::draw()
         }
     }
 
+	for (U32 i = 0; i < 16; i++)
+	{
+        U32 value = joystick->getJoystickButton(i);
+		if (!mAxisButton[i]->getEnabled() && value)
+		{
+			mAxisButton[i]->setEnabled(TRUE);
+		}
+		mAxisButton[i]->setToggleState(value);
+	}
     LLFloater::draw();
 }
 
@@ -154,6 +163,12 @@ BOOL LLFloaterJoystick::postBuild()
         }
     }
 
+	for (U32 i = 0; i < 16; i++)
+	{
+		std::string btn_name = llformat("btn%d", i);
+		mAxisButton[i] = getChild<LLButton>(btn_name);
+	}
+
     mJoysticksCombo = getChild<LLComboBox>("joystick_combo");
     childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this);
     mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled");
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index 6a804239dbf9556acf416c399f05b7b6ba7ea11a..5aa0dbd0104d957ff1f9e98531b4a095dde2872b 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -100,6 +100,8 @@ class LLFloaterJoystick final : public LLFloater
 
     // stats view
     LLStatBar* mAxisStatsBar[6];
+
+	LLButton* mAxisButton[16];
 };
 
 #endif
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index 739234534a912cf52824469210becdb1e2ddc9ce..dcccd244013f0b13c860a63ffbad9673af6e8fa3 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -402,6 +402,19 @@ LLViewerJoystick::LLViewerJoystick()
 
     gSavedSettings.getControl("JoystickInvertPitch")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
 
+    gSavedSettings.getControl("JoystickButtonRollLeft")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonRollRight")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonRollDefault")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonZoomOut")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonZoomIn")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonZoomDefault")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonJump")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonCrouch")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonFly")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonMouselook")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonFlycam")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+    gSavedSettings.getControl("JoystickButtonRunToggle")->getCommitSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) { refreshFromSettings(); });
+
     refreshFromSettings();
 }
 
@@ -607,6 +620,19 @@ void LLViewerJoystick::refreshFromSettings()
     mFlycamFeathering = gSavedSettings.getF32("FlycamFeathering");
 
     mInvertPitch = gSavedSettings.getBOOL("JoystickInvertPitch");
+	
+	mMappedButtons[ROLL_LEFT] = gSavedSettings.getS32("JoystickButtonRollLeft");
+	mMappedButtons[ROLL_RIGHT] = gSavedSettings.getS32("JoystickButtonRollRight");
+	mMappedButtons[ROLL_DEFAULT] = gSavedSettings.getS32("JoystickButtonRollDefault");
+	mMappedButtons[ZOOM_OUT] = gSavedSettings.getS32("JoystickButtonZoomOut");
+	mMappedButtons[ZOOM_IN] = gSavedSettings.getS32("JoystickButtonZoomIn");
+	mMappedButtons[ZOOM_DEFAULT] = gSavedSettings.getS32("JoystickButtonZoomDefault");
+	mMappedButtons[JUMP] = gSavedSettings.getS32("JoystickButtonJump");
+	mMappedButtons[CROUCH] = gSavedSettings.getS32("JoystickButtonCrouch");
+	mMappedButtons[FLY] = gSavedSettings.getS32("JoystickButtonFly");
+	mMappedButtons[MOUSELOOK] = gSavedSettings.getS32("JoystickButtonMouselook");
+	mMappedButtons[FLYCAM] = gSavedSettings.getS32("JoystickButtonFlycam");
+	mMappedButtons[TOGGLE_RUN] = gSavedSettings.getS32("JoystickButtonRunToggle");
 }
 
 void LLViewerJoystick::initDevice(LLSD &guid)
@@ -958,49 +984,115 @@ void LLViewerJoystick::moveObjects(bool reset)
 
     F32 cur_delta[6];
     F32 time = gFrameIntervalSeconds.value();
+    bool is_zero = true;
 
-    // avoid making ridicously big movements if there's a big drop in fps
-    if (time > .2f)
-    {
-        time = .2f;
-    }
+    static LLCachedControl<bool> blackdragon(gSavedSettings, "BlackDragonControls", false);
+	if(blackdragon)
+	{
+		//BD - Avoid making ridicously big movements if there's a big drop in fps 
+		time = llclamp(time, 0.016f, 0.033f);
 
-    // max feather is 32
-    F32 feather = mBuildFeathering;
-    bool is_zero = true, absolute = m3DCursor;
+	//	//BD - Remappable Joystick Controls
 
-    for (U32 i = 0; i < 6; i++)
-    {
-        cur_delta[i] = -mAxes[mJoystickAxis[i]];
-//      //BD - Invertable Pitch Controls
-        if (!mInvertPitch && i == 4)
-            cur_delta[i] = -cur_delta[i];
+	
+		for (U32 i = 0; i < 6; i++)
+		{
+			cur_delta[i] = -getJoystickAxis(mJoystickAxis[i]);
 
-        F32 tmp = cur_delta[i];
-        if (absolute)
-        {
-            cur_delta[i] = cur_delta[i] - sLastDelta[i];
-        }
-        sLastDelta[i] = tmp;
-        is_zero = is_zero && (cur_delta[i] == 0.f);
-
-        if (cur_delta[i] > 0)
-        {
-            cur_delta[i] = llmax(cur_delta[i]- mBuildAxisDeadZone[i], 0.f);
-        }
-        else
-        {
-            cur_delta[i] = llmin(cur_delta[i]+ mBuildAxisDeadZone[i], 0.f);
-        }
-        cur_delta[i] *= mBuildAxisScale[i];
-
-        if (!absolute)
-        {
-            cur_delta[i] *= time;
-        }
+            if (i == CAM_X_AXIS)
+            {
+                cur_delta[i] -= (F32)getJoystickButton(mMappedButtons[ROLL_LEFT]);
+                cur_delta[i] += (F32)getJoystickButton(mMappedButtons[ROLL_RIGHT]);
+            }
+            if (i == Z_AXIS)
+            {
+                cur_delta[i] += (F32)getJoystickButton(mMappedButtons[JUMP]);
+                cur_delta[i] -= (F32)getJoystickButton(mMappedButtons[CROUCH]);
+            }
 
-        sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather;
-    }
+	//		//BD - Invertable Pitch Controls
+            if (mInvertPitch && i == 4)
+				cur_delta[4] *= -1.f;
+
+			F32 tmp = cur_delta[i];
+			F32 axis_deadzone = mBuildAxisDeadZone[i];
+			if (m3DCursor || llabs(cur_delta[i]) < axis_deadzone)
+			{
+				cur_delta[i] = cur_delta[i] - sLastDelta[i];
+			}
+			sLastDelta[i] = tmp;
+			is_zero = is_zero && (cur_delta[i] == 0.f);
+			
+			//BD - We assume that delta 1.0 is the maximum.
+			if (llabs(cur_delta[i]) > axis_deadzone)
+			{
+				//BD - Clamp the delta between 1 and -1 while taking the deadzone into account.
+				if (cur_delta[i] > 0)
+				{
+					cur_delta[i] = llclamp(cur_delta[i] - axis_deadzone, 0.f, 1.f - axis_deadzone);
+				}
+				else
+				{
+					cur_delta[i] = llclamp(cur_delta[i] + axis_deadzone, -1.f + axis_deadzone, 0.f);
+				}
+				//BD - Rescale the remaining delta to match the maximum to get a new clean 0 to 1 range.
+				cur_delta[i] = cur_delta[i] / (1.f - axis_deadzone);
+			}
+			cur_delta[i] *= mBuildAxisScale[i];
+		
+			if (!m3DCursor)
+			{
+				cur_delta[i] *= time;
+			}
+
+			sDelta[i] = sDelta[i] + (cur_delta[i] - sDelta[i]) * time * mBuildFeathering;
+		}
+	}
+	else
+	{
+	    // avoid making ridicously big movements if there's a big drop in fps
+	    if (time > .2f)
+	    {
+	        time = .2f;
+	    }
+
+	    // max feather is 32
+	    F32 feather = mBuildFeathering;
+	    bool absolute = m3DCursor;
+
+	    for (U32 i = 0; i < 6; i++)
+	    {
+	        cur_delta[i] = -mAxes[mJoystickAxis[i]];
+	//      //BD - Invertable Pitch Controls
+	        if (!mInvertPitch && i == 4)
+	            cur_delta[i] = -cur_delta[i];
+
+	        F32 tmp = cur_delta[i];
+	        if (absolute)
+	        {
+	            cur_delta[i] = cur_delta[i] - sLastDelta[i];
+	        }
+	        sLastDelta[i] = tmp;
+	        is_zero = is_zero && (cur_delta[i] == 0.f);
+
+	        if (cur_delta[i] > 0)
+	        {
+	            cur_delta[i] = llmax(cur_delta[i]- mBuildAxisDeadZone[i], 0.f);
+	        }
+	        else
+	        {
+	            cur_delta[i] = llmin(cur_delta[i]+ mBuildAxisDeadZone[i], 0.f);
+	        }
+	        cur_delta[i] *= mBuildAxisScale[i];
+
+	        if (!absolute)
+	        {
+	            cur_delta[i] *= time;
+	        }
+
+	        sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather;
+	    }
+	}
 
     U32 upd_type = UPD_NONE;
     LLVector3 v;
@@ -1058,198 +1150,373 @@ void LLViewerJoystick::moveAvatar(bool reset)
         return;
     }
 
-    bool is_zero = true;
-    static bool button_held = false;
-
-    if (mBtn[1] == 1)
-    {
-        // If AutomaticFly is enabled, then button1 merely causes a
-        // jump (as the up/down axis already controls flying) if on the
-        // ground, or cease flight if already flying.
-        // If AutomaticFly is disabled, then button1 toggles flying.
-        if (ALControlCache::AutomaticFly)
-        {
-            if (!gAgent.getFlying())
-            {
-                gAgent.moveUp(1);
-            }
-            else if (!button_held)
-            {
-                button_held = true;
-                gAgent.setFlying(FALSE);
-            }
-        }
-        else if (!button_held)
-        {
-            button_held = true;
-            gAgent.setFlying(!gAgent.getFlying());
-        }
-
-        is_zero = false;
-    }
-    else
-    {
-        button_held = false;
-    }
-
-    // time interval in seconds between this frame and the previous
-    F32 time = gFrameIntervalSeconds.value();
-
-    // avoid making ridicously big movements if there's a big drop in fps
-    if (time > .2f)
-    {
-        time = .2f;
-    }
-
-    // note: max feather is 32.0
-    F32 feather = mAvatarFeathering;
-
-    F32 cur_delta[6];
-    F32 val, dom_mov = 0.f;
-    U32 dom_axis = Z_I;
-#if LIB_NDOF
-    bool absolute = (m3DCursor && mNdofDev->absolute);
-#else
-    bool absolute = false;
-#endif
-    // remove dead zones and determine biggest movement on the joystick
-    for (U32 i = 0; i < 6; i++)
-    {
-        cur_delta[i] = -mAxes[mJoystickAxis[i]];
-
-        if (!mInvertPitch && i == 4)
-            cur_delta[i] = -cur_delta[i];
-
-        if (absolute)
-        {
-            F32 tmp = cur_delta[i];
-            cur_delta[i] = cur_delta[i] - sLastDelta[i];
-            sLastDelta[i] = tmp;
-        }
-
-        if (cur_delta[i] > 0)
-        {
-            cur_delta[i] = llmax(cur_delta[i]- mAvatarAxisDeadZone[i], 0.f);
-        }
-        else
-        {
-            cur_delta[i] = llmin(cur_delta[i]+ mAvatarAxisDeadZone[i], 0.f);
-        }
-
-        // we don't care about Roll (RZ) and Z is calculated after the loop
-        if (i != Z_I && i != RZ_I)
-        {
-            // find out the axis with the biggest joystick motion
-            val = fabs(cur_delta[i]);
-            if (val > dom_mov)
+    static LLCachedControl<bool> blackdragon(gSavedSettings, "BlackDragonControls", false);
+    if (blackdragon)
+	{
+		bool is_zero = true;
+		static bool button_held = false;
+		//BD
+		static bool w_button_held = false;
+		static bool m_button_held = false;
+
+	//	//BD - Remappable Joystick Controls
+		if (getJoystickButton(mMappedButtons[FLY]) == 1 && !button_held)
+		{
+			button_held = true;
+			if (gAgent.getFlying())
+			{
+				gAgent.setFlying(FALSE);
+			}
+			else
+			{
+				gAgent.setFlying(TRUE);
+			}
+		}
+		else if (getJoystickButton(mMappedButtons[FLY]) == 0 && button_held)
+		{
+			button_held = false;
+		}
+
+		if (getJoystickButton(mMappedButtons[TOGGLE_RUN]) == 1 && !w_button_held)
+		{
+			w_button_held = true;
+			if (gAgent.getAlwaysRun())
+			{
+				gAgent.clearAlwaysRun();
+			}
+			else
+			{
+				gAgent.setAlwaysRun();
+			}
+		}
+		else if (getJoystickButton(mMappedButtons[TOGGLE_RUN]) == 0 && w_button_held)
+		{
+			w_button_held = false;
+		}
+
+		if (getJoystickButton(mMappedButtons[MOUSELOOK]) == 1 && !m_button_held)
+		{
+			m_button_held = true;
+			if (gAgentCamera.cameraMouselook())
+			{
+				gAgentCamera.changeCameraToDefault();
+			}
+			else
+			{
+				gAgentCamera.changeCameraToMouselook();
+			}
+		}
+		else if (getJoystickButton(mMappedButtons[MOUSELOOK]) == 0 && m_button_held)
+		{
+			m_button_held = false;
+		}
+
+		// time interval in seconds between this frame and the previous
+		F32 time = gFrameIntervalSeconds.value();
+
+		//BD - Avoid making ridicously big movements if there's a big drop in fps 
+		time = llclamp(time, 0.016f, 0.033f);
+
+		// note: max feather is 32.0
+	
+        F32 cur_delta[6] = {};
+		F32 val, dom_mov = 0.f;
+		U32 dom_axis = Z_I;
+
+		// remove dead zones and determine biggest movement on the joystick 
+		for (U32 i = 0; i < 6; i++)
+		{
+			cur_delta[i] = -getJoystickAxis(mJoystickAxis[i]);
+
+            if(i == Z_AXIS)
             {
-                dom_axis = i;
-                dom_mov = val;
+                cur_delta[i] += (F32)getJoystickButton(mMappedButtons[JUMP]);
+                cur_delta[i] -= (F32)getJoystickButton(mMappedButtons[CROUCH]);
             }
-        }
-
-        is_zero = is_zero && (cur_delta[i] == 0.f);
-    }
-
-    if (!is_zero)
-    {
-        // Clear AFK state if moved beyond the deadzone
-        if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
-        {
-            gAgent.clearAFK();
-        }
-
-        setCameraNeedsUpdate(true);
-    }
-
-    // forward|backward movements overrule the real dominant movement if
-    // they're bigger than its 20%. This is what you want 'cos moving forward
-    // is what you do most. We also added a special (even more lenient) case
-    // for RX|RY to allow walking while pitching and turning
-    if (fabs(cur_delta[Z_I]) > .2f * dom_mov
-        || ((dom_axis == RX_I || dom_axis == RY_I)
-        && fabs(cur_delta[Z_I]) > .05f * dom_mov))
-    {
-        dom_axis = Z_I;
-    }
-
-    sDelta[X_I] = -cur_delta[X_I] * mAvatarAxisScale[X_I];
-    sDelta[Y_I] = -cur_delta[Y_I] * mAvatarAxisScale[Y_I];
-    sDelta[Z_I] = -cur_delta[Z_I] * mAvatarAxisScale[Z_I];
-    cur_delta[RX_I] *= -mAvatarAxisScale[RX_I] * mPerfScale;
-    cur_delta[RY_I] *= -mAvatarAxisScale[RY_I] * mPerfScale;
-
-    if (!absolute)
-    {
-        cur_delta[RX_I] *= time;
-        cur_delta[RY_I] *= time;
-    }
-    sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * feather;
-    sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * feather;
-
-    handleRun((F32) sqrt(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I]));
 
-    // Allow forward/backward movement some priority
-    if (dom_axis == Z_I)
-    {
-        agentPush(sDelta[Z_I]);         // forward/back
-
-        if (fabs(sDelta[X_I])  > .1f)
-        {
-            agentSlide(sDelta[X_I]);    // move sideways
-        }
-
-        if (fabs(sDelta[Y_I])  > .1f)
-        {
-            agentFly(sDelta[Y_I]);      // up/down & crouch
-        }
-
-        // too many rotations during walking can be confusing, so apply
-        // the deadzones one more time (quick & dirty), at 50%|30% power
-        F32 eff_rx = .3f * mAvatarAxisDeadZone[RX_I];
-        F32 eff_ry = .3f * mAvatarAxisDeadZone[RY_I];
-
-        if (sDelta[RX_I] > 0)
-        {
-            eff_rx = llmax(sDelta[RX_I] - eff_rx, 0.f);
-        }
-        else
-        {
-            eff_rx = llmin(sDelta[RX_I] + eff_rx, 0.f);
-        }
-
-        if (sDelta[RY_I] > 0)
-        {
-            eff_ry = llmax(sDelta[RY_I] - eff_ry, 0.f);
-        }
-        else
-        {
-            eff_ry = llmin(sDelta[RY_I] + eff_ry, 0.f);
-        }
-
-
-        if (fabs(eff_rx) > 0.f || fabs(eff_ry) > 0.f)
-        {
-            if (gAgent.getFlying())
-            {
-                agentPitch(eff_rx);
-                agentYaw(eff_ry);
-            }
-            else
-            {
-                agentPitch(eff_rx);
-                agentYaw(2.f * eff_ry);
-            }
-        }
-    }
-    else
-    {
-        agentSlide(sDelta[X_I]);        // move sideways
-        agentFly(sDelta[Y_I]);          // up/down & crouch
-        agentPush(sDelta[Z_I]);         // forward/back
-        agentPitch(sDelta[RX_I]);       // pitch
-        agentYaw(sDelta[RY_I]);         // turn
-    }
+			F32 axis_deadzone = mAvatarAxisDeadZone[i];
+
+			//BD - We assume that delta 1.0 is the maximum.
+			if (llabs(cur_delta[i]) > axis_deadzone)
+			{
+				//BD - Clamp the delta between 1 and -1 while taking the deadzone into account.
+				if (cur_delta[i] > 0)
+				{
+					cur_delta[i] = llclamp(cur_delta[i] - axis_deadzone, 0.f, 1.f - axis_deadzone);
+				}
+				else
+				{
+					cur_delta[i] = llclamp(cur_delta[i] + axis_deadzone, -1.f + axis_deadzone, 0.f);
+				}
+				//BD - Rescale the remaining delta to match the maximum to get a new clean 0 to 1 range.
+				cur_delta[i] = cur_delta[i] / (1.f - axis_deadzone);
+			}
+			else
+			{
+				cur_delta[i] = 0.f;
+			}
+
+			// we don't care about Roll (RZ) and Z is calculated after the loop
+	        if (i != Z_I && i != RZ_I)
+			{
+				// find out the axis with the biggest joystick motion
+				val = fabs(cur_delta[i]);
+				if (val > dom_mov)
+				{
+					dom_axis = i;
+					dom_mov = val;
+				}
+			}
+		
+			cur_delta[i] *= mAvatarAxisScale[i] * time;
+
+			//sDelta[i] = sDelta[i] + (cur_delta[i] - sDelta[i]) * time;
+			is_zero = is_zero && (cur_delta[i] == 0.f);
+		}
+
+		if (!is_zero)
+		{
+			// Clear AFK state if moved beyond the deadzone
+			if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+			{
+				gAgent.clearAFK();
+			}
+		
+			setCameraNeedsUpdate(true);
+		}
+
+	//	//BD - Invertable Pitch Controls
+		if (!mInvertPitch)
+			cur_delta[RX_I] = -cur_delta[RX_I];
+
+		// forward|backward movements overrule the real dominant movement if 
+		// they're bigger than its 20%. This is what you want 'cos moving forward
+		// is what you do most. We also added a special (even more lenient) case 
+		// for RX|RY to allow walking while pitching and turning
+		if (fabs(cur_delta[Z_I]) > .2f * dom_mov
+		    || ((dom_axis == RX_I || dom_axis == RY_I) 
+			&& fabs(cur_delta[Z_I]) > .05f * dom_mov))
+		{
+			dom_axis = Z_I;
+		}
+
+		sDelta[X_I] = -cur_delta[X_I];
+		sDelta[Y_I] = -cur_delta[Y_I];
+		sDelta[Z_I] = -cur_delta[Z_I];
+		cur_delta[RX_I] *= -mAvatarAxisScale[RX_I];
+		cur_delta[RY_I] *= -mAvatarAxisScale[RY_I];
+		
+		sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * mAvatarFeathering;
+		sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * mAvatarFeathering;
+	
+		handleRun((F32) sqrt(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I]));
+	
+	//	//BD - Xbox360 Controller Support
+		//     Use raw deltas, do not add any stupid limitations or extra dead zones
+		//     otherwise alot controllers will cry and camera movement will bug out
+		//     or be completely ignored on some controllers. Especially fixes Xbox 360
+		//     controller avatar movement.
+		agentSlide(sDelta[X_I]);		// move sideways
+		agentFly(sDelta[Y_I]);			// up/down & crouch
+		agentPush(sDelta[Z_I]);			// forward/back
+		agentPitch(sDelta[RX_I]);		// pitch
+		agentYaw(sDelta[RY_I]);			// turn
+	}
+	else
+	{
+	    bool is_zero = true;
+	    static bool button_held = false;
+
+	    if (mBtn[1] == 1)
+	    {
+	        // If AutomaticFly is enabled, then button1 merely causes a
+	        // jump (as the up/down axis already controls flying) if on the
+	        // ground, or cease flight if already flying.
+	        // If AutomaticFly is disabled, then button1 toggles flying.
+	        if (ALControlCache::AutomaticFly)
+	        {
+	            if (!gAgent.getFlying())
+	            {
+	                gAgent.moveUp(1);
+	            }
+	            else if (!button_held)
+	            {
+	                button_held = true;
+	                gAgent.setFlying(FALSE);
+	            }
+	        }
+	        else if (!button_held)
+	        {
+	            button_held = true;
+	            gAgent.setFlying(!gAgent.getFlying());
+	        }
+
+	        is_zero = false;
+	    }
+	    else
+	    {
+	        button_held = false;
+	    }
+
+	    // time interval in seconds between this frame and the previous
+	    F32 time = gFrameIntervalSeconds.value();
+
+	    // avoid making ridicously big movements if there's a big drop in fps
+	    if (time > .2f)
+	    {
+	        time = .2f;
+	    }
+
+	    // note: max feather is 32.0
+	    F32 feather = mAvatarFeathering;
+
+	    F32 cur_delta[6];
+	    F32 val, dom_mov = 0.f;
+	    U32 dom_axis = Z_I;
+	#if LIB_NDOF
+	    bool absolute = (m3DCursor && mNdofDev->absolute);
+	#else
+	    bool absolute = false;
+	#endif
+	    // remove dead zones and determine biggest movement on the joystick
+	    for (U32 i = 0; i < 6; i++)
+	    {
+	        cur_delta[i] = -mAxes[mJoystickAxis[i]];
+
+	        if (!mInvertPitch && i == 4)
+	            cur_delta[i] = -cur_delta[i];
+
+	        if (absolute)
+	        {
+	            F32 tmp = cur_delta[i];
+	            cur_delta[i] = cur_delta[i] - sLastDelta[i];
+	            sLastDelta[i] = tmp;
+	        }
+
+	        if (cur_delta[i] > 0)
+	        {
+	            cur_delta[i] = llmax(cur_delta[i]- mAvatarAxisDeadZone[i], 0.f);
+	        }
+	        else
+	        {
+	            cur_delta[i] = llmin(cur_delta[i]+ mAvatarAxisDeadZone[i], 0.f);
+	        }
+
+	        // we don't care about Roll (RZ) and Z is calculated after the loop
+	        if (i != Z_I && i != RZ_I)
+	        {
+	            // find out the axis with the biggest joystick motion
+	            val = fabs(cur_delta[i]);
+	            if (val > dom_mov)
+	            {
+	                dom_axis = i;
+	                dom_mov = val;
+	            }
+	        }
+
+	        is_zero = is_zero && (cur_delta[i] == 0.f);
+	    }
+
+	    if (!is_zero)
+	    {
+	        // Clear AFK state if moved beyond the deadzone
+	        if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+	        {
+	            gAgent.clearAFK();
+	        }
+
+	        setCameraNeedsUpdate(true);
+	    }
+
+	    // forward|backward movements overrule the real dominant movement if
+	    // they're bigger than its 20%. This is what you want 'cos moving forward
+	    // is what you do most. We also added a special (even more lenient) case
+	    // for RX|RY to allow walking while pitching and turning
+	    if (fabs(cur_delta[Z_I]) > .2f * dom_mov
+	        || ((dom_axis == RX_I || dom_axis == RY_I)
+	        && fabs(cur_delta[Z_I]) > .05f * dom_mov))
+	    {
+	        dom_axis = Z_I;
+	    }
+
+	    sDelta[X_I] = -cur_delta[X_I] * mAvatarAxisScale[X_I];
+	    sDelta[Y_I] = -cur_delta[Y_I] * mAvatarAxisScale[Y_I];
+	    sDelta[Z_I] = -cur_delta[Z_I] * mAvatarAxisScale[Z_I];
+	    cur_delta[RX_I] *= -mAvatarAxisScale[RX_I] * mPerfScale;
+	    cur_delta[RY_I] *= -mAvatarAxisScale[RY_I] * mPerfScale;
+
+	    if (!absolute)
+	    {
+	        cur_delta[RX_I] *= time;
+	        cur_delta[RY_I] *= time;
+	    }
+	    sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * feather;
+	    sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * feather;
+
+	    handleRun((F32) sqrt(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I]));
+
+	    // Allow forward/backward movement some priority
+	    if (dom_axis == Z_I)
+	    {
+	        agentPush(sDelta[Z_I]);         // forward/back
+
+	        if (fabs(sDelta[X_I])  > .1f)
+	        {
+	            agentSlide(sDelta[X_I]);    // move sideways
+	        }
+
+	        if (fabs(sDelta[Y_I])  > .1f)
+	        {
+	            agentFly(sDelta[Y_I]);      // up/down & crouch
+	        }
+
+	        // too many rotations during walking can be confusing, so apply
+	        // the deadzones one more time (quick & dirty), at 50%|30% power
+	        F32 eff_rx = .3f * mAvatarAxisDeadZone[RX_I];
+	        F32 eff_ry = .3f * mAvatarAxisDeadZone[RY_I];
+
+	        if (sDelta[RX_I] > 0)
+	        {
+	            eff_rx = llmax(sDelta[RX_I] - eff_rx, 0.f);
+	        }
+	        else
+	        {
+	            eff_rx = llmin(sDelta[RX_I] + eff_rx, 0.f);
+	        }
+
+	        if (sDelta[RY_I] > 0)
+	        {
+	            eff_ry = llmax(sDelta[RY_I] - eff_ry, 0.f);
+	        }
+	        else
+	        {
+	            eff_ry = llmin(sDelta[RY_I] + eff_ry, 0.f);
+	        }
+
+
+	        if (fabs(eff_rx) > 0.f || fabs(eff_ry) > 0.f)
+	        {
+	            if (gAgent.getFlying())
+	            {
+	                agentPitch(eff_rx);
+	                agentYaw(eff_ry);
+	            }
+	            else
+	            {
+	                agentPitch(eff_rx);
+	                agentYaw(2.f * eff_ry);
+	            }
+	        }
+	    }
+	    else
+	    {
+	        agentSlide(sDelta[X_I]);        // move sideways
+	        agentFly(sDelta[Y_I]);          // up/down & crouch
+	        agentPush(sDelta[Z_I]);         // forward/back
+	        agentPitch(sDelta[RX_I]);       // pitch
+	        agentYaw(sDelta[RY_I]);         // turn
+	    }
+	}
 }
 
 // -----------------------------------------------------------------------------
@@ -1277,106 +1544,250 @@ void LLViewerJoystick::moveFlycam(bool reset)
         return;
     }
 
-    F32 time = gFrameIntervalSeconds.value();
+    static LLCachedControl<F32> build_mode_scale(gSavedSettings, "FlycamBuildModeScale", 1.0);
 
-    // avoid making ridiculously big movements if there's a big drop in fps
-    if (time > .2f)
-    {
-        time = .2f;
-    }
+    static LLCachedControl<bool> blackdragon(gSavedSettings, "BlackDragonControls", false);
+    if (blackdragon)
+	{
+		F32 time = gFrameIntervalSeconds.value();
 
-    F32 cur_delta[7];
-    F32 feather = mFlycamFeathering;
-    bool absolute = m3DCursor;
-    bool is_zero = true;
+		//BD - Avoid making ridiculously big movements if there's a big drop in fps 
+		time = llclamp(time, 0.016f, 0.033f);
 
-    for (U32 i = 0; i < 7; i++)
-    {
-        cur_delta[i] = -getJoystickAxis(mJoystickAxis[i]);
+		F32 flycam_feather = mFlycamFeathering;
+		F32 cur_delta[MAX_AXES];
+		F32 max_angle = LLViewerCamera::getInstance()->getMaxView();
+		F32 min_angle = LLViewerCamera::getInstance()->getMinView();
 
-        if (!mInvertPitch && i == 4)
-            cur_delta[i] = -cur_delta[i];
+		//BD - Slam zoom back to default and kill any delta we might have.
+		if (getJoystickButton(mMappedButtons[ZOOM_DEFAULT]) == 1)
+		{
+			sFlycamZoom = gSavedSettings.getF32("CameraAngle");
+			sDelta[CAM_W_AXIS] = 0.0f;
+		}
 
-        F32 tmp = cur_delta[i];
-        if (absolute)
-        {
-            cur_delta[i] = cur_delta[i] - sLastDelta[i];
-        }
-        sLastDelta[i] = tmp;
+		//BD - Only smooth flycam zoom if we are not capping at the min/max otherwise the feathering
+		//     ends up working against previous input, delaying zoom in movement when we just zoomed
+		//     out beyond capped max for a bit and vise versa.
+		if ((sFlycamZoom <= min_angle
+			|| sFlycamZoom >= max_angle))
+		{
+			flycam_feather = 3.0f;
+		}
 
-        if (cur_delta[i] > 0)
-        {
-            cur_delta[i] = llmax(cur_delta[i]- mFlycamAxisDeadZone[i], 0.f);
-        }
-        else
-        {
-            cur_delta[i] = llmin(cur_delta[i]+ mFlycamAxisDeadZone[i], 0.f);
-        }
+		bool is_zero = true;
+		for (U32 i = 0; i < 7; i++)
+		{
+			cur_delta[i] = -getJoystickAxis(mJoystickAxis[i]);
 
-        // We may want to scale camera movements up or down in build mode.
-        // NOTE: this needs to remain after the deadzone calculation, otherwise
-        // we have issues with flycam "jumping" when the build dialog is opened/closed  -Nyx
-        if (in_build_mode)
-        {
-            if (i == X_I || i == Y_I || i == Z_I)
+            if (i == CAM_W_AXIS)
             {
-                static LLCachedControl<F32> build_mode_scale(gSavedSettings,"FlycamBuildModeScale", 1.0);
-                cur_delta[i] *= build_mode_scale;
+                cur_delta[i] -= (F32)getJoystickButton(mMappedButtons[ZOOM_OUT]);
+                cur_delta[i] += (F32)getJoystickButton(mMappedButtons[ZOOM_IN]);
+            }
+            if (i == Z_AXIS)
+            {
+                cur_delta[i] += (F32)getJoystickButton(mMappedButtons[JUMP]);
+                cur_delta[i] -= (F32)getJoystickButton(mMappedButtons[CROUCH]);
+            }
+            if (i == CAM_X_AXIS)
+            {
+                cur_delta[i] -= (F32)getJoystickButton(mMappedButtons[ROLL_LEFT]);
+                cur_delta[i] += (F32)getJoystickButton(mMappedButtons[ROLL_RIGHT]);
             }
-        }
-
-        cur_delta[i] *= mFlycamAxisScale[i];
-
-        if (!absolute)
-        {
-            cur_delta[i] *= time;
-        }
-
-        sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather;
-
-        is_zero = is_zero && (cur_delta[i] == 0.f);
-
-    }
-
-    // Clear AFK state if moved beyond the deadzone
-    if (!is_zero && gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
-    {
-        gAgent.clearAFK();
-    }
-
-    sFlycamPosition += LLVector3(sDelta.data()) * sFlycamRotation;
-
-    LLMatrix3 rot_mat(sDelta[3], sDelta[4], sDelta[5]);
-    sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation;
-
-    if (mAutoLeveling)
-    {
-        LLMatrix3 level(sFlycamRotation);
-
-        LLVector3 x = LLVector3(level.mMatrix[0]);
-        LLVector3 y = LLVector3(level.mMatrix[1]);
-        LLVector3 z = LLVector3(level.mMatrix[2]);
-
-        y.mV[2] = 0.f;
-        y.normVec();
-
-        level.setRows(x,y,z);
-        level.orthogonalize();
-
-        LLQuaternion quat(level);
-        sFlycamRotation = nlerp(llmin(feather*time,1.f), sFlycamRotation, quat);
-    }
 
-    if (mZoomDirect)
-    {
-        sFlycamZoom = sLastDelta[6]* mFlycamAxisScale[6]+ mFlycamAxisDeadZone[6];
-    }
-    else
-    {
-        //BD - We need to cap zoom otherwise it internally counts higher causing
-        //     the zoom level to not react until that extra has been removed first.
-        sFlycamZoom = llclamp(sFlycamZoom + sDelta[6], LLViewerCamera::getInstance()->getMinView(), LLViewerCamera::getInstance()->getMaxView());
-    }
+			F32 tmp = cur_delta[i];
+			F32 axis_deadzone = mFlycamAxisDeadZone[i];
+			if (m3DCursor || llabs(cur_delta[i]) < axis_deadzone)
+			{
+				cur_delta[i] = cur_delta[i] - sLastDelta[i];
+			}
+			sLastDelta[i] = tmp;
+
+			//BD - We assume that delta 1.0 is the maximum.
+			if (llabs(cur_delta[i]) > axis_deadzone)
+			{
+				//BD - Clamp the delta between 1 and -1 while taking the deadzone into account.
+				if (cur_delta[i] > 0)
+				{
+					cur_delta[i] = llclamp(cur_delta[i] - axis_deadzone, 0.f, 1.f - axis_deadzone);
+				}
+				else
+				{
+					cur_delta[i] = llclamp(cur_delta[i] + axis_deadzone, -1.f + axis_deadzone, 0.f);
+				}
+				//BD - Rescale the remaining delta to match the maximum to get a new clean 0 to 1 range.
+				cur_delta[i] = cur_delta[i] / (1.f - axis_deadzone);
+			}
+
+			// We may want to scale camera movements up or down in build mode.
+			// NOTE: this needs to remain after the deadzone calculation, otherwise
+			// we have issues with flycam "jumping" when the build dialog is opened/closed  -Nyx
+			if (LLToolMgr::getInstance()->inBuildMode())
+			{
+				if (i == X_I || i == Y_I || i == Z_I)
+				{
+					cur_delta[i] *= build_mode_scale;
+				}
+			}
+
+			cur_delta[i] *= mFlycamAxisScale[i];
+
+			if (!m3DCursor)
+			{
+				cur_delta[i] *= time;
+			}
+
+			sDelta[i] = sDelta[i] + (cur_delta[i] - sDelta[i]) * time * flycam_feather;
+			is_zero = is_zero && (cur_delta[i] == 0.f);
+		}
+
+	//	//BD - Invertable Pitch Controls
+		if (mInvertPitch)
+			cur_delta[CAM_Y_AXIS] = -cur_delta[CAM_Y_AXIS];
+	
+		// Clear AFK state if moved beyond the deadzone
+		if (!is_zero && gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+		{
+			gAgent.clearAFK();
+		}
+
+		sFlycamPosition += LLVector3(sDelta.data()) * sFlycamRotation;
+		LLMatrix3 rot_mat(sDelta[CAM_X_AXIS], sDelta[CAM_Y_AXIS], sDelta[CAM_Z_AXIS]);
+		sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation;
+
+		if (mAutoLeveling || getJoystickButton(mMappedButtons[ROLL_DEFAULT]) == 1)
+		{
+			LLMatrix3 level(sFlycamRotation);
+
+			LLVector3 x = LLVector3(level.mMatrix[0]);
+			LLVector3 y = LLVector3(level.mMatrix[1]);
+			LLVector3 z = LLVector3(level.mMatrix[2]);
+
+			y.mV[2] = 0.f;
+			y.normVec();
+
+			level.setRows(x,y,z);
+			level.orthogonalize();
+				
+			LLQuaternion quat(level);
+			LLQuaternion lerp = nlerp(llmin(flycam_feather * time, 1.f), sFlycamRotation, quat);
+			sFlycamRotation = getJoystickButton(mMappedButtons[ROLL_DEFAULT]) == 1 ? quat : lerp;
+		}
+
+		if (mZoomDirect)
+		{
+			sFlycamZoom = sLastDelta[CAM_W_AXIS] * mFlycamAxisScale[FLYCAM_AXIS_6] + mFlycamAxisScale[FLYCAM_AXIS_6];
+		}
+		else
+		{
+			//BD - We need to cap zoom otherwise it internally counts higher causing
+			//     the zoom level to not react until that extra has been removed first.
+			sFlycamZoom = llclamp(sFlycamZoom + sDelta[CAM_W_AXIS], LLViewerCamera::getInstance()->getMinView(), LLViewerCamera::getInstance()->getMaxView());
+		}
+	}
+	else
+	{
+	    F32 time = gFrameIntervalSeconds.value();
+
+	    // avoid making ridiculously big movements if there's a big drop in fps
+	    if (time > .2f)
+	    {
+	        time = .2f;
+	    }
+
+	    F32 cur_delta[7];
+	    F32 feather = mFlycamFeathering;
+	    bool absolute = m3DCursor;
+	    bool is_zero = true;
+
+	    for (U32 i = 0; i < 7; i++)
+	    {
+	        cur_delta[i] = -getJoystickAxis(mJoystickAxis[i]);
+
+	        if (!mInvertPitch && i == 4)
+	            cur_delta[i] = -cur_delta[i];
+
+	        F32 tmp = cur_delta[i];
+	        if (absolute)
+	        {
+	            cur_delta[i] = cur_delta[i] - sLastDelta[i];
+	        }
+	        sLastDelta[i] = tmp;
+
+	        if (cur_delta[i] > 0)
+	        {
+	            cur_delta[i] = llmax(cur_delta[i]- mFlycamAxisDeadZone[i], 0.f);
+	        }
+	        else
+	        {
+	            cur_delta[i] = llmin(cur_delta[i]+ mFlycamAxisDeadZone[i], 0.f);
+	        }
+
+	        // We may want to scale camera movements up or down in build mode.
+	        // NOTE: this needs to remain after the deadzone calculation, otherwise
+	        // we have issues with flycam "jumping" when the build dialog is opened/closed  -Nyx
+	        if (in_build_mode)
+	        {
+	            if (i == X_I || i == Y_I || i == Z_I)
+	            {
+	                cur_delta[i] *= build_mode_scale;
+	            }
+	        }
+
+	        cur_delta[i] *= mFlycamAxisScale[i];
+
+	        if (!absolute)
+	        {
+	            cur_delta[i] *= time;
+	        }
+
+	        sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather;
+
+	        is_zero = is_zero && (cur_delta[i] == 0.f);
+
+	    }
+
+	    // Clear AFK state if moved beyond the deadzone
+	    if (!is_zero && gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
+	    {
+	        gAgent.clearAFK();
+	    }
+
+	    sFlycamPosition += LLVector3(sDelta.data()) * sFlycamRotation;
+
+	    LLMatrix3 rot_mat(sDelta[3], sDelta[4], sDelta[5]);
+	    sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation;
+
+	    if (mAutoLeveling)
+	    {
+	        LLMatrix3 level(sFlycamRotation);
+
+	        LLVector3 x = LLVector3(level.mMatrix[0]);
+	        LLVector3 y = LLVector3(level.mMatrix[1]);
+	        LLVector3 z = LLVector3(level.mMatrix[2]);
+
+	        y.mV[2] = 0.f;
+	        y.normVec();
+
+	        level.setRows(x,y,z);
+	        level.orthogonalize();
+
+	        LLQuaternion quat(level);
+	        sFlycamRotation = nlerp(llmin(feather*time,1.f), sFlycamRotation, quat);
+	    }
+
+	    if (mZoomDirect)
+	    {
+	        sFlycamZoom = sLastDelta[6]* mFlycamAxisScale[6]+ mFlycamAxisDeadZone[6];
+	    }
+	    else
+	    {
+	        //BD - We need to cap zoom otherwise it internally counts higher causing
+	        //     the zoom level to not react until that extra has been removed first.
+	        sFlycamZoom = llclamp(sFlycamZoom + sDelta[6], LLViewerCamera::getInstance()->getMinView(), LLViewerCamera::getInstance()->getMaxView());
+	    }
+	}
 
     LLMatrix3 mat(sFlycamRotation);
 
@@ -1445,17 +1856,35 @@ void LLViewerJoystick::scanJoystick()
 
     static long toggle_flycam = 0;
 
-    if (mBtn[0] == 1)
-    {
-        if (mBtn[0] != toggle_flycam)
-        {
-            toggle_flycam = toggleFlycam() ? 1 : 0;
-        }
-    }
-    else
-    {
-        toggle_flycam = 0;
-    }
+    static LLCachedControl<bool> blackdragon(gSavedSettings, "BlackDragonControls", false);
+    if (blackdragon)
+	{
+		if (getJoystickButton(mMappedButtons[FLYCAM]) == 1)
+		{
+			if (getJoystickButton(mMappedButtons[FLYCAM]) != toggle_flycam)
+			{
+				toggle_flycam = toggleFlycam() ? 1 : 0;
+			}
+		}
+		else
+		{
+			toggle_flycam = 0;
+		}
+	}
+	else
+	{
+	    if (mBtn[0] == 1)
+	    {
+	        if (mBtn[0] != toggle_flycam)
+	        {
+	            toggle_flycam = toggleFlycam() ? 1 : 0;
+	        }
+	    }
+	    else
+	    {
+	        toggle_flycam = 0;
+	    }
+	}
 
     if (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && mBuildEnabled))
     {
@@ -1617,6 +2046,7 @@ void LLViewerJoystick::setSNDefaults()
 
     //gViewerWindow->alertXml("CacheWillClear");
     LL_INFOS("Joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
+    gSavedSettings.setBOOL("BlackDragonControls", FALSE);
 
     gSavedSettings.setS32("JoystickAxis0", 1); // z (at)
     gSavedSettings.setS32("JoystickAxis1", 0); // x (slide)
@@ -1626,6 +2056,19 @@ void LLViewerJoystick::setSNDefaults()
     gSavedSettings.setS32("JoystickAxis5", 5); // yaw
     gSavedSettings.setS32("JoystickAxis6", -1);
 
+	gSavedSettings.setS32("JoystickButtonJump", -1);
+	gSavedSettings.setS32("JoystickButtonCrouch", -1);
+	gSavedSettings.setS32("JoystickButtonFly", -1);
+	gSavedSettings.setS32("JoystickButtonRunToggle", -1);
+	gSavedSettings.setS32("JoystickButtonMouselook", -1);
+	gSavedSettings.setS32("JoystickButtonZoomDefault", -1);
+	gSavedSettings.setS32("JoystickButtonFlycam", 0);
+	gSavedSettings.setS32("JoystickButtonZoomOut", -1);
+	gSavedSettings.setS32("JoystickButtonZoomIn", -1);
+	gSavedSettings.setS32("JoystickButtonRollLeft", -1);
+	gSavedSettings.setS32("JoystickButtonRollRight", -1);
+	gSavedSettings.setS32("JoystickButtonRollDefault", -1);
+	
     gSavedSettings.setBOOL("Cursor3D", is_3d_cursor);
     gSavedSettings.setBOOL("AutoLeveling", true);
     gSavedSettings.setBOOL("ZoomDirect", false);
@@ -1680,6 +2123,7 @@ void LLViewerJoystick::setSNDefaults()
 void LLViewerJoystick::setXboxDefaults()
 {
     LL_INFOS() << "restoring Xbox Controller defaults..." << LL_ENDL;
+    gSavedSettings.setBOOL("BlackDragonControls", TRUE);
 
     gSavedSettings.setS32("JoystickAxis0", 1);  // Z
     gSavedSettings.setS32("JoystickAxis1", 0);  // X
@@ -1689,6 +2133,19 @@ void LLViewerJoystick::setXboxDefaults()
     gSavedSettings.setS32("JoystickAxis5", 3);  // Yaw
     gSavedSettings.setS32("JoystickAxis6", -1); // Zoom
 
+	gSavedSettings.setS32("JoystickButtonJump", 0);
+	gSavedSettings.setS32("JoystickButtonCrouch", 1);
+	gSavedSettings.setS32("JoystickButtonFly", 2);
+	gSavedSettings.setS32("JoystickButtonRunToggle", 8);
+	gSavedSettings.setS32("JoystickButtonMouselook", 9);
+	gSavedSettings.setS32("JoystickButtonZoomDefault", 6);
+	gSavedSettings.setS32("JoystickButtonFlycam", 7);
+	gSavedSettings.setS32("JoystickButtonZoomOut", 5);
+	gSavedSettings.setS32("JoystickButtonZoomIn", 4);
+	gSavedSettings.setS32("JoystickButtonRollLeft", -1);
+	gSavedSettings.setS32("JoystickButtonRollRight", -1);
+	gSavedSettings.setS32("JoystickButtonRollDefault", -1);
+	
     gSavedSettings.setBOOL("Cursor3D", false); // Xbox Gamepad, not 3D Mouse
     gSavedSettings.setBOOL("AutoLeveling", false);
     gSavedSettings.setBOOL("ZoomDirect", false);
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 51a1c26d8b112f9851c82489518665feac61d0d9..19e544f7da754ebb294125ad8867098aadc22ef8 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -46,6 +46,67 @@ typedef enum e_joystick_driver_state
     JDS_INITIALIZING
 } EJoystickDriverState;
 
+typedef enum E_Buttons
+{
+	ROLL_LEFT = 0,
+	ROLL_RIGHT,
+	ROLL_DEFAULT ,
+	ZOOM_IN,
+	ZOOM_OUT,
+	ZOOM_DEFAULT,
+	JUMP,
+	CROUCH,
+	FLY,
+	MOUSELOOK,
+	FLYCAM,
+	TOGGLE_RUN,
+	MAX_BUTTONS
+} E_buttons;
+
+typedef enum E_Axes
+{
+	X_AXIS = 0,
+	Y_AXIS = 1,
+	Z_AXIS = 2,
+	CAM_X_AXIS = 3,
+	CAM_Y_AXIS = 4,
+	CAM_Z_AXIS = 5,
+	CAM_W_AXIS = 6,
+	MAX_AXES = 7
+} E_Axes;
+
+typedef enum E_AVScalings
+{
+	AV_AXIS_0 = 0,
+	AV_AXIS_1,
+	AV_AXIS_2,
+	AV_AXIS_3,
+	AV_AXIS_4,
+	AV_AXIS_5,
+} E_AVScalings;
+
+typedef enum E_BuildScalings
+{
+	BUILD_AXIS_0 = 0,
+	BUILD_AXIS_1,
+	BUILD_AXIS_2,
+	BUILD_AXIS_3,
+	BUILD_AXIS_4,
+	BUILD_AXIS_5,
+} E_BuildScalings;
+
+typedef enum E_FlycamScalings
+{
+	FLYCAM_AXIS_0 = 0,
+	FLYCAM_AXIS_1,
+	FLYCAM_AXIS_2,
+	FLYCAM_AXIS_3,
+	FLYCAM_AXIS_4,
+	FLYCAM_AXIS_5,
+	FLYCAM_AXIS_6,
+} E_FlycamScalings;
+
+
 class LLViewerJoystick final : public LLSingleton<LLViewerJoystick>
 {
     LLSINGLETON(LLViewerJoystick);
@@ -132,6 +193,7 @@ class LLViewerJoystick final : public LLSingleton<LLViewerJoystick>
     bool mAvatarEnabled;
     bool mBuildEnabled;
     bool mFlycamEnabled;
+    S32 mMappedButtons[MAX_BUTTONS];
     F32 mAvatarAxisScale[6];
     F32 mBuildAxisScale[6];
     F32 mFlycamAxisScale[7];
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index eab371f8b27a740bd8c67aa9855e71df686b737a..36ba00251e5b867d91d520c931839ce20f5b6a75 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -967,4 +967,25 @@ with the same filename but different name
 
   <texture name="Cam_Recall" file_name="icons/Cam_Recall.png"/>
   <texture name="Cam_Save" file_name="icons/Cam_Save.png"/>
+
+  <texture name="Button_A" file_name="xbox/button_a.png" preload="false" />
+  <texture name="Button_B" file_name="xbox/button_b.png" preload="false" />
+  <texture name="Button_Y" file_name="xbox/button_y.png" preload="false" />
+  <texture name="Button_X" file_name="xbox/button_x.png" preload="false" />
+  <texture name="Button_Back" file_name="xbox/button_back.png" preload="false" />
+  <texture name="Button_Start" file_name="xbox/button_start.png" preload="false" />
+  <texture name="Left_Button" file_name="xbox/left_button.png" preload="false" />
+  <texture name="Right_Button" file_name="xbox/right_button.png" preload="false" />
+  <texture name="Left_Thumb" file_name="xbox/left_thumb.png" preload="false" />
+  <texture name="Right_Thumb" file_name="xbox/right_thumb.png" preload="false" />
+  <texture name="Left_Thumb_Press" file_name="xbox/left_thumb_press.png" preload="false" />
+  <texture name="Right_Thumb_Press" file_name="xbox/right_thumb_press.png" preload="false" />
+  <texture name="Left_Thumb_X" file_name="xbox/left_thumb_x.png" preload="false" />
+  <texture name="Right_Thumb_X" file_name="xbox/right_thumb_x.png" preload="false" />
+  <texture name="Left_Thumb_Y" file_name="xbox/left_thumb_y.png" preload="false" />
+  <texture name="Right_Thumb_Y" file_name="xbox/right_thumb_y.png" preload="false" />
+  <texture name="Left_Trigger" file_name="xbox/left_trigger.png" preload="false" />
+  <texture name="Right_Trigger" file_name="xbox/right_trigger.png" preload="false" />
+  <texture name="Triggers" file_name="xbox/triggers.png" preload="false" />
+  <texture name="None" file_name="xbox/none.png" preload="false" />
 </textures>
diff --git a/indra/newview/skins/default/textures/xbox/button_a.png b/indra/newview/skins/default/textures/xbox/button_a.png
new file mode 100644
index 0000000000000000000000000000000000000000..09d2fc5623110512e54e18704f48000bccd1c4cc
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/button_a.png differ
diff --git a/indra/newview/skins/default/textures/xbox/button_b.png b/indra/newview/skins/default/textures/xbox/button_b.png
new file mode 100644
index 0000000000000000000000000000000000000000..d88699f8884c7f34b3e8c4d0364bc38b3a5b5366
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/button_b.png differ
diff --git a/indra/newview/skins/default/textures/xbox/button_back.png b/indra/newview/skins/default/textures/xbox/button_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..af2ca91ede0f35c00e8306354c68ba400f7467ee
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/button_back.png differ
diff --git a/indra/newview/skins/default/textures/xbox/button_start.png b/indra/newview/skins/default/textures/xbox/button_start.png
new file mode 100644
index 0000000000000000000000000000000000000000..11db7f3de1dd4e1567e04f7448f987e18570a0fb
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/button_start.png differ
diff --git a/indra/newview/skins/default/textures/xbox/button_x.png b/indra/newview/skins/default/textures/xbox/button_x.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6fb980b78bb03ff7158a4444234b4b8b82f4cfa
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/button_x.png differ
diff --git a/indra/newview/skins/default/textures/xbox/button_y.png b/indra/newview/skins/default/textures/xbox/button_y.png
new file mode 100644
index 0000000000000000000000000000000000000000..774dbb4a67771a57377bac723e922e9b70987e89
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/button_y.png differ
diff --git a/indra/newview/skins/default/textures/xbox/left_button.png b/indra/newview/skins/default/textures/xbox/left_button.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2a84340e63c9cf3bed53df36ad71ac318c4ee9f
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/left_button.png differ
diff --git a/indra/newview/skins/default/textures/xbox/left_thumb.png b/indra/newview/skins/default/textures/xbox/left_thumb.png
new file mode 100644
index 0000000000000000000000000000000000000000..75cbfd30956152fdf4af609439de3e72fb0cbdec
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/left_thumb.png differ
diff --git a/indra/newview/skins/default/textures/xbox/left_thumb_press.png b/indra/newview/skins/default/textures/xbox/left_thumb_press.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e710f9ff9ef80deb6ca7d7f54363e56b611af3c
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/left_thumb_press.png differ
diff --git a/indra/newview/skins/default/textures/xbox/left_thumb_x.png b/indra/newview/skins/default/textures/xbox/left_thumb_x.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d6711a6979e2a2a97368397587992b494f5f2e2
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/left_thumb_x.png differ
diff --git a/indra/newview/skins/default/textures/xbox/left_thumb_y.png b/indra/newview/skins/default/textures/xbox/left_thumb_y.png
new file mode 100644
index 0000000000000000000000000000000000000000..3384a50c7a05c5de81e6c685afb4f1a88764a7d2
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/left_thumb_y.png differ
diff --git a/indra/newview/skins/default/textures/xbox/left_trigger.png b/indra/newview/skins/default/textures/xbox/left_trigger.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa68944df8f41d50cbafe024c56a1a180a91e2ad
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/left_trigger.png differ
diff --git a/indra/newview/skins/default/textures/xbox/none.png b/indra/newview/skins/default/textures/xbox/none.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b6ec1c74c0ef84c267f5043ca5284ab2a82a6b9
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/none.png differ
diff --git a/indra/newview/skins/default/textures/xbox/right_button.png b/indra/newview/skins/default/textures/xbox/right_button.png
new file mode 100644
index 0000000000000000000000000000000000000000..094349661cb1e76d8c2e3363b3a0468c5aa4d0d2
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/right_button.png differ
diff --git a/indra/newview/skins/default/textures/xbox/right_thumb.png b/indra/newview/skins/default/textures/xbox/right_thumb.png
new file mode 100644
index 0000000000000000000000000000000000000000..d254f7847927720eef28aeb74c0f510f1f711711
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/right_thumb.png differ
diff --git a/indra/newview/skins/default/textures/xbox/right_thumb_press.png b/indra/newview/skins/default/textures/xbox/right_thumb_press.png
new file mode 100644
index 0000000000000000000000000000000000000000..fbeba206dc0cf21ed11c8712ada9a57ed02f89a7
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/right_thumb_press.png differ
diff --git a/indra/newview/skins/default/textures/xbox/right_thumb_x.png b/indra/newview/skins/default/textures/xbox/right_thumb_x.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5c1ce2c975a40025053bc53727816c333d62ce9
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/right_thumb_x.png differ
diff --git a/indra/newview/skins/default/textures/xbox/right_thumb_y.png b/indra/newview/skins/default/textures/xbox/right_thumb_y.png
new file mode 100644
index 0000000000000000000000000000000000000000..9cfdebd85dba9257e1db97c76b16f59c2876fdab
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/right_thumb_y.png differ
diff --git a/indra/newview/skins/default/textures/xbox/right_trigger.png b/indra/newview/skins/default/textures/xbox/right_trigger.png
new file mode 100644
index 0000000000000000000000000000000000000000..0afa104f6e09fc736ae82259c64fd56f40c6e575
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/right_trigger.png differ
diff --git a/indra/newview/skins/default/textures/xbox/triggers.png b/indra/newview/skins/default/textures/xbox/triggers.png
new file mode 100644
index 0000000000000000000000000000000000000000..462f2deacb5c51b63783f4da6acf35c4a8bf2684
Binary files /dev/null and b/indra/newview/skins/default/textures/xbox/triggers.png differ
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
index a84fe28cf79fd9532d404d0ed99345d0b3fb8973..05f0fbbcae5d776838f1b058cc27585af7205b38 100644
--- a/indra/newview/skins/default/xui/en/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <floater
  legacy_header_height="18"
- height="500"
+ height="700"
  layout="topleft"
  name="Joystick"
  help_topic="Viewerhelp:Joystick_Configuration"
  title="JOYSTICK CONFIGURATION"
- width="569">
+ width="565">
     <floater.string
      name="JoystickDisabled">
         None
@@ -175,7 +175,7 @@
      bottom="134"
      height="10"     
      control_name="JoystickAvatarEnabled"
-     halign="center"
+     halign="left"
      label="Avatar"
      layout="topleft"
      left="150"
@@ -185,7 +185,7 @@
      bottom_delta="0"
      height="10"     
      control_name="JoystickBuildEnabled"
-     halign="center"
+     halign="left"
      label="Build"
      layout="topleft"
      left="219"
@@ -195,7 +195,7 @@
      bottom_delta="0"
      height="10"     
      control_name="JoystickFlycamEnabled"
-     halign="center"
+     halign="left"
      label="Flycam"
      layout="topleft"
      left="289"
@@ -892,6 +892,1654 @@
      left="290"
      name="FlycamAxisDeadZone6"
      width="56" />
+     <text
+     name="general_label"
+     follows="left|top"
+     layout="topleft"
+     top_pad="5" 
+     left="30" 
+     height="12"
+     width="94">
+     Button Mapping:
+     </text>
+       <text
+       top_pad="7"
+       height="18"
+       label_width="125"
+       layout="topleft"
+       left_delta="0"
+       name="JoystickButtonJump"
+       width="90" >
+       Jump
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonJump"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonJump"
+           top_delta="0"
+           width="170">
+           <icons_combo_box.drop_down_button
+           image_overlay="None"
+           image_overlay_alignment="left"
+           imgoverlay_label_space="3"
+           pad_left="3"/>
+           <icons_combo_box.item
+              name="none"
+              value="-1">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="None"
+                value="None"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="btn_a"
+              value="0">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Button A"
+                value="Button_A"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="btn_b"
+              value="1">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Button B"
+                value="Button_B"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="btn_y"
+              value="3">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Button Y"
+                value="Button_Y"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="btn_x"
+              value="2">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Button X"
+                value="Button_X"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="back"
+              value="6">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Back"
+                value="Button_Back"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="start"
+              value="7">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Start"
+                value="Button_Start"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="button_left"
+              value="4">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Left Shoulder Button"
+                value="Left_Button"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="button_right"
+              value="5">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Right Shoulder Button"
+                value="Right_Button"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="thumb_l"
+              value="8">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Thumbstick Left"
+                value="Left_Thumb_Press"
+                width="20"/>
+            </icons_combo_box.item>
+           <icons_combo_box.item
+              name="thumb_r"
+              value="9">
+              <item.columns
+                halign="left"
+                type="icontext"
+                label="Thumbstick Right"
+                value="Right_Thumb_Press"
+                width="20"/>
+            </icons_combo_box.item>
+        </icons_combo_box>
+        <text
+       top_pad="5"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonCrouch"
+       width="90"
+       height="18" >
+       Crouch
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonCrouch"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonCrouch"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       top_pad="5"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonFly"
+       width="90" 
+       height="18">
+       Toggle Fly
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonFly"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonFly"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonRunToggle"
+       width="90" >
+       Toggle Run
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonRunToggle"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonRunToggle"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonMouselook"
+       width="90" >
+       Mouselook
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonMouselook"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonMouselook"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonFlycam"
+       width="90" >
+       Toggle Flycam
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonFlycam"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonFlycam"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_delta="-140"
+       label_width="125"
+       layout="topleft"
+       left_pad="10"
+       name="JoystickButtonZoomOut"
+       width="90" >
+       Zoom Out
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonZoomOut"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonZoomOut"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       label_width="125"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonZoomIn"
+       width="90" >
+       Zoom In
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonZoomIn"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonZoomIn"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       label_width="125"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonZoomDefault"
+       width="90" >
+       Zoom Default
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonZoomDefault"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonZoomDefault"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+        height="18"
+       top_pad="5"
+       label_width="125"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonRollLeft"
+       width="90" >
+       Roll Left
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonRollLeft"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonRollLeft"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       label_width="125"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonRollRight"
+       width="90" >
+       Roll Right
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonRollRight"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonRollRight"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+        <text
+       height="18"
+       top_pad="5"
+       label_width="125"
+       layout="topleft"
+       left_delta="-90"
+       name="JoystickButtonRollDefault"
+       width="90" >
+       Roll Default
+       </text>
+        <icons_combo_box
+           follows="left|top|right"
+           control_name="JoystickButtonRollDefault"
+           height="23"
+           layout="topleft"
+           left_pad="0"
+           name="JoystickButtonRollDefault"
+           top_delta="0"
+           width="170">
+              <icons_combo_box.commit_callback
+              function="Joystick.Refresh"/>
+              <icons_combo_box.drop_down_button
+              image_overlay="None"
+              image_overlay_alignment="left"
+              imgoverlay_label_space="3"
+              pad_left="3"/>
+              <icons_combo_box.item
+                 name="none"
+                 value="-1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="None"
+                   value="None"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_a"
+                 value="0">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button A"
+                   value="Button_A"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_b"
+                 value="1">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button B"
+                   value="Button_B"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_y"
+                 value="3">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button Y"
+                   value="Button_Y"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="btn_x"
+                 value="2">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Button X"
+                   value="Button_X"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="back"
+                 value="6">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Back"
+                   value="Button_Back"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="start"
+                 value="7">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Start"
+                   value="Button_Start"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_left"
+                 value="4">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Left Shoulder Button"
+                   value="Left_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="button_right"
+                 value="5">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Right Shoulder Button"
+                   value="Right_Button"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_l"
+                 value="8">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Left"
+                   value="Left_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+              <icons_combo_box.item
+                 name="thumb_r"
+                 value="9">
+                 <item.columns
+                   halign="left"
+                   type="icontext"
+                   label="Thumbstick Right"
+                   value="Right_Thumb_Press"
+                   width="20"/>
+               </icons_combo_box.item>
+          </icons_combo_box>
+
     <button
      follows="left|top"
      height="22"
@@ -916,9 +2564,9 @@
      label="OK"
      label_selected="OK"
      layout="topleft"
-     left_delta="0"
+     left="359"
      name="ok_btn"
-     top_pad="7"
+     top="650"
      width="98" />
     <button
      follows="right|bottom"