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