Merge branch 'next' into kill-TMatrix

This commit is contained in:
Alam Ed Arias 2022-10-23 00:33:20 -04:00
commit 7631d0f521
257 changed files with 23906 additions and 57170 deletions

View file

@ -425,20 +425,18 @@ sectortypes
12 = "Space Countdown";
13 = "Ramp Sector (double step-up/down)";
14 = "Non-Ramp Sector (no step-down)";
15 = "Bouncy FOF";
15 = "Bouncy FOF <deprecated>";
16 = "Trigger Line Ex. (Pushable Objects)";
32 = "Trigger Line Ex. (Anywhere, All Players)";
48 = "Trigger Line Ex. (Floor Touch, All Players)";
64 = "Trigger Line Ex. (Anywhere in Sector)";
80 = "Trigger Line Ex. (Floor Touch)";
96 = "Trigger Line Ex. (Emerald Check)";
112 = "Trigger Line Ex. (NiGHTS Mare)";
96 = "Trigger Line Ex. (Emerald Check) <deprecated>";
112 = "Trigger Line Ex. (NiGHTS Mare) <deprecated>";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
512 = "Wind/Current";
1024 = "Conveyor Belt";
160 = "Special Stage Time/Spheres Parameters <deprecated>";
176 = "Custom Global Gravity <deprecated>";
1280 = "Speed Pad";
4096 = "Star Post Activator";
8192 = "Exit/Special Stage Pit/Return Flag";
@ -475,7 +473,7 @@ gen_sectortypes
12 = "Space Countdown";
13 = "Ramp Sector (double step-up/down)";
14 = "Non-Ramp Sector (no step-down)";
15 = "Bouncy FOF";
15 = "Bouncy FOF <deprecated>";
}
second
@ -486,19 +484,17 @@ gen_sectortypes
48 = "Trigger Line Ex. (Floor Touch, All Players)";
64 = "Trigger Line Ex. (Anywhere in Sector)";
80 = "Trigger Line Ex. (Floor Touch)";
96 = "Trigger Line Ex. (Emerald Check)";
112 = "Trigger Line Ex. (NiGHTS Mare)";
96 = "Trigger Line Ex. (Emerald Check) <deprecated>";
112 = "Trigger Line Ex. (NiGHTS Mare) <deprecated>";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
160 = "Special Stage Time/Spheres Parameters <deprecated>";
176 = "Custom Global Gravity <deprecated>";
}
third
{
0 = "Normal";
512 = "Wind/Current";
1024 = "Conveyor Belt";
1280 = "Speed Pad";
}
@ -771,6 +767,12 @@ linedeftypes
flags2text = "[1] Use control sector tag";
flags64text = "[6] No sound effect";
}
76
{
title = "Make FOF Bouncy";
prefix = "(76)";
}
}
polyobject
@ -1279,7 +1281,7 @@ linedeftypes
160
{
title = "Floating, Bobbing";
title = "Water Bobbing";
prefix = "(160)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
@ -2018,6 +2020,48 @@ linedeftypes
flags1024text = "[10] Use faster, unordered execution";
}
337
{
title = "Emerald Check - Continuous";
prefix = "(337)";
}
338
{
title = "Emerald Check - Each Time";
prefix = "(338)";
}
339
{
title = "Emerald Check - Once";
prefix = "(339)";
}
340
{
title = "NiGHTS Mare - Continuous";
flags2text = "[1] Mare greater or equal";
flags64text = "[6] Mare less or equal";
prefix = "(340)";
}
341
{
title = "NiGHTS Mare - Each Time";
flags2text = "[1] Mare greater or equal";
flags64text = "[6] Mare less or equal";
prefix = "(341)";
}
342
{
title = "NiGHTS Mare - Once";
flags2text = "[1] Mare greater or equal";
flags64text = "[6] Mare less or equal";
prefix = "(342)";
}
399
{
title = "Level Load";
@ -2048,23 +2092,35 @@ linedeftypes
402
{
title = "Set Tagged Sector's Light Level";
title = "Copy Light Level to Tagged Sectors";
prefix = "(402)";
flags8text = "[3] Set delay by backside sector";
}
408
{
title = "Set Tagged Sector's Flats";
prefix = "(408)";
flags64text = "[6] Don't set floor flat";
flags512text = "[9] Don't set ceiling flat";
}
409
{
title = "Change Tagged Sector's Tag";
prefix = "(409)";
flags2text = "[1] Remove tag";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Add tag";
}
410
{
title = "Change Front Sector's Tag";
prefix = "(410)";
flags2text = "[1] Remove tag";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Add tag";
}
416
@ -2122,6 +2178,14 @@ linedeftypes
prefix = "(435)";
flags8text = "[3] Set delay by backside sector";
}
467
{
title = "Set Tagged Sector's Light Level";
prefix = "(467)";
flags8text = "[3] Set delay by backside sector";
flags256text = "[8] Set relative to current";
}
}
linedefexecplane
@ -2417,6 +2481,7 @@ linedeftypes
prefix = "(439)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Only existing";
flags8192text = "[13] Use backside textures";
}
440
@ -3228,6 +3293,7 @@ linedeftypes
{
title = "Set Tagged Dynamic Slope Vertex to Front Sector Height";
prefix = "(799)";
flags64text = "[6] Use relative heights";
}
}
@ -6884,7 +6950,7 @@ thingtypes
{
color = 10; // Green
title = "Tutorial";
799
{
title = "Tutorial Plant";

View file

@ -191,6 +191,12 @@ mapformat_doom
// that make the same thing appear in the same modes
thingflagsmask1 = 7; // 1 + 2 + 4
thingflagsmask2 = 0;
// THING TYPES
thingtypes
{
include("SRB222_things.cfg", "doom");
}
}
mapformat_udmf
@ -240,17 +246,7 @@ mapformat_udmf
include("SRB222_misc.cfg", "sectorbrightness");
}
// SECTOR TYPES
sectortypes
{
include("SRB222_sectors.cfg", "sectortypes");
}
// GENERALISED SECTOR TYPES
gen_sectortypes
{
include("SRB222_sectors.cfg", "gen_sectortypes");
}
damagetypes = "Generic Water Fire Lava Electric Spike DeathPitTilt DeathPitNoTilt Instakill SpecialStage";
// LINEDEF FLAGS
linedefflags
@ -289,6 +285,12 @@ mapformat_udmf
include("UDMF_misc.cfg", "thingflagscompare");
}
// THING TYPES
thingtypes
{
include("SRB222_things.cfg", "udmf");
}
// LINEDEF TYPES
linedeftypes
{

File diff suppressed because it is too large Load diff

View file

@ -58,7 +58,6 @@ linedefflags_udmf
wrapmidtex = "Repeat Midtexture";
netonly = "Netgame Only";
nonet = "No Netgame";
effect6 = "Effect 6";
bouncy = "Bouncy Wall";
transfer = "Transfer Line";
}
@ -78,6 +77,33 @@ sectorflags
colormapfog = "Fog Planes in Colormap";
colormapfadesprites = "Fade Fullbright in Colormap";
colormapprotected = "Protected Colormap";
flipspecial_nofloor = "No Trigger on Floor Touch";
flipspecial_ceiling = "Trigger on Ceiling Touch";
triggerspecial_touch = "Trigger on Edge Touch";
triggerspecial_headbump = "Trigger on Headbump";
triggerline_plane = "Linedef Trigger Requires Plane Touch";
triggerline_mobj = "Non-Pushables Can Trigger Linedef";
invertprecip = "Invert Precipitation";
gravityflip = "Flip Objects in Reverse Gravity";
heatwave = "Heat Wave";
noclipcamera = "Intangible to the Camera";
outerspace = "Space Countdown";
doublestepup = "Ramp Sector (double step-up/down)";
nostepdown = "Non-Ramp Sector (No step-down)";
speedpad = "Speed Pad";
starpostactivator = "Star Post Activator";
exit = "Exit";
specialstagepit = "Special Stage Pit";
returnflag = "Return Flag";
redteambase = "Red Team Base";
blueteambase = "Blue Team Base";
fan = "Fan Sector";
supertransform = "Super Sonic Transform";
forcespin = "Force Spin";
zoomtubestart = "Zoom Tube Start";
zoomtubeend = "Zoom Tube End";
finishline = "Circuit Finish Line";
ropehang = "Rope Hang";
}
thingflags
@ -91,10 +117,7 @@ thingflags
// THING FLAGS
thingflags_udmf
{
extra = "Extra";
flip = "Flip";
special = "Special";
ambush = "Ambush";
}
@ -227,6 +250,30 @@ universalfields
type = 3;
default = false;
}
friction
{
type = 1;
default = 0.90625;
}
triggertag
{
type = 15;
default = 0;
}
triggerer
{
type = 0;
default = 0;
enum
{
0 = "Player";
1 = "All players";
2 = "Object";
}
}
}
linedef
@ -236,6 +283,26 @@ universalfields
type = 0;
default = 0;
}
arg6
{
type = 0;
default = 0;
}
arg7
{
type = 0;
default = 0;
}
arg8
{
type = 0;
default = 0;
}
arg9
{
type = 0;
default = 0;
}
stringarg0
{
type = 2;
@ -264,6 +331,41 @@ universalfields
thing
{
arg5
{
type = 0;
default = 0;
}
arg6
{
type = 0;
default = 0;
}
arg7
{
type = 0;
default = 0;
}
arg8
{
type = 0;
default = 0;
}
arg9
{
type = 0;
default = 0;
}
stringarg0
{
type = 2;
default = "";
}
stringarg1
{
type = 2;
default = "";
}
}
}
@ -410,6 +512,12 @@ enums
1 = "Yes";
}
setadd
{
0 = "Set";
1 = "Add";
}
onoff
{
0 = "On";
@ -441,6 +549,13 @@ enums
2 = "Back";
}
frontbackboth
{
0 = "Front";
1 = "Back";
2 = "Front and back";
}
tangibility
{
1 = "Intangible from top";
@ -448,6 +563,100 @@ enums
4 = "Don't block players";
8 = "Don't block non-players";
}
floorceiling
{
0 = "Floor";
1 = "Ceiling";
2 = "Both";
}
scrollcarry
{
0 = "Scroll and carry";
1 = "Scroll";
2 = "Carry";
}
scrolltype
{
0 = "Regular";
1 = "Accelerative";
2 = "Displacement";
}
comparison
{
0 = "Equal";
1 = "Less than or equal";
2 = "Greater than or equal";
}
triggertype
{
0 = "Continuous";
1 = "Once";
2 = "Each time on entry";
3 = "Each time on entry/exit";
}
xtriggertype
{
0 = "Continuous";
1 = "Each time on entry";
2 = "Each time on entry/exit";
}
team
{
0 = "Red";
1 = "Blue";
}
flagcheck
{
0 = "Has all";
1 = "Has any";
2 = "Has exactly";
3 = "Doesn't have all";
4 = "Doesn't have any";
}
maceflags
{
1 = "Double size";
2 = "No sounds";
4 = "Player-turnable chain";
8 = "Swing instead of spin";
16 = "Make chain from end item";
32 = "Spawn link at origin";
64 = "Clip inside ground";
128 = "No distance check";
}
pushablebehavior
{
0 = "Normal";
1 = "Slide";
2 = "Immovable";
3 = "Classic";
}
monitorrespawn
{
0 = "Same item";
1 = "Random (Weak)";
2 = "Random (Strong)";
}
blendmodes
{
0 = "Translucent";
1 = "Add";
2 = "Subtract";
3 = "Reverse subtract";
4 = "Modulate";
}
}
//Default things filters
@ -626,4 +835,4 @@ flats
start = "F_START";
end = "FF_END";
}
}
}

View file

@ -15,20 +15,18 @@ sectortypes
12 = "Space Countdown";
13 = "Ramp Sector (double step-up/down)";
14 = "Non-Ramp Sector (no step-down)";
15 = "Bouncy FOF";
15 = "Bouncy FOF <deprecated>";
16 = "Trigger Line Ex. (Pushable Objects)";
32 = "Trigger Line Ex. (Anywhere, All Players)";
48 = "Trigger Line Ex. (Floor Touch, All Players)";
64 = "Trigger Line Ex. (Anywhere in Sector)";
80 = "Trigger Line Ex. (Floor Touch)";
96 = "Trigger Line Ex. (Emerald Check)";
112 = "Trigger Line Ex. (NiGHTS Mare)";
96 = "Trigger Line Ex. (Emerald Check) <deprecated>";
112 = "Trigger Line Ex. (NiGHTS Mare) <deprecated>";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
512 = "Wind/Current";
1024 = "Conveyor Belt";
160 = "Special Stage Time/Spheres Parameters <deprecated>";
176 = "Custom Global Gravity <deprecated>";
1280 = "Speed Pad";
4096 = "Star Post Activator";
8192 = "Exit/Special Stage Pit/Return Flag";
@ -63,7 +61,7 @@ gen_sectortypes
12 = "Space Countdown";
13 = "Ramp Sector (double step-up/down)";
14 = "Non-Ramp Sector (no step-down)";
15 = "Bouncy FOF";
15 = "Bouncy FOF <deprecated>";
}
second
@ -74,19 +72,17 @@ gen_sectortypes
48 = "Trigger Line Ex. (Floor Touch, All Players)";
64 = "Trigger Line Ex. (Anywhere in Sector)";
80 = "Trigger Line Ex. (Floor Touch)";
96 = "Trigger Line Ex. (Emerald Check)";
112 = "Trigger Line Ex. (NiGHTS Mare)";
96 = "Trigger Line Ex. (Emerald Check) <deprecated>";
112 = "Trigger Line Ex. (NiGHTS Mare) <deprecated>";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
160 = "Special Stage Time/Spheres Parameters <deprecated>";
176 = "Custom Global Gravity <deprecated>";
}
third
{
0 = "Normal";
512 = "Wind/Current";
1024 = "Conveyor Belt";
1280 = "Speed Pad";
}

File diff suppressed because it is too large Load diff

View file

@ -25,12 +25,6 @@ scriptlumpnames
include("Includes\\SRB222_misc.cfg", "scriptlumpnames");
}
// THING TYPES
thingtypes
{
include("Includes\\SRB222_things.cfg");
}
//Default things filters
thingsfilters
{

View file

@ -25,12 +25,6 @@ scriptlumpnames
include("Includes\\SRB222_misc.cfg", "scriptlumpnames");
}
// THING TYPES
thingtypes
{
include("Includes\\SRB222_things.cfg");
}
//Default things filters
thingsfilters
{

View file

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<IncludePath>$(SolutionDir)libs\fmodex\inc;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)libs\fmodex\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup />
<ItemDefinitionGroup Condition="'$(PlatformTarget)'=='x64'">
<Link>
<AdditionalDependencies>fmodexL64_vc.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(PlatformTarget)'=='x86'">
<Link>
<AdditionalDependencies>fmodexL_vc.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,159 +0,0 @@
/* ==================================================================================================== */
/* FMOD Ex - codec development header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2011. */
/* */
/* Use this header if you are wanting to develop your own file format plugin to use with */
/* FMOD's codec system. With this header you can make your own fileformat plugin that FMOD */
/* can register and use. See the documentation and examples on how to make a working plugin. */
/* */
/* ==================================================================================================== */
#ifndef _FMOD_CODEC_H
#define _FMOD_CODEC_H
typedef struct FMOD_CODEC_STATE FMOD_CODEC_STATE;
typedef struct FMOD_CODEC_WAVEFORMAT FMOD_CODEC_WAVEFORMAT;
/*
Codec callbacks
*/
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_OPENCALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_CLOSECALLBACK) (FMOD_CODEC_STATE *codec_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_READCALLBACK) (FMOD_CODEC_STATE *codec_state, void *buffer, unsigned int sizebytes, unsigned int *bytesread);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETLENGTHCALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *length, FMOD_TIMEUNIT lengthtype);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SETPOSITIONCALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, unsigned int position, FMOD_TIMEUNIT postype);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETPOSITIONCALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *position, FMOD_TIMEUNIT postype);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SOUNDCREATECALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, FMOD_SOUND *sound);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_METADATACALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_TAGTYPE tagtype, char *name, void *data, unsigned int datalen, FMOD_TAGDATATYPE datatype, int unique);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETWAVEFORMAT) (FMOD_CODEC_STATE *codec_state, int index, FMOD_CODEC_WAVEFORMAT *waveformat);
/*
[STRUCTURE]
[
[DESCRIPTION]
When creating a codec, declare one of these and provide the relevant callbacks and name for FMOD to use when it opens and reads a file.
[REMARKS]
Members marked with [in] mean the variable can be written to. The user can set the value.
Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_CODEC_STATE
]
*/
typedef struct FMOD_CODEC_DESCRIPTION
{
const char *name; /* [in] Name of the codec. */
unsigned int version; /* [in] Plugin writer's version number. */
int defaultasstream; /* [in] Tells FMOD to open the file as a stream when calling System::createSound, and not a static sample. Should normally be 0 (FALSE), because generally the user wants to decode the file into memory when using System::createSound. Mainly used for formats that decode for a very long time, or could use large amounts of memory when decoded. Usually sequenced formats such as mod/s3m/xm/it/midi fall into this category. It is mainly to stop users that don't know what they're doing from getting FMOD_ERR_MEMORY returned from createSound when they should have in fact called System::createStream or used FMOD_CREATESTREAM in System::createSound. */
FMOD_TIMEUNIT timeunits; /* [in] When setposition codec is called, only these time formats will be passed to the codec. Use bitwise OR to accumulate different types. */
FMOD_CODEC_OPENCALLBACK open; /* [in] Open callback for the codec for when FMOD tries to open a sound using this codec. */
FMOD_CODEC_CLOSECALLBACK close; /* [in] Close callback for the codec for when FMOD tries to close a sound using this codec. */
FMOD_CODEC_READCALLBACK read; /* [in] Read callback for the codec for when FMOD tries to read some data from the file to the destination format (specified in the open callback). */
FMOD_CODEC_GETLENGTHCALLBACK getlength; /* [in] Callback to return the length of the song in whatever format required when Sound::getLength is called. */
FMOD_CODEC_SETPOSITIONCALLBACK setposition; /* [in] Seek callback for the codec for when FMOD tries to seek within the file with Channel::setPosition. */
FMOD_CODEC_GETPOSITIONCALLBACK getposition; /* [in] Tell callback for the codec for when FMOD tries to get the current position within the with Channel::getPosition. */
FMOD_CODEC_SOUNDCREATECALLBACK soundcreate; /* [in] Sound creation callback for the codec when FMOD finishes creating the sound. (So the codec can set more parameters for the related created sound, ie loop points/mode or 3D attributes etc). */
FMOD_CODEC_GETWAVEFORMAT getwaveformat; /* [in] Callback to tell FMOD about the waveformat of a particular subsound. This is to save memory, rather than saving 1000 FMOD_CODEC_WAVEFORMAT structures in the codec, the codec might have a more optimal way of storing this information. */
} FMOD_CODEC_DESCRIPTION;
/*
[STRUCTURE]
[
[DESCRIPTION]
Set these values marked 'in' to tell fmod what sort of sound to create.
The format, channels and frequency tell FMOD what sort of hardware buffer to create when you initialize your code. So if you wrote an MP3 codec that decoded to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2.
Members marked as 'out' are set by fmod. Do not modify these. Simply specify 0 for these values when declaring the structure, FMOD will fill in the values for you after creation with the correct function pointers.
[REMARKS]
Members marked with [in] mean the variable can be written to. The user can set the value.
Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
An FMOD file might be from disk, memory or network, however the file may be opened by the user.
'numsubsounds' should be 0 if the file is a normal single sound stream or sound. Examples of this would be .WAV, .WMA, .MP3, .AIFF.
'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself. Examples of these types would be CDDA (multiple CD tracks), FSB (contains multiple sounds), MIDI/MOD/S3M/XM/IT (contain instruments).
The arrays of format, channel, frequency, length and blockalign should point to arrays of information based on how many subsounds are in the format. If the number of subsounds is 0 then it should point to 1 of each attribute, the same as if the number of subsounds was 1. If subsounds was 100 for example, each pointer should point to an array of 100 of each attribute.
When a sound has 1 or more subsounds, you must play the individual sounds specified by first obtaining the subsound with Sound::getSubSound.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_SOUND_FORMAT
FMOD_FILE_READCALLBACK
FMOD_FILE_SEEKCALLBACK
FMOD_CODEC_METADATACALLBACK
Sound::getSubSound
Sound::getNumSubSounds
]
*/
struct FMOD_CODEC_WAVEFORMAT
{
char name[256]; /* [in] Name of sound.*/
FMOD_SOUND_FORMAT format; /* [in] Format for (decompressed) codec output, ie FMOD_SOUND_FORMAT_PCM8, FMOD_SOUND_FORMAT_PCM16.*/
int channels; /* [in] Number of channels used by codec, ie mono = 1, stereo = 2. */
int frequency; /* [in] Default frequency in hz of the codec, ie 44100. */
unsigned int lengthbytes; /* [in] Length in bytes of the source data. */
unsigned int lengthpcm; /* [in] Length in decompressed, PCM samples of the file, ie length in seconds * frequency. Used for Sound::getLength and for memory allocation of static decompressed sample data. */
int blockalign; /* [in] Blockalign in decompressed, PCM samples of the optimal decode chunk size for this format. The codec read callback will be called in multiples of this value. */
int loopstart; /* [in] Loopstart in decompressed, PCM samples of file. */
int loopend; /* [in] Loopend in decompressed, PCM samples of file. */
FMOD_MODE mode; /* [in] Mode to determine whether the sound should by default load as looping, non looping, 2d or 3d. */
unsigned int channelmask; /* [in] Microsoft speaker channel mask, as defined for WAVEFORMATEXTENSIBLE and is found in ksmedia.h. Leave at 0 to play in natural speaker order. */
};
/*
[STRUCTURE]
[
[DESCRIPTION]
Codec plugin structure that is passed into each callback.
Set these numsubsounds and waveformat members when called in FMOD_CODEC_OPENCALLBACK to tell fmod what sort of sound to create.
The format, channels and frequency tell FMOD what sort of hardware buffer to create when you initialize your code. So if you wrote an MP3 codec that decoded to stereo 16bit integer PCM, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2.
[REMARKS]
Members marked with [in] mean the variable can be written to. The user can set the value.
Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
An FMOD file might be from disk, memory or internet, however the file may be opened by the user.
'numsubsounds' should be 0 if the file is a normal single sound stream or sound. Examples of this would be .WAV, .WMA, .MP3, .AIFF.
'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself. Examples of these types would be CDDA (multiple CD tracks), FSB (contains multiple sounds), DLS (contain instruments).
The arrays of format, channel, frequency, length and blockalign should point to arrays of information based on how many subsounds are in the format. If the number of subsounds is 0 then it should point to 1 of each attribute, the same as if the number of subsounds was 1. If subsounds was 100 for example, each pointer should point to an array of 100 of each attribute.
When a sound has 1 or more subsounds, you must play the individual sounds specified by first obtaining the subsound with Sound::getSubSound.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_SOUND_FORMAT
FMOD_FILE_READCALLBACK
FMOD_FILE_SEEKCALLBACK
FMOD_CODEC_METADATACALLBACK
Sound::getSubSound
Sound::getNumSubSounds
]
*/
struct FMOD_CODEC_STATE
{
int numsubsounds; /* [in] Number of 'subsounds' in this sound. Anything other than 0 makes it a 'container' format (ie CDDA/DLS/FSB etc which contain 1 or more su bsounds). For most normal, single sound codec such as WAV/AIFF/MP3, this should be 0 as they are not a container for subsounds, they are the sound by itself. */
FMOD_CODEC_WAVEFORMAT *waveformat; /* [in] Pointer to an array of format structures containing information about each sample. Can be 0 or NULL if FMOD_CODEC_GETWAVEFORMAT callback is preferred. The number of entries here must equal the number of subsounds defined in the subsound parameter. If numsubsounds = 0 then there should be 1 instance of this structure. */
void *plugindata; /* [in] Plugin writer created data the codec author wants to attach to this object. */
void *filehandle; /* [out] This will return an internal FMOD file handle to use with the callbacks provided. */
unsigned int filesize; /* [out] This will contain the size of the file in bytes. */
FMOD_FILE_READCALLBACK fileread; /* [out] This will return a callable FMOD file function to use from codec. */
FMOD_FILE_SEEKCALLBACK fileseek; /* [out] This will return a callable FMOD file function to use from codec. */
FMOD_CODEC_METADATACALLBACK metadata; /* [out] This will return a callable FMOD metadata function to use from codec. */
};
#endif

View file

@ -1,743 +0,0 @@
/* ========================================================================================== */
/* FMOD Ex - DSP header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2011. */
/* */
/* Use this header if you are interested in delving deeper into the FMOD software mixing / */
/* DSP engine. In this header you can find parameter structures for FMOD system reigstered */
/* DSP effects and generators. */
/* Also use this header if you are wanting to develop your own DSP plugin to use with FMOD's */
/* dsp system. With this header you can make your own DSP plugin that FMOD can */
/* register and use. See the documentation and examples on how to make a working plugin. */
/* */
/* ========================================================================================== */
#ifndef _FMOD_DSP_H
#define _FMOD_DSP_H
typedef struct FMOD_DSP_STATE FMOD_DSP_STATE;
/*
DSP callbacks
*/
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_CREATECALLBACK) (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_RELEASECALLBACK) (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_RESETCALLBACK) (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_READCALLBACK) (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_SETPOSITIONCALLBACK)(FMOD_DSP_STATE *dsp_state, unsigned int pos);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_SETPARAMCALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float value);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_GETPARAMCALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr);
typedef FMOD_RESULT (F_CALLBACK *FMOD_DSP_DIALOGCALLBACK) (FMOD_DSP_STATE *dsp_state, void *hwnd, int show);
/*
[ENUM]
[
[DESCRIPTION]
These definitions can be used for creating FMOD defined special effects or DSP units.
[REMARKS]
To get them to be active, first create the unit, then add it somewhere into the DSP network, either at the front of the network near the soundcard unit to affect the global output (by using System::getDSPHead), or on a single channel (using Channel::getDSPHead).
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
System::createDSPByType
]
*/
typedef enum
{
FMOD_DSP_TYPE_UNKNOWN, /* This unit was created via a non FMOD plugin so has an unknown purpose. */
FMOD_DSP_TYPE_MIXER, /* This unit does nothing but take inputs and mix them together then feed the result to the soundcard unit. */
FMOD_DSP_TYPE_OSCILLATOR, /* This unit generates sine/square/saw/triangle or noise tones. */
FMOD_DSP_TYPE_LOWPASS, /* This unit filters sound using a high quality, resonant lowpass filter algorithm but consumes more CPU time. */
FMOD_DSP_TYPE_ITLOWPASS, /* This unit filters sound using a resonant lowpass filter algorithm that is used in Impulse Tracker, but with limited cutoff range (0 to 8060hz). */
FMOD_DSP_TYPE_HIGHPASS, /* This unit filters sound using a resonant highpass filter algorithm. */
FMOD_DSP_TYPE_ECHO, /* This unit produces an echo on the sound and fades out at the desired rate. */
FMOD_DSP_TYPE_FLANGE, /* This unit produces a flange effect on the sound. */
FMOD_DSP_TYPE_DISTORTION, /* This unit distorts the sound. */
FMOD_DSP_TYPE_NORMALIZE, /* This unit normalizes or amplifies the sound to a certain level. */
FMOD_DSP_TYPE_PARAMEQ, /* This unit attenuates or amplifies a selected frequency range. */
FMOD_DSP_TYPE_PITCHSHIFT, /* This unit bends the pitch of a sound without changing the speed of playback. */
FMOD_DSP_TYPE_CHORUS, /* This unit produces a chorus effect on the sound. */
FMOD_DSP_TYPE_VSTPLUGIN, /* This unit allows the use of Steinberg VST plugins */
FMOD_DSP_TYPE_WINAMPPLUGIN, /* This unit allows the use of Nullsoft Winamp plugins */
FMOD_DSP_TYPE_ITECHO, /* This unit produces an echo on the sound and fades out at the desired rate as is used in Impulse Tracker. */
FMOD_DSP_TYPE_COMPRESSOR, /* This unit implements dynamic compression (linked multichannel, wideband) */
FMOD_DSP_TYPE_SFXREVERB, /* This unit implements SFX reverb */
FMOD_DSP_TYPE_LOWPASS_SIMPLE, /* This unit filters sound using a simple lowpass with no resonance, but has flexible cutoff and is fast. */
FMOD_DSP_TYPE_DELAY, /* This unit produces different delays on individual channels of the sound. */
FMOD_DSP_TYPE_TREMOLO, /* This unit produces a tremolo / chopper effect on the sound. */
FMOD_DSP_TYPE_LADSPAPLUGIN, /* This unit allows the use of LADSPA standard plugins. */
FMOD_DSP_TYPE_HIGHPASS_SIMPLE, /* This unit filters sound using a simple highpass with no resonance, but has flexible cutoff and is fast. */
FMOD_DSP_TYPE_HARDWARE = 1000, /* Offset that platform specific FMOD_HARDWARE DSPs will start at. */
FMOD_DSP_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */
} FMOD_DSP_TYPE;
/*
[STRUCTURE]
[
[DESCRIPTION]
Structure to define a parameter for a DSP unit.
[REMARKS]
Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
Members marked with [w] mean the variable can be written to. The user can set the value.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
System::createDSP
DSP::setParameter
]
*/
typedef struct FMOD_DSP_PARAMETERDESC
{
float min; /* [w] Minimum value of the parameter (ie 100.0). */
float max; /* [w] Maximum value of the parameter (ie 22050.0). */
float defaultval; /* [w] Default value of parameter. */
char name[16]; /* [w] Name of the parameter to be displayed (ie "Cutoff frequency"). */
char label[16]; /* [w] Short string to be put next to value to denote the unit type (ie "hz"). */
const char *description; /* [w] Description of the parameter to be displayed as a help item / tooltip for this parameter. */
} FMOD_DSP_PARAMETERDESC;
/*
[STRUCTURE]
[
[DESCRIPTION]
When creating a DSP unit, declare one of these and provide the relevant callbacks and name for FMOD to use when it creates and uses a DSP unit of this type.
[REMARKS]
Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
Members marked with [w] mean the variable can be written to. The user can set the value.
There are 2 different ways to change a parameter in this architecture.
One is to use DSP::setParameter / DSP::getParameter. This is platform independant and is dynamic, so new unknown plugins can have their parameters enumerated and used.
The other is to use DSP::showConfigDialog. This is platform specific and requires a GUI, and will display a dialog box to configure the plugin.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
System::createDSP
FMOD_DSP_STATE
]
*/
typedef struct FMOD_DSP_DESCRIPTION
{
char name[32]; /* [w] Name of the unit to be displayed in the network. */
unsigned int version; /* [w] Plugin writer's version number. */
int channels; /* [w] Number of channels. Use 0 to process whatever number of channels is currently in the network. >0 would be mostly used if the unit is a unit that only generates sound. */
FMOD_DSP_CREATECALLBACK create; /* [w] Create callback. This is called when DSP unit is created. Can be null. */
FMOD_DSP_RELEASECALLBACK release; /* [w] Release callback. This is called just before the unit is freed so the user can do any cleanup needed for the unit. Can be null. */
FMOD_DSP_RESETCALLBACK reset; /* [w] Reset callback. This is called by the user to reset any history buffers that may need resetting for a filter, when it is to be used or re-used for the first time to its initial clean state. Use to avoid clicks or artifacts. */
FMOD_DSP_READCALLBACK read; /* [w] Read callback. Processing is done here. Can be null. */
FMOD_DSP_SETPOSITIONCALLBACK setposition; /* [w] Set position callback. This is called if the unit wants to update its position info but not process data, or reset a cursor position internally if it is reading data from a certain source. Can be null. */
int numparameters; /* [w] Number of parameters used in this filter. The user finds this with DSP::getNumParameters */
FMOD_DSP_PARAMETERDESC *paramdesc; /* [w] Variable number of parameter structures. */
FMOD_DSP_SETPARAMCALLBACK setparameter; /* [w] This is called when the user calls DSP::setParameter. Can be null. */
FMOD_DSP_GETPARAMCALLBACK getparameter; /* [w] This is called when the user calls DSP::getParameter. Can be null. */
FMOD_DSP_DIALOGCALLBACK config; /* [w] This is called when the user calls DSP::showConfigDialog. Can be used to display a dialog to configure the filter. Can be null. */
int configwidth; /* [w] Width of config dialog graphic if there is one. 0 otherwise.*/
int configheight; /* [w] Height of config dialog graphic if there is one. 0 otherwise.*/
void *userdata; /* [w] Optional. Specify 0 to ignore. This is user data to be attached to the DSP unit during creation. Access via DSP::getUserData. */
} FMOD_DSP_DESCRIPTION;
/*
[STRUCTURE]
[
[DESCRIPTION]
DSP plugin structure that is passed into each callback.
[REMARKS]
Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
Members marked with [w] mean the variable can be written to. The user can set the value.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_DSP_DESCRIPTION
]
*/
struct FMOD_DSP_STATE
{
FMOD_DSP *instance; /* [r] Handle to the DSP hand the user created. Not to be modified. C++ users cast to FMOD::DSP to use. */
void *plugindata; /* [w] Plugin writer created data the output author wants to attach to this object. */
unsigned short speakermask; /* [w] Specifies which speakers the DSP effect is active on */
};
/*
===================================================================================================
FMOD built in effect parameters.
Use DSP::setParameter with these enums for the 'index' parameter.
===================================================================================================
*/
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_OSCILLATOR filter.
[REMARKS]
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_OSCILLATOR_TYPE, /* Waveform type. 0 = sine. 1 = square. 2 = sawup. 3 = sawdown. 4 = triangle. 5 = noise. */
FMOD_DSP_OSCILLATOR_RATE /* Frequency of the sinewave in hz. 1.0 to 22000.0. Default = 220.0. */
} FMOD_DSP_OSCILLATOR;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_LOWPASS filter.
[REMARKS]
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_LOWPASS_CUTOFF, /* Lowpass cutoff frequency in hz. 10.0 to 22000.0. Default = 5000.0. */
FMOD_DSP_LOWPASS_RESONANCE /* Lowpass resonance Q value. 1.0 to 10.0. Default = 1.0. */
} FMOD_DSP_LOWPASS;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_ITLOWPASS filter.
This is different to the default FMOD_DSP_TYPE_ITLOWPASS filter in that it uses a different quality algorithm and is
the filter used to produce the correct sounding playback in .IT files.
FMOD Ex's .IT playback uses this filter.
[REMARKS]
Note! This filter actually has a limited cutoff frequency below the specified maximum, due to its limited design,
so for a more open range filter use FMOD_DSP_LOWPASS or if you don't mind not having resonance,
FMOD_DSP_LOWPASS_SIMPLE.
The effective maximum cutoff is about 8060hz.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_ITLOWPASS_CUTOFF, /* Lowpass cutoff frequency in hz. 1.0 to 22000.0. Default = 5000.0/ */
FMOD_DSP_ITLOWPASS_RESONANCE /* Lowpass resonance Q value. 0.0 to 127.0. Default = 1.0. */
} FMOD_DSP_ITLOWPASS;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_HIGHPASS filter.
[REMARKS]
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_HIGHPASS_CUTOFF, /* Highpass cutoff frequency in hz. 1.0 to output 22000.0. Default = 5000.0. */
FMOD_DSP_HIGHPASS_RESONANCE /* Highpass resonance Q value. 1.0 to 10.0. Default = 1.0. */
} FMOD_DSP_HIGHPASS;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_ECHO filter.
[REMARKS]
Note. Every time the delay is changed, the plugin re-allocates the echo buffer. This means the echo will dissapear at that time while it refills its new buffer.
Larger echo delays result in larger amounts of memory allocated.
'<i>maxchannels</i>' also dictates the amount of memory allocated. By default, the maxchannels value is 0. If FMOD is set to stereo, the echo unit will allocate enough memory for 2 channels. If it is 5.1, it will allocate enough memory for a 6 channel echo, etc.
If the echo effect is only ever applied to the global mix (ie it was added with System::addDSP), then 0 is the value to set as it will be enough to handle all speaker modes.
When the echo is added to a channel (ie Channel::addDSP) then the channel count that comes in could be anything from 1 to 8 possibly. It is only in this case where you might want to increase the channel count above the output's channel count.
If a channel echo is set to a lower number than the sound's channel count that is coming in, it will not echo the sound.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_ECHO_DELAY, /* Echo delay in ms. 10 to 5000. Default = 500. */
FMOD_DSP_ECHO_DECAYRATIO, /* Echo decay per delay. 0 to 1. 1.0 = No decay, 0.0 = total decay (ie simple 1 line delay). Default = 0.5. */
FMOD_DSP_ECHO_MAXCHANNELS, /* Maximum channels supported. 0 to 16. 0 = same as fmod's default output polyphony, 1 = mono, 2 = stereo etc. See remarks for more. Default = 0. It is suggested to leave at 0! */
FMOD_DSP_ECHO_DRYMIX, /* Volume of original signal to pass to output. 0.0 to 1.0. Default = 1.0. */
FMOD_DSP_ECHO_WETMIX /* Volume of echo signal to pass to output. 0.0 to 1.0. Default = 1.0. */
} FMOD_DSP_ECHO;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_DELAY filter.
[REMARKS]
Note. Every time MaxDelay is changed, the plugin re-allocates the delay buffer. This means the delay will dissapear at that time while it refills its new buffer.
A larger MaxDelay results in larger amounts of memory allocated.
Channel delays above MaxDelay will be clipped to MaxDelay and the delay buffer will not be resized.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_DELAY_CH0, /* Channel #0 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH1, /* Channel #1 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH2, /* Channel #2 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH3, /* Channel #3 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH4, /* Channel #4 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH5, /* Channel #5 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH6, /* Channel #6 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH7, /* Channel #7 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH8, /* Channel #8 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH9, /* Channel #9 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH10, /* Channel #10 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH11, /* Channel #11 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH12, /* Channel #12 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH13, /* Channel #13 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH14, /* Channel #14 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_CH15, /* Channel #15 Delay in ms. 0 to 10000. Default = 0. */
FMOD_DSP_DELAY_MAXDELAY /* Maximum delay in ms. 0 to 10000. Default = 10. */
} FMOD_DSP_DELAY;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_FLANGE filter.
[REMARKS]
Flange is an effect where the signal is played twice at the same time, and one copy slides back and forth creating a whooshing or flanging effect.
As there are 2 copies of the same signal, by default each signal is given 50% mix, so that the total is not louder than the original unaffected signal.
Flange depth is a percentage of a 10ms shift from the original signal. Anything above 10ms is not considered flange because to the ear it begins to 'echo' so 10ms is the highest value possible.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_FLANGE_DRYMIX, /* Volume of original signal to pass to output. 0.0 to 1.0. Default = 0.45. */
FMOD_DSP_FLANGE_WETMIX, /* Volume of flange signal to pass to output. 0.0 to 1.0. Default = 0.55. */
FMOD_DSP_FLANGE_DEPTH, /* Flange depth (percentage of 40ms delay). 0.01 to 1.0. Default = 1.0. */
FMOD_DSP_FLANGE_RATE /* Flange speed in hz. 0.0 to 20.0. Default = 0.1. */
} FMOD_DSP_FLANGE;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_TREMOLO filter.
[REMARKS]
The tremolo effect varies the amplitude of a sound. Depending on the settings, this unit can produce a tremolo, chopper or auto-pan effect.
The shape of the LFO (low freq. oscillator) can morphed between sine, triangle and sawtooth waves using the FMOD_DSP_TREMOLO_SHAPE and FMOD_DSP_TREMOLO_SKEW parameters.
FMOD_DSP_TREMOLO_DUTY and FMOD_DSP_TREMOLO_SQUARE are useful for a chopper-type effect where the first controls the on-time duration and second controls the flatness of the envelope.
FMOD_DSP_TREMOLO_SPREAD varies the LFO phase between channels to get an auto-pan effect. This works best with a sine shape LFO.
The LFO can be synchronized using the FMOD_DSP_TREMOLO_PHASE parameter which sets its instantaneous phase.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_TREMOLO_FREQUENCY, /* LFO frequency in Hz. 0.1 to 20. Default = 4. */
FMOD_DSP_TREMOLO_DEPTH, /* Tremolo depth. 0 to 1. Default = 0. */
FMOD_DSP_TREMOLO_SHAPE, /* LFO shape morph between triangle and sine. 0 to 1. Default = 0. */
FMOD_DSP_TREMOLO_SKEW, /* Time-skewing of LFO cycle. -1 to 1. Default = 0. */
FMOD_DSP_TREMOLO_DUTY, /* LFO on-time. 0 to 1. Default = 0.5. */
FMOD_DSP_TREMOLO_SQUARE, /* Flatness of the LFO shape. 0 to 1. Default = 0. */
FMOD_DSP_TREMOLO_PHASE, /* Instantaneous LFO phase. 0 to 1. Default = 0. */
FMOD_DSP_TREMOLO_SPREAD /* Rotation / auto-pan effect. -1 to 1. Default = 0. */
} FMOD_DSP_TREMOLO;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_DISTORTION filter.
[REMARKS]
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_DISTORTION_LEVEL /* Distortion value. 0.0 to 1.0. Default = 0.5. */
} FMOD_DSP_DISTORTION;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_NORMALIZE filter.
[REMARKS]
Normalize amplifies the sound based on the maximum peaks within the signal.
For example if the maximum peaks in the signal were 50% of the bandwidth, it would scale the whole sound by 2.
The lower threshold value makes the normalizer ignores peaks below a certain point, to avoid over-amplification if a loud signal suddenly came in, and also to avoid amplifying to maximum things like background hiss.
Because FMOD is a realtime audio processor, it doesn't have the luxury of knowing the peak for the whole sound (ie it can't see into the future), so it has to process data as it comes in.
To avoid very sudden changes in volume level based on small samples of new data, fmod fades towards the desired amplification which makes for smooth gain control. The fadetime parameter can control this.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_NORMALIZE_FADETIME, /* Time to ramp the silence to full in ms. 0.0 to 20000.0. Default = 5000.0. */
FMOD_DSP_NORMALIZE_THRESHHOLD, /* Lower volume range threshold to ignore. 0.0 to 1.0. Default = 0.1. Raise higher to stop amplification of very quiet signals. */
FMOD_DSP_NORMALIZE_MAXAMP /* Maximum amplification allowed. 1.0 to 100000.0. Default = 20.0. 1.0 = no amplifaction, higher values allow more boost. */
} FMOD_DSP_NORMALIZE;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_PARAMEQ filter.
[REMARKS]
Parametric EQ is a bandpass filter that attenuates or amplifies a selected frequency and its neighbouring frequencies.
To create a multi-band EQ create multiple FMOD_DSP_TYPE_PARAMEQ units and set each unit to different frequencies, for example 1000hz, 2000hz, 4000hz, 8000hz, 16000hz with a range of 1 octave each.
When a frequency has its gain set to 1.0, the sound will be unaffected and represents the original signal exactly.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_PARAMEQ_CENTER, /* Frequency center. 20.0 to 22000.0. Default = 8000.0. */
FMOD_DSP_PARAMEQ_BANDWIDTH, /* Octave range around the center frequency to filter. 0.2 to 5.0. Default = 1.0. */
FMOD_DSP_PARAMEQ_GAIN /* Frequency Gain. 0.05 to 3.0. Default = 1.0. */
} FMOD_DSP_PARAMEQ;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_PITCHSHIFT filter.
[REMARKS]
This pitch shifting unit can be used to change the pitch of a sound without speeding it up or slowing it down.
It can also be used for time stretching or scaling, for example if the pitch was doubled, and the frequency of the sound was halved, the pitch of the sound would sound correct but it would be twice as slow.
<b>Warning!</b> This filter is very computationally expensive! Similar to a vocoder, it requires several overlapping FFT and IFFT's to produce smooth output, and can require around 440mhz for 1 stereo 48khz signal using the default settings.
Reducing the signal to mono will half the cpu usage.
Reducing this will lower audio quality, but what settings to use are largely dependant on the sound being played. A noisy polyphonic signal will need higher fft size compared to a speaking voice for example.
This pitch shifter is based on the pitch shifter code at http://www.dspdimension.com, written by Stephan M. Bernsee.
The original code is COPYRIGHT 1999-2003 Stephan M. Bernsee <smb@dspdimension.com>.
'<i>maxchannels</i>' dictates the amount of memory allocated. By default, the maxchannels value is 0. If FMOD is set to stereo, the pitch shift unit will allocate enough memory for 2 channels. If it is 5.1, it will allocate enough memory for a 6 channel pitch shift, etc.
If the pitch shift effect is only ever applied to the global mix (ie it was added with System::addDSP), then 0 is the value to set as it will be enough to handle all speaker modes.
When the pitch shift is added to a channel (ie Channel::addDSP) then the channel count that comes in could be anything from 1 to 8 possibly. It is only in this case where you might want to increase the channel count above the output's channel count.
If a channel pitch shift is set to a lower number than the sound's channel count that is coming in, it will not pitch shift the sound.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_PITCHSHIFT_PITCH, /* Pitch value. 0.5 to 2.0. Default = 1.0. 0.5 = one octave down, 2.0 = one octave up. 1.0 does not change the pitch. */
FMOD_DSP_PITCHSHIFT_FFTSIZE, /* FFT window size. 256, 512, 1024, 2048, 4096. Default = 1024. Increase this to reduce 'smearing'. This effect is a warbling sound similar to when an mp3 is encoded at very low bitrates. */
FMOD_DSP_PITCHSHIFT_OVERLAP, /* Removed. Do not use. FMOD now uses 4 overlaps and cannot be changed. */
FMOD_DSP_PITCHSHIFT_MAXCHANNELS /* Maximum channels supported. 0 to 16. 0 = same as fmod's default output polyphony, 1 = mono, 2 = stereo etc. See remarks for more. Default = 0. It is suggested to leave at 0! */
} FMOD_DSP_PITCHSHIFT;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_CHORUS filter.
[REMARKS]
Chrous is an effect where the sound is more 'spacious' due to 1 to 3 versions of the sound being played along side the original signal but with the pitch of each copy modulating on a sine wave.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_CHORUS_DRYMIX, /* Volume of original signal to pass to output. 0.0 to 1.0. Default = 0.5. */
FMOD_DSP_CHORUS_WETMIX1, /* Volume of 1st chorus tap. 0.0 to 1.0. Default = 0.5. */
FMOD_DSP_CHORUS_WETMIX2, /* Volume of 2nd chorus tap. This tap is 90 degrees out of phase of the first tap. 0.0 to 1.0. Default = 0.5. */
FMOD_DSP_CHORUS_WETMIX3, /* Volume of 3rd chorus tap. This tap is 90 degrees out of phase of the second tap. 0.0 to 1.0. Default = 0.5. */
FMOD_DSP_CHORUS_DELAY, /* Chorus delay in ms. 0.1 to 100.0. Default = 40.0 ms. */
FMOD_DSP_CHORUS_RATE, /* Chorus modulation rate in hz. 0.0 to 20.0. Default = 0.8 hz. */
FMOD_DSP_CHORUS_DEPTH /* Chorus modulation depth. 0.0 to 1.0. Default = 0.03. */
} FMOD_DSP_CHORUS;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_ITECHO filter.
This is effectively a software based echo filter that emulates the DirectX DMO echo effect. Impulse tracker files can support this, and FMOD will produce the effect on ANY platform, not just those that support DirectX effects!
[REMARKS]
Note. Every time the delay is changed, the plugin re-allocates the echo buffer. This means the echo will dissapear at that time while it refills its new buffer.
Larger echo delays result in larger amounts of memory allocated.
As this is a stereo filter made mainly for IT playback, it is targeted for stereo signals.
With mono signals only the FMOD_DSP_ITECHO_LEFTDELAY is used.
For multichannel signals (>2) there will be no echo on those channels.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::SetParameter
DSP::GetParameter
FMOD_DSP_TYPE
System::addDSP
]
*/
typedef enum
{
FMOD_DSP_ITECHO_WETDRYMIX, /* Ratio of wet (processed) signal to dry (unprocessed) signal. Must be in the range from 0.0 through 100.0 (all wet). The default value is 50. */
FMOD_DSP_ITECHO_FEEDBACK, /* Percentage of output fed back into input, in the range from 0.0 through 100.0. The default value is 50. */
FMOD_DSP_ITECHO_LEFTDELAY, /* Delay for left channel, in milliseconds, in the range from 1.0 through 2000.0. The default value is 500 ms. */
FMOD_DSP_ITECHO_RIGHTDELAY, /* Delay for right channel, in milliseconds, in the range from 1.0 through 2000.0. The default value is 500 ms. */
FMOD_DSP_ITECHO_PANDELAY /* Value that specifies whether to swap left and right delays with each successive echo. The default value is zero, meaning no swap. Possible values are defined as 0.0 (equivalent to FALSE) and 1.0 (equivalent to TRUE). CURRENTLY NOT SUPPORTED. */
} FMOD_DSP_ITECHO;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_COMPRESSOR unit.
This is a simple linked multichannel software limiter that is uniform across the whole spectrum.
[REMARKS]
The limiter is not guaranteed to catch every peak above the threshold level,
because it cannot apply gain reduction instantaneously - the time delay is
determined by the attack time. However setting the attack time too short will
distort the sound, so it is a compromise. High level peaks can be avoided by
using a short attack time - but not too short, and setting the threshold a few
decibels below the critical level.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::SetParameter
DSP::GetParameter
FMOD_DSP_TYPE
System::addDSP
]
*/
typedef enum
{
FMOD_DSP_COMPRESSOR_THRESHOLD, /* Threshold level (dB) in the range from -60 through 0. The default value is 0. */
FMOD_DSP_COMPRESSOR_ATTACK, /* Gain reduction attack time (milliseconds), in the range from 10 through 200. The default value is 50. */
FMOD_DSP_COMPRESSOR_RELEASE, /* Gain reduction release time (milliseconds), in the range from 20 through 1000. The default value is 50. */
FMOD_DSP_COMPRESSOR_GAINMAKEUP /* Make-up gain (dB) applied after limiting, in the range from 0 through 30. The default value is 0. */
} FMOD_DSP_COMPRESSOR;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_SFXREVERB unit.
[REMARKS]
This is a high quality I3DL2 based reverb.
On top of the I3DL2 property set, "Dry Level" is also included to allow the dry mix to be changed.
These properties can be set with presets in FMOD_REVERB_PRESETS.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::SetParameter
DSP::GetParameter
FMOD_DSP_TYPE
System::addDSP
FMOD_REVERB_PRESETS
]
*/
typedef enum
{
FMOD_DSP_SFXREVERB_DRYLEVEL, /* Dry Level : Mix level of dry signal in output in mB. Ranges from -10000.0 to 0.0. Default is 0. */
FMOD_DSP_SFXREVERB_ROOM, /* Room : Room effect level at low frequencies in mB. Ranges from -10000.0 to 0.0. Default is -10000.0. */
FMOD_DSP_SFXREVERB_ROOMHF, /* Room HF : Room effect high-frequency level re. low frequency level in mB. Ranges from -10000.0 to 0.0. Default is 0.0. */
FMOD_DSP_SFXREVERB_DECAYTIME, /* Decay Time : Reverberation decay time at low-frequencies in seconds. Ranges from 0.1 to 20.0. Default is 1.0. */
FMOD_DSP_SFXREVERB_DECAYHFRATIO, /* Decay HF Ratio : High-frequency to low-frequency decay time ratio. Ranges from 0.1 to 2.0. Default is 0.5. */
FMOD_DSP_SFXREVERB_REFLECTIONSLEVEL, /* Reflections : Early reflections level relative to room effect in mB. Ranges from -10000.0 to 1000.0. Default is -10000.0. */
FMOD_DSP_SFXREVERB_REFLECTIONSDELAY, /* Reflect Delay : Delay time of first reflection in seconds. Ranges from 0.0 to 0.3. Default is 0.02. */
FMOD_DSP_SFXREVERB_REVERBLEVEL, /* Reverb : Late reverberation level relative to room effect in mB. Ranges from -10000.0 to 2000.0. Default is 0.0. */
FMOD_DSP_SFXREVERB_REVERBDELAY, /* Reverb Delay : Late reverberation delay time relative to first reflection in seconds. Ranges from 0.0 to 0.1. Default is 0.04. */
FMOD_DSP_SFXREVERB_DIFFUSION, /* Diffusion : Reverberation diffusion (echo density) in percent. Ranges from 0.0 to 100.0. Default is 100.0. */
FMOD_DSP_SFXREVERB_DENSITY, /* Density : Reverberation density (modal density) in percent. Ranges from 0.0 to 100.0. Default is 100.0. */
FMOD_DSP_SFXREVERB_HFREFERENCE, /* HF Reference : Reference high frequency in Hz. Ranges from 20.0 to 20000.0. Default is 5000.0. */
FMOD_DSP_SFXREVERB_ROOMLF, /* Room LF : Room effect low-frequency level in mB. Ranges from -10000.0 to 0.0. Default is 0.0. */
FMOD_DSP_SFXREVERB_LFREFERENCE /* LF Reference : Reference low-frequency in Hz. Ranges from 20.0 to 1000.0. Default is 250.0. */
} FMOD_DSP_SFXREVERB;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_LOWPASS_SIMPLE filter.
This is a very simple low pass filter, based on two single-pole RC time-constant modules.
The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.
[REMARKS]
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_LOWPASS_SIMPLE_CUTOFF /* Lowpass cutoff frequency in hz. 10.0 to 22000.0. Default = 5000.0 */
} FMOD_DSP_LOWPASS_SIMPLE;
/*
[ENUM]
[
[DESCRIPTION]
Parameter types for the FMOD_DSP_TYPE_HIGHPASS_SIMPLE filter.
This is a very simple single-order high pass filter.
The emphasis is on speed rather than accuracy, so this should not be used for task requiring critical filtering.
[REMARKS]
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
DSP::setParameter
DSP::getParameter
FMOD_DSP_TYPE
]
*/
typedef enum
{
FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF /* Highpass cutoff frequency in hz. 10.0 to 22000.0. Default = 1000.0 */
} FMOD_DSP_HIGHPASS_SIMPLE;
#endif

View file

@ -1,123 +0,0 @@
/* ============================================================================================== */
/* FMOD Ex - Error string header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2011. */
/* */
/* Use this header if you want to store or display a string version / english explanation of */
/* the FMOD error codes. */
/* */
/* ============================================================================================== */
#ifndef _FMOD_ERRORS_H
#define _FMOD_ERRORS_H
#include "fmod.h"
#ifdef __GNUC__
static const char *FMOD_ErrorString(FMOD_RESULT errcode) __attribute__((unused));
#endif
static const char *FMOD_ErrorString(FMOD_RESULT errcode)
{
switch (errcode)
{
case FMOD_ERR_ALREADYLOCKED: return "Tried to call lock a second time before unlock was called. ";
case FMOD_ERR_BADCOMMAND: return "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound). ";
case FMOD_ERR_CDDA_DRIVERS: return "Neither NTSCSI nor ASPI could be initialised. ";
case FMOD_ERR_CDDA_INIT: return "An error occurred while initialising the CDDA subsystem. ";
case FMOD_ERR_CDDA_INVALID_DEVICE: return "Couldn't find the specified device. ";
case FMOD_ERR_CDDA_NOAUDIO: return "No audio tracks on the specified disc. ";
case FMOD_ERR_CDDA_NODEVICES: return "No CD/DVD devices were found. ";
case FMOD_ERR_CDDA_NODISC: return "No disc present in the specified drive. ";
case FMOD_ERR_CDDA_READ: return "A CDDA read error occurred. ";
case FMOD_ERR_CHANNEL_ALLOC: return "Error trying to allocate a channel. ";
case FMOD_ERR_CHANNEL_STOLEN: return "The specified channel has been reused to play another sound. ";
case FMOD_ERR_COM: return "A Win32 COM related error occured. COM failed to initialize or a QueryInterface failed meaning a Windows codec or driver was not installed properly. ";
case FMOD_ERR_DMA: return "DMA Failure. See debug output for more information. ";
case FMOD_ERR_DSP_CONNECTION: return "DSP connection error. Connection possibly caused a cyclic dependancy. Or tried to connect a tree too many units deep (more than 128). ";
case FMOD_ERR_DSP_FORMAT: return "DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format. ";
case FMOD_ERR_DSP_NOTFOUND: return "DSP connection error. Couldn't find the DSP unit specified. ";
case FMOD_ERR_DSP_RUNNING: return "DSP error. Cannot perform this operation while the network is in the middle of running. This will most likely happen if a connection or disconnection is attempted in a DSP callback. ";
case FMOD_ERR_DSP_TOOMANYCONNECTIONS: return "DSP connection error. The unit being connected to or disconnected should only have 1 input or output. ";
case FMOD_ERR_EVENT_ALREADY_LOADED: return "The specified project or bank has already been loaded. Having multiple copies of the same project loaded simultaneously is forbidden. ";
case FMOD_ERR_EVENT_FAILED: return "An Event failed to be retrieved, most likely due to 'just fail' being specified as the max playbacks behavior. ";
case FMOD_ERR_EVENT_GUIDCONFLICT: return "An event with the same GUID already exists. ";
case FMOD_ERR_EVENT_INFOONLY: return "Can't execute this command on an EVENT_INFOONLY event. ";
case FMOD_ERR_EVENT_INTERNAL: return "An error occured that wasn't supposed to. See debug log for reason. ";
case FMOD_ERR_EVENT_MAXSTREAMS: return "Event failed because 'Max streams' was hit when FMOD_EVENT_INIT_FAIL_ON_MAXSTREAMS was specified. ";
case FMOD_ERR_EVENT_MISMATCH: return "FSB mismatches the FEV it was compiled with, the stream/sample mode it was meant to be created with was different, or the FEV was built for a different platform. ";
case FMOD_ERR_EVENT_NAMECONFLICT: return "A category with the same name already exists. ";
case FMOD_ERR_EVENT_NEEDSSIMPLE: return "Tried to call a function on a complex event that's only supported by simple events. ";
case FMOD_ERR_EVENT_NOTFOUND: return "The requested event, event group, event category or event property could not be found. ";
case FMOD_ERR_FILE_BAD: return "Error loading file. ";
case FMOD_ERR_FILE_COULDNOTSEEK: return "Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format. ";
case FMOD_ERR_FILE_DISKEJECTED: return "Media was ejected while reading. ";
case FMOD_ERR_FILE_EOF: return "End of file unexpectedly reached while trying to read essential data (truncated data?). ";
case FMOD_ERR_FILE_NOTFOUND: return "File not found. ";
case FMOD_ERR_FILE_UNWANTED: return "Unwanted file access occured. ";
case FMOD_ERR_FORMAT: return "Unsupported file or audio format. ";
case FMOD_ERR_HTTP: return "A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere. ";
case FMOD_ERR_HTTP_ACCESS: return "The specified resource requires authentication or is forbidden. ";
case FMOD_ERR_HTTP_PROXY_AUTH: return "Proxy authentication is required to access the specified resource. ";
case FMOD_ERR_HTTP_SERVER_ERROR: return "A HTTP server error occurred. ";
case FMOD_ERR_HTTP_TIMEOUT: return "The HTTP request timed out. ";
case FMOD_ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function. ";
case FMOD_ERR_INITIALIZED: return "Cannot call this command after System::init. ";
case FMOD_ERR_INTERNAL: return "An error occured that wasn't supposed to. Contact support. ";
case FMOD_ERR_INVALID_ADDRESS: return "On Xbox 360, this memory address passed to FMOD must be physical, (ie allocated with XPhysicalAlloc.) ";
case FMOD_ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float. ";
case FMOD_ERR_INVALID_HANDLE: return "An invalid object handle was used. ";
case FMOD_ERR_INVALID_PARAM: return "An invalid parameter was passed to this function. ";
case FMOD_ERR_INVALID_POSITION: return "An invalid seek position was passed to this function. ";
case FMOD_ERR_INVALID_SPEAKER: return "An invalid speaker was passed to this function based on the current speaker mode. ";
case FMOD_ERR_INVALID_SYNCPOINT: return "The syncpoint did not come from this sound handle. ";
case FMOD_ERR_INVALID_VECTOR: return "The vectors passed in are not unit length, or perpendicular. ";
case FMOD_ERR_MAXAUDIBLE: return "Reached maximum audible playback count for this sound's soundgroup. ";
case FMOD_ERR_MEMORY: return "Not enough memory or resources. ";
case FMOD_ERR_MEMORY_CANTPOINT: return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used. ";
case FMOD_ERR_MEMORY_SRAM: return "Not enough memory or resources on console sound ram. ";
case FMOD_ERR_MUSIC_NOCALLBACK: return "The music callback is required, but it has not been set. ";
case FMOD_ERR_MUSIC_NOTFOUND: return "The requested music entity could not be found. ";
case FMOD_ERR_MUSIC_UNINITIALIZED: return "Music system is not initialized probably because no music data is loaded. ";
case FMOD_ERR_NEEDS2D: return "Tried to call a command on a 3d sound when the command was meant for 2d sound. ";
case FMOD_ERR_NEEDS3D: return "Tried to call a command on a 2d sound when the command was meant for 3d sound. ";
case FMOD_ERR_NEEDSHARDWARE: return "Tried to use a feature that requires hardware support. (ie trying to play a GCADPCM compressed sound in software on Wii). ";
case FMOD_ERR_NEEDSSOFTWARE: return "Tried to use a feature that requires the software engine. Software engine has either been turned off, or command was executed on a hardware channel which does not support this feature. ";
case FMOD_ERR_NET_CONNECT: return "Couldn't connect to the specified host. ";
case FMOD_ERR_NET_SOCKET_ERROR: return "A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere. ";
case FMOD_ERR_NET_URL: return "The specified URL couldn't be resolved. ";
case FMOD_ERR_NET_WOULD_BLOCK: return "Operation on a non-blocking socket could not complete immediately. ";
case FMOD_ERR_NOTREADY: return "Operation could not be performed because specified sound/DSP connection is not ready. ";
case FMOD_ERR_OUTPUT_ALLOCATED: return "Error initializing output device, but more specifically, the output device is already in use and cannot be reused. ";
case FMOD_ERR_OUTPUT_CREATEBUFFER: return "Error creating hardware sound buffer. ";
case FMOD_ERR_OUTPUT_DRIVERCALL: return "A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted. ";
case FMOD_ERR_OUTPUT_ENUMERATION: return "Error enumerating the available driver list. List may be inconsistent due to a recent device addition or removal. ";
case FMOD_ERR_OUTPUT_FORMAT: return "Soundcard does not support the minimum features needed for this soundsystem (16bit stereo output). ";
case FMOD_ERR_OUTPUT_INIT: return "Error initializing output device. ";
case FMOD_ERR_OUTPUT_NOHARDWARE: return "FMOD_HARDWARE was specified but the sound card does not have the resources necessary to play it. ";
case FMOD_ERR_OUTPUT_NOSOFTWARE: return "Attempted to create a software sound but no software channels were specified in System::init. ";
case FMOD_ERR_PAN: return "Panning only works with mono or stereo sound sources. ";
case FMOD_ERR_PLUGIN: return "An unspecified error has been returned from a 3rd party plugin. ";
case FMOD_ERR_PLUGIN_INSTANCES: return "The number of allowed instances of a plugin has been exceeded. ";
case FMOD_ERR_PLUGIN_MISSING: return "A requested output, dsp unit type or codec was not available. ";
case FMOD_ERR_PLUGIN_RESOURCE: return "A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback or other DLLs that it needs to load) ";
case FMOD_ERR_PRELOADED: return "The specified sound is still in use by the event system, call EventSystem::unloadFSB before trying to release it. ";
case FMOD_ERR_PROGRAMMERSOUND: return "The specified sound is still in use by the event system, wait for the event which is using it finish with it. ";
case FMOD_ERR_RECORD: return "An error occured trying to initialize the recording device. ";
case FMOD_ERR_REVERB_INSTANCE: return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesnt exist. ";
case FMOD_ERR_SUBSOUNDS: return "The error occured because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound, or a parent sound was played without setting up a sentence first. ";
case FMOD_ERR_SUBSOUND_ALLOCATED: return "This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first. ";
case FMOD_ERR_SUBSOUND_CANTMOVE: return "Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file. ";
case FMOD_ERR_SUBSOUND_MODE: return "The subsound's mode bits do not match with the parent sound's mode bits. See documentation for function that it was called with. ";
case FMOD_ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags. ";
case FMOD_ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the maxinputchannels parameter in System::setSoftwareFormat. ";
case FMOD_ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be! contact support! ";
case FMOD_ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called. ";
case FMOD_ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified. ";
case FMOD_ERR_UPDATE: return "An error caused by System::update occured. ";
case FMOD_ERR_VERSION: return "The version number of this file format is not supported. ";
case FMOD_OK: return "No errors.";
default : return "Unknown error.";
};
}
#endif

View file

@ -1,201 +0,0 @@
/* ============================================================================================= */
/* FMOD Ex - Memory info header file. Copyright (c), Firelight Technologies Pty, Ltd. 2008-2011. */
/* */
/* Use this header if you are interested in getting detailed information on FMOD's memory */
/* usage. See the documentation for more details. */
/* */
/* ============================================================================================= */
#ifndef _FMOD_MEMORYINFO_H
#define _FMOD_MEMORYINFO_H
/*
[STRUCTURE]
[
[DESCRIPTION]
Structure to be filled with detailed memory usage information of an FMOD object
[REMARKS]
Every public FMOD class has a getMemoryInfo function which can be used to get detailed information on what memory resources are associated with the object in question.
On return from getMemoryInfo, each member of this structure will hold the amount of memory used for its type in bytes.
Members marked with [in] mean the user sets the value before passing it to the function.
Members marked with [out] mean FMOD sets the value to be used after the function exits.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
System::getMemoryInfo
EventSystem::getMemoryInfo
FMOD_MEMBITS
FMOD_EVENT_MEMBITS
]
*/
typedef struct FMOD_MEMORY_USAGE_DETAILS
{
unsigned int other; /* [out] Memory not accounted for by other types */
unsigned int string; /* [out] String data */
unsigned int system; /* [out] System object and various internals */
unsigned int plugins; /* [out] Plugin objects and internals */
unsigned int output; /* [out] Output module object and internals */
unsigned int channel; /* [out] Channel related memory */
unsigned int channelgroup; /* [out] ChannelGroup objects and internals */
unsigned int codec; /* [out] Codecs allocated for streaming */
unsigned int file; /* [out] File buffers and structures */
unsigned int sound; /* [out] Sound objects and internals */
unsigned int secondaryram; /* [out] Sound data stored in secondary RAM */
unsigned int soundgroup; /* [out] SoundGroup objects and internals */
unsigned int streambuffer; /* [out] Stream buffer memory */
unsigned int dspconnection; /* [out] DSPConnection objects and internals */
unsigned int dsp; /* [out] DSP implementation objects */
unsigned int dspcodec; /* [out] Realtime file format decoding DSP objects */
unsigned int profile; /* [out] Profiler memory footprint. */
unsigned int recordbuffer; /* [out] Buffer used to store recorded data from microphone */
unsigned int reverb; /* [out] Reverb implementation objects */
unsigned int reverbchannelprops; /* [out] Reverb channel properties structs */
unsigned int geometry; /* [out] Geometry objects and internals */
unsigned int syncpoint; /* [out] Sync point memory. */
unsigned int eventsystem; /* [out] EventSystem and various internals */
unsigned int musicsystem; /* [out] MusicSystem and various internals */
unsigned int fev; /* [out] Definition of objects contained in all loaded projects e.g. events, groups, categories */
unsigned int memoryfsb; /* [out] Data loaded with preloadFSB */
unsigned int eventproject; /* [out] EventProject objects and internals */
unsigned int eventgroupi; /* [out] EventGroup objects and internals */
unsigned int soundbankclass; /* [out] Objects used to manage wave banks */
unsigned int soundbanklist; /* [out] Data used to manage lists of wave bank usage */
unsigned int streaminstance; /* [out] Stream objects and internals */
unsigned int sounddefclass; /* [out] Sound definition objects */
unsigned int sounddefdefclass; /* [out] Sound definition static data objects */
unsigned int sounddefpool; /* [out] Sound definition pool data */
unsigned int reverbdef; /* [out] Reverb definition objects */
unsigned int eventreverb; /* [out] Reverb objects */
unsigned int userproperty; /* [out] User property objects */
unsigned int eventinstance; /* [out] Event instance base objects */
unsigned int eventinstance_complex; /* [out] Complex event instance objects */
unsigned int eventinstance_simple; /* [out] Simple event instance objects */
unsigned int eventinstance_layer; /* [out] Event layer instance objects */
unsigned int eventinstance_sound; /* [out] Event sound instance objects */
unsigned int eventenvelope; /* [out] Event envelope objects */
unsigned int eventenvelopedef; /* [out] Event envelope definition objects */
unsigned int eventparameter; /* [out] Event parameter objects */
unsigned int eventcategory; /* [out] Event category objects */
unsigned int eventenvelopepoint; /* [out] Event envelope point objects */
unsigned int eventinstancepool; /* [out] Event instance pool memory */
} FMOD_MEMORY_USAGE_DETAILS;
/*
[DEFINE]
[
[NAME]
FMOD_MEMBITS
[DESCRIPTION]
Bitfield used to request specific memory usage information from the getMemoryInfo function of every public FMOD Ex class.
Use with the "memorybits" parameter of getMemoryInfo to get information on FMOD Ex memory usage.
[REMARKS]
Every public FMOD class has a getMemoryInfo function which can be used to get detailed information on what memory resources are associated with the object in question.
The FMOD_MEMBITS defines can be OR'd together to specify precisely what memory usage you'd like to get information on. See System::getMemoryInfo for an example.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_EVENT_MEMBITS
System::getMemoryInfo
]
*/
#define FMOD_MEMBITS_OTHER 0x00000001 /* Memory not accounted for by other types */
#define FMOD_MEMBITS_STRING 0x00000002 /* String data */
#define FMOD_MEMBITS_SYSTEM 0x00000004 /* System object and various internals */
#define FMOD_MEMBITS_PLUGINS 0x00000008 /* Plugin objects and internals */
#define FMOD_MEMBITS_OUTPUT 0x00000010 /* Output module object and internals */
#define FMOD_MEMBITS_CHANNEL 0x00000020 /* Channel related memory */
#define FMOD_MEMBITS_CHANNELGROUP 0x00000040 /* ChannelGroup objects and internals */
#define FMOD_MEMBITS_CODEC 0x00000080 /* Codecs allocated for streaming */
#define FMOD_MEMBITS_FILE 0x00000100 /* Codecs allocated for streaming */
#define FMOD_MEMBITS_SOUND 0x00000200 /* Sound objects and internals */
#define FMOD_MEMBITS_SOUND_SECONDARYRAM 0x00000400 /* Sound data stored in secondary RAM */
#define FMOD_MEMBITS_SOUNDGROUP 0x00000800 /* SoundGroup objects and internals */
#define FMOD_MEMBITS_STREAMBUFFER 0x00001000 /* Stream buffer memory */
#define FMOD_MEMBITS_DSPCONNECTION 0x00002000 /* DSPConnection objects and internals */
#define FMOD_MEMBITS_DSP 0x00004000 /* DSP implementation objects */
#define FMOD_MEMBITS_DSPCODEC 0x00008000 /* Realtime file format decoding DSP objects */
#define FMOD_MEMBITS_PROFILE 0x00010000 /* Profiler memory footprint. */
#define FMOD_MEMBITS_RECORDBUFFER 0x00020000 /* Buffer used to store recorded data from microphone */
#define FMOD_MEMBITS_REVERB 0x00040000 /* Reverb implementation objects */
#define FMOD_MEMBITS_REVERBCHANNELPROPS 0x00080000 /* Reverb channel properties structs */
#define FMOD_MEMBITS_GEOMETRY 0x00100000 /* Geometry objects and internals */
#define FMOD_MEMBITS_SYNCPOINT 0x00200000 /* Sync point memory. */
#define FMOD_MEMBITS_ALL 0xffffffff /* All memory used by FMOD Ex */
/* [DEFINE_END] */
/*
[DEFINE]
[
[NAME]
FMOD_EVENT_MEMBITS
[DESCRIPTION]
Bitfield used to request specific memory usage information from the getMemoryInfo function of every public FMOD Event System class.
Use with the "event_memorybits" parameter of getMemoryInfo to get information on FMOD Event System memory usage.
[REMARKS]
Every public FMOD Event System class has a getMemoryInfo function which can be used to get detailed information on what memory resources are associated with the object in question.
The FMOD_EVENT_MEMBITS defines can be OR'd together to specify precisely what memory usage you'd like to get information on. See EventSystem::getMemoryInfo for an example.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_MEMBITS
System::getMemoryInfo
]
*/
#define FMOD_EVENT_MEMBITS_EVENTSYSTEM 0x00000001 /* EventSystem and various internals */
#define FMOD_EVENT_MEMBITS_MUSICSYSTEM 0x00000002 /* MusicSystem and various internals */
#define FMOD_EVENT_MEMBITS_FEV 0x00000004 /* Definition of objects contained in all loaded projects e.g. events, groups, categories */
#define FMOD_EVENT_MEMBITS_MEMORYFSB 0x00000008 /* Data loaded with preloadFSB */
#define FMOD_EVENT_MEMBITS_EVENTPROJECT 0x00000010 /* EventProject objects and internals */
#define FMOD_EVENT_MEMBITS_EVENTGROUPI 0x00000020 /* EventGroup objects and internals */
#define FMOD_EVENT_MEMBITS_SOUNDBANKCLASS 0x00000040 /* Objects used to manage wave banks */
#define FMOD_EVENT_MEMBITS_SOUNDBANKLIST 0x00000080 /* Data used to manage lists of wave bank usage */
#define FMOD_EVENT_MEMBITS_STREAMINSTANCE 0x00000100 /* Stream objects and internals */
#define FMOD_EVENT_MEMBITS_SOUNDDEFCLASS 0x00000200 /* Sound definition objects */
#define FMOD_EVENT_MEMBITS_SOUNDDEFDEFCLASS 0x00000400 /* Sound definition static data objects */
#define FMOD_EVENT_MEMBITS_SOUNDDEFPOOL 0x00000800 /* Sound definition pool data */
#define FMOD_EVENT_MEMBITS_REVERBDEF 0x00001000 /* Reverb definition objects */
#define FMOD_EVENT_MEMBITS_EVENTREVERB 0x00002000 /* Reverb objects */
#define FMOD_EVENT_MEMBITS_USERPROPERTY 0x00004000 /* User property objects */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCE 0x00008000 /* Event instance base objects */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_COMPLEX 0x00010000 /* Complex event instance objects */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_SIMPLE 0x00020000 /* Simple event instance objects */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_LAYER 0x00040000 /* Event layer instance objects */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_SOUND 0x00080000 /* Event sound instance objects */
#define FMOD_EVENT_MEMBITS_EVENTENVELOPE 0x00100000 /* Event envelope objects */
#define FMOD_EVENT_MEMBITS_EVENTENVELOPEDEF 0x00200000 /* Event envelope definition objects */
#define FMOD_EVENT_MEMBITS_EVENTPARAMETER 0x00400000 /* Event parameter objects */
#define FMOD_EVENT_MEMBITS_EVENTCATEGORY 0x00800000 /* Event category objects */
#define FMOD_EVENT_MEMBITS_EVENTENVELOPEPOINT 0x01000000 /* Event envelope point object+s */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCEPOOL 0x02000000 /* Event instance pool data */
#define FMOD_EVENT_MEMBITS_ALL 0xffffffff /* All memory used by FMOD Event System */
/* All event instance memory */
#define FMOD_EVENT_MEMBITS_EVENTINSTANCE_GROUP (FMOD_EVENT_MEMBITS_EVENTINSTANCE | \
FMOD_EVENT_MEMBITS_EVENTINSTANCE_COMPLEX | \
FMOD_EVENT_MEMBITS_EVENTINSTANCE_SIMPLE | \
FMOD_EVENT_MEMBITS_EVENTINSTANCE_LAYER | \
FMOD_EVENT_MEMBITS_EVENTINSTANCE_SOUND)
/* All sound definition memory */
#define FMOD_EVENT_MEMBITS_SOUNDDEF_GROUP (FMOD_EVENT_MEMBITS_SOUNDDEFCLASS | \
FMOD_EVENT_MEMBITS_SOUNDDEFDEFCLASS | \
FMOD_EVENT_MEMBITS_SOUNDDEFPOOL)
/* [DEFINE_END] */
#endif

View file

@ -1,93 +0,0 @@
/* ==================================================================================================== */
/* FMOD Ex - output development header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2011. */
/* */
/* Use this header if you are wanting to develop your own output plugin to use with */
/* FMOD's output system. With this header you can make your own output plugin that FMOD */
/* can register and use. See the documentation and examples on how to make a working plugin. */
/* */
/* ==================================================================================================== */
#ifndef _FMOD_OUTPUT_H
#define _FMOD_OUTPUT_H
#include "fmod.h"
typedef struct FMOD_OUTPUT_STATE FMOD_OUTPUT_STATE;
/*
Output callbacks
*/
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETNUMDRIVERSCALLBACK)(FMOD_OUTPUT_STATE *output_state, int *numdrivers);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETDRIVERNAMECALLBACK)(FMOD_OUTPUT_STATE *output_state, int id, char *name, int namelen);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETDRIVERCAPSCALLBACK)(FMOD_OUTPUT_STATE *output_state, int id, FMOD_CAPS *caps);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_INITCALLBACK) (FMOD_OUTPUT_STATE *output_state, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_CLOSECALLBACK) (FMOD_OUTPUT_STATE *output_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_UPDATECALLBACK) (FMOD_OUTPUT_STATE *output_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETHANDLECALLBACK) (FMOD_OUTPUT_STATE *output_state, void **handle);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_GETPOSITIONCALLBACK) (FMOD_OUTPUT_STATE *output_state, unsigned int *pcm);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_LOCKCALLBACK) (FMOD_OUTPUT_STATE *output_state, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_UNLOCKCALLBACK) (FMOD_OUTPUT_STATE *output_state, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
typedef FMOD_RESULT (F_CALLBACK *FMOD_OUTPUT_READFROMMIXER) (FMOD_OUTPUT_STATE *output_state, void *buffer, unsigned int length);
/*
[STRUCTURE]
[
[DESCRIPTION]
When creating an output, declare one of these and provide the relevant callbacks and name for FMOD to use when it opens and reads a file of this type.
[REMARKS]
Members marked with [in] mean the variable can be written to. The user can set the value.
Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_OUTPUT_STATE
]
*/
typedef struct FMOD_OUTPUT_DESCRIPTION
{
const char *name; /* [in] Name of the output. */
unsigned int version; /* [in] Plugin writer's version number. */
int polling; /* [in] If TRUE (non zero), this tells FMOD to start a thread and call getposition / lock / unlock for feeding data. If 0, the output is probably callback based, so all the plugin needs to do is call readfrommixer to the appropriate pointer. */
FMOD_OUTPUT_GETNUMDRIVERSCALLBACK getnumdrivers; /* [in] For sound device enumeration. This callback is to give System::getNumDrivers somthing to return. */
FMOD_OUTPUT_GETDRIVERNAMECALLBACK getdrivername; /* [in] For sound device enumeration. This callback is to give System::getDriverName somthing to return. */
FMOD_OUTPUT_GETDRIVERCAPSCALLBACK getdrivercaps; /* [in] For sound device enumeration. This callback is to give System::getDriverCaps somthing to return. */
FMOD_OUTPUT_INITCALLBACK init; /* [in] Initialization function for the output device. This is called from System::init. */
FMOD_OUTPUT_CLOSECALLBACK close; /* [in] Cleanup / close down function for the output device. This is called from System::close. */
FMOD_OUTPUT_UPDATECALLBACK update; /* [in] Update function that is called once a frame by the user. This is called from System::update. */
FMOD_OUTPUT_GETHANDLECALLBACK gethandle; /* [in] This is called from System::getOutputHandle. This is just to return a pointer to the internal system device object that the system may be using.*/
FMOD_OUTPUT_GETPOSITIONCALLBACK getposition; /* [in] This is called from the FMOD software mixer thread if 'polling' = true. This returns a position value in samples so that FMOD knows where and when to fill its buffer. */
FMOD_OUTPUT_LOCKCALLBACK lock; /* [in] This is called from the FMOD software mixer thread if 'polling' = true. This function provides a pointer to data that FMOD can write to when software mixing. */
FMOD_OUTPUT_UNLOCKCALLBACK unlock; /* [in] This is called from the FMOD software mixer thread if 'polling' = true. This optional function accepts the data that has been mixed and copies it or does whatever it needs to before sending it to the hardware. */
} FMOD_OUTPUT_DESCRIPTION;
/*
[STRUCTURE]
[
[DESCRIPTION]
Output plugin structure that is passed into each callback.
[REMARKS]
Members marked with [in] mean the variable can be written to. The user can set the value.
Members marked with [out] mean the variable is modified by FMOD and is for reading purposes only. Do not change this value.
[PLATFORMS]
Win32, Win64, Linux, Linux64, Macintosh, Xbox360, PlayStation Portable, PlayStation 3, Wii, iPhone, 3GS, NGP, Android
[SEE_ALSO]
FMOD_OUTPUT_DESCRIPTION
]
*/
struct FMOD_OUTPUT_STATE
{
void *plugindata; /* [in] Plugin writer created data the output author wants to attach to this object. */
FMOD_OUTPUT_READFROMMIXER readfrommixer; /* [out] Function to update mixer and write the result to the provided pointer. Used from callback based output only. Polling based output uses lock/unlock/getposition. */
};
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,28 +0,0 @@
Which library do I link?
------------------------
If you want to use fmodex.dll:
Visual Studio users - fmodex_vc.lib.
Metrowerks Codewarrior users - fmodex_vc.lib.
Borland users - fmodex_bc.lib.
LCC-Win32 users - fmodex_lcc.lib.
Dev-C++, MinGW and CygWin users - libfmodex.a.
If you want to use fmodexL.dll: (same as fmodex.dll but with debug logging enabled)
Visual Studio users - fmodexL_vc.lib.
Metrowerks Codewarrior users - fmodexL_vc.lib.
Borland users - fmodexL_bc.lib.
LCC-Win32 users - fmodexL_lcc.lib.
Dev-C++, MinGW and CygWin users - libfmodexL.a.
If you want to use fmodex64.dll: (same as fmodex.dll but for 64bit machines)
Visual Studio users - fmodex64_vc.lib.
If you want to use fmodexL64.dll: (same as fmodex64.dll but with debug logging enabled)
Visual Studio users - fmodexL64_vc.lib.
No other compilers are supported for 64bit libraries.

View file

@ -31,8 +31,8 @@
# MINGW=1, MINGW64=1 - Windows (MinGW toolchain)
# UNIX=1 - Generic Unix like system
# FREEBSD=1
# SDL=1 - Use SDL backend. SDL is the only backend though
# and thus, always enabled.
# SDL=1 - Use SDL backend. SDL is the only implemented backend though.
# If disabled, a dummy backend will be used.
#
# A list of supported GCC versions can be found in
# Makefile.d/detect.mk -- search 'gcc_versions'.

View file

@ -17,7 +17,6 @@ all_systems:=\
UNIX\
LINUX\
FREEBSD\
SDL\
# check for user specified system
ifeq (,$(filter $(all_systems),$(.VARIABLES)))

5
src/Makefile.d/dummy.mk Normal file
View file

@ -0,0 +1,5 @@
makedir:=$(makedir)/Dummy
sources+=$(call List,dummy/Sourcefile)
NOHW=1

View file

@ -18,7 +18,7 @@ opts+=-I/usr/X11R6/include
libs+=-L/usr/X11R6/lib
endif
SDL=1
SDL?=1
# In common usage.
ifdef LINUX

View file

@ -64,6 +64,8 @@ ifdef UNIX
include Makefile.d/nix.mk
endif
ifdef SDL
ifeq ($(SDL), 1)
include Makefile.d/sdl.mk
else
include Makefile.d/dummy.mk
endif

View file

@ -19,7 +19,7 @@ libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
nasm_format:=win32
SDL=1
SDL?=1
ifndef NOHW
opts+=-DUSE_WGL_SWAP
@ -76,6 +76,7 @@ else
lib:=../libs/SDL2_mixer/$(mingw)
endif
ifdef SDL
mixer_opts:=-I$(lib)/include/SDL2
mixer_libs:=-L$(lib)/lib
@ -85,6 +86,7 @@ SDL_opts:=-I$(lib)/include/SDL2\
SDL_libs:=-L$(lib)/lib $(mixer_libs)\
-lmingw32 -lSDL2main -lSDL2 -mwindows
$(eval $(call _set,SDL))
endif
lib:=../libs/zlib
ZLIB_opts:=-I$(lib)

View file

@ -31,9 +31,9 @@ void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
"__usedindex",
"__gc", "__mode", "__eq",
"__gc", "__mode", "__len", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__len", "__lt", "__le",
"__pow", "__unm", "__lt", "__le",
"__concat", "__call"
,"__strhook"
,"__and", "__or", "__xor", "__shl", "__shr", "__not"

View file

@ -21,6 +21,7 @@ typedef enum {
TM_USEDINDEX,
TM_GC,
TM_MODE,
TM_LEN,
TM_EQ, /* last tag method with `fast' access */
TM_ADD,
TM_SUB,
@ -29,7 +30,6 @@ typedef enum {
TM_MOD,
TM_POW,
TM_UNM,
TM_LEN,
TM_LT,
TM_LE,
TM_CONCAT,

View file

@ -311,6 +311,33 @@ void luaV_concat (lua_State *L, int total, int last) {
}
static void objlen (lua_State *L, StkId ra, TValue *rb) {
const TValue *tm;
switch (ttype(rb)) {
case LUA_TTABLE: {
Table *h = hvalue(rb);
tm = fasttm(L, h->metatable, TM_LEN);
if (tm) break; /* metamethod? break switch to call it */
setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */
return;
}
case LUA_TSTRING: {
tm = fasttm(L, G(L)->mt[LUA_TSTRING], TM_LEN);
if (tm) break; /* metamethod? break switch to call it */
setnvalue(ra, cast_num(tsvalue(rb)->len));
return;
}
default: { /* try metamethod */
tm = luaT_gettmbyobj(L, rb, TM_LEN);
if (ttisnil(tm)) /* no metamethod? */
luaG_typeerror(L, rb, "get length of");
break;
}
}
callTMres(L, ra, tm, rb, luaO_nilobject);
}
static void Arith (lua_State *L, StkId ra, TValue *rb,
TValue *rc, TMS op) {
TValue tempb, tempc;
@ -568,23 +595,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
continue;
}
case OP_LEN: {
TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE: {
setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
break;
}
case LUA_TSTRING: {
setnvalue(ra, cast_num(tsvalue(rb)->len));
break;
}
default: { /* try metamethod */
Protect(
if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
luaG_typeerror(L, rb, "get length of");
)
}
}
Protect(objlen(L, ra, RB(i)));
continue;
}
case OP_CONCAT: {

View file

@ -660,7 +660,7 @@ static void COM_ExecuteString(char *ptext)
// check cvars
// Hurdler: added at Ebola's request ;)
// (don't flood the console in software mode with bad gl_xxx command)
if (!CV_Command() && con_destlines)
if (!CV_Command() && (con_destlines || dedicated))
CONS_Printf(M_GetText("Unknown command '%s'\n"), COM_Argv(0));
}

View file

@ -880,7 +880,7 @@ void D_RegisterClientCommands(void)
// ingame object placing
COM_AddCommand("objectplace", Command_ObjectPlace_f);
COM_AddCommand("writethings", Command_Writethings_f);
//COM_AddCommand("writethings", Command_Writethings_f);
CV_RegisterVar(&cv_speed);
CV_RegisterVar(&cv_opflags);
CV_RegisterVar(&cv_ophoopflags);

View file

@ -245,7 +245,8 @@ typedef enum
CR_MINECART,
CR_ROLLOUT,
CR_PTERABYTE,
CR_DUSTDEVIL
CR_DUSTDEVIL,
CR_FAN
} carrytype_t; // pw_carry
// Player powers. (don't edit this comment)

View file

@ -330,14 +330,85 @@ static inline int lib_getenum(lua_State *L)
}
else if (fastncmp("ML_", word, 3)) {
p = word+3;
for (i = 0; i < 16; i++)
if (ML_LIST[i] && fastcmp(p, ML_LIST[i])) {
for (i = 0; ML_LIST[i]; i++)
if (fastcmp(p, ML_LIST[i])) {
lua_pushinteger(L, ((lua_Integer)1<<i));
return 1;
}
// Aliases
if (fastcmp(p, "EFFECT1"))
{
lua_pushinteger(L, (lua_Integer)ML_SKEWTD);
return 1;
}
if (fastcmp(p, "EFFECT2"))
{
lua_pushinteger(L, (lua_Integer)ML_NOSKEW);
return 1;
}
if (fastcmp(p, "EFFECT3"))
{
lua_pushinteger(L, (lua_Integer)ML_MIDPEG);
return 1;
}
if (fastcmp(p, "EFFECT4"))
{
lua_pushinteger(L, (lua_Integer)ML_MIDSOLID);
return 1;
}
if (fastcmp(p, "EFFECT5"))
{
lua_pushinteger(L, (lua_Integer)ML_WRAPMIDTEX);
return 1;
}
if (mathlib) return luaL_error(L, "linedef flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("MSF_", word, 4)) {
p = word + 4;
for (i = 0; MSF_LIST[i]; i++)
if (fastcmp(p, MSF_LIST[i])) {
lua_pushinteger(L, ((lua_Integer)1 << i));
return 1;
}
if (fastcmp(p, "FLIPSPECIAL_BOTH"))
{
lua_pushinteger(L, (lua_Integer)MSF_FLIPSPECIAL_BOTH);
return 1;
}
if (mathlib) return luaL_error(L, "sector flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("SSF_", word, 4)) {
p = word + 4;
for (i = 0; SSF_LIST[i]; i++)
if (fastcmp(p, SSF_LIST[i])) {
lua_pushinteger(L, ((lua_Integer)1 << i));
return 1;
}
if (mathlib) return luaL_error(L, "sector special flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("SD_", word, 3)) {
p = word + 3;
for (i = 0; SD_LIST[i]; i++)
if (fastcmp(p, SD_LIST[i])) {
lua_pushinteger(L, i);
return 1;
}
if (mathlib) return luaL_error(L, "sector damagetype '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("TO_", word, 3)) {
p = word + 3;
for (i = 0; TO_LIST[i]; i++)
if (fastcmp(p, TO_LIST[i])) {
lua_pushinteger(L, i);
return 1;
}
if (mathlib) return luaL_error(L, "sector triggerer '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("S_",word,2)) {
p = word+2;
for (i = 0; i < NUMSTATEFREESLOTS; i++) {

View file

@ -2687,10 +2687,10 @@ void readhuditem(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "F"))
{
hudinfo[num].f = i;
hudinfo[num].f = get_number(word2);
}
else
deh_warning("Level header %d: unknown word '%s'", num, word);
deh_warning("HUD item %d: unknown word '%s'", num, word);
}
} while (!myfeof(f)); // finish when the line is empty
@ -3307,7 +3307,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
else
re = atoi(params[1]);
if (re < 0 || re >= NUMMAPS)
if (re <= 0 || re > NUMMAPS)
{
deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS);
return;
@ -3327,7 +3327,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
else
x1 = (INT16)atoi(params[1]);
if (x1 < 0 || x1 >= NUMMAPS)
if (x1 <= 0 || x1 > NUMMAPS)
{
deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS);
return;
@ -3362,7 +3362,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
else
x1 = (INT16)atoi(params[1]);
if (x1 < 0 || x1 >= NUMMAPS)
if (x1 <= 0 || x1 > NUMMAPS)
{
deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS);
return;

View file

@ -91,6 +91,8 @@ actionpointer_t actionpointers[] =
{{A_FaceTracer}, "A_FACETRACER"},
{{A_Scream}, "A_SCREAM"},
{{A_BossDeath}, "A_BOSSDEATH"},
{{A_SetShadowScale}, "A_SETSHADOWSCALE"},
{{A_ShadowScream}, "A_SHADOWSCREAM"},
{{A_CustomPower}, "A_CUSTOMPOWER"},
{{A_GiveWeapon}, "A_GIVEWEAPON"},
{{A_RingBox}, "A_RINGBOX"},
@ -197,6 +199,7 @@ actionpointer_t actionpointers[] =
{{A_Boss3Path}, "A_BOSS3PATH"},
{{A_Boss3ShockThink}, "A_BOSS3SHOCKTHINK"},
{{A_LinedefExecute}, "A_LINEDEFEXECUTE"},
{{A_LinedefExecuteFromArg}, "A_LINEDEFEXECUTEFROMARG"},
{{A_PlaySeeSound}, "A_PLAYSEESOUND"},
{{A_PlayAttackSound}, "A_PLAYATTACKSOUND"},
{{A_PlayActiveSound}, "A_PLAYACTIVESOUND"},
@ -4169,17 +4172,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_FINISHFLAG", // Finish flag
// Ambient Sounds
"MT_AWATERA", // Ambient Water Sound 1
"MT_AWATERB", // Ambient Water Sound 2
"MT_AWATERC", // Ambient Water Sound 3
"MT_AWATERD", // Ambient Water Sound 4
"MT_AWATERE", // Ambient Water Sound 5
"MT_AWATERF", // Ambient Water Sound 6
"MT_AWATERG", // Ambient Water Sound 7
"MT_AWATERH", // Ambient Water Sound 8
"MT_RANDOMAMBIENT",
"MT_RANDOMAMBIENT2",
"MT_MACHINEAMBIENCE",
"MT_AMBIENT",
"MT_CORK",
"MT_LHRT",
@ -4283,7 +4276,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_CRUMBLEOBJ", // Sound generator for crumbling platform
"MT_TUBEWAYPOINT",
"MT_PUSH",
"MT_PULL",
"MT_GHOST",
"MT_OVERLAY",
"MT_ANGLEMAN",
@ -4520,23 +4512,85 @@ const char *const GAMETYPERULE_LIST[] = {
};
// Linedef flags
const char *const ML_LIST[16] = {
const char *const ML_LIST[] = {
"IMPASSIBLE",
"BLOCKMONSTERS",
"TWOSIDED",
"DONTPEGTOP",
"DONTPEGBOTTOM",
"EFFECT1",
"SKEWTD",
"NOCLIMB",
"EFFECT2",
"EFFECT3",
"EFFECT4",
"EFFECT5",
"NOSONIC",
"NOTAILS",
"NOKNUX",
"NOSKEW",
"MIDPEG",
"MIDSOLID",
"WRAPMIDTEX",
"NETONLY",
"NONET",
"EFFECT6",
"BOUNCY",
"TFERLINE"
"TFERLINE",
NULL
};
// Sector flags
const char *const MSF_LIST[] = {
"FLIPSPECIAL_FLOOR",
"FLIPSPECIAL_CEILING",
"TRIGGERSPECIAL_TOUCH",
"TRIGGERSPECIAL_HEADBUMP",
"TRIGGERLINE_PLANE",
"TRIGGERLINE_MOBJ",
"GRAVITYFLIP",
"HEATWAVE",
"NOCLIPCAMERA",
NULL
};
// Sector special flags
const char *const SSF_LIST[] = {
"OUTERSPACE",
"DOUBLESTEPUP",
"WINDCURRENT",
"CONVEYOR",
"SPEEDPAD",
"STARPOSTACTIVATOR",
"EXIT",
"SPECIALSTAGEPIT",
"RETURNFLAG",
"REDTEAMBASE",
"BLUETEAMBASE",
"FAN",
"SUPERTRANSFORM",
"FORCESPIN",
"ZOOMTUBESTART",
"ZOOMTUBEEND",
"FINISHLINE",
"ROPEHANG",
NULL
};
// Sector damagetypes
const char *const SD_LIST[] = {
"NONE",
"GENERIC",
"WATER",
"FIRE",
"LAVA",
"ELECTRIC",
"SPIKE",
"DEATHPITTILT",
"DEATHPITNOTILT",
"INSTAKILL",
"SPECIALSTAGE",
NULL
};
// Sector triggerer
const char *const TO_LIST[] = {
"PLAYER",
"ALLPLAYERS",
"MOBJ",
NULL
};
const char *COLOR_ENUMS[] = {
@ -5065,6 +5119,7 @@ struct int_const_s const INT_CONST[] = {
{"CR_ROLLOUT",CR_ROLLOUT},
{"CR_PTERABYTE",CR_PTERABYTE},
{"CR_DUSTDEVIL",CR_DUSTDEVIL},
{"CR_FAN",CR_FAN},
// Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon
@ -5272,44 +5327,92 @@ struct int_const_s const INT_CONST[] = {
{"SKSJUMP",SKSJUMP},
// 3D Floor/Fake Floor/FOF/whatever flags
{"FF_EXISTS",FF_EXISTS}, ///< Always set, to check for validity.
{"FF_BLOCKPLAYER",FF_BLOCKPLAYER}, ///< Solid to player, but nothing else
{"FF_BLOCKOTHERS",FF_BLOCKOTHERS}, ///< Solid to everything but player
{"FF_SOLID",FF_SOLID}, ///< Clips things.
{"FF_RENDERSIDES",FF_RENDERSIDES}, ///< Renders the sides.
{"FF_RENDERPLANES",FF_RENDERPLANES}, ///< Renders the floor/ceiling.
{"FF_RENDERALL",FF_RENDERALL}, ///< Renders everything.
{"FF_SWIMMABLE",FF_SWIMMABLE}, ///< Is a water block.
{"FF_NOSHADE",FF_NOSHADE}, ///< Messes with the lighting?
{"FF_CUTSOLIDS",FF_CUTSOLIDS}, ///< Cuts out hidden solid pixels.
{"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels.
{"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels.
{"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes.
{"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA.
{"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through!
{"FF_FOG",FF_FOG}, ///< Fog "brush."
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes.
{"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides.
{"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides.
{"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light?
{"FF_FLOATBOB",FF_FLOATBOB}, ///< Floats on water and bobs if you step on it.
{"FF_NORETURN",FF_NORETURN}, ///< Used with ::FF_CRUMBLE. Will not return to its original position after falling.
{"FF_CRUMBLE",FF_CRUMBLE}, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist).
{"FF_SHATTERBOTTOM",FF_SHATTERBOTTOM}, ///< Used with ::FF_BUSTUP. Like FF_SHATTER, but only breaks from the bottom. Good for springing up through rubble.
{"FF_MARIO",FF_MARIO}, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector.
{"FF_BUSTUP",FF_BUSTUP}, ///< You can spin through/punch this block and it will crumble!
{"FF_QUICKSAND",FF_QUICKSAND}, ///< Quicksand!
{"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top.
{"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
{"FF_INTANGIBLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid.
{"FF_INTANGABLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangable, but the sides are still solid.
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
{"FF_STRONGBUST",FF_STRONGBUST}, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
{"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
{"FOF_EXISTS",FOF_EXISTS}, ///< Always set, to check for validity.
{"FOF_BLOCKPLAYER",FOF_BLOCKPLAYER}, ///< Solid to player, but nothing else
{"FOF_BLOCKOTHERS",FOF_BLOCKOTHERS}, ///< Solid to everything but player
{"FOF_SOLID",FOF_SOLID}, ///< Clips things.
{"FOF_RENDERSIDES",FOF_RENDERSIDES}, ///< Renders the sides.
{"FOF_RENDERPLANES",FOF_RENDERPLANES}, ///< Renders the floor/ceiling.
{"FOF_RENDERALL",FOF_RENDERALL}, ///< Renders everything.
{"FOF_SWIMMABLE",FOF_SWIMMABLE}, ///< Is a water block.
{"FOF_NOSHADE",FOF_NOSHADE}, ///< Messes with the lighting?
{"FOF_CUTSOLIDS",FOF_CUTSOLIDS}, ///< Cuts out hidden solid pixels.
{"FOF_CUTEXTRA",FOF_CUTEXTRA}, ///< Cuts out hidden translucent pixels.
{"FOF_CUTLEVEL",FOF_CUTLEVEL}, ///< Cuts out all hidden pixels.
{"FOF_CUTSPRITES",FOF_CUTSPRITES}, ///< Final step in making 3D water.
{"FOF_BOTHPLANES",FOF_BOTHPLANES}, ///< Render inside and outside planes.
{"FOF_EXTRA",FOF_EXTRA}, ///< Gets cut by ::FOF_CUTEXTRA.
{"FOF_TRANSLUCENT",FOF_TRANSLUCENT}, ///< See through!
{"FOF_FOG",FOF_FOG}, ///< Fog "brush."
{"FOF_INVERTPLANES",FOF_INVERTPLANES}, ///< Only render inside planes.
{"FOF_ALLSIDES",FOF_ALLSIDES}, ///< Render inside and outside sides.
{"FOF_INVERTSIDES",FOF_INVERTSIDES}, ///< Only render inside sides.
{"FOF_DOUBLESHADOW",FOF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light?
{"FOF_FLOATBOB",FOF_FLOATBOB}, ///< Floats on water and bobs if you step on it.
{"FOF_NORETURN",FOF_NORETURN}, ///< Used with ::FOF_CRUMBLE. Will not return to its original position after falling.
{"FOF_CRUMBLE",FOF_CRUMBLE}, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist).
{"FOF_GOOWATER",FOF_GOOWATER}, ///< Used with ::FOF_SWIMMABLE. Makes thick bouncey goop.
{"FOF_MARIO",FOF_MARIO}, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector.
{"FOF_BUSTUP",FOF_BUSTUP}, ///< You can spin through/punch this block and it will crumble!
{"FOF_QUICKSAND",FOF_QUICKSAND}, ///< Quicksand!
{"FOF_PLATFORM",FOF_PLATFORM}, ///< You can jump up through this to the top.
{"FOF_REVERSEPLATFORM",FOF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
{"FOF_INTANGIBLEFLATS",FOF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid.
{"FOF_RIPPLE",FOF_RIPPLE}, ///< Ripple the flats
{"FOF_COLORMAPONLY",FOF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
{"FOF_BOUNCY",FOF_BOUNCY}, ///< Bounces players
{"FOF_SPLAT",FOF_SPLAT}, ///< Use splat flat renderer (treat cyan pixels as invisible)
// Old FOF flags for backwards compatibility
{"FF_EXISTS",FF_OLD_EXISTS},
{"FF_BLOCKPLAYER",FF_OLD_BLOCKPLAYER},
{"FF_BLOCKOTHERS",FF_OLD_BLOCKOTHERS},
{"FF_SOLID",FF_OLD_SOLID},
{"FF_RENDERSIDES",FF_OLD_RENDERSIDES},
{"FF_RENDERPLANES",FF_OLD_RENDERPLANES},
{"FF_RENDERALL",FF_OLD_RENDERALL},
{"FF_SWIMMABLE",FF_OLD_SWIMMABLE},
{"FF_NOSHADE",FF_OLD_NOSHADE},
{"FF_CUTSOLIDS",FF_OLD_CUTSOLIDS},
{"FF_CUTEXTRA",FF_OLD_CUTEXTRA},
{"FF_CUTLEVEL",FF_OLD_CUTLEVEL},
{"FF_CUTSPRITES",FF_OLD_CUTSPRITES},
{"FF_BOTHPLANES",FF_OLD_BOTHPLANES},
{"FF_EXTRA",FF_OLD_EXTRA},
{"FF_TRANSLUCENT",FF_OLD_TRANSLUCENT},
{"FF_FOG",FF_OLD_FOG},
{"FF_INVERTPLANES",FF_OLD_INVERTPLANES},
{"FF_ALLSIDES",FF_OLD_ALLSIDES},
{"FF_INVERTSIDES",FF_OLD_INVERTSIDES},
{"FF_DOUBLESHADOW",FF_OLD_DOUBLESHADOW},
{"FF_FLOATBOB",FF_OLD_FLOATBOB},
{"FF_NORETURN",FF_OLD_NORETURN},
{"FF_CRUMBLE",FF_OLD_CRUMBLE},
{"FF_SHATTERBOTTOM",FF_OLD_SHATTERBOTTOM},
{"FF_GOOWATER",FF_OLD_GOOWATER},
{"FF_MARIO",FF_OLD_MARIO},
{"FF_BUSTUP",FF_OLD_BUSTUP},
{"FF_QUICKSAND",FF_OLD_QUICKSAND},
{"FF_PLATFORM",FF_OLD_PLATFORM},
{"FF_REVERSEPLATFORM",FF_OLD_REVERSEPLATFORM},
{"FF_INTANGIBLEFLATS",FF_OLD_INTANGIBLEFLATS},
{"FF_INTANGABLEFLATS",FF_OLD_INTANGIBLEFLATS},
{"FF_SHATTER",FF_OLD_SHATTER},
{"FF_SPINBUST",FF_OLD_SPINBUST},
{"FF_STRONGBUST",FF_OLD_STRONGBUST},
{"FF_RIPPLE",FF_OLD_RIPPLE},
{"FF_COLORMAPONLY",FF_OLD_COLORMAPONLY},
// FOF bustable flags
{"FB_PUSHABLES",FB_PUSHABLES},
{"FB_EXECUTOR",FB_EXECUTOR},
{"FB_ONLYBOTTOM",FB_ONLYBOTTOM},
// Bustable FOF type
{"BT_TOUCH",BT_TOUCH},
{"BT_SPINBUST",BT_SPINBUST},
{"BT_REGULAR",BT_REGULAR},
{"BT_STRONG",BT_STRONG},
// PolyObject flags
{"POF_CLIPLINES",POF_CLIPLINES}, ///< Test against lines for collision

View file

@ -64,7 +64,11 @@ extern const char *const MOBJEFLAG_LIST[];
extern const char *const MAPTHINGFLAG_LIST[4];
extern const char *const PLAYERFLAG_LIST[];
extern const char *const GAMETYPERULE_LIST[];
extern const char *const ML_LIST[16]; // Linedef flags
extern const char *const ML_LIST[]; // Linedef flags
extern const char *const MSF_LIST[]; // Sector flags
extern const char *const SSF_LIST[]; // Sector special flags
extern const char *const SD_LIST[]; // Sector damagetype
extern const char *const TO_LIST[]; // Sector triggerer
extern const char *COLOR_ENUMS[];
extern const char *const POWERS_LIST[];
extern const char *const HUDITEMS_LIST[];

View file

@ -123,15 +123,15 @@ typedef struct
// lower texture unpegged
#define ML_DONTPEGBOTTOM 16
#define ML_EFFECT1 32
#define ML_SKEWTD 32
// Don't let Knuckles climb on this line
#define ML_NOCLIMB 64
#define ML_EFFECT2 128
#define ML_EFFECT3 256
#define ML_EFFECT4 512
#define ML_EFFECT5 1024
#define ML_NOSKEW 128
#define ML_MIDPEG 256
#define ML_MIDSOLID 512
#define ML_WRAPMIDTEX 1024
#define ML_NETONLY 2048 // Apply effect only in netgames
#define ML_NONET 4096 // Apply effect only in single player games
@ -196,7 +196,7 @@ typedef struct
#pragma pack()
#endif
#define NUMMAPTHINGARGS 6
#define NUMMAPTHINGARGS 10
#define NUMMAPTHINGSTRINGARGS 2
// Thing definition, position, orientation and type,

View file

@ -401,7 +401,7 @@ extern skincolor_t skincolors[MAXSKINCOLORS];
#define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items.
// Special linedef executor tag numbers!
// Special linedef executor tag numbers! Binary map format only (UDMF has other ways of doing these things).
enum {
LE_PINCHPHASE = -2, // A boss entered pinch phase (and, in most cases, is preparing their pinch phase attack!)
LE_ALLBOSSESDEAD = -3, // All bosses in the map are dead (Egg capsule raise)
@ -483,8 +483,11 @@ extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL;
char *va(const char *format, ...) FUNCPRINTF;
char *M_GetToken(const char *inputString);
void M_UnGetToken(void);
UINT32 M_GetTokenPos(void);
void M_SetTokenPos(UINT32 newPos);
void M_TokenizerOpen(const char *inputString);
void M_TokenizerClose(void);
const char *M_TokenizerRead(UINT32 i);
UINT32 M_TokenizerGetEndPos(void);
void M_TokenizerSetEndPos(UINT32 newPos);
char *sizeu1(size_t num);
char *sizeu2(size_t num);
char *sizeu3(size_t num);
@ -530,6 +533,22 @@ extern boolean capslock;
// i_system.c, replace getchar() once the keyboard has been appropriated
INT32 I_GetKey(void);
/* http://www.cse.yorku.ca/~oz/hash.html */
static inline
UINT32 quickncasehash (const char *p, size_t n)
{
size_t i = 0;
UINT32 x = 5381;
while (i < n && p[i])
{
x = (x * 33) ^ tolower(p[i]);
i++;
}
return x;
}
#ifndef min // Double-Check with WATTCP-32's cdefs.h
#define min(x, y) (((x) < (y)) ? (x) : (y))
#endif

View file

@ -392,8 +392,6 @@ unset_bit_array (bitarray_t * const array, const int value)
array[value >> 3] &= ~(1<<(value & 7));
}
#ifdef HAVE_SDL
typedef UINT64 precise_t;
#endif
#endif //__DOOMTYPE__

5
src/dummy/Sourcefile Normal file
View file

@ -0,0 +1,5 @@
i_net.c
i_system.c
i_main.c
i_video.c
i_sound.c

View file

@ -139,29 +139,24 @@ boolean I_LoadSong(char *data, size_t len)
void I_UnloadSong(void)
{
(void)handle;
}
boolean I_PlaySong(boolean looping)
{
(void)handle;
(void)looping;
return false;
}
void I_StopSong(void)
{
(void)handle;
}
void I_PauseSong(void)
{
(void)handle;
}
void I_ResumeSong(void)
{
(void)handle;
}
void I_SetMusicVolume(UINT8 volume)
@ -188,18 +183,20 @@ void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
{
(void)target_volume;
(void)source_volume;
(void)ms;
(void)callback;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
{
(void)target_volume;
(void)ms;
(void)callback;
return false;
}

View file

@ -1,6 +1,9 @@
#include "../doomdef.h"
#include "../doomtype.h"
#include "../i_system.h"
FILE *logstream = NULL;
UINT8 graphics_started = 0;
UINT8 keyboard_started = 0;
@ -16,11 +19,17 @@ tic_t I_GetTime(void)
return 0;
}
int I_GetTimeMicros(void)
precise_t I_GetPreciseTime(void)
{
return 0;
}
int I_PreciseToMicros(precise_t d)
{
(void)d;
return 0;
}
void I_Sleep(void){}
void I_GetEvent(void){}
@ -96,8 +105,6 @@ void I_StartupMouse(void){}
void I_StartupMouse2(void){}
void I_StartupKeyboard(void){}
INT32 I_GetKey(void)
{
return 0;
@ -176,12 +183,18 @@ INT32 I_ClipboardCopy(const char *data, size_t size)
return -1;
}
char *I_ClipboardPaste(void)
const char *I_ClipboardPaste(void)
{
return NULL;
}
void I_RegisterSysCommands(void) {}
void I_GetCursorPosition(INT32 *x, INT32 *y)
{
(void)x;
(void)y;
}
#include "../sdl/dosstr.c"

View file

@ -2221,7 +2221,7 @@ void G_AddGhost(char *defdemoname)
gh->mo->angle = FixedAngle(mthing->angle << FRACBITS);
f = gh->mo->floorz;
c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height;
if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP))
if (!!(mthing->args[0]) ^ !!(mthing->options & MTF_OBJECTFLIP))
{
z = c - offset;
if (z < f)

View file

@ -74,6 +74,8 @@ typedef struct gl_vissprite_s
float spritexscale, spriteyscale;
float spritexoffset, spriteyoffset;
skincolornum_t color;
UINT32 renderflags;
UINT8 rotateflags;

View file

@ -887,9 +887,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
if (endtop < endrealbot && top < realbot)
return;
if (!(list[i].flags & FF_NOSHADE))
if (!(list[i].flags & FOF_NOSHADE))
{
if (pfloor && (pfloor->flags & FF_FOG))
if (pfloor && (pfloor->fofflags & FOF_FOG))
{
lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y);
colormap = pfloor->master->frontsector->extra_colormap;
@ -903,13 +903,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
solid = false;
if ((sector->lightlist[i].flags & FF_CUTSOLIDS) && !(cutflag & FF_EXTRA))
if ((sector->lightlist[i].flags & FOF_CUTSOLIDS) && !(cutflag & FOF_EXTRA))
solid = true;
else if ((sector->lightlist[i].flags & FF_CUTEXTRA) && (cutflag & FF_EXTRA))
else if ((sector->lightlist[i].flags & FOF_CUTEXTRA) && (cutflag & FOF_EXTRA))
{
if (sector->lightlist[i].flags & FF_EXTRA)
if (sector->lightlist[i].flags & FOF_EXTRA)
{
if ((sector->lightlist[i].flags & (FF_FOG|FF_SWIMMABLE)) == (cutflag & (FF_FOG|FF_SWIMMABLE))) // Only merge with your own types
if ((sector->lightlist[i].flags & (FOF_FOG|FOF_SWIMMABLE)) == (cutflag & (FOF_FOG|FOF_SWIMMABLE))) // Only merge with your own types
solid = true;
}
else
@ -978,7 +978,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
if (cutflag & FF_FOG)
if (cutflag & FOF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, lightnum, colormap);
@ -1007,7 +1007,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
if (cutflag & FF_FOG)
if (cutflag & FOF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, lightnum, colormap);
@ -1146,7 +1146,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// PEGGING
if (gl_linedef->flags & ML_DONTPEGTOP)
texturevpegtop = 0;
else if (gl_linedef->flags & ML_EFFECT1)
else if (gl_linedef->flags & ML_SKEWTD)
texturevpegtop = worldhigh + textureheight[gl_sidedef->toptexture] - worldtop;
else
texturevpegtop = gl_backsector->ceilingheight + textureheight[gl_sidedef->toptexture] - gl_frontsector->ceilingheight;
@ -1162,7 +1162,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_EFFECT1))
if (!(gl_linedef->flags & ML_SKEWTD))
{
// Unskewed
wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY;
@ -1192,7 +1192,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL, 0);
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FOF_CUTLEVEL, NULL, 0);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, PF_Environment, false, lightnum, colormap);
else
@ -1212,7 +1212,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// PEGGING
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
texturevpegbottom = 0;
else if (gl_linedef->flags & ML_EFFECT1)
else if (gl_linedef->flags & ML_SKEWTD)
texturevpegbottom = worldbottom - worldlow;
else
texturevpegbottom = gl_frontsector->floorheight - gl_backsector->floorheight;
@ -1228,7 +1228,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_EFFECT1))
if (!(gl_linedef->flags & ML_SKEWTD))
{
// Unskewed
wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY;
@ -1258,7 +1258,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL, 0);
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FOF_CUTLEVEL, NULL, 0);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, PF_Environment, false, lightnum, colormap);
else
@ -1286,7 +1286,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (gl_sidedef->repeatcnt)
repeats = 1 + gl_sidedef->repeatcnt;
else if (gl_linedef->flags & ML_EFFECT5)
else if (gl_linedef->flags & ML_WRAPMIDTEX)
{
fixed_t high, low;
@ -1328,9 +1328,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
popenbottom = max(worldbottom, worldlow);
}
if (gl_linedef->flags & ML_EFFECT2)
if (gl_linedef->flags & ML_NOSKEW)
{
if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3))
if (gl_linedef->flags & ML_MIDPEG)
{
polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset;
polytop = polybottom + textureheight[gl_midtexture]*repeats;
@ -1341,7 +1341,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
polybottom = polytop - textureheight[gl_midtexture]*repeats;
}
}
else if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3))
else if (gl_linedef->flags & ML_MIDPEG)
{
polybottom = popenbottom + gl_sidedef->rowoffset;
polytop = polybottom + textureheight[gl_midtexture]*repeats;
@ -1371,7 +1371,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
// PEGGING
if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3))
if (gl_linedef->flags & ML_MIDPEG)
texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom;
else
texturevpeg = polytop - h;
@ -1394,9 +1394,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
fixed_t midtextureslant;
if (gl_linedef->flags & ML_EFFECT2)
if (gl_linedef->flags & ML_NOSKEW)
midtextureslant = 0;
else if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3))
else if (gl_linedef->flags & ML_MIDPEG)
midtextureslant = worldlow < worldbottom
? worldbottomslope-worldbottom
: worldlowslope-worldlow;
@ -1421,7 +1421,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
// PEGGING
if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3))
if (gl_linedef->flags & ML_MIDPEG)
texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom;
else
texturevpeg = polytop - h;
@ -1435,44 +1435,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// set alpha for transparent walls
// ooops ! this do not work at all because render order we should render it in backtofront order
switch (gl_linedef->special)
if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
{
// Translucent
case 102:
case 121:
case 123:
case 124:
case 125:
case 141:
case 142:
case 144:
case 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
else
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
{
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
else
blendmode = PF_Masked;
break;
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
else
blendmode = PF_Masked;
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
{
@ -1492,9 +1465,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (gl_frontsector->numlights)
{
if (!(blendmode & PF_Masked))
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL, blendmode);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_TRANSLUCENT, NULL, blendmode);
else
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, blendmode);
}
else if (!(blendmode & PF_Masked))
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
@ -1538,7 +1511,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
fixed_t texturevpeg;
// PEGGING
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_EFFECT2)) == (ML_DONTPEGBOTTOM|ML_EFFECT2))
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset;
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset;
@ -1554,7 +1527,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
// Texture correction for slopes
if (gl_linedef->flags & ML_EFFECT2) {
if (gl_linedef->flags & ML_NOSKEW) {
wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY;
wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY;
wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY;
@ -1576,7 +1549,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// I don't think that solid walls can use translucent linedef types...
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, 0);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FOF_CUTLEVEL, NULL, 0);
else
{
if (grTex->mipmap.flags & TF_TRANSPARENT)
@ -1640,9 +1613,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (bothsides) continue;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
if (!(rover->fofflags & FOF_ALLSIDES) && rover->fofflags & FOF_INVERTSIDES)
continue;
SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight)
@ -1683,7 +1656,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
if (rover->flags & FF_FOG)
if (rover->fofflags & FOF_FOG)
{
wallVerts[3].t = wallVerts[2].t = 0;
wallVerts[0].t = wallVerts[1].t = 0;
@ -1703,13 +1676,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
texturevpeg = sides[newline->sidenum[0]].rowoffset;
attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM);
slopeskew = !!(newline->flags & ML_DONTPEGTOP);
slopeskew = !!(newline->flags & ML_SKEWTD);
}
else
{
texturevpeg = sides[rover->master->sidenum[0]].rowoffset;
attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM);
slopeskew = !!(rover->master->flags & ML_DONTPEGTOP);
slopeskew = !!(rover->master->flags & ML_SKEWTD);
}
grTex = HWR_GetTexture(texnum);
@ -1742,7 +1715,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
}
if (rover->flags & FF_FOG)
if (rover->fofflags & FOF_FOG)
{
FBITFIELD blendmode;
@ -1754,7 +1727,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode);
HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->fofflags, rover, blendmode);
else
HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap);
}
@ -1762,14 +1735,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
FBITFIELD blendmode = PF_Masked;
if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
if ((rover->fofflags & FOF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
{
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
}
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->fofflags, rover, blendmode);
else
{
if (blendmode != PF_Masked)
@ -1797,9 +1770,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (bothsides) continue;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
if (!(rover->fofflags & FOF_ALLSIDES || rover->fofflags & FOF_INVERTSIDES))
continue;
SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight)
@ -1839,7 +1812,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(hS);
wallVerts[0].y = FIXED_TO_FLOAT(l);
wallVerts[1].y = FIXED_TO_FLOAT(lS);
if (rover->flags & FF_FOG)
if (rover->fofflags & FOF_FOG)
{
wallVerts[3].t = wallVerts[2].t = 0;
wallVerts[0].t = wallVerts[1].t = 0;
@ -1865,7 +1838,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
}
if (rover->flags & FF_FOG)
if (rover->fofflags & FOF_FOG)
{
FBITFIELD blendmode;
@ -1877,7 +1850,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode);
HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->fofflags, rover, blendmode);
else
HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap);
}
@ -1885,14 +1858,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
FBITFIELD blendmode = PF_Masked;
if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
if ((rover->fofflags & FOF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
{
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
}
if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->fofflags, rover, blendmode);
else
{
if (blendmode != PF_Masked)
@ -2973,7 +2946,7 @@ static FBITFIELD HWR_RippleBlend(sector_t *sector, ffloor_t *rover, boolean ceil
{
(void)sector;
(void)ceiling;
return /*R_IsRipplePlane(sector, rover, ceiling)*/ (rover->flags & FF_RIPPLE) ? PF_Ripple : 0;
return /*R_IsRipplePlane(sector, rover, ceiling)*/ (rover->fofflags & FOF_RIPPLE) ? PF_Ripple : 0;
}
// -----------------+
@ -3062,13 +3035,13 @@ static void HWR_Subsector(size_t num)
}
light = R_GetPlaneLight(gl_frontsector, locFloorHeight, false);
if (gl_frontsector->floorlightsec == -1)
floorlightlevel = *gl_frontsector->lightlist[light].lightlevel;
if (gl_frontsector->floorlightsec == -1 && !gl_frontsector->floorlightabsolute)
floorlightlevel = max(0, min(255, *gl_frontsector->lightlist[light].lightlevel + gl_frontsector->floorlightlevel));
floorcolormap = *gl_frontsector->lightlist[light].extra_colormap;
light = R_GetPlaneLight(gl_frontsector, locCeilingHeight, false);
if (gl_frontsector->ceilinglightsec == -1)
ceilinglightlevel = *gl_frontsector->lightlist[light].lightlevel;
if (gl_frontsector->ceilinglightsec == -1 && !gl_frontsector->ceilinglightabsolute)
ceilinglightlevel = max(0, min(255, *gl_frontsector->lightlist[light].lightlevel + gl_frontsector->ceilinglightlevel));
ceilingcolormap = *gl_frontsector->lightlist[light].extra_colormap;
}
@ -3141,17 +3114,17 @@ static void HWR_Subsector(size_t num)
cullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy);
centerHeight = P_GetFFloorBottomZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y);
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES))
continue;
if (sub->validcount == validcount)
continue;
if (centerHeight <= locCeilingHeight &&
centerHeight >= locFloorHeight &&
((dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
((dup_viewz < cullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) ||
(dup_viewz > cullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
if (rover->flags & FF_FOG)
if (rover->fofflags & FOF_FOG)
{
UINT8 alpha;
@ -3166,7 +3139,7 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap);
}
else if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend) // SoM: Flags are more efficient
else if ((rover->fofflags & FOF_TRANSLUCENT && rover->alpha < 256) || rover->blend) // SoM: Flags are more efficient
{
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
@ -3194,10 +3167,10 @@ static void HWR_Subsector(size_t num)
if (centerHeight >= locFloorHeight &&
centerHeight <= locCeilingHeight &&
((dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
((dup_viewz > cullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) ||
(dup_viewz < cullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
if (rover->flags & FF_FOG)
if (rover->fofflags & FOF_FOG)
{
UINT8 alpha;
@ -3212,7 +3185,7 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap);
}
else if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
else if ((rover->fofflags & FOF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
{
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
@ -3594,7 +3567,7 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
return false;
cullplane = FIXED_TO_FLOAT(cullheight->frontsector->floorheight);
if (cullheight->flags & ML_NOCLIMB) // Group culling
if (cullheight->args[1]) // Group culling
{
if (!viewcullheight)
return false;
@ -3632,6 +3605,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
FBITFIELD blendmode = PF_Translucent|PF_Modulated;
INT32 shader = SHADER_DEFAULT;
UINT8 i;
INT32 heightsec, phs;
SINT8 flip = P_MobjFlip(thing);
INT32 light;
@ -3644,7 +3618,23 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
groundz = R_GetShadowZ(thing, &groundslope);
//if (abs(groundz - gl_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes
heightsec = thing->subsector->sector->heightsec;
if (viewplayer->mo && viewplayer->mo->subsector)
phs = viewplayer->mo->subsector->sector->heightsec;
else
phs = -1;
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
{
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
thing->z >= sectors[heightsec].floorheight :
thing->z < sectors[heightsec].floorheight)
return;
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
thing->z < sectors[heightsec].ceilingheight && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
thing->z >= sectors[heightsec].ceilingheight)
return;
}
floordiff = abs((flip < 0 ? thing->height : 0) + thing->z - groundz);
@ -3949,7 +3939,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
return;
// even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
if (!(list[i].flags & FOF_NOSHADE) && (list[i].flags & FOF_CUTSPRITES))
{
if (!lightset)
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
@ -5301,13 +5291,19 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
{
float top = gzt;
float bottom = FIXED_TO_FLOAT(thing->z);
if (R_ThingIsFloorSprite(thing))
top = bottom;
if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
bottom >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
top < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
return;
if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
FIXED_TO_FLOAT(thing->z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
top < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
bottom >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
return;
}
@ -5374,6 +5370,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
vis->mobj = thing;
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer && thing->color == SKINCOLOR_NONE)
vis->color = thing->tracer->color;
else
vis->color = thing->color;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
@ -5383,13 +5383,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
else if (vis->mobj->type == MT_METALSONIC_BATTLE)
vis->colormap = R_GetTranslationColormap(TC_METALSONIC, 0, GTC_CACHE);
else
vis->colormap = R_GetTranslationColormap(TC_BOSS, vis->mobj->color, GTC_CACHE);
vis->colormap = R_GetTranslationColormap(TC_BOSS, vis->color, GTC_CACHE);
}
else if (thing->color)
else if (vis->color)
{
// New colormap stuff for skins Tails 06-07-2002
if (thing->colorized)
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE);
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, vis->color, GTC_CACHE);
else if (thing->player && thing->player->dashmode >= DASHMODE_THRESHOLD
&& (thing->player->charflags & SF_DASHMODE)
&& ((leveltime/2) & 1))
@ -5397,15 +5397,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->player->charflags & SF_MACHINE)
vis->colormap = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
else
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, thing->color, GTC_CACHE);
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, vis->color, GTC_CACHE);
}
else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player!
{
size_t skinnum = (skin_t*)thing->skin-skins;
vis->colormap = R_GetTranslationColormap((INT32)skinnum, thing->color, GTC_CACHE);
vis->colormap = R_GetTranslationColormap((INT32)skinnum, vis->color, GTC_CACHE);
}
else
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE);
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->color ? vis->color : SKINCOLOR_CYAN, GTC_CACHE);
}
else
vis->colormap = NULL;
@ -5515,6 +5515,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
vis->flip = flip;
vis->mobj = (mobj_t *)thing;
vis->color = SKINCOLOR_NONE;
vis->colormap = NULL;

View file

@ -1306,7 +1306,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!R_ThingIsFullBright(spr->mobj))
if (R_ThingIsFullDark(spr->mobj))
lightlevel = 0;
else if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (*sector->lightlist[light].lightlevel>>1);
else if (!R_ThingIsFullBright(spr->mobj))
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
@ -1314,7 +1318,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
}
else
{
if (!R_ThingIsFullBright(spr->mobj))
if (R_ThingIsFullDark(spr->mobj))
lightlevel = 0;
else if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (sector->lightlevel>>1);
else if (!R_ThingIsFullBright(spr->mobj))
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
@ -1346,12 +1354,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
//if (tics > durs)
//durs = tics;
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
if (spr->mobj->frame & FF_TRANSMASK)
Surf.PolyFlags = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
Surf.PolyFlags = HWR_SurfaceBlend(blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else
{
Surf.PolyColor.s.alpha = (spr->mobj->flags2 & MF2_SHADOW) ? 0x40 : 0xff;
Surf.PolyFlags = HWR_GetBlendModeFlag(spr->mobj->blendmode);
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
// don't forget to enable the depth test because we can't do this

View file

@ -903,7 +903,7 @@ state_t states[NUMSTATES] =
{SPR_TRET, FF_FULLBRIGHT|2, 7, {A_Pain}, 0, 0, S_TURRETSHOCK7}, // S_TURRETSHOCK6
{SPR_TRET, FF_FULLBRIGHT|3, 7, {NULL}, 0, 0, S_TURRETSHOCK8}, // S_TURRETSHOCK7
{SPR_TRET, FF_FULLBRIGHT|4, 7, {NULL}, 0, 0, S_TURRETSHOCK9}, // S_TURRETSHOCK8
{SPR_TRET, FF_FULLBRIGHT|4, 7, {A_LinedefExecute}, LE_TURRET, 0, S_XPLD1}, // S_TURRETSHOCK9
{SPR_TRET, FF_FULLBRIGHT|4, 7, {A_LinedefExecuteFromArg}, 0, 0, S_XPLD1}, // S_TURRETSHOCK9
{SPR_TURR, 0, 1, {A_Look}, 1, 0, S_TURRETPOPDOWN8}, // S_TURRETLOOK
{SPR_TURR, 0, 0, {A_FaceTarget}, 0, 0, S_TURRETPOPUP1}, // S_TURRETSEE
@ -1456,7 +1456,7 @@ state_t states[NUMSTATES] =
{SPR_FANG, 18, 16, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT1}, // S_FANG_PINCHLOBSHOT0
{SPR_FANG, 19, 2, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT2}, // S_FANG_PINCHLOBSHOT1
{SPR_FANG, 20, 30, {A_Boss5MakeItRain}, MT_FBOMB, -16, S_FANG_PINCHLOBSHOT3}, // S_FANG_PINCHLOBSHOT2
{SPR_FANG, 20, 18, {A_LinedefExecute}, LE_BOSS4DROP, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3
{SPR_FANG, 20, 18, {A_LinedefExecuteFromArg}, 4, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3
{SPR_FANG, 0, 0, {A_Boss5Calm}, 0, 0, S_FANG_PATHINGSTART1}, // S_FANG_PINCHLOBSHOT4
{SPR_FANG, 21, 0, {A_DoNPCPain}, 0, 0, S_FANG_DIE2}, // S_FANG_DIE1
@ -1588,7 +1588,7 @@ state_t states[NUMSTATES] =
{SPR_BRAK, 21, 3*TICRATE, {NULL}, 0, 0, S_BLACKEGG_DESTROYPLAT2}, // S_BLACKEGG_DESTROYPLAT1
{SPR_BRAK, 21, 1, {A_PlaySound}, sfx_s3k54, 0, S_BLACKEGG_DESTROYPLAT3}, // S_BLACKEGG_DESTROYPLAT2
{SPR_BRAK, 21, 14, {A_LinedefExecute}, LE_BRAKPLATFORM, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3
{SPR_BRAK, 21, 14, {A_LinedefExecuteFromArg}, 5, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3
{SPR_NULL, 0, 1, {A_CapeChase}, (160 - 20) << 16, 0, S_BLACKEGG_HELPER}, // S_BLACKEGG_HELPER
@ -1622,7 +1622,7 @@ state_t states[NUMSTATES] =
{SPR_BRAK, 26 + FF_FULLBRIGHT, 2, {A_BrakFireShot}, MT_CYBRAKDEMON_FLAMESHOT, 128, S_CYBRAKDEMON_FLAME_ATTACK4}, // S_CYBRAKDEMON_FLAME_ATTACK3 // Fire
{SPR_BRAK, 7, 1, {A_Repeat}, 30, S_CYBRAKDEMON_FLAME_ATTACK3, S_CYBRAKDEMON_FINISH_ATTACK1}, // S_CYBRAKDEMON_FLAME_ATTACK4 // Loop
{SPR_BRAK, 0, 6, {A_RandomState}, S_CYBRAKDEMON_VILE_ATTACK1, S_CYBRAKDEMON_NAPALM_ATTACK1, S_CYBRAKDEMON_MISSILE_ATTACK1}, // S_CYBRAKDEMON_CHOOSE_ATTACK2
{SPR_BRAK, 20, 0, {A_LinedefExecute}, LE_BRAKVILEATACK, 0, S_CYBRAKDEMON_VILE_ATTACK2}, // S_CYBRAKDEMON_VILE_ATTACK1
{SPR_BRAK, 20, 0, {A_LinedefExecuteFromArg}, 5, 0, S_CYBRAKDEMON_VILE_ATTACK2}, // S_CYBRAKDEMON_VILE_ATTACK1
{SPR_BRAK, 20, 24, {A_VileTarget}, MT_CYBRAKDEMON_TARGET_RETICULE, 1, S_CYBRAKDEMON_VILE_ATTACK3}, // S_CYBRAKDEMON_VILE_ATTACK2
{SPR_BRAK, 19, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK4}, // S_CYBRAKDEMON_VILE_ATTACK3
{SPR_BRAK, 18, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK5}, // S_CYBRAKDEMON_VILE_ATTACK4
@ -1635,7 +1635,7 @@ state_t states[NUMSTATES] =
{SPR_BRAK, 0, 0, {A_SetReactionTime}, 0, 0, S_CYBRAKDEMON_WALK1}, // S_CYBRAKDEMON_FINISH_ATTACK2 // If just attacked, remove MF2_FRET w/out going back to spawnstate
{SPR_BRAK, 18, 24, {A_Pain}, 0, 0, S_CYBRAKDEMON_PAIN2}, // S_CYBRAKDEMON_PAIN1
{SPR_BRAK, 18, 0, {A_CheckHealth}, 3, S_CYBRAKDEMON_PAIN3, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN2
{SPR_BRAK, 18, 0, {A_LinedefExecute}, LE_PINCHPHASE, 0, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN3
{SPR_BRAK, 18, 0, {A_LinedefExecuteFromArg}, 4, 0, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN3
{SPR_BRAK, 18, 1, {A_Repeat}, 1, S_CYBRAKDEMON_DIE1, S_CYBRAKDEMON_DIE2}, // S_CYBRAKDEMON_DIE1
{SPR_BRAK, 18, 2, {A_BossScream}, 2, 0, S_CYBRAKDEMON_DIE3}, // S_CYBRAKDEMON_DIE2
{SPR_BRAK, 18, 0, {A_Repeat}, 52, S_CYBRAKDEMON_DIE2, S_CYBRAKDEMON_DIE4}, // S_CYBRAKDEMON_DIE3
@ -2992,10 +2992,10 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 15*2, {NULL}, 0, 0, S_ZAPSB2 }, // S_ZAPSB11
// Thunder spark
{SPR_SSPK, FF_ANIMATE, -1, {NULL}, 1, 2, S_NULL}, // S_THUNDERCOIN_SPARK
{SPR_SSPK, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 1, 2, S_NULL}, // S_THUNDERCOIN_SPARK
// Invincibility Sparkles
{SPR_IVSP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP
{SPR_IVSP, FF_ANIMATE|FF_FULLBRIGHT, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP
// Super Sonic Spark
{SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1
@ -3936,23 +3936,23 @@ state_t states[NUMSTATES] =
{SPR_SPRK, FF_TRANS20|FF_ANIMATE|9, 18, {NULL}, 8, 2, S_NULL}, // S_SPRK3
// Robot Explosion
{SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY
{SPR_BOM1, 0, 2, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1
{SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2
{SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3
{SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4
{SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5
{SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6
{SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY
{SPR_BOM1, 0, 2, {A_ShadowScream}, 0, 0, S_XPLD2}, // S_XPLD1
{SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2
{SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3
{SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4
{SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5
{SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6
{SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP
// Underwater Explosion
{SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1
{SPR_BOM4, 1, 3, {NULL}, 0, 0, S_WPLD3}, // S_WPLD2
{SPR_BOM4, 2, 3, {NULL}, 0, 0, S_WPLD4}, // S_WPLD3
{SPR_BOM4, 3, 3, {NULL}, 0, 0, S_WPLD5}, // S_WPLD4
{SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5
{SPR_BOM4, 5, 3, {NULL}, 0, 0, S_NULL}, // S_WPLD6
{SPR_BOM4, 0, 3, {A_ShadowScream}, 0, 0, S_WPLD2}, // S_WPLD1
{SPR_BOM4, 1, 3, {NULL}, 0, 0, S_WPLD3}, // S_WPLD2
{SPR_BOM4, 2, 3, {NULL}, 0, 0, S_WPLD4}, // S_WPLD3
{SPR_BOM4, 3, 3, {NULL}, 0, 0, S_WPLD5}, // S_WPLD4
{SPR_BOM4, 4, 3, {NULL}, 0, 0, S_WPLD6}, // S_WPLD5
{SPR_BOM4, 5, 3, {NULL}, 0, 0, S_NULL}, // S_WPLD6
{SPR_DUST, FF_TRANS40, 4, {NULL}, 0, 0, S_DUST2}, // S_DUST1
{SPR_DUST, 1|FF_TRANS50, 5, {NULL}, 0, 0, S_DUST3}, // S_DUST2
@ -18217,13 +18217,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
// ambient water 1a (large)
{ // MT_AWATERA
// ambient sound effect
{ // MT_AMBIENT
700, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
1000, // spawnhealth
S_NULL, // seestate
sfx_amwtr1, // seesound
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -18245,283 +18245,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
// ambient water 1b (large)
{ // MT_AWATERB
701, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr2, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
// ambient water 2a (medium)
{ // MT_AWATERC
702, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr3, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
// ambient water 2b (medium)
{ // MT_AWATERD
703, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr4, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
// ambient water 3a (small)
{ // MT_AWATERE
704, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr5, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
// ambient water 3b (small)
{ // MT_AWATERF
705, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr6, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
// ambient water 4a (extra large)
{ // MT_AWATERG
706, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr7, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
// ambient water 4b (extra large)
{ // MT_AWATERH
707, // doomednum
S_INVISIBLE, // spawnstate
35, // spawnhealth
S_NULL, // seestate
sfx_amwtr8, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
{ // MT_RANDOMAMBIENT
708, // doomednum
S_INVISIBLE, // spawnstate
512, // spawnhealth: repeat speed
S_NULL, // seestate
sfx_ambint, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
255, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
1000, // mass
0, // damage
sfx_None, // activesound
MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
{ // MT_RANDOMAMBIENT2
709, // doomednum
S_INVISIBLE, // spawnstate
220, // spawnhealth: repeat speed
S_NULL, // seestate
sfx_ambin2, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
255, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
1000, // mass
0, // damage
sfx_None, // activesound
MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
{ // MT_MACHINEAMBIENCE
710, // doomednum
S_INVISIBLE, // spawnstate
24, // spawnhealth: repeat speed
S_NULL, // seestate
sfx_ambmac, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
200, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
1*FRACUNIT, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
100, // mass
20, // damage
sfx_None, // activesound
MF_NOSECTOR|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_AMBIENT, // flags
S_NULL // raisestate
},
{ // MT_CORK
-1, // doomednum
S_CORK, // spawnstate
@ -20874,34 +20597,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
// for use with wind and current effects
{ // MT_PULL
755, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8, // radius
8, // height
0, // display offset
10, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_GHOST
-1, // doomednum
S_THOK, // spawnstate

View file

@ -44,6 +44,8 @@ enum actionnum
A_FACETRACER,
A_SCREAM,
A_BOSSDEATH,
A_SETSHADOWSCALE,
A_SHADOWSCREAM,
A_CUSTOMPOWER,
A_GIVEWEAPON,
A_RINGBOX,
@ -150,6 +152,7 @@ enum actionnum
A_BOSS3PATH,
A_BOSS3SHOCKTHINK,
A_LINEDEFEXECUTE,
A_LINEDEFEXECUTEFROMARG,
A_PLAYSEESOUND,
A_PLAYATTACKSOUND,
A_PLAYACTIVESOUND,
@ -312,6 +315,8 @@ void A_FaceTarget();
void A_FaceTracer();
void A_Scream();
void A_BossDeath();
void A_SetShadowScale();
void A_ShadowScream(); // MARIA!!!!!!
void A_CustomPower(); // Use this for a custom power
void A_GiveWeapon(); // Gives the player weapon(s)
void A_RingBox(); // Obtained Ring Box Tails
@ -411,6 +416,7 @@ void A_Boss3TakeDamage();
void A_Boss3Path();
void A_Boss3ShockThink();
void A_LinedefExecute();
void A_LinedefExecuteFromArg();
void A_PlaySeeSound();
void A_PlayAttackSound();
void A_PlayActiveSound();
@ -4995,17 +5001,7 @@ typedef enum mobj_type
MT_FINISHFLAG, // Finish flag
// Ambient Sounds
MT_AWATERA, // Ambient Water Sound 1
MT_AWATERB, // Ambient Water Sound 2
MT_AWATERC, // Ambient Water Sound 3
MT_AWATERD, // Ambient Water Sound 4
MT_AWATERE, // Ambient Water Sound 5
MT_AWATERF, // Ambient Water Sound 6
MT_AWATERG, // Ambient Water Sound 7
MT_AWATERH, // Ambient Water Sound 8
MT_RANDOMAMBIENT,
MT_RANDOMAMBIENT2,
MT_MACHINEAMBIENCE,
MT_AMBIENT,
MT_CORK,
MT_LHRT,
@ -5109,7 +5105,6 @@ typedef enum mobj_type
MT_CRUMBLEOBJ, // Sound generator for crumbling platform
MT_TUBEWAYPOINT,
MT_PUSH,
MT_PULL,
MT_GHOST,
MT_OVERLAY,
MT_ANGLEMAN,

View file

@ -2202,6 +2202,31 @@ static int lib_pExplodeMissile(lua_State *L)
return 0;
}
static int lib_pMobjTouchingSectorSpecial(lua_State *L)
{
mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ));
INT32 section = (INT32)luaL_checkinteger(L, 2);
INT32 number = (INT32)luaL_checkinteger(L, 3);
//HUDSAFE
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR);
return 1;
}
static int lib_pMobjTouchingSectorSpecialFlag(lua_State *L)
{
mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ));
sectorspecialflags_t flag = (INT32)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
LUA_PushUserdata(L, P_MobjTouchingSectorSpecialFlag(mo, flag), META_SECTOR);
return 1;
}
static int lib_pPlayerTouchingSectorSpecial(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2215,6 +2240,18 @@ static int lib_pPlayerTouchingSectorSpecial(lua_State *L)
return 1;
}
static int lib_pPlayerTouchingSectorSpecialFlag(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
sectorspecialflags_t flag = (INT32)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
LUA_PushUserdata(L, P_PlayerTouchingSectorSpecialFlag(player, flag), META_SECTOR);
return 1;
}
static int lib_pFindLowestFloorSurrounding(lua_State *L)
{
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@ -2346,23 +2383,13 @@ static int lib_pFadeLight(lua_State *L)
INT32 speed = (INT32)luaL_checkinteger(L, 3);
boolean ticbased = lua_optboolean(L, 4);
boolean force = lua_optboolean(L, 5);
boolean relative = lua_optboolean(L, 6);
NOHUD
INLEVEL
P_FadeLight(tag, destvalue, speed, ticbased, force);
P_FadeLight(tag, destvalue, speed, ticbased, force, relative);
return 0;
}
static int lib_pThingOnSpecial3DFloor(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
LUA_PushUserdata(L, P_ThingOnSpecial3DFloor(mo), META_SECTOR);
return 1;
}
static int lib_pIsFlagAtBase(lua_State *L)
{
mobjtype_t flag = luaL_checkinteger(L, 1);
@ -4055,7 +4082,10 @@ static luaL_Reg lib[] = {
{"P_SetMobjStateNF",lib_pSetMobjStateNF},
{"P_DoSuperTransformation",lib_pDoSuperTransformation},
{"P_ExplodeMissile",lib_pExplodeMissile},
{"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial},
{"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag},
{"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial},
{"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag},
{"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding},
{"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding},
{"P_FindNextHighestFloor",lib_pFindNextHighestFloor},
@ -4067,7 +4097,6 @@ static luaL_Reg lib[] = {
{"P_LinedefExecute",lib_pLinedefExecute},
{"P_SpawnLightningFlash",lib_pSpawnLightningFlash},
{"P_FadeLight",lib_pFadeLight},
{"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor},
{"P_IsFlagAtBase",lib_pIsFlagAtBase},
{"P_SetupLevelSky",lib_pSetupLevelSky},
{"P_SetSkyboxMobj",lib_pSetSkyboxMobj},

View file

@ -35,6 +35,10 @@ enum sector_e {
sector_floorpic,
sector_ceilingpic,
sector_lightlevel,
sector_floorlightlevel,
sector_floorlightabsolute,
sector_ceilinglightlevel,
sector_ceilinglightabsolute,
sector_special,
sector_tag,
sector_taglist,
@ -44,7 +48,14 @@ enum sector_e {
sector_lines,
sector_ffloors,
sector_fslope,
sector_cslope
sector_cslope,
sector_flags,
sector_specialflags,
sector_damagetype,
sector_triggertag,
sector_triggerer,
sector_friction,
sector_gravity,
};
static const char *const sector_opt[] = {
@ -54,6 +65,10 @@ static const char *const sector_opt[] = {
"floorpic",
"ceilingpic",
"lightlevel",
"floorlightlevel",
"floorlightabsolute",
"ceilinglightlevel",
"ceilinglightabsolute",
"special",
"tag",
"taglist",
@ -64,6 +79,13 @@ static const char *const sector_opt[] = {
"ffloors",
"f_slope",
"c_slope",
"flags",
"specialflags",
"damagetype",
"triggertag",
"triggerer",
"friction",
"gravity",
NULL};
enum subsector_e {
@ -88,6 +110,7 @@ enum line_e {
line_v2,
line_dx,
line_dy,
line_angle,
line_flags,
line_special,
line_tag,
@ -113,6 +136,7 @@ static const char *const line_opt[] = {
"v2",
"dx",
"dy",
"angle",
"flags",
"special",
"tag",
@ -190,6 +214,7 @@ enum ffloor_e {
ffloor_tslope,
ffloor_bslope,
ffloor_sector,
ffloor_fofflags,
ffloor_flags,
ffloor_master,
ffloor_target,
@ -197,6 +222,12 @@ enum ffloor_e {
ffloor_prev,
ffloor_alpha,
ffloor_blend,
ffloor_bustflags,
ffloor_busttype,
ffloor_busttag,
ffloor_sinkspeed,
ffloor_friction,
ffloor_bouncestrength,
};
static const char *const ffloor_opt[] = {
@ -209,6 +240,7 @@ static const char *const ffloor_opt[] = {
"t_slope",
"b_slope",
"sector", // secnum pushed as control sector userdata
"fofflags",
"flags",
"master", // control linedef
"target", // target sector
@ -216,6 +248,12 @@ static const char *const ffloor_opt[] = {
"prev",
"alpha",
"blend",
"bustflags",
"busttype",
"busttag",
"sinkspeed",
"friction",
"bouncestrength",
NULL};
#ifdef HAVE_LUA_SEGS
@ -581,6 +619,18 @@ static int sector_get(lua_State *L)
case sector_lightlevel:
lua_pushinteger(L, sector->lightlevel);
return 1;
case sector_floorlightlevel:
lua_pushinteger(L, sector->floorlightlevel);
return 1;
case sector_floorlightabsolute:
lua_pushboolean(L, sector->floorlightabsolute);
return 1;
case sector_ceilinglightlevel:
lua_pushinteger(L, sector->ceilinglightlevel);
return 1;
case sector_ceilinglightabsolute:
lua_pushboolean(L, sector->ceilinglightabsolute);
return 1;
case sector_special:
lua_pushinteger(L, sector->special);
return 1;
@ -619,6 +669,27 @@ static int sector_get(lua_State *L)
case sector_cslope: // c_slope
LUA_PushUserdata(L, sector->c_slope, META_SLOPE);
return 1;
case sector_flags: // flags
lua_pushinteger(L, sector->flags);
return 1;
case sector_specialflags: // specialflags
lua_pushinteger(L, sector->specialflags);
return 1;
case sector_damagetype: // damagetype
lua_pushinteger(L, (UINT8)sector->damagetype);
return 1;
case sector_triggertag: // triggertag
lua_pushinteger(L, (INT16)sector->triggertag);
return 1;
case sector_triggerer: // triggerer
lua_pushinteger(L, (UINT8)sector->triggerer);
return 1;
case sector_friction: // friction
lua_pushfixed(L, sector->friction);
return 1;
case sector_gravity: // gravity
lua_pushfixed(L, sector->gravity);
return 1;
}
return 0;
}
@ -646,6 +717,7 @@ static int sector_set(lua_State *L)
case sector_ffloors: // ffloors
case sector_fslope: // f_slope
case sector_cslope: // c_slope
case sector_friction: // friction
default:
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
case sector_floorheight: { // floorheight
@ -685,6 +757,18 @@ static int sector_set(lua_State *L)
case sector_lightlevel:
sector->lightlevel = (INT16)luaL_checkinteger(L, 3);
break;
case sector_floorlightlevel:
sector->floorlightlevel = (INT16)luaL_checkinteger(L, 3);
break;
case sector_floorlightabsolute:
sector->floorlightabsolute = luaL_checkboolean(L, 3);
break;
case sector_ceilinglightlevel:
sector->ceilinglightlevel = (INT16)luaL_checkinteger(L, 3);
break;
case sector_ceilinglightabsolute:
sector->ceilinglightabsolute = luaL_checkboolean(L, 3);
break;
case sector_special:
sector->special = (INT16)luaL_checkinteger(L, 3);
break;
@ -693,6 +777,25 @@ static int sector_set(lua_State *L)
break;
case sector_taglist:
return LUA_ErrSetDirectly(L, "sector_t", "taglist");
case sector_flags:
sector->flags = luaL_checkinteger(L, 3);
CheckForReverseGravity |= (sector->flags & MSF_GRAVITYFLIP);
break;
case sector_specialflags:
sector->specialflags = luaL_checkinteger(L, 3);
break;
case sector_damagetype:
sector->damagetype = (UINT8)luaL_checkinteger(L, 3);
break;
case sector_triggertag:
sector->triggertag = (INT16)luaL_checkinteger(L, 3);
break;
case sector_triggerer:
sector->triggerer = (UINT8)luaL_checkinteger(L, 3);
break;
case sector_gravity:
sector->gravity = luaL_checkfixed(L, 3);
break;
}
return 0;
}
@ -823,6 +926,9 @@ static int line_get(lua_State *L)
case line_dy:
lua_pushfixed(L, line->dy);
return 1;
case line_angle:
lua_pushangle(L, line->angle);
return 1;
case line_flags:
lua_pushinteger(L, line->flags);
return 1;
@ -1737,6 +1843,80 @@ static int lib_numnodes(lua_State *L)
// ffloor_t //
//////////////
static INT32 P_GetOldFOFFlags(ffloor_t *fflr)
{
INT32 result = 0;
if (fflr->fofflags & FOF_EXISTS)
result |= FF_OLD_EXISTS;
if (fflr->fofflags & FOF_BLOCKPLAYER)
result |= FF_OLD_BLOCKPLAYER;
if (fflr->fofflags & FOF_BLOCKOTHERS)
result |= FF_OLD_BLOCKOTHERS;
if (fflr->fofflags & FOF_RENDERSIDES)
result |= FF_OLD_RENDERSIDES;
if (fflr->fofflags & FOF_RENDERPLANES)
result |= FF_OLD_RENDERPLANES;
if (fflr->fofflags & FOF_SWIMMABLE)
result |= FF_OLD_SWIMMABLE;
if (fflr->fofflags & FOF_NOSHADE)
result |= FF_OLD_NOSHADE;
if (fflr->fofflags & FOF_CUTSOLIDS)
result |= FF_OLD_CUTSOLIDS;
if (fflr->fofflags & FOF_CUTEXTRA)
result |= FF_OLD_CUTEXTRA;
if (fflr->fofflags & FOF_CUTSPRITES)
result |= FF_OLD_CUTSPRITES;
if (fflr->fofflags & FOF_BOTHPLANES)
result |= FF_OLD_BOTHPLANES;
if (fflr->fofflags & FOF_EXTRA)
result |= FF_OLD_EXTRA;
if (fflr->fofflags & FOF_TRANSLUCENT)
result |= FF_OLD_TRANSLUCENT;
if (fflr->fofflags & FOF_FOG)
result |= FF_OLD_FOG;
if (fflr->fofflags & FOF_INVERTPLANES)
result |= FF_OLD_INVERTPLANES;
if (fflr->fofflags & FOF_ALLSIDES)
result |= FF_OLD_ALLSIDES;
if (fflr->fofflags & FOF_INVERTSIDES)
result |= FF_OLD_INVERTSIDES;
if (fflr->fofflags & FOF_DOUBLESHADOW)
result |= FF_OLD_DOUBLESHADOW;
if (fflr->fofflags & FOF_FLOATBOB)
result |= FF_OLD_FLOATBOB;
if (fflr->fofflags & FOF_NORETURN)
result |= FF_OLD_NORETURN;
if (fflr->fofflags & FOF_CRUMBLE)
result |= FF_OLD_CRUMBLE;
if (fflr->bustflags & FB_ONLYBOTTOM)
result |= FF_OLD_SHATTERBOTTOM;
if (fflr->fofflags & FOF_GOOWATER)
result |= FF_OLD_GOOWATER;
if (fflr->fofflags & FOF_MARIO)
result |= FF_OLD_MARIO;
if (fflr->fofflags & FOF_BUSTUP)
result |= FF_OLD_BUSTUP;
if (fflr->fofflags & FOF_QUICKSAND)
result |= FF_OLD_QUICKSAND;
if (fflr->fofflags & FOF_PLATFORM)
result |= FF_OLD_PLATFORM;
if (fflr->fofflags & FOF_REVERSEPLATFORM)
result |= FF_OLD_REVERSEPLATFORM;
if (fflr->fofflags & FOF_INTANGIBLEFLATS)
result |= FF_OLD_INTANGIBLEFLATS;
if (fflr->busttype == BT_TOUCH)
result |= FF_OLD_SHATTER;
if (fflr->busttype == BT_SPINBUST)
result |= FF_OLD_SPINBUST;
if (fflr->busttype == BT_STRONG)
result |= FF_OLD_STRONGBUST;
if (fflr->fofflags & FF_OLD_RIPPLE)
result |= FOF_RIPPLE;
if (fflr->fofflags & FF_OLD_COLORMAPONLY)
result |= FOF_COLORMAPONLY;
return result;
}
static int ffloor_get(lua_State *L)
{
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
@ -1791,8 +1971,11 @@ static int ffloor_get(lua_State *L)
case ffloor_sector:
LUA_PushUserdata(L, &sectors[ffloor->secnum], META_SECTOR);
return 1;
case ffloor_fofflags:
lua_pushinteger(L, ffloor->fofflags);
return 1;
case ffloor_flags:
lua_pushinteger(L, ffloor->flags);
lua_pushinteger(L, P_GetOldFOFFlags(ffloor));
return 1;
case ffloor_master:
LUA_PushUserdata(L, ffloor->master, META_LINE);
@ -1812,10 +1995,110 @@ static int ffloor_get(lua_State *L)
case ffloor_blend:
lua_pushinteger(L, ffloor->blend);
return 1;
case ffloor_bustflags:
lua_pushinteger(L, ffloor->bustflags);
return 1;
case ffloor_busttype:
lua_pushinteger(L, ffloor->busttype);
return 1;
case ffloor_busttag:
lua_pushinteger(L, ffloor->busttag);
return 1;
case ffloor_sinkspeed:
lua_pushfixed(L, ffloor->sinkspeed);
return 1;
case ffloor_friction:
lua_pushfixed(L, ffloor->friction);
return 1;
case ffloor_bouncestrength:
lua_pushfixed(L, ffloor->bouncestrength);
return 1;
}
return 0;
}
static void P_SetOldFOFFlags(ffloor_t *fflr, oldffloortype_e oldflags)
{
ffloortype_e originalflags = fflr->fofflags;
fflr->fofflags = 0;
if (oldflags & FF_OLD_EXISTS)
fflr->fofflags |= FOF_EXISTS;
if (oldflags & FF_OLD_BLOCKPLAYER)
fflr->fofflags |= FOF_BLOCKPLAYER;
if (oldflags & FF_OLD_BLOCKOTHERS)
fflr->fofflags |= FOF_BLOCKOTHERS;
if (oldflags & FF_OLD_RENDERSIDES)
fflr->fofflags |= FOF_RENDERSIDES;
if (oldflags & FF_OLD_RENDERPLANES)
fflr->fofflags |= FOF_RENDERPLANES;
if (oldflags & FF_OLD_SWIMMABLE)
fflr->fofflags |= FOF_SWIMMABLE;
if (oldflags & FF_OLD_NOSHADE)
fflr->fofflags |= FOF_NOSHADE;
if (oldflags & FF_OLD_CUTSOLIDS)
fflr->fofflags |= FOF_CUTSOLIDS;
if (oldflags & FF_OLD_CUTEXTRA)
fflr->fofflags |= FOF_CUTEXTRA;
if (oldflags & FF_OLD_CUTSPRITES)
fflr->fofflags |= FOF_CUTSPRITES;
if (oldflags & FF_OLD_BOTHPLANES)
fflr->fofflags |= FOF_BOTHPLANES;
if (oldflags & FF_OLD_EXTRA)
fflr->fofflags |= FOF_EXTRA;
if (oldflags & FF_OLD_TRANSLUCENT)
fflr->fofflags |= FOF_TRANSLUCENT;
if (oldflags & FF_OLD_FOG)
fflr->fofflags |= FOF_FOG;
if (oldflags & FF_OLD_INVERTPLANES)
fflr->fofflags |= FOF_INVERTPLANES;
if (oldflags & FF_OLD_ALLSIDES)
fflr->fofflags |= FOF_ALLSIDES;
if (oldflags & FF_OLD_INVERTSIDES)
fflr->fofflags |= FOF_INVERTSIDES;
if (oldflags & FF_OLD_DOUBLESHADOW)
fflr->fofflags |= FOF_DOUBLESHADOW;
if (oldflags & FF_OLD_FLOATBOB)
fflr->fofflags |= FOF_FLOATBOB;
if (oldflags & FF_OLD_NORETURN)
fflr->fofflags |= FOF_NORETURN;
if (oldflags & FF_OLD_CRUMBLE)
fflr->fofflags |= FOF_CRUMBLE;
if (oldflags & FF_OLD_GOOWATER)
fflr->fofflags |= FOF_GOOWATER;
if (oldflags & FF_OLD_MARIO)
fflr->fofflags |= FOF_MARIO;
if (oldflags & FF_OLD_BUSTUP)
fflr->fofflags |= FOF_BUSTUP;
if (oldflags & FF_OLD_QUICKSAND)
fflr->fofflags |= FOF_QUICKSAND;
if (oldflags & FF_OLD_PLATFORM)
fflr->fofflags |= FOF_PLATFORM;
if (oldflags & FF_OLD_REVERSEPLATFORM)
fflr->fofflags |= FOF_REVERSEPLATFORM;
if (oldflags & FF_OLD_RIPPLE)
fflr->fofflags |= FOF_RIPPLE;
if (oldflags & FF_OLD_COLORMAPONLY)
fflr->fofflags |= FOF_COLORMAPONLY;
if (originalflags & FOF_BOUNCY)
fflr->fofflags |= FOF_BOUNCY;
if (originalflags & FOF_SPLAT)
fflr->fofflags |= FOF_SPLAT;
if (oldflags & FF_OLD_SHATTER)
fflr->busttype = BT_TOUCH;
else if (oldflags & FF_OLD_SPINBUST)
fflr->busttype = BT_SPINBUST;
else if (oldflags & FF_OLD_STRONGBUST)
fflr->busttype = BT_STRONG;
else
fflr->busttype = BT_REGULAR;
if (oldflags & FF_OLD_SHATTERBOTTOM)
fflr->bustflags |= FB_ONLYBOTTOM;
else
fflr->bustflags &= ~FB_ONLYBOTTOM;
}
static int ffloor_set(lua_State *L)
{
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
@ -1880,10 +2163,20 @@ static int ffloor_set(lua_State *L)
case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
break;
case ffloor_fofflags: {
ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags
ffloor->fofflags = luaL_checkinteger(L, 3);
if (ffloor->fofflags != oldflags)
ffloor->target->moved = true; // reset target sector's lightlist
break;
}
case ffloor_flags: {
ffloortype_e oldflags = ffloor->flags; // store FOF's old flags
ffloor->flags = luaL_checkinteger(L, 3);
if (ffloor->flags != oldflags)
ffloortype_e oldflags = ffloor->fofflags; // store FOF's old flags
busttype_e oldbusttype = ffloor->busttype;
ffloorbustflags_e oldbustflags = ffloor->bustflags;
oldffloortype_e newflags = luaL_checkinteger(L, 3);
P_SetOldFOFFlags(ffloor, newflags);
if (ffloor->fofflags != oldflags || ffloor->busttype != oldbusttype || ffloor->bustflags != oldbustflags)
ffloor->target->moved = true; // reset target sector's lightlist
break;
}

View file

@ -244,13 +244,14 @@ static int lib_polyobj_rotate(lua_State *L)
{
polyobj_t *po = *((polyobj_t **)luaL_checkudata(L, 1, META_POLYOBJ));
angle_t delta = luaL_checkangle(L, 2);
UINT8 turnthings = (UINT8)luaL_optinteger(L, 3, 0); // don't turn anything by default? (could change this if not desired)
boolean checkmobjs = lua_opttrueboolean(L, 4);
boolean turnplayers = lua_opttrueboolean(L, 3);
boolean turnothers = lua_opttrueboolean(L, 4);
boolean checkmobjs = lua_opttrueboolean(L, 5);
NOHUD
INLEVEL
if (!po)
return LUA_ErrInvalid(L, "polyobj_t");
lua_pushboolean(L, Polyobj_rotate(po, delta, turnthings, checkmobjs));
lua_pushboolean(L, Polyobj_rotate(po, delta, turnplayers, turnothers, checkmobjs));
return 1;
}

View file

@ -387,6 +387,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 1;
} else if (fastcmp(word, "stagefailed")) {
lua_pushboolean(L, stagefailed);
return 1;
} else if (fastcmp(word, "mouse")) {
LUA_PushUserdata(L, &mouse, META_MOUSE);
return 1;

View file

@ -539,7 +539,7 @@ void Command_Teleport_f(void)
// Flagging a player's ambush will make them start on the ceiling
// Objectflip inverts
if (!!(mt->options & MTF_AMBUSH) ^ !!(mt->options & MTF_OBJECTFLIP))
if (!!(mt->args[0]) ^ !!(mt->options & MTF_OBJECTFLIP))
intz = ss->sector->ceilingheight - p->mo->height - offset;
else
intz = ss->sector->floorheight + offset;
@ -1004,7 +1004,7 @@ static void OP_CycleThings(INT32 amt)
} while
(mobjinfo[op_currentthing].doomednum == -1
|| op_currentthing == MT_NIGHTSDRONE
|| mobjinfo[op_currentthing].flags & (MF_AMBIENT|MF_NOSECTOR)
|| mobjinfo[op_currentthing].flags & MF_NOSECTOR
|| (states[mobjinfo[op_currentthing].spawnstate].sprite == SPR_NULL
&& states[mobjinfo[op_currentthing].seestate].sprite == SPR_NULL)
);
@ -1137,7 +1137,7 @@ void OP_ResetObjectplace(void)
//
// Main meat of objectplace: handling functions
//
void OP_NightsObjectplace(player_t *player)
/*void OP_NightsObjectplace(player_t *player)
{
ticcmd_t *cmd = &player->cmd;
mapthing_t *mt;
@ -1283,14 +1283,14 @@ void OP_NightsObjectplace(player_t *player)
mt = OP_CreateNewMapThing(player, (UINT16)cv_mapthingnum.value, false);
mt->angle = angle;
if (mt->type >= 600 && mt->type <= 609) // Placement patterns
if (mt->type >= 600 && mt->type <= 611) // Placement patterns
P_SpawnItemPattern(mt, false);
else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops
else if (mt->type == 1713) // NiGHTS Hoops
P_SpawnHoop(mt);
else
P_SpawnMapThing(mt);
}
}
}*/
//
// OP_ObjectplaceMovement
@ -1414,9 +1414,9 @@ void OP_ObjectplaceMovement(player_t *player)
return;
mt = OP_CreateNewMapThing(player, (UINT16)spawnthing, ceiling);
if (mt->type >= 600 && mt->type <= 609) // Placement patterns
if (mt->type >= 600 && mt->type <= 611) // Placement patterns
P_SpawnItemPattern(mt, false);
else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops
else if (mt->type == 1713) // NiGHTS Hoops
P_SpawnHoop(mt);
else
P_SpawnMapThing(mt);
@ -1428,14 +1428,14 @@ void OP_ObjectplaceMovement(player_t *player)
//
// Objectplace related commands.
//
void Command_Writethings_f(void)
/*void Command_Writethings_f(void)
{
REQUIRE_INLEVEL;
REQUIRE_SINGLEPLAYER;
REQUIRE_OBJECTPLACE;
P_WriteThings();
}
}*/
void Command_ObjectPlace_f(void)
{

View file

@ -26,7 +26,7 @@ void cht_Init(void);
// ObjectPlace
//
void Command_ObjectPlace_f(void);
void Command_Writethings_f(void);
//void Command_Writethings_f(void);
extern consvar_t cv_opflags, cv_ophoopflags, cv_mapthingnum, cv_speed;
//extern consvar_t cv_snapto, cv_grid;
@ -38,7 +38,7 @@ extern UINT32 op_displayflags;
boolean OP_FreezeObjectplace(void);
void OP_ResetObjectplace(void);
void OP_NightsObjectplace(player_t *player);
//void OP_NightsObjectplace(player_t *player);
void OP_ObjectplaceMovement(player_t *player);
//

View file

@ -4746,7 +4746,7 @@ static void M_DrawPauseMenu(void)
emblemslot = 2;
break;
case ET_NGRADE:
snprintf(targettext, 9, "%u", P_GetScoreForGrade(gamemap, 0, emblem->var));
snprintf(targettext, 9, "%u", P_GetScoreForGradeOverall(gamemap, emblem->var));
snprintf(currenttext, 9, "%u", G_GetBestNightsScore(gamemap, 0));
targettext[8] = 0;
@ -5403,11 +5403,13 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
if (actnum)
sprintf(mapname, "%s %d", mapheaderinfo[headingIterate]->lvlttl, actnum);
else if (V_ThinStringWidth(mapheaderinfo[headingIterate]->lvlttl, 0) <= 80)
strlcpy(mapname, mapheaderinfo[headingIterate]->lvlttl, 22);
else
strcpy(mapname, mapheaderinfo[headingIterate]->lvlttl);
if (strlen(mapname) >= 17)
strcpy(mapname+17-3, "...");
{
strlcpy(mapname, mapheaderinfo[headingIterate]->lvlttl, 15);
strcat(mapname, "...");
}
strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname);
}
@ -5742,7 +5744,7 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea
? 159 : 63));
if (strlen(levelselect.rows[row].mapnames[col]) > 6) // "AERIAL GARDEN" vs "ACT 18" - "THE ACT" intentionally compressed
V_DrawThinString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
V_DrawThinString(x, y+50+1, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
else
V_DrawString(x, y+50, (highlight ? V_YELLOWMAP : 0), levelselect.rows[row].mapnames[col]);
}
@ -8743,12 +8745,12 @@ static void M_ReadSavegameInfo(UINT32 slot)
if(!mapheaderinfo[(fake-1) & 8191])
savegameinfo[slot].levelname[0] = '\0';
else if (V_ThinStringWidth(mapheaderinfo[(fake-1) & 8191]->lvlttl, 0) <= 78)
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 22);
else
{
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 17+1);
if (strlen(mapheaderinfo[(fake-1) & 8191]->lvlttl) >= 17)
strcpy(savegameinfo[slot].levelname+17-3, "...");
strlcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl, 15);
strcat(savegameinfo[slot].levelname, "...");
}
savegameinfo[slot].gamemap = fake;

View file

@ -389,9 +389,9 @@ typedef struct
// level select platter
typedef struct
{
char header[22+5]; // mapheader_t lvltttl max length + " ZONE"
char header[22+5]; // mapheader_t lvlttl max length + " ZONE"
INT32 maplist[3];
char mapnames[3][17+1];
char mapnames[3][22]; // lvlttl max length
boolean mapavailable[4]; // mapavailable[3] == wide or not
} levelselectrow_t;

View file

@ -566,10 +566,13 @@ void M_FirstLoadConfig(void)
gameconfig_loaded = true;
// reset to default player stuff
COM_BufAddText (va("%s \"%s\"\n",cv_skin.name,cv_defaultskin.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor.name,cv_defaultplayercolor.string));
COM_BufAddText (va("%s \"%s\"\n",cv_skin2.name,cv_defaultskin2.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor2.name,cv_defaultplayercolor2.string));
if (!dedicated)
{
COM_BufAddText (va("%s \"%s\"\n",cv_skin.name,cv_defaultskin.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor.name,cv_defaultplayercolor.string));
COM_BufAddText (va("%s \"%s\"\n",cv_skin2.name,cv_defaultskin2.string));
COM_BufAddText (va("%s \"%s\"\n",cv_playercolor2.name,cv_defaultplayercolor2.string));
}
}
/** Saves the game configuration.
@ -1970,18 +1973,168 @@ void M_UnGetToken(void)
endPos = oldendPos;
}
/** Returns the current token's position.
*/
UINT32 M_GetTokenPos(void)
#define NUMTOKENS 2
static const char *tokenizerInput = NULL;
static UINT32 tokenCapacity[NUMTOKENS] = {0};
static char *tokenizerToken[NUMTOKENS] = {NULL};
static UINT32 tokenizerStartPos = 0;
static UINT32 tokenizerEndPos = 0;
static UINT32 tokenizerInputLength = 0;
static UINT8 tokenizerInComment = 0; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */
void M_TokenizerOpen(const char *inputString)
{
return endPos;
size_t i;
tokenizerInput = inputString;
for (i = 0; i < NUMTOKENS; i++)
{
tokenCapacity[i] = 1024;
tokenizerToken[i] = (char*)Z_Malloc(tokenCapacity[i] * sizeof(char), PU_STATIC, NULL);
}
tokenizerInputLength = strlen(tokenizerInput);
}
/** Sets the current token's position.
*/
void M_SetTokenPos(UINT32 newPos)
void M_TokenizerClose(void)
{
endPos = newPos;
size_t i;
tokenizerInput = NULL;
for (i = 0; i < NUMTOKENS; i++)
Z_Free(tokenizerToken[i]);
tokenizerStartPos = 0;
tokenizerEndPos = 0;
tokenizerInComment = 0;
}
static void M_DetectComment(UINT32 *pos)
{
if (tokenizerInComment)
return;
if (*pos >= tokenizerInputLength - 1)
return;
if (tokenizerInput[*pos] != '/')
return;
//Single-line comment start
if (tokenizerInput[*pos + 1] == '/')
tokenizerInComment = 1;
//Multi-line comment start
else if (tokenizerInput[*pos + 1] == '*')
tokenizerInComment = 2;
}
static void M_ReadTokenString(UINT32 i)
{
UINT32 tokenLength = tokenizerEndPos - tokenizerStartPos;
if (tokenLength + 1 > tokenCapacity[i])
{
tokenCapacity[i] = tokenLength + 1;
// Assign the memory. Don't forget an extra byte for the end of the string!
tokenizerToken[i] = (char *)Z_Malloc(tokenCapacity[i] * sizeof(char), PU_STATIC, NULL);
}
// Copy the string.
M_Memcpy(tokenizerToken[i], tokenizerInput + tokenizerStartPos, (size_t)tokenLength);
// Make the final character NUL.
tokenizerToken[i][tokenLength] = '\0';
}
const char *M_TokenizerRead(UINT32 i)
{
if (!tokenizerInput)
return NULL;
tokenizerStartPos = tokenizerEndPos;
// Try to detect comments now, in case we're pointing right at one
M_DetectComment(&tokenizerStartPos);
// Find the first non-whitespace char, or else the end of the string trying
while ((tokenizerInput[tokenizerStartPos] == ' '
|| tokenizerInput[tokenizerStartPos] == '\t'
|| tokenizerInput[tokenizerStartPos] == '\r'
|| tokenizerInput[tokenizerStartPos] == '\n'
|| tokenizerInput[tokenizerStartPos] == '\0'
|| tokenizerInput[tokenizerStartPos] == '=' || tokenizerInput[tokenizerStartPos] == ';' // UDMF TEXTMAP.
|| tokenizerInComment != 0)
&& tokenizerStartPos < tokenizerInputLength)
{
// Try to detect comment endings now
if (tokenizerInComment == 1 && tokenizerInput[tokenizerStartPos] == '\n')
tokenizerInComment = 0; // End of line for a single-line comment
else if (tokenizerInComment == 2
&& tokenizerStartPos < tokenizerInputLength - 1
&& tokenizerInput[tokenizerStartPos] == '*'
&& tokenizerInput[tokenizerStartPos+1] == '/')
{
// End of multi-line comment
tokenizerInComment = 0;
tokenizerStartPos++; // Make damn well sure we're out of the comment ending at the end of it all
}
tokenizerStartPos++;
M_DetectComment(&tokenizerStartPos);
}
// If the end of the string is reached, no token is to be read
if (tokenizerStartPos == tokenizerInputLength) {
tokenizerEndPos = tokenizerInputLength;
return NULL;
}
// Else, if it's one of these three symbols, capture only this one character
else if (tokenizerInput[tokenizerStartPos] == ','
|| tokenizerInput[tokenizerStartPos] == '{'
|| tokenizerInput[tokenizerStartPos] == '}')
{
tokenizerEndPos = tokenizerStartPos + 1;
tokenizerToken[i][0] = tokenizerInput[tokenizerStartPos];
tokenizerToken[i][1] = '\0';
return tokenizerToken[i];
}
// Return entire string within quotes, except without the quotes.
else if (tokenizerInput[tokenizerStartPos] == '"')
{
tokenizerEndPos = ++tokenizerStartPos;
while (tokenizerInput[tokenizerEndPos] != '"' && tokenizerEndPos < tokenizerInputLength)
tokenizerEndPos++;
M_ReadTokenString(i);
tokenizerEndPos++;
return tokenizerToken[i];
}
// Now find the end of the token. This includes several additional characters that are okay to capture as one character, but not trailing at the end of another token.
tokenizerEndPos = tokenizerStartPos + 1;
while ((tokenizerInput[tokenizerEndPos] != ' '
&& tokenizerInput[tokenizerEndPos] != '\t'
&& tokenizerInput[tokenizerEndPos] != '\r'
&& tokenizerInput[tokenizerEndPos] != '\n'
&& tokenizerInput[tokenizerEndPos] != ','
&& tokenizerInput[tokenizerEndPos] != '{'
&& tokenizerInput[tokenizerEndPos] != '}'
&& tokenizerInput[tokenizerEndPos] != '=' && tokenizerInput[tokenizerEndPos] != ';' // UDMF TEXTMAP.
&& tokenizerInComment == 0)
&& tokenizerEndPos < tokenizerInputLength)
{
tokenizerEndPos++;
// Try to detect comment starts now; if it's in a comment, we don't want it in this token
M_DetectComment(&tokenizerEndPos);
}
M_ReadTokenString(i);
return tokenizerToken[i];
}
UINT32 M_TokenizerGetEndPos(void)
{
return tokenizerEndPos;
}
void M_TokenizerSetEndPos(UINT32 newPos)
{
tokenizerEndPos = newPos;
}
/** Count bits in a number.

View file

@ -34,7 +34,6 @@ INT32 ceilmovesound = sfx_None;
void T_MoveCeiling(ceiling_t *ceiling)
{
result_e res;
boolean dontupdate = false;
if (ceiling->delaytimer)
{
@ -42,259 +41,81 @@ void T_MoveCeiling(ceiling_t *ceiling)
return;
}
switch (ceiling->direction)
res = T_MovePlane(ceiling->sector, ceiling->speed, (ceiling->direction == 1) ? ceiling->topheight : ceiling->bottomheight, false, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
case 0: // IN STASIS
break;
case 1: // UP
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
const fixed_t origspeed = FixedDiv(ceiling->origspeed,(ELEVATORSPEED/2));
const fixed_t fs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].frontsector->ceilingheight);
const fixed_t bs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].backsector->ceilingheight);
if (fs < bs)
ceiling->speed = FixedDiv(fs,25*FRACUNIT) + FRACUNIT/4;
else
ceiling->speed = FixedDiv(bs,25*FRACUNIT) + FRACUNIT/4;
ceiling->speed = FixedMul(ceiling->speed,origspeed);
}
if (res == pastdest)
{
switch (ceiling->type)
{
case instantMoveCeilingByFrontSector:
if (ceiling->texture > -1)
ceiling->sector->ceilingpic = ceiling->texture;
ceiling->sector->ceilingdata = NULL;
ceiling->sector->ceilspeed = 0;
P_RemoveThinker(&ceiling->thinker);
dontupdate = true;
break;
case moveCeilingByFrontSector:
if (ceiling->texture < -1) // chained linedef executing
P_LinedefExecute((INT16)(ceiling->texture + INT16_MAX + 2), NULL, NULL);
if (ceiling->texture > -1) // flat changing
ceiling->sector->ceilingpic = ceiling->texture;
/* FALLTHRU */
case raiseToHighest:
// case raiseCeilingByLine:
case moveCeilingByFrontTexture:
ceiling->sector->ceilingdata = NULL;
ceiling->sector->ceilspeed = 0;
P_RemoveThinker(&ceiling->thinker);
dontupdate = true;
break;
case fastCrushAndRaise:
case crushAndRaise:
ceiling->direction = -1;
break;
case bounceCeiling:
{
fixed_t dest = ceiling->topheight;
if (dest == lines[ceiling->texture].frontsector->ceilingheight)
dest = lines[ceiling->texture].backsector->ceilingheight;
else
dest = lines[ceiling->texture].frontsector->ceilingheight;
if (dest < ceiling->sector->ceilingheight) // must move down
{
ceiling->direction = -1;
ceiling->bottomheight = dest;
}
else // must move up
{
ceiling->direction = 1;
ceiling->topheight = dest;
}
ceiling->delaytimer = ceiling->delay;
// That's it. Do not set dontupdate, do not remove the thinker.
break;
}
case bounceCeilingCrush:
{
fixed_t dest = ceiling->topheight;
if (dest == lines[ceiling->texture].frontsector->ceilingheight)
{
dest = lines[ceiling->texture].backsector->ceilingheight;
ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dy),4*FRACUNIT); // return trip, use dy
}
else
{
dest = lines[ceiling->texture].frontsector->ceilingheight;
ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dx),4*FRACUNIT); // going frontways, use dx
}
if (dest < ceiling->sector->ceilingheight) // must move down
{
ceiling->direction = -1;
ceiling->bottomheight = dest;
}
else // must move up
{
ceiling->direction = 1;
ceiling->topheight = dest;
}
ceiling->delaytimer = ceiling->delay;
// That's it. Do not set dontupdate, do not remove the thinker.
break;
}
default:
break;
}
}
break;
case -1: // DOWN
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
const fixed_t origspeed = FixedDiv(ceiling->origspeed,(ELEVATORSPEED/2));
const fixed_t fs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].frontsector->ceilingheight);
const fixed_t bs = abs(ceiling->sector->ceilingheight - lines[ceiling->texture].backsector->ceilingheight);
if (fs < bs)
ceiling->speed = FixedDiv(fs,25*FRACUNIT) + FRACUNIT/4;
else
ceiling->speed = FixedDiv(bs,25*FRACUNIT) + FRACUNIT/4;
ceiling->speed = FixedMul(ceiling->speed,origspeed);
}
if (res == pastdest)
{
switch (ceiling->type)
{
// make platform stop at bottom of all crusher strokes
// except generalized ones, reset speed, start back up
case crushAndRaise:
ceiling->speed = CEILSPEED;
/* FALLTHRU */
case fastCrushAndRaise:
ceiling->direction = 1;
break;
case instantMoveCeilingByFrontSector:
if (ceiling->texture > -1)
ceiling->sector->ceilingpic = ceiling->texture;
ceiling->sector->ceilingdata = NULL;
ceiling->sector->ceilspeed = 0;
P_RemoveThinker(&ceiling->thinker);
dontupdate = true;
break;
case moveCeilingByFrontSector:
if (ceiling->texture < -1) // chained linedef executing
P_LinedefExecute((INT16)(ceiling->texture + INT16_MAX + 2), NULL, NULL);
if (ceiling->texture > -1) // flat changing
ceiling->sector->ceilingpic = ceiling->texture;
// don't break
/* FALLTHRU */
// in all other cases, just remove the active ceiling
case lowerAndCrush:
case lowerToLowest:
case raiseToLowest:
// case lowerCeilingByLine:
case moveCeilingByFrontTexture:
ceiling->sector->ceilingdata = NULL;
ceiling->sector->ceilspeed = 0;
P_RemoveThinker(&ceiling->thinker);
dontupdate = true;
break;
case bounceCeiling:
{
fixed_t dest = ceiling->bottomheight;
if (dest == lines[ceiling->texture].frontsector->ceilingheight)
dest = lines[ceiling->texture].backsector->ceilingheight;
else
dest = lines[ceiling->texture].frontsector->ceilingheight;
if (dest < ceiling->sector->ceilingheight) // must move down
{
ceiling->direction = -1;
ceiling->bottomheight = dest;
}
else // must move up
{
ceiling->direction = 1;
ceiling->topheight = dest;
}
ceiling->delaytimer = ceiling->delay;
// That's it. Do not set dontupdate, do not remove the thinker.
break;
}
case bounceCeilingCrush:
{
fixed_t dest = ceiling->bottomheight;
if (dest == lines[ceiling->texture].frontsector->ceilingheight)
{
dest = lines[ceiling->texture].backsector->ceilingheight;
ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dy),4*FRACUNIT); // return trip, use dy
}
else
{
dest = lines[ceiling->texture].frontsector->ceilingheight;
ceiling->speed = ceiling->origspeed = FixedDiv(abs(lines[ceiling->texture].dx),4*FRACUNIT); // going frontways, use dx
}
if (dest < ceiling->sector->ceilingheight) // must move down
{
ceiling->direction = -1;
ceiling->bottomheight = dest;
}
else // must move up
{
ceiling->direction = 1;
ceiling->topheight = dest;
}
ceiling->delaytimer = ceiling->delay;
// That's it. Do not set dontupdate, do not remove the thinker.
break;
}
default:
break;
}
}
else if (res == crushed)
{
switch (ceiling->type)
{
case crushAndRaise:
case lowerAndCrush:
ceiling->speed = FixedDiv(CEILSPEED,8*FRACUNIT);
break;
default:
break;
}
}
break;
const fixed_t origspeed = FixedDiv(ceiling->origspeed, (ELEVATORSPEED/2));
const fixed_t fs = abs(ceiling->sector->ceilingheight - lines[ceiling->sourceline].frontsector->ceilingheight);
const fixed_t bs = abs(ceiling->sector->ceilingheight - lines[ceiling->sourceline].backsector->ceilingheight);
if (fs < bs)
ceiling->speed = FixedDiv(fs, 25*FRACUNIT) + FRACUNIT/4;
else
ceiling->speed = FixedDiv(bs, 25*FRACUNIT) + FRACUNIT/4;
ceiling->speed = FixedMul(ceiling->speed, origspeed);
}
if (!dontupdate)
ceiling->sector->ceilspeed = ceiling->speed*ceiling->direction;
else
ceiling->sector->ceilspeed = 0;
if (res == pastdest)
{
switch (ceiling->type)
{
case instantMoveCeilingByFrontSector:
if (ceiling->texture > -1) // flat changing
ceiling->sector->ceilingpic = ceiling->texture;
ceiling->sector->ceilingdata = NULL;
ceiling->sector->ceilspeed = 0;
P_RemoveThinker(&ceiling->thinker);
return;
case moveCeilingByFrontSector:
if (ceiling->tag) // chained linedef executing
P_LinedefExecute(ceiling->tag, NULL, NULL);
if (ceiling->texture > -1) // flat changing
ceiling->sector->ceilingpic = ceiling->texture;
/* FALLTHRU */
case raiseToHighest:
case moveCeilingByDistance:
ceiling->sector->ceilingdata = NULL;
ceiling->sector->ceilspeed = 0;
P_RemoveThinker(&ceiling->thinker);
return;
case bounceCeiling:
case bounceCeilingCrush:
{
fixed_t dest = (ceiling->direction == 1) ? ceiling->topheight : ceiling->bottomheight;
if (dest == lines[ceiling->sourceline].frontsector->ceilingheight)
{
dest = lines[ceiling->sourceline].backsector->ceilingheight;
ceiling->origspeed = lines[ceiling->sourceline].args[3] << (FRACBITS - 2); // return trip, use args[3]
}
else
{
dest = lines[ceiling->sourceline].frontsector->ceilingheight;
ceiling->origspeed = lines[ceiling->sourceline].args[2] << (FRACBITS - 2); // going frontways, use args[2]
}
if (ceiling->type == bounceCeilingCrush)
ceiling->speed = ceiling->origspeed;
if (dest < ceiling->sector->ceilingheight) // must move down
{
ceiling->direction = -1;
ceiling->bottomheight = dest;
}
else // must move up
{
ceiling->direction = 1;
ceiling->topheight = dest;
}
ceiling->delaytimer = ceiling->delay;
break;
}
default:
break;
}
}
ceiling->sector->ceilspeed = ceiling->speed*ceiling->direction;
}
/** Moves a ceiling crusher.
@ -322,11 +143,7 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (res == pastdest)
{
ceiling->direction = -1;
if (lines[ceiling->sourceline].flags & ML_EFFECT4)
ceiling->speed = ceiling->oldspeed;
else
ceiling->speed = ceiling->oldspeed*2;
ceiling->speed = lines[ceiling->sourceline].args[2] << (FRACBITS - 2);
if (ceiling->type == crushCeilOnce
|| ceiling->type == crushBothOnce)
@ -367,12 +184,8 @@ void T_CrushCeiling(ceiling_t *ceiling)
ceiling->sector->soundorg.z = ceiling->sector->floorheight;
S_StartSound(mp,sfx_pstop);
if (lines[ceiling->sourceline].flags & ML_EFFECT4)
ceiling->speed = ceiling->oldspeed;
else
ceiling->speed = ceiling->oldspeed/2;
ceiling->direction = 1;
ceiling->speed = lines[ceiling->sourceline].args[3] << (FRACBITS - 2);
}
break;
}
@ -385,18 +198,18 @@ void T_CrushCeiling(ceiling_t *ceiling)
/** Starts a ceiling mover.
*
* \param tag Tag.
* \param line The source line.
* \param type The type of ceiling movement.
* \return 1 if at least one ceiling mover was started, 0 otherwise.
* \sa EV_DoCrush, EV_DoFloor, EV_DoElevator, T_MoveCeiling
*/
INT32 EV_DoCeiling(line_t *line, ceiling_e type)
INT32 EV_DoCeiling(mtag_t tag, line_t *line, ceiling_e type)
{
INT32 rtn = 0, firstone = 1;
INT32 secnum = -1;
sector_t *sec;
ceiling_t *ceiling;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_SECTORS(tag, secnum)
{
@ -417,44 +230,12 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
switch (type)
{
case fastCrushAndRaise:
ceiling->crush = true;
ceiling->topheight = sec->ceilingheight;
ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
ceiling->direction = -1;
ceiling->speed = CEILSPEED * 2;
break;
case crushAndRaise:
ceiling->crush = true;
ceiling->topheight = sec->ceilingheight;
/* FALLTHRU */
case lowerAndCrush:
ceiling->bottomheight = sec->floorheight;
ceiling->bottomheight += 4*FRACUNIT;
ceiling->direction = -1;
ceiling->speed = line->dx;
break;
case raiseToHighest:
ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
ceiling->direction = 1;
ceiling->speed = CEILSPEED;
break;
//SoM: 3/6/2000: Added Boom types
case lowerToLowest:
ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
ceiling->direction = -1;
ceiling->speed = CEILSPEED;
break;
case raiseToLowest: // Graue 09-07-2004
ceiling->topheight = P_FindLowestCeilingSurrounding(sec) - 4*FRACUNIT;
ceiling->direction = 1;
ceiling->speed = line->dx; // hack
break;
case lowerToLowestFast:
ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
ceiling->direction = -1;
@ -469,8 +250,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
// Linedef executor excellence
case moveCeilingByFrontSector:
ceiling->speed = P_AproxDistance(line->dx, line->dy);
ceiling->speed = FixedDiv(ceiling->speed,8*FRACUNIT);
ceiling->speed = line->args[2] << (FRACBITS - 3);
if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up
{
ceiling->direction = 1;
@ -483,21 +263,13 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
}
// chained linedef executing ability
if (line->flags & ML_BLOCKMONSTERS)
{
// only set it on ONE of the moving sectors (the smallest numbered)
// and front side x offset must be positive
if (firstone && sides[line->sidenum[0]].textureoffset > 0)
ceiling->texture = (sides[line->sidenum[0]].textureoffset>>FRACBITS) - 32769;
else
ceiling->texture = -1;
}
// only set it on ONE of the moving sectors (the smallest numbered)
// only set it if there isn't also a floor mover
if (line->args[3] && line->args[1] == 1)
ceiling->tag = firstone ? (INT16)line->args[3] : 0;
// flat changing ability
else if (line->flags & ML_NOCLIMB)
ceiling->texture = line->frontsector->ceilingpic;
else
ceiling->texture = -1;
ceiling->texture = line->args[4] ? line->frontsector->ceilingpic : -1;
break;
// More linedef executor junk
@ -514,67 +286,30 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
ceiling->direction = -1;
ceiling->bottomheight = line->frontsector->ceilingheight;
}
if (line->flags & ML_NOCLIMB)
ceiling->texture = -1;
else
ceiling->texture = line->frontsector->ceilingpic;
// If flag is set, change ceiling texture after moving
ceiling->texture = line->args[2] ? line->frontsector->ceilingpic : -1;
break;
case moveCeilingByFrontTexture:
if (line->flags & ML_NOCLIMB)
case moveCeilingByDistance:
if (line->args[4])
ceiling->speed = INT32_MAX/2; // as above, "instant" is one tic
else
ceiling->speed = FixedDiv(sides[line->sidenum[0]].textureoffset,8*FRACUNIT); // texture x offset
if (sides[line->sidenum[0]].rowoffset > 0)
ceiling->speed = line->args[3] << (FRACBITS - 3);
if (line->args[2] > 0)
{
ceiling->direction = 1; // up
ceiling->topheight = sec->ceilingheight + sides[line->sidenum[0]].rowoffset; // texture y offset
ceiling->topheight = sec->ceilingheight + (line->args[2] << FRACBITS);
}
else {
ceiling->direction = -1; // down
ceiling->bottomheight = sec->ceilingheight + sides[line->sidenum[0]].rowoffset; // texture y offset
ceiling->bottomheight = sec->ceilingheight + (line->args[2] << FRACBITS);
}
break;
/*
case lowerCeilingByLine:
ceiling->speed = FixedDiv(abs(line->dx),8*FRACUNIT);
ceiling->direction = -1; // Move down
ceiling->bottomheight = sec->ceilingheight - abs(line->dy);
break;
case raiseCeilingByLine:
ceiling->speed = FixedDiv(abs(line->dx),8*FRACUNIT);
ceiling->direction = 1; // Move up
ceiling->topheight = sec->ceilingheight + abs(line->dy);
break;
*/
case bounceCeiling:
ceiling->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous
ceiling->speed = FixedDiv(ceiling->speed,4*FRACUNIT);
ceiling->origspeed = ceiling->speed;
if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up
{
ceiling->direction = 1;
ceiling->topheight = line->frontsector->ceilingheight;
}
else // Move down
{
ceiling->direction = -1;
ceiling->bottomheight = line->frontsector->ceilingheight;
}
// Any delay?
ceiling->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS;
ceiling->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay
ceiling->texture = (fixed_t)(line - lines); // hack: use texture to store sourceline number
break;
case bounceCeilingCrush:
ceiling->speed = abs(line->dx); // same speed as elevateContinuous
ceiling->speed = FixedDiv(ceiling->speed,4*FRACUNIT);
ceiling->speed = line->args[2] << (FRACBITS - 2); // same speed as elevateContinuous
ceiling->origspeed = ceiling->speed;
if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up
{
@ -588,10 +323,8 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
}
// Any delay?
ceiling->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS;
ceiling->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay
ceiling->texture = (fixed_t)(line - lines); // hack: use texture to store sourceline number
ceiling->delay = line->args[5];
ceiling->delaytimer = line->args[4]; // Initial delay
break;
default:
@ -599,7 +332,6 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
}
ceiling->tag = tag;
ceiling->type = type;
firstone = 0;
}
@ -608,19 +340,19 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
/** Starts a ceiling crusher.
*
* \param tag Tag.
* \param line The source line.
* \param type The type of ceiling, either ::crushAndRaise or
* ::fastCrushAndRaise.
* \return 1 if at least one crusher was started, 0 otherwise.
* \sa EV_DoCeiling, EV_DoFloor, EV_DoElevator, T_CrushCeiling
*/
INT32 EV_DoCrush(line_t *line, ceiling_e type)
INT32 EV_DoCrush(mtag_t tag, line_t *line, ceiling_e type)
{
INT32 rtn = 0;
INT32 secnum = -1;
sector_t *sec;
ceiling_t *ceiling;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_SECTORS(tag, secnum)
{
@ -638,46 +370,33 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
ceiling->sector = sec;
ceiling->crush = true;
ceiling->sourceline = (INT32)(line-lines);
if (line->flags & ML_EFFECT4)
ceiling->oldspeed = FixedDiv(abs(line->dx),4*FRACUNIT);
else
ceiling->oldspeed = (R_PointToDist2(line->v2->x, line->v2->y, line->v1->x, line->v1->y)/16);
ceiling->speed = ceiling->origspeed = line->args[2] << (FRACBITS - 2);
switch(type)
{
case fastCrushAndRaise: // Up and then down
case raiseAndCrush: // Up and then down
ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
ceiling->direction = 1;
ceiling->speed = ceiling->oldspeed;
// Retain stupid behavior for backwards compatibility
if (!udmf && !(line->flags & ML_MIDSOLID))
ceiling->speed /= 2;
else
ceiling->speed = line->args[3] << (FRACBITS - 2);
ceiling->bottomheight = sec->floorheight + FRACUNIT;
break;
case crushBothOnce:
ceiling->topheight = sec->ceilingheight;
ceiling->bottomheight = sec->floorheight + (sec->ceilingheight-sec->floorheight)/2;
ceiling->direction = -1;
if (line->flags & ML_EFFECT4)
ceiling->speed = ceiling->oldspeed;
else
ceiling->speed = ceiling->oldspeed*2;
break;
case crushCeilOnce:
default: // Down and then up.
ceiling->topheight = sec->ceilingheight;
ceiling->direction = -1;
if (line->flags & ML_EFFECT4)
ceiling->speed = ceiling->oldspeed;
else
ceiling->speed = ceiling->oldspeed*2;
ceiling->bottomheight = sec->floorheight + FRACUNIT;
break;
}
ceiling->tag = tag;
ceiling->type = type;
}
return rtn;

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@
/// \file p_floor.c
/// \brief Floor animation, elevators
#include "dehacked.h"
#include "doomdef.h"
#include "doomstat.h"
#include "m_random.h"
@ -162,7 +163,7 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus
void T_MoveFloor(floormove_t *movefloor)
{
result_e res = 0;
boolean dontupdate = false;
boolean remove = false;
if (movefloor->delaytimer)
{
@ -178,8 +179,8 @@ void T_MoveFloor(floormove_t *movefloor)
if (movefloor->type == bounceFloor)
{
const fixed_t origspeed = FixedDiv(movefloor->origspeed,(ELEVATORSPEED/2));
const fixed_t fs = abs(movefloor->sector->floorheight - lines[movefloor->texture].frontsector->floorheight);
const fixed_t bs = abs(movefloor->sector->floorheight - lines[movefloor->texture].backsector->floorheight);
const fixed_t fs = abs(movefloor->sector->floorheight - lines[movefloor->sourceline].frontsector->floorheight);
const fixed_t bs = abs(movefloor->sector->floorheight - lines[movefloor->sourceline].backsector->floorheight);
if (fs < bs)
movefloor->speed = FixedDiv(fs,25*FRACUNIT) + FRACUNIT/4;
else
@ -190,113 +191,62 @@ void T_MoveFloor(floormove_t *movefloor)
if (res == pastdest)
{
if (movefloor->direction == 1)
switch (movefloor->type)
{
switch (movefloor->type)
{
case moveFloorByFrontSector:
if (movefloor->texture < -1) // chained linedef executing
P_LinedefExecute((INT16)(movefloor->texture + INT16_MAX + 2), NULL, NULL);
/* FALLTHRU */
case instantMoveFloorByFrontSector:
if (movefloor->texture > -1) // flat changing
movefloor->sector->floorpic = movefloor->texture;
break;
case bounceFloor: // Graue 03-12-2004
if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight)
movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight;
else
movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight;
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case bounceFloorCrush: // Graue 03-27-2004
if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight)
{
movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight;
movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dy),4*FRACUNIT); // return trip, use dy
}
else
{
movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight;
movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dx),4*FRACUNIT); // forward again, use dx
}
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case crushFloorOnce:
movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight;
case moveFloorByFrontSector:
if (movefloor->tag) // chained linedef executing
P_LinedefExecute(movefloor->tag, NULL, NULL);
/* FALLTHRU */
case instantMoveFloorByFrontSector:
if (movefloor->texture > -1) // flat changing
movefloor->sector->floorpic = movefloor->texture;
remove = true;
break;
case bounceFloor: // Graue 03-12-2004
case bounceFloorCrush: // Graue 03-27-2004
if (movefloor->floordestheight == lines[movefloor->sourceline].frontsector->floorheight)
{
movefloor->floordestheight = lines[movefloor->sourceline].backsector->floorheight;
movefloor->origspeed = lines[movefloor->sourceline].args[3] << (FRACBITS - 2); // return trip, use args[3]
}
else
{
movefloor->floordestheight = lines[movefloor->sourceline].frontsector->floorheight;
movefloor->origspeed = lines[movefloor->sourceline].args[2] << (FRACBITS - 2); // forward again, use args[2]
}
if (movefloor->type == bounceFloorCrush)
movefloor->speed = movefloor->origspeed;
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->delaytimer = movefloor->delay;
remove = false;
break;
case crushFloorOnce:
if (movefloor->direction == 1)
{
movefloor->floordestheight = lines[movefloor->sourceline].frontsector->floorheight;
movefloor->direction = -1;
movefloor->speed = lines[movefloor->sourceline].args[3] << (FRACBITS - 2);
movefloor->sector->soundorg.z = movefloor->sector->floorheight;
S_StartSound(&movefloor->sector->soundorg,sfx_pstop);
P_RecalcPrecipInSector(movefloor->sector);
return;
default:
break;
}
}
else if (movefloor->direction == -1)
{
switch (movefloor->type)
{
case moveFloorByFrontSector:
if (movefloor->texture < -1) // chained linedef executing
P_LinedefExecute((INT16)(movefloor->texture + INT16_MAX + 2), NULL, NULL);
/* FALLTHRU */
case instantMoveFloorByFrontSector:
if (movefloor->texture > -1) // flat changing
movefloor->sector->floorpic = movefloor->texture;
break;
case bounceFloor: // Graue 03-12-2004
if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight)
movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight;
else
movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight;
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case bounceFloorCrush: // Graue 03-27-2004
if (movefloor->floordestheight == lines[movefloor->texture].frontsector->floorheight)
{
movefloor->floordestheight = lines[movefloor->texture].backsector->floorheight;
movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dy),4*FRACUNIT); // return trip, use dy
}
else
{
movefloor->floordestheight = lines[movefloor->texture].frontsector->floorheight;
movefloor->speed = movefloor->origspeed = FixedDiv(abs(lines[movefloor->texture].dx),4*FRACUNIT); // forward again, use dx
}
movefloor->direction = (movefloor->floordestheight < movefloor->sector->floorheight) ? -1 : 1;
movefloor->sector->floorspeed = movefloor->speed * movefloor->direction;
movefloor->delaytimer = movefloor->delay;
P_RecalcPrecipInSector(movefloor->sector);
return; // not break, why did this work? Graue 04-03-2004
case crushFloorOnce:
movefloor->sector->floordata = NULL; // Clear up the thinker so others can use it
P_RemoveThinker(&movefloor->thinker);
movefloor->sector->floorspeed = 0;
P_RecalcPrecipInSector(movefloor->sector);
return;
default:
break;
}
S_StartSound(&movefloor->sector->soundorg, sfx_pstop);
remove = false;
}
else
remove = true;
break;
default:
remove = true;
break;
}
}
if (remove)
{
movefloor->sector->floordata = NULL; // Clear up the thinker so others can use it
movefloor->sector->floorspeed = 0;
P_RemoveThinker(&movefloor->thinker);
dontupdate = true;
}
if (!dontupdate)
movefloor->sector->floorspeed = movefloor->speed*movefloor->direction;
else
movefloor->sector->floorspeed = 0;
movefloor->sector->floorspeed = movefloor->speed*movefloor->direction;
P_RecalcPrecipInSector(movefloor->sector);
}
@ -601,7 +551,7 @@ static fixed_t P_SectorCheckWater(sector_t *analyzesector,
for (rover = analyzesector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_SOLID)
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_SOLID)
continue;
// If the sector is below the water, don't bother.
@ -634,7 +584,6 @@ void T_BounceCheese(bouncecheese_t *bouncer)
sector_t *actionsector;
boolean remove;
INT32 i;
mtag_t tag = Tag_FGet(&bouncer->sourceline->tags);
if (bouncer->sector->crumblestate == CRUMBLE_RESTORE || bouncer->sector->crumblestate == CRUMBLE_WAIT
|| bouncer->sector->crumblestate == CRUMBLE_ACTIVATED) // Oops! Crumbler says to remove yourself!
@ -649,7 +598,7 @@ void T_BounceCheese(bouncecheese_t *bouncer)
}
// You can use multiple target sectors, but at your own risk!!!
TAG_ITER_SECTORS(tag, i)
TAG_ITER_SECTORS(bouncer->sourceline->args[0], i)
{
actionsector = &sectors[i];
actionsector->moved = true;
@ -773,7 +722,7 @@ void T_StartCrumble(crumble_t *crumble)
ffloor_t *rover;
sector_t *sector;
INT32 i;
mtag_t tag = Tag_FGet(&crumble->sourceline->tags);
mtag_t tag = crumble->sourceline->args[0];
// Once done, the no-return thinker just sits there,
// constantly 'returning'... kind of an oxymoron, isn't it?
@ -808,10 +757,10 @@ void T_StartCrumble(crumble_t *crumble)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_CRUMBLE))
if (!(rover->fofflags & FOF_CRUMBLE))
continue;
if (!(rover->flags & FF_FLOATBOB))
if (!(rover->fofflags & FOF_FLOATBOB))
continue;
if (rover->master != crumble->sourceline)
@ -820,7 +769,7 @@ void T_StartCrumble(crumble_t *crumble)
rover->alpha = crumble->origalpha;
if (rover->alpha == 0xff)
rover->flags &= ~FF_TRANSLUCENT;
rover->fofflags &= ~FOF_TRANSLUCENT;
}
}
@ -844,13 +793,13 @@ void T_StartCrumble(crumble_t *crumble)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (rover->flags & FF_NORETURN)
if (rover->fofflags & FOF_NORETURN)
continue;
if (!(rover->flags & FF_CRUMBLE))
if (!(rover->fofflags & FOF_CRUMBLE))
continue;
if (!(rover->flags & FF_FLOATBOB))
if (!(rover->fofflags & FOF_FLOATBOB))
continue;
if (rover->master != crumble->sourceline)
@ -858,7 +807,7 @@ void T_StartCrumble(crumble_t *crumble)
if (rover->alpha == crumble->origalpha)
{
rover->flags |= FF_TRANSLUCENT;
rover->fofflags |= FOF_TRANSLUCENT;
rover->alpha = 0x00;
}
else
@ -866,7 +815,7 @@ void T_StartCrumble(crumble_t *crumble)
rover->alpha = crumble->origalpha;
if (rover->alpha == 0xff)
rover->flags &= ~FF_TRANSLUCENT;
rover->fofflags &= ~FOF_TRANSLUCENT;
}
}
}
@ -1097,23 +1046,6 @@ void T_MarioBlockChecker(mariocheck_t *block)
}
}
static boolean P_IsPlayerValid(size_t playernum)
{
if (!playeringame[playernum])
return false;
if (!players[playernum].mo)
return false;
if (players[playernum].mo->health <= 0)
return false;
if (players[playernum].spectator)
return false;
return true;
}
// This is the Thwomp's 'brain'. It looks around for players nearby, and if
// it finds any, **SMASH**!!! Muahahhaa....
void T_ThwompSector(thwomp_t *thwomp)
@ -1150,7 +1082,7 @@ void T_ThwompSector(thwomp_t *thwomp)
if (thwomp->direction == 0) // Not going anywhere, so look for players.
{
if (rover->flags & FF_EXISTS)
if (rover->fofflags & FOF_EXISTS)
{
UINT8 i;
// scan the players to find victims!
@ -1243,7 +1175,7 @@ void T_ThwompSector(thwomp_t *thwomp)
if (res == pastdest)
{
if (rover->flags & FF_EXISTS)
if (rover->fofflags & FOF_EXISTS)
S_StartSound((void *)&actionsector->soundorg, thwomp->sound);
thwomp->direction = 1; // start heading back up
@ -1290,7 +1222,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
sector_t *sec = NULL;
INT32 secnum = -1;
boolean FOFsector = false;
mtag_t tag = Tag_FGet(&nobaddies->sourceline->tags);
mtag_t tag = nobaddies->sourceline->args[0];
TAG_ITER_SECTORS(tag, secnum)
{
@ -1302,14 +1234,13 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
for (i = 0; i < sec->linecount; i++)
{
INT32 targetsecnum = -1;
mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags);
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
continue;
FOFsector = true;
TAG_ITER_SECTORS(tag2, targetsecnum)
TAG_ITER_SECTORS(sec->lines[i]->args[0], targetsecnum)
{
if (T_SectorHasEnemies(&sectors[targetsecnum]))
return;
@ -1327,217 +1258,68 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
P_RemoveThinker(&nobaddies->thinker);
}
//
// P_IsObjectOnRealGround
//
// Helper function for T_EachTimeThinker
// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS
// I'll consider whether to make this a more globally accessible function or whatever in future
// -- Monster Iestyn
//
static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec)
static boolean P_CheckAllTrigger(eachtime_t *eachtime)
{
// Is the object in reverse gravity?
if (mo->eflags & MFE_VERTICALFLIP)
size_t i;
for (i = 0; i < MAXPLAYERS; i++)
{
// Detect if the player is on the ceiling.
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true;
if (P_CanPlayerTrigger(i) && !eachtime->playersInArea[i])
return false;
}
// Nope!
else
{
// Detect if the player is on the floor.
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true;
}
return false;
return true;
}
static boolean P_IsMobjTouchingSector(mobj_t *mo, sector_t *sec)
{
msecnode_t *node;
if (mo->subsector->sector == sec)
return true;
if (!(sec->flags & SF_TRIGGERSPECIAL_TOUCH))
return false;
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector == sec)
return true;
}
return false;
}
//
// T_EachTimeThinker
//
// Runs a linedef exec whenever a player enters an area.
// Keeps track of players currently in the area and notices any changes.
//
// \sa P_AddEachTimeThinker
//
void T_EachTimeThinker(eachtime_t *eachtime)
{
size_t i, j;
sector_t *sec = NULL;
sector_t *targetsec = NULL;
INT32 secnum = -1;
size_t i;
boolean oldPlayersInArea[MAXPLAYERS];
boolean oldPlayersOnArea[MAXPLAYERS];
boolean *oldPlayersArea;
boolean *playersArea;
boolean FOFsector = false;
boolean floortouch = false;
fixed_t bottomheight, topheight;
ffloor_t *rover;
mtag_t tag = Tag_FGet(&eachtime->sourceline->tags);
sector_t *caller[MAXPLAYERS];
boolean allPlayersChecked = false;
boolean allPlayersTrigger = false;
for (i = 0; i < MAXPLAYERS; i++)
{
oldPlayersInArea[i] = eachtime->playersInArea[i];
oldPlayersOnArea[i] = eachtime->playersOnArea[i];
eachtime->playersInArea[i] = false;
eachtime->playersOnArea[i] = false;
}
TAG_ITER_SECTORS(tag, secnum)
{
sec = &sectors[secnum];
FOFsector = false;
if (GETSECSPECIAL(sec->special, 2) == 3 || GETSECSPECIAL(sec->special, 2) == 5)
floortouch = true;
else if (GETSECSPECIAL(sec->special, 2) >= 1 && GETSECSPECIAL(sec->special, 2) <= 8)
floortouch = false;
else
continue;
// Check the lines of this sector, to see if it is a FOF control sector.
for (i = 0; i < sec->linecount; i++)
{
INT32 targetsecnum = -1;
mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags);
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
continue;
FOFsector = true;
TAG_ITER_SECTORS(tag2, targetsecnum)
{
targetsec = &sectors[targetsecnum];
// Find the FOF corresponding to the control linedef
for (rover = targetsec->ffloors; rover; rover = rover->next)
{
if (rover->master == sec->lines[i])
break;
}
if (!rover) // This should be impossible, but don't complain if it is the case somehow
continue;
if (!(rover->flags & FF_EXISTS)) // If the FOF does not "exist", we pretend that nobody's there
continue;
for (j = 0; j < MAXPLAYERS; j++)
{
if (!P_IsPlayerValid(j))
continue;
if (!P_IsMobjTouchingSector(players[j].mo, targetsec))
continue;
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec);
if (players[j].mo->z > topheight)
continue;
if (players[j].mo->z + players[j].mo->height < bottomheight)
continue;
if (floortouch && P_IsObjectOnGroundIn(players[j].mo, targetsec))
eachtime->playersOnArea[j] = true;
else
eachtime->playersInArea[j] = true;
}
}
}
if (!FOFsector)
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (!P_IsPlayerValid(i))
continue;
if (!P_IsMobjTouchingSector(players[i].mo, sec))
continue;
if (!(players[i].mo->subsector->sector == sec
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
continue;
if (floortouch && P_IsObjectOnRealGround(players[i].mo, sec))
eachtime->playersOnArea[i] = true;
else
eachtime->playersInArea[i] = true;
}
}
}
// Check if a new player entered.
// If not, check if a player hit the floor.
// If either condition is true, execute.
if (floortouch)
{
playersArea = eachtime->playersOnArea;
oldPlayersArea = oldPlayersOnArea;
}
else
{
playersArea = eachtime->playersInArea;
oldPlayersArea = oldPlayersInArea;
caller[i] = P_CanPlayerTrigger(i) ? P_FindPlayerTrigger(&players[i], eachtime->sourceline) : NULL;
eachtime->playersInArea[i] = caller[i] != NULL;
}
// Easy check... nothing has changed
if (!memcmp(playersArea, oldPlayersArea, sizeof(boolean)*MAXPLAYERS))
if (!memcmp(eachtime->playersInArea, oldPlayersInArea, sizeof(boolean)*MAXPLAYERS))
return;
// If sector has an "all players" trigger type, all players need to be in area
if (GETSECSPECIAL(sec->special, 2) == 2 || GETSECSPECIAL(sec->special, 2) == 3)
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (P_IsPlayerValid(i) && !playersArea[i])
return;
}
}
// Trigger for every player who has entered (and exited, if triggerOnExit)
for (i = 0; i < MAXPLAYERS; i++)
{
if (playersArea[i] == oldPlayersArea[i])
if (eachtime->playersInArea[i] == oldPlayersInArea[i])
continue;
// If player has just left, check if still valid
if (!playersArea[i] && (!eachtime->triggerOnExit || !P_IsPlayerValid(i)))
if (!eachtime->playersInArea[i] && (!eachtime->triggerOnExit || !P_CanPlayerTrigger(i)))
continue;
CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", tag);
// If sector has an "all players" trigger type, all players need to be in area
if (caller[i] && caller[i]->triggerer == TO_ALLPLAYERS)
{
if (!allPlayersChecked)
{
allPlayersChecked = true;
allPlayersTrigger = P_CheckAllTrigger(eachtime);
}
if (!allPlayersTrigger)
continue;
}
CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", Tag_FGet(&eachtime->sourceline->tags));
// 03/08/14 -Monster Iestyn
// No more stupid hacks involving changing eachtime->sourceline's tag or special or whatever!
// This should now run ONLY the stuff for eachtime->sourceline itself, instead of all trigger linedefs sharing the same tag.
// Makes much more sense doing it this way, honestly.
P_RunTriggerLinedef(eachtime->sourceline, players[i].mo, sec);
P_RunTriggerLinedef(eachtime->sourceline, players[i].mo, caller[i]);
if (!eachtime->sourceline->special) // this happens only for "Trigger on X calls" linedefs
P_RemoveThinker(&eachtime->thinker);
@ -1806,13 +1588,12 @@ void T_PlaneDisplace(planedisplace_t *pd)
// (egg capsule button), P_PlayerInSpecialSector (buttons),
// and P_SpawnSpecials (continuous floor movers and instant lower).
//
void EV_DoFloor(line_t *line, floor_e floortype)
void EV_DoFloor(mtag_t tag, line_t *line, floor_e floortype)
{
INT32 firstone = 1;
INT32 secnum = -1;
sector_t *sec;
floormove_t *dofloor;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_SECTORS(tag, secnum)
{
@ -1833,34 +1614,25 @@ void EV_DoFloor(line_t *line, floor_e floortype)
dofloor->type = floortype;
dofloor->crush = false; // default: types that crush will change this
dofloor->sector = sec;
dofloor->sourceline = (INT32)(line - lines);
switch (floortype)
{
// Lowers a floor to the lowest surrounding floor.
case lowerFloorToLowest:
dofloor->direction = -1; // down
dofloor->speed = FLOORSPEED*2; // 2 fracunits per tic
dofloor->floordestheight = P_FindLowestFloorSurrounding(sec);
break;
// Used for part of the Egg Capsule, when an FOF with type 666 is
// contacted by the player.
// Used to open the top of an Egg Capsule.
case raiseFloorToNearestFast:
dofloor->direction = -1; // down
dofloor->speed = FLOORSPEED*4; // 4 fracunits per tic
dofloor->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
break;
// Used for sectors tagged to 50 linedefs (effectively
// changing the base height for placing things in that sector).
// Instantly lower floor to surrounding sectors.
// Used as a hack in the binary map format to allow thing heights above 4096.
case instantLower:
dofloor->direction = -1; // down
dofloor->speed = INT32_MAX/2; // "instant" means "takes one tic"
dofloor->floordestheight = P_FindLowestFloorSurrounding(sec);
break;
// Linedef executor command, linetype 101.
// Front sector floor = destination height.
case instantMoveFloorByFrontSector:
dofloor->speed = INT32_MAX/2; // as above, "instant" is one tic
dofloor->floordestheight = line->frontsector->floorheight;
@ -1870,22 +1642,12 @@ void EV_DoFloor(line_t *line, floor_e floortype)
else
dofloor->direction = -1; // down
// New for 1.09: now you can use the no climb flag to
// DISABLE the flat changing. This makes it work
// totally opposite the way linetype 106 does. Yet
// another reason I'll be glad to break backwards
// compatibility for the final.
if (line->flags & ML_NOCLIMB)
dofloor->texture = -1; // don't mess with the floorpic
else
dofloor->texture = line->frontsector->floorpic;
// If flag is set, change floor texture after moving
dofloor->texture = line->args[2] ? line->frontsector->floorpic : -1;
break;
// Linedef executor command, linetype 106.
// Line length = speed, front sector floor = destination height.
case moveFloorByFrontSector:
dofloor->speed = P_AproxDistance(line->dx, line->dy);
dofloor->speed = FixedDiv(dofloor->speed,8*FRACUNIT);
dofloor->speed = line->args[2] << (FRACBITS - 3);
dofloor->floordestheight = line->frontsector->floorheight;
if (dofloor->floordestheight >= sec->floorheight)
@ -1894,85 +1656,31 @@ void EV_DoFloor(line_t *line, floor_e floortype)
dofloor->direction = -1; // down
// chained linedef executing ability
if (line->flags & ML_BLOCKMONSTERS)
{
// Only set it on one of the moving sectors (the
// smallest numbered) and only if the front side
// x offset is positive, indicating a valid tag.
if (firstone && sides[line->sidenum[0]].textureoffset > 0)
dofloor->texture = (sides[line->sidenum[0]].textureoffset>>FRACBITS) - 32769;
else
dofloor->texture = -1;
}
// Only set it on one of the moving sectors (the smallest numbered)
if (line->args[3])
dofloor->tag = firstone ? (INT16)line->args[3] : -1;
// flat changing ability
else if (line->flags & ML_NOCLIMB)
dofloor->texture = line->frontsector->floorpic;
else
dofloor->texture = -1; // nothing special to do after movement completes
dofloor->texture = line->args[4] ? line->frontsector->floorpic : -1;
break;
case moveFloorByFrontTexture:
if (line->flags & ML_NOCLIMB)
case moveFloorByDistance:
if (line->args[4])
dofloor->speed = INT32_MAX/2; // as above, "instant" is one tic
else
dofloor->speed = FixedDiv(sides[line->sidenum[0]].textureoffset,8*FRACUNIT); // texture x offset
dofloor->floordestheight = sec->floorheight + sides[line->sidenum[0]].rowoffset; // texture y offset
dofloor->speed = line->args[3] << (FRACBITS - 3);
dofloor->floordestheight = sec->floorheight + (line->args[2] << FRACBITS);
if (dofloor->floordestheight > sec->floorheight)
dofloor->direction = 1; // up
else
dofloor->direction = -1; // down
break;
/*
// Linedef executor command, linetype 108.
// dx = speed, dy = amount to lower.
case lowerFloorByLine:
dofloor->direction = -1; // down
dofloor->speed = FixedDiv(abs(line->dx),8*FRACUNIT);
dofloor->floordestheight = sec->floorheight - abs(line->dy);
if (dofloor->floordestheight > sec->floorheight) // wrapped around
I_Error("Can't lower sector %d\n", secnum);
break;
// Linedef executor command, linetype 109.
// dx = speed, dy = amount to raise.
case raiseFloorByLine:
dofloor->direction = 1; // up
dofloor->speed = FixedDiv(abs(line->dx),8*FRACUNIT);
dofloor->floordestheight = sec->floorheight + abs(line->dy);
if (dofloor->floordestheight < sec->floorheight) // wrapped around
I_Error("Can't raise sector %d\n", secnum);
break;
*/
// Linetypes 2/3.
// Move floor up and down indefinitely like the old elevators.
// Move floor up and down indefinitely.
// bounceFloor has slowdown at the top and bottom of movement.
case bounceFloor:
dofloor->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous
dofloor->speed = FixedDiv(dofloor->speed,4*FRACUNIT);
dofloor->origspeed = dofloor->speed; // it gets slowed down at the top and bottom
dofloor->floordestheight = line->frontsector->floorheight;
if (dofloor->floordestheight >= sec->floorheight)
dofloor->direction = 1; // up
else
dofloor->direction = -1; // down
// Any delay?
dofloor->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS;
dofloor->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay
dofloor->texture = (fixed_t)(line - lines); // hack: store source line number
break;
// Linetypes 6/7.
// Like 2/3, but no slowdown at the top and bottom of movement,
// and the speed is line->dx the first way, line->dy for the
// return trip. Good for crushers.
case bounceFloorCrush:
dofloor->speed = FixedDiv(abs(line->dx),4*FRACUNIT);
dofloor->speed = line->args[2] << (FRACBITS - 2); // same speed as elevateContinuous
dofloor->origspeed = dofloor->speed;
dofloor->floordestheight = line->frontsector->floorheight;
@ -1982,27 +1690,18 @@ void EV_DoFloor(line_t *line, floor_e floortype)
dofloor->direction = -1; // down
// Any delay?
dofloor->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS;
dofloor->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay
dofloor->texture = (fixed_t)(line - lines); // hack: store source line number
dofloor->delay = line->args[5];
dofloor->delaytimer = line->args[4]; // Initial delay
break;
case crushFloorOnce:
dofloor->speed = FixedDiv(abs(line->dx),4*FRACUNIT);
dofloor->origspeed = dofloor->speed;
dofloor->speed = dofloor->origspeed = line->args[2] << (FRACBITS - 2);
dofloor->floordestheight = line->frontsector->ceilingheight;
if (dofloor->floordestheight >= sec->floorheight)
dofloor->direction = 1; // up
else
dofloor->direction = -1; // down
// Any delay?
dofloor->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS;
dofloor->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS;
dofloor->texture = (fixed_t)(line - lines); // hack: store source line number
break;
default:
@ -2023,14 +1722,13 @@ void EV_DoFloor(line_t *line, floor_e floortype)
//
// jff 2/22/98 new type to move floor and ceiling in parallel
//
void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype)
{
INT32 secnum = -1;
sector_t *sec;
elevator_t *elevator;
mtag_t tag = Tag_FGet(&line->tags);
// act on all sectors with the same tag as the triggering linedef
// act on all sectors with the given tag
TAG_ITER_SECTORS(tag, secnum)
{
sec = &sectors[secnum];
@ -2048,6 +1746,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
elevator->type = elevtype;
elevator->sourceline = line;
elevator->distance = 1; // Always crush unless otherwise
elevator->sector = sec;
// set up the fields according to the type of elevator action
switch (elevtype)
@ -2055,91 +1754,57 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
// elevator down to next floor
case elevateDown:
elevator->direction = -1;
elevator->sector = sec;
elevator->speed = ELEVATORSPEED/2; // half speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
break;
// elevator up to next floor
case elevateUp:
elevator->direction = 1;
elevator->sector = sec;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
break;
// elevator up to highest floor
case elevateHighest:
elevator->direction = 1;
elevator->sector = sec;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindHighestFloorSurrounding(sec);
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
break;
// elevator to floor height of activating switch's front sector
case elevateCurrent:
elevator->sector = sec;
elevator->speed = ELEVATORSPEED;
elevator->floordestheight = line->frontsector->floorheight;
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
elevator->direction = elevator->floordestheight > sec->floorheight? 1 : -1;
break;
case elevateContinuous:
if (customspeed)
{
elevator->origspeed = P_AproxDistance(line->dx, line->dy);
elevator->origspeed = FixedDiv(elevator->origspeed,4*FRACUNIT);
elevator->speed = elevator->origspeed;
}
else
{
elevator->speed = ELEVATORSPEED/2;
elevator->origspeed = elevator->speed;
}
elevator->origspeed = line->args[1] << (FRACBITS - 2);
elevator->speed = elevator->origspeed;
elevator->sector = sec;
elevator->low = !(line->flags & ML_NOCLIMB); // go down first unless noclimb is on
elevator->low = !line->args[4]; // go down first unless args[4] is set
if (elevator->low)
{
elevator->direction = 1;
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
}
else
{
elevator->direction = -1;
elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
}
elevator->floorwasheight = elevator->sector->floorheight;
elevator->ceilingwasheight = elevator->sector->ceilingheight;
elevator->delay = sides[line->sidenum[0]].textureoffset >> FRACBITS;
elevator->delaytimer = sides[line->sidenum[0]].rowoffset >> FRACBITS; // Initial delay
elevator->delay = line->args[3];
elevator->delaytimer = line->args[2]; // Initial delay
break;
case bridgeFall:
elevator->direction = -1;
elevator->sector = sec;
elevator->speed = ELEVATORSPEED*4; // quadruple speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight
+ sec->ceilingheight - sec->floorheight;
break;
default:
break;
}
elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight;
}
}
@ -2149,7 +1814,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
fixed_t leftx, rightx, topy, bottomy, topz, bottomz, widthfactor, heightfactor, a, b, c, spacing;
mobjtype_t type;
tic_t lifetime;
INT16 flags;
boolean fromcenter;
sector_t *controlsec = rover->master->frontsector;
mtag_t tag = Tag_FGet(&controlsec->tags);
@ -2179,25 +1844,20 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
spacing = (32<<FRACBITS);
type = MT_ROCKCRUMBLE1;
lifetime = 3*TICRATE;
flags = 0;
fromcenter = false;
if (tag != 0)
{
INT32 tagline = Tag_FindLineSpecial(14, tag);
if (tagline != -1)
{
if (sides[lines[tagline].sidenum[0]].toptexture)
type = (mobjtype_t)sides[lines[tagline].sidenum[0]].toptexture; // Set as object type in p_setup.c...
if (sides[lines[tagline].sidenum[0]].textureoffset)
spacing = sides[lines[tagline].sidenum[0]].textureoffset;
if (sides[lines[tagline].sidenum[0]].rowoffset)
{
if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS != -1)
lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS);
else
lifetime = 0;
}
flags = lines[tagline].flags;
if (lines[tagline].stringargs[0])
type = get_number(lines[tagline].stringargs[0]);
if (lines[tagline].args[0])
spacing = lines[tagline].args[0] << FRACBITS;
if (lines[tagline].args[1])
lifetime = (lines[tagline].args[1] != -1) ? lines[tagline].args[1] : 0;
fromcenter = !!lines[tagline].args[2];
}
}
@ -2232,7 +1892,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
topz = *rover->topheight-(spacing>>1);
bottomz = *rover->bottomheight;
if (flags & ML_EFFECT1)
if (fromcenter)
{
widthfactor = (rightx + topy - leftx - bottomy)>>3;
heightfactor = (topz - *rover->bottomheight)>>2;
@ -2255,7 +1915,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
spawned = P_SpawnMobj(a, b, c, type);
spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones
if (flags & ML_EFFECT1)
if (fromcenter)
{
P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor));
P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false);
@ -2268,7 +1928,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
}
// no longer exists (can't collide with again)
rover->flags &= ~FF_EXISTS;
rover->fofflags &= ~FOF_EXISTS;
rover->master->frontsector->moved = true;
P_RecalcPrecipInSector(sec);
}
@ -2327,7 +1987,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
crumble_t *crumble;
sector_t *foundsec;
INT32 i;
mtag_t tag = Tag_FGet(&rover->master->tags);
mtag_t tag = rover->master->args[0];
// If floor is already activated, skip it
if (sec->floordata)
@ -2394,8 +2054,8 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
if (roversec->floordata || roversec->ceilingdata)
return;
if (!(rover->flags & FF_SOLID))
rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL);
if (!(rover->fofflags & FOF_SOLID))
rover->fofflags |= (FOF_SOLID|FOF_RENDERALL|FOF_CUTLEVEL);
// Find an item to pop out!
thing = SearchMarioNode(roversec->touching_thinglist);
@ -2419,7 +2079,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
block->direction = 1;
block->floorstartheight = block->sector->floorheight;
block->ceilingstartheight = block->sector->ceilingheight;
block->tag = (INT16)Tag_FGet(&sector->tags);
block->tag = (INT16)rover->master->args[0];
if (itsamonitor)
{

View file

@ -762,6 +762,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// return;
{
UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2;
sectorspecialflags_t specialflag = (special->type == MT_REDFLAG) ? SSF_REDTEAMBASE : SSF_BLUETEAMBASE;
const char *flagtext;
char flagcolor;
char plname[MAXPLAYERNAME+4];
@ -791,7 +792,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->fuse = 1;
special->flags2 |= MF2_JUSTATTACKED;
if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam))
if (!P_PlayerTouchingSectorSpecialFlag(player, specialflag))
{
CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80);
@ -1380,19 +1381,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
case MT_AXE:
{
line_t junk;
thinker_t *th;
mobj_t *mo2;
if (player->bot && player->bot != BOT_MPAI)
return;
// Initialize my junk
junk.tags.tags = NULL;
junk.tags.count = 0;
Tag_FSet(&junk.tags, LE_AXE);
EV_DoElevator(&junk, bridgeFall, false);
if (special->spawnpoint)
EV_DoElevator(special->spawnpoint->args[0], NULL, bridgeFall);
// scan the remaining thinkers to find koopa
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
@ -1441,7 +1437,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// Misc touchables //
// *************** //
case MT_STARPOST:
P_TouchStarPost(special, player, special->spawnpoint && (special->spawnpoint->options & MTF_OBJECTSPECIAL));
P_TouchStarPost(special, player, special->spawnpoint && special->spawnpoint->args[1]);
return;
case MT_FAKEMOBILE:
@ -2775,7 +2771,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
case MT_BLASTEXECUTOR:
if (target->spawnpoint)
P_LinedefExecute(target->spawnpoint->angle, (source ? source : inflictor), target->subsector->sector);
P_LinedefExecute(target->spawnpoint->args[0], (source ? source : inflictor), target->subsector->sector);
break;
case MT_SPINBOBERT:

View file

@ -30,7 +30,7 @@ void P_RemoveLighting(sector_t *sector)
// The thinker is the first member in all the lighting action structs,
// so just let the thinker get freed, and that will free the whole
// structure.
P_RemoveThinker(&((elevator_t *)sector->lightingdata)->thinker);
P_RemoveThinker(&((thinkerdata_t *)sector->lightingdata)->thinker);
sector->lightingdata = NULL;
}
}
@ -54,43 +54,36 @@ void T_FireFlicker(fireflicker_t *flick)
amount = (INT16)((UINT8)(P_RandomByte() & 3) * 16);
if (flick->sector->lightlevel - amount < flick->minlight)
flick->sector->lightlevel = (INT16)flick->minlight;
flick->sector->lightlevel = flick->minlight;
else
flick->sector->lightlevel = (INT16)((INT16)flick->maxlight - amount);
flick->sector->lightlevel = flick->maxlight - amount;
flick->count = flick->resetcount;
}
/** Spawns an adjustable fire flicker effect in a sector.
*
* \param minsector Sector whose light level is used as the darkest.
* \param maxsector Sector whose light level is used as the brightest,
* and also the target sector for the effect.
* \param sector Target sector for the effect.
* \param lighta One of the two light levels to move between.
* \param lightb The other light level.
* \param length Four times the number of tics between flickers.
* \sa T_FireFlicker
*/
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length)
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length)
{
fireflicker_t *flick;
P_RemoveLighting(maxsector); // out with the old, in with the new
P_RemoveLighting(sector); // out with the old, in with the new
flick = Z_Calloc(sizeof (*flick), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &flick->thinker);
flick->thinker.function.acp1 = (actionf_p1)T_FireFlicker;
flick->sector = maxsector;
flick->maxlight = maxsector->lightlevel;
flick->minlight = minsector->lightlevel;
if (flick->minlight > flick->maxlight)
{
// You mixed them up, you dummy.
INT32 oops = flick->minlight;
flick->minlight = flick->maxlight;
flick->maxlight = oops;
}
flick->sector = sector;
flick->maxlight = max(lighta, lightb);
flick->minlight = min(lighta, lightb);
flick->count = flick->resetcount = length/4;
maxsector->lightingdata = flick;
sector->lightingdata = flick;
// input bounds checking and stuff
if (!flick->resetcount)
@ -103,6 +96,9 @@ fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxse
flick->maxlight++;
}
// Make sure the starting light level is in range.
sector->lightlevel = max(flick->minlight, min(flick->maxlight, sector->lightlevel));
return flick;
}
@ -148,7 +144,7 @@ void P_SpawnLightningFlash(sector_t *sector)
minlight = ((lightflash_t *)sector->lightingdata)->minlight;
}
P_RemoveThinker(&((elevator_t *)sector->lightingdata)->thinker);
P_RemoveThinker(&((thinkerdata_t *)sector->lightingdata)->thinker);
}
sector->lightingdata = NULL;
@ -182,21 +178,21 @@ void T_StrobeFlash(strobe_t *flash)
if (flash->sector->lightlevel == flash->minlight)
{
flash->sector->lightlevel = (INT16)flash->maxlight;
flash->sector->lightlevel = flash->maxlight;
flash->count = flash->brighttime;
}
else
{
flash->sector->lightlevel = (INT16)flash->minlight;
flash->sector->lightlevel = flash->minlight;
flash->count = flash->darktime;
}
}
/** Spawns an adjustable strobe light effect in a sector.
*
* \param minsector Sector whose light level is used as the darkest.
* \param maxsector Sector whose light level is used as the brightest,
* and also the target sector for the effect.
* \param sector Target sector for the effect.
* \param lighta One of the two light levels to move between.
* \param lightb The other light level.
* \param darktime Time in tics for the light to be dark.
* \param brighttime Time in tics for the light to be bright.
* \param inSync If true, the effect will be kept in sync
@ -207,29 +203,21 @@ void T_StrobeFlash(strobe_t *flash)
* the strobe flash is random.
* \sa T_StrobeFlash
*/
strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, INT32 darktime, INT32 brighttime, boolean inSync)
strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *sector, INT16 lighta, INT16 lightb, INT32 darktime, INT32 brighttime, boolean inSync)
{
strobe_t *flash;
P_RemoveLighting(maxsector); // out with the old, in with the new
P_RemoveLighting(sector); // out with the old, in with the new
flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &flash->thinker);
flash->sector = maxsector;
flash->sector = sector;
flash->darktime = darktime;
flash->brighttime = brighttime;
flash->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
flash->maxlight = maxsector->lightlevel;
flash->minlight = minsector->lightlevel;
if (flash->minlight > flash->maxlight)
{
// You mixed them up, you dummy.
INT32 oops = flash->minlight;
flash->minlight = flash->maxlight;
flash->maxlight = oops;
}
flash->maxlight = max(lighta, lightb);
flash->minlight = min(lighta, lightb);
if (flash->minlight == flash->maxlight)
flash->minlight = 0;
@ -239,7 +227,10 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector,
else
flash->count = 1;
maxsector->lightingdata = flash;
// Make sure the starting light level is in range.
sector->lightlevel = max(flash->minlight, min(flash->maxlight, sector->lightlevel));
sector->lightingdata = flash;
return flash;
}
@ -254,20 +245,20 @@ void T_Glow(glow_t *g)
{
case -1:
// DOWN
g->sector->lightlevel = (INT16)(g->sector->lightlevel - (INT16)g->speed);
g->sector->lightlevel -= g->speed;
if (g->sector->lightlevel <= g->minlight)
{
g->sector->lightlevel = (INT16)(g->sector->lightlevel + (INT16)g->speed);
g->sector->lightlevel += g->speed;
g->direction = 1;
}
break;
case 1:
// UP
g->sector->lightlevel = (INT16)(g->sector->lightlevel + (INT16)g->speed);
g->sector->lightlevel += g->speed;
if (g->sector->lightlevel >= g->maxlight)
{
g->sector->lightlevel = (INT16)(g->sector->lightlevel - (INT16)g->speed);
g->sector->lightlevel -= g->speed;
g->direction = -1;
}
break;
@ -276,34 +267,27 @@ void T_Glow(glow_t *g)
/** Spawns an adjustable glowing light effect in a sector.
*
* \param minsector Sector whose light level is used as the darkest.
* \param maxsector Sector whose light level is used as the brightest,
* and also the target sector for the effect.
* \param sector Target sector for the effect.
* \param lighta One of the two light levels to move between.
* \param lightb The other light level.
* \param length The speed of the effect.
* \sa T_Glow
*/
glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length)
glow_t *P_SpawnAdjustableGlowingLight(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length)
{
glow_t *g;
P_RemoveLighting(maxsector); // out with the old, in with the new
P_RemoveLighting(sector); // out with the old, in with the new
g = Z_Calloc(sizeof (*g), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &g->thinker);
g->sector = maxsector;
g->minlight = minsector->lightlevel;
g->maxlight = maxsector->lightlevel;
if (g->minlight > g->maxlight)
{
// You mixed them up, you dummy.
INT32 oops = g->minlight;
g->minlight = g->maxlight;
g->maxlight = oops;
}
g->sector = sector;
g->minlight = min(lighta, lightb);
g->maxlight = max(lighta, lightb);
g->thinker.function.acp1 = (actionf_p1)T_Glow;
g->direction = 1;
g->speed = length/4;
g->speed = (INT16)(length/4);
if (g->speed > (g->maxlight - g->minlight)/2) // don't make it ridiculous speed
g->speed = (g->maxlight - g->minlight)/2;
@ -317,7 +301,10 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector,
g->speed = (g->maxlight - g->minlight)/2;
}
maxsector->lightingdata = g;
// Make sure the starting light level is in range.
sector->lightlevel = max(g->minlight, min(g->maxlight, sector->lightlevel));
sector->lightingdata = g;
return g;
}
@ -371,9 +358,10 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean
}
}
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force)
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force, boolean relative)
{
INT32 i;
INT32 realdestvalue;
// search all sectors for ones with tag
TAG_ITER_SECTORS(tag, i)
@ -386,7 +374,9 @@ void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, bool
CONS_Debug(DBG_GAMELOGIC, "Line type 420 Executor: Fade light thinker already exists, timer: %d\n", ((lightlevel_t*)sectors[i].lightingdata)->timer);
continue;
}
P_FadeLightBySector(&sectors[i], destvalue, speed, ticbased);
realdestvalue = relative ? max(0, min(255, sectors[i].lightlevel + destvalue)) : destvalue;
P_FadeLightBySector(&sectors[i], realdestvalue, speed, ticbased);
}
}

View file

@ -148,7 +148,6 @@ boolean P_PlayerShouldUseSpinHeight(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo);
boolean P_IsObjectOnGround(mobj_t *mo);
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_InSpaceSector(mobj_t *mo);
boolean P_InQuicksand(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
@ -373,7 +372,7 @@ void P_NewChaseDir(mobj_t *actor);
boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist);
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward);
void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo);
void P_InternalFlickySetColor(mobj_t *actor, UINT8 color);
#define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0)
void P_InternalFlickyBubble(mobj_t *actor);
void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez);

View file

@ -492,7 +492,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
switch (spring->type)
{
case MT_FAN: // fan
if (zdist > (spring->health << FRACBITS)) // max z distance determined by health (set by map thing angle)
if (zdist > (spring->health << FRACBITS)) // max z distance determined by health (set by map thing args[0])
break;
if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother
break;
@ -505,11 +505,12 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
if (flipval*object->momz > FixedMul(speed, spring->scale))
object->momz = flipval*FixedMul(speed, spring->scale);
if (p && !p->powers[pw_tailsfly]) // doesn't reset anim for Tails' flight
if (p && !p->powers[pw_tailsfly] && !p->powers[pw_carry]) // doesn't reset anim for Tails' flight
{
P_ResetPlayer(p);
if (p->panim != PA_FALL)
P_SetPlayerMobjState(object, S_PLAY_FALL);
P_SetPlayerMobjState(object, S_PLAY_FALL);
P_SetTarget(&object->tracer, spring);
p->powers[pw_carry] = CR_FAN;
}
break;
case MT_STEAM: // Steam
@ -2073,13 +2074,13 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER) && !(thing->flags & MF_NOGRAVITY))
if ((rover->fofflags & (FOF_SWIMMABLE|FOF_GOOWATER)) == (FOF_SWIMMABLE|FOF_GOOWATER) && !(thing->flags & MF_NOGRAVITY))
{
// If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
@ -2118,14 +2119,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (thing->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(thing->player, rover)))
;
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
else if (thing->type == MT_SKIM && (rover->fofflags & FOF_SWIMMABLE))
;
else if (!((rover->flags & FF_BLOCKPLAYER && thing->player)
|| (rover->flags & FF_BLOCKOTHERS && !thing->player)
|| rover->flags & FF_QUICKSAND))
else if (!((rover->fofflags & FOF_BLOCKPLAYER && thing->player)
|| (rover->fofflags & FOF_BLOCKOTHERS && !thing->player)
|| rover->fofflags & FOF_QUICKSAND))
continue;
if (rover->flags & FF_QUICKSAND)
if (rover->fofflags & FOF_QUICKSAND)
{
if (thing->z < topheight && bottomheight < thingtop)
{
@ -2145,15 +2146,15 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
+ ((topheight - bottomheight)/2));
if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
&& !(rover->fofflags & FOF_REVERSEPLATFORM))
{
tmfloorz = tmdropoffz = topheight;
tmfloorrover = rover;
tmfloorslope = *rover->t_slope;
}
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
&& !(rover->fofflags & FOF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->fofflags & FOF_SWIMMABLE)))
{
tmceilingz = tmdrpoffceilz = bottomheight;
tmceilingrover = rover;
@ -2331,7 +2332,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
mapcampointer = thiscam;
if (GETSECSPECIAL(newsubsec->sector->special, 4) == 12)
if (newsubsec->sector->flags & MSF_NOCLIPCAMERA)
{ // Camera noclip on entire sector.
tmfloorz = tmdropoffz = thiscam->z;
tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height;
@ -2371,7 +2372,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERALL) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL);
@ -2443,7 +2444,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (GETSECSPECIAL(polysec->special, 4) == 12)
if (polysec->flags & MSF_NOCLIPCAMERA)
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@ -2711,14 +2712,14 @@ increment_move
if (thing->player)
{
// If using type Section1:13, double the maxstep.
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13)
// If using SSF_DOUBLESTEPUP, double the maxstep.
if (P_PlayerTouchingSectorSpecialFlag(thing->player, SSF_DOUBLESTEPUP)
|| (R_PointInSubsector(x, y)->sector->specialflags & SSF_DOUBLESTEPUP))
maxstep <<= 1;
// If using type Section1:14, no maxstep.
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
// If using SSF_NOSTEPDOWN, no maxstep.
if (P_PlayerTouchingSectorSpecialFlag(thing->player, SSF_NOSTEPDOWN)
|| (R_PointInSubsector(x, y)->sector->specialflags & SSF_NOSTEPDOWN))
maxstep = 0;
// Don't 'step up' while springing,
@ -2729,12 +2730,12 @@ increment_move
}
else if (thing->flags & MF_PUSHABLE)
{
// If using type Section1:13, double the maxstep.
if (GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13)
// If using SSF_DOUBLESTEPUP, double the maxstep.
if (R_PointInSubsector(x, y)->sector->specialflags & SSF_DOUBLESTEPUP)
maxstep <<= 1;
// If using type Section1:14, no maxstep.
if (GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
// If using SSF_NOSTEPDOWN, no maxstep.
if (R_PointInSubsector(x, y)->sector->specialflags & SSF_NOSTEPDOWN)
maxstep = 0;
}
@ -3024,9 +3025,9 @@ static boolean P_ThingHeightClip(mobj_t *thing)
{
rover = (thing->eflags & MFE_VERTICALFLIP) ? oldceilingrover : oldfloorrover;
// Match the Thing's old floorz to an FOF and check for FF_EXISTS
// If ~FF_EXISTS, don't set mobj Z.
if (!rover || ((rover->flags & FF_EXISTS) && (rover->flags & FF_SOLID)))
// Match the Thing's old floorz to an FOF and check for FOF_EXISTS
// If ~FOF_EXISTS, don't set mobj Z.
if (!rover || ((rover->fofflags & FOF_EXISTS) && (rover->fofflags & FOF_SOLID)))
{
hitfloor = bouncing;
if (thing->eflags & MFE_VERTICALFLIP)
@ -3101,7 +3102,7 @@ static void P_HitCameraSlideLine(line_t *ld, camera_t *thiscam)
}
side = P_PointOnLineSide(thiscam->x, thiscam->y, ld);
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
lineangle = ld->angle;
if (side == 1)
lineangle += ANGLE_180;
@ -3147,7 +3148,7 @@ static void P_HitSlideLine(line_t *ld)
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
lineangle = ld->angle;
if (side == 1)
lineangle += ANGLE_180;
@ -3190,7 +3191,7 @@ static void P_HitBounceLine(line_t *ld)
return;
}
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
lineangle = ld->angle;
if (lineangle >= ANGLE_180)
lineangle -= ANGLE_180;
@ -3287,7 +3288,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
for (rover = glidesector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_BLOCKPLAYER))
continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
@ -3403,7 +3404,7 @@ static void PTR_GlideClimbTraverse(line_t *li)
{
for (rover = checksector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || ((rover->flags & FF_BUSTUP) && (slidemo->player->charflags & SF_CANBUSTWALLS)))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_BLOCKPLAYER) || ((rover->fofflags & FOF_BUSTUP) && (slidemo->player->charflags & SF_CANBUSTWALLS)))
continue;
topheight = P_GetFFloorTopZAt (rover, slidemo->x, slidemo->y);
@ -3498,7 +3499,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
// see if it is closer than best so far
if (li->polyobj && slidemo->player)
{
if ((li->polyobj->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS))
if ((li->polyobj->lines[0]->backsector->flags & MSF_TRIGGERSPECIAL_TOUCH) && !(li->polyobj->flags & POF_NOSPECIALS))
P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector);
}
@ -3631,16 +3632,13 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->flags & FF_SWIMMABLE))
if (!(rover->fofflags & FOF_SWIMMABLE))
continue;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 3)
continue;
if (rover->master->flags & ML_BLOCKMONSTERS)
if (rover->master->frontsector->damagetype != SD_LAVA)
continue;
topheight = P_GetFFloorTopZAt(rover, mo->x, mo->y);
@ -4244,8 +4242,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
for (rover = thing->subsector->sector->ffloors; rover; rover = rover->next)
{
if (!(((rover->flags & FF_BLOCKPLAYER) && thing->player)
|| ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS))
if (!(((rover->fofflags & FOF_BLOCKPLAYER) && thing->player)
|| ((rover->fofflags & FOF_BLOCKOTHERS) && !thing->player)) || !(rover->fofflags & FOF_EXISTS))
continue;
topheight = *rover->topheight;
@ -5039,16 +5037,16 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
if ((!(rover->fofflags & FOF_SOLID || rover->fofflags & FOF_QUICKSAND) || (rover->fofflags & FOF_SWIMMABLE)))
continue;
topheight = P_GetFFloorTopZAt (rover, x, y);
bottomheight = P_GetFFloorBottomZAt(rover, x, y);
if (rover->flags & FF_QUICKSAND)
if (rover->fofflags & FOF_QUICKSAND)
{
if (z < topheight && bottomheight < thingtop)
{
@ -5083,16 +5081,16 @@ fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
if ((!(rover->fofflags & FOF_SOLID || rover->fofflags & FOF_QUICKSAND) || (rover->fofflags & FOF_SWIMMABLE)))
continue;
topheight = P_GetFFloorTopZAt (rover, x, y);
bottomheight = P_GetFFloorBottomZAt(rover, x, y);
if (rover->flags & FF_QUICKSAND)
if (rover->fofflags & FOF_QUICKSAND)
{
if (thingtop > bottomheight && topheight > z)
{

View file

@ -374,7 +374,7 @@ void P_CameraLineOpening(line_t *linedef)
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
@ -398,7 +398,7 @@ void P_CameraLineOpening(line_t *linedef)
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
@ -491,7 +491,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
fixed_t thingtop = mobj->z + mobj->height;
// Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4
if (linedef->flags & ML_MIDSOLID
&& !linedef->polyobj // don't do anything for polyobjects! ...for now
) {
side_t *side = &sides[linedef->sidenum[0]];
@ -508,10 +508,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// don't remove this code unless solid midtextures
// on non-solid polyobjects should NEVER happen in the future
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat
texbottom = back->floorheight + side->rowoffset;
textop = back->ceilingheight + side->rowoffset;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
} else if (linedef->flags & ML_MIDTEX) {
texbottom = back->floorheight + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1);
} else {
@ -521,10 +521,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
} else
#endif
{
if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat
texbottom = openbottom + side->rowoffset;
textop = opentop + side->rowoffset;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
} else if (linedef->flags & ML_MIDPEG) {
texbottom = openbottom + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1);
} else {
@ -594,13 +594,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
for (rover = front->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
@ -609,7 +609,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
@ -620,7 +620,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
@ -636,13 +636,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player)
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
@ -651,7 +651,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
@ -662,7 +662,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;

File diff suppressed because it is too large Load diff

View file

@ -118,7 +118,7 @@ typedef enum
// Don't apply gravity (every tic); object will float, keeping current height
// or changing it actively.
MF_NOGRAVITY = 1<<9,
// This object is an ambient sound.
// This object is an ambient sound. Obsolete, but keep this around for backwards compatibility.
MF_AMBIENT = 1<<10,
// Slide this object when it hits a wall.
MF_SLIDEME = 1<<11,

View file

@ -785,7 +785,7 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo)
vertex_t closest;
// calculate angle of line and subtract 90 degrees to get normal
lineangle = R_PointToAngle2(0, 0, line->dx, line->dy) - ANGLE_90;
lineangle = line->angle - ANGLE_90;
lineangle >>= ANGLETOFINESHIFT;
momx = FixedMul(po->thrust, FINECOSINE(lineangle));
momy = FixedMul(po->thrust, FINESINE(lineangle));
@ -963,7 +963,7 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line)
else
Polyobj_pushThing(po, line, mo);
if (mo->player && (po->lines[0]->backsector->flags & SF_TRIGGERSPECIAL_TOUCH) && !(po->flags & POF_NOSPECIALS))
if (mo->player && (po->lines[0]->backsector->flags & MSF_TRIGGERSPECIAL_TOUCH) && !(po->flags & POF_NOSPECIALS))
P_ProcessSpecialSector(mo->player, mo->subsector->sector, po->lines[0]->backsector);
hitflags |= 1;
@ -1060,6 +1060,8 @@ static void Polyobj_rotateLine(line_t *ld)
ld->dx = v2->x - v1->x;
ld->dy = v2->y - v1->y;
ld->angle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
// determine slopetype
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE;
@ -1089,7 +1091,7 @@ static void Polyobj_rotateLine(line_t *ld)
}
// Causes objects resting on top of the rotating polyobject to 'ride' with its movement.
static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, UINT8 turnthings)
static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, boolean turnplayers, boolean turnothers)
{
static INT32 pomovecount = 10000;
INT32 x, y;
@ -1151,7 +1153,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta,
Polyobj_slideThing(mo, newxoff, newyoff);
if (turnthings == 2 || (turnthings == 1 && !mo->player)) {
if ((turnplayers && mo->player) || (turnothers && !mo->player)) {
mo->angle += delta;
if (mo->player)
P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta);
@ -1163,7 +1165,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta,
}
// Rotates a polyobject around its start point.
boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs)
boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolean turnothers, boolean checkmobjs)
{
size_t i;
angle_t angle;
@ -1201,7 +1203,7 @@ boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean c
for (i = 0; i < po->numLines; ++i)
hitflags |= Polyobj_clipThings(po, po->lines[i]);
Polyobj_rotateThings(po, origin, delta, turnthings);
Polyobj_rotateThings(po, origin, delta, turnplayers, turnothers);
}
if (hitflags & 2)
@ -1409,7 +1411,7 @@ void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y)
fixed_t dx, dy;
// first, rotate to the saved angle
Polyobj_rotate(po, angle, false, false);
Polyobj_rotate(po, angle, false, false, false);
// determine component distances to translate
dx = x - po->spawnSpot.x;
@ -1452,7 +1454,7 @@ void T_PolyObjRotate(polyrotate_t *th)
// rotate by 'speed' angle per frame
// if distance == -1, this polyobject rotates perpetually
if (Polyobj_rotate(po, th->speed, th->turnobjs, true) && th->distance != -1)
if (Polyobj_rotate(po, th->speed, th->turnobjs & PTF_PLAYERS, th->turnobjs & PTF_OTHERS, true) && th->distance != -1)
{
INT32 avel = abs(th->speed);
@ -1854,7 +1856,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
// rotate by 'speed' angle per frame
// if distance == -1, this polyobject rotates perpetually
if (Polyobj_rotate(po, th->speed, false, true) && th->distance != -1)
if (Polyobj_rotate(po, th->speed, false, false, true) && th->distance != -1)
{
INT32 avel = abs(th->speed);
@ -1985,7 +1987,7 @@ void T_PolyObjRotDisplace(polyrotdisplace_t *th)
rotangle = FixedMul(th->rotscale, delta);
if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs, true))
if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs & PTF_PLAYERS, th->turnobjs & PTF_OTHERS, true))
th->oldHeights = newheights;
}
@ -2014,7 +2016,7 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata)
return false;
// check for override if this polyobj already has a thinker
if (po->thinker && !prdata->overRide)
if (po->thinker && !(prdata->flags & TMPR_OVERRIDE))
return false;
// create a new thinker
@ -2029,10 +2031,10 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata)
// use Hexen-style byte angles for speed and distance
th->speed = Polyobj_AngSpeed(prdata->speed * prdata->direction);
if (prdata->distance == 360) // 360 means perpetual
if (prdata->flags & TMPR_CONTINUOUS)
th->distance = -1;
else if (prdata->distance == 0) // 0 means 360 degrees
th->distance = 0xffffffff - 1;
else if (prdata->distance == 360)
th->distance = ANGLE_MAX - 1;
else
th->distance = FixedAngle(prdata->distance*FRACUNIT);
@ -2047,7 +2049,11 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata)
oldpo = po;
th->turnobjs = prdata->turnobjs;
th->turnobjs = 0;
if (!(prdata->flags & TMPR_DONTROTATEOTHERS))
th->turnobjs |= PTF_OTHERS;
if (prdata->flags & TMPR_ROTATEPLAYERS)
th->turnobjs |= PTF_PLAYERS;
// apply action to mirroring polyobjects as well
start = 0;

View file

@ -137,7 +137,7 @@ typedef struct polyrotate_s
INT32 polyObjNum; // numeric id of polyobject (avoid C pointers here)
INT32 speed; // speed of movement per frame
INT32 distance; // distance to move
UINT8 turnobjs; // turn objects? 0=no, 1=everything but players, 2=everything
UINT8 turnobjs; // turn objects? PTF_ flags
} polyrotate_t;
typedef struct polymove_s
@ -247,14 +247,27 @@ typedef struct polyfade_s
// Line Activation Data Structures
//
typedef enum
{
TMPR_DONTROTATEOTHERS = 1,
TMPR_ROTATEPLAYERS = 1<<1,
TMPR_CONTINUOUS = 1<<2,
TMPR_OVERRIDE = 1<<3,
} textmappolyrotate_t;
typedef enum
{
PTF_PLAYERS = 1, // Turn players with movement
PTF_OTHERS = 1<<1, // Turn other mobjs with movement
} polyturnflags_e;
typedef struct polyrotdata_s
{
INT32 polyObjNum; // numeric id of polyobject to affect
INT32 direction; // direction of rotation
INT32 speed; // angular speed
INT32 distance; // distance to move
UINT8 turnobjs; // rotate objects being carried?
UINT8 overRide; // if true, will override any action on the object
UINT8 flags; // TMPR_ flags
} polyrotdata_t;
typedef struct polymovedata_s
@ -281,6 +294,20 @@ typedef struct polywaypointdata_s
UINT8 flags; // PWF_ flags
} polywaypointdata_t;
typedef enum
{
TMPV_NOCHANGE = 1,
TMPV_VISIBLE = 1<<1,
TMPV_INVISIBLE = 1<<2,
} textmappolyvisibility_t;
typedef enum
{
TMPT_NOCHANGE = 1,
TMPT_TANGIBLE = 1<<1,
TMPT_INTANGIBLE = 1<<2,
} textmappolytangibility_t;
// polyobject door types
typedef enum
{
@ -322,6 +349,15 @@ typedef struct polyflagdata_s
fixed_t momx;
} polyflagdata_t;
typedef enum
{
TMPF_RELATIVE = 1,
TMPF_OVERRIDE = 1<<1,
TMPF_TICBASED = 1<<2,
TMPF_IGNORECOLLISION = 1<<3,
TMPF_GHOSTFADE = 1<<4,
} textmappolyfade_t;
typedef struct polyfadedata_s
{
INT32 polyObjNum;
@ -337,7 +373,7 @@ typedef struct polyfadedata_s
//
boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs);
boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs);
boolean Polyobj_rotate(polyobj_t *po, angle_t delta, boolean turnplayers, boolean turnothers, boolean checkmobjs);
polyobj_t *Polyobj_GetForNum(INT32 id);
void Polyobj_InitLevel(void);
void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y);

View file

@ -850,6 +850,17 @@ static void P_NetUnArchiveWaypoints(void)
#define SD_TAGLIST 0x01
#define SD_COLORMAP 0x02
#define SD_CRUMBLESTATE 0x04
#define SD_FLOORLIGHT 0x08
#define SD_CEILLIGHT 0x10
#define SD_FLAG 0x20
#define SD_SPECIALFLAG 0x40
#define SD_DIFF4 0x80
//diff4 flags
#define SD_DAMAGETYPE 0x01
#define SD_TRIGGERTAG 0x02
#define SD_TRIGGERER 0x04
#define SD_GRAVITY 0x08
#define LD_FLAG 0x01
#define LD_SPECIAL 0x02
@ -904,7 +915,7 @@ static boolean CheckFFloorDiff(const sector_t *ss)
for (rover = ss->ffloors; rover; rover = rover->next)
{
if (rover->flags != rover->spawnflags
if (rover->fofflags != rover->spawnflags
|| rover->alpha != rover->spawnalpha)
{
return true; // we found an FOF that changed!
@ -924,7 +935,7 @@ static void ArchiveFFloors(const sector_t *ss)
for (rover = ss->ffloors; rover; rover = rover->next)
{
fflr_diff = 0; // reset diff flags
if (rover->flags != rover->spawnflags)
if (rover->fofflags != rover->spawnflags)
fflr_diff |= FD_FLAGS;
if (rover->alpha != rover->spawnalpha)
fflr_diff |= FD_ALPHA;
@ -934,7 +945,7 @@ static void ArchiveFFloors(const sector_t *ss)
WRITEUINT16(save_p, j); // save ffloor "number"
WRITEUINT8(save_p, fflr_diff);
if (fflr_diff & FD_FLAGS)
WRITEUINT32(save_p, rover->flags);
WRITEUINT32(save_p, rover->fofflags);
if (fflr_diff & FD_ALPHA)
WRITEINT16(save_p, rover->alpha);
}
@ -972,7 +983,7 @@ static void UnArchiveFFloors(const sector_t *ss)
fflr_diff = READUINT8(save_p);
if (fflr_diff & FD_FLAGS)
rover->flags = READUINT32(save_p);
rover->fofflags = READUINT32(save_p);
if (fflr_diff & FD_ALPHA)
rover->alpha = READINT16(save_p);
@ -988,11 +999,11 @@ static void ArchiveSectors(void)
size_t i, j;
const sector_t *ss = sectors;
const sector_t *spawnss = spawnsectors;
UINT8 diff, diff2, diff3;
UINT8 diff, diff2, diff3, diff4;
for (i = 0; i < numsectors; i++, ss++, spawnss++)
{
diff = diff2 = diff3 = 0;
diff = diff2 = diff3 = diff4 = 0;
if (ss->floorheight != spawnss->floorheight)
diff |= SD_FLOORHT;
if (ss->ceilingheight != spawnss->ceilingheight)
@ -1031,9 +1042,29 @@ static void ArchiveSectors(void)
if (ss->crumblestate)
diff3 |= SD_CRUMBLESTATE;
if (ss->floorlightlevel != spawnss->floorlightlevel || ss->floorlightabsolute != spawnss->floorlightabsolute)
diff3 |= SD_FLOORLIGHT;
if (ss->ceilinglightlevel != spawnss->ceilinglightlevel || ss->ceilinglightabsolute != spawnss->ceilinglightabsolute)
diff3 |= SD_CEILLIGHT;
if (ss->flags != spawnss->flags)
diff3 |= SD_FLAG;
if (ss->specialflags != spawnss->specialflags)
diff3 |= SD_SPECIALFLAG;
if (ss->damagetype != spawnss->damagetype)
diff4 |= SD_DAMAGETYPE;
if (ss->triggertag != spawnss->triggertag)
diff4 |= SD_TRIGGERTAG;
if (ss->triggerer != spawnss->triggerer)
diff4 |= SD_TRIGGERER;
if (ss->gravity != spawnss->gravity)
diff4 |= SD_GRAVITY;
if (ss->ffloors && CheckFFloorDiff(ss))
diff |= SD_FFLOORS;
if (diff4)
diff3 |= SD_DIFF4;
if (diff3)
diff2 |= SD_DIFF3;
@ -1048,6 +1079,8 @@ static void ArchiveSectors(void)
WRITEUINT8(save_p, diff2);
if (diff2 & SD_DIFF3)
WRITEUINT8(save_p, diff3);
if (diff3 & SD_DIFF4)
WRITEUINT8(save_p, diff4);
if (diff & SD_FLOORHT)
WRITEFIXED(save_p, ss->floorheight);
if (diff & SD_CEILHT)
@ -1084,6 +1117,28 @@ static void ArchiveSectors(void)
// returns existing index if already added, or appends to net_colormaps and returns new index
if (diff3 & SD_CRUMBLESTATE)
WRITEINT32(save_p, ss->crumblestate);
if (diff3 & SD_FLOORLIGHT)
{
WRITEINT16(save_p, ss->floorlightlevel);
WRITEUINT8(save_p, ss->floorlightabsolute);
}
if (diff3 & SD_CEILLIGHT)
{
WRITEINT16(save_p, ss->ceilinglightlevel);
WRITEUINT8(save_p, ss->ceilinglightabsolute);
}
if (diff3 & SD_FLAG)
WRITEUINT32(save_p, ss->flags);
if (diff3 & SD_SPECIALFLAG)
WRITEUINT32(save_p, ss->specialflags);
if (diff4 & SD_DAMAGETYPE)
WRITEUINT8(save_p, ss->damagetype);
if (diff4 & SD_TRIGGERTAG)
WRITEINT16(save_p, ss->triggertag);
if (diff4 & SD_TRIGGERER)
WRITEUINT8(save_p, ss->triggerer);
if (diff4 & SD_GRAVITY)
WRITEFIXED(save_p, ss->gravity);
if (diff & SD_FFLOORS)
ArchiveFFloors(ss);
}
@ -1095,7 +1150,7 @@ static void ArchiveSectors(void)
static void UnArchiveSectors(void)
{
UINT16 i, j;
UINT8 diff, diff2, diff3;
UINT8 diff, diff2, diff3, diff4;
for (;;)
{
i = READUINT16(save_p);
@ -1115,6 +1170,10 @@ static void UnArchiveSectors(void)
diff3 = READUINT8(save_p);
else
diff3 = 0;
if (diff3 & SD_DIFF4)
diff4 = READUINT8(save_p);
else
diff4 = 0;
if (diff & SD_FLOORHT)
sectors[i].floorheight = READFIXED(save_p);
@ -1175,6 +1234,31 @@ static void UnArchiveSectors(void)
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p));
if (diff3 & SD_CRUMBLESTATE)
sectors[i].crumblestate = READINT32(save_p);
if (diff3 & SD_FLOORLIGHT)
{
sectors[i].floorlightlevel = READINT16(save_p);
sectors[i].floorlightabsolute = READUINT8(save_p);
}
if (diff3 & SD_CEILLIGHT)
{
sectors[i].ceilinglightlevel = READINT16(save_p);
sectors[i].ceilinglightabsolute = READUINT8(save_p);
}
if (diff3 & SD_FLAG)
{
sectors[i].flags = READUINT32(save_p);
CheckForReverseGravity |= (sectors[i].flags & MSF_GRAVITYFLIP);
}
if (diff3 & SD_SPECIALFLAG)
sectors[i].specialflags = READUINT32(save_p);
if (diff4 & SD_DAMAGETYPE)
sectors[i].damagetype = READUINT8(save_p);
if (diff4 & SD_TRIGGERTAG)
sectors[i].triggertag = READINT16(save_p);
if (diff4 & SD_TRIGGERER)
sectors[i].triggerer = READUINT8(save_p);
if (diff4 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p);
if (diff & SD_FFLOORS)
UnArchiveFFloors(&sectors[i]);
@ -1985,7 +2069,6 @@ static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type)
for (i = 0; i < MAXPLAYERS; i++)
{
WRITECHAR(save_p, ht->playersInArea[i]);
WRITECHAR(save_p, ht->playersOnArea[i]);
}
WRITECHAR(save_p, ht->triggerOnExit);
}
@ -2013,14 +2096,12 @@ static void SaveCeilingThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, ht->bottomheight);
WRITEFIXED(save_p, ht->topheight);
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->oldspeed);
WRITEFIXED(save_p, ht->delay);
WRITEFIXED(save_p, ht->delaytimer);
WRITEUINT8(save_p, ht->crush);
WRITEINT32(save_p, ht->texture);
WRITEINT32(save_p, ht->direction);
WRITEINT32(save_p, ht->tag);
WRITEINT32(save_p, ht->olddirection);
WRITEINT16(save_p, ht->tag);
WRITEFIXED(save_p, ht->origspeed);
WRITEFIXED(save_p, ht->sourceline);
}
@ -2039,6 +2120,8 @@ static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, ht->origspeed);
WRITEFIXED(save_p, ht->delay);
WRITEFIXED(save_p, ht->delaytimer);
WRITEINT16(save_p, ht->tag);
WRITEFIXED(save_p, ht->sourceline);
}
static void SaveLightflashThinker(const thinker_t *th, const UINT8 type)
@ -2056,8 +2139,8 @@ static void SaveStrobeThinker(const thinker_t *th, const UINT8 type)
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->count);
WRITEINT32(save_p, ht->minlight);
WRITEINT32(save_p, ht->maxlight);
WRITEINT16(save_p, ht->minlight);
WRITEINT16(save_p, ht->maxlight);
WRITEINT32(save_p, ht->darktime);
WRITEINT32(save_p, ht->brighttime);
}
@ -2067,10 +2150,10 @@ static void SaveGlowThinker(const thinker_t *th, const UINT8 type)
const glow_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->minlight);
WRITEINT32(save_p, ht->maxlight);
WRITEINT32(save_p, ht->direction);
WRITEINT32(save_p, ht->speed);
WRITEINT16(save_p, ht->minlight);
WRITEINT16(save_p, ht->maxlight);
WRITEINT16(save_p, ht->direction);
WRITEINT16(save_p, ht->speed);
}
static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type)
@ -2080,8 +2163,8 @@ static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->count);
WRITEINT32(save_p, ht->resetcount);
WRITEINT32(save_p, ht->maxlight);
WRITEINT32(save_p, ht->minlight);
WRITEINT16(save_p, ht->maxlight);
WRITEINT16(save_p, ht->minlight);
}
static void SaveElevatorThinker(const thinker_t *th, const UINT8 type)
@ -2155,13 +2238,9 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type)
const pusher_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEINT32(save_p, ht->x_mag);
WRITEINT32(save_p, ht->y_mag);
WRITEINT32(save_p, ht->magnitude);
WRITEINT32(save_p, ht->radius);
WRITEINT32(save_p, ht->x);
WRITEINT32(save_p, ht->y);
WRITEINT32(save_p, ht->z);
WRITEFIXED(save_p, ht->x_mag);
WRITEFIXED(save_p, ht->y_mag);
WRITEFIXED(save_p, ht->z_mag);
WRITEINT32(save_p, ht->affectee);
WRITEUINT8(save_p, ht->roverpusher);
WRITEINT32(save_p, ht->referrer);
@ -2259,18 +2338,30 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type)
WRITEUINT8(save_p, ht->type);
}
static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type)
static inline void SaveDynamicLineSlopeThinker(const thinker_t *th, const UINT8 type)
{
const dynplanethink_t* ht = (const void*)th;
const dynlineplanethink_t* ht = (const void*)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEUINT32(save_p, SaveSlope(ht->slope));
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEFIXED(save_p, ht->extent);
}
WRITEMEM(save_p, ht->tags, sizeof(ht->tags));
WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
static inline void SaveDynamicVertexSlopeThinker(const thinker_t *th, const UINT8 type)
{
size_t i;
const dynvertexplanethink_t* ht = (const void*)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSlope(ht->slope));
for (i = 0; i < 3; i++)
WRITEUINT32(save_p, SaveSector(ht->secs[i]));
WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
WRITEMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights));
WRITEMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights));
WRITEUINT8(save_p, ht->relative);
}
static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type)
@ -2595,12 +2686,12 @@ static void P_NetArchiveThinkers(void)
}
else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine)
{
SaveDynamicSlopeThinker(th, tc_dynslopeline);
SaveDynamicLineSlopeThinker(th, tc_dynslopeline);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeVert)
{
SaveDynamicSlopeThinker(th, tc_dynslopevert);
SaveDynamicVertexSlopeThinker(th, tc_dynslopevert);
continue;
}
#ifdef PARANOIA
@ -2715,7 +2806,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
{
UINT16 spawnpointnum = READUINT16(save_p);
if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
if (mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
{
P_SpawnHoop(&mapthings[spawnpointnum]);
return NULL;
@ -3090,7 +3181,6 @@ static thinker_t* LoadEachTimeThinker(actionf_p1 thinker)
for (i = 0; i < MAXPLAYERS; i++)
{
ht->playersInArea[i] = READCHAR(save_p);
ht->playersOnArea[i] = READCHAR(save_p);
}
ht->triggerOnExit = READCHAR(save_p);
return &ht->thinker;
@ -3120,14 +3210,12 @@ static thinker_t* LoadCeilingThinker(actionf_p1 thinker)
ht->bottomheight = READFIXED(save_p);
ht->topheight = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->oldspeed = READFIXED(save_p);
ht->delay = READFIXED(save_p);
ht->delaytimer = READFIXED(save_p);
ht->crush = READUINT8(save_p);
ht->texture = READINT32(save_p);
ht->direction = READINT32(save_p);
ht->tag = READINT32(save_p);
ht->olddirection = READINT32(save_p);
ht->tag = READINT16(save_p);
ht->origspeed = READFIXED(save_p);
ht->sourceline = READFIXED(save_p);
if (ht->sector)
@ -3149,6 +3237,8 @@ static thinker_t* LoadFloormoveThinker(actionf_p1 thinker)
ht->origspeed = READFIXED(save_p);
ht->delay = READFIXED(save_p);
ht->delaytimer = READFIXED(save_p);
ht->tag = READINT16(save_p);
ht->sourceline = READFIXED(save_p);
if (ht->sector)
ht->sector->floordata = ht;
return &ht->thinker;
@ -3172,8 +3262,8 @@ static thinker_t* LoadStrobeThinker(actionf_p1 thinker)
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->count = READINT32(save_p);
ht->minlight = READINT32(save_p);
ht->maxlight = READINT32(save_p);
ht->minlight = READINT16(save_p);
ht->maxlight = READINT16(save_p);
ht->darktime = READINT32(save_p);
ht->brighttime = READINT32(save_p);
if (ht->sector)
@ -3186,10 +3276,10 @@ static thinker_t* LoadGlowThinker(actionf_p1 thinker)
glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->minlight = READINT32(save_p);
ht->maxlight = READINT32(save_p);
ht->direction = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->minlight = READINT16(save_p);
ht->maxlight = READINT16(save_p);
ht->direction = READINT16(save_p);
ht->speed = READINT16(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
@ -3202,8 +3292,8 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker)
ht->sector = LoadSector(READUINT32(save_p));
ht->count = READINT32(save_p);
ht->resetcount = READINT32(save_p);
ht->maxlight = READINT32(save_p);
ht->minlight = READINT32(save_p);
ht->maxlight = READINT16(save_p);
ht->minlight = READINT16(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
@ -3295,19 +3385,14 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker)
pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->x_mag = READINT32(save_p);
ht->y_mag = READINT32(save_p);
ht->magnitude = READINT32(save_p);
ht->radius = READINT32(save_p);
ht->x = READINT32(save_p);
ht->y = READINT32(save_p);
ht->z = READINT32(save_p);
ht->x_mag = READFIXED(save_p);
ht->y_mag = READFIXED(save_p);
ht->z_mag = READFIXED(save_p);
ht->affectee = READINT32(save_p);
ht->roverpusher = READUINT8(save_p);
ht->referrer = READINT32(save_p);
ht->exclusive = READINT32(save_p);
ht->slider = READINT32(save_p);
ht->source = P_GetPushThing(ht->affectee);
return &ht->thinker;
}
@ -3431,17 +3516,31 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker)
return &ht->thinker;
}
static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker)
static inline thinker_t* LoadDynamicLineSlopeThinker(actionf_p1 thinker)
{
dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
dynlineplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->slope = LoadSlope(READUINT32(save_p));
ht->sourceline = LoadLine(READUINT32(save_p));
ht->extent = READFIXED(save_p);
READMEM(save_p, ht->tags, sizeof(ht->tags));
return &ht->thinker;
}
static inline thinker_t* LoadDynamicVertexSlopeThinker(actionf_p1 thinker)
{
size_t i;
dynvertexplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->slope = LoadSlope(READUINT32(save_p));
for (i = 0; i < 3; i++)
ht->secs[i] = LoadSector(READUINT32(save_p));
READMEM(save_p, ht->vex, sizeof(ht->vex));
READMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights));
READMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights));
ht->relative = READUINT8(save_p);
return &ht->thinker;
}
@ -3754,11 +3853,11 @@ static void P_NetUnArchiveThinkers(void)
break;
case tc_dynslopeline:
th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeLine);
th = LoadDynamicLineSlopeThinker((actionf_p1)T_DynamicSlopeLine);
break;
case tc_dynslopevert:
th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeVert);
th = LoadDynamicVertexSlopeThinker((actionf_p1)T_DynamicSlopeVert);
break;
case tc_scroll:

File diff suppressed because it is too large Load diff

View file

@ -107,7 +107,7 @@ boolean P_AddFolder(const char *folderpath);
boolean P_RunSOC(const char *socfilename);
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num);
void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num);
void P_WriteThings(void);
//void P_WriteThings(void);
size_t P_PrecacheLevelFlats(void);
void P_AllocMapHeader(INT16 i);
@ -122,5 +122,6 @@ void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);
UINT8 P_HasGrades(INT16 map, UINT8 mare);
UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade);
UINT32 P_GetScoreForGradeOverall(INT16 map, UINT8 grade);
#endif

View file

@ -306,8 +306,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
// check front sector's FOFs first
for (rover = front->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS)
|| !(rover->flags & FF_RENDERSIDES) || (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
if (!(rover->fofflags & FOF_EXISTS)
|| !(rover->fofflags & FOF_RENDERSIDES) || (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG)))
{
continue;
}
@ -322,8 +322,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
// check back sector's FOFs as well
for (rover = back->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS)
|| !(rover->flags & FF_RENDERSIDES) || (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
if (!(rover->fofflags & FOF_EXISTS)
|| !(rover->fofflags & FOF_RENDERSIDES) || (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG)))
{
continue;
}
@ -451,8 +451,8 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
// Allow sight through water, fog, etc.
/// \todo Improve by checking fog density/translucency
/// and setting a sight limit.
if (!(rover->flags & FF_EXISTS)
|| !(rover->flags & FF_RENDERPLANES) || (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
if (!(rover->fofflags & FOF_EXISTS)
|| !(rover->fofflags & FOF_RENDERPLANES) || (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG)))
{
continue;
}
@ -470,10 +470,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
return false;
}
if (rover->flags & FF_SOLID)
if (rover->fofflags & FOF_SOLID)
continue; // shortcut since neither mobj can be inside the 3dfloor
if (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))
if (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))
{
if (los.sightzstart >= topz1 && t2->z + t2->height < topz2)
return false; // blocked by upper outside plane
@ -482,7 +482,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
return false; // blocked by lower outside plane
}
if (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)
if (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)
{
if (los.sightzstart < topz1 && t2->z >= topz2)
return false; // blocked by upper inside plane

View file

@ -121,7 +121,7 @@ static void ReconfigureViaConstants (pslope_t *slope, const fixed_t a, const fix
}
/// Recalculate dynamic slopes.
void T_DynamicSlopeLine (dynplanethink_t* th)
void T_DynamicSlopeLine (dynlineplanethink_t* th)
{
pslope_t* slope = th->slope;
line_t* srcline = th->sourceline;
@ -161,47 +161,56 @@ void T_DynamicSlopeLine (dynplanethink_t* th)
}
/// Mapthing-defined
void T_DynamicSlopeVert (dynplanethink_t* th)
void T_DynamicSlopeVert (dynvertexplanethink_t* th)
{
pslope_t* slope = th->slope;
size_t i;
INT32 l;
for (i = 0; i < 3; i++) {
l = Tag_FindLineSpecial(799, th->tags[i]);
if (l != -1) {
th->vex[i].z = lines[l].frontsector->floorheight;
}
for (i = 0; i < 3; i++)
{
if (th->relative & (1 << i))
th->vex[i].z = th->origvecheights[i] + (th->secs[i]->floorheight - th->origsecheights[i]);
else
th->vex[i].z = 0;
th->vex[i].z = th->secs[i]->floorheight;
}
ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]);
}
static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent, const INT16 tags[3], const vector3_t vx[3])
static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent)
{
dynplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL);
switch (type)
{
case DP_VERTEX:
th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert;
memcpy(th->tags, tags, sizeof(th->tags));
memcpy(th->vex, vx, sizeof(th->vex));
break;
default:
th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine;
th->sourceline = sourceline;
th->extent = extent;
}
dynlineplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL);
th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine;
th->slope = slope;
th->type = type;
th->sourceline = sourceline;
th->extent = extent;
P_AddThinker(THINK_DYNSLOPE, &th->thinker);
}
static inline void P_AddDynVertexSlopeThinker (pslope_t* slope, const INT16 tags[3], const vector3_t vx[3])
{
dynvertexplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL);
size_t i;
INT32 l;
th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert;
th->slope = slope;
for (i = 0; i < 3; i++) {
l = Tag_FindLineSpecial(799, tags[i]);
if (l == -1)
{
Z_Free(th);
return;
}
th->secs[i] = lines[l].frontsector;
th->vex[i] = vx[i];
th->origsecheights[i] = lines[l].frontsector->floorheight;
th->origvecheights[i] = vx[i].z;
if (lines[l].args[0])
th->relative |= 1<<i;
}
P_AddThinker(THINK_DYNSLOPE, &th->thinker);
}
/// Create a new slope and add it to the slope list.
static inline pslope_t* Slope_Add (const UINT8 flags)
@ -268,6 +277,27 @@ static fixed_t GetExtent(sector_t *sector, line_t *line)
return fardist;
}
static boolean P_CopySlope(pslope_t** toslope, pslope_t* fromslope)
{
if (*toslope || !fromslope)
return true;
*toslope = fromslope;
return true;
}
static void P_UpdateHasSlope(sector_t *sec)
{
size_t i;
sec->hasslope = true;
// if this is an FOF control sector, make sure any target sectors also are marked as having slopes
if (sec->numattached)
for (i = 0; i < sec->numattached; i++)
sectors[sec->attached[i]].hasslope = true;
}
/// Creates one or more slopes based on the given line type and front/back sectors.
static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
{
@ -358,7 +388,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
P_CalculateSlopeNormal(fslope);
if (spawnthinker && (flags & SL_DYNAMIC))
P_AddDynSlopeThinker(fslope, DP_FRONTFLOOR, line, extent, NULL, NULL);
P_AddDynLineSlopeThinker(fslope, DP_FRONTFLOOR, line, extent);
}
if(frontceil)
{
@ -375,7 +405,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
P_CalculateSlopeNormal(cslope);
if (spawnthinker && (flags & SL_DYNAMIC))
P_AddDynSlopeThinker(cslope, DP_FRONTCEIL, line, extent, NULL, NULL);
P_AddDynLineSlopeThinker(cslope, DP_FRONTCEIL, line, extent);
}
}
if(backfloor || backceil)
@ -415,7 +445,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
P_CalculateSlopeNormal(fslope);
if (spawnthinker && (flags & SL_DYNAMIC))
P_AddDynSlopeThinker(fslope, DP_BACKFLOOR, line, extent, NULL, NULL);
P_AddDynLineSlopeThinker(fslope, DP_BACKFLOOR, line, extent);
}
if(backceil)
{
@ -432,9 +462,26 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker)
P_CalculateSlopeNormal(cslope);
if (spawnthinker && (flags & SL_DYNAMIC))
P_AddDynSlopeThinker(cslope, DP_BACKCEIL, line, extent, NULL, NULL);
P_AddDynLineSlopeThinker(cslope, DP_BACKCEIL, line, extent);
}
}
if (line->args[2] & TMSL_COPY)
{
if (frontfloor)
P_CopySlope(&line->backsector->f_slope, line->frontsector->f_slope);
if (backfloor)
P_CopySlope(&line->frontsector->f_slope, line->backsector->f_slope);
if (frontceil)
P_CopySlope(&line->backsector->c_slope, line->frontsector->c_slope);
if (backceil)
P_CopySlope(&line->frontsector->c_slope, line->backsector->c_slope);
if (backfloor || backceil)
P_UpdateHasSlope(line->frontsector);
if (frontfloor || frontceil)
P_UpdateHasSlope(line->backsector);
}
}
/// Creates a new slope from three mapthings with the specified IDs
@ -469,14 +516,14 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
vx[i].x = mt->x << FRACBITS;
vx[i].y = mt->y << FRACBITS;
vx[i].z = mt->z << FRACBITS;
if (!mt->extrainfo)
if (!mt->args[0])
vx[i].z += R_PointInSubsector(vx[i].x, vx[i].y)->sector->floorheight;
}
ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]);
if (spawnthinker && (flags & SL_DYNAMIC))
P_AddDynSlopeThinker(ret, DP_VERTEX, NULL, 0, tags, vx);
P_AddDynVertexSlopeThinker(ret, tags, vx);
return ret;
}
@ -591,27 +638,6 @@ static boolean P_SetSlopeFromTag(sector_t *sec, INT32 tag, boolean ceiling)
return false;
}
static boolean P_CopySlope(pslope_t **toslope, pslope_t *fromslope)
{
if (*toslope || !fromslope)
return true;
*toslope = fromslope;
return true;
}
static void P_UpdateHasSlope(sector_t *sec)
{
size_t i;
sec->hasslope = true;
// if this is an FOF control sector, make sure any target sectors also are marked as having slopes
if (sec->numattached)
for (i = 0; i < sec->numattached; i++)
sectors[sec->attached[i]].hasslope = true;
}
//
// P_CopySectorSlope
//
@ -701,9 +727,6 @@ void P_SpawnSlopes(const boolean fromsave) {
for (i = 0; i < numlines; i++)
switch (lines[i].special)
{
case 700:
if (lines[i].flags & ML_TFERLINE) P_CopySectorSlope(&lines[i]);
break;
case 720:
P_CopySectorSlope(&lines[i]);
default:

View file

@ -44,7 +44,8 @@ typedef enum
typedef enum
{
TMSL_NOPHYSICS = 1,
TMSL_DYNAMIC = 2,
TMSL_DYNAMIC = 1<<1,
TMSL_COPY = 1<<2,
} textmapslopeflags_t;
void P_LinkSlopeThinkers (void);
@ -95,26 +96,29 @@ typedef enum {
DP_FRONTCEIL,
DP_BACKFLOOR,
DP_BACKCEIL,
DP_VERTEX
} dynplanetype_t;
/// Permit slopes to be dynamically altered through a thinker.
typedef struct
{
thinker_t thinker;
pslope_t* slope;
pslope_t *slope;
dynplanetype_t type;
// Used by line slopes.
line_t* sourceline;
line_t *sourceline;
fixed_t extent;
} dynlineplanethink_t;
// Used by mapthing vertex slopes.
INT16 tags[3];
typedef struct
{
thinker_t thinker;
pslope_t *slope;
sector_t *secs[3];
vector3_t vex[3];
} dynplanethink_t;
fixed_t origsecheights[3];
fixed_t origvecheights[3];
UINT8 relative;
} dynvertexplanethink_t;
void T_DynamicSlopeLine (dynplanethink_t* th);
void T_DynamicSlopeVert (dynplanethink_t* th);
void T_DynamicSlopeLine (dynlineplanethink_t* th);
void T_DynamicSlopeVert (dynvertexplanethink_t* th);
#endif // #ifndef P_SLOPES_H__

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,450 @@ extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpo
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
#define SCROLL_SHIFT 5
typedef enum
{
TMM_DOUBLESIZE = 1,
TMM_SILENT = 1<<1,
TMM_ALLOWYAWCONTROL = 1<<2,
TMM_SWING = 1<<3,
TMM_MACELINKS = 1<<4,
TMM_CENTERLINK = 1<<5,
TMM_CLIP = 1<<6,
TMM_ALWAYSTHINK = 1<<7,
} textmapmaceflags_t;
typedef enum
{
TMDA_BOTTOMOFFSET = 1,
TMDA_BOTTOM = 1<<1,
TMDA_MIDDLE = 1<<2,
TMDA_TOP = 1<<3,
} textmapdronealignment_t;
typedef enum
{
TMSF_RETRACTED = 1,
TMSF_INTANGIBLE = 1<<1,
} textmapspikeflags_t;
typedef enum
{
TMFF_AIMLESS = 1,
TMFF_STATIONARY = 1<<1,
TMFF_HOP = 1<<2,
} textmapflickyflags_t;
typedef enum
{
TMFH_NOFLAME = 1,
TMFH_CORONA = 1<<1,
} textmapflameholderflags_t;
typedef enum
{
TMDS_NOGRAVITY = 1,
TMDS_ROTATEEXTRA = 1<<1,
} textmapdiagonalspringflags_t;
typedef enum
{
TMF_INVISIBLE = 1,
TMF_NODISTANCECHECK = 1<<1,
} textmapfanflags_t;
typedef enum
{
TMGD_BACK = 0,
TMGD_RIGHT = 1,
TMGD_LEFT = 2,
} textmapguarddirection_t;
typedef enum
{
TMNI_BONUSONLY = 1,
TMNI_REVEAL = 1<<1,
} textmapnightsitem_t;
typedef enum
{
TMP_NORMAL = 0,
TMP_SLIDE = 1,
TMP_IMMOVABLE = 2,
TMP_CLASSIC = 3,
} textmappushabletype_t;
typedef enum
{
TMED_NONE = 0,
TMED_RIGHT = 1,
TMED_LEFT = 2,
} textmapeggrobodirection_t;
typedef enum
{
TMMR_SAME = 0,
TMMR_WEAK = 1,
TMMR_STRONG = 2,
} textmapmonitorrespawn_t;
typedef enum
{
TMF_GRAYSCALE = 1,
TMF_SKIPINTRO = 1<<1,
} textmapfangflags_t;
typedef enum
{
TMB_NODEATHFLING = 1,
TMB_BARRIER = 1<<1,
} textmapbrakflags_t;
typedef enum
{
TMEF_SKIPTALLY = 1,
TMEF_EMERALDCHECK = 1<<1,
} textmapexitflags_t;
typedef enum
{
TMSP_NOTELEPORT = 1,
TMSP_FORCESPIN = 1<<1,
} textmapspeedpadflags_t;
//FOF flags
typedef enum
{
TMFA_NOPLANES = 1,
TMFA_NOSIDES = 1<<1,
TMFA_INSIDES = 1<<2,
TMFA_ONLYINSIDES = 1<<3,
TMFA_NOSHADE = 1<<4,
TMFA_SPLAT = 1<<5,
} textmapfofappearance_t;
typedef enum
{
TMFT_INTANGIBLETOP = 1,
TMFT_INTANGIBLEBOTTOM = 1<<1,
TMFT_DONTBLOCKPLAYER = 1<<2,
TMFT_VISIBLEFROMINSIDE = (TMFT_INTANGIBLETOP|TMFT_INTANGIBLEBOTTOM|TMFT_DONTBLOCKPLAYER),
TMFT_DONTBLOCKOTHERS = 1<<3,
TMFT_INTANGIBLE = (TMFT_DONTBLOCKPLAYER|TMFT_DONTBLOCKOTHERS),
} textmapfoftangibility_t;
typedef enum
{
TMFW_NOSIDES = 1,
TMFW_DOUBLESHADOW = 1<<1,
TMFW_COLORMAPONLY = 1<<2,
TMFW_NORIPPLE = 1<<3,
TMFW_GOOWATER = 1<<4,
TMFW_SPLAT = 1<<5,
} textmapfofwater_t;
typedef enum
{
TMFB_REVERSE = 1,
TMFB_SPINDASH = 1<<1,
TMFB_DYNAMIC = 1<<2,
} textmapfofbobbing_t;
typedef enum
{
TMFC_NOSHADE = 1,
TMFC_NORETURN = 1<<1,
TMFC_AIRBOB = 1<<2,
TMFC_FLOATBOB = 1<<3,
TMFC_SPLAT = 1<<4,
} textmapfofcrumbling_t;
typedef enum
{
TMFR_REVERSE = 1,
TMFR_SPINDASH = 1<<1,
} textmapfofrising_t;
typedef enum
{
TMFM_BRICK = 1,
TMFM_INVISIBLE = 1<<1,
} textmapfofmario_t;
typedef enum
{
TMFB_TOUCH,
TMFB_SPIN,
TMFB_REGULAR,
TMFB_STRONG,
} textmapfofbusttype_t;
typedef enum
{
TMFB_PUSHABLES = 1,
TMFB_EXECUTOR = 1<<1,
TMFB_ONLYBOTTOM = 1<<2,
TMFB_SPLAT = 1<<3,
} textmapfofbustflags_t;
typedef enum
{
TMFL_NOBOSSES = 1,
TMFL_SPLAT = 1<<1,
} textmapfoflaserflags_t;
typedef enum
{
TMT_CONTINUOUS = 0,
TMT_ONCE = 1,
TMT_EACHTIMEMASK = TMT_ONCE,
TMT_EACHTIMEENTER = 2,
TMT_EACHTIMEENTERANDEXIT = 3,
} textmaptriggertype_t;
typedef enum
{
TMXT_CONTINUOUS = 0,
TMXT_EACHTIMEMASK = TMXT_CONTINUOUS,
TMXT_EACHTIMEENTER = 1,
TMXT_EACHTIMEENTERANDEXIT = 2,
} textmapxtriggertype_t;
typedef enum
{
TMF_HASALL = 0,
TMF_HASANY = 1,
TMF_HASEXACTLY = 2,
TMF_DOESNTHAVEALL = 3,
TMF_DOESNTHAVEANY = 4,
} textmapflagcheck_t;
typedef enum
{
TMT_RED = 0,
TMT_BLUE = 1,
} textmapteam_t;
typedef enum
{
TMC_EQUAL = 0,
TMC_LTE = 1,
TMC_GTE = 2,
} textmapcomparison_t;
typedef enum
{
TMNP_FASTEST = 0,
TMNP_SLOWEST = 1,
TMNP_TRIGGERER = 2,
} textmapnightsplayer_t;
typedef enum
{
TMN_ALWAYS = 0,
TMN_FROMNONIGHTS = 1,
TMN_FROMNIGHTS = 2,
} textmapnighterizeoptions_t;
typedef enum
{
TMN_BONUSLAPS = 1,
TMN_LEVELCOMPLETION = 1<<2,
} textmapnightserizeflags_t;
typedef enum
{
TMD_ALWAYS = 0,
TMD_NOBODYNIGHTS = 1,
TMD_SOMEBODYNIGHTS = 2,
} textmapdenighterizeoptions_t;
typedef enum
{
TMS_IFENOUGH = 0,
TMS_IFNOTENOUGH = 1,
TMS_ALWAYS = 2,
} textmapspherescheck_t;
typedef enum
{
TMI_BONUSLAPS = 1,
TMI_ENTER = 1<<2,
} textmapideyacaptureflags_t;
typedef enum
{
TMP_FLOOR = 0,
TMP_CEILING = 1,
TMP_BOTH = 2,
} textmapplanes_t;
typedef enum
{
TMT_ADD = 0,
TMT_REMOVE = 1,
TMT_REPLACEFIRST = 2,
TMT_TRIGGERTAG = 3,
} textmaptagoptions_t;
typedef enum
{
TMT_SILENT = 1,
TMT_KEEPANGLE = 1<<1,
TMT_KEEPMOMENTUM = 1<<2,
TMT_RELATIVE = 1<<3,
} textmapteleportflags_t;
typedef enum
{
TMM_ALLPLAYERS = 1,
TMM_OFFSET = 1<<1,
TMM_FADE = 1<<2,
TMM_NORELOAD = 1<<3,
TMM_FORCERESET = 1<<4,
TMM_NOLOOP = 1<<5,
} textmapmusicflags_t;
typedef enum
{
TMSS_TRIGGERMOBJ = 0,
TMSS_TRIGGERSECTOR = 1,
TMSS_NOWHERE = 2,
TMSS_TAGGEDSECTOR = 3,
} textmapsoundsource_t;
typedef enum
{
TMSL_EVERYONE = 0,
TMSL_TRIGGERER = 1,
TMSL_TAGGEDSECTOR = 2,
} textmapsoundlistener_t;
typedef enum
{
TML_SECTOR = 0,
TML_FLOOR = 1,
TML_CEILING = 2,
} textmaplightareas_t;
typedef enum
{
TMLC_NOSECTOR = 1,
TMLC_NOFLOOR = 1<<1,
TMLC_NOCEILING = 1<<2,
} textmaplightcopyflags_t;
typedef enum
{
TMF_RELATIVE = 1,
TMF_OVERRIDE = 1<<1,
TMF_TICBASED = 1<<2,
} textmapfadeflags_t;
typedef enum
{
TMB_USETARGET = 1,
TMB_SYNC = 1<<1,
} textmapblinkinglightflags_t;
typedef enum
{
TMFR_NORETURN = 1,
TMFR_CHECKFLAG = 1<<1,
} textmapfofrespawnflags_t;
typedef enum
{
TMST_RELATIVE = 1,
TMST_DONTDOTRANSLUCENT = 1<<1,
} textmapsettranslucencyflags_t;
typedef enum
{
TMFT_RELATIVE = 1,
TMFT_OVERRIDE = 1<<1,
TMFT_TICBASED = 1<<2,
TMFT_IGNORECOLLISION = 1<<3,
TMFT_GHOSTFADE = 1<<4,
TMFT_DONTDOTRANSLUCENT = 1<<5,
TMFT_DONTDOEXISTS = 1<<6,
TMFT_DONTDOLIGHTING = 1<<7,
TMFT_DONTDOCOLORMAP = 1<<8,
TMFT_USEEXACTALPHA = 1<<9,
} textmapfadetranslucencyflags_t;
typedef enum
{
TMS_VIEWPOINT = 0,
TMS_CENTERPOINT = 1,
TMS_BOTH = 2,
} textmapskybox_t;
typedef enum
{
TMP_CLOSE = 1,
TMP_RUNPOSTEXEC = 1<<1,
TMP_CALLBYNAME = 1<<2,
TMP_KEEPCONTROLS = 1<<3,
TMP_KEEPREALTIME = 1<<4,
//TMP_ALLPLAYERS = 1<<5,
//TMP_FREEZETHINKERS = 1<<6,
} textmappromptflags_t;
typedef enum
{
TMF_NOCHANGE = 0,
TMF_ADD = 1,
TMF_REMOVE = 2,
} textmapsetflagflags_t;
typedef enum
{
TMSD_FRONT = 0,
TMSD_BACK = 1,
TMSD_FRONTBACK = 2,
} textmapsides_t;
typedef enum
{
TMS_SCROLLCARRY = 0,
TMS_SCROLLONLY = 1,
TMS_CARRYONLY = 2,
} textmapscroll_t;
typedef enum
{
TMST_REGULAR = 0,
TMST_ACCELERATIVE = 1,
TMST_DISPLACEMENT = 2,
TMST_TYPEMASK = 3,
TMST_NONEXCLUSIVE = 4,
} textmapscrolltype_t;
typedef enum
{
TMPF_SLIDE = 1,
TMPF_NONEXCLUSIVE = 1<<1,
} textmappusherflags_t;
typedef enum
{
TMPP_NOZFADE = 1,
TMPP_PUSHZ = 1<<1,
TMPP_NONEXCLUSIVE = 1<<2,
} textmappointpushflags_t;
typedef enum
{
TMB_TRANSLUCENT = 0,
TMB_ADD = 1,
TMB_SUBTRACT = 2,
TMB_REVERSESUBTRACT = 3,
TMB_MODULATE = 4,
} textmapblendmodes_t;
// GETSECSPECIAL (specialval, section)
//
// Pulls out the special # from a particular section.
@ -38,12 +482,21 @@ void P_SetupLevelFlatAnims(void);
// at map load
void P_InitSpecials(void);
void P_ApplyFlatAlignment(sector_t* sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs, boolean floor, boolean ceiling);
fixed_t P_GetSectorGravityFactor(sector_t *sec);
void P_SpawnSpecials(boolean fromnetsave);
// every tic
void P_UpdateSpecials(void);
sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number);
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag);
sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number);
sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag);
void P_PlayerInSpecialSector(player_t *player);
void P_CheckMobjTrigger(mobj_t *mobj, boolean pushable);
sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline);
boolean P_IsPlayerValid(size_t playernum);
boolean P_CanPlayerTrigger(size_t playernum);
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);
fixed_t P_FindLowestFloorSurrounding(sector_t *sec);
@ -60,6 +513,10 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
void P_SetupSignExit(player_t *player);
boolean P_IsFlagAtBase(mobjtype_t flag);
boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec);
boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec);
boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec);
void P_SwitchWeather(INT32 weathernum);
boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller);
@ -72,6 +529,12 @@ void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean e
UINT16 P_GetFFloorID(ffloor_t *fflr);
ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id);
// Use this when you don't know the type of your thinker data struct but need to access its thinker.
typedef struct
{
thinker_t thinker;
} thinkerdata_t;
//
// P_LIGHTS
//
@ -83,8 +546,8 @@ typedef struct
sector_t *sector; ///< The sector where action is taking place.
INT32 count;
INT32 resetcount;
INT32 maxlight; ///< The brightest light level to use.
INT32 minlight; ///< The darkest light level to use.
INT16 maxlight; ///< The brightest light level to use.
INT16 minlight; ///< The darkest light level to use.
} fireflicker_t;
typedef struct
@ -112,8 +575,8 @@ typedef struct
thinker_t thinker; ///< The thinker in use for the effect.
sector_t *sector; ///< The sector where the action is taking place.
INT32 count;
INT32 minlight; ///< The minimum light level to use.
INT32 maxlight; ///< The maximum light level to use.
INT16 minlight; ///< The minimum light level to use.
INT16 maxlight; ///< The maximum light level to use.
INT32 darktime; ///< How INT32 to use minlight.
INT32 brighttime; ///< How INT32 to use maxlight.
} strobe_t;
@ -122,10 +585,10 @@ typedef struct
{
thinker_t thinker;
sector_t *sector;
INT32 minlight;
INT32 maxlight;
INT32 direction;
INT32 speed;
INT16 minlight;
INT16 maxlight;
INT16 direction;
INT16 speed;
} glow_t;
/** Thinker struct for fading lights.
@ -151,18 +614,18 @@ typedef struct
void P_RemoveLighting(sector_t *sector);
void T_FireFlicker(fireflicker_t *flick);
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length);
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length);
void T_LightningFlash(lightflash_t *flash);
void T_StrobeFlash(strobe_t *flash);
void P_SpawnLightningFlash(sector_t *sector);
strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, INT32 darktime, INT32 brighttime, boolean inSync);
strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *sector, INT16 lighta, INT16 lightb, INT32 darktime, INT32 brighttime, boolean inSync);
void T_Glow(glow_t *g);
glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length);
glow_t *P_SpawnAdjustableGlowingLight(sector_t *sector, INT16 lighta, INT16 lightb, INT32 length);
void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased);
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force);
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force, boolean relative);
void T_LightFade(lightlevel_t *ll);
typedef enum
@ -178,22 +641,19 @@ typedef enum
typedef enum
{
raiseToHighest,
lowerToLowest,
raiseToLowest,
lowerToLowestFast,
instantRaise, // instant-move for ceilings
lowerAndCrush,
crushAndRaise,
fastCrushAndRaise,
raiseAndCrush,
crushCeilOnce,
crushBothOnce,
moveCeilingByFrontSector,
instantMoveCeilingByFrontSector,
moveCeilingByFrontTexture,
moveCeilingByDistance,
bounceCeiling,
bounceCeilingCrush,
@ -209,7 +669,6 @@ typedef struct
fixed_t bottomheight; ///< The lowest height to move to.
fixed_t topheight; ///< The highest height to move to.
fixed_t speed; ///< Ceiling speed.
fixed_t oldspeed;
fixed_t delay;
fixed_t delaytimer;
UINT8 crush; ///< Whether to crush things or not.
@ -218,17 +677,16 @@ typedef struct
INT32 direction; ///< 1 = up, 0 = waiting, -1 = down.
// ID
INT32 tag;
INT32 olddirection;
INT16 tag; ///< Tag of linedef executor to run when movement is done.
fixed_t origspeed; ///< The original, "real" speed.
INT32 sourceline; ///< Index of the source linedef
} ceiling_t;
#define CEILSPEED (FRACUNIT)
INT32 EV_DoCeiling(line_t *line, ceiling_e type);
INT32 EV_DoCeiling(mtag_t tag, line_t *line, ceiling_e type);
INT32 EV_DoCrush(line_t *line, ceiling_e type);
INT32 EV_DoCrush(mtag_t tag, line_t *line, ceiling_e type);
void T_CrushCeiling(ceiling_t *ceiling);
void T_MoveCeiling(ceiling_t *ceiling);
@ -238,9 +696,6 @@ void T_MoveCeiling(ceiling_t *ceiling);
//
typedef enum
{
// lower floor to lowest surrounding floor
lowerFloorToLowest,
// raise floor to next highest surrounding floor
raiseFloorToNearestFast,
@ -250,7 +705,7 @@ typedef enum
moveFloorByFrontSector,
instantMoveFloorByFrontSector,
moveFloorByFrontTexture,
moveFloorByDistance,
bounceFloor,
bounceFloorCrush,
@ -262,7 +717,6 @@ typedef enum
{
elevateUp,
elevateDown,
elevateCurrent,
elevateContinuous,
elevateBounce,
elevateHighest,
@ -282,6 +736,8 @@ typedef struct
fixed_t origspeed;
fixed_t delay;
fixed_t delaytimer;
INT16 tag;
INT32 sourceline;
} floormove_t;
typedef struct
@ -403,7 +859,6 @@ typedef struct
thinker_t thinker;
line_t *sourceline; // Source line of the thinker
boolean playersInArea[MAXPLAYERS];
boolean playersOnArea[MAXPLAYERS];
boolean triggerOnExit;
} eachtime_t;
@ -439,8 +894,8 @@ typedef enum
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
boolean ceiling, INT32 direction);
void EV_DoFloor(line_t *line, floor_e floortype);
void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
void EV_DoFloor(mtag_t tag, line_t *line, floor_e floortype);
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype);
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
@ -525,30 +980,20 @@ void T_Friction(friction_t *f);
typedef enum
{
p_push, ///< Point pusher or puller.
p_wind, ///< Wind.
p_current, ///< Current.
p_upcurrent, ///< Upwards current.
p_downcurrent, ///< Downwards current.
p_upwind, ///< Upwards wind.
p_downwind ///< Downwards wind.
} pushertype_e;
// Model for pushers for push/pull effects
typedef struct
{
thinker_t thinker; ///< Thinker structure for push/pull effect.
/** Types of push/pull effects.
*/
pushertype_e type; ///< Type of push/pull effect.
mobj_t *source; ///< Point source if point pusher/puller.
INT32 x_mag; ///< X strength.
INT32 y_mag; ///< Y strength.
INT32 magnitude; ///< Vector strength for point pusher/puller.
INT32 radius; ///< Effective radius for point pusher/puller.
INT32 x, y, z; ///< Point source if point pusher/puller.
thinker_t thinker; ///< Thinker structure for pusher effect.
pushertype_e type; ///< Type of pusher effect.
fixed_t x_mag; ///< X strength.
fixed_t y_mag; ///< Y strength.
fixed_t z_mag; ///< Z strength.
INT32 affectee; ///< Number of affected sector.
UINT8 roverpusher; ///< flag for whether pusher originated from a FOF or not
UINT8 roverpusher; ///< flag for whether pusher originated from a FOF or not
INT32 referrer; ///< If roverpusher == true, then this will contain the sector # of the control sector where the effect was applied.
INT32 exclusive; /// < Once this affect has been applied to a mobj, no other pushers may affect it.
INT32 slider; /// < Should the player go into an uncontrollable slide?
@ -584,8 +1029,8 @@ typedef struct
INT16 speed; ///< Speed to fade by
boolean ticbased; ///< Tic-based logic toggle
INT32 timer; ///< Timer for tic-based logic
boolean doexists; ///< Handle FF_EXISTS
boolean dotranslucent; ///< Handle FF_TRANSLUCENT
boolean doexists; ///< Handle FOF_EXISTS
boolean dotranslucent; ///< Handle FOF_TRANSLUCENT
boolean dolighting; ///< Handle shadows and light blocks
boolean docolormap; ///< Handle colormaps
boolean docollision; ///< Handle interactive flags
@ -610,9 +1055,8 @@ typedef struct
void T_FadeColormap(fadecolormap_t *d);
// Prototype functions for pushers
// Prototype function for pushers
void T_Pusher(pusher_t *p);
mobj_t *P_GetPushThing(UINT32 s);
// Plane displacement
typedef struct
@ -637,6 +1081,4 @@ void T_PlaneDisplace(planedisplace_t *pd);
void P_CalcHeight(player_t *player);
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
#endif

View file

@ -706,8 +706,7 @@ static void P_DeNightserizePlayer(player_t *player)
// If you screwed up, kiss your score and ring bonus goodbye.
// But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground.
player->marescore = player->spheres =\
player->rings = 0;
player->marescore = player->spheres = player->rings = 0;
}
// Check to see if the player should be killed.
@ -717,13 +716,12 @@ static void P_DeNightserizePlayer(player_t *player)
continue;
mo2 = (mobj_t *)th;
if (!(mo2->type == MT_NIGHTSDRONE))
if (mo2->type != MT_NIGHTSDRONE)
continue;
if (mo2->flags2 & MF2_AMBUSH)
{
player->marescore = player->spheres =\
player->rings = 0;
player->marescore = player->spheres = player->rings = 0;
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
// Reset music to beginning if MIXNIGHTSCOUNTDOWN
@ -777,7 +775,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
UINT8 oldmare, oldmarelap, oldmarebonuslap;
// Bots can't be NiGHTSerized, silly!1 :P
if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN)
if (player->bot)
return;
if (player->powers[pw_carry] != CR_NIGHTSMODE)
@ -969,9 +967,6 @@ pflags_t P_GetJumpFlags(player_t *player)
//
boolean P_PlayerInPain(player_t *player)
{
// If the player doesn't have a mobj, it can't be in pain.
if (!player->mo)
return false;
// no silly, sliding isn't pain
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing])
return true;
@ -1238,8 +1233,8 @@ void P_GivePlayerSpheres(player_t *player, INT32 num_spheres)
if (!player)
return;
if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader)
player = player->botleader;
if (player->bot)
player = &players[consoleplayer];
if (!player->mo)
return;
@ -1265,8 +1260,8 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
if (!player)
return;
if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader)
player = player->botleader;
if (player->bot)
player = &players[consoleplayer];
if (gamestate == GS_LEVEL)
{
@ -1732,89 +1727,6 @@ boolean P_IsObjectOnGround(mobj_t *mo)
return false;
}
//
// P_IsObjectOnGroundIn
//
// Returns true if the player is
// on the ground in a specific sector. Takes reverse
// gravity and FOFs into account.
//
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
{
ffloor_t *rover;
// Is the object in reverse gravity?
if (mo->eflags & MFE_VERTICALFLIP)
{
// Detect if the player is on the ceiling.
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true;
// Otherwise, detect if the player is on the bottom of a FOF.
else
{
for (rover = sec->ffloors; rover; rover = rover->next)
{
// If the FOF doesn't exist, continue.
if (!(rover->flags & FF_EXISTS))
continue;
// If the FOF is configured to let the object through, continue.
if (!((rover->flags & FF_BLOCKPLAYER && mo->player)
|| (rover->flags & FF_BLOCKOTHERS && !mo->player)))
continue;
// If the the platform is intangible from below, continue.
if (rover->flags & FF_PLATFORM)
continue;
// If the FOF is a water block, continue. (Unnecessary check?)
if (rover->flags & FF_SWIMMABLE)
continue;
// Actually check if the player is on the suitable FOF.
if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec))
return true;
}
}
}
// Nope!
else
{
// Detect if the player is on the floor.
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true;
// Otherwise, detect if the player is on the top of a FOF.
else
{
for (rover = sec->ffloors; rover; rover = rover->next)
{
// If the FOF doesn't exist, continue.
if (!(rover->flags & FF_EXISTS))
continue;
// If the FOF is configured to let the object through, continue.
if (!((rover->flags & FF_BLOCKPLAYER && mo->player)
|| (rover->flags & FF_BLOCKOTHERS && !mo->player)))
continue;
// If the the platform is intangible from above, continue.
if (rover->flags & FF_REVERSEPLATFORM)
continue;
// If the FOF is a water block, continue. (Unnecessary check?)
if (rover->flags & FF_SWIMMABLE)
continue;
// Actually check if the player is on the suitable FOF.
if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec))
return true;
}
}
}
return false;
}
//
// P_SetObjectMomZ
//
@ -2054,12 +1966,22 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
ghost->rollangle = mobj->rollangle;
ghost->sprite = mobj->sprite;
ghost->sprite2 = mobj->sprite2;
ghost->frame = mobj->frame;
ghost->tics = -1;
ghost->frame &= ~FF_TRANSMASK;
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
ghost->renderflags = mobj->renderflags;
ghost->blendmode = mobj->blendmode;
ghost->spritexscale = mobj->spritexscale;
ghost->spriteyscale = mobj->spriteyscale;
ghost->spritexoffset = mobj->spritexoffset;
ghost->spriteyoffset = mobj->spriteyoffset;
ghost->fuse = ghost->info->damage;
ghost->skin = mobj->skin;
@ -2273,13 +2195,12 @@ void P_DoPlayerExit(player_t *player)
P_RestoreMusic(player);
}
#define SPACESPECIAL 12
boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
{
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;
if (GETSECSPECIAL(sector->special, 1) == SPACESPECIAL)
if (sector->specialflags & SSF_OUTERSPACE)
return true;
if (sector->ffloors)
@ -2288,10 +2209,10 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
if (!(rover->master->frontsector->specialflags & SSF_OUTERSPACE))
continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
@ -2541,10 +2462,10 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->flags & FF_QUICKSAND))
if (!(rover->fofflags & FOF_QUICKSAND))
continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
@ -2565,67 +2486,69 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover)
{
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
return false;
if (!(rover->flags & FF_BUSTUP))
if (!(rover->fofflags & FOF_BUSTUP))
return false;
/*if (rover->master->frontsector->crumblestate != CRUMBLE_NONE)
return false;*/
// If it's an FF_SHATTER, you can break it just by touching it.
if (rover->flags & FF_SHATTER)
return true;
// If it's an FF_SPINBUST, you can break it if you are in your spinning frames
// (either from jumping or spindashing).
if (rover->flags & FF_SPINBUST)
switch (rover->busttype)
{
case BT_TOUCH: // Shatters on contact
return true;
case BT_SPINBUST: // Can be busted by spinning (either from jumping or spindashing)
if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_STARTDASH))
return true;
if ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE))
return true;
/* FALLTHRU */
case BT_REGULAR:
// Spinning (and not jumping)
if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
return true;
// Passive wall breaking
if (player->charflags & SF_CANBUSTWALLS)
return true;
// Super
if (player->powers[pw_super])
return true;
// Dashmode
if ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) && player->dashmode >= DASHMODE_THRESHOLD)
return true;
// NiGHTS drill
if (player->pflags & PF_DRILLING)
return true;
// Recording for Metal Sonic
if (metalrecording)
return true;
/* FALLTHRU */
case BT_STRONG: // Requires a "strong ability"
if (player->charflags & SF_CANBUSTWALLS)
return true;
if (player->pflags & PF_BOUNCING)
return true;
if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)
return true;
if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
return true;
break;
}
// Strong abilities can break even FF_STRONGBUST.
if (player->charflags & SF_CANBUSTWALLS)
return true;
if (player->pflags & PF_BOUNCING)
return true;
if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)
return true;
if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
return true;
// Everyone else is out of luck.
if (rover->flags & FF_STRONGBUST)
return false;
// Spinning (and not jumping)
if ((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED))
return true;
// Super
if (player->powers[pw_super])
return true;
// Dashmode
if ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) && player->dashmode >= DASHMODE_THRESHOLD)
return true;
// NiGHTS drill
if (player->pflags & PF_DRILLING)
return true;
// Recording for Metal Sonic
if (metalrecording)
return true;
return false;
}
@ -2676,7 +2599,7 @@ static void P_CheckBustableBlocks(player_t *player)
}
// Height checks
if (rover->flags & FF_SHATTERBOTTOM)
if (rover->bustflags & FB_ONLYBOTTOM)
{
if (player->mo->z + player->mo->momz + player->mo->height < bottomheight)
continue;
@ -2684,35 +2607,41 @@ static void P_CheckBustableBlocks(player_t *player)
if (player->mo->z + player->mo->height > bottomheight)
continue;
}
else if (rover->flags & FF_SPINBUST)
{
if (player->mo->z + player->mo->momz > topheight)
continue;
if (player->mo->z + player->mo->height < bottomheight)
continue;
}
else if (rover->flags & FF_SHATTER)
{
if (player->mo->z + player->mo->momz > topheight)
continue;
if (player->mo->z + player->mo->momz + player->mo->height < bottomheight)
continue;
}
else
{
if (player->mo->z >= topheight)
continue;
switch (rover->busttype)
{
case BT_TOUCH:
if (player->mo->z + player->mo->momz > topheight)
continue;
if (player->mo->z + player->mo->height < bottomheight)
continue;
if (player->mo->z + player->mo->momz + player->mo->height < bottomheight)
continue;
break;
case BT_SPINBUST:
if (player->mo->z + player->mo->momz > topheight)
continue;
if (player->mo->z + player->mo->height < bottomheight)
continue;
break;
default:
if (player->mo->z >= topheight)
continue;
if (player->mo->z + player->mo->height < bottomheight)
continue;
break;
}
}
// Impede the player's fall a bit
if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight)
if (((rover->busttype == BT_TOUCH) || (rover->busttype == BT_SPINBUST)) && player->mo->z >= topheight)
player->mo->momz >>= 1;
else if (rover->flags & FF_SHATTER)
else if (rover->busttype == BT_TOUCH)
{
player->mo->momx >>= 1;
player->mo->momy >>= 1;
@ -2724,8 +2653,8 @@ static void P_CheckBustableBlocks(player_t *player)
EV_CrumbleChain(NULL, rover); // node->m_sector
// Run a linedef executor??
if (rover->master->flags & ML_EFFECT5)
P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector);
if (rover->bustflags & FB_EXECUTOR)
P_LinedefExecute(rover->busttag, player->mo, node->m_sector);
goto bustupdone;
}
@ -2770,14 +2699,20 @@ static void P_CheckBouncySectors(player_t *player)
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
fixed_t bouncestrength;
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_EXISTS))
continue; // FOFs should not be bouncy if they don't even "exist"
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != 15)
continue; // this sector type is required for FOFs to be bouncy
// Handle deprecated bouncy FOF sector type
if (!udmf && GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
{
rover->fofflags |= FOF_BOUNCY;
rover->bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100;
}
if (!(rover->fofflags & FOF_BOUNCY))
continue;
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
@ -2788,14 +2723,11 @@ static void P_CheckBouncySectors(player_t *player)
if (player->mo->z + player->mo->height < bottomheight)
continue;
bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100;
if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)
&& oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
{
player->mo->momx = -FixedMul(player->mo->momx,bouncestrength);
player->mo->momy = -FixedMul(player->mo->momy,bouncestrength);
player->mo->momx = -FixedMul(player->mo->momx,rover->bouncestrength);
player->mo->momy = -FixedMul(player->mo->momy,rover->bouncestrength);
}
else
{
@ -2808,9 +2740,9 @@ static void P_CheckBouncySectors(player_t *player)
if (slope)
P_ReverseQuantizeMomentumToSlope(&momentum, slope);
momentum.z = -FixedMul(momentum.z,bouncestrength)/2;
momentum.z = -FixedMul(momentum.z,rover->bouncestrength)/2;
if (abs(momentum.z) < (bouncestrength*2))
if (abs(momentum.z) < (rover->bouncestrength*2))
goto bouncydone;
if (momentum.z > FixedMul(24*FRACUNIT, player->mo->scale)) //half of the default player height
@ -2844,7 +2776,7 @@ bouncydone:
static void P_CheckQuicksand(player_t *player)
{
ffloor_t *rover;
fixed_t sinkspeed, friction;
fixed_t sinkspeed;
fixed_t topheight, bottomheight;
if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0))
@ -2852,9 +2784,9 @@ static void P_CheckQuicksand(player_t *player)
for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS)) continue;
if (!(rover->fofflags & FOF_EXISTS)) continue;
if (!(rover->flags & FF_QUICKSAND))
if (!(rover->fofflags & FOF_QUICKSAND))
continue;
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
@ -2862,9 +2794,7 @@ static void P_CheckQuicksand(player_t *player)
if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height)
{
sinkspeed = abs(rover->master->v1->x - rover->master->v2->x)>>1;
sinkspeed = FixedDiv(sinkspeed,TICRATE*FRACUNIT);
sinkspeed = FixedDiv(rover->sinkspeed,TICRATE*FRACUNIT);
if (player->mo->eflags & MFE_VERTICALFLIP)
{
@ -2891,10 +2821,8 @@ static void P_CheckQuicksand(player_t *player)
P_PlayerHitFloor(player, false);
}
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
player->mo->momx = FixedMul(player->mo->momx, friction);
player->mo->momy = FixedMul(player->mo->momy, friction);
player->mo->momx = FixedMul(player->mo->momx, rover->friction);
player->mo->momy = FixedMul(player->mo->momy, rover->friction);
}
}
}
@ -3208,7 +3136,7 @@ static void P_DoClimbing(player_t *player)
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || ((rover->flags & FF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_BLOCKPLAYER) || ((rover->fofflags & FOF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
continue;
floorclimb = true;
@ -3249,7 +3177,7 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below this one that we can move onto?
for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
{
if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || ((rover->flags & FF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
if (!(roverbelow->fofflags & FOF_EXISTS) || !(roverbelow->fofflags & FOF_BLOCKPLAYER) || ((rover->fofflags & FOF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
continue;
if (roverbelow == rover)
@ -3294,7 +3222,7 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below this one that we can move onto?
for (roverbelow = glidesector->sector->ffloors; roverbelow; roverbelow = roverbelow->next)
{
if (!(roverbelow->flags & FF_EXISTS) || !(roverbelow->flags & FF_BLOCKPLAYER) || ((rover->flags & FF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
if (!(roverbelow->fofflags & FOF_EXISTS) || !(roverbelow->fofflags & FOF_BLOCKPLAYER) || ((rover->fofflags & FOF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
continue;
if (roverbelow == rover)
@ -3328,8 +3256,8 @@ static void P_DoClimbing(player_t *player)
if (floorclimb)
{
if (rover->flags & FF_CRUMBLE && !(netgame && player->spectator))
EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN));
if (rover->fofflags & FOF_CRUMBLE && !(netgame && player->spectator))
EV_StartCrumble(rover->master->frontsector, rover, (rover->fofflags & FOF_FLOATBOB), player, rover->alpha, !(rover->fofflags & FOF_NORETURN));
break;
}
}
@ -3351,7 +3279,7 @@ static void P_DoClimbing(player_t *player)
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || ((rover->flags & FF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_BLOCKPLAYER) || ((rover->fofflags & FOF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
continue;
bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
@ -3391,7 +3319,7 @@ static void P_DoClimbing(player_t *player)
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || ((rover->flags & FF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_BLOCKPLAYER) || ((rover->fofflags & FOF_BUSTUP) && (player->charflags & SF_CANBUSTWALLS)))
continue;
topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y);
@ -3765,14 +3693,14 @@ static void P_DoTeeter(player_t *player)
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS)) continue;
if (!(rover->fofflags & FOF_EXISTS)) continue;
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (P_CheckSolidLava(rover))
;
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
else if (!(rover->fofflags & FOF_BLOCKPLAYER || rover->fofflags & FOF_QUICKSAND))
continue; // intangible 3d floor
if (player->mo->eflags & MFE_VERTICALFLIP)
@ -4778,7 +4706,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
&& player->speed < 5*player->mo->scale && canstand)
{
if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
if ((player->mo->subsector->sector->specialflags & SSF_FORCESPIN) || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
P_InstaThrust(player->mo, player->mo->angle, 10*player->mo->scale);
else
{
@ -5672,6 +5600,22 @@ INT32 P_GetPlayerControlDirection(player_t *player)
return 1; // Controls pointing in player's general direction
}
static boolean P_ShouldResetConveyorMomentum(player_t *player)
{
switch (player->onconveyor)
{
case 1:
return false;
case 2: // Wind/Current
return !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER));
case 3:
default:
return true;
case 4: // Actual conveyor belt
return !P_IsObjectOnGround(player->mo);
}
}
// Control scheme for 2d levels.
static void P_2dMovement(player_t *player)
{
@ -5706,16 +5650,7 @@ static void P_2dMovement(player_t *player)
}
}
// cmomx/cmomy stands for the conveyor belt speed.
if (player->onconveyor == 2) // Wind/Current
{
//if (player->mo->z > player->mo->watertop || player->mo->z + player->mo->height < player->mo->waterbottom)
if (!(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
player->cmomx = player->cmomy = 0;
}
else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt
player->cmomx = player->cmomy = 0;
else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1)
if (P_ShouldResetConveyorMomentum(player))
player->cmomx = player->cmomy = 0;
player->rmomx = player->mo->momx - player->cmomx;
@ -5898,16 +5833,7 @@ static void P_3dMovement(player_t *player)
}
movepushsideangle = movepushangle-ANGLE_90;
// cmomx/cmomy stands for the conveyor belt speed.
if (player->onconveyor == 2) // Wind/Current
{
//if (player->mo->z > player->mo->watertop || player->mo->z + player->mo->height < player->mo->waterbottom)
if (!(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
player->cmomx = player->cmomy = 0;
}
else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt
player->cmomx = player->cmomy = 0;
else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1)
if (P_ShouldResetConveyorMomentum(player))
player->cmomx = player->cmomy = 0;
player->rmomx = player->mo->momx - player->cmomx;
@ -6695,7 +6621,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
//
static void P_DoNiGHTSCapsule(player_t *player)
{
INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic, startingspheres;
INT32 i, spherecount, totalduration, popduration, deductinterval, deductquantity, sphereresult, firstpoptic;
INT32 tictimer = ++player->capsule->extravalue2;
if (abs(player->mo->x-player->capsule->x) <= 3*FRACUNIT)
@ -6818,15 +6744,20 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (player->capsule->health > sphereresult && player->spheres > 0)
{
// If spherecount isn't a multiple of deductquantity, the final deduction might steal too many spheres from the player
// E.g. with 80 capsule health, deductquantity is 3, 3*26 is 78, 78+3=81, and then it'll have stolen more than the 80 that it was meant to!
// So let's adjust deductquantity accordingly for the final deduction
deductquantity = min(deductquantity, player->capsule->health - sphereresult);
player->spheres -= deductquantity;
player->capsule->health -= deductquantity;
if (player->spheres < 0) // This can't happen... without Lua, setrings, et cetera
player->spheres = 0;
//if (player->capsule->health < sphereresult) // This can't happen
//player->capsule->health = sphereresult;
}
if (player->spheres < 0)
player->spheres = 0;
if (player->capsule->health < sphereresult)
player->capsule->health = sphereresult;
}
// Spawn a 'pop' for every 2 tics
@ -6847,9 +6778,8 @@ static void P_DoNiGHTSCapsule(player_t *player)
}
else
{
startingspheres = player->spheres - player->capsule->health;
player->spheres -= player->capsule->health;
player->capsule->health = 0;
player->spheres = startingspheres;
}
}
@ -7616,8 +7546,8 @@ static void P_NiGHTSMovement(player_t *player)
}
}
if (objectplacing)
OP_NightsObjectplace(player);
//if (objectplacing)
// OP_NightsObjectplace(player);
}
// May be used in future for CTF
@ -8678,7 +8608,7 @@ void P_MovePlayer(player_t *player)
#endif
// Look for blocks to bust up
// Because of FF_SHATTER, we should look for blocks constantly,
// Because of BT_TOUCH, we should look for blocks constantly,
// not just when spinning or playing as Knuckles
if (CheckForBustableBlocks)
P_CheckBustableBlocks(player);
@ -10142,7 +10072,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERALL) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
continue;
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@ -10206,7 +10136,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
// We're inside it! Yess...
polysec = po->lines[0]->backsector;
if (GETSECSPECIAL(polysec->special, 4) == 12)
if (polysec->flags & MSF_NOCLIPCAMERA)
{ // Camera noclip polyobj.
plink = (polymaplink_t *)(plink->link.next);
continue;
@ -10268,7 +10198,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) != 12)
if ((rover->fofflags & FOF_BLOCKOTHERS) && (rover->fofflags & FOF_RENDERALL) && (rover->fofflags & FOF_EXISTS) && !(rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
{
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
@ -10344,7 +10274,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
thiscam->momx = FixedMul(x - thiscam->x, camspeed);
thiscam->momy = FixedMul(y - thiscam->y, camspeed);
if (GETSECSPECIAL(thiscam->subsector->sector->special, 1) == 6
if (thiscam->subsector->sector->damagetype == SD_DEATHPITTILT
&& thiscam->z < thiscam->subsector->sector->floorheight + 256*FRACUNIT
&& FixedMul(z - thiscam->z, camspeed) < 0)
{
@ -10551,7 +10481,6 @@ static void P_CalcPostImg(player_t *player)
postimg_t *type;
INT32 *param;
fixed_t pviewheight;
size_t i;
if (player->mo->eflags & MFE_VERTICALFLIP)
pviewheight = player->mo->z + player->mo->height - player->viewheight;
@ -10576,45 +10505,30 @@ static void P_CalcPostImg(player_t *player)
}
// see if we are in heat (no, not THAT kind of heat...)
for (i = 0; i < sector->tags.count; i++)
if (sector->flags & MSF_HEATWAVE)
*type = postimg_heat;
else if (sector->ffloors)
{
if (Tag_FindLineSpecial(13, sector->tags.tags[i]) != -1)
{
*type = postimg_heat;
break;
}
else if (sector->ffloors)
{
ffloor_t *rover;
fixed_t topheight;
fixed_t bottomheight;
boolean gotres = false;
ffloor_t *rover;
fixed_t topheight;
fixed_t bottomheight;
for (rover = sector->ffloors; rover; rover = rover->next)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->fofflags & FOF_EXISTS))
continue;
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (pviewheight >= topheight || pviewheight <= bottomheight)
continue;
if (rover->master->frontsector->flags & MSF_HEATWAVE)
{
size_t j;
if (!(rover->flags & FF_EXISTS))
continue;
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
if (pviewheight >= topheight || pviewheight <= bottomheight)
continue;
for (j = 0; j < rover->master->frontsector->tags.count; j++)
{
if (Tag_FindLineSpecial(13, rover->master->frontsector->tags.tags[j]) != -1)
{
*type = postimg_heat;
gotres = true;
break;
}
}
}
if (gotres)
*type = postimg_heat;
break;
}
}
}
@ -10627,7 +10541,7 @@ static void P_CalcPostImg(player_t *player)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER)
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_BLOCKPLAYER)
continue;
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
@ -10690,7 +10604,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n
ffloor_t *rover;
for (rover = sec->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & (FF_EXISTS|FF_BLOCKOTHERS)))
if (!(rover->fofflags & (FOF_EXISTS|FOF_BLOCKOTHERS)))
continue;
*nz = P_GetFFloorTopZAt(rover, x, y);
@ -10853,7 +10767,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target
fixed_t nx, ny;
angle_t nang, dummy, angdiff;
mobj_t *mark;
mobj_t *snax = P_GetAxis(sides[lines[lline].sidenum[0]].textureoffset >> FRACBITS);
mobj_t *snax = P_GetAxis(lines[lline].args[0]);
if (!snax)
return NULL;
P_GetAxisPosition(x, y, snax, &nx, &ny, &nang, &dummy);
@ -10955,7 +10869,7 @@ static void P_MinecartThink(player_t *player)
// Update axis if the cart is standing on a rail.
if (sec && lnum != -1)
{
mobj_t *axis = P_GetAxis(sides[lines[lnum].sidenum[0]].textureoffset >> FRACBITS);
mobj_t *axis = P_GetAxis(lines[lnum].args[0]);
fixed_t newx, newy;
angle_t targetangle, grind;
angle_t prevangle, angdiff;
@ -12001,7 +11915,7 @@ void P_PlayerThink(player_t *player)
if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration...
acceleration = FixedMul(acceleration<<FRACBITS, player->mo->movefactor)>>FRACBITS;
P_Thrust(player->mo, moveAngle, -acceleration);
P_Thrust(player->mo, moveAngle, FixedMul(-acceleration, player->mo->scale));
}
if (!(player->pflags & PF_AUTOBRAKE)
@ -12334,7 +12248,10 @@ static boolean P_MobjAboveLava(mobj_t *mobj)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || GETSECSPECIAL(rover->master->frontsector->special, 1) != 3)
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE))
continue;
if (rover->master->frontsector->damagetype != SD_FIRE && rover->master->frontsector->damagetype != SD_LAVA)
continue;
if (mobj->eflags & MFE_VERTICALFLIP)
@ -12672,6 +12589,29 @@ void P_PlayerAfterThink(player_t *player)
break;
}
case CR_FAN:
{
fixed_t zdist;
mobj_t *mo = player->mo, *fan = player->mo->tracer;
if (!(player->pflags & PF_JUMPSTASIS))
player->pflags |= PF_JUMPSTASIS;
if (fan->eflags & MFE_VERTICALFLIP)
zdist = (mo->z + mo->height) - (fan->z + fan->height);
else
zdist = mo->z - fan->z;
if ((fan->type != MT_FAN && !P_PlayerTouchingSectorSpecialFlag(player, SSF_FAN))
|| (fan->type == MT_FAN && (abs(mo->x - fan->x) > fan->radius || abs(mo->y - fan->y) > fan->radius || zdist > (fan->health << FRACBITS))))
{
P_SetTarget(&player->mo->tracer, NULL);
player->pflags &= ~PF_JUMPSTASIS;
player->powers[pw_carry] = CR_NONE;
break;
}
break;
}
case CR_ROLLOUT:
{
mobj_t *mo = player->mo, *rock = player->mo->tracer;

View file

@ -238,11 +238,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
{
if (floorlightlevel)
*floorlightlevel = sec->floorlightsec == -1 ?
sec->lightlevel : sectors[sec->floorlightsec].lightlevel;
(sec->floorlightabsolute ? sec->floorlightlevel : max(0, min(255, sec->lightlevel + sec->floorlightlevel))) : sectors[sec->floorlightsec].lightlevel;
if (ceilinglightlevel)
*ceilinglightlevel = sec->ceilinglightsec == -1 ?
sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel;
(sec->ceilinglightabsolute ? sec->ceilinglightlevel : max(0, min(255, sec->lightlevel + sec->ceilinglightlevel))) : sectors[sec->ceilinglightsec].lightlevel;
// if (sec->midmap != -1)
// mapnum = sec->midmap;
@ -301,11 +301,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->lightlevel = s->lightlevel;
if (floorlightlevel)
*floorlightlevel = s->floorlightsec == -1 ? s->lightlevel
*floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel)))
: sectors[s->floorlightsec].lightlevel;
if (ceilinglightlevel)
*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel
*ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel)))
: sectors[s->ceilinglightsec].lightlevel;
}
else if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight
@ -339,12 +339,12 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
tempsec->lightlevel = s->lightlevel;
if (floorlightlevel)
*floorlightlevel = s->floorlightsec == -1 ? s->lightlevel :
sectors[s->floorlightsec].lightlevel;
*floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel)))
: sectors[s->floorlightsec].lightlevel;
if (ceilinglightlevel)
*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel :
sectors[s->ceilinglightsec].lightlevel;
*ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel)))
: sectors[s->ceilinglightsec].lightlevel;
}
sec = tempsec;
}
@ -370,6 +370,10 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
&& back->ceiling_yoffs == front->ceiling_yoffs
&& back->ceilingpic_angle == front->ceilingpic_angle
// Consider altered lighting.
&& back->floorlightlevel == front->floorlightlevel
&& back->floorlightabsolute == front->floorlightabsolute
&& back->ceilinglightlevel == front->ceilinglightlevel
&& back->ceilinglightabsolute == front->ceilinglightabsolute
&& back->floorlightsec == front->floorlightsec
&& back->ceilinglightsec == front->ceilinglightsec
// Consider colormaps
@ -872,12 +876,12 @@ static void R_Subsector(size_t num)
}
light = R_GetPlaneLight(frontsector, floorcenterz, false);
if (frontsector->floorlightsec == -1)
floorlightlevel = *frontsector->lightlist[light].lightlevel;
if (frontsector->floorlightsec == -1 && !frontsector->floorlightabsolute)
floorlightlevel = max(0, min(255, *frontsector->lightlist[light].lightlevel + frontsector->floorlightlevel));
floorcolormap = *frontsector->lightlist[light].extra_colormap;
light = R_GetPlaneLight(frontsector, ceilingcenterz, false);
if (frontsector->ceilinglightsec == -1)
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
if (frontsector->ceilinglightsec == -1 && !frontsector->ceilinglightabsolute)
ceilinglightlevel = max(0, min(255, *frontsector->lightlist[light].lightlevel + frontsector->ceilinglightlevel));
ceilingcolormap = *frontsector->lightlist[light].extra_colormap;
}
@ -915,7 +919,7 @@ static void R_Subsector(size_t num)
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES))
continue;
if (frontsector->cullheight)
@ -935,8 +939,8 @@ static void R_Subsector(size_t num)
planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
if (planecenterz <= ceilingcenterz
&& planecenterz >= floorcenterz
&& ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
&& ((viewz < heightcheck && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES)))
|| (viewz > heightcheck && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz,
viewz < heightcheck);
@ -965,8 +969,8 @@ static void R_Subsector(size_t num)
planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
if (planecenterz >= floorcenterz
&& planecenterz <= ceilingcenterz
&& ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
&& ((viewz > heightcheck && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES)))
|| (viewz < heightcheck && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
@ -1102,11 +1106,11 @@ void R_Prep3DFloors(sector_t *sector)
count = 1;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if ((rover->flags & FF_EXISTS) && (!(rover->flags & FF_NOSHADE)
|| (rover->flags & FF_CUTLEVEL) || (rover->flags & FF_CUTSPRITES)))
if ((rover->fofflags & FOF_EXISTS) && (!(rover->fofflags & FOF_NOSHADE)
|| (rover->fofflags & FOF_CUTLEVEL) || (rover->fofflags & FOF_CUTSPRITES)))
{
count++;
if (rover->flags & FF_DOUBLESHADOW)
if (rover->fofflags & FOF_DOUBLESHADOW)
count++;
}
}
@ -1137,8 +1141,8 @@ void R_Prep3DFloors(sector_t *sector)
for (rover = sector->ffloors; rover; rover = rover->next)
{
rover->lastlight = 0;
if (!(rover->flags & FF_EXISTS) || (rover->flags & FF_NOSHADE
&& !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
if (!(rover->fofflags & FOF_EXISTS) || (rover->fofflags & FOF_NOSHADE
&& !(rover->fofflags & FOF_CUTLEVEL) && !(rover->fofflags & FOF_CUTSPRITES)))
continue;
heighttest = P_GetFFloorTopZAt(rover, sector->soundorg.x, sector->soundorg.y);
@ -1150,7 +1154,7 @@ void R_Prep3DFloors(sector_t *sector)
bestslope = *rover->t_slope;
continue;
}
if (rover->flags & FF_DOUBLESHADOW) {
if (rover->fofflags & FOF_DOUBLESHADOW) {
heighttest = P_GetFFloorBottomZAt(rover, sector->soundorg.x, sector->soundorg.y);
if (heighttest > bestheight
@ -1171,16 +1175,16 @@ void R_Prep3DFloors(sector_t *sector)
sector->lightlist[i].height = maxheight = bestheight;
sector->lightlist[i].caster = best;
sector->lightlist[i].flags = best->flags;
sector->lightlist[i].flags = best->fofflags;
sector->lightlist[i].slope = bestslope;
sec = &sectors[best->secnum];
if (best->flags & FF_NOSHADE)
if (best->fofflags & FOF_NOSHADE)
{
sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel;
sector->lightlist[i].extra_colormap = sector->lightlist[i-1].extra_colormap;
}
else if (best->flags & FF_COLORMAPONLY)
else if (best->fofflags & FOF_COLORMAPONLY)
{
sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel;
sector->lightlist[i].extra_colormap = &sec->extra_colormap;
@ -1191,7 +1195,7 @@ void R_Prep3DFloors(sector_t *sector)
sector->lightlist[i].extra_colormap = &sec->extra_colormap;
}
if (best->flags & FF_DOUBLESHADOW)
if (best->fofflags & FOF_DOUBLESHADOW)
{
heighttest = P_GetFFloorBottomZAt(best, sector->soundorg.x, sector->soundorg.y);
if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red

View file

@ -115,45 +115,99 @@ typedef struct
*/
typedef enum
{
FF_EXISTS = 0x1, ///< Always set, to check for validity.
FF_BLOCKPLAYER = 0x2, ///< Solid to player, but nothing else
FF_BLOCKOTHERS = 0x4, ///< Solid to everything but player
FF_SOLID = 0x6, ///< Clips things.
FF_RENDERSIDES = 0x8, ///< Renders the sides.
FF_RENDERPLANES = 0x10, ///< Renders the floor/ceiling.
FF_RENDERALL = 0x18, ///< Renders everything.
FF_SWIMMABLE = 0x20, ///< Is a water block.
FF_NOSHADE = 0x40, ///< Messes with the lighting?
FF_CUTSOLIDS = 0x80, ///< Cuts out hidden solid pixels.
FF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels.
FF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels.
FF_CUTSPRITES = 0x200, ///< Final step in making 3D water.
FF_BOTHPLANES = 0x400, ///< Render inside and outside planes.
FF_EXTRA = 0x800, ///< Gets cut by ::FF_CUTEXTRA.
FF_TRANSLUCENT = 0x1000, ///< See through!
FF_FOG = 0x2000, ///< Fog "brush."
FF_INVERTPLANES = 0x4000, ///< Only render inside planes.
FF_ALLSIDES = 0x8000, ///< Render inside and outside sides.
FF_INVERTSIDES = 0x10000, ///< Only render inside sides.
FF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light?
FF_FLOATBOB = 0x40000, ///< Floats on water and bobs if you step on it.
FF_NORETURN = 0x80000, ///< Used with ::FF_CRUMBLE. Will not return to its original position after falling.
FF_CRUMBLE = 0x100000, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist).
FF_SHATTERBOTTOM = 0x200000, ///< Used with ::FF_BUSTUP. Like FF_SHATTER, but only breaks from the bottom. Good for springing up through rubble.
FF_MARIO = 0x400000, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector.
FF_BUSTUP = 0x800000, ///< You can spin through/punch this block and it will crumble!
FF_QUICKSAND = 0x1000000, ///< Quicksand!
FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top.
FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
FF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid.
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
FF_RIPPLE = 0x40000000, ///< Ripple the flats
FF_COLORMAPONLY = 0x80000000, ///< Only copy the colormap, not the lightlevel
FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
FOF_EXISTS = 0x1, ///< Always set, to check for validity.
FOF_BLOCKPLAYER = 0x2, ///< Solid to player, but nothing else
FOF_BLOCKOTHERS = 0x4, ///< Solid to everything but player
FOF_SOLID = 0x6, ///< Clips things.
FOF_RENDERSIDES = 0x8, ///< Renders the sides.
FOF_RENDERPLANES = 0x10, ///< Renders the floor/ceiling.
FOF_RENDERALL = 0x18, ///< Renders everything.
FOF_SWIMMABLE = 0x20, ///< Is a water block.
FOF_NOSHADE = 0x40, ///< Messes with the lighting?
FOF_CUTSOLIDS = 0x80, ///< Cuts out hidden solid pixels.
FOF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels.
FOF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels.
FOF_CUTSPRITES = 0x200, ///< Final step in making 3D water.
FOF_BOTHPLANES = 0x400, ///< Render inside and outside planes.
FOF_EXTRA = 0x800, ///< Gets cut by ::FOF_CUTEXTRA.
FOF_TRANSLUCENT = 0x1000, ///< See through!
FOF_FOG = 0x2000, ///< Fog "brush."
FOF_INVERTPLANES = 0x4000, ///< Only render inside planes.
FOF_ALLSIDES = 0x8000, ///< Render inside and outside sides.
FOF_INVERTSIDES = 0x10000, ///< Only render inside sides.
FOF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light?
FOF_FLOATBOB = 0x40000, ///< Floats on water and bobs if you step on it.
FOF_NORETURN = 0x80000, ///< Used with ::FOF_CRUMBLE. Will not return to its original position after falling.
FOF_CRUMBLE = 0x100000, ///< Falls 2 seconds after being stepped on, and randomly brings all touching crumbling 3dfloors down with it, providing their master sectors share the same tag (allows crumble platforms above or below, to also exist).
FOF_GOOWATER = 0x200000, ///< Used with ::FOF_SWIMMABLE. Makes thick bouncey goop.
FOF_MARIO = 0x400000, ///< Acts like a question block when hit from underneath. Goodie spawned at top is determined by master sector.
FOF_BUSTUP = 0x800000, ///< You can spin through/punch this block and it will crumble!
FOF_QUICKSAND = 0x1000000, ///< Quicksand!
FOF_PLATFORM = 0x2000000, ///< You can jump up through this to the top.
FOF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
FOF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid.
FOF_RIPPLE = 0x8000000, ///< Ripple the flats
FOF_COLORMAPONLY = 0x10000000, ///< Only copy the colormap, not the lightlevel
FOF_BOUNCY = 0x20000000, ///< Bounces players
FOF_SPLAT = 0x40000000, ///< Use splat flat renderer (treat cyan pixels as invisible)
} ffloortype_e;
typedef enum
{
FF_OLD_EXISTS = 0x1,
FF_OLD_BLOCKPLAYER = 0x2,
FF_OLD_BLOCKOTHERS = 0x4,
FF_OLD_SOLID = 0x6,
FF_OLD_RENDERSIDES = 0x8,
FF_OLD_RENDERPLANES = 0x10,
FF_OLD_RENDERALL = 0x18,
FF_OLD_SWIMMABLE = 0x20,
FF_OLD_NOSHADE = 0x40,
FF_OLD_CUTSOLIDS = 0x80,
FF_OLD_CUTEXTRA = 0x100,
FF_OLD_CUTLEVEL = 0x180,
FF_OLD_CUTSPRITES = 0x200,
FF_OLD_BOTHPLANES = 0x400,
FF_OLD_EXTRA = 0x800,
FF_OLD_TRANSLUCENT = 0x1000,
FF_OLD_FOG = 0x2000,
FF_OLD_INVERTPLANES = 0x4000,
FF_OLD_ALLSIDES = 0x8000,
FF_OLD_INVERTSIDES = 0x10000,
FF_OLD_DOUBLESHADOW = 0x20000,
FF_OLD_FLOATBOB = 0x40000,
FF_OLD_NORETURN = 0x80000,
FF_OLD_CRUMBLE = 0x100000,
FF_OLD_SHATTERBOTTOM = 0x200000,
FF_OLD_GOOWATER = 0x200000,
FF_OLD_MARIO = 0x400000,
FF_OLD_BUSTUP = 0x800000,
FF_OLD_QUICKSAND = 0x1000000,
FF_OLD_PLATFORM = 0x2000000,
FF_OLD_REVERSEPLATFORM = 0x4000000,
FF_OLD_INTANGIBLEFLATS = 0x6000000,
FF_OLD_SHATTER = 0x8000000,
FF_OLD_SPINBUST = 0x10000000,
FF_OLD_STRONGBUST = 0x20000000,
FF_OLD_RIPPLE = 0x40000000,
FF_OLD_COLORMAPONLY = 0x80000000,
} oldffloortype_e;
typedef enum
{
FB_PUSHABLES = 0x1, // Bustable by pushables
FB_EXECUTOR = 0x2, // Trigger linedef executor
FB_ONLYBOTTOM = 0x4, // Only bustable from below
} ffloorbustflags_e;
typedef enum
{
BT_TOUCH,
BT_SPINBUST,
BT_REGULAR,
BT_STRONG,
} busttype_e;
typedef struct ffloor_s
{
fixed_t *topheight;
@ -174,7 +228,7 @@ typedef struct ffloor_s
struct pslope_s **b_slope;
size_t secnum;
ffloortype_e flags;
ffloortype_e fofflags;
struct line_s *master;
struct sector_s *target;
@ -187,6 +241,18 @@ typedef struct ffloor_s
UINT8 blend; // blendmode
tic_t norender; // for culling
// Only relevant for FOF_BUSTUP
ffloorbustflags_e bustflags;
UINT8 busttype;
INT16 busttag;
// Only relevant for FOF_QUICKSAND
fixed_t sinkspeed;
fixed_t friction;
// Only relevant for FOF_BOUNCY
fixed_t bouncestrength;
// these are saved for netgames, so do not let Lua touch these!
ffloortype_e spawnflags; // flags the 3D floor spawned with
INT32 spawnalpha; // alpha the 3D floor spawned with
@ -205,7 +271,7 @@ typedef struct lightlist_s
extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes
INT32 flags;
ffloor_t *caster;
struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
struct pslope_s *slope; // FOF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
} lightlist_t;
@ -252,16 +318,68 @@ typedef struct pslope_s
typedef enum
{
// flipspecial - planes with effect
SF_FLIPSPECIAL_FLOOR = 1,
SF_FLIPSPECIAL_CEILING = 1<<1,
SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
MSF_FLIPSPECIAL_FLOOR = 1,
MSF_FLIPSPECIAL_CEILING = 1<<1,
MSF_FLIPSPECIAL_BOTH = (MSF_FLIPSPECIAL_FLOOR|MSF_FLIPSPECIAL_CEILING),
// triggerspecial - conditions under which plane touch causes effect
SF_TRIGGERSPECIAL_TOUCH = 1<<2,
SF_TRIGGERSPECIAL_HEADBUMP = 1<<3,
MSF_TRIGGERSPECIAL_TOUCH = 1<<2,
MSF_TRIGGERSPECIAL_HEADBUMP = 1<<3,
// triggerline - conditions for linedef executor triggering
MSF_TRIGGERLINE_PLANE = 1<<4, // require plane touch
MSF_TRIGGERLINE_MOBJ = 1<<5, // allow non-pushable mobjs to trigger
// invertprecip - inverts presence of precipitation
SF_INVERTPRECIP = 1<<4,
MSF_INVERTPRECIP = 1<<6,
MSF_GRAVITYFLIP = 1<<7,
MSF_HEATWAVE = 1<<8,
MSF_NOCLIPCAMERA = 1<<9,
} sectorflags_t;
typedef enum
{
SSF_OUTERSPACE = 1,
SSF_DOUBLESTEPUP = 1<<1,
SSF_NOSTEPDOWN = 1<<2,
SSF_WINDCURRENT = 1<<3,
SSF_CONVEYOR = 1<<4,
SSF_SPEEDPAD = 1<<5,
SSF_STARPOSTACTIVATOR = 1<<6,
SSF_EXIT = 1<<7,
SSF_SPECIALSTAGEPIT = 1<<8,
SSF_RETURNFLAG = 1<<9,
SSF_REDTEAMBASE = 1<<10,
SSF_BLUETEAMBASE = 1<<11,
SSF_FAN = 1<<12,
SSF_SUPERTRANSFORM = 1<<13,
SSF_FORCESPIN = 1<<14,
SSF_ZOOMTUBESTART = 1<<15,
SSF_ZOOMTUBEEND = 1<<16,
SSF_FINISHLINE = 1<<17,
SSF_ROPEHANG = 1<<18,
} sectorspecialflags_t;
typedef enum
{
SD_NONE = 0,
SD_GENERIC = 1,
SD_WATER = 2,
SD_FIRE = 3,
SD_LAVA = 4,
SD_ELECTRIC = 5,
SD_SPIKE = 6,
SD_DEATHPITTILT = 7,
SD_DEATHPITNOTILT = 8,
SD_INSTAKILL = 9,
SD_SPECIALSTAGE = 10,
} sectordamage_t;
typedef enum
{
TO_PLAYER = 0,
TO_ALLPLAYERS = 1,
TO_MOBJ = 2,
TO_PLAYEREMERALDS = 3, // only for binary backwards compatibility: check player emeralds
TO_PLAYERNIGHTS = 4, // only for binary backwards compatibility: check NiGHTS mare
} triggerobject_t;
typedef enum
{
@ -313,7 +431,11 @@ typedef struct sector_s
INT32 heightsec; // other sector, or -1 if no other sector
INT32 camsec; // used for camera clipping
INT32 floorlightsec, ceilinglightsec;
// floor and ceiling lighting
INT16 floorlightlevel, ceilinglightlevel;
boolean floorlightabsolute, ceilinglightabsolute; // absolute or relative to sector's light level?
INT32 floorlightsec, ceilinglightsec; // take floor/ceiling light level from another sector
INT32 crumblestate; // used for crumbling and bobbing
// list of mobjs that are at least partially in the sector
@ -337,10 +459,18 @@ typedef struct sector_s
extracolormap_t *extra_colormap;
boolean colormap_protected;
// This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity
boolean verticalflip; // If gravity < 0, then allow flipped physics
fixed_t gravity; // per-sector gravity factor
fixed_t *gravityptr; // For binary format: Read gravity from floor height of master sector
sectorflags_t flags;
sectorspecialflags_t specialflags;
UINT8 damagetype;
// Linedef executor triggering
mtag_t triggertag; // tag to call upon triggering
UINT8 triggerer; // who can trigger?
fixed_t friction;
// Sprite culling feature
struct line_s *cullheight;
@ -377,7 +507,7 @@ typedef enum
#define HORIZONSPECIAL 41
#define NUMLINEARGS 6
#define NUMLINEARGS 10
#define NUMLINESTRINGARGS 2
typedef struct line_s
@ -387,6 +517,7 @@ typedef struct line_s
vertex_t *v2;
fixed_t dx, dy; // Precalculated v2 - v1 for side checking.
angle_t angle; // Precalculated angle between dx and dy
// Animation related.
INT16 flags;

View file

@ -2128,7 +2128,7 @@ void R_DrawColumnShadowed_8(void)
{
// If the height of the light is above the column, get the colormap
// anyway because the lighting of the top should be affected.
solid = dc_lightlist[i].flags & FF_CUTSOLIDS;
solid = dc_lightlist[i].flags & FOF_CUTSOLIDS;
height = dc_lightlist[i].height >> LIGHTSCALESHIFT;
if (solid)

View file

@ -445,7 +445,7 @@ fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
// R_DoCulling
// Checks viewz and top/bottom heights of an item against culling planes
// Returns true if the item is to be culled, i.e it shouldn't be drawn!
// if ML_NOCLIMB is set, the camera view is required to be in the same area for culling to occur
// if args[1] is set, the camera view is required to be in the same area for culling to occur
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph)
{
fixed_t cullplane;
@ -454,7 +454,7 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe
return false;
cullplane = cullheight->frontsector->floorheight;
if (cullheight->flags & ML_NOCLIMB) // Group culling
if (cullheight->args[1]) // Group culling
{
if (!viewcullheight)
return false;

View file

@ -105,6 +105,7 @@ typedef struct
} spriteinfo_t;
// Portable Network Graphics
#define PNG_HEADER_SIZE (8)
boolean Picture_IsLumpPNG(const UINT8 *d, size_t s);
#define Picture_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic

View file

@ -836,13 +836,13 @@ void R_DrawSinglePlane(visplane_t *pl)
// Don't draw planes that shouldn't be drawn.
for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next)
{
if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))
if ((pl->ffloor->fofflags & FOF_CUTEXTRA) && (rover->fofflags & FOF_EXTRA))
{
if (pl->ffloor->flags & FF_EXTRA)
if (pl->ffloor->fofflags & FOF_EXTRA)
{
// The plane is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
if (((pl->ffloor->fofflags & (FOF_FOG|FOF_SWIMMABLE)) == (rover->fofflags & (FOF_FOG|FOF_SWIMMABLE)))
&& pl->height < *rover->topheight
&& pl->height > *rover->bottomheight)
return;
@ -850,9 +850,9 @@ void R_DrawSinglePlane(visplane_t *pl)
}
}
if (pl->ffloor->flags & FF_TRANSLUCENT)
if (pl->ffloor->fofflags & FOF_TRANSLUCENT)
{
spanfunctype = (pl->ffloor->master->flags & ML_EFFECT6) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
spanfunctype = (pl->ffloor->fofflags & FOF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
// Hacked up support for alpha value in software mode Tails 09-24-2002
// ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021
@ -871,14 +871,14 @@ void R_DrawSinglePlane(visplane_t *pl)
else
light = LIGHTLEVELS-1;
}
else if (pl->ffloor->flags & FF_FOG)
else if (pl->ffloor->fofflags & FOF_FOG)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
if (pl->ffloor->flags & FF_RIPPLE)
if (pl->ffloor->fofflags & FOF_RIPPLE)
{
INT32 top, bottom;

View file

@ -244,7 +244,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
rlight->flags = light->flags;
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|| (rlight->flags & FF_FOG)
|| (rlight->flags & FOF_FOG)
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
else
@ -301,7 +301,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (ds->curline->sidedef->repeatcnt)
repeats = 1 + ds->curline->sidedef->repeatcnt;
else if (ldef->flags & ML_EFFECT5)
else if (ldef->flags & ML_WRAPMIDTEX)
{
fixed_t high, low;
@ -345,7 +345,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
dc_texturemid = ds->maskedtextureheight[dc_x];
if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3))
if (curline->linedef->flags & ML_MIDPEG)
dc_texturemid += (textureheight[texnum])*times + textureheight[texnum];
else
dc_texturemid -= (textureheight[texnum])*times;
@ -387,7 +387,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
rlight = &dc_lightlist[i];
if ((rlight->flags & FF_NOSHADE))
if ((rlight->flags & FOF_NOSHADE))
continue;
if (rlight->lightnum < 0)
@ -547,7 +547,7 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor)
// Polyobjects have no ffloors, and they're handled in the conditional above.
if (pfloor->ffloor != NULL)
return (pfloor->ffloor->flags & (FF_TRANSLUCENT|FF_FOG));
return (pfloor->ffloor->fofflags & (FOF_TRANSLUCENT|FOF_FOG));
return false;
}
@ -602,7 +602,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture);
}
if (pfloor->flags & FF_TRANSLUCENT)
if (pfloor->fofflags & FOF_TRANSLUCENT)
{
boolean fuzzy = true;
@ -621,7 +621,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (fuzzy)
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
}
else if (pfloor->flags & FF_FOG)
else if (pfloor->fofflags & FOF_FOG)
colfunc = colfuncs[COLDRAWFUNC_FOG];
range = max(ds->x2-ds->x1, 1);
@ -684,7 +684,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else rlight->heightstep = CLAMPMIN;
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
rlight->flags = light->flags;
if (light->flags & FF_CUTLEVEL)
if (light->flags & FOF_CUTLEVEL)
{
SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight)
#undef SLOPEPARAMS
@ -708,12 +708,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
rlight->extra_colormap = *light->extra_colormap;
// Check if the current light effects the colormap/lightlevel
if (pfloor->flags & FF_FOG)
if (pfloor->fofflags & FOF_FOG)
rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
else
rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
if (pfloor->fofflags & FOF_FOG || rlight->flags & FOF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
;
else if (curline->v1->y == curline->v2->y)
rlight->lightnum--;
@ -730,7 +730,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// Get correct light level!
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
else if (pfloor->flags & FF_FOG)
else if (pfloor->fofflags & FOF_FOG)
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
lightnum = LIGHTLEVELS-1;
@ -738,7 +738,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
->lightlevel >> LIGHTSEGSHIFT;
if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)));
if (pfloor->fofflags & FOF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)));
else if (curline->v1->y == curline->v2->y)
lightnum--;
else if (curline->v1->x == curline->v2->x)
@ -765,10 +765,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
skewslope = *pfloor->t_slope; // skew using top slope by default
if (newline)
{
if (newline->flags & ML_DONTPEGTOP)
if (newline->flags & ML_SKEWTD)
slopeskew = true;
}
else if (pfloor->master->flags & ML_DONTPEGTOP)
else if (pfloor->master->flags & ML_SKEWTD)
slopeskew = true;
if (slopeskew)
@ -885,7 +885,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{
rlight = &dc_lightlist[i];
rlight->height += rlight->heightstep;
if (rlight->flags & FF_CUTLEVEL)
if (rlight->flags & FOF_CUTLEVEL)
rlight->botheight += rlight->botheightstep;
}
}
@ -912,7 +912,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{
// Check if the current light effects the colormap/lightlevel
rlight = &dc_lightlist[i];
lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE);
lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE);
if (lighteffect)
{
lightnum = rlight->lightnum;
@ -929,7 +929,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
if (pfloor->flags & FF_FOG)
if (pfloor->fofflags & FOF_FOG)
{
if (pfloor->master->frontsector->extra_colormap)
rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
@ -948,15 +948,15 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
solid = 0; // don't carry over solid-cutting flag from the previous light
// Check if the current light can cut the current 3D floor.
if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA))
if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA))
solid = 1;
else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA)
else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA)
{
if (rlight->flags & FF_EXTRA)
if (rlight->flags & FOF_EXTRA)
{
// The light is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE)))
if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE)))
solid = 1;
}
else
@ -993,7 +993,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{
rlight = &dc_lightlist[i];
rlight->height += rlight->heightstep;
if (rlight->flags & FF_CUTLEVEL)
if (rlight->flags & FOF_CUTLEVEL)
rlight->botheight += rlight->botheightstep;
}
continue;
@ -1024,7 +1024,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_colormap = walllights[pindex];
if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap)
dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
else if (frontsector->extra_colormap)
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
@ -1455,9 +1455,9 @@ static void R_RenderSegLoop (void)
maskedtexturecol[rw_x] = (INT16)texturecolumn;
if (maskedtextureheight != NULL) {
maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ?
maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ?
max(rw_midtexturemid, rw_midtextureback) :
min(rw_midtexturemid, rw_midtextureback));
min(rw_midtexturemid, rw_midtextureback);
}
}
@ -1466,7 +1466,7 @@ static void R_RenderSegLoop (void)
for (i = 0; i < dc_numlights; i++)
{
dc_lightlist[i].height += dc_lightlist[i].heightstep;
if (dc_lightlist[i].flags & FF_CUTSOLIDS)
if (dc_lightlist[i].flags & FOF_CUTSOLIDS)
dc_lightlist[i].botheight += dc_lightlist[i].botheightstep;
}
}
@ -1766,7 +1766,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
texheight = textureheight[midtexture];
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true;
if (linedef->flags & ML_EFFECT2) {
if (linedef->flags & ML_NOSKEW) {
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = frontsector->floorheight + texheight - viewz;
else
@ -1903,18 +1903,20 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else if (worldlow != worldbottom
|| worldlowslope != worldbottomslope
|| backsector->f_slope != frontsector->f_slope
|| backsector->floorpic != frontsector->floorpic
|| backsector->lightlevel != frontsector->lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
|| backsector->floor_xoffs != frontsector->floor_xoffs
|| backsector->floor_yoffs != frontsector->floor_yoffs
|| backsector->floorpic_angle != frontsector->floorpic_angle
//SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum)
|| backsector->floorlightsec != frontsector->floorlightsec
//SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
|| backsector->floorpic != frontsector->floorpic
|| backsector->lightlevel != frontsector->lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
|| backsector->floor_xoffs != frontsector->floor_xoffs
|| backsector->floor_yoffs != frontsector->floor_yoffs
|| backsector->floorpic_angle != frontsector->floorpic_angle
//SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum)
|| backsector->floorlightlevel != frontsector->floorlightlevel
|| backsector->floorlightabsolute != frontsector->floorlightabsolute
|| backsector->floorlightsec != frontsector->floorlightsec
//SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
{
markfloor = true;
}
@ -1934,18 +1936,20 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else if (worldhigh != worldtop
|| worldhighslope != worldtopslope
|| backsector->c_slope != frontsector->c_slope
|| backsector->ceilingpic != frontsector->ceilingpic
|| backsector->lightlevel != frontsector->lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
|| backsector->ceiling_xoffs != frontsector->ceiling_xoffs
|| backsector->ceiling_yoffs != frontsector->ceiling_yoffs
|| backsector->ceilingpic_angle != frontsector->ceilingpic_angle
//SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum)
|| backsector->ceilinglightsec != frontsector->ceilinglightsec
//SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
|| backsector->ceilingpic != frontsector->ceilingpic
|| backsector->lightlevel != frontsector->lightlevel
//SoM: 3/22/2000: Check floor x and y offsets.
|| backsector->ceiling_xoffs != frontsector->ceiling_xoffs
|| backsector->ceiling_yoffs != frontsector->ceiling_yoffs
|| backsector->ceilingpic_angle != frontsector->ceilingpic_angle
//SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum)
|| backsector->ceilinglightlevel != frontsector->ceilinglightlevel
|| backsector->ceilinglightabsolute != frontsector->ceilinglightabsolute
|| backsector->ceilinglightsec != frontsector->ceilinglightsec
//SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap
|| (frontsector->ffloors != backsector->ffloors && !Tag_Compare(&frontsector->tags, &backsector->tags)))
{
markceiling = true;
}
@ -1971,23 +1975,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
fixed_t texheight;
// top texture
if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM))
&& linedef->sidenum[1] != 0xffff)
{
// Special case... use offsets from 2nd side but only if it has a texture.
side_t *def = &sides[linedef->sidenum[1]];
toptexture = R_GetTextureNum(def->toptexture);
toptexture = R_GetTextureNum(sidedef->toptexture);
texheight = textureheight[toptexture];
if (!toptexture) //Second side has no texture, use the first side's instead.
toptexture = R_GetTextureNum(sidedef->toptexture);
texheight = textureheight[toptexture];
}
else
{
toptexture = R_GetTextureNum(sidedef->toptexture);
texheight = textureheight[toptexture];
}
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
if (!(linedef->flags & ML_SKEWTD)) { // Ignore slopes for lower/upper textures unless flag is checked
if (linedef->flags & ML_DONTPEGTOP)
rw_toptexturemid = frontsector->ceilingheight - viewz;
else
@ -2012,7 +2003,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// bottom texture
bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
if (!(linedef->flags & ML_SKEWTD)) { // Ignore slopes for lower/upper textures unless flag is checked
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_bottomtexturemid = frontsector->floorheight - viewz;
else
@ -2061,9 +2052,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
i = 0;
for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
if (!(rover->fofflags & FOF_ALLSIDES) && rover->fofflags & FOF_INVERTSIDES)
continue;
if (rover->norender == leveltime)
@ -2080,23 +2071,23 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (r2->master == rover->master) // Skip if same control line.
break;
if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES))
if (!(r2->fofflags & FOF_EXISTS) || !(r2->fofflags & FOF_RENDERSIDES))
continue;
if (r2->norender == leveltime)
continue;
if (rover->flags & FF_EXTRA)
if (rover->fofflags & FOF_EXTRA)
{
if (!(r2->flags & FF_CUTEXTRA))
if (!(r2->fofflags & FOF_CUTEXTRA))
continue;
if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
if (r2->fofflags & FOF_EXTRA && (r2->fofflags & (FOF_TRANSLUCENT|FOF_FOG)) != (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG)))
continue;
}
else
{
if (!(r2->flags & FF_CUTSOLIDS))
if (!(r2->fofflags & FOF_CUTSOLIDS))
continue;
}
@ -2119,9 +2110,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
if (!(rover->fofflags & FOF_ALLSIDES || rover->fofflags & FOF_INVERTSIDES))
continue;
if (rover->norender == leveltime)
@ -2138,23 +2129,23 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (r2->master == rover->master) // Skip if same control line.
break;
if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES))
if (!(r2->fofflags & FOF_EXISTS) || !(r2->fofflags & FOF_RENDERSIDES))
continue;
if (r2->norender == leveltime)
continue;
if (rover->flags & FF_EXTRA)
if (rover->fofflags & FOF_EXTRA)
{
if (!(r2->flags & FF_CUTEXTRA))
if (!(r2->fofflags & FOF_CUTEXTRA))
continue;
if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG)))
if (r2->fofflags & FOF_EXTRA && (r2->fofflags & (FOF_TRANSLUCENT|FOF_FOG)) != (rover->fofflags & (FOF_TRANSLUCENT|FOF_FOG)))
continue;
}
else
{
if (!(r2->flags & FF_CUTSOLIDS))
if (!(r2->fofflags & FOF_CUTSOLIDS))
continue;
}
@ -2179,9 +2170,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
if (!(rover->fofflags & FOF_ALLSIDES) && rover->fofflags & FOF_INVERTSIDES)
continue;
if (rover->norender == leveltime)
continue;
@ -2201,9 +2192,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
if (!(rover->fofflags & FOF_RENDERSIDES) || !(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
if (!(rover->fofflags & FOF_ALLSIDES || rover->fofflags & FOF_INVERTSIDES))
continue;
if (rover->norender == leveltime)
continue;
@ -2243,7 +2234,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (curline->polyseg)
{ // use REAL front and back floors please, so midtexture rendering isn't mucked up
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
if (linedef->flags & ML_MIDPEG)
rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz;
@ -2251,16 +2242,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else
{
// Set midtexture starting height
if (linedef->flags & ML_EFFECT2)
if (linedef->flags & ML_NOSKEW)
{ // Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
if (linedef->flags & ML_MIDPEG)
rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz;
}
else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
else if (linedef->flags & ML_MIDPEG)
{
rw_midtexturemid = worldbottom;
rw_midtextureslide = floorfrontslide;
@ -2425,7 +2416,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
rlight->flags = light->flags;
if (light->caster && light->caster->flags & FF_CUTSOLIDS)
if (light->caster && light->caster->fofflags & FOF_CUTSOLIDS)
{
leftheight = P_GetFFloorBottomZAt(light->caster, segleft.x, segleft.y);
rightheight = P_GetFFloorBottomZAt(light->caster, segright.x, segright.y);
@ -2512,7 +2503,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES))
continue;
if (rover->norender == leveltime)
continue;
@ -2527,8 +2518,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
((viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) ||
(viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = roverleft;
@ -2550,8 +2541,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
((viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) ||
(viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = roverleft;
@ -2569,7 +2560,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES))
continue;
if (rover->norender == leveltime)
continue;
@ -2584,8 +2575,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
((viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) ||
(viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = roverleft;
@ -2607,8 +2598,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
((viewz > planevistest && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) ||
(viewz < planevistest && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = roverleft;

View file

@ -59,6 +59,7 @@ INT32 *texturetranslation;
// Painfully simple texture id cacheing to make maps load faster. :3
static struct {
char name[9];
UINT32 hash;
INT32 id;
} *tidcache = NULL;
static INT32 tidcachelen = 0;
@ -725,6 +726,7 @@ Rloadflats (INT32 i, INT32 w)
UINT16 texstart, texend;
texture_t *texture;
texpatch_t *patch;
UINT8 header[PNG_HEADER_SIZE];
// Yes
if (W_FileHasFolders(wadfiles[w]))
@ -743,7 +745,6 @@ Rloadflats (INT32 i, INT32 w)
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
UINT8 *flatlump;
UINT16 wadnum = (UINT16)w;
lumpnum_t lumpnum = texstart + j;
size_t lumplength;
@ -755,7 +756,7 @@ Rloadflats (INT32 i, INT32 w)
continue; // If it is then SKIP IT
}
flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
switch (lumplength)
@ -788,14 +789,17 @@ Rloadflats (INT32 i, INT32 w)
// Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
texture->hash = quickncasehash(texture->name, 8);
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)flatlump, lumplength))
if (Picture_IsLumpPNG(header, lumplength))
{
UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
INT32 width, height;
Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength);
texture->width = (INT16)width;
texture->height = (INT16)height;
Z_Free(flatlump);
}
else
#endif
@ -814,8 +818,6 @@ Rloadflats (INT32 i, INT32 w)
patch->lump = texstart + j;
patch->flip = 0;
Z_Unlock(flatlump);
texturewidth[i] = texture->width;
textureheight[i] = texture->height << FRACBITS;
i++;
@ -835,8 +837,8 @@ Rloadtextures (INT32 i, INT32 w)
UINT16 j;
UINT16 texstart, texend, texturesLumpPos;
texture_t *texture;
softwarepatch_t *patchlump;
texpatch_t *patch;
softwarepatch_t patchlump;
// Get the lump numbers for the markers in the WAD, if they exist.
if (W_FileHasFolders(wadfiles[w]))
@ -876,7 +878,7 @@ Rloadtextures (INT32 i, INT32 w)
continue; // If it is then SKIP IT
}
patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
#ifndef NO_PNG_LUMPS
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
#endif
@ -886,20 +888,23 @@ Rloadtextures (INT32 i, INT32 w)
// Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
texture->hash = quickncasehash(texture->name, 8);
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)patchlump, lumplength))
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
{
UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
INT32 width, height;
Picture_PNGDimensions((UINT8 *)patchlump, &width, &height, NULL, NULL, lumplength);
Picture_PNGDimensions(png, &width, &height, NULL, NULL, lumplength);
texture->width = (INT16)width;
texture->height = (INT16)height;
Z_Free(png);
}
else
#endif
{
texture->width = SHORT(patchlump->width);
texture->height = SHORT(patchlump->height);
texture->width = SHORT(patchlump.width);
texture->height = SHORT(patchlump.height);
}
texture->type = TEXTURETYPE_SINGLEPATCH;
@ -915,8 +920,6 @@ Rloadtextures (INT32 i, INT32 w)
patch->lump = texstart + j;
patch->flip = 0;
Z_Unlock(patchlump);
texturewidth[i] = texture->width;
textureheight[i] = texture->height << FRACBITS;
i++;
@ -926,27 +929,53 @@ Rloadtextures (INT32 i, INT32 w)
return i;
}
//
// R_LoadTextures
// Initializes the texture list with the textures from the world map.
//
void R_LoadTextures(void)
static INT32
count_range
( const char * marker_start,
const char * marker_end,
const char * folder,
UINT16 wadnum)
{
INT32 i, w;
UINT16 j;
UINT16 texstart, texend, texturesLumpPos;
UINT16 texstart, texend;
INT32 count = 0;
// Free previous memory before numtextures change.
if (numtextures)
// Count flats
if (W_FileHasFolders(wadfiles[wadnum]))
{
for (i = 0; i < numtextures; i++)
{
Z_Free(textures[i]);
Z_Free(texturecache[i]);
}
Z_Free(texturetranslation);
Z_Free(textures);
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
}
else
{
texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0);
texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart);
}
if (texstart != INT16_MAX && texend != INT16_MAX)
{
// PK3s have subfolders, so we can't just make a simple sum
if (W_FileHasFolders(wadfiles[wadnum]))
{
for (j = texstart; j < texend; j++)
{
if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it
count++;
}
}
else // Add all the textures between markers
{
count += (texend - texstart);
}
}
return count;
}
static INT32 R_CountTextures(UINT16 wadnum)
{
UINT16 texturesLumpPos;
INT32 count = 0;
// Load patches and textures.
@ -955,113 +984,132 @@ void R_LoadTextures(void)
// the markers.
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
for (w = 0, numtextures = 0; w < numwadfiles; w++)
{
#ifdef WALLFLATS
// Count flats
if (W_FileHasFolders(wadfiles[w]))
{
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
}
else
{
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
}
count += count_range("F_START", "F_END", "flats/", wadnum);
#endif
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
// PK3s have subfolders, so we can't just make a simple sum
if (W_FileHasFolders(wadfiles[w]))
{
for (j = texstart; j < texend; j++)
{
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
numtextures++;
}
}
else // Add all the textures between F_START and F_END
{
numtextures += (UINT32)(texend - texstart);
}
}
#endif/*WALLFLATS*/
// Count the textures from TEXTURES lumps
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0);
// Count the textures from TEXTURES lumps
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
while (texturesLumpPos != INT16_MAX)
{
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
}
// Count single-patch textures
if (W_FileHasFolders(wadfiles[w]))
{
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
}
else
{
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
}
if (texstart == INT16_MAX || texend == INT16_MAX)
continue;
// PK3s have subfolders, so we can't just make a simple sum
if (W_FileHasFolders(wadfiles[w]))
{
for (j = texstart; j < texend; j++)
{
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
numtextures++;
}
}
else // Add all the textures between TX_START and TX_END
{
numtextures += (UINT32)(texend - texstart);
}
while (texturesLumpPos != INT16_MAX)
{
count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1);
}
// If no textures found by this point, bomb out
if (!numtextures)
I_Error("No textures detected in any WADs!\n");
// Count single-patch textures
count += count_range(TX_START, TX_END, "textures/", wadnum);
return count;
}
static void
recallocuser
( void * user,
size_t old,
size_t new)
{
char *p = Z_Realloc(*(void**)user,
new, PU_STATIC, user);
if (new > old)
memset(&p[old], 0, (new - old));
}
static void R_AllocateTextures(INT32 add)
{
const INT32 newtextures = (numtextures + add);
const size_t newsize = newtextures * sizeof (void*);
const size_t oldsize = numtextures * sizeof (void*);
INT32 i;
// Allocate memory and initialize to 0 for all the textures we are initialising.
// There are actually 5 buffers allocated in one for convenience.
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
recallocuser(&textures, oldsize, newsize);
// Allocate texture column offset table.
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
recallocuser(&texturecolumnofs, oldsize, newsize);
// Allocate texture referencing cache.
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
recallocuser(&texturecache, oldsize, newsize);
// Allocate texture width table.
texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
recallocuser(&texturewidth, oldsize, newsize);
// Allocate texture height table.
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
recallocuser(&textureheight, oldsize, newsize);
// Create translation table for global animation.
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
Z_Realloc(texturetranslation, (newtextures + 1) * sizeof(*texturetranslation), PU_STATIC, &texturetranslation);
for (i = 0; i < numtextures; i++)
texturetranslation[i] = i;
for (i = 0, w = 0; w < numwadfiles; w++)
for (i = 0; i < numtextures; ++i)
{
#ifdef WALLFLATS
i = Rloadflats(i, w);
#endif
i = Rloadtextures(i, w);
// R_FlushTextureCache relies on the user for
// Z_Free, texturecache has been reallocated so the
// user is now garbage memory.
Z_SetUser(texturecache[i],
(void**)&texturecache[i]);
}
while (i < newtextures)
{
texturetranslation[i] = i;
i++;
}
}
static INT32 R_DefineTextures(INT32 i, UINT16 w)
{
#ifdef WALLFLATS
i = Rloadflats(i, w);
#endif
return Rloadtextures(i, w);
}
static void R_FinishLoadingTextures(INT32 add)
{
numtextures += add;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_LoadMapTextures(numtextures);
#endif
}
//
// R_LoadTextures
// Initializes the texture list with the textures from the world map.
//
void R_LoadTextures(void)
{
INT32 i, w;
INT32 newtextures = 0;
for (w = 0; w < numwadfiles; w++)
{
newtextures += R_CountTextures((UINT16)w);
}
// If no textures found by this point, bomb out
if (!newtextures)
I_Error("No textures detected in any WADs!\n");
R_AllocateTextures(newtextures);
for (i = 0, w = 0; w < numwadfiles; w++)
{
i = R_DefineTextures(i, w);
}
R_FinishLoadingTextures(newtextures);
}
void R_LoadTexturesPwad(UINT16 wadnum)
{
INT32 newtextures = R_CountTextures(wadnum);
R_AllocateTextures(newtextures);
R_DefineTextures(numtextures, wadnum);
R_FinishLoadingTextures(newtextures);
}
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
{
char *texturesToken;
@ -1368,6 +1416,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
// Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily.
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t),PU_STATIC,NULL);
M_Memcpy(resultTexture->name, newTextureName, 8);
resultTexture->hash = quickncasehash(newTextureName, 8);
resultTexture->width = newTextureWidth;
resultTexture->height = newTextureHeight;
resultTexture->type = TEXTURETYPE_COMPOSITE;
@ -1594,19 +1643,22 @@ void R_ClearTextureNumCache(boolean btell)
INT32 R_CheckTextureNumForName(const char *name)
{
INT32 i;
UINT32 hash;
// "NoTexture" marker.
if (name[0] == '-')
return 0;
hash = quickncasehash(name, 8);
for (i = 0; i < tidcachelen; i++)
if (!strncasecmp(tidcache[i].name, name, 8))
if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
return tidcache[i].id;
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
//for (i = 0; i < numtextures; i++) <- old
for (i = (numtextures - 1); i >= 0; i--) // <- new
if (!strncasecmp(textures[i]->name, name, 8))
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
{
tidcachelen++;
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
@ -1615,6 +1667,7 @@ INT32 R_CheckTextureNumForName(const char *name)
#ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
#endif
tidcache[tidcachelen-1].hash = hash;
tidcache[tidcachelen-1].id = i;
return i;
}

View file

@ -54,6 +54,7 @@ typedef struct
{
// Keep name for switch changing, etc.
char name[8];
UINT32 hash;
UINT8 type; // TEXTURETYPE_
INT16 width, height;
boolean holes;
@ -76,6 +77,7 @@ extern UINT8 **texturecache; // graphics data for each generated full-size textu
// Load TEXTURES definitions, create lookup tables
void R_LoadTextures(void);
void R_LoadTexturesPwad(UINT16 wadnum);
void R_FlushTextureCache(void);
// Texture generation

View file

@ -754,13 +754,13 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
else if (vis->mobj->type == MT_METALSONIC_BATTLE)
return R_GetTranslationColormap(TC_METALSONIC, 0, GTC_CACHE);
else
return R_GetTranslationColormap(TC_BOSS, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap(TC_BOSS, vis->color, GTC_CACHE);
}
else if (vis->mobj->color)
else if (vis->color)
{
// New colormap stuff for skins Tails 06-07-2002
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
return R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap(TC_RAINBOW, vis->color, GTC_CACHE);
else if (!(vis->cut & SC_PRECIP)
&& vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD
&& (vis->mobj->player->charflags & SF_DASHMODE)
@ -769,15 +769,15 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
if (vis->mobj->player->charflags & SF_MACHINE)
return R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
else
return R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap(TC_RAINBOW, vis->color, GTC_CACHE);
}
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
{
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
return R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap((INT32)skinnum, vis->color, GTC_CACHE);
}
else // Use the defaults
return R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color, GTC_CACHE);
return R_GetTranslationColormap(TC_DEFAULT, vis->color, GTC_CACHE);
}
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
return R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE);
@ -822,7 +822,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (R_SpriteIsFlashing(vis)) // Bosses "flash"
colfunc = colfuncs[COLDRAWFUNC_TRANS]; // translate certain pixels to white
else if (vis->mobj->color && vis->transmap) // Color mapping
else if (vis->color && vis->transmap) // Color mapping
{
colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS];
dc_transmap = vis->transmap;
@ -832,7 +832,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table
}
else if (vis->mobj->color) // translate green skin to another color
else if (vis->color) // translate green skin to another color
colfunc = colfuncs[COLDRAWFUNC_TRANS];
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
colfunc = colfuncs[COLDRAWFUNC_TRANS];
@ -1055,7 +1055,7 @@ static void R_SplitSprite(vissprite_t *sprite)
{
fixed_t testheight;
if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES))
if (!(sector->lightlist[i].caster->fofflags & FOF_CUTSPRITES))
continue;
testheight = P_GetLightZAt(&sector->lightlist[i], sprite->gx, sprite->gy);
@ -1096,7 +1096,7 @@ static void R_SplitSprite(vissprite_t *sprite)
newsprite->szt -= 8;
newsprite->cut |= SC_TOP;
if (!(sector->lightlist[i].caster->flags & FF_NOSHADE))
if (!(sector->lightlist[i].caster->fofflags & FOF_NOSHADE))
{
lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
@ -1162,7 +1162,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
if (sector->ffloors)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES) || (rover->alpha < 90 && !(rover->fofflags & FOF_SWIMMABLE)))
continue;
z = isflipped ? P_GetFFloorBottomZAt(rover, thing->x, thing->y) : P_GetFFloorTopZAt(rover, thing->x, thing->y);
@ -1275,6 +1275,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
vissprite_t *shadow;
patch_t *patch;
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
INT32 heightsec, phs;
INT32 light = 0;
fixed_t scalemul; UINT8 trans;
fixed_t floordiff;
@ -1286,6 +1287,24 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
heightsec = thing->subsector->sector->heightsec;
if (viewplayer->mo && viewplayer->mo->subsector)
phs = viewplayer->mo->subsector->sector->heightsec;
else
phs = -1;
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
{
if (viewz < sectors[phs].floorheight ?
groundz >= sectors[heightsec].floorheight :
groundz < sectors[heightsec].floorheight)
return;
if (viewz > sectors[phs].ceilingheight ?
groundz < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
groundz >= sectors[heightsec].ceilingheight)
return;
}
floordiff = abs((isflipped ? thing->height : 0) + thing->z - groundz);
trans = floordiff / (100*FRACUNIT) + 3;
@ -1337,6 +1356,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->shear.tan = shadowskew; // repurposed variable
shadow->mobj = thing; // Easy access! Tails 06-07-2002
shadow->color = thing->color;
shadow->x1 = x1 < portalclipstart ? portalclipstart : x1;
shadow->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
@ -1592,7 +1612,16 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->rollangle
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
{
rollangle = R_GetRollAngle(thing->rollangle);
if (papersprite && ang >= ANGLE_180)
{
// Makes Software act much more sane like OpenGL
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
}
else
{
rollangle = R_GetRollAngle(thing->rollangle);
}
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
if (rotsprite != NULL)
@ -1942,13 +1971,19 @@ static void R_ProjectSprite(mobj_t *thing)
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
{
fixed_t top = gzt;
fixed_t bottom = thing->z;
if (splat)
top = bottom;
if (viewz < sectors[phs].floorheight ?
thing->z >= sectors[heightsec].floorheight :
gzt < sectors[heightsec].floorheight)
bottom >= sectors[heightsec].floorheight :
top < sectors[heightsec].floorheight)
return;
if (viewz > sectors[phs].ceilingheight ?
gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
thing->z >= sectors[heightsec].ceilingheight)
top < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight :
bottom >= sectors[heightsec].ceilingheight)
return;
}
@ -1981,6 +2016,10 @@ static void R_ProjectSprite(mobj_t *thing)
vis->viewpoint.angle = viewangle;
vis->mobj = thing; // Easy access! Tails 06-07-2002
if ((oldthing->flags2 & MF2_LINKDRAW) && oldthing->tracer && oldthing->color == SKINCOLOR_NONE)
vis->color = oldthing->tracer->color;
else
vis->color = oldthing->color;
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
@ -2234,6 +2273,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->cut = SC_PRECIP;
vis->extra_colormap = thing->subsector->sector->extra_colormap;
vis->heightsec = thing->subsector->sector->heightsec;
vis->color = SKINCOLOR_NONE;
// Fullbright
vis->colormap = colormaps;
@ -2822,6 +2862,57 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr)
R_DrawPrecipitationVisSprite(spr);
}
//SoM: 3/17/2000: Clip sprites in water.
static void R_HeightSecClip(vissprite_t *spr, INT32 x1, INT32 x2)
{
fixed_t mh, h;
INT32 x, phs;
if (spr->heightsec == -1)
return;
if (spr->cut & (SC_SPLAT | SC_SHADOW) || spr->renderflags & RF_SHADOWDRAW)
return;
phs = viewplayer->mo->subsector->sector->heightsec;
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
(h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight)
{
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
{ // clip bottom
for (x = x1; x <= x2; x++)
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
spr->clipbot[x] = (INT16)h;
}
else // clip top
{
for (x = x1; x <= x2; x++)
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
spr->cliptop[x] = (INT16)h;
}
}
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
(h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight)
{
if (phs != -1 && viewz >= sectors[phs].ceilingheight)
{ // clip bottom
for (x = x1; x <= x2; x++)
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
spr->clipbot[x] = (INT16)h;
}
else // clip top
{
for (x = x1; x <= x2; x++)
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
spr->cliptop[x] = (INT16)h;
}
}
}
// R_ClipVisSprite
// Clips vissprites without drawing, so that portals can work. -Red
void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal)
@ -2923,47 +3014,9 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p
}
}
}
//SoM: 3/17/2000: Clip sprites in water.
if (spr->heightsec != -1) // only things in specially marked sectors
{
fixed_t mh, h;
INT32 phs = viewplayer->mo->subsector->sector->heightsec;
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
(h = centeryfrac - FixedMul(mh -= viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight)
{
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
{ // clip bottom
for (x = x1; x <= x2; x++)
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
spr->clipbot[x] = (INT16)h;
}
else // clip top
{
for (x = x1; x <= x2; x++)
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
spr->cliptop[x] = (INT16)h;
}
}
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
(h = centeryfrac - FixedMul(mh-viewz, spr->sortscale)) >= 0 &&
(h >>= FRACBITS) < viewheight)
{
if (phs != -1 && viewz >= sectors[phs].ceilingheight)
{ // clip bottom
for (x = x1; x <= x2; x++)
if (spr->clipbot[x] == -2 || h < spr->clipbot[x])
spr->clipbot[x] = (INT16)h;
}
else // clip top
{
for (x = x1; x <= x2; x++)
if (spr->cliptop[x] == -2 || h > spr->cliptop[x])
spr->cliptop[x] = (INT16)h;
}
}
}
R_HeightSecClip(spr, x1, x2);
if (spr->cut & SC_TOP && spr->cut & SC_BOTTOM)
{
for (x = x1; x <= x2; x++)

Some files were not shown because too many files have changed in this diff Show more