]> icculus.org git repositories - divverent/nexuiz.git/blob - menu/mfuncs.qc
added secondary fire zoom on nex
[divverent/nexuiz.git] / menu / mfuncs.qc
1 ///////////////////////////////////////////////
2 // Functions Source File
3 ///////////////////////
4 // This file belongs to dpmod/darkplaces
5 // AK contains all menu controlling stuff (sub-menus)
6 ///////////////////////////////////////////////
7
8 // raise function
9 /* template
10
11 void(entity ent)        raise_x =
12 {
13         entity old;
14         if(!ent._x)
15                 return;
16
17         old = self;
18         self = ent;
19         self._x();
20         self = old;
21 };
22 */
23
24 void(entity ent)        raise_reinit =
25 {
26         entity old;
27         if(!ent._reinit)
28                 return;
29
30         old = self;
31         self = ent;
32         self._reinit();
33         self = old;
34 };
35
36 void(entity ent)        raise_destroy =
37 {
38         entity old;
39         if(!ent._destroy)
40                 return;
41
42         old = self;
43         self = ent;
44         self._destroy();
45         self = old;
46 };
47
48 void(entity ent, float keynr, float ascii)      raise_key =
49 {
50         entity old;
51         if(!ent._key)
52                 return;
53
54         old = self;
55         self = ent;
56         self._key(keynr, ascii);
57         self = old;
58 };
59
60 void(entity ent)        raise_draw =
61 {
62         entity old;
63         if(!ent._draw)
64                 return;
65
66         old = self;
67         self = ent;
68         self._draw();
69         self = old;
70 };
71
72 void(entity ent)        raise_mouse_enter =
73 {
74         entity old;
75         if(!ent._mouse_enter)
76                 return;
77
78         old = self;
79         self = ent;
80         self._mouse_enter();
81         self = old;
82 };
83
84 void(entity ent)        raise_mouse_leave =
85 {
86         entity old;
87         if(!ent._mouse_leave)
88                 return;
89
90         old = self;
91         self = ent;
92         self._mouse_leave();
93         self = old;
94 };
95
96 void(entity ent)        raise_action =
97 {
98         entity old;
99         if(!ent._action)
100                 return;
101
102         old = self;
103         self = ent;
104         self._action();
105         self = old;
106 };
107
108 void(entity ent)        raise_refresh =
109 {
110         entity old;
111         if(!ent._refresh)
112                 return;
113
114         old = self;
115         self = ent;
116         self._refresh();
117         self = old;
118 };
119
120 // safe call control function functions
121 // default control functions
122 /* template
123
124 void(void) ctcall_x     =
125 {
126         if(self.x)
127                 self.x();
128 };
129
130 */
131 void(void)      ctcall_init =
132 {
133         if(self.init)
134                 self.init();
135 };
136
137 void(void)  ctcall_reinit =
138 {
139         if(self.reinit)
140                 self.reinit();
141 };
142
143 void(void) ctcall_destroy =
144 {
145         if(self.destroy)
146                 self.destroy();
147 };
148
149 float(float keynr, float ascii)  ctcall_key =
150 {
151         if(self.key)
152                 return self.key(keynr, ascii);
153         else
154                 return false;
155 };
156
157 void(void)      ctcall_draw =
158 {
159         if(self.draw)
160                 self.draw();
161 };
162
163 void(void)      ctcall_mouse_enter =
164 {
165         if(self.mouse_enter)
166                 self.mouse_enter();
167 };
168
169 void(void)      ctcall_mouse_leave =
170 {
171         if(self.mouse_leave)
172                 self.mouse_leave();
173 };
174
175 void(void)      ctcall_action =
176 {
177         if(self.action)
178                 self.action();
179 };
180
181 void(void) ctcall_refresh =
182 {
183         if(self.refresh)
184                 self.refresh();
185 }
186
187 // default control functions
188 /* template (expect defct_key)
189
190 void(void) defct_x =
191 {
192         ctcall_x();
193 };
194
195 */
196 // defct_init not needed cause its the same like the type function
197
198 void(void) defct_reinit =
199 {
200         ctcall_reinit();
201 };
202
203 void(void) defct_destroy =
204 {
205         ctcall_destroy();
206 };
207
208 void(float keynr, float ascii)  defct_key =
209 {
210         if(!ctcall_key(keynr, ascii))
211                 def_keyevent(keynr, ascii);
212 };
213
214 void(void)      defct_draw =
215 {
216         ctcall_draw();
217 };
218
219 void(void)      defct_mouse_enter =
220 {
221         ctcall_mouse_enter();
222 };
223
224 void(void)      defct_mouse_leave =
225 {
226         ctcall_mouse_leave();
227 };
228
229 void(void)      defct_action =
230 {
231         ctcall_action();
232 };
233
234 void(void)      defct_refresh =
235 {
236         // do first the own fresh stuff and *then* call refresh
237         def_refresh();
238         ctcall_refresh();
239 }
240
241 // default refresh function
242 void(void)      def_refresh =
243 {
244         // refresh stuff
245         if(self.flag & FLAG_AUTOSETCLICK)
246         {
247                 self.click_pos = self.pos;
248                 self.click_size = self.size;
249         }
250         if(self.flag & FLAG_AUTOSETCLIP)
251         {
252                 self.clip_pos = self.pos;
253                 self.clip_size = self.size;
254         }
255 };
256
257 // default key function
258 void(float keynr, float ascii)  def_keyevent =
259 {
260         if(keynr == K_ESCAPE)
261         {
262                 // move up to the parent
263                 menu_selectup();
264         } else if(keynr == K_LEFTARROW || keynr == K_UPARROW)
265         {
266                 // move to the previous element
267                 menu_loopprev();
268
269                 if(menu_selected == self)
270                 {
271                         if(self._prev)
272                         {
273                                 menu_selected = self._prev;
274                                 menu_selectdown();
275                                 if(menu_selected != self._prev)
276                                 {
277                                         return;
278                                 }
279                         }
280                         menu_selected = self;
281                 }
282         } else if(keynr == K_RIGHTARROW || keynr == K_DOWNARROW)
283         {
284                 // move to the  next element
285                 menu_loopnext();
286
287                 if(menu_selected == self)
288                 {
289                         if(self._next)
290                         {
291                                 menu_selected = self._next;
292                                 menu_selectdown();
293                                 if(menu_selected != self._next)
294                                 {
295                                         return;
296                                 }
297                         }
298                         menu_selected = self;
299                 }
300         } else if(keynr == K_ENTER || keynr == K_MOUSE1)
301         {
302                 if(self._action)
303                         self._action();
304                 // move to the child menu
305                 menu_selectdown();
306         }
307 };
308
309 // a rect is described by the top-left point and its size
310 float(vector point, vector r_pos, vector r_size) inrect =
311 {
312         if(point_x < r_pos_x)
313                 return false;
314         if(point_y < r_pos_y)
315                 return false;
316         if(point_x > (r_pos_x + r_size_x))
317                 return false;
318         if(point_y > (r_pos_y + r_size_y))
319                 return false;
320         return true;
321 };
322
323 vector(vector r_pos, vector r_size, vector c_pos, vector c_size) cliprectpos =
324 {
325         vector v;
326
327         // clip r_pos only
328         v_x = max(c_pos_x, r_pos_x);
329         v_y = max(c_pos_y, r_pos_y);
330
331         return v;
332 };
333
334 vector(vector r_pos, vector r_size, vector c_pos, vector c_size) cliprectsize =
335 {
336         vector v;
337         // safe version
338         //r_size_x = bound(c_pos_x, r_pos_x + r_size_x, c_pos_x + c_size_x) - bound(c_pos_x, r_pos_x, c_pos_x + c_size_x);
339         //r_size_y = bound(c_pos_y, r_pos_y + r_size_y, c_pos_y + c_size_y) - bound(c_pos_y, r_pos_y, c_pos_y + c_size_y);
340         v_x = min(c_pos_x + c_size_x, r_pos_x + r_size_x) - max(c_pos_x, r_pos_x);
341         v_y = min(c_pos_y + c_size_y, r_pos_y + r_size_y) - max(c_pos_y, r_pos_y);
342
343         if(v_x <= 0 || v_y <= 0)
344                 v = '0 0 0';
345
346         return v;
347 }
348
349 void(void(void) reinitevent, void(void) destroyevent, void(float key, float ascii) keyevent, void(void) drawevent, void(void) mouse_enterevent, void(void) mouse_leaveevent, void(void) actionevent, void(void) refreshevent)
350         item_init =
351 {
352         self._reinit  = reinitevent;
353         self._destroy = destroyevent;
354
355         self._key       = keyevent;
356         self._draw      = drawevent;
357         self._mouse_enter = mouse_enterevent;
358         self._mouse_leave = mouse_leaveevent;
359         self._action = actionevent;
360         self._refresh = refreshevent;
361 };
362
363 float(float tfactor) getflicker =
364 {
365         // TODO: use tfactor to vary the result
366         return (sin(tfactor * time) + 1)/2;
367 };
368
369 float(string s) getaltstringcount =
370 {
371         float len;
372         float count;
373         float pos;
374
375         len = strlen(s);
376         count = 0;
377         for(pos = 0; pos < len; pos = pos + 1)
378         {
379                 if(substring(s,pos,1) == "'")
380                         count = count + 1;
381         }
382
383         if(mod(count,2) == 1)
384                 return 0; // bad string
385
386         return (count / 2);
387 };
388
389 string(float n, string s) getaltstring =
390 {
391         float start, length;
392         float tmp;
393
394         n = rint(n);
395
396         if(n >= getaltstringcount(s) || n < 0)
397                 return "";
398
399         // go to the beginning of the altstring
400         tmp = 0;
401         for(start = 0;tmp <= n * 2 ; start = start + 1)
402         {
403                 if(substring(s, start, 1) == "'")
404                         tmp = tmp + 1;
405         }
406
407         for(length = 0; substring(s, start + length, 1) != "'"; length = length + 1)
408         {
409         }
410
411         return substring(s, start, length);
412 };
413
414 void(string key) bind_unbindkey =
415 {
416         cmd(strcat("unbind ",key,"\n"));
417 };
418
419 void(string key, string command) bind_bindkey =
420 {
421         cmd(strcat("bind ",key," ",command,"\n"));
422 };
423
424 string(float keynum) bind_getstringforkey =
425 {
426         return keynumtostring(keynum);
427 };
428
429 string(string command) bind_getkeylist =
430 {
431         return findkeysforcommand(command);
432 };
433
434 void(float num, string command) bind_limitbinds =
435 {
436         float maxnum;
437         float counter;
438         string keystr;
439
440         keystr = strzone(bind_getkeylist(command));
441
442         maxnum = getaltstringcount(keystr);
443         if(num > maxnum)
444                 num = maxnum;
445
446         //dprint("num = ", ftos(num),"\n");
447         //dprint("maxnum = ", ftos(maxnum), "\n");
448
449         counter = 0;
450         while(counter < maxnum)
451         {
452                 float keynum;
453
454                 keynum = stof(getaltstring(counter, keystr));
455
456                 //dprint(ftos(keynum),"\n");
457
458                 if(keynum == -1)
459                         break;
460
461                 if(counter >= num)
462                         bind_unbindkey(bind_getstringforkey(keynum));
463
464                 counter = counter + 1;
465         }
466
467         strunzone(keystr);
468 };