summaryrefslogtreecommitdiff
path: root/src/hexen/p_anim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hexen/p_anim.c')
-rw-r--r--src/hexen/p_anim.c473
1 files changed, 473 insertions, 0 deletions
diff --git a/src/hexen/p_anim.c b/src/hexen/p_anim.c
new file mode 100644
index 00000000..f0605b84
--- /dev/null
+++ b/src/hexen/p_anim.c
@@ -0,0 +1,473 @@
+
+//**************************************************************************
+//**
+//** p_anim.c : Heretic 2 : Raven Software, Corp.
+//**
+//** $RCSfile: p_anim.c,v $
+//** $Revision: 1.9 $
+//** $Date: 95/07/17 18:50:37 $
+//** $Author: bgokey $
+//**
+//**************************************************************************
+
+// HEADER FILES ------------------------------------------------------------
+
+#include "h2def.h"
+#include "p_local.h"
+
+// MACROS ------------------------------------------------------------------
+
+#define ANIM_SCRIPT_NAME "ANIMDEFS"
+#define MAX_ANIM_DEFS 20
+#define MAX_FRAME_DEFS 96
+#define ANIM_FLAT 0
+#define ANIM_TEXTURE 1
+#define SCI_FLAT "flat"
+#define SCI_TEXTURE "texture"
+#define SCI_PIC "pic"
+#define SCI_TICS "tics"
+#define SCI_RAND "rand"
+
+#define LIGHTNING_SPECIAL 198
+#define LIGHTNING_SPECIAL2 199
+#define SKYCHANGE_SPECIAL 200
+
+// TYPES -------------------------------------------------------------------
+
+typedef struct
+{
+ int index;
+ int tics;
+} frameDef_t;
+
+typedef struct
+{
+ int type;
+ int index;
+ int tics;
+ int currentFrameDef;
+ int startFrameDef;
+ int endFrameDef;
+} animDef_t;
+
+// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
+
+// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
+
+// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
+
+static void P_LightningFlash(void);
+
+// EXTERNAL DATA DECLARATIONS ----------------------------------------------
+
+extern fixed_t Sky1ColumnOffset;
+extern fixed_t Sky2ColumnOffset;
+extern int Sky1Texture;
+extern boolean DoubleSky;
+
+// PUBLIC DATA DEFINITIONS -------------------------------------------------
+
+fixed_t Sky1ScrollDelta;
+fixed_t Sky2ScrollDelta;
+
+// PRIVATE DATA DEFINITIONS ------------------------------------------------
+
+static animDef_t AnimDefs[MAX_ANIM_DEFS];
+static frameDef_t FrameDefs[MAX_FRAME_DEFS];
+static int AnimDefCount;
+static boolean LevelHasLightning;
+static int NextLightningFlash;
+static int LightningFlash;
+static int *LightningLightLevels;
+
+// CODE --------------------------------------------------------------------
+
+//==========================================================================
+//
+// P_AnimateSurfaces
+//
+//==========================================================================
+
+void P_AnimateSurfaces(void)
+{
+ int i;
+ animDef_t *ad;
+ line_t *line;
+
+ // Animate flats and textures
+ for(i = 0; i < AnimDefCount; i++)
+ {
+ ad = &AnimDefs[i];
+ ad->tics--;
+ if(ad->tics == 0)
+ {
+ if(ad->currentFrameDef == ad->endFrameDef)
+ {
+ ad->currentFrameDef = ad->startFrameDef;
+ }
+ else
+ {
+ ad->currentFrameDef++;
+ }
+ ad->tics = FrameDefs[ad->currentFrameDef].tics;
+ if(ad->tics > 255)
+ { // Random tics
+ ad->tics = (ad->tics>>16)
+ +P_Random()%((ad->tics&0xff00)>>8);
+ }
+ if(ad->type == ANIM_FLAT)
+ {
+ flattranslation[ad->index] =
+ FrameDefs[ad->currentFrameDef].index;
+ }
+ else
+ { // Texture
+ texturetranslation[ad->index] =
+ FrameDefs[ad->currentFrameDef].index;
+ }
+ }
+ }
+
+ // Update scrolling textures
+ for(i = 0; i < numlinespecials; i++)
+ {
+ line = linespeciallist[i];
+ switch(line->special)
+ {
+ case 100: // Scroll_Texture_Left
+ sides[line->sidenum[0]].textureoffset += line->arg1<<10;
+ break;
+ case 101: // Scroll_Texture_Right
+ sides[line->sidenum[0]].textureoffset -= line->arg1<<10;
+ break;
+ case 102: // Scroll_Texture_Up
+ sides[line->sidenum[0]].rowoffset += line->arg1<<10;
+ break;
+ case 103: // Scroll_Texture_Down
+ sides[line->sidenum[0]].rowoffset -= line->arg1<<10;
+ break;
+ }
+ }
+
+ // Update sky column offsets
+ Sky1ColumnOffset += Sky1ScrollDelta;
+ Sky2ColumnOffset += Sky2ScrollDelta;
+
+ if(LevelHasLightning)
+ {
+ if(!NextLightningFlash || LightningFlash)
+ {
+ P_LightningFlash();
+ }
+ else
+ {
+ NextLightningFlash--;
+ }
+ }
+}
+
+//==========================================================================
+//
+// P_LightningFlash
+//
+//==========================================================================
+
+static void P_LightningFlash(void)
+{
+ int i;
+ sector_t *tempSec;
+ int *tempLight;
+ boolean foundSec;
+ int flashLight;
+
+ if(LightningFlash)
+ {
+ LightningFlash--;
+ if(LightningFlash)
+ {
+ tempLight = LightningLightLevels;
+ tempSec = sectors;
+ for(i = 0; i < numsectors; i++, tempSec++)
+ {
+ if(tempSec->ceilingpic == skyflatnum
+ || tempSec->special == LIGHTNING_SPECIAL
+ || tempSec->special == LIGHTNING_SPECIAL2)
+ {
+ if(*tempLight < tempSec->lightlevel-4)
+ {
+ tempSec->lightlevel -= 4;
+ }
+ tempLight++;
+ }
+ }
+ }
+ else
+ { // remove the alternate lightning flash special
+ tempLight = LightningLightLevels;
+ tempSec = sectors;
+ for(i = 0; i < numsectors; i++, tempSec++)
+ {
+ if(tempSec->ceilingpic == skyflatnum
+ || tempSec->special == LIGHTNING_SPECIAL
+ || tempSec->special == LIGHTNING_SPECIAL2)
+ {
+ tempSec->lightlevel = *tempLight;
+ tempLight++;
+ }
+ }
+ Sky1Texture = P_GetMapSky1Texture(gamemap);
+ }
+ return;
+ }
+ LightningFlash = (P_Random()&7)+8;
+ flashLight = 200+(P_Random()&31);
+ tempSec = sectors;
+ tempLight = LightningLightLevels;
+ foundSec = false;
+ for(i = 0; i < numsectors; i++, tempSec++)
+ {
+ if(tempSec->ceilingpic == skyflatnum
+ || tempSec->special == LIGHTNING_SPECIAL
+ || tempSec->special == LIGHTNING_SPECIAL2)
+ {
+ *tempLight = tempSec->lightlevel;
+ if(tempSec->special == LIGHTNING_SPECIAL)
+ {
+ tempSec->lightlevel += 64;
+ if(tempSec->lightlevel > flashLight)
+ {
+ tempSec->lightlevel = flashLight;
+ }
+ }
+ else if(tempSec->special == LIGHTNING_SPECIAL2)
+ {
+ tempSec->lightlevel += 32;
+ if(tempSec->lightlevel > flashLight)
+ {
+ tempSec->lightlevel = flashLight;
+ }
+ }
+ else
+ {
+ tempSec->lightlevel = flashLight;
+ }
+ if(tempSec->lightlevel < *tempLight)
+ {
+ tempSec->lightlevel = *tempLight;
+ }
+ tempLight++;
+ foundSec = true;
+ }
+ }
+ if(foundSec)
+ {
+ Sky1Texture = P_GetMapSky2Texture(gamemap); // set alternate sky
+ S_StartSound(NULL, SFX_THUNDER_CRASH);
+ }
+ // Calculate the next lighting flash
+ if(!NextLightningFlash)
+ {
+ if(P_Random() < 50)
+ { // Immediate Quick flash
+ NextLightningFlash = (P_Random()&15)+16;
+ }
+ else
+ {
+ if(P_Random() < 128 && !(leveltime&32))
+ {
+ NextLightningFlash = ((P_Random()&7)+2)*35;
+ }
+ else
+ {
+ NextLightningFlash = ((P_Random()&15)+5)*35;
+ }
+ }
+ }
+}
+
+//==========================================================================
+//
+// P_ForceLightning
+//
+//==========================================================================
+
+void P_ForceLightning(void)
+{
+ NextLightningFlash = 0;
+}
+
+//==========================================================================
+//
+// P_InitLightning
+//
+//==========================================================================
+
+void P_InitLightning(void)
+{
+ int i;
+ int secCount;
+
+ if(!P_GetMapLightning(gamemap))
+ {
+ LevelHasLightning = false;
+ LightningFlash = 0;
+ return;
+ }
+ LightningFlash = 0;
+ secCount = 0;
+ for(i = 0; i < numsectors; i++)
+ {
+ if(sectors[i].ceilingpic == skyflatnum
+ || sectors[i].special == LIGHTNING_SPECIAL
+ || sectors[i].special == LIGHTNING_SPECIAL2)
+ {
+ secCount++;
+ }
+ }
+ if(secCount)
+ {
+ LevelHasLightning = true;
+ }
+ else
+ {
+ LevelHasLightning = false;
+ return;
+ }
+ LightningLightLevels = (int *)Z_Malloc(secCount*sizeof(int), PU_LEVEL,
+ NULL);
+ NextLightningFlash = ((P_Random()&15)+5)*35; // don't flash at level start
+}
+
+//==========================================================================
+//
+// P_InitFTAnims
+//
+// Initialize flat and texture animation lists.
+//
+//==========================================================================
+
+void P_InitFTAnims(void)
+{
+ int base;
+ int mod;
+ int fd;
+ animDef_t *ad;
+ boolean ignore;
+ boolean done;
+
+ fd = 0;
+ ad = AnimDefs;
+ AnimDefCount = 0;
+ SC_Open(ANIM_SCRIPT_NAME);
+ while(SC_GetString())
+ {
+ if(AnimDefCount == MAX_ANIM_DEFS)
+ {
+ I_Error("P_InitFTAnims: too many AnimDefs.");
+ }
+ if(SC_Compare(SCI_FLAT))
+ {
+ ad->type = ANIM_FLAT;
+ }
+ else if(SC_Compare(SCI_TEXTURE))
+ {
+ ad->type = ANIM_TEXTURE;
+ }
+ else
+ {
+ SC_ScriptError(NULL);
+ }
+ SC_MustGetString(); // Name
+ ignore = false;
+ if(ad->type == ANIM_FLAT)
+ {
+ if(W_CheckNumForName(sc_String) == -1)
+ {
+ ignore = true;
+ }
+ else
+ {
+ ad->index = R_FlatNumForName(sc_String);
+ }
+ }
+ else
+ { // Texture
+ if(R_CheckTextureNumForName(sc_String) == -1)
+ {
+ ignore = true;
+ }
+ else
+ {
+ ad->index = R_TextureNumForName(sc_String);
+ }
+ }
+ ad->startFrameDef = fd;
+ done = false;
+ while(done == false)
+ {
+ if(SC_GetString())
+ {
+ if(SC_Compare(SCI_PIC))
+ {
+ if(fd == MAX_FRAME_DEFS)
+ {
+ I_Error("P_InitFTAnims: too many FrameDefs.");
+ }
+ SC_MustGetNumber();
+ if(ignore == false)
+ {
+ FrameDefs[fd].index = ad->index+sc_Number-1;
+ }
+ SC_MustGetString();
+ if(SC_Compare(SCI_TICS))
+ {
+ SC_MustGetNumber();
+ if(ignore == false)
+ {
+ FrameDefs[fd].tics = sc_Number;
+ fd++;
+ }
+ }
+ else if(SC_Compare(SCI_RAND))
+ {
+ SC_MustGetNumber();
+ base = sc_Number;
+ SC_MustGetNumber();
+ if(ignore == false)
+ {
+ mod = sc_Number-base+1;
+ FrameDefs[fd].tics = (base<<16)+(mod<<8);
+ fd++;
+ }
+ }
+ else
+ {
+ SC_ScriptError(NULL);
+ }
+ }
+ else
+ {
+ SC_UnGet();
+ done = true;
+ }
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ if((ignore == false) && (fd-ad->startFrameDef < 2))
+ {
+ I_Error("P_InitFTAnims: AnimDef has framecount < 2.");
+ }
+ if(ignore == false)
+ {
+ ad->endFrameDef = fd-1;
+ ad->currentFrameDef = ad->endFrameDef;
+ ad->tics = 1; // Force 1st game tic to animate
+ AnimDefCount++;
+ ad++;
+ }
+ }
+ SC_Close();
+}