Merge branch 'master' into sdl2-branch

This commit is contained in:
Fabian Greffrath 2016-09-17 13:12:26 +02:00
commit 5974dfc9ce
57 changed files with 590 additions and 218 deletions

View file

@ -70,6 +70,11 @@ following guidelines before opening a pull request:
* Please follow the coding style guidelines described in the
[HACKING](../HACKING.md) file.
* Please don't make unnecessary changes which just change formatting
without any actual change to program logic. While being consistent
is nice, such changes destroy the ability to use the `git blame`
command to see when code was last changed.
* The guidelines given above in the "feature requests" section also
apply here. New features which aren't in line with the project
philosophy are likely to be rejected. If you're not sure, open a

1
.gitignore vendored
View file

@ -19,6 +19,7 @@ stamp-h
stamp-h.in
stamp-h1
tags
\#*\#
# These are the default patterns globally ignored by Subversion:
*.o

View file

@ -12,6 +12,12 @@
* Checksum calculations were fixed on big endian systems, allowing
multiplayer games to be played in mixed little/big-endian
environments. (thanks GhostlyDeath, njankowski)
* The NES30, SNES30, and SFC30 gamepads are detected and configured
automatically by the Setup tool. The automap can also be
configured to a joystick button. (thanks Jon)
* The vanilla limit of 4046 lumps per WAD is now enforced. (thanks
Jon, Quasar, Edward-san)
* Solidsegs overflow is emulated like in vanilla. (thanks Quasar)
### Build systems
* Improved compatibility with BSD Make. (thanks R.Rebello)
@ -31,6 +37,8 @@
* Allow starting multiplayer Chex Quest games.
* Allow Freedoom: Phase 1 ≤ 0.10.1 to be loaded with mods, with
-gameversion older than ultimate. (thanks Fabian, chungy)
* The IWAD order preference for GOG.com installs matches vanilla
Final Doom: doom2, plutonia, tnt, doom. (thanks chungy)
* Added safety checks against write failures when saving a game,
such as when the directory is read-only. Try falling back to a
temporary directory and reporting an error instead. (thanks

View file

@ -19,12 +19,6 @@ AC_CHECK_PROG(HAVE_PYTHON, python, true, false)
OPT_LEVEL=2
# Engine room, we need more speed!
AC_ARG_ENABLE(penis-extension,
[ --enable-penis-extension Enable counterproductive compiler optimisations ],
[ OPT_LEVEL=3 ])
# If this is gcc, we have some options we'd like to turn on. Turn on
# optimisation and debugging symbols.

1
msvc/.gitignore vendored
View file

@ -2,6 +2,7 @@
*.ncb
*.suo
*.user
hexndata
savegames
strfsav*
*.pcx

View file

@ -65,6 +65,7 @@
IgnoreAllDefaultLibraries="false"
IgnoreDefaultLibraryNames="msvcrt"
GenerateDebugInformation="true"
GenerateMapFile="true"
SubSystem="1"
TargetMachine="1"
/>

View file

@ -21,7 +21,7 @@
// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
// OPL2 ROMs.
//
// version: 1.7.2
// version: 1.7.4
//
#include <stdio.h>
@ -126,7 +126,7 @@ static const Bit16u exprom[256] = {
0x3d4, 0x3da, 0x3df, 0x3e4, 0x3ea, 0x3ef, 0x3f5, 0x3fa
};
//
//
// freq mult table multiplied by 2
//
// 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15
@ -1184,14 +1184,14 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf)
if ((chip->timer & 0x3f) == 0x3f)
{
chip->tremolopos = (chip->tremolopos + 1) % 210;
if (chip->tremolopos < 105)
{
chip->tremolo = chip->tremolopos >> chip->tremoloshift;
}
else
{
chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift;
}
}
if (chip->tremolopos < 105)
{
chip->tremolo = chip->tremolopos >> chip->tremoloshift;
}
else
{
chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift;
}
if ((chip->timer & 0x3ff) == 0x3ff)
@ -1201,9 +1201,13 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf)
chip->timer++;
while (chip->writebuf_cur != chip->writebuf_last
&& chip->writebuf[chip->writebuf_cur].time <= chip->writebuf_samplecnt)
while (chip->writebuf[chip->writebuf_cur].time <= chip->writebuf_samplecnt)
{
if (!(chip->writebuf[chip->writebuf_cur].reg & 0x200))
{
break;
}
chip->writebuf[chip->writebuf_cur].reg &= 0x1ff;
OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_cur].reg,
chip->writebuf[chip->writebuf_cur].data);
chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE;
@ -1268,6 +1272,8 @@ void OPL3_Reset(opl3_chip *chip, Bit32u samplerate)
}
chip->noise = 0x306600;
chip->rateratio = (samplerate << RSM_FRAC) / 49716;
chip->tremoloshift = 4;
chip->vibshift = 1;
}
void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v)
@ -1372,8 +1378,18 @@ void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v)
void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v)
{
Bit64u time1, time2;
chip->writebuf[chip->writebuf_last % OPL_WRITEBUF_SIZE].reg = reg;
chip->writebuf[chip->writebuf_last % OPL_WRITEBUF_SIZE].data = v;
if (chip->writebuf[chip->writebuf_last].reg & 0x200)
{
OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_last].reg & 0x1ff,
chip->writebuf[chip->writebuf_last].data);
chip->writebuf_cur = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE;
chip->writebuf_samplecnt = chip->writebuf[chip->writebuf_last].time;
}
chip->writebuf[chip->writebuf_last].reg = reg | 0x200;
chip->writebuf[chip->writebuf_last].data = v;
time1 = chip->writebuf_lasttime + OPL_WRITEBUF_DELAY;
time2 = chip->writebuf_samplecnt;
@ -1382,7 +1398,7 @@ void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v)
time1 = time2;
}
chip->writebuf[chip->writebuf_last % OPL_WRITEBUF_SIZE].time = time1;
chip->writebuf[chip->writebuf_last].time = time1;
chip->writebuf_lasttime = time1;
chip->writebuf_last = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE;
}
@ -1390,7 +1406,7 @@ void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v)
void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples)
{
Bit32u i;
for(i = 0; i < numsamples; i++)
{
OPL3_GenerateResampled(chip, sndptr);

View file

@ -21,7 +21,7 @@
// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
// OPL2 ROMs.
//
// version: 1.7.2
// version: 1.7.4
//
#ifndef OPL_OPL3_H
@ -114,7 +114,7 @@ struct _opl3_chip {
Bit16s zeromod;
Bit32s mixbuff[2];
//OPL3L
Bit32s rateratio;
Bit32s rateratio;
Bit32s samplecnt;
Bit16s oldsamples[2];
Bit16s samples[2];

2
src/.gitignore vendored
View file

@ -12,8 +12,10 @@ chocolate-heretic-setup
chocolate-hexen-setup
chocolate-strife-setup
chocolate-setup
*.cfg
*.exe
*.desktop
*.txt
*.appdata.xml
tags
TAGS

View file

@ -154,14 +154,6 @@ static registry_value_t root_path_keys[] =
"INSTALLPATH",
},
// Ultimate Doom
{
HKEY_LOCAL_MACHINE,
SOFTWARE_KEY "\\GOG.com\\Games\\1435827232",
"PATH",
},
// Doom II
{
@ -178,6 +170,14 @@ static registry_value_t root_path_keys[] =
"PATH",
},
// Ultimate Doom
{
HKEY_LOCAL_MACHINE,
SOFTWARE_KEY "\\GOG.com\\Games\\1435827232",
"PATH",
},
// Strife: Veteran Edition
{
@ -195,8 +195,8 @@ static char *root_path_subdirs[] =
"Doom2",
"Final Doom",
"Ultimate Doom",
"TNT",
"Plutonia",
"TNT",
};
// Location where Steam is installed
@ -256,7 +256,7 @@ static char *GetRegistryString(registry_value_t *reg_val)
{
// Allocate a buffer for the value and read the value
result = malloc(len);
result = malloc(len + 1);
if (RegQueryValueEx(key, reg_val->value, NULL, &valtype,
(unsigned char *) result, &len) != ERROR_SUCCESS)
@ -264,6 +264,11 @@ static char *GetRegistryString(registry_value_t *reg_val)
free(result);
result = NULL;
}
else
{
// Ensure the value is null-terminated
result[len] = '\0';
}
}
// Close the key

View file

@ -32,6 +32,7 @@
#include "m_controls.h"
#include "m_misc.h"
#include "i_system.h"
#include "i_timer.h"
// Needs access to LFB.
#include "v_video.h"
@ -598,11 +599,32 @@ AM_Responder
int rc;
static int bigstate=0;
static int joywait = 0;
static char buffer[20];
int key;
rc = false;
if (ev->type == ev_joystick && joybautomap >= 0
&& (ev->data1 & (1 << joybautomap)) != 0 && joywait < I_GetTime())
{
joywait = I_GetTime() + 5;
if (!automapactive)
{
AM_Start ();
viewactive = false;
}
else
{
bigstate = 0;
viewactive = true;
AM_Stop ();
}
return true;
}
if (!automapactive)
{
if (ev->type == ev_keydown && ev->data1 == key_map_toggle)

View file

@ -815,6 +815,7 @@ void D_IdentifyVersion(void)
// with Freedoom and get the right level names.
//!
// @category compat
// @arg <pack>
//
// Explicitly specify a Doom II "mission pack" to run as, instead of

View file

@ -2220,12 +2220,13 @@ void G_DoPlayDemo (void)
void G_TimeDemo (char* name)
{
//!
// @vanilla
// @category video
// @vanilla
//
// Disable rendering the screen entirely.
//
nodrawers = M_CheckParm ("-nodraw");
nodrawers = M_CheckParm ("-nodraw");
timingdemo = true;
singletics = true;

View file

@ -63,3 +63,10 @@ void M_ClearRandom (void)
{
rndindex = prndindex = 0;
}
// inspired by the same routine in Eternity, thanks haleyjd
int P_SubRandom (void)
{
int r = P_Random();
return r - P_Random();
}

View file

@ -24,7 +24,6 @@
#include "doomtype.h"
// Returns a number from 0 to 255,
// from a lookup table.
int M_Random (void);
@ -35,5 +34,7 @@ int P_Random (void);
// Fix randoms for demos.
void M_ClearRandom (void);
// Defined version of P_Random() - P_Random()
int P_SubRandom (void);
#endif

View file

@ -777,7 +777,7 @@ void A_FaceTarget (mobj_t* actor)
actor->target->y);
if (actor->target->flags & MF_SHADOW)
actor->angle += (P_Random()-P_Random())<<21;
actor->angle += P_SubRandom() << 21;
}
@ -798,7 +798,7 @@ void A_PosAttack (mobj_t* actor)
slope = P_AimLineAttack (actor, angle, MISSILERANGE);
S_StartSound (actor, sfx_pistol);
angle += (P_Random()-P_Random())<<20;
angle += P_SubRandom() << 20;
damage = ((P_Random()%5)+1)*3;
P_LineAttack (actor, angle, MISSILERANGE, slope, damage);
}
@ -821,7 +821,7 @@ void A_SPosAttack (mobj_t* actor)
for (i=0 ; i<3 ; i++)
{
angle = bangle + ((P_Random()-P_Random())<<20);
angle = bangle + (P_SubRandom() << 20);
damage = ((P_Random()%5)+1)*3;
P_LineAttack (actor, angle, MISSILERANGE, slope, damage);
}
@ -842,7 +842,7 @@ void A_CPosAttack (mobj_t* actor)
bangle = actor->angle;
slope = P_AimLineAttack (actor, bangle, MISSILERANGE);
angle = bangle + ((P_Random()-P_Random())<<20);
angle = bangle + (P_SubRandom() << 20);
damage = ((P_Random()%5)+1)*3;
P_LineAttack (actor, angle, MISSILERANGE, slope, damage);
}
@ -1877,7 +1877,7 @@ void A_BrainExplode (mobj_t* mo)
int z;
mobj_t* th;
x = mo->x + (P_Random () - P_Random ())*2048;
x = mo->x + P_SubRandom() * 2048;
y = mo->y;
z = 128 + P_Random()*2*FRACUNIT;
th = P_SpawnMobj (x,y,z, MT_ROCKET);

