ref: 21bcebf312e41a3b831c22f72bfd0e94368484e4
parent: 9eaf5ccf437353a2ad61ea033fd2acb7f396cdd1
parent: 5f7bfef2ab7a38ce5f7bda943719189fdc23a2c6
author: Simon Howard <fraggle@soulsphere.org>
date: Fri Oct 18 08:50:18 EDT 2019
Merge pull request #1205 from SmileTheory/chocolate-v12 Doom 1.2 demo support
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -959,6 +959,7 @@
const char *cmdline;
GameVersion_t version;
} gameversions[] = {
+ {"Doom 1.2", "1.2", exe_doom_1_2},
{"Doom 1.666", "1.666", exe_doom_1_666},
{"Doom 1.7/1.7a", "1.7", exe_doom_1_7},
{"Doom 1.8", "1.8", exe_doom_1_8},
@@ -986,9 +987,9 @@
// @arg <version>
// @category compat
//
- // Emulate a specific version of Doom. Valid values are "1.666",
- // "1.7", "1.8", "1.9", "ultimate", "final", "final2", "hacx" and
- // "chex".
+ // Emulate a specific version of Doom. Valid values are "1.2",
+ // "1.666", "1.7", "1.8", "1.9", "ultimate", "final", "final2",
+ // "hacx" and "chex".
//
p = M_CheckParmWithArgs("-gameversion", 1);
@@ -1051,6 +1052,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;
@@ -1088,6 +1096,12 @@
gameversion = exe_final;
}
+ }
+
+ // Deathmatch 2.0 did not exist until Doom v1.4
+ if (gameversion <= exe_doom_1_2 && deathmatch == 2)
+ {
+ deathmatch = 1;
}
// The original exe does not support retail - 4th episode not supported
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -2052,8 +2052,6 @@
{
switch (gameversion)
{
- case exe_doom_1_2:
- I_Error("Doom 1.2 does not have a version code!");
case exe_doom_1_666:
return 106;
case exe_doom_1_7:
@@ -2088,7 +2086,7 @@
{
*demo_p++ = DOOM_191_VERSION;
}
- else
+ else if (gameversion > exe_doom_1_2)
{
*demo_p++ = G_VanillaVersionCode();
}
@@ -2096,11 +2094,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];
@@ -2165,6 +2166,7 @@
skill_t skill;
int i, lumpnum, episode, map;
int demoversion;
+ boolean olddemo = false;
lumpnum = W_GetNumForName(defdemoname);
gameaction = ga_nothing;
@@ -2173,6 +2175,12 @@
demoversion = *demo_p++;
+ if (demoversion >= 0 && demoversion <= 4)
+ {
+ olddemo = true;
+ demo_p--;
+ }
+
longtics = false;
// Longtics demos use the modified format that is generated by cph's
@@ -2182,7 +2190,8 @@
{
longtics = true;
}
- else if (demoversion != G_VanillaVersionCode())
+ else if (demoversion != G_VanillaVersionCode() &&
+ !(gameversion <= exe_doom_1_2 && olddemo))
{
const char *message = "Demo is from a different game version!\n"
"(read %i, should be %i)\n"
@@ -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 (!olddemo)
+ {
+ 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/hu_stuff.c
+++ b/src/doom/hu_stuff.c
@@ -522,7 +522,7 @@
message_counter = HU_MSGTIMEOUT;
if ( gamemode == commercial )
S_StartSound(0, sfx_radio);
- else
+ else if (gameversion > exe_doom_1_2)
S_StartSound(0, sfx_tink);
}
HUlib_resetIText(&w_inputbuffer[i]);
--- 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.
@@ -397,7 +397,8 @@
player->health = deh_max_soulsphere;
player->mo->health = player->health;
player->message = DEH_String(GOTSUPER);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
case SPR_MEGA:
@@ -409,7 +410,8 @@
// affects the MegaArmor.
P_GiveArmor (player, 2);
player->message = DEH_String(GOTMSPHERE);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
// cards
@@ -485,7 +487,8 @@
if (!P_GivePower (player, pw_invulnerability))
return;
player->message = DEH_String(GOTINVUL);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
case SPR_PSTR:
@@ -494,7 +497,8 @@
player->message = DEH_String(GOTBERSERK);
if (player->readyweapon != wp_fist)
player->pendingweapon = wp_fist;
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
case SPR_PINS:
@@ -501,7 +505,8 @@
if (!P_GivePower (player, pw_invisibility))
return;
player->message = DEH_String(GOTINVIS);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
case SPR_SUIT:
@@ -508,7 +513,8 @@
if (!P_GivePower (player, pw_ironfeet))
return;
player->message = DEH_String(GOTSUIT);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
case SPR_PMAP:
@@ -515,7 +521,8 @@
if (!P_GivePower (player, pw_allmap))
return;
player->message = DEH_String(GOTMAP);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
case SPR_PVIS:
@@ -522,7 +529,8 @@
if (!P_GivePower (player, pw_infrared))
return;
player->message = DEH_String(GOTVISOR);
- sound = sfx_getpow;
+ if (gameversion > exe_doom_1_2)
+ sound = sfx_getpow;
break;
// ammo
@@ -907,7 +915,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
@@ -17,8 +17,8 @@
//
-
#include "doomdef.h"
+#include "doomstat.h"
#include "i_system.h"
#include "p_local.h"
@@ -40,6 +40,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 +374,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,36 @@
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;
+
+ 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
@@ -661,7 +661,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("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++)
{