]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/bgmscript.qc
speed up loading of BGM script
[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                 string mychar;
81                 float i;
82
83                 m = strcat(e.bgmscript, " ");
84                 l = strlen(m);
85
86                 e.bgmscriptline0 = -1;
87                 for(i = 0; i < bgmscriptbufsize; ++i)
88                 {
89                         if(substring(bufstr_get(bgmscriptbuf, i), 0, l) == m)
90                                 break;
91                 }
92                 e.bgmscriptline = e.bgmscriptline0 = i;
93                 if(i >= bgmscriptbufsize)
94                 {
95                         print("func_pointparticles: bgmscript does not define ", mychar, "\n");
96                         e.bgmscript = "";
97                 }
98         }
99 }
100
101 float BGMScript(entity e)
102 {
103         float t;
104         float amp;
105
106         if(e.bgmscript == "")
107                 return 1;
108         
109         if(cvar("bgmvolume") <= 0)
110                 return -1;
111
112         e.just_toggled = FALSE;
113
114         t = gettime(GETTIME_CDTRACK);
115         if(t < e.bgmscripttime)
116         {
117                 e.bgmscriptline = e.bgmscriptline0;
118                 e.bgmscripttime = 0;
119                 e.bgmscriptstatetime = t - drawframetime - e.bgmscriptdelta; // FIXME this causes a tiny hitch
120         }
121
122         // find the CURRENT line
123         for(;;)
124         {
125                 tokenize_sane(bufstr_get(bgmscriptbuf, e.bgmscriptline));
126                 if(stof(argv(1)) >= t)
127                         break;
128                 if(argv(0) != e.bgmscript)
129                 {
130                         // end of bgmscript, will revert to beginning later
131                         break;
132                 }
133                 else if(t >= stof(argv(1)))
134                 {
135                         e.bgmscriptline += 1;
136                         e.bgmscripttime = stof(argv(1));
137
138                         if(e.bgmscriptstate)
139                                 amp = GetAttackDecaySustainAmplitude(e.bgmscriptattack, e.bgmscriptdecay, e.bgmscriptsustain, e.bgmscripttime - e.bgmscriptstatetime) * e.bgmscriptvelocity;
140                         else
141                                 amp = GetReleaseAmplitude(e.bgmscriptsustain, e.bgmscriptrelease, e.bgmscripttime - e.bgmscriptstatetime);
142
143                         // time code reached!
144                         e.bgmscriptvelocity = stof(argv(2));
145                         if(e.bgmscriptvelocity > 0)
146                                 e.just_toggled = e.bgmscriptstate = TRUE;
147                         else
148                                 e.just_toggled = e.bgmscriptstate = FALSE;
149
150                         if(e.bgmscriptstate)
151                                 e.bgmscriptstatetime = e.bgmscripttime - GetAttackTime(e.bgmscriptattack, amp / e.bgmscriptvelocity);
152                         else
153                         {
154                                 e.bgmscriptstatetime = e.bgmscripttime - GetReleaseTime(e.bgmscriptsustain, e.bgmscriptrelease, amp);
155                                 amp = GetReleaseAmplitude(e.bgmscriptsustain, e.bgmscriptrelease, e.bgmscripttime - e.bgmscriptstatetime);
156                         }
157                 }
158         }
159
160         if(e.bgmscriptstate)
161         {
162                 // attack, decay or sustain
163                 e.bgmscriptdelta = t - e.bgmscriptstatetime;
164                 return GetAttackDecaySustainAmplitude(e.bgmscriptattack, e.bgmscriptdecay, e.bgmscriptsustain, e.bgmscriptdelta) * e.bgmscriptvelocity;
165         }
166         else
167         {
168                 // release
169                 e.bgmscriptdelta = t - e.bgmscriptstatetime;
170                 return GetReleaseAmplitude(e.bgmscriptsustain, e.bgmscriptrelease, self.bgmscriptdelta);
171         }
172 }
173