View file

@ -1351,8 +1351,8 @@ boolean PIT_ChangeSector (mobj_t* thing)
thing->y,
thing->z + thing->height/2, MT_BLOOD);
mo->momx = (P_Random() - P_Random ())<<12;
mo->momy = (P_Random() - P_Random ())<<12;
mo->momx = P_SubRandom() << 12;
mo->momy = P_SubRandom() << 12;
}
// keep checking (crush other things)

View file

@ -867,7 +867,7 @@ P_SpawnPuff
{
mobj_t* th;
z += ((P_Random()-P_Random())<<10);
z += (P_SubRandom() << 10);
th = P_SpawnMobj (x,y,z, MT_PUFF);
th->momz = FRACUNIT;
@ -895,7 +895,7 @@ P_SpawnBlood
{
mobj_t* th;
z += ((P_Random()-P_Random())<<10);
z += (P_SubRandom() << 10);
th = P_SpawnMobj (x,y,z, MT_BLOOD);
th->momz = FRACUNIT*2;
th->tics -= P_Random()&3;
@ -980,7 +980,7 @@ P_SpawnMissile
// fuzzy player
if (dest->flags & MF_SHADOW)
an += (P_Random()-P_Random())<<20;
an += P_SubRandom() << 20;
th->angle = an;
an >>= ANGLETOFINESHIFT;

View file

@ -470,7 +470,7 @@ A_Punch
damage *= 10;
angle = player->mo->angle;
angle += (P_Random()-P_Random())<<18;
angle += P_SubRandom() << 18;
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage);
@ -500,7 +500,7 @@ A_Saw
damage = 2*(P_Random ()%10+1);
angle = player->mo->angle;
angle += (P_Random()-P_Random())<<18;
angle += P_SubRandom() << 18;
// use meleerange + 1 se the puff doesn't skip the flash
slope = P_AimLineAttack (player->mo, angle, MELEERANGE+1);
@ -643,7 +643,7 @@ P_GunShot
angle = mo->angle;
if (!accurate)
angle += (P_Random()-P_Random())<<18;
angle += P_SubRandom() << 18;
P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);
}
@ -726,11 +726,11 @@ A_FireShotgun2
{
damage = 5*(P_Random ()%3+1);
angle = player->mo->angle;
angle += (P_Random()-P_Random())<<ANGLETOFINESHIFT;
angle += P_SubRandom() << ANGLETOFINESHIFT;
P_LineAttack (player->mo,
angle,
MISSILERANGE,
bulletslope + ((P_Random()-P_Random())<<5), damage);
bulletslope + (P_SubRandom() << 5), damage);
}
}

View file

@ -356,7 +356,7 @@ P_FindNextHighestFloor
}
else if (h == MAX_ADJOINING_SECTORS + 2)
{
// Fatal overflow: game crashes at 22 textures
// Fatal overflow: game crashes at 22 sectors
I_Error("Sector with more than 22 adjoining sectors. "
"Vanilla will crash here");
}

View file

@ -77,8 +77,14 @@ typedef struct
} cliprange_t;
#define MAXSEGS 32
// We must expand MAXSEGS to the theoretical limit of the number of solidsegs
// that can be generated in a scene by the DOOM engine. This was determined by
// Lee Killough during BOOM development to be a function of the screensize.
// The simplest thing we can do, other than fix this bug, is to let the game
// render overage and then bomb out by detecting the overflow after the
// fact. -haleyjd
//#define MAXSEGS 32
#define MAXSEGS (SCREENWIDTH / 2 + 1)
// newend is one past the last valid seg
cliprange_t* newend;
@ -532,6 +538,10 @@ void R_Subsector (int num)
R_AddLine (line);
line++;
}
// check for solidsegs overflow - extremely unsatisfactory!
if(newend > &solidsegs[32])
I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n");
}

View file

@ -20,6 +20,7 @@
#include "doomdef.h"
#include "deh_str.h"
#include "i_timer.h"
#include "i_video.h"
#include "m_controls.h"
#include "p_local.h"
@ -508,10 +509,29 @@ boolean AM_Responder(event_t * ev)
int rc;
int key;
static int bigstate = 0;
static int joywait = 0;
key = ev->data1;
rc = false;
if (ev->type == ev_joystick && joybautomap >= 0
&& (ev->data1 & (1 << joybautomap)) != 0 && joywait < I_GetTime())
{
joywait = I_GetTime() + 5;
if (!automapactive)
{
AM_Start ();
viewactive = false;
}
else
{
bigstate = 0;
viewactive = true;
AM_Stop ();
}
}
if (!automapactive)
{

View file

@ -68,3 +68,9 @@ void M_ClearRandom(void)
rndindex = prndindex = 0;
}
// inspired by the same routine in Eternity, thanks haleyjd
int P_SubRandom (void)
{
int r = P_Random();
return r - P_Random();
}

View file

@ -30,5 +30,8 @@ void M_ClearRandom(void);
extern int rndindex;
// Defined version of P_Random() - P_Random()
int P_SubRandom (void);
#endif // HERETIC_M_RANDOM_H

View file

