foxygit / doom Log in
commit 05200b0232831c337fda365d0d2d7acc87acfc0c
Author:     Michael Day <contact@michaelcday.com>
AuthorDate: Thu Oct 19 22:58:52 2023 -0400
Commit:     Michael Day <contact@michaelcday.com>
CommitDate: Wed Oct 25 22:29:00 2023 -0400

    Add analog control to non-Doom games
---
 src/heretic/g_game.c | 97 ++++++++++++++++++++++++++++++++++++++++++---------
 src/hexen/g_game.c   | 98 +++++++++++++++++++++++++++++++++++++++++++---------
 src/setup/joystick.c |  2 +-
 src/strife/g_game.c  | 76 +++++++++++++++++++++++++++++++---------
 4 files changed, 224 insertions(+), 49 deletions(-)

diff --git a/src/heretic/g_game.c b/src/heretic/g_game.c
index 8f0fa9bf..666384da 100644
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -23,6 +23,7 @@
 #include "doomkeys.h"
 #include "deh_str.h"
 #include "i_input.h"
+#include "i_joystick.h"
 #include "i_timer.h"
 #include "i_system.h"
 #include "m_argv.h"
@@ -351,10 +352,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
             side += sidemove[speed];
         if (gamekeydown[key_left] || mousebuttons[mousebturnleft])
             side -= sidemove[speed];
-        if (joyxmove > 0)
-            side += sidemove[speed];
-        if (joyxmove < 0)
-            side -= sidemove[speed];
+        if (use_analog && joyxmove)
+        {
+            joyxmove = joyxmove * joystick_move_sensitivity / 10;
+            joyxmove = (joyxmove > FRACUNIT) ? FRACUNIT : joyxmove;
+            joyxmove = (joyxmove < -FRACUNIT) ? -FRACUNIT : joyxmove;
+            side += FixedMul(sidemove[speed], joyxmove);
+        }
+        else
+        {
+            if (joyxmove > 0)
+                side += sidemove[speed];
+            if (joyxmove < 0)
+                side -= sidemove[speed];
+        }
     }
     else
     {
@@ -362,36 +373,90 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
             cmd->angleturn -= angleturn[tspeed];
         if (gamekeydown[key_left] || mousebuttons[mousebturnleft])
             cmd->angleturn += angleturn[tspeed];
-        if (joyxmove > 0)
-            cmd->angleturn -= angleturn[tspeed];
-        if (joyxmove < 0)
-            cmd->angleturn += angleturn[tspeed];
+        if (use_analog && joyxmove)
+        {
+            // Cubic response curve allows for finer control when stick
+            // deflection is small.
+            joyxmove = FixedMul(FixedMul(joyxmove, joyxmove), joyxmove);
+            joyxmove = joyxmove * joystick_turn_sensitivity / 10;
+            cmd->angleturn -= FixedMul(angleturn[1], joyxmove);
+        }
+        else
+        {
+            if (joyxmove > 0)
+                cmd->angleturn -= angleturn[tspeed];
+            if (joyxmove < 0)
+                cmd->angleturn += angleturn[tspeed];
+        }
     }

     if (gamekeydown[key_up])
         forward += forwardmove[speed];
     if (gamekeydown[key_down])
         forward -= forwardmove[speed];
-    if (joyymove < 0)
-        forward += forwardmove[speed];
-    if (joyymove > 0)
-        forward -= forwardmove[speed];
+    if (use_analog && joyymove)
+    {
+        joyymove = joyymove * joystick_move_sensitivity / 10;
+        joyymove = (joyymove > FRACUNIT) ? FRACUNIT : joyymove;
+        joyymove = (joyymove < -FRACUNIT) ? FRACUNIT : joyymove;
+        forward -= FixedMul(forwardmove[speed], joyymove);
+    }
+    else
+    {
+        if (joyymove < 0)
+            forward += forwardmove[speed];
+        if (joyymove > 0)
+            forward -= forwardmove[speed];
+    }
     if (gamekeydown[key_straferight] || mousebuttons[mousebstraferight]
-     || joybuttons[joybstraferight] || joystrafemove > 0)
+     || joybuttons[joybstraferight])
         side += sidemove[speed];
     if (gamekeydown[key_strafeleft] || mousebuttons[mousebstrafeleft]
-     || joybuttons[joybstrafeleft] || joystrafemove < 0)
+     || joybuttons[joybstrafeleft])
         side -= sidemove[speed];

