ref: a8de7d9027b678cdc44da8ef85a121c70e6b8c5c
dir: /p_anim.c/
//************************************************************************** //** //** p_anim.c : Heretic 2 : Raven Software, Corp. //** //** $Revision: 373 $ //** $Date: 2009-05-19 21:14:28 +0300 (Tue, 19 May 2009) $ //** //************************************************************************** // HEADER FILES ------------------------------------------------------------ #include "h2stdinc.h" #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(); }