]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu-div0test/menu.qc
minor Xaw skin improvements; work around fteqcc bug as always
[divverent/nexuiz.git] / data / qcsrc / menu-div0test / menu.qc
1 ///////////////////////////////////////////////
2 // Menu Source File
3 ///////////////////////
4 // This file belongs to dpmod/darkplaces
5 // AK contains all menu functions (especially the required ones)
6 ///////////////////////////////////////////////
7
8 float mouseButtonsPressed;
9 vector menuMousePos;
10 float menuShiftState;
11 float menuPrevTime;
12 float menuAlpha;
13 float menuLogoAlpha;
14 float prevMenuAlpha;
15 float menuLoadedMaplist;
16 float menuNotTheFirstFrame;
17
18 void SUB_Null() { };
19
20 void() m_init =
21 {
22         dprint_load();
23 }
24
25 void() m_init_delayed =
26 {
27         float fh;
28         string s;
29
30         dprint_load();
31
32         menuLoadedMaplist = 0;
33         MapInfo_Enumerate();
34         if(!MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 1))
35                 return;
36         menuLoadedMaplist = 1;
37
38         GameCommand_Init();
39
40         fh = -1;
41         if(cvar_string("menu_skin") != "")
42         {
43                 draw_currentSkin = strcat("gfx/menu/", cvar_string("menu_skin"));
44                 fh = fopen(strcat(draw_currentSkin, "/skinvalues.txt"), FILE_READ);
45         }
46         if(fh < 0)
47         {
48                 draw_currentSkin = "gfx/menu/default";
49                 fh = fopen(strcat(draw_currentSkin, "/skinvalues.txt"), FILE_READ);
50         }
51         draw_currentSkin = strzone(draw_currentSkin);
52         while((s = fgets(fh)))
53                 if(tokenize(s) == 2)
54                         Skin_ApplySetting(argv(0), argv(1));
55         fclose(fh);
56
57         draw_setMousePointer("cursor");
58
59         main = spawnMainWindow(); main.configureMainWindow(main);
60         draw_reset();
61         main.resizeNotify(main, draw_shift, draw_scale, draw_shift, draw_scale);
62         main.focused = 1;
63         menuShiftState = 0;
64
65         if(Menu_Active)
66                 m_display(); // delayed menu display
67 };
68
69 void(float key, float ascii) m_keyup =
70 {
71         if(!menuLoadedMaplist)
72                 return;
73         if(!Menu_Active)
74                 return;
75         draw_reset();
76         main.keyUp(main, key, ascii, menuShiftState);
77         if(key >= K_MOUSE1 && key <= K_MOUSE3)
78         {
79                 --mouseButtonsPressed;
80                 if(!mouseButtonsPressed)
81                         main.mouseRelease(main, menuMousePos);
82                 if(mouseButtonsPressed < 0)
83                 {
84                         mouseButtonsPressed = 0;
85                         print("Warning: released an already released button\n");
86                 }
87         }
88         if(key == K_ALT) menuShiftState -= (menuShiftState & S_ALT);
89         if(key == K_CTRL) menuShiftState -= (menuShiftState & S_CTRL);
90         if(key == K_SHIFT) menuShiftState -= (menuShiftState & S_SHIFT);
91 };
92
93 void(float key, float ascii) m_keydown =
94 {
95         if(!menuLoadedMaplist)
96                 return;
97         if(!Menu_Active)
98                 return;
99         if(keyGrabber)
100         {
101                 entity e;
102                 e = keyGrabber;
103                 keyGrabber = NULL;
104                 e.keyGrabbed(e, key, ascii);
105         }
106         else
107         {
108                 draw_reset();
109                 if(!main.keyDown(main, key, ascii, menuShiftState))
110                         if(key == K_ESCAPE)
111                                 if(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)) // don't back out to console only
112                                         m_hide(); // disable menu on unhandled ESC
113                 if(key >= K_MOUSE1 && key <= K_MOUSE3)
114                         if(!mouseButtonsPressed)
115                                 main.mousePress(main, menuMousePos);
116         }
117         if(key >= K_MOUSE1 && key <= K_MOUSE3)
118         {
119                 ++mouseButtonsPressed;
120                 if(mouseButtonsPressed > 10)
121                 {
122                         mouseButtonsPressed = 10;
123                         print("Warning: pressed an already pressed button\n");
124                 }
125         }
126         if(key == K_ALT) menuShiftState |= S_ALT;
127         if(key == K_CTRL) menuShiftState |= S_CTRL;
128         if(key == K_SHIFT) menuShiftState |= S_SHIFT;
129 };
130
131 void() m_draw =
132 {
133         float t;
134         float realFrametime;
135
136         if(!menuNotTheFirstFrame)
137         {
138                 menuNotTheFirstFrame = 1;
139                 if(Menu_Active)
140                 if(!cvar("menu_video_played"))
141                 {
142                         localcmd("set menu_video_played 1; cd loop 1; play sound/announcer/male/welcome.ogg\n");
143                         menuLogoAlpha = -0.8; // no idea why, but when I start this at zero, it jumps instead of fading
144                 }
145         }
146         if(!menuLoadedMaplist)
147         {
148                 // TODO draw an info image about this situation
149                 m_init_delayed();
150                 return;
151         }
152         t = gettime();
153         realFrametime = frametime = min(0.2, t - menuPrevTime);
154         menuPrevTime = t;
155         time += frametime;
156
157         if(Menu_Active)
158         {
159                 if(getmousetarget() == MT_MENU && (getkeydest() == KEY_MENU || getkeydest() == KEY_MENU_GRABBED))
160                         setkeydest(keyGrabber ? KEY_MENU_GRABBED : KEY_MENU);
161                 else
162                         m_hide();
163         }
164
165         if(cvar("cl_capturevideo"))
166                 frametime = 1 / cvar("cl_capturevideo_fps"); // make capturevideo work smoothly
167
168         dprint_load();
169         gamestatus = 0;
170         if(isserver())
171                 gamestatus = gamestatus | GAME_ISSERVER;
172         if(clientstate() == CS_CONNECTED)
173                 gamestatus = gamestatus | GAME_CONNECTED;
174         if(cvar("developer"))
175                 gamestatus = gamestatus | GAME_DEVELOPER;
176
177         prevMenuAlpha = menuAlpha;
178         if(Menu_Active)
179         {
180                 if(menuAlpha == 0 && menuLogoAlpha < 2)
181                 {
182                         menuLogoAlpha = menuLogoAlpha + frametime * 2;
183                 }
184                 else
185                 {
186                         menuAlpha = min(1, menuAlpha + frametime * 5);
187                         menuLogoAlpha = 2;
188                 }
189         }
190         else
191         {
192                 menuAlpha = max(0, menuAlpha - frametime * 5);
193                 menuLogoAlpha = 2;
194         }
195
196         draw_reset();
197
198         if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER)))
199         {
200                 vector sz;
201                 vector isz;
202                 sz = draw_PictureSize(SKINGFX_BACKGROUND);
203                 // keep aspect of image
204                 if(sz_x * draw_scale_y >= sz_y * draw_scale_x)
205                 {
206                         // that is, sz_x/sz_y >= draw_scale_x/draw_scale_y
207                         // match up the height
208                         isz_y = 1;
209                         isz_x = isz_y * (sz_x / sz_y) * (draw_scale_y / draw_scale_x);
210                 }
211                 else
212                 {
213                         // that is, sz_x/sz_y <= draw_scale_x/draw_scale_y
214                         // match up the width
215                         isz_x = 1;
216                         isz_y = isz_x * (sz_y / sz_x) * (draw_scale_x / draw_scale_y);
217                 }
218                 draw_Picture('0.5 0.5 0' - 0.5 * isz, SKINGFX_BACKGROUND, isz, '1 1 1', bound(0, menuLogoAlpha, 1));
219         }
220
221         if(menuAlpha <= 0)
222         {
223                 if(prevMenuAlpha > 0)
224                         main.initializeDialog(main, main.firstChild);
225                 return;
226         }
227
228         draw_alpha *= menuAlpha;
229
230         if(frametime > 0)
231         {
232                 vector dMouse;
233                 dMouse = getmousepos() * (frametime / realFrametime); // for capturevideo
234                 if(dMouse != '0 0 0')
235                 {
236                         dMouse = globalToBoxSize(dMouse, draw_scale);
237                         menuMousePos += dMouse * 1; // TODO use a cvar here
238                         menuMousePos_x = bound(0, menuMousePos_x, 1);
239                         menuMousePos_y = bound(0, menuMousePos_y, 1);
240                         if(mouseButtonsPressed)
241                                 main.mouseDrag(main, menuMousePos);
242                         else
243                                 main.mouseMove(main, menuMousePos);
244                 }
245         }
246         main.draw(main);
247         draw_drawMousePointer(menuMousePos);
248
249         frametime = 0;
250 };
251
252 void() m_display =
253 {
254         Menu_Active = true;
255         setkeydest(KEY_MENU);
256         setmousetarget(MT_MENU);
257
258         if(!menuLoadedMaplist)
259                 return;
260
261         if(mouseButtonsPressed)
262                 main.mouseRelease(main, menuMousePos);
263         mouseButtonsPressed = 0;
264
265         main.focusEnter(main);
266         main.showNotify(main);
267 };
268
269 void() m_hide =
270 {
271         Menu_Active = false;
272         setkeydest(KEY_GAME);
273         setmousetarget(MT_CLIENT);
274
275         if(!menuLoadedMaplist)
276                 return;
277
278         main.focusLeave(main);
279         main.hideNotify(main);
280 };
281
282 void() m_toggle =
283 {
284         if(Menu_Active)
285                 m_hide();
286         else
287                 m_display();
288 };
289
290 void() m_shutdown =
291 {
292         m_hide();
293 };
294
295 void(string itemname) m_goto =
296 {
297         entity e;
298         if(!menuLoadedMaplist)
299                 return;
300         if(itemname == "") // this can be called by GameCommand
301         {
302                 if(gamestatus & (GAME_ISSERVER | GAME_CONNECTED))
303                         m_hide();
304                 else
305                 {
306                         main.initializeDialog(main, main.firstChild);
307                         m_display();
308                 }
309         }
310         else
311         {
312                 e = findstring(NULL, name, itemname);
313                 if(e && e.parent == main)
314                 {
315                         m_hide();
316                         main.initializeDialog(main, e);
317                         m_display();
318                 }
319         }
320 }