+    if (use_analog && joystrafemove)
+    {
+        joystrafemove = joystrafemove * joystick_move_sensitivity / 10;
+        joystrafemove = (joystrafemove > FRACUNIT) ? FRACUNIT : joystrafemove;
+        joystrafemove = (joystrafemove < -FRACUNIT) ? -FRACUNIT : joystrafemove;
+        side += FixedMul(sidemove[speed], joystrafemove);
+    }
+    else
+    {
+        if (joystrafemove < 0)
+            side -= sidemove[speed];
+        if (joystrafemove > 0)
+            side += sidemove[speed];
+    }
     // Look up/down/center keys
-    if (gamekeydown[key_lookup] || joylook < 0)
+    if (gamekeydown[key_lookup])
     {
         look = lspeed;
     }
-    if (gamekeydown[key_lookdown] || joylook > 0)
+    if (gamekeydown[key_lookdown])
     {
         look = -lspeed;
     }
+    if (use_analog && joylook)
+    {
+        joylook = joylook * joystick_look_sensitivity / 10;
+        joylook = (joylook > FRACUNIT) ? FRACUNIT : joylook;
+        joylook = (joylook < -FRACUNIT) ? -FRACUNIT : joylook;
+        look = -FixedMul(2, joylook);
+    }
+    else
+    {
+        if (joylook < 0)
+        {
+            look = lspeed;
+        }
+
+        if (joylook > 0)
+        {
+            look = -lspeed;
+        }
+    }
     // haleyjd: removed externdriver crap
     if (gamekeydown[key_lookcenter])
     {
diff --git a/src/hexen/g_game.c b/src/hexen/g_game.c
index 8426edeb..972178b9 100644
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -21,6 +21,7 @@
 #include "s_sound.h"
 #include "doomkeys.h"
 #include "i_input.h"
+#include "i_joystick.h"
 #include "i_video.h"
 #include "i_system.h"
 #include "i_timer.h"
@@ -272,13 +273,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
         {
             side -= sidemove[pClass][speed];
         }
-        if (joyxmove > 0)
+        if (use_analog && joyxmove)
         {
-            side += sidemove[pClass][speed];
+            joyxmove = joyxmove * joystick_move_sensitivity / 10;
+            joyxmove = (joyxmove > FRACUNIT) ? FRACUNIT : joyxmove;
+            joyxmove = (joyxmove < -FRACUNIT) ? -FRACUNIT : joyxmove;
+            side += FixedMul(sidemove[pClass][speed], joyxmove);
         }
-        if (joyxmove < 0)
+        else
         {
-            side -= sidemove[pClass][speed];
+            if (joyxmove > 0)
+            {
+                side += sidemove[pClass][speed];
+            }
+            if (joyxmove < 0)
+            {
+                side -= sidemove[pClass][speed];
+            }
         }
     }
     else
@@ -287,10 +298,21 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
             cmd->angleturn -= angleturn[tspeed];
         if (gamekeydown[key_left] || mousebuttons[mousebturnleft])
             cmd->angleturn += angleturn[tspeed];
-        if (joyxmove > 0)
-            cmd->angleturn -= angleturn[tspeed];
-        if (joyxmove < 0)
-            cmd->angleturn += angleturn[tspeed];
+        if (use_analog && joyxmove)
+        {
+            // Cubic response curve allows for finer control when stick
+            // deflection is small.
+            joyxmove = FixedMul(FixedMul(joyxmove, joyxmove), joyxmove);
+            joyxmove = joyxmove * joystick_turn_sensitivity / 10;
+            cmd->angleturn -= FixedMul(angleturn[1], joyxmove);
+        }
+        else
+        {
+            if (joyxmove > 0)
+                cmd->angleturn -= angleturn[tspeed];
+            if (joyxmove < 0)
+                cmd->angleturn += angleturn[tspeed];
+        }
     }

     if (gamekeydown[key_up])
