foxygit / doom Log in
commit 3d6f4785591eced3e4195a342980facd0adcb284
Author:     Thomas A. Birkel <capnclever@gmail.com>
AuthorDate: Sat Oct 15 00:53:43 2016 -0400
Commit:     Thomas A. Birkel <capnclever@gmail.com>
CommitDate: Sat Oct 15 00:53:43 2016 -0400

    g_game.c: Add -shortticfix optional feature for Heretic/Hexen.

    Doom's turning code during demos accurately rounds the value to produce
    a smooth resolution, which Heretic and Hexen lack by default. The
    -shortticfix parameter allows for this to be fixed in these games.

    Partial implementation of #432
---
 src/heretic/g_game.c | 34 +++++++++++++++++++++++++++++++---
 src/hexen/g_game.c   | 34 +++++++++++++++++++++++++++++++---
 2 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/src/heretic/g_game.c b/src/heretic/g_game.c
index ab10460f..65488b7b 100644
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -112,6 +112,7 @@ char demoname[32];
 boolean demorecording;
 boolean longtics;
 boolean lowres_turn;
+boolean shortticfix;        // properly calculates lowres turns like in doom
 boolean demoplayback;
 byte *demobuffer, *demo_p, *demoend;
 boolean singledemo;             // quit after playing a demo from cmdline
@@ -628,9 +629,29 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)

     if (lowres_turn)
     {
-        // truncate angleturn to the nearest 256 boundary
-        // for recording demos with single byte values for turn
-        cmd->angleturn &= 0xff00;
+        if (shortticfix)
+        {
+            static signed short carry = 0;
+            signed short desired_angleturn;
+
+            desired_angleturn = cmd->angleturn + carry;
+
+            // round angleturn to the nearest 256 unit boundary
+            // for recording demos with single byte values for turn
+
+            cmd->angleturn = (desired_angleturn + 128) & 0xff00;
+
+            // Carry forward the error from the reduced resolution to the
+            // next tic, so that successive small movements can accumulate.
+
+            carry = desired_angleturn - cmd->angleturn;
+        }
+        else
+        {
+            // truncate angleturn to the nearest 256 boundary
+            // for recording demos with single byte values for turn
+            cmd->angleturn &= 0xff00;
+        }
     }
 }

@@ -1719,6 +1740,13 @@ void G_RecordDemo(skill_t skill, int numplayers, int episode, int map,

     lowres_turn = !longtics;

+    //!
+    // @category demo
+    //
+    // Smooths out low turning resolution when recording a demo.
+    //
+    shortticfix = M_CheckParm("-shortticfix") != 0;
+
     G_InitNew(skill, episode, map);
     usergame = false;
     M_StringCopy(demoname, name, sizeof(demoname));
diff --git a/src/hexen/g_game.c b/src/hexen/g_game.c
index c01776c6..906b031e 100644
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -95,6 +95,7 @@ char demoname[32];
 boolean demorecording;
 boolean longtics;
 boolean lowres_turn;
+boolean shortticfix;        // properly calculates lowres turns like in doom
 boolean demoplayback;
 byte *demobuffer, *demo_p, *demoend;
 boolean singledemo;             // quit after playing a demo from cmdline
@@ -629,9 +630,29 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)

     if (lowres_turn)
     {
-        // truncate angleturn to the nearest 256 boundary
-        // for recording demos with single byte values for turn
-        cmd->angleturn &= 0xff00;
+        if (shortticfix)
+        {
+            static signed short carry = 0;
+            signed short desired_angleturn;
+
+            desired_angleturn = cmd->angleturn + carry;
+
+            // round angleturn to the nearest 256 unit boundary
+            // for recording demos with single byte values for turn
+
+            cmd->angleturn = (desired_angleturn + 128) & 0xff00;
+
+            // Carry forward the error from the reduced resolution to the
+            // next tic, so that successive small movements can accumulate.
+
+            carry = desired_angleturn - cmd->angleturn;
+        }
+        else
+        {
+            // truncate angleturn to the nearest 256 boundary
+            // for recording demos with single byte values for turn
+            cmd->angleturn &= 0xff00;
+        }
     }
 }

@@ -1870,6 +1891,13 @@ void G_RecordDemo(skill_t skill, int numplayers, int episode, int map,

     // If not recording a longtics demo, record in low res

+    //!
+    // @category demo
+    //
+    // Smooths out low turning resolution when recording a demo.
+    //
+    shortticfix = M_CheckParm("-shortticfix") != 0;
+
     lowres_turn = !longtics;

     G_InitNew(skill, episode, map);