]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/bgmscript.qc
error message fix
[divverent/nexuiz.git] / data / qcsrc / client / bgmscript.qc
1 float bgmscriptbuf;
2 float bgmscriptbufsize;
3 float bgmscriptbufloaded;
4
5 .float bgmscriptline;
6 .float bgmscriptline0;
7 .float bgmscriptvelocity;
8 .float bgmscripttime;
9 .float bgmscriptstate;
10 .float bgmscriptstatetime;
11 .float bgmscriptdelta;
12
13 float GetAttackDecaySustainAmplitude(float a, float d, float s, float t)
14 {
15         // phase:
16         //   attack: from 0 to 1, in time a for a full length
17         //   decay: from 1 to s, in time d
18         //   sustain: s
19         
20         if(a)
21                 if(t <= a)
22                         return max(0, t / a);
23
24         if(d)
25                 if(t <= a + d)
26                         return max(0, ((t - a) / d)) * (s - 1) + 1;
27
28         return s;
29 }
30
31 float GetReleaseAmplitude(float s, float r, float t)
32 {
33         if(r)
34                 return s * (1 - min(1, t / r));
35         
36         return 0;
37 }
38
39 float GetAttackTime(float a, float amp)
40 {
41         return amp * a;
42 }
43
44 float GetReleaseTime(float s, float r, float amp)
45 {
46         if(s)
47                 return (1 - amp / s) * r;
48
49         return 0;
50 }
51
52 void BGMScript_Init()
53 {
54         string s;
55         float fh;
56         bgmscriptbuf = bgmscriptbufsize = 0;
57         bgmscriptbufloaded = 1;
58         s = strcat("maps/", mi_shortname, ".bgs");
59         fh = fopen(s, FILE_READ);
60         if(fh < 0)
61                 return;
62         bgmscriptbuf = buf_create();
63         while((s = fgets(fh)))
64         {
65                 bufstr_set(bgmscriptbuf, bgmscriptbufsize, s);
66                 ++bgmscriptbufsize;
67         }
68         fclose(fh);
69 }
70
71 void BGMScript_InitEntity(entity e)
72 {
73         float l;
74         string m;
75         if(e.bgmscript != "")
76         {
77                 if(!bgmscriptbufloaded)
78                         BGMScript_Init();
79
80                 float i;
81
82                 m = strcat(e.bgmscript, " ");
83                 l = strlen(m);
84
85                 e.bgmscriptline0 = -1;
86                 for(i = 0; i < bgmscriptbufsize; ++i)
87                 {
88                         if(substring(bufstr_get(bgmscriptbuf, i), 0, l) == m)
89                                 break;
90                 }
91                 e.bgmscriptline = e.bgmscriptline0 = i;
92                 if(i >= bgmscriptbufsize)
93                 {
94                         print("func_pointparticles: bgmscript does not define ", e.bgmscript, "\n");
95                         e.bgmscript = "";
96                 }
97         }
98 }
99
100 float BGMScript(entity e)
101 {
102         float t;
103         float amp;
104
105         if(e.bgmscript == "")
106                 return 1;
107         
108         if(cvar("bgmvolume") <= 0)
109                 return -1;
110
111         e.just_toggled = FALSE;
112
113         t = gettime(GETTIME_CDTRACK);
114         if(t < e.bgmscripttime)
115         {
116                 e.bgmscriptline = e.bgmscriptline0;
117                 e.bgmscripttime = 0;
118                 e.bgmscriptstatetime = t - drawframetime - e.bgmscriptdelta; // FIXME this causes a tiny hitch
119         }
120
121         // find the CURRENT line
122         for(;;)
123         {
124                 tokenize_sane(bufstr_get(bgmscriptbuf, e.bgmscriptline));
125                 if(stof(argv(1)) >= t)
126                         break;
127                 if(argv(0) != e.bgmscript)
128                 {
129                         // end of bgmscript, will revert to beginning later
130                         break;
131                 }
132                 else if(t >= stof(argv(1)))
133                 {
134                         e.bgmscriptline += 1;
135                         e.bgmscripttime = stof(argv(1));
136
137                         if(e.bgmscriptstate)
138                                 amp = GetAttackDecaySustainAmplitude(e.bgmscriptattack, e.bgmscriptdecay, e.bgmscriptsustain, e.bgmscripttime - e.bgmscriptstatetime) * e.bgmscriptvelocity;
139                         else
140                                 amp = GetReleaseAmplitude(e.bgmscriptsustain, e.bgmscriptrelease, e.bgmscripttime - e.bgmscriptstatetime);
141
142                         // time code reached!
143                         e.bgmscriptvelocity = stof(argv(2));
144                         if(e.bgmscriptvelocity > 0)
145                                 e.just_toggled = e.bgmscriptstate = TRUE;
146                         else
147                                 e.just_toggled = e.bgmscriptstate = FALSE;
148
149                         if(e.bgmscriptstate)
150                                 e.bgmscriptstatetime = e.bgmscripttime - GetAttackTime(e.bgmscriptattack, amp / e.bgmscriptvelocity);
151                         else
152                         {
153                                 e.bgmscriptstatetime = e.bgmscripttime - GetReleaseTime(e.bgmscriptsustain, e.bgmscriptrelease, amp);
154                                 amp = GetReleaseAmplitude(e.bgmscriptsustain, e.bgmscriptrelease, e.bgmscripttime - e.bgmscriptstatetime);
155                         }
156                 }
157         }
158
159         if(e.bgmscriptstate)
160         {
161                 // attack, decay or sustain
162                 e.bgmscriptdelta = t - e.bgmscriptstatetime;
163                 return GetAttackDecaySustainAmplitude(e.bgmscriptattack, e.bgmscriptdecay, e.bgmscriptsustain, e.bgmscriptdelta) * e.bgmscriptvelocity;
164         }
165         else
166         {
167                 // release
168                 e.bgmscriptdelta = t - e.bgmscriptstatetime;
169                 return GetReleaseAmplitude(e.bgmscriptsustain, e.bgmscriptrelease, self.bgmscriptdelta);
170         }
171 }
172