@@ -301,34 +323,78 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
     {
         forward -= forwardmove[pClass][speed];
     }
-    if (joyymove < 0)
+    if (use_analog && joyymove)
     {
-        forward += forwardmove[pClass][speed];
+        joyymove = joyymove * joystick_move_sensitivity / 10;
+        joyymove = (joyymove > FRACUNIT) ? FRACUNIT : joyymove;
+        joyymove = (joyymove < -FRACUNIT) ? FRACUNIT : joyymove;
+        forward -= FixedMul(forwardmove[pClass][speed], joyymove);
     }
-    if (joyymove > 0)
+    else
     {
-        forward -= forwardmove[pClass][speed];
+        if (joyymove < 0)
+        {
+            forward += forwardmove[pClass][speed];
+        }
+        if (joyymove > 0)
+        {
+            forward -= forwardmove[pClass][speed];
+        }
     }
     if (gamekeydown[key_straferight] || mousebuttons[mousebstraferight]
-     || joystrafemove > 0 || joybuttons[joybstraferight])
+     || joybuttons[joybstraferight])
     {
         side += sidemove[pClass][speed];
     }
     if (gamekeydown[key_strafeleft] || mousebuttons[mousebstrafeleft]
-     || joystrafemove < 0 || joybuttons[joybstrafeleft])
+     || joybuttons[joybstrafeleft])
     {
         side -= sidemove[pClass][speed];
     }

+    if (use_analog && joystrafemove)
+    {
+        joystrafemove = joystrafemove * joystick_move_sensitivity / 10;
+        joystrafemove = (joystrafemove > FRACUNIT) ? FRACUNIT : joystrafemove;
+        joystrafemove = (joystrafemove < -FRACUNIT) ? -FRACUNIT : joystrafemove;
+        side += FixedMul(sidemove[pClass][speed], joystrafemove);
+    }
+    else
+    {
+        if (joystrafemove < 0)
+            side -= sidemove[pClass][speed];
+        if (joystrafemove > 0)
+            side += sidemove[pClass][speed];
+    }
+
     // Look up/down/center keys
-    if (gamekeydown[key_lookup] || joylook < 0)
+    if (gamekeydown[key_lookup])
     {
         look = lspeed;
     }
-    if (gamekeydown[key_lookdown] || joylook > 0)
+    if (gamekeydown[key_lookdown])
     {
         look = -lspeed;
     }
+    if (use_analog && joylook)
+    {
+        joylook = joylook * joystick_look_sensitivity / 10;
+        joylook = (joylook > FRACUNIT) ? FRACUNIT : joylook;
+        joylook = (joylook < -FRACUNIT) ? -FRACUNIT : joylook;
+        look = -FixedMul(2, joylook);
+    }
+    else
+    {
+        if (joylook < 0)
+        {
+            look = lspeed;
+        }
+
+        if (joylook > 0)
+        {
+            look = -lspeed;
+        }
+    }
     // haleyjd: removed externdriver crap
     if (gamekeydown[key_lookcenter])
     {
diff --git a/src/setup/joystick.c b/src/setup/joystick.c
index abb007f7..61358eca 100644
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -1155,7 +1155,7 @@ static void AdjustAnalog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
         TXT_NewLabel("Turn"),
         TXT_NewSpinControl(&joystick_turn_sensitivity, 0, 20),
         NULL);
