ref: 9eae89d3eb668df2ea218f3944d12996e3364000
parent: 9eaf5ccf437353a2ad61ea033fd2acb7f396cdd1
author: James Canete <[email protected]>
date: Sun Oct 13 08:46:28 EDT 2019
Doom 1.2 demo support Mostly cribbed from prboom-plus
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -1051,6 +1051,13 @@
status = true;
switch (demoversion)
{
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ gameversion = exe_doom_1_2;
+ break;
case 106:
gameversion = exe_doom_1_666;
break;
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -2053,7 +2053,7 @@
switch (gameversion)
{
case exe_doom_1_2:
- I_Error("Doom 1.2 does not have a version code!");
+ return 102;
case exe_doom_1_666:
return 106;
case exe_doom_1_7:
@@ -2088,7 +2088,7 @@
{
*demo_p++ = DOOM_191_VERSION;
}
- else
+ else if (gameversion != exe_doom_1_2)
{
*demo_p++ = G_VanillaVersionCode();
}
@@ -2096,11 +2096,14 @@
*demo_p++ = gameskill;
*demo_p++ = gameepisode;
*demo_p++ = gamemap;
- *demo_p++ = deathmatch;
- *demo_p++ = respawnparm;
- *demo_p++ = fastparm;
- *demo_p++ = nomonsters;
- *demo_p++ = consoleplayer;
+ if (longtics || gameversion != exe_doom_1_2)
+ {
+ *demo_p++ = deathmatch;
+ *demo_p++ = respawnparm;
+ *demo_p++ = fastparm;
+ *demo_p++ = nomonsters;
+ *demo_p++ = consoleplayer;
+ }
for (i=0 ; i<MAXPLAYERS ; i++)
*demo_p++ = playeringame[i];
@@ -2148,7 +2151,7 @@
// Unknown version. Perhaps this is a pre-v1.4 IWAD? If the version
// byte is in the range 0-4 then it can be a v1.0-v1.2 demo.
- if (version >= 0 && version <= 4)
+ if (version == 102 || (version >= 0 && version <= 4))
{
return "v1.0/v1.1/v1.2";
}
@@ -2173,6 +2176,12 @@
demoversion = *demo_p++;
+ if (demoversion < 102)
+ {
+ demoversion = 102;
+ demo_p--;
+ }
+
longtics = false;
// Longtics demos use the modified format that is generated by cph's
@@ -2200,12 +2209,24 @@
skill = *demo_p++;
episode = *demo_p++;
map = *demo_p++;
- deathmatch = *demo_p++;
- respawnparm = *demo_p++;
- fastparm = *demo_p++;
- nomonsters = *demo_p++;
- consoleplayer = *demo_p++;
-
+ if (demoversion != 102)
+ {
+ deathmatch = *demo_p++;
+ respawnparm = *demo_p++;
+ fastparm = *demo_p++;
+ nomonsters = *demo_p++;
+ consoleplayer = *demo_p++;
+ }
+ else
+ {
+ deathmatch = 0;
+ respawnparm = 0;
+ fastparm = 0;
+ nomonsters = 0;
+ consoleplayer = 0;
+ }
+
+
for (i=0 ; i<MAXPLAYERS ; i++)
playeringame[i] = *demo_p++;
--- a/src/doom/m_menu.c
+++ b/src/doom/m_menu.c
@@ -2006,7 +2006,7 @@
{
name = DEH_String(currentMenu->menuitems[i].name);
- if (name[0])
+ if (name[0] && W_CheckNumForName(name) > 0)
{
V_DrawPatchDirect (x, y, W_CacheLumpName(name, PU_CACHE));
}
--- a/src/doom/p_enemy.c
+++ b/src/doom/p_enemy.c
@@ -168,6 +168,7 @@
{
mobj_t* pl;
fixed_t dist;
+ fixed_t range;
if (!actor->target)
return false;
@@ -175,8 +176,14 @@
pl = actor->target;
dist = P_AproxDistance (pl->x-actor->x, pl->y-actor->y);
- if (dist >= MELEERANGE-20*FRACUNIT+pl->info->radius)
- return false;
+ if (gameversion == exe_doom_1_2)
+ range = MELEERANGE;
+ else
+ range = MELEERANGE-20*FRACUNIT+pl->info->radius;
+
+ if (dist >= range)
+ return false;
+
if (! P_CheckSight (actor, actor->target) )
return false;
@@ -665,8 +672,8 @@
// modify target threshold
if (actor->threshold)
{
- if (!actor->target
- || actor->target->health <= 0)
+ if (gameversion != exe_doom_1_2 &&
+ (!actor->target || actor->target->health <= 0))
{
actor->threshold = 0;
}
@@ -925,11 +932,19 @@
return;
A_FaceTarget (actor);
- if (P_CheckMeleeRange (actor))
+
+ if (gameversion != exe_doom_1_2)
{
- damage = ((P_Random()%10)+1)*4;
- P_DamageMobj (actor->target, actor, actor, damage);
+ if (!P_CheckMeleeRange (actor))
+ return;
}
+
+ damage = ((P_Random()%10)+1)*4;
+
+ if (gameversion == exe_doom_1_2)
+ P_LineAttack(actor, actor->angle, MELEERANGE, 0, damage);
+ else
+ P_DamageMobj (actor->target, actor, actor, damage);
}
void A_HeadAttack (mobj_t* actor)
--- a/src/doom/p_floor.c
+++ b/src/doom/p_floor.c
@@ -303,7 +303,8 @@
floor->speed = FLOORSPEED * 4;
floor->floordestheight =
P_FindHighestFloorSurrounding(sec);
- if (floor->floordestheight != sec->floorheight)
+ if (gameversion == exe_doom_1_2 ||
+ floor->floordestheight != sec->floorheight)
floor->floordestheight += 8*FRACUNIT;
break;
--- a/src/doom/p_inter.c
+++ b/src/doom/p_inter.c
@@ -382,7 +382,7 @@
case SPR_BON2:
player->armorpoints++; // can go over 100%
- if (player->armorpoints > deh_max_armor)
+ if (player->armorpoints > deh_max_armor && gameversion != exe_doom_1_2)
player->armorpoints = deh_max_armor;
// deh_green_armor_class only applies to the green armor shirt;
// for the armor helmets, armortype 1 is always used.
@@ -907,7 +907,7 @@
target->reactiontime = 0; // we're awake now...
if ( (!target->threshold || target->type == MT_VILE)
- && source && source != target
+ && source && (source != target || gameversion == exe_doom_1_2)
&& source->type != MT_VILE)
{
// if not intent on another player,
--- a/src/doom/p_map.c
+++ b/src/doom/p_map.c
@@ -1317,7 +1317,8 @@
{
P_SetMobjState (thing, S_GIBS);
- thing->flags &= ~MF_SOLID;
+ if (gameversion != exe_doom_1_2)
+ thing->flags &= ~MF_SOLID;
thing->height = 0;
thing->radius = 0;
--- a/src/doom/p_sight.c
+++ b/src/doom/p_sight.c
@@ -16,9 +16,10 @@
// LineOfSight/Visibility checks, uses REJECT Lookup Table.
//
+#include <stdlib.h> // abs()
-
#include "doomdef.h"
+#include "doomstat.h"
#include "i_system.h"
#include "p_local.h"
@@ -40,6 +41,44 @@
int sightcounts[2];
+// PTR_SightTraverse() for Doom 1.2 sight calculations
+// taken from prboom-plus/src/p_sight.c:69-102
+boolean PTR_SightTraverse(intercept_t *in)
+{
+ line_t *li;
+ fixed_t slope;
+
+ li = in->d.line;
+
+ //
+ // crosses a two sided line
+ //
+ P_LineOpening(li);
+
+ if (openbottom >= opentop) // quick test for totally closed doors
+ return false; // stop
+
+ if (li->frontsector->floorheight != li->backsector->floorheight)
+ {
+ slope = FixedDiv(openbottom - sightzstart , in->frac);
+ if (slope > bottomslope)
+ bottomslope = slope;
+ }
+
+ if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
+ {
+ slope = FixedDiv(opentop - sightzstart, in->frac);
+ if (slope < topslope)
+ topslope = slope;
+ }
+
+ if (topslope <= bottomslope)
+ return false; // stop
+
+ return true; // keep going
+}
+
+
//
// P_DivlineSide
// Returns side 0 (front), 1 (back), or 2 (on).
@@ -336,6 +375,12 @@
topslope = (t2->z+t2->height) - sightzstart;
bottomslope = (t2->z) - sightzstart;
+ if (gameversion == exe_doom_1_2)
+ {
+ return P_PathTraverse(t1->x, t1->y, t2->x, t2->y,
+ PT_EARLYOUT | PT_ADDLINES, PTR_SightTraverse);
+ }
+
strace.x = t1->x;
strace.y = t1->y;
t2x = t2->x;
--- a/src/doom/p_spec.c
+++ b/src/doom/p_spec.c
@@ -509,24 +509,37 @@
line = &lines[linenum];
- // Triggers that other things can activate
+ if (gameversion == exe_doom_1_2)
+ {
+ if (line->special > 98 && line->special != 104)
+ {
+ return;
+ }
+ }
+ else
+ {
+ // Triggers that other things can activate
+ if (!thing->player)
+ {
+ // Things that should NOT trigger specials...
+ switch(thing->type)
+ {
+ case MT_ROCKET:
+ case MT_PLASMA:
+ case MT_BFG:
+ case MT_TROOPSHOT:
+ case MT_HEADSHOT:
+ case MT_BRUISERSHOT:
+ return;
+ break;
+
+ default: break;
+ }
+ }
+ }
+
if (!thing->player)
{
- // Things that should NOT trigger specials...
- switch(thing->type)
- {
- case MT_ROCKET:
- case MT_PLASMA:
- case MT_BFG:
- case MT_TROOPSHOT:
- case MT_HEADSHOT:
- case MT_BRUISERSHOT:
- return;
- break;
-
- default: break;
- }
-
ok = 0;
switch(line->special)
{
--- a/src/doom/s_sound.c
+++ b/src/doom/s_sound.c
@@ -445,6 +445,40 @@
I_Error("Bad sfx #: %d", sfx_id);
}
+ // substitute missing sounds in Doom 1.2
+ if (gameversion == exe_doom_1_2)
+ {
+ switch(sfx_id)
+ {
+ case sfx_bdcls:
+ sfx_id = sfx_dorcls;
+ break;
+
+ case sfx_bdopn:
+ sfx_id = sfx_doropn;
+ break;
+
+ case sfx_getpow:
+ sfx_id = sfx_itemup;
+ break;
+
+ case sfx_itmbk:
+ sfx_id = sfx_stnmov;
+ break;
+
+ case sfx_pdiehi:
+ sfx_id = sfx_pldeth;
+ break;
+
+ case sfx_tink:
+ sfx_id = sfx_swtchx;
+ break;
+
+ default:
+ break;
+ }
+ }
+
sfx = &S_sfx[sfx_id];
// Initialize sound parameters
@@ -661,7 +695,8 @@
// and d_introa. The latter is used for OPL playback.
if (musicnum == mus_intro && (snd_musicdevice == SNDDEVICE_ADLIB
- || snd_musicdevice == SNDDEVICE_SB))
+ || snd_musicdevice == SNDDEVICE_SB)
+ && W_CheckNumForName("D_INTROA") > 0)
{
musicnum = mus_introa;
}
--- a/src/doom/st_lib.c
+++ b/src/doom/st_lib.c
@@ -50,7 +50,10 @@
void STlib_init(void)
{
- sttminus = (patch_t *) W_CacheLumpName(DEH_String("STTMINUS"), PU_STATIC);
+ if (W_CheckNumForName(DEH_String("STTMINUS")) > 0)
+ sttminus = (patch_t *) W_CacheLumpName(DEH_String("STTMINUS"), PU_STATIC);
+ else
+ sttminus = NULL;
}
@@ -136,7 +139,7 @@
}
// draw a minus sign if necessary
- if (neg)
+ if (neg && sttminus)
V_DrawPatch(x - 8, n->y, sttminus);
}
--- a/src/doom/st_stuff.c
+++ b/src/doom/st_stuff.c
@@ -307,6 +307,9 @@
// main bar left
static patch_t* sbar;
+// main bar right, for doom 1.0
+static patch_t* sbarr;
+
// 0-9, tall numbers
static patch_t* tallnum[10];
@@ -422,6 +425,10 @@
V_DrawPatch(ST_X, 0, sbar);
+ // draw right side of bar if needed (Doom 1.0)
+ if (sbarr)
+ V_DrawPatch(ST_ARMSBGX, 0, sbarr);
+
if (netgame)
V_DrawPatch(ST_FX, 0, faceback);
@@ -1142,7 +1149,16 @@
callback(namebuf, &faceback);
// status bar background bits
- callback(DEH_String("STBAR"), &sbar);
+ if (W_CheckNumForName(DEH_String("STBAR")) > 0)
+ {
+ callback(DEH_String("STBAR"), &sbar);
+ sbarr = NULL;
+ }
+ else
+ {
+ callback(DEH_String("STMBARL"), &sbar);
+ callback(DEH_String("STMBARR"), &sbarr);
+ }
// face states
facenum = 0;
--- a/src/doom/wi_stuff.c
+++ b/src/doom/wi_stuff.c
@@ -675,7 +675,7 @@
}
// draw a minus sign if necessary
- if (neg)
+ if (neg && wiminus)
V_DrawPatch(x-=8, y, wiminus);
return x;
@@ -1613,7 +1613,10 @@
}
// More hacks on minus sign.
- callback(DEH_String("WIMINUS"), &wiminus);
+ if (W_CheckNumForName(DEH_String("WIMINUS")) > 0)
+ callback(DEH_String("WIMINUS"), &wiminus);
+ else
+ wiminus = NULL;
for (i=0;i<10;i++)
{