convert line ends
[canaan.git] / prj / cam / src / actreact / ssrclife.cpp
blob37d624543788efcbf0d22f7958f90c8c34883d63
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/actreact/ssrclife.cpp,v 1.5 1998/10/05 17:28:14 mahk Exp $
7 #include <ssrclife.h>
8 #include <sdesbase.h>
9 #include <iobjsys.h>
10 #include <stimbase.h>
13 // Must be last header
14 #include <dbmem.h>
17 ////////////////////////////////////////////////////////////
18 // PERIODIC LIFE CYCLE IMPL
21 //------------------------------------------------------------
22 // STRUCT DESC
25 static const char* periodic_flags[] =
27 "No Max Firings" ,
28 "Destroy Object on Completion"
31 #define NUM_PERIODIC_FLAGS (sizeof(periodic_flags)/sizeof(periodic_flags[0]))
34 static sFieldDesc periodic_fields[] =
36 { "Flags", kFieldTypeBits, FieldLocation(sPeriodicLifeCycle,flags), kFieldFlagNone, 0, NUM_PERIODIC_FLAGS, NUM_PERIODIC_FLAGS, periodic_flags },
37 { "Period", kFieldTypeInt, FieldLocation(sPeriodicLifeCycle,period), kFieldFlagUnsigned },
38 { "Max Firings", kFieldTypeInt, FieldLocation(sPeriodicLifeCycle,max_firings) },
39 { "Intensity Slope", kFieldTypeFloat, FieldLocation(sPeriodicLifeCycle,slope) },
42 static sStructDesc periodic_sdesc = StructDescBuild(sPeriodicLifeCycle,kStructFlagNone,periodic_fields);
44 const sStructDesc* sPeriodicLifeCycle::gpDesc = &periodic_sdesc;
46 //------------------------------------------------------------
47 // Firing Iterator
50 struct sPeriodicLifeCycleFire
52 // our life cycle
53 sPeriodicLifeCycle& life;
55 typedef tStimTimeStamp tTime;
57 // config variables
58 tTime start;
59 tTime last;
60 tTime now;
61 tStimLevel level;
63 // iteration variables
64 tTime t;
65 int i;
67 int to_fire;
69 sPeriodicLifeCycleFire(sPeriodicLifeCycle* plife, BOOL initial, tStimLevel lv, tTime s, tTime l, tTime n)
70 : start(s),last(l),now(n), i (0),life(*plife),level(lv)
73 // handle zero period case somewhat gracefully...
74 if (life.period == 0)
76 Warning(("Stim source has zero-length period\n"));
77 life.period++;
80 // convert period to freq so we don't have to divide twice
81 // @NOTE: possible precision issue.
82 float freq = 1.0/life.period;
84 if (last < start) last = start;
85 if (now < start)
87 to_fire = 0;
88 t = start;
89 return;
92 // how many times we've already fired.
93 int fired = (last - start) * freq;
94 to_fire = (now - start) * freq;
96 // special case: send an event at the first firing
97 if (!initial)
98 fired++;
99 to_fire ++;
101 if (!(life.flags & sPeriodicLifeCycle::kNoMaxFirings))
103 if (fired >= life.max_firings)
104 to_fire = 0; // we're expired
105 else if (to_fire >= life.max_firings)
106 to_fire = life.max_firings;
109 // set up iteration
110 t = start + life.period * fired;
111 i = fired;
112 level += i * life.slope;
116 BOOL Next(tStimLevel* plev, tTime* pt, ulong* flags)
118 *plev = level;
119 *pt = t;
121 if (i >= to_fire)
122 return FALSE;
124 t += life.period;
125 level += life.slope;
126 i++;
128 *flags = 0;
130 ulong destroy_mask = sPeriodicLifeCycle::kNoMaxFirings|sPeriodicLifeCycle::kDestroy;
132 // destroy set but not no max firings
133 if ((life.flags & destroy_mask) == sPeriodicLifeCycle::kDestroy
134 && i == life.max_firings)
135 *flags |= kStimDestroySrcObj;
137 return TRUE;
141 sPeriodicLifeCycle::sFire* sPeriodicLifeCycle::BeginFiring(BOOL initial,
142 tStimLevel level,
143 tStimTimeStamp start,
144 tStimTimeStamp last,
145 tStimTimeStamp now)
147 return new sFire(this,initial,level,start,last,now);
150 BOOL sPeriodicLifeCycle::FireNext(sFire* fire, tStimLevel* nextlevel, tStimTimeStamp* nexttime, ulong* flags)
152 Assert_(fire);
153 return fire->Next(nextlevel,nexttime,flags);
156 BOOL sPeriodicLifeCycle::EndFiring(sFire* fire)
158 BOOL retval = (flags & kNoMaxFirings) || fire->i < max_firings;
159 delete fire;
160 return retval;