-    if (gamemission == heretic || gamemission == hexen || gamemission == strife)
+    if (gamemission == heretic || gamemission == hexen)
     {
         TXT_AddWidgets(window,
             TXT_NewLabel("Look"),
diff --git a/src/strife/g_game.c b/src/strife/g_game.c
index a1675014..0eaf08e8 100644
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -35,6 +35,7 @@
 #include "m_saves.h" // STRIFE
 #include "m_random.h"
 #include "i_input.h"
+#include "i_joystick.h"
 #include "i_system.h"
 #include "i_timer.h"
 #include "i_video.h"
@@ -431,10 +432,20 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
             //	fprintf(stderr, "strafe left\n");
             side -= sidemove[speed];
         }
-        if (joyxmove > 0)
-            side += sidemove[speed];
-        if (joyxmove < 0)
-            side -= sidemove[speed];
+        if (use_analog && joyxmove)
+        {
+            joyxmove = joyxmove * joystick_move_sensitivity / 10;
+            joyxmove = (joyxmove > FRACUNIT) ? FRACUNIT : joyxmove;
+            joyxmove = (joyxmove < -FRACUNIT) ? -FRACUNIT : joyxmove;
+            side += FixedMul(sidemove[speed], joyxmove);
+        }
+        else
+        {
+            if (joyxmove > 0)
+                side += sidemove[speed];
+            if (joyxmove < 0)
+                side -= sidemove[speed];
+        }

     }
     else
@@ -443,10 +454,21 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
             cmd->angleturn -= angleturn[tspeed];
         if (gamekeydown[key_left] || mousebuttons[mousebturnleft])
             cmd->angleturn += angleturn[tspeed];
-        if (joyxmove > 0)
-            cmd->angleturn -= angleturn[tspeed];
-        if (joyxmove < 0)
-            cmd->angleturn += angleturn[tspeed];
+        if (use_analog && joyxmove)
+        {
+            // Cubic response curve allows for finer control when stick
+            // deflection is small.
+            joyxmove = FixedMul(FixedMul(joyxmove, joyxmove), joyxmove);
+            joyxmove = joyxmove * joystick_turn_sensitivity / 10;
+            cmd->angleturn -= FixedMul(angleturn[1], joyxmove);
+        }
+        else
+        {
+            if (joyxmove > 0)
+                cmd->angleturn -= angleturn[tspeed];
+            if (joyxmove < 0)
+                cmd->angleturn += angleturn[tspeed];
+        }
     }

     if (gamekeydown[key_up])
@@ -460,27 +482,49 @@ void G_BuildTiccmd (ticcmd_t* cmd, int maketic)
         forward -= forwardmove[speed];
     }

-    if (joyymove < 0)
-        forward += forwardmove[speed];
-    if (joyymove > 0)
-        forward -= forwardmove[speed];
+    if (use_analog && joyymove)
+    {
+        joyymove = joyymove * joystick_move_sensitivity / 10;
+        joyymove = (joyymove > FRACUNIT) ? FRACUNIT : joyymove;
+        joyymove = (joyymove < -FRACUNIT) ? FRACUNIT : joyymove;
+        forward -= FixedMul(forwardmove[speed], joyymove);
+    }
+    else
+    {
+        if (joyymove < 0)
+            forward += forwardmove[speed];
+        if (joyymove > 0)
+            forward -= forwardmove[speed];
+    }

     if (gamekeydown[key_strafeleft]
      || joybuttons[joybstrafeleft]
-     || mousebuttons[mousebstrafeleft]
-     || joystrafemove < 0)
+     || mousebuttons[mousebstrafeleft])
     {
         side -= sidemove[speed];
     }

     if (gamekeydown[key_straferight]
      || joybuttons[joybstraferight]
-     || mousebuttons[mousebstraferight]
-     || joystrafemove > 0)
+     || mousebuttons[mousebstraferight])
     {
         side += sidemove[speed];
     }

+    if (use_analog && joystrafemove)
+    {
+        joystrafemove = joystrafemove * joystick_move_sensitivity / 10;
+        joystrafemove = (joystrafemove > FRACUNIT) ? FRACUNIT : joystrafemove;
+        joystrafemove = (joystrafemove < -FRACUNIT) ? -FRACUNIT : joystrafemove;
+        side += FixedMul(sidemove[speed], joystrafemove);
+    }
+    else
+    {
+        if (joystrafemove < 0)
+            side -= sidemove[speed];
+        if (joystrafemove > 0)
+            side += sidemove[speed];
+    }
     // buttons
     cmd->chatchar = HU_dequeueChatChar();