ref: 01b69307e00ee6c0a1366542b843f1495c79ea15
parent: afccf65a4e492befad0a0e6ba311fc1aa7659cc2
author: Thomas A. Birkel <[email protected]>
date: Fri Oct 14 20:29:21 EDT 2016
Add longtics and lowres_turn feature to Heretic/Hexen Allow demos to be recorded and played back assuming 16-bit resolution in player turns, similar to Doom's 1.91 hack. Unlike Doom, -longtics must also be specified using -playdemo and -timedemo. Also fixes a network consistency bug caused by some but not all players recording a demo. Partial implementation of #432
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -1031,6 +1031,14 @@
printf("Playing demo %s.\n", file);
}
+ //!
+ // @category demo
+ //
+ // Record a high turning resolution demo.
+ //
+
+ longtics = M_CheckParm("-longtics") != 0;
+
if (W_CheckNumForName(DEH_String("E2M1")) == -1)
{
gamemode = shareware;
--- a/src/heretic/d_net.c
+++ b/src/heretic/d_net.c
@@ -115,10 +115,17 @@
startmap = settings->map;
startskill = settings->skill;
// TODO startloadgame = settings->loadgame;
+ lowres_turn = settings->lowres_turn;
nomonsters = settings->nomonsters;
respawnparm = settings->respawn_monsters;
consoleplayer = settings->consoleplayer;
+ if (lowres_turn)
+ {
+ printf("NOTE: Turning resolution is reduced; this is probably "
+ "because there is a client recording a Vanilla demo.\n");
+ }
+
for (i = 0; i < MAXPLAYERS; ++i)
{
playeringame[i] = i < settings->num_players;
@@ -142,7 +149,9 @@
settings->nomonsters = nomonsters;
settings->respawn_monsters = respawnparm;
settings->timelimit = 0;
- settings->lowres_turn = false;
+
+ settings->lowres_turn = M_CheckParm("-record") > 0
+ && M_CheckParm("-longtics") == 0;
}
static void InitConnectData(net_connect_data_t *connect_data)
@@ -159,7 +168,10 @@
connect_data->gamemode = gamemode;
connect_data->gamemission = heretic;
- connect_data->lowres_turn = false;
+ // Are we recording a demo? Possibly set lowres turn mode
+
+ connect_data->lowres_turn = M_CheckParm("-record") > 0
+ && M_CheckParm("-longtics") == 0;
// Read checksums of our WAD directory and dehacked information
--- a/src/heretic/doomdef.h
+++ b/src/heretic/doomdef.h
@@ -527,6 +527,9 @@
extern int GetWeaponAmmo[NUMWEAPONS];
extern boolean demorecording;
+extern boolean lowres_turn; // Truncate angleturn in ticcmds to nearest 256.
+ // Used when recording Vanilla demos in netgames.
+extern boolean longtics; // specifies 16-bit angleturn resolution in demos
extern boolean demoplayback;
extern int skytexture;
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -110,6 +110,8 @@
char demoname[32];
boolean demorecording;
+boolean longtics;
+boolean lowres_turn;
boolean demoplayback;
byte *demobuffer, *demo_p, *demoend;
boolean singledemo; // quit after playing a demo from cmdline
@@ -622,6 +624,14 @@
BT_SPECIAL | BTS_SAVEGAME | (savegameslot << BTS_SAVESHIFT);
}
+ // low-res turning
+
+ if (lowres_turn)
+ {
+ // truncate angleturn to the nearest 256 boundary
+ // for recording demos with single byte values for turn
+ cmd->angleturn &= 0xff00;
+ }
}
@@ -1630,7 +1640,19 @@
}
cmd->forwardmove = ((signed char) *demo_p++);
cmd->sidemove = ((signed char) *demo_p++);
- cmd->angleturn = ((unsigned char) *demo_p++) << 8;
+
+ // If this is a longtics demo, read back in higher resolution
+
+ if (longtics)
+ {
+ cmd->angleturn = *demo_p++;
+ cmd->angleturn |= (*demo_p++) << 8;
+ }
+ else
+ {
+ cmd->angleturn = ((unsigned char) *demo_p++) << 8;
+ }
+
cmd->buttons = (unsigned char) *demo_p++;
cmd->lookfly = (unsigned char) *demo_p++;
cmd->arti = (unsigned char) *demo_p++;
@@ -1638,16 +1660,35 @@
void G_WriteDemoTiccmd(ticcmd_t * cmd)
{
+ byte *demo_start;
+
if (gamekeydown[key_demo_quit]) // press to end demo recording
G_CheckDemoStatus();
+
+ demo_start = demo_p;
+
*demo_p++ = cmd->forwardmove;
*demo_p++ = cmd->sidemove;
- *demo_p++ = cmd->angleturn >> 8;
+
+ // If this is a longtics demo, record in higher resolution
+
+ if (longtics)
+ {
+ *demo_p++ = (cmd->angleturn & 0xff);
+ *demo_p++ = (cmd->angleturn >> 8) & 0xff;
+ }
+ else
+ {
+ *demo_p++ = cmd->angleturn >> 8;
+ }
+
*demo_p++ = cmd->buttons;
*demo_p++ = cmd->lookfly;
*demo_p++ = cmd->arti;
- demo_p -= 6;
+ // reset demo pointer back
+ demo_p = demo_start;
+
if (demo_p > demoend - 16)
{
// no more space
@@ -1673,6 +1714,10 @@
{
int i;
int maxsize;
+
+ // If not recording a longtics demo, record in low res
+
+ lowres_turn = !longtics;
G_InitNew(skill, episode, map);
usergame = false;
--- a/src/hexen/d_net.c
+++ b/src/hexen/d_net.c
@@ -116,10 +116,17 @@
startmap = settings->map;
startskill = settings->skill;
// TODO startloadgame = settings->loadgame;
+ lowres_turn = settings->lowres_turn;
nomonsters = settings->nomonsters;
respawnparm = settings->respawn_monsters;
consoleplayer = settings->consoleplayer;
+ if (lowres_turn)
+ {
+ printf("NOTE: Turning resolution is reduced; this is probably "
+ "because there is a client recording a Vanilla demo.\n");
+ }
+
for (i=0; i<maxplayers; ++i)
{
playeringame[i] = i < settings->num_players;
@@ -154,7 +161,9 @@
settings->nomonsters = nomonsters;
settings->respawn_monsters = respawnparm;
settings->timelimit = 0;
- settings->lowres_turn = false;
+
+ settings->lowres_turn = M_CheckParm("-record") > 0
+ && M_CheckParm("-longtics") == 0;
}
static void InitConnectData(net_connect_data_t *connect_data)
@@ -170,7 +179,11 @@
connect_data->gamemode = gamemode;
connect_data->gamemission = hexen;
- connect_data->lowres_turn = false;
+ // Are we recording a demo? Possibly set lowres turn mode
+
+ connect_data->lowres_turn = M_CheckParm("-record") > 0
+ && M_CheckParm("-longtics") == 0;
+
connect_data->drone = false;
connect_data->max_players = maxplayers;
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -93,6 +93,8 @@
char demoname[32];
boolean demorecording;
+boolean longtics;
+boolean lowres_turn;
boolean demoplayback;
byte *demobuffer, *demo_p, *demoend;
boolean singledemo; // quit after playing a demo from cmdline
@@ -622,6 +624,15 @@
cmd->buttons =
BT_SPECIAL | BTS_SAVEGAME | (savegameslot << BTS_SAVESHIFT);
}
+
+ // low-res turning
+
+ if (lowres_turn)
+ {
+ // truncate angleturn to the nearest 256 boundary
+ // for recording demos with single byte values for turn
+ cmd->angleturn &= 0xff00;
+ }
}
@@ -1782,7 +1793,19 @@
}
cmd->forwardmove = ((signed char) *demo_p++);
cmd->sidemove = ((signed char) *demo_p++);
- cmd->angleturn = ((unsigned char) *demo_p++) << 8;
+
+ // If this is a longtics demo, read back in higher resolution
+
+ if (longtics)
+ {
+ cmd->angleturn = *demo_p++;
+ cmd->angleturn |= (*demo_p++) << 8;
+ }
+ else
+ {
+ cmd->angleturn = ((unsigned char) *demo_p++) << 8;
+ }
+
cmd->buttons = (unsigned char) *demo_p++;
cmd->lookfly = (unsigned char) *demo_p++;
cmd->arti = (unsigned char) *demo_p++;
@@ -1790,16 +1813,35 @@
void G_WriteDemoTiccmd(ticcmd_t * cmd)
{
+ byte *demo_start;
+
if (gamekeydown[key_demo_quit]) // press to end demo recording
G_CheckDemoStatus();
+
+ demo_start = demo_p;
+
*demo_p++ = cmd->forwardmove;
*demo_p++ = cmd->sidemove;
- *demo_p++ = cmd->angleturn >> 8;
+
+ // If this is a longtics demo, record in higher resolution
+
+ if (longtics)
+ {
+ *demo_p++ = (cmd->angleturn & 0xff);
+ *demo_p++ = (cmd->angleturn >> 8) & 0xff;
+ }
+ else
+ {
+ *demo_p++ = cmd->angleturn >> 8;
+ }
+
*demo_p++ = cmd->buttons;
*demo_p++ = cmd->lookfly;
*demo_p++ = cmd->arti;
- demo_p -= 6;
+ // reset demo pointer back
+ demo_p = demo_start;
+
if (demo_p > demoend - 16)
{
// no more space
@@ -1825,6 +1867,10 @@
{
int i;
int maxsize;
+
+ // If not recording a longtics demo, record in low res
+
+ lowres_turn = !longtics;
G_InitNew(skill, episode, map);
usergame = false;
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -676,6 +676,14 @@
ST_Message("Playing demo %s.\n", myargv[p+1]);
}
+ //!
+ // @category demo
+ //
+ // Record a high turning resolution demo.
+ //
+
+ longtics = M_CheckParm("-longtics") != 0;
+
if (M_ParmExists("-testcontrols"))
{
autostart = true;
--- a/src/hexen/h2def.h
+++ b/src/hexen/h2def.h
@@ -632,6 +632,9 @@
extern boolean DebugSound; // debug flag for displaying sound info
+extern boolean lowres_turn; // Truncate angleturn in ticcmds to nearest 256.
+ // Used when recording Vanilla demos in netgames.
+extern boolean longtics; // specifies 16-bit angleturn resolution in demos
extern boolean demoplayback;
extern int maxzone; // Maximum chunk allocated for zone heap