@ -813,7 +813,7 @@ void A_FaceTarget(mobj_t * actor)
actor->target->y);
if (actor->target->flags & MF_SHADOW)
{ // Target is a ghost
actor->angle += (P_Random() - P_Random()) << 21;
actor->angle += P_SubRandom() << 21;
}
}
@ -840,12 +840,16 @@ void A_Pain(mobj_t * actor)
void A_DripBlood(mobj_t * actor)
{
mobj_t *mo;
int r1,r2;
mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 11),
actor->y + ((P_Random() - P_Random()) << 11), actor->z,
r1 = P_SubRandom();
r2 = P_SubRandom();
mo = P_SpawnMobj(actor->x + (r1 << 11),
actor->y + (r2 << 11), actor->z,
MT_BLOOD);
mo->momx = (P_Random() - P_Random()) << 10;
mo->momy = (P_Random() - P_Random()) << 10;
mo->momx = P_SubRandom() << 10;
mo->momy = P_SubRandom() << 10;
mo->flags2 |= MF2_LOGRAV;
}
@ -889,12 +893,12 @@ void A_ImpExplode(mobj_t * actor)
mobj_t *mo;
mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_IMPCHUNK1);
mo->momx = (P_Random() - P_Random()) << 10;
mo->momy = (P_Random() - P_Random()) << 10;
mo->momx = P_SubRandom() << 10;
mo->momy = P_SubRandom() << 10;
mo->momz = 9 * FRACUNIT;
mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_IMPCHUNK2);
mo->momx = (P_Random() - P_Random()) << 10;
mo->momy = (P_Random() - P_Random()) << 10;
mo->momx = P_SubRandom() << 10;
mo->momy = P_SubRandom() << 10;
mo->momz = 9 * FRACUNIT;
if (actor->special1.i == 666)
{ // Extreme death crash
@ -912,9 +916,13 @@ void A_BeastPuff(mobj_t * actor)
{
if (P_Random() > 64)
{
P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 10),
actor->y + ((P_Random() - P_Random()) << 10),
actor->z + ((P_Random() - P_Random()) << 10), MT_PUFFY);
int r1,r2,r3;
r1 = P_SubRandom();
r2 = P_SubRandom();
r3 = P_SubRandom();
P_SpawnMobj(actor->x + (r1 << 10),
actor->y + (r2 << 10),
actor->z + (r3 << 10), MT_PUFFY);
}
}
@ -1179,8 +1187,8 @@ void A_Feathers(mobj_t * actor)
mo = P_SpawnMobj(actor->x, actor->y, actor->z + 20 * FRACUNIT,
MT_FEATHER);
mo->target = actor;
mo->momx = (P_Random() - P_Random()) << 8;
mo->momy = (P_Random() - P_Random()) << 8;
mo->momx = P_SubRandom() << 8;
mo->momy = P_SubRandom() << 8;
mo->momz = FRACUNIT + (P_Random() << 9);
P_SetMobjState(mo, S_FEATHER1 + (P_Random() & 7));
}
@ -1475,8 +1483,8 @@ void A_BlueSpark(mobj_t * actor)
for (i = 0; i < 2; i++)
{
mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SOR2FXSPARK);
mo->momx = (P_Random() - P_Random()) << 9;
mo->momy = (P_Random() - P_Random()) << 9;
mo->momx = P_SubRandom() << 9;
mo->momy = P_SubRandom() << 9;
mo->momz = FRACUNIT + (P_Random() << 8);
}
}
@ -1755,10 +1763,14 @@ void A_MinotaurAtk3(mobj_t * actor)
void A_MntrFloorFire(mobj_t * actor)
{
mobj_t *mo;
int r1, r2;
r1 = P_SubRandom();
r2 = P_SubRandom();
actor->z = actor->floorz;
mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 10),
actor->y + ((P_Random() - P_Random()) << 10), ONFLOORZ,
mo = P_SpawnMobj(actor->x + (r1 << 10),
actor->y + (r2 << 10), ONFLOORZ,
MT_MNTRFX3);
mo->target = actor->target;
mo->momx = 1; // Force block checking
@ -2122,8 +2134,8 @@ void P_DropItem(mobj_t * source, mobjtype_t type, int special, int chance)
}
mo = P_SpawnMobj(source->x, source->y,
source->z + (source->height >> 1), type);
mo->momx = (P_Random() - P_Random()) << 8;
mo->momy = (P_Random() - P_Random()) << 8;
mo->momx = P_SubRandom() << 8;
mo->momy = P_SubRandom() << 8;
mo->momz = FRACUNIT * 5 + (P_Random() << 10);
mo->flags |= MF_DROPPED;
mo->health = special;
@ -2233,8 +2245,8 @@ void A_PodPain(mobj_t * actor)
goo = P_SpawnMobj(actor->x, actor->y,
actor->z + 48 * FRACUNIT, MT_PODGOO);
goo->target = actor;
goo->momx = (P_Random() - P_Random()) << 9;
goo->momy = (P_Random() - P_Random()) << 9;
goo->momx = P_SubRandom() << 9;
goo->momy = P_SubRandom() << 9;
goo->momz = FRACUNIT / 2 + (P_Random() << 9);
}
}
@ -2404,8 +2416,10 @@ void A_ESound(mobj_t * mo)
void A_SpawnTeleGlitter(mobj_t * actor)
{
mobj_t *mo;
int r;
mo = P_SpawnMobj(actor->x + ((P_Random() & 31) - 16) * FRACUNIT,
r = P_Random();
mo = P_SpawnMobj(actor->x + ((r & 31) - 16) * FRACUNIT,
actor->y + ((P_Random() & 31) - 16) * FRACUNIT,
actor->subsector->sector->floorheight, MT_TELEGLITTER);
mo->momz = FRACUNIT / 4;
@ -2420,8 +2434,10 @@ void A_SpawnTeleGlitter(mobj_t * actor)
void A_SpawnTeleGlitter2(mobj_t * actor)
{
mobj_t *mo;
int r;
mo = P_SpawnMobj(actor->x + ((P_Random() & 31) - 16) * FRACUNIT,
r = P_Random();
mo = P_SpawnMobj(actor->x + ((r & 31) - 16) * FRACUNIT,
actor->y + ((P_Random() & 31) - 16) * FRACUNIT,
actor->subsector->sector->floorheight, MT_TELEGLITTER2);
mo->momz = FRACUNIT / 4;
@ -2560,8 +2576,8 @@ void A_SkullPop(mobj_t * actor)
mo = P_SpawnMobj(actor->x, actor->y, actor->z + 48 * FRACUNIT,
MT_BLOODYSKULL);
//mo->target = actor;
mo->momx = (P_Random() - P_Random()) << 9;
mo->momy = (P_Random() - P_Random()) << 9;
mo->momx = P_SubRandom() << 9;
mo->momy = P_SubRandom() << 9;
mo->momz = FRACUNIT * 2 + (P_Random() << 6);
// Attach player mobj to bloody skull
player = actor->player;

View file

@ -988,9 +988,9 @@ void P_TouchWhirlwind(mobj_t * target)
{
int randVal;
target->angle += (P_Random() - P_Random()) << 20;
target->momx += (P_Random() - P_Random()) << 10;
target->momy += (P_Random() - P_Random()) << 10;
target->angle += P_SubRandom() << 20;
target->momx += P_SubRandom() << 10;
target->momy += P_SubRandom() << 10;
if (leveltime & 16 && !(target->flags2 & MF2_BOSS))
{
randVal = P_Random();

View file

@ -1656,8 +1656,8 @@ boolean PIT_ChangeSector(mobj_t * thing)
// spray blood in a random direction
mo = P_SpawnMobj(thing->x, thing->y, thing->z + thing->height / 2,
MT_BLOOD);
mo->momx = (P_Random() - P_Random()) << 12;
mo->momy = (P_Random() - P_Random()) << 12;
mo->momx = P_SubRandom() << 12;
mo->momy = P_SubRandom() << 12;
}
return true; // keep checking (crush other things)

View file

@ -1192,7 +1192,7 @@ void P_SpawnPuff(fixed_t x, fixed_t y, fixed_t z)
{
mobj_t *puff;
z += ((P_Random() - P_Random()) << 10);
z += (P_SubRandom() << 10);
puff = P_SpawnMobj(x, y, z, PuffType);
if (puff->info->attacksound)
{
@ -1225,7 +1225,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage)
{
mobj_t *th;
z += ((P_Random()-P_Random())<<10);
z += (P_SubRandom()<<10);
th = P_SpawnMobj (x,y,z, MT_BLOOD);
th->momz = FRACUNIT*2;
th->tics -= P_Random()&3;
@ -1249,8 +1249,8 @@ void P_BloodSplatter(fixed_t x, fixed_t y, fixed_t z, mobj_t * originator)
mo = P_SpawnMobj(x, y, z, MT_BLOODSPLATTER);
mo->target = originator;
mo->momx = (P_Random() - P_Random()) << 9;
mo->momy = (P_Random() - P_Random()) << 9;
mo->momx = P_SubRandom() << 9;
mo->momy = P_SubRandom() << 9;
mo->momz = FRACUNIT * 2;
}
@ -1265,9 +1265,9 @@ void P_RipperBlood(mobj_t * mo)
mobj_t *th;
fixed_t x, y, z;
x = mo->x + ((P_Random() - P_Random()) << 12);
y = mo->y + ((P_Random() - P_Random()) << 12);
z = mo->z + ((P_Random() - P_Random()) << 12);
x = mo->x + (P_SubRandom() << 12);
y = mo->y + (P_SubRandom() << 12);
z = mo->z + (P_SubRandom() << 12);
th = P_SpawnMobj(x, y, z, MT_BLOOD);
th->flags |= MF_NOGRAVITY;
th->momx = mo->momx >> 1;
@ -1317,8 +1317,8 @@ int P_HitFloor(mobj_t * thing)
P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASHBASE);
mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASH);
mo->target = thing;
mo->momx = (P_Random() - P_Random()) << 8;
mo->momy = (P_Random() - P_Random()) << 8;
mo->momx = P_SubRandom() << 8;
mo->momy = P_SubRandom() << 8;
mo->momz = 2 * FRACUNIT + (P_Random() << 8);
S_StartSound(mo, sfx_gloop);
return (FLOOR_WATER);
@ -1332,8 +1332,8 @@ int P_HitFloor(mobj_t * thing)
P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SLUDGESPLASH);
mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SLUDGECHUNK);
mo->target = thing;
mo->momx = (P_Random() - P_Random()) << 8;
mo->momy = (P_Random() - P_Random()) << 8;
mo->momx = P_SubRandom() << 8;
mo->momy = P_SubRandom() << 8;
mo->momz = FRACUNIT + (P_Random() << 8);
return (FLOOR_SLUDGE);
}
@ -1414,7 +1414,7 @@ mobj_t *P_SpawnMissile(mobj_t * source, mobj_t * dest, mobjtype_t type)
an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
if (dest->flags & MF_SHADOW)
{ // Invisible target
an += (P_Random() - P_Random()) << 21;
an += P_SubRandom() << 21;
}
th->angle = an;
an >>= ANGLETOFINESHIFT;

View file

@ -896,7 +896,7 @@ void A_StaffAttackPL1(player_t * player, pspdef_t * psp)
damage = 5 + (P_Random() & 15);
angle = player->mo->angle;
angle += (P_Random() - P_Random()) << 18;
angle += P_SubRandom() << 18;
slope = P_AimLineAttack(player->mo, angle, MELEERANGE);
PuffType = MT_STAFFPUFF;
P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);
@ -925,7 +925,7 @@ void A_StaffAttackPL2(player_t * player, pspdef_t * psp)
// P_inter.c:P_DamageMobj() handles target momentums
damage = 18 + (P_Random() & 63);
angle = player->mo->angle;
angle += (P_Random() - P_Random()) << 18;
angle += P_SubRandom() << 18;
slope = P_AimLineAttack(player->mo, angle, MELEERANGE);
PuffType = MT_STAFFPUFF2;
P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);
@ -959,7 +959,7 @@ void A_FireBlasterPL1(player_t * player, pspdef_t * psp)
angle = mo->angle;
if (player->refire)
{
angle += (P_Random() - P_Random()) << 18;
angle += P_SubRandom() << 18;
}
PuffType = MT_BLASTERPUFF1;
P_LineAttack(mo, angle, MISSILERANGE, bulletslope, damage);
@ -1005,7 +1005,7 @@ void A_FireGoldWandPL1(player_t * player, pspdef_t * psp)
angle = mo->angle;
if (player->refire)
{
angle += (P_Random() - P_Random()) << 18;
angle += P_SubRandom() << 18;
}
PuffType = MT_GOLDWANDPUFF1;
P_LineAttack(mo, angle, MISSILERANGE, bulletslope, damage);
@ -1397,8 +1397,8 @@ void A_BoltSpark(mobj_t * bolt)
if (P_Random() > 50)
{
spark = P_SpawnMobj(bolt->x, bolt->y, bolt->z, MT_CRBOWFX4);
spark->x += (P_Random() - P_Random()) << 10;
spark->y += (P_Random() - P_Random()) << 10;
spark->x += P_SubRandom() << 10;
spark->y += P_SubRandom() << 10;
}
}
@ -1696,8 +1696,8 @@ void A_FirePhoenixPL2(player_t * player, pspdef_t * psp)
}
pmo = player->mo;
angle = pmo->angle;
x = pmo->x + ((P_Random() - P_Random()) << 9);
y = pmo->y + ((P_Random() - P_Random()) << 9);
x = pmo->x + (P_SubRandom() << 9);
y = pmo->y + (P_SubRandom() << 9);
z = pmo->z + 26 * FRACUNIT + ((player->lookdir) << FRACBITS) / 173;
if (pmo->flags2 & MF2_FEETARECLIPPED)
{
@ -1773,14 +1773,14 @@ void A_GauntletAttack(player_t * player, pspdef_t * psp)
{
damage = HITDICE(2);
dist = 4 * MELEERANGE;
angle += (P_Random() - P_Random()) << 17;
angle += P_SubRandom() << 17;
PuffType = MT_GAUNTLETPUFF2;
}
else
{
damage = HITDICE(2);
dist = MELEERANGE + 1;
angle += (P_Random() - P_Random()) << 18;
angle += P_SubRandom() << 18;
PuffType = MT_GAUNTLETPUFF1;
}
slope = P_AimLineAttack(player->mo, angle, dist);

View file

@ -421,7 +421,7 @@ void P_ChickenPlayerThink(player_t * player)
pmo = player->mo;
if (!(pmo->momx + pmo->momy) && P_Random() < 160)
{ // Twitch view angle
pmo->angle += (P_Random() - P_Random()) << 19;
pmo->angle += P_SubRandom() << 19;
}
if ((pmo->z <= pmo->floorz) && (P_Random() < 32))
{ // Jump and noise

View file

@ -58,7 +58,14 @@ typedef struct
int first, last;
} cliprange_t;
#define MAXSEGS 32
// We must expand MAXSEGS to the theoretical limit of the number of solidsegs
// that can be generated in a scene by the DOOM engine. This was determined by
// Lee Killough during BOOM development to be a function of the screensize.
// The simplest thing we can do, other than fix this bug, is to let the game
// render overage and then bomb out by detecting the overflow after the
// fact. -haleyjd
//#define MAXSEGS 32
#define MAXSEGS (SCREENWIDTH / 2 + 1)
cliprange_t solidsegs[MAXSEGS], *newend; // newend is one past the last valid seg
@ -437,6 +444,10 @@ void R_Subsector(int num)
R_AddLine(line);
line++;
}
// check for solidsegs overflow - extremely unsatisfactory!
if(newend > &solidsegs[32])
I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n");
}

