123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- #include <stdlib.h>
- #include "engine.h"
- #include "sectorfx.h"
- #include "globals.h"
- #include "db.h"
- #include "misc.h"
- #include "trig.h"
- #include "debug4g.h"
- #include <memcheck.h>
- #define kPanScale 8
- short shadeList[kMaxXSectors];
- short panList[kMaxXSectors];
- int shadeCount = 0, panCount = 0;
- short wallPanList[kMaxXSectors];
- int wallPanCount = 0;
- int gDepth[] =
- {
- 0, // kDepthWalk
- 15 << 8, // kDepthTread
- 30 << 8, // kDepthWade
- 40 << 8 // kDepthSwim
- };
- // monotonic flicker -- very doom like
- static char flicker1[] = {
- 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0,
- 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1,
- };
- // organic flicker -- good for torches
- static char flicker2[] = {
- 1, 2, 4, 2, 3, 4, 3, 2, 0, 0, 1, 2, 4, 3, 2, 0,
- 2, 1, 0, 1, 0, 2, 3, 4, 3, 2, 1, 1, 2, 0, 0, 1,
- 1, 2, 3, 4, 4, 3, 2, 1, 2, 3, 4, 4, 2, 1, 0, 1,
- 0, 0, 0, 0, 1, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2,
- };
- // mostly on flicker -- good for flaky fluourescents
- static char flicker3[] = {
- 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 2, 4, 3, 4, 4,
- 4, 4, 2, 1, 3, 3, 3, 4, 3, 4, 4, 4, 4, 4, 2, 4,
- 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 1, 0, 1,
- 0, 1, 0, 1, 0, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3, 4,
- };
- // not yet done (same as 2 for now)
- static char flicker4[] = {
- 1, 2, 4, 2, 3, 4, 3, 2, 0, 0, 1, 2, 4, 3, 2, 0,
- 2, 1, 0, 1, 0, 2, 3, 4, 3, 2, 1, 1, 2, 0, 0, 1,
- 1, 2, 3, 4, 4, 3, 2, 1, 2, 3, 4, 4, 2, 1, 0, 1,
- 0, 0, 0, 0, 1, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2,
- };
- static char strobe[] = {
- 64, 64, 64, 48, 36, 27, 20, 15, 11, 9, 6, 5, 4, 3, 2, 2,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
- static int GetWaveValue( int nWave, long time, int freq, int amplitude )
- {
- switch (nWave)
- {
- case kWaveNone:
- return amplitude;
- case kWaveSquare:
- return ((time * freq >> 11) & 1) * amplitude;
- case kWaveSaw:
- return abs(0x80 - ((time * freq >> 4) & 0xFF)) * amplitude >> 7;
- case kWaveRampup:
- return ((time * freq >> 4) & 0xFF) * amplitude >> 8;
- case kWaveRampdown:
- return (0xFF - ((time * freq >> 4) & 0xFF)) * amplitude >> 8;
- case kWaveSine:
- return (amplitude + mulscale30(amplitude, Sin(time * freq >> 1))) >> 1;
- case kWaveFlicker1:
- return flicker1[(time * freq >> 6) & 0x3F] * amplitude;
- case kWaveFlicker2:
- return flicker2[(time * freq >> 6) & 0x3F] * amplitude >> 2;
- case kWaveFlicker3:
- return flicker3[(time * freq >> 6) & 0x3F] * amplitude >> 2;
- case kWaveFlicker4:
- return flicker4[(time * freq >> 6) & 0x3F] * amplitude >> 2;
- case kWaveStrobe:
- return strobe[(time * freq >> 6) & 0x3F] * amplitude >> 6;
- case kWaveSearch:
- {
- int phi = ((time * freq >> 1) & kAngleMask) << 2;
- if (phi > kAngle360)
- return 0;
- return (amplitude - mulscale30(amplitude, Cos(phi))) >> 1;
- }
- }
- return 0;
- };
- void DoSectorLighting( void )
- {
- int i, nXSector, nSector;
- int nWave, freq, amplitude, value;
- int nWall, startwall, endwall;
- for (i = 0; i < shadeCount; i++)
- {
- nXSector = shadeList[i];
- XSECTOR *pXSector = &xsector[nXSector];
- nSector = pXSector->reference;
- dassert(sector[nSector].extra == nXSector);
- // undo previous lighting
- if ( pXSector->shade != 0 )
- {
- value = pXSector->shade;
- if ( pXSector->shadeFloor )
- sector[nSector].floorshade = (schar)(sector[nSector].floorshade - value);
- if ( pXSector->shadeCeiling )
- sector[nSector].ceilingshade = (schar)(sector[nSector].ceilingshade - value);
- if ( pXSector->shadeWalls )
- {
- startwall = sector[nSector].wallptr;
- endwall = startwall + sector[nSector].wallnum-1;
- for (nWall = startwall; nWall <= endwall; nWall++)
- wall[nWall].shade = (schar)(wall[nWall].shade - value);
- }
- pXSector->shade = 0;
- }
- if ( pXSector->shadeAlways || pXSector->busy )
- {
- freq = pXSector->freq;
- nWave = pXSector->wave;
- amplitude = pXSector->amplitude;
- if ( !pXSector->shadeAlways && pXSector->busy )
- amplitude = mulscale16(amplitude, pXSector->busy);
- value = GetWaveValue(nWave, gFrameClock + pXSector->phase, freq, amplitude);
- if ( pXSector->shadeFloor )
- sector[nSector].floorshade = (schar)ClipRange(sector[nSector].floorshade + value, -128, 127);
- if ( pXSector->shadeCeiling )
- sector[nSector].ceilingshade = (schar)ClipRange(sector[nSector].ceilingshade + value, -128, 127);
- if ( pXSector->shadeWalls )
- {
- startwall = sector[nSector].wallptr;
- endwall = startwall + sector[nSector].wallnum-1;
- for (nWall = startwall; nWall <= endwall; nWall++)
- wall[nWall].shade = (schar)ClipRange(wall[nWall].shade + value, -128, 127);
- }
- pXSector->shade = value;
- }
- }
- }
- void UndoSectorLighting( void ) // should be used only in mapedit
- {
- int nXSector, nSector;
- int value;
- int nWall, startwall, endwall;
- for (nSector = 0; nSector < numsectors; nSector++)
- {
- nXSector = sector[nSector].extra;
- if (nXSector <= 0)
- continue;
- XSECTOR *pXSector = &xsector[nXSector];
- if ( pXSector->shade != 0 )
- {
- value = pXSector->shade;
- if ( pXSector->shadeFloor )
- sector[nSector].floorshade = (schar)(sector[nSector].floorshade - value);
- if ( pXSector->shadeCeiling )
- sector[nSector].ceilingshade = (schar)(sector[nSector].ceilingshade - value);
- if ( pXSector->shadeWalls )
- {
- startwall = sector[nSector].wallptr;
- endwall = startwall + sector[nSector].wallnum-1;
- for (nWall = startwall; nWall <= endwall; nWall++)
- wall[nWall].shade = (schar)(wall[nWall].shade - value);
- }
- pXSector->shade = 0;
- }
- }
- }
- void DoSectorPanning( void )
- {
- int i;
- for (i = 0; i < panCount; i++)
- {
- int nXSector = panList[i];
- XSECTOR *pXSector = &xsector[nXSector];
- int nSector = pXSector->reference;
- dassert(nSector >= 0 && nSector < kMaxSectors);
- SECTOR *pSector = §or[nSector];
- dassert(pSector->extra == nXSector);
- if ( pXSector->panAlways || pXSector->busy )
- {
- int panAngle = (pXSector->panAngle - kAngle90) & kAngleMask;
- int panVel = pXSector->panVel << kPanScale;
- if ( !pXSector->panAlways && (pXSector->busy & kFluxMask) )
- panVel = mulscale16(panVel, pXSector->busy);
- if ( pXSector->panFloor )
- {
- int nTile = pSector->floorpicnum;
- int panX = (pSector->floorxpanning << 8) + pXSector->floorxpanFrac;
- int panY = (pSector->floorypanning << 8) + pXSector->floorypanFrac;
- panX += mulscale30(kFrameTicks * panVel, Cos(panAngle)) >>
- ((picsiz[nTile] & 0xF) - (pSector->floorstat & kSectorExpand ? 1 : 0));
- panY += mulscale30(kFrameTicks * panVel, Sin(panAngle)) >>
- ((picsiz[nTile] / 16) - (pSector->floorstat & kSectorExpand ? 1 : 0));
- pSector->floorxpanning = (char)(panX >> 8);
- pSector->floorypanning = (char)(panY >> 8);
- pXSector->floorxpanFrac = panX & 0xFF;
- pXSector->floorypanFrac = panY & 0xFF;
- }
- if ( pXSector->panCeiling )
- {
- int nTile = pSector->ceilingpicnum;
- int panX = (pSector->ceilingxpanning << 8) + pXSector->ceilxpanFrac;
- int panY = (pSector->ceilingypanning << 8) + pXSector->ceilypanFrac;
- panX += mulscale30(kFrameTicks * panVel, Cos(panAngle)) >>
- ((picsiz[nTile] & 0xF) - (pSector->ceilingstat & kSectorExpand ? 1 : 0));
- panY += mulscale30(kFrameTicks * panVel, Sin(panAngle)) >>
- ((picsiz[nTile] / 16) - (pSector->ceilingstat & kSectorExpand ? 1 : 0));
- pSector->ceilingxpanning = (char)(panX >> 8);
- pSector->ceilingypanning = (char)(panY >> 8);
- pXSector->ceilxpanFrac = panX & 0xFF;
- pXSector->ceilypanFrac = panY & 0xFF;
- }
- }
- }
- for (i = 0; i < wallPanCount; i++)
- {
- int nXWall = wallPanList[i];
- XWALL *pXWall = &xwall[nXWall];
- int nWall = pXWall->reference;
- dassert(wall[nWall].extra == nXWall);
- if ( pXWall->panAlways || pXWall->busy )
- {
- int panXVel = pXWall->panXVel << 8;
- int panYVel = pXWall->panYVel << 8;
- if ( !pXWall->panAlways && (pXWall->busy & kFluxMask) )
- {
- panXVel = mulscale16(panXVel, pXWall->busy);
- panYVel = mulscale16(panYVel, pXWall->busy);
- }
- int nTile = wall[nWall].picnum;
- int panX = (wall[nWall].xpanning << 8) + pXWall->xpanFrac;
- int panY = (wall[nWall].ypanning << 8) + pXWall->ypanFrac;
- panX += kFrameTicks * panXVel >> (picsiz[nTile] & 0xF);
- panY += kFrameTicks * panYVel >> (picsiz[nTile] / 16);
- wall[nWall].xpanning = (char)(panX >> 8);
- wall[nWall].ypanning = (char)(panY >> 8);
- pXWall->xpanFrac = panX & 0xFF;
- pXWall->ypanFrac = panY & 0xFF;
- }
- }
- }
- void InitSectorFX( void )
- {
- int i;
- shadeCount = 0;
- panCount = 0;
- wallPanCount = 0;
- for (i = 0; i < numsectors; i++)
- {
- short nXSector = sector[i].extra;
- if ( nXSector > 0 )
- {
- XSECTOR *pXSector = &xsector[nXSector];
- if ( pXSector->amplitude != 0 )
- shadeList[shadeCount++] = nXSector;
- if ( pXSector->panVel != 0 )
- panList[panCount++] = nXSector;
- }
- }
- for (i = 0; i < numwalls; i++)
- {
- short nXWall = wall[i].extra;
- if ( nXWall > 0 )
- {
- XWALL *pXWall = &xwall[nXWall];
- if ( pXWall->panXVel != 0 || pXWall->panYVel != 0)
- wallPanList[wallPanCount++] = nXWall;
- }
- }
- }
|