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