View file

@ -126,11 +126,14 @@ int orbitTableY[256] = {
void A_DripBlood(mobj_t *actor)
{
mobj_t *mo;
int r;
mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<11),
actor->y+((P_Random()-P_Random())<<11), actor->z, MT_BLOOD);
mo->momx = (P_Random()-P_Random())<<10;
mo->momy = (P_Random()-P_Random())<<10;
r = P_SubRandom();
mo = P_SpawnMobj(actor->x+(r<<11),
actor->y+(P_SubRandom()<<11), actor->z, MT_BLOOD);
mo->momx = P_SubRandom()<<10;
mo->momy = P_SubRandom()<<10;
mo->flags2 |= MF2_LOGRAV;
}
*/
@ -153,8 +156,8 @@ void A_PotteryExplode(mobj_t * actor)
if (mo)
{
mo->momz = ((P_Random() & 7) + 5) * (3 * FRACUNIT / 4);
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momx = P_SubRandom() << (FRACBITS - 6);
mo->momy = P_SubRandom() << (FRACBITS - 6);
}
}
S_StartSound(mo, SFX_POTTERY_EXPLODE);
@ -265,8 +268,8 @@ void A_CorpseExplode(mobj_t * actor)
if (mo)
{
mo->momz = ((P_Random() & 7) + 5) * (3 * FRACUNIT / 4);
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momx = P_SubRandom() << (FRACBITS - 6);
mo->momy = P_SubRandom() << (FRACBITS - 6);
}
}
// Spawn a skull
@ -275,8 +278,8 @@ void A_CorpseExplode(mobj_t * actor)
if (mo)
{
mo->momz = ((P_Random() & 7) + 5) * (3 * FRACUNIT / 4);
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momx = P_SubRandom() << (FRACBITS - 6);
mo->momy = P_SubRandom() << (FRACBITS - 6);
S_StartSound(mo, SFX_FIRED_DEATH);
}
P_RemoveMobj(actor);
@ -300,8 +303,8 @@ void A_LeafSpawn(mobj_t * actor)
// see ISO-IEC 9899-1999, [6.5.2.2.10]
mobjtype_t type = MT_LEAF1 + (P_Random() & 1);
fixed_t z = actor->z + (P_Random() << 14);
fixed_t y = actor->y + ((P_Random() - P_Random()) << 14);
fixed_t x = actor->x + ((P_Random() - P_Random()) << 14);
fixed_t y = actor->y + (P_SubRandom() << 14);
fixed_t x = actor->x + (P_SubRandom() << 14);
mo = P_SpawnMobj(x, y, z, type);
if (mo)
@ -1040,8 +1043,8 @@ void P_SpawnDirt(mobj_t * actor, fixed_t radius)
angle = P_Random() << 5; // <<24 >>19
x = actor->x + FixedMul(radius, finecosine[angle]);
y = actor->y + FixedMul(radius, finesine[angle]);
// x = actor->x + ((P_Random()-P_Random())%radius)<<FRACBITS;
// y = actor->y + ((P_Random()-P_Random()<<FRACBITS)%radius);
// x = actor->x + (P_SubRandom()%radius)<<FRACBITS;
// y = actor->y + ((P_SubRandom()<<FRACBITS)%radius);
z = actor->z + (P_Random() << 9) + FRACUNIT;
switch (P_Random() % 6)
{
@ -1165,19 +1168,23 @@ void A_SoAExplode(mobj_t * actor)
{
mobj_t *mo;
int i;
int r1,r2,r3;
for (i = 0; i < 10; i++)
{
mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
actor->y + ((P_Random() - 128) << 12),
actor->z + (P_Random() * actor->height / 256),
r1 = P_Random();
r2 = P_Random();
r3 = P_Random();
mo = P_SpawnMobj(actor->x + ((r1 - 128) << 12),
actor->y + ((r2 - 128) << 12),
actor->z + (r3 * actor->height / 256),
MT_ZARMORCHUNK);
P_SetMobjState(mo, mo->info->spawnstate + i);
if (mo)
{
mo->momz = ((P_Random() & 7) + 5) * FRACUNIT;
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 6);
mo->momx = P_SubRandom() << (FRACBITS - 6);
mo->momy = P_SubRandom() << (FRACBITS - 6);
}
}
if (actor->args[0])

View file

@ -20,6 +20,7 @@
#include "doomkeys.h"
#include "i_video.h"
#include "i_swap.h"
#include "i_timer.h"
#include "m_controls.h"
#include "m_misc.h"
#include "p_local.h"
@ -421,9 +422,33 @@ boolean AM_Responder(event_t * ev)
int rc;
int key;
static int bigstate = 0;
static int joywait = 0;
key = ev->data1;
if (ev->type == ev_joystick && joybautomap >= 0
&& (ev->data1 & (1 << joybautomap)) != 0 && joywait < I_GetTime())
{
joywait = I_GetTime() + 5;
if (!automapactive)
{
AM_Start ();
SB_state = -1;
viewactive = false;
}
else
{
bigstate = 0;
viewactive = true;
AM_Stop ();
SB_state = -1;
}
return true;
}
rc = false;
if (!automapactive)
{

View file

@ -72,3 +72,9 @@ void M_ClearRandom(void)
rndindex = prndindex = 0;
}
// inspired by the same routine in Eternity, thanks haleyjd
int P_SubRandom (void)
{
int r = P_Random();
return r - P_Random();
}

View file

@ -30,5 +30,8 @@ void M_ClearRandom(void);
extern int rndindex;
// Defined version of P_Random() - P_Random()
int P_SubRandom (void);
#endif // HEXEN_M_RANDOM_H

View file

@ -820,7 +820,7 @@ void A_FaceTarget(mobj_t * actor)
actor->target->y);
if (actor->target->flags & MF_SHADOW)
{ // Target is a ghost
actor->angle += (P_Random() - P_Random()) << 21;
actor->angle += P_SubRandom() << 21;
}
}
@ -1481,10 +1481,13 @@ void A_MinotaurAtk3(mobj_t * actor)
void A_MntrFloorFire(mobj_t * actor)
{
mobj_t *mo;
int r;
r = P_SubRandom();
actor->z = actor->floorz;
mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 10),
actor->y + ((P_Random() - P_Random()) << 10), ONFLOORZ,
mo = P_SpawnMobj(actor->x + (r << 10),
actor->y + (P_SubRandom() << 10), ONFLOORZ,
MT_MNTRFX3);
mo->target = actor->target;
mo->momx = 1; // Force block checking
@ -1597,8 +1600,8 @@ void P_DropItem(mobj_t *source, mobjtype_t type, int special, int chance)
}
mo = P_SpawnMobj(source->x, source->y,
source->z+(source->height>>1), type);
mo->momx = (P_Random()-P_Random())<<8;
mo->momy = (P_Random()-P_Random())<<8;
mo->momx = P_SubRandom()<<8;
mo->momy = P_SubRandom()<<8;
mo->momz = FRACUNIT*5+(P_Random()<<10);
mo->flags2 |= MF2_DROPPED;
mo->health = special;
@ -1773,8 +1776,8 @@ void A_SkullPop(mobj_t * actor)
mo = P_SpawnMobj(actor->x, actor->y, actor->z + 48 * FRACUNIT,
MT_BLOODYSKULL);
//mo->target = actor;
mo->momx = (P_Random() - P_Random()) << 9;
mo->momy = (P_Random() - P_Random()) << 9;
mo->momx = P_SubRandom() << 9;
mo->momy = P_SubRandom() << 9;
mo->momz = FRACUNIT * 2 + (P_Random() << 6);
// Attach player mobj to bloody skull
player = actor->player;
@ -2408,8 +2411,9 @@ void A_SerpentHeadPop(mobj_t * actor)
void A_SerpentSpawnGibs(mobj_t * actor)
{
mobj_t *mo;
int r = P_Random();
mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
mo = P_SpawnMobj(actor->x + ((r - 128) << 12),
actor->y + ((P_Random() - 128) << 12),
actor->floorz + FRACUNIT, MT_SERPENT_GIB1);
if (mo)
@ -2418,7 +2422,8 @@ void A_SerpentSpawnGibs(mobj_t * actor)
mo->momy = (P_Random() - 128) << 6;
mo->floorclip = 6 * FRACUNIT;
}
mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
r = P_Random();
mo = P_SpawnMobj(actor->x + ((r - 128) << 12),
actor->y + ((P_Random() - 128) << 12),
actor->floorz + FRACUNIT, MT_SERPENT_GIB2);
if (mo)
@ -2427,7 +2432,8 @@ void A_SerpentSpawnGibs(mobj_t * actor)
mo->momy = (P_Random() - 128) << 6;
mo->floorclip = 6 * FRACUNIT;
}
mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12),
r = P_Random();
mo = P_SpawnMobj(actor->x + ((r - 128) << 12),
actor->y + ((P_Random() - 128) << 12),
actor->floorz + FRACUNIT, MT_SERPENT_GIB3);
if (mo)
@ -2779,15 +2785,21 @@ void A_BishopPuff(mobj_t * actor)
void A_BishopPainBlur(mobj_t * actor)
{
mobj_t *mo;
int r1,r2,r3;
if (P_Random() < 64)
{
P_SetMobjState(actor, S_BISHOP_BLUR1);
return;
}
mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 12), actor->y
+ ((P_Random() - P_Random()) << 12),
actor->z + ((P_Random() - P_Random()) << 11),
r1 = P_SubRandom();
r2 = P_SubRandom();
r3 = P_SubRandom();
mo = P_SpawnMobj(actor->x + (r1 << 12), actor->y
+ (r2 << 12),
actor->z + (r3 << 11),
MT_BISHOPPAINBLUR);
if (mo)
{
@ -3027,14 +3039,18 @@ void A_DragonFX2(mobj_t * actor)
{
mobj_t *mo;
int i;
int r1,r2,r3;
int delay;
delay = 16 + (P_Random() >> 3);
for (i = 1 + (P_Random() & 3); i; i--)
{
mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 14),
actor->y + ((P_Random() - 128) << 14),
actor->z + ((P_Random() - 128) << 12),
r1 = P_Random();
r2 = P_Random();
r3 = P_Random();
mo = P_SpawnMobj(actor->x + ((r1 - 128) << 14),
actor->y + ((r2 - 128) << 14),
actor->z + ((r3 - 128) << 12),
MT_DRAGON_FX2);
if (mo)
{
@ -4764,7 +4780,8 @@ void A_CheckFloor(mobj_t * actor)
void A_FreezeDeath(mobj_t * actor)
{
actor->tics = 75 + P_Random() + P_Random();
int r = P_Random();
actor->tics = 75 + r + P_Random();
actor->flags |= MF_SOLID | MF_SHOOTABLE | MF_NOBLOOD;
actor->flags2 |= MF2_PUSHABLE | MF2_TELESTOMP | MF2_PASSMOBJ | MF2_SLIDE;
actor->height <<= 2;
@ -4832,6 +4849,7 @@ void A_IceCheckHeadDone(mobj_t * actor)
void A_FreezeDeathChunks(mobj_t * actor)
{
int i;
int r1,r2,r3;
mobj_t *mo;
if (actor->momx || actor->momy || actor->momz)
@ -4843,35 +4861,41 @@ void A_FreezeDeathChunks(mobj_t * actor)
for (i = 12 + (P_Random() & 15); i >= 0; i--)
{
r1 = P_Random();
r2 = P_Random();
r3 = P_Random();
mo = P_SpawnMobj(actor->x +
(((P_Random() - 128) * actor->radius) >> 7),
(((r1 - 128) * actor->radius) >> 7),
actor->y +
(((P_Random() - 128) * actor->radius) >> 7),
actor->z + (P_Random() * actor->height / 255),
(((r2 - 128) * actor->radius) >> 7),
actor->z + (r3 * actor->height / 255),
MT_ICECHUNK);
P_SetMobjState(mo, mo->info->spawnstate + (P_Random() % 3));
if (mo)
{
mo->momz = FixedDiv(mo->z - actor->z, actor->height) << 2;
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7);
mo->momx = P_SubRandom() << (FRACBITS - 7);
mo->momy = P_SubRandom() << (FRACBITS - 7);
A_IceSetTics(mo); // set a random tic wait
}
}
for (i = 12 + (P_Random() & 15); i >= 0; i--)
{
r1 = P_Random();
r2 = P_Random();
r3 = P_Random();
mo = P_SpawnMobj(actor->x +
(((P_Random() - 128) * actor->radius) >> 7),
(((r1 - 128) * actor->radius) >> 7),
actor->y +
(((P_Random() - 128) * actor->radius) >> 7),
actor->z + (P_Random() * actor->height / 255),
(((r2 - 128) * actor->radius) >> 7),
actor->z + (r3 * actor->height / 255),
MT_ICECHUNK);
P_SetMobjState(mo, mo->info->spawnstate + (P_Random() % 3));
if (mo)
{
mo->momz = FixedDiv(mo->z - actor->z, actor->height) << 2;
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7);
mo->momx = P_SubRandom() << (FRACBITS - 7);
mo->momy = P_SubRandom() << (FRACBITS - 7);
A_IceSetTics(mo); // set a random tic wait
}
}
@ -4881,8 +4905,8 @@ void A_FreezeDeathChunks(mobj_t * actor)
MT_ICECHUNK);
P_SetMobjState(mo, S_ICECHUNK_HEAD);
mo->momz = FixedDiv(mo->z - actor->z, actor->height) << 2;
mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7);
mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7);
mo->momx = P_SubRandom() << (FRACBITS - 7);
mo->momy = P_SubRandom() << (FRACBITS - 7);
mo->flags2 |= MF2_ICEDAMAGE; // used to force blue palette
mo->flags2 &= ~MF2_FLOORCLIP;
mo->player = actor->player;

View file

@ -2277,8 +2277,8 @@ boolean PIT_ChangeSector(mobj_t * thing)
{
mo = P_SpawnMobj(thing->x, thing->y, thing->z + thing->height / 2,
MT_BLOOD);
mo->momx = (P_Random() - P_Random()) << 12;
mo->momy = (P_Random() - P_Random()) << 12;
mo->momx = P_SubRandom() << 12;
mo->momy = P_SubRandom() << 12;
}
}

View file

@ -1755,7 +1755,7 @@ void P_SpawnPuff(fixed_t x, fixed_t y, fixed_t z)
{
mobj_t *puff;
z += ((P_Random() - P_Random()) << 10);
z += (P_SubRandom() << 10);
puff = P_SpawnMobj(x, y, z, PuffType);
if (linetarget && puff->info->seesound)
{ // Hit thing sound
@ -1792,7 +1792,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage)
{
mobj_t *th;
z += ((P_Random()-P_Random())<<10);
z += (P_SubRandom()<<10);
th = P_SpawnMobj (x,y,z, MT_BLOOD);
th->momz = FRACUNIT*2;
th->tics -= P_Random()&3;
@ -1816,8 +1816,8 @@ void P_BloodSplatter(fixed_t x, fixed_t y, fixed_t z, mobj_t * originator)
mo = P_SpawnMobj(x, y, z, MT_BLOODSPLATTER);
mo->target = originator;
mo->momx = (P_Random() - P_Random()) << 10;
mo->momy = (P_Random() - P_Random()) << 10;
mo->momx = P_SubRandom() << 10;
mo->momy = P_SubRandom() << 10;
mo->momz = 3 * FRACUNIT;
}
@ -1847,9 +1847,9 @@ void P_RipperBlood(mobj_t * mo)
mobj_t *th;
fixed_t x, y, z;
x = mo->x + ((P_Random() - P_Random()) << 12);
y = mo->y + ((P_Random() - P_Random()) << 12);
z = mo->z + ((P_Random() - P_Random()) << 12);
x = mo->x + (P_SubRandom() << 12);
y = mo->y + (P_SubRandom() << 12);
z = mo->z + (P_SubRandom() << 12);
th = P_SpawnMobj(x, y, z, MT_BLOOD);
// th->flags |= MF_NOGRAVITY;
th->momx = mo->momx >> 1;
@ -1935,8 +1935,8 @@ int P_HitFloor(mobj_t * thing)
{
mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASH);
mo->target = thing;
mo->momx = (P_Random() - P_Random()) << 8;
mo->momy = (P_Random() - P_Random()) << 8;
mo->momx = P_SubRandom() << 8;
mo->momy = P_SubRandom() << 8;
mo->momz = 2 * FRACUNIT + (P_Random() << 8);
mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASHBASE);
if (thing->player)
@ -1978,8 +1978,8 @@ int P_HitFloor(mobj_t * thing)
mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ,
MT_SLUDGECHUNK);
mo->target = thing;
mo->momx = (P_Random() - P_Random()) << 8;
mo->momy = (P_Random() - P_Random()) << 8;
mo->momx = P_SubRandom() << 8;
mo->momy = P_SubRandom() << 8;
mo->momz = FRACUNIT + (P_Random() << 8);
mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ,
MT_SLUDGESPLASH);
@ -2066,7 +2066,7 @@ mobj_t *P_SpawnMissile(mobj_t * source, mobj_t * dest, mobjtype_t type)
an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
if (dest->flags & MF_SHADOW)
{ // Invisible target
an += (P_Random() - P_Random()) << 21;
an += P_SubRandom() << 21;
}
th->angle = an;
an >>= ANGLETOFINESHIFT;
@ -2108,7 +2108,7 @@ mobj_t *P_SpawnMissileXYZ(fixed_t x, fixed_t y, fixed_t z,
an = R_PointToAngle2(source->x, source->y, dest->x, dest->y);
if (dest->flags & MF_SHADOW)
{ // Invisible target
an += (P_Random() - P_Random()) << 21;
an += P_SubRandom() << 21;
}
th->angle = an;
an >>= ANGLETOFINESHIFT;
@ -2449,7 +2449,7 @@ mobj_t *P_SpawnKoraxMissile(fixed_t x, fixed_t y, fixed_t z,
an = R_PointToAngle2(x, y, dest->x, dest->y);
if (dest->flags & MF_SHADOW)
{ // Invisible target
an += (P_Random() - P_Random()) << 21;
an += P_SubRandom() << 21;
}
th->angle = an;
an >>= ANGLETOFINESHIFT;

View file

@ -861,12 +861,16 @@ void A_FSwordAttack2(mobj_t * actor)
void A_FSwordFlames(mobj_t * actor)
{
int i;
int r1,r2,r3;
for (i = 1 + (P_Random() & 3); i; i--)
{
P_SpawnMobj(actor->x + ((P_Random() - 128) << 12), actor->y
+ ((P_Random() - 128) << 12),
actor->z + ((P_Random() - 128) << 11), MT_FSWORD_FLAME);
r1 = P_Random();
r2 = P_Random();
r3 = P_Random();
P_SpawnMobj(actor->x + ((r1 - 128) << 12), actor->y
+ ((r2 - 128) << 12),
actor->z + ((r3 - 128) << 11), MT_FSWORD_FLAME);
}
}
@ -979,6 +983,7 @@ void A_LightningZap(mobj_t * actor)
{
mobj_t *mo;
fixed_t deltaZ;
int r1,r2;
A_LightningClip(actor);
@ -996,8 +1001,10 @@ void A_LightningZap(mobj_t * actor)
{
deltaZ = -10 * FRACUNIT;
}
mo = P_SpawnMobj(actor->x + ((P_Random() - 128) * actor->radius / 256),
actor->y + ((P_Random() - 128) * actor->radius / 256),
r1 = P_Random();
r2 = P_Random();
mo = P_SpawnMobj(actor->x + ((r1 - 128) * actor->radius / 256),
actor->y + ((r2 - 128) * actor->radius / 256),
actor->z + deltaZ, MT_LIGHTNING_ZAP);
if (mo)
{
@ -1388,8 +1395,10 @@ void A_FAxeAttack(player_t * player, pspdef_t * psp)
int slope;
int i;
int useMana;
int r;
damage = 40 + (P_Random() & 15) + (P_Random() & 7);
r = P_Random();
damage = 40 + (r & 15) + (P_Random() & 7);
power = 0;
if (player->mana[MANA_1] > 0)
{
@ -1741,7 +1750,7 @@ void A_CFlameAttack(player_t *player, pspdef_t *psp)
angle = pmo->angle;
if(player->refire)
{
angle += (P_Random()-P_Random())<<17;
angle += P_SubRandom()<<17;
}
P_AimLineAttack(pmo, angle, CFLAMERANGE); // Correctly set linetarget
if(!linetarget)
@ -1851,6 +1860,7 @@ void A_CHolyAttack2(mobj_t * actor)
{
int j;
int i;
int r;
mobj_t *mo;
mobj_t *tail, *next;
@ -1873,8 +1883,9 @@ void A_CHolyAttack2(mobj_t * actor)
mo->special2.i = (32 + (P_Random() & 7)) << 16; // lower-left
break;
case 3:
r = P_Random();
mo->special2.i =
((32 + (P_Random() & 7)) << 16) + 32 + (P_Random() & 7);
((32 + (r & 7)) << 16) + 32 + (P_Random() & 7);
break;
}
mo->z = actor->z;

View file

@ -59,7 +59,14 @@ typedef struct
int first, last;
} cliprange_t;
#define MAXSEGS 32
// We must expand MAXSEGS to the theoretical limit of the number of solidsegs
// that can be generated in a scene by the DOOM engine. This was determined by
// Lee Killough during BOOM development to be a function of the screensize.
// The simplest thing we can do, other than fix this bug, is to let the game
// render overage and then bomb out by detecting the overflow after the
// fact. -haleyjd
//#define MAXSEGS 32
#define MAXSEGS (SCREENWIDTH / 2 + 1)
cliprange_t solidsegs[MAXSEGS], *newend; // newend is one past the last valid seg
@ -458,6 +465,10 @@ void R_Subsector(int num)
R_AddLine(line);
line++;
}
// check for solidsegs overflow - extremely unsatisfactory!
if(newend > &solidsegs[32])
I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n");
}

View file

@ -901,7 +901,7 @@ static boolean I_SDL_InitMusic(void)
int i;
//!
// @arg <output filename>
// @arg <filename>
//
// Read all MIDI files from loaded WAD files, dump an example substitution
// music config file to the specified filename and quit.

View file

@ -341,6 +341,8 @@ static void ReleaseSoundOnChannel(int channel)
{
allocated_sound_t *snd = channels_playing[channel];
Mix_HaltChannel(channel);
if (snd == NULL)
{
return;
@ -984,8 +986,6 @@ static void I_SDL_StopSound(int handle)
return;
}
Mix_HaltChannel(handle);
// Sound data is no longer needed; release the
// sound data being used for this channel

View file

@ -818,12 +818,13 @@ void I_GraphicsCheckCommandLine(void)
int i;
//!
// @category video
// @vanilla
//
// Disable blitting the screen.
//
noblit = M_CheckParm ("-noblit");
noblit = M_CheckParm ("-noblit");
//!
// @category video

View file

@ -1059,6 +1059,12 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_INT(joyb_menu_activate),
//!
// Joystick virtual button to toggle the automap.
//
CONFIG_VARIABLE_INT(joyb_toggle_automap),
//!
// Joystick virtual button that cycles to the previous weapon.
//

View file

@ -192,6 +192,7 @@ int joybprevweapon = -1;
int joybnextweapon = -1;
int joybmenu = -1;
int joybautomap = -1;
// Control whether if a mouse button is double clicked, it acts like
// "use" has been pressed
@ -225,6 +226,7 @@ void M_BindBaseControls(void)
M_BindIntVariable("joyb_speed", &joybspeed);
M_BindIntVariable("joyb_menu_activate", &joybmenu);
M_BindIntVariable("joyb_toggle_automap", &joybautomap);
// Extra controls that are not in the Vanilla versions:

View file

@ -150,6 +150,7 @@ extern int joybprevweapon;
extern int joybnextweapon;
extern int joybmenu;
extern int joybautomap;
extern int dclick_use;

View file

@ -1345,6 +1345,7 @@ void NET_SV_SendQueryResponse(net_addr_t *addr)
querydata.gamemission = sv_gamemission;
//!
// @category net
// @arg <name>
//
// When starting a network server, specify a name for the server.
@ -1785,11 +1786,11 @@ static void UpdateMasterServer(void)
void NET_SV_RegisterWithMaster(void)
{
//!
// @category net
//
// When running a server, don't register with the global master server.
// Implies -server.
//
// @category net
//
if (!M_CheckParm("-privateserver"))
{

View file

@ -127,22 +127,33 @@ static int all_joysticks_len = 0;
// Always loaded before others, to get a known starting configuration.
static const joystick_config_t empty_defaults[] =
{
{"joystick_x_axis", -1},
{"joystick_x_invert", 0},
{"joystick_y_axis", -1},
{"joystick_y_invert", 0},
{"joystick_strafe_axis", -1},
{"joystick_strafe_invert", 0},
{"joyb_fire", -1},
{"joyb_use", -1},
{"joyb_strafe", -1},
{"joyb_speed", -1},
{"joyb_strafeleft", -1},
{"joyb_straferight", -1},
{"joyb_prevweapon", -1},
{"joyb_nextweapon", -1},
{"joyb_jump", -1},
{"joyb_menu_activate", -1},
{"joystick_x_axis", -1},
{"joystick_x_invert", 0},
{"joystick_y_axis", -1},
{"joystick_y_invert", 0},
{"joystick_strafe_axis", -1},
{"joystick_strafe_invert", 0},
{"joyb_fire", -1},
{"joyb_use", -1},
{"joyb_strafe", -1},
{"joyb_speed", -1},
{"joyb_strafeleft", -1},
{"joyb_straferight", -1},
{"joyb_prevweapon", -1},
{"joyb_nextweapon", -1},
{"joyb_jump", -1},
{"joyb_menu_activate", -1},
{"joyb_toggle_automap", -1},
{"joystick_physical_button0", 0},
{"joystick_physical_button1", 1},
{"joystick_physical_button2", 2},
{"joystick_physical_button3", 3},
{"joystick_physical_button4", 4},
{"joystick_physical_button5", 5},
{"joystick_physical_button6", 6},
{"joystick_physical_button7", 7},
{"joystick_physical_button8", 8},
{"joystick_physical_button9", 9},
{NULL, 0},
};
@ -315,6 +326,38 @@ static const joystick_config_t pc_gameport_controller[] =
{NULL, 0},
};
// http://www.8bitdo.com/nes30pro/
static const joystick_config_t nes30_pro_controller[] =
{
{"joystick_x_axis", CREATE_HAT_AXIS(0, HAT_AXIS_HORIZONTAL)},
{"joystick_y_axis", CREATE_HAT_AXIS(0, HAT_AXIS_VERTICAL)},
{"joyb_fire", 4}, // Y
{"joyb_speed", 1}, // B
{"joyb_jump", 2}, // X
{"joyb_use", 0}, // A
{"joyb_strafeleft", 8}, // L1
{"joyb_straferight", 9}, // R1
{"joyb_prevweapon", 6}, // L2
{"joyb_nextweapon", 7}, // R2
{"joyb_menu_activate", 11}, // Start
{NULL, 0},
};
// http://www.8bitdo.com/sfc30/ or http://www.8bitdo.com/snes30/
static const joystick_config_t sfc30_controller[] =
{
{"joystick_x_axis", 0},
{"joystick_y_axis", 1},
{"joyb_fire", 4}, // Y
{"joyb_speed", 1}, // B
{"joyb_jump", 3}, // X
{"joyb_use", 0}, // A
{"joyb_strafeleft", 6}, // L
{"joyb_straferight", 7}, // R
{"joyb_menu_activate", 11}, // Start
{"joyb_toggle_automap", 10}, // Select
{NULL, 0},
};
static const known_joystick_t known_joysticks[] =
{
@ -407,6 +450,52 @@ static const known_joystick_t known_joysticks[] =
2, 8, 1,
pc_gameport_controller,
},
// 8Bitdo NES30 Pro, http://www.8bitdo.com/nes30pro/
// Probably some of their other controllers can use the same config.
{
"8Bitdo NES30 Pro",
4, 16, 1,
nes30_pro_controller,
},
// 8Bitdo SFC30 SNES replica controller
// in default mode and in controller mode (Start+R)
// the latter suffixes "Joystick" to the name
// http://www.8bitdo.com/sfc30/
{
"8Bitdo SFC30 GamePad*",
4, 16, 1,
sfc30_controller,
},
// As above, but as detected on RHEL Linux (odd extra axes)
{
"8Bitdo SFC30 GamePad*",
6, 16, 1,
sfc30_controller,
},
// SNES30 colour variation of the above
// http://www.8bitdo.com/snes30/
{
"8Bitdo SNES30 GamePad*",
4, 16, 1,
sfc30_controller,
},
// 8Bitdo SFC30 SNES replica controller in USB controller mode
// tested with firmware V2.68 (Beta); latest stable V2.65 doesn't work on
// OS X in USB controller mode
// Names seen so far:
// 'SFC30 Joystick' (OS X)
// 'SFC30 SFC30 Joystick' (Fedora 24; RHEL7)
// XXX: there is probably a SNES30 variant of this too
{
"SFC30 *",
4, 12, 1,
sfc30_controller,
},
};
static const known_joystick_t *GetJoystickType(int index)
@ -805,7 +894,7 @@ void ConfigJoystick(void)
window = TXT_NewWindow("Gamepad/Joystick configuration");
TXT_SetTableColumns(window, 6);
TXT_SetColumnWidths(window, 18, 10, 2, 14, 10, 0);
TXT_SetColumnWidths(window, 18, 10, 1, 15, 10, 0);
TXT_SetWindowHelpURL(window, WINDOW_HELP_URL);
TXT_AddWidgets(window,
@ -872,6 +961,8 @@ void ConfigJoystick(void)
AddJoystickControl(window, "Activate menu", &joybmenu);
AddJoystickControl(window, "Toggle Automap", &joybautomap);
TXT_SignalConnect(joystick_button, "pressed", CalibrateJoystick, NULL);
TXT_SetWindowAction(window, TXT_HORIZ_CENTER, TestConfigAction());

View file

@ -56,6 +56,7 @@ static int *all_joystick_buttons[] =
&joybnextweapon,
&joybjump,
&joybmenu,
&joybautomap,
};
static int PhysicalForVirtualButton(int vbutton)

View file

@ -32,6 +32,7 @@
#include "m_cheat.h"
#include "m_controls.h"
#include "i_system.h"
#include "i_timer.h"
// Needs access to LFB.
#include "v_video.h"
@ -579,11 +580,33 @@ AM_Responder
int rc;
static int bigstate=0;
static int joywait = 0;
static char buffer[20];
int key;
rc = false;
if (ev->type == ev_joystick && joybautomap >= 0
&& (ev->data1 & (1 << joybautomap)) != 0 && joywait < I_GetTime())
{
joywait = I_GetTime() + 5;
if (!automapactive)
{
AM_Start ();
viewactive = false;
}
else
{
bigstate = 0;
viewactive = true;
AM_Stop ();
}
return true;
}
if (!automapactive)
{
if (ev->type == ev_keydown && ev->data1 == key_map_toggle)

View file

@ -2381,7 +2381,8 @@ void G_DoPlayDemo (void)
void G_TimeDemo (char* name)
{
//!
// @vanilla
// @category video
// @vanilla
//
// Disable rendering the screen entirely.
//

View file

@ -436,7 +436,7 @@ P_FindNextHighestFloor
}
else if (h == MAX_ADJOINING_SECTORS + 2)
{
// Fatal overflow: game crashes at 22 textures
// Fatal overflow: game crashes at 22 sectors
I_Error("Sector with more than 22 adjoining sectors. "
"Vanilla will crash here");
}

View file

@ -77,8 +77,14 @@ typedef struct
} cliprange_t;
#define MAXSEGS 32
// We must expand MAXSEGS to the theoretical limit of the number of solidsegs
// that can be generated in a scene by the DOOM engine. This was determined by
// Lee Killough during BOOM development to be a function of the screensize.
// The simplest thing we can do, other than fix this bug, is to let the game
// render overage and then bomb out by detecting the overflow after the
// fact. -haleyjd
//#define MAXSEGS 32
#define MAXSEGS (SCREENWIDTH / 2 + 1)
// newend is one past the last valid seg
cliprange_t* newend;
@ -532,6 +538,10 @@ void R_Subsector (int num)
R_AddLine (line);
line++;
}
// check for solidsegs overflow - extremely unsatisfactory!
if(newend > &solidsegs[32])
I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n");
}

View file

@ -55,7 +55,7 @@ static void CopyRegion(byte *dest, int dest_pitch,
s = src; d = dest;
for (y = 0; y < h; ++y)
{
memcpy(d, s, w);
memcpy(d, s, w * sizeof(*d));
s += src_pitch;
d += dest_pitch;
}
@ -67,12 +67,14 @@ static void SaveDiskData(char *disk_lump, int xoffs, int yoffs)
patch_t *disk;
// Allocate a complete temporary screen where we'll draw the patch.
tmpscreen = Z_Malloc(SCREENWIDTH * SCREENHEIGHT, PU_STATIC, NULL);
memset(tmpscreen, 0, SCREENWIDTH * SCREENHEIGHT);
tmpscreen = Z_Malloc(SCREENWIDTH * SCREENHEIGHT * sizeof(*tmpscreen),
PU_STATIC, NULL);
memset(tmpscreen, 0, SCREENWIDTH * SCREENHEIGHT * sizeof(*tmpscreen));
V_UseBuffer(tmpscreen);
// Buffer where we'll save the disk data.
disk_data = Z_Malloc(LOADING_DISK_W * LOADING_DISK_H, PU_STATIC, NULL);
disk_data = Z_Malloc(LOADING_DISK_W * LOADING_DISK_H * sizeof(*disk_data),
PU_STATIC, NULL);
// Draw the patch and save the result to disk_data.
disk = W_CacheLumpName(disk_lump, PU_STATIC);
@ -91,8 +93,9 @@ void V_EnableLoadingDisk(char *lump_name, int xoffs, int yoffs)
loading_disk_xoffs = xoffs;
loading_disk_yoffs = yoffs;
saved_background = Z_Malloc(LOADING_DISK_W * LOADING_DISK_H, PU_STATIC,
NULL);
saved_background = Z_Malloc(LOADING_DISK_W * LOADING_DISK_H
* sizeof(*saved_background),
PU_STATIC, NULL);
SaveDiskData(lump_name, xoffs, yoffs);
}

View file

@ -673,6 +673,7 @@ void WritePCXfile(char *filename, byte *data,
pcx->hres = SHORT(width);
pcx->vres = SHORT(height);
memset (pcx->palette,0,sizeof(pcx->palette));
pcx->reserved = 0; // PCX spec: reserved byte must be zero
pcx->color_planes = 1; // chunky image
pcx->bytes_per_line = SHORT(width);
pcx->palette_type = SHORT(2); // not a grey scale

View file

@ -169,6 +169,7 @@ wad_file_t *W_AddFile (char *filename)
// Homebrew levels?
if (strncmp(header.identification,"PWAD",4))
{
W_CloseFile(wad_file);
I_Error ("Wad file %s doesn't have IWAD "
"or PWAD id\n", filename);
}
@ -177,6 +178,16 @@ wad_file_t *W_AddFile (char *filename)
}
header.numlumps = LONG(header.numlumps);
// Vanilla Doom doesn't like WADs with more than 4046 lumps
// https://www.doomworld.com/vb/post/1010985
if (!strncmp(header.identification,"PWAD",4) && header.numlumps > 4046)
{
W_CloseFile(wad_file);
I_Error ("Error: Vanilla limit for lumps in a WAD is 4046, "
"PWAD %s has %d", filename, header.numlumps);
}
header.infotableofs = LONG(header.infotableofs);
length = header.numlumps*sizeof(filelump_t);
fileinfo = Z_Malloc(length, PU_STATIC, 0);
@ -189,6 +200,7 @@ wad_file_t *W_AddFile (char *filename)
filelumps = calloc(numfilelumps, sizeof(lumpinfo_t));
if (filelumps == NULL)
{
W_CloseFile(wad_file);
I_Error("Failed to allocate array for lumps from new file.");
}
@ -197,6 +209,7 @@ wad_file_t *W_AddFile (char *filename)
lumpinfo = realloc(lumpinfo, numlumps * sizeof(lumpinfo_t *));
if (lumpinfo == NULL)
{
W_CloseFile(wad_file);
I_Error("Failed to increase lumpinfo[] array size.");
}

View file

@ -122,13 +122,13 @@ void Z_Init (void)
block->size = mainzone->size - sizeof(memzone_t);
//!
// [Deliberately undocumented]
// Zone memory debugging flag. If set, memory is zeroed after it is freed
// to deliberately break any code that attempts to use it after free.
//
zero_on_free = M_ParmExists("-zonezero");
//!
// [Deliberately undocumented]
// Zone memory debugging flag. If set, each time memory is freed, the zone
// heap is scanned to look for remaining pointers to the freed block.
//