Tweak the system sound to use 0.5 as the default volume, instead of 1.0. This allows...
[voretournament/voretournament.git] / data / qcsrc / menu / draw.qc
1 string draw_mousepointer;\r
2 vector draw_mousepointer_offset;\r
3 vector draw_mousepointer_size;\r
4 \r
5 string draw_UseSkinFor(string pic)\r
6 {\r
7         if(substring(pic, 0, 1) == "/")\r
8                 return substring(pic, 1, strlen(pic)-1);\r
9         else\r
10                 return strcat(draw_currentSkin, "/", pic);\r
11 }\r
12 \r
13 void draw_setMousePointer(string pic, vector theSize, vector theOffset)\r
14 {\r
15         draw_mousepointer = strzone(draw_UseSkinFor(pic));\r
16         draw_mousepointer_size = theSize;\r
17         draw_mousepointer_offset = eX * (theOffset_x * theSize_x) + eY * (theOffset_y * theSize_y);\r
18 }\r
19 \r
20 void draw_drawMousePointer(vector where)\r
21 {\r
22         drawpic(boxToGlobal(where, draw_shift, draw_scale) - draw_mousepointer_offset, draw_mousepointer, draw_mousepointer_size, '1 1 1', draw_alpha, 0);\r
23 }\r
24 \r
25 void draw_reset(float cw, float ch, float ox, float oy)\r
26 {\r
27         drawfont = FONT_USER+0;\r
28         draw_shift = '1 0 0' * ox + '0 1 0' * oy;\r
29         draw_scale = '1 0 0' * cw + '0 1 0' * ch;\r
30         draw_alpha = 1;\r
31         draw_fontscale = '1 1 0';\r
32 }\r
33 \r
34 vector globalToBox(vector v, vector theOrigin, vector theScale)\r
35 {\r
36         v -= theOrigin;\r
37         v_x /= theScale_x;\r
38         v_y /= theScale_y;\r
39         return v;\r
40 }\r
41 \r
42 vector globalToBoxSize(vector v, vector theScale)\r
43 {\r
44         v_x /= theScale_x;\r
45         v_y /= theScale_y;\r
46         return v;\r
47 }\r
48 \r
49 vector boxToGlobal(vector v, vector theOrigin, vector theScale)\r
50 {\r
51         v_x *= theScale_x;\r
52         v_y *= theScale_y;\r
53         v += theOrigin;\r
54         return v;\r
55 }\r
56 \r
57 vector boxToGlobalSize(vector v, vector theScale)\r
58 {\r
59         v_x *= theScale_x;\r
60         v_y *= theScale_y;\r
61         return v;\r
62 }\r
63 \r
64 void draw_PreloadPicture(string pic)\r
65 {\r
66         pic = draw_UseSkinFor(pic);\r
67         precache_pic(pic);\r
68 }\r
69 \r
70 void draw_Picture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)\r
71 {\r
72         pic = draw_UseSkinFor(pic);\r
73         drawpic(boxToGlobal(theOrigin, draw_shift, draw_scale), pic, boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0);\r
74 }\r
75 \r
76 vector draw_PictureSize(string pic)\r
77 {\r
78         pic = draw_UseSkinFor(pic);\r
79         return drawgetimagesize(pic);\r
80 }\r
81 \r
82 void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha)\r
83 {\r
84         drawfill(boxToGlobal(theOrigin, draw_shift, draw_scale), boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0);\r
85 }\r
86 \r
87 // a button picture is a texture containing three parts:\r
88 //   1/4 width: left part\r
89 //   1/2 width: middle part (stretched)\r
90 //   1/4 width: right part\r
91 // it is assumed to be 4x as wide as high for aspect ratio purposes, which\r
92 // means, the parts are a square, two squares and a square.\r
93 void draw_ButtonPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)\r
94 {\r
95         vector square;\r
96         vector width, height;\r
97         vector bW;\r
98         pic = draw_UseSkinFor(pic);\r
99         theOrigin = boxToGlobal(theOrigin, draw_shift, draw_scale);\r
100         theSize = boxToGlobalSize(theSize, draw_scale);\r
101         theAlpha *= draw_alpha;\r
102         width = eX * theSize_x;\r
103         height = eY * theSize_y;\r
104         if(theSize_x <= theSize_y * 2)\r
105         {\r
106                 // button not wide enough\r
107                 // draw just left and right part then\r
108                 square = eX * theSize_x * 0.5;\r
109                 bW = eX * (0.25 * theSize_x / (theSize_y * 2));\r
110                 drawsubpic(theOrigin,          square + height, pic, '0 0 0', eY + bW, theColor, theAlpha, 0);\r
111                 drawsubpic(theOrigin + square, square + height, pic, eX - bW, eY + bW, theColor, theAlpha, 0);\r
112         }\r
113         else\r
114         {\r
115                 square = eX * theSize_y;\r
116                 drawsubpic(theOrigin,                  height  +     square, pic, '0    0 0', '0.25 1 0', theColor, theAlpha, 0);\r
117                 drawsubpic(theOrigin +         square, theSize - 2 * square, pic, '0.25 0 0', '0.5  1 0', theColor, theAlpha, 0);\r
118                 drawsubpic(theOrigin + width - square, height  +     square, pic, '0.75 0 0', '0.25 1 0', theColor, theAlpha, 0);\r
119         }\r
120 }\r
121 \r
122 // a vertical button picture is a texture containing three parts:\r
123 //   1/4 height: left part\r
124 //   1/2 height: middle part (stretched)\r
125 //   1/4 height: right part\r
126 // it is assumed to be 4x as high as wide for aspect ratio purposes, which\r
127 // means, the parts are a square, two squares and a square.\r
128 void draw_VertButtonPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)\r
129 {\r
130         vector square;\r
131         vector width, height;\r
132         vector bH;\r
133         pic = draw_UseSkinFor(pic);\r
134         theOrigin = boxToGlobal(theOrigin, draw_shift, draw_scale);\r
135         theSize = boxToGlobalSize(theSize, draw_scale);\r
136         theAlpha *= draw_alpha;\r
137         width = eX * theSize_x;\r
138         height = eY * theSize_y;\r
139         if(theSize_y <= theSize_x * 2)\r
140         {\r
141                 // button not high enough\r
142                 // draw just upper and lower part then\r
143                 square = eY * theSize_y * 0.5;\r
144                 bH = eY * (0.25 * theSize_y / (theSize_x * 2));\r
145                 drawsubpic(theOrigin,          square + width, pic, '0 0 0', eX + bH, theColor, theAlpha, 0);\r
146                 drawsubpic(theOrigin + square, square + width, pic, eY - bH, eX + bH, theColor, theAlpha, 0);\r
147         }\r
148         else\r
149         {\r
150                 square = eY * theSize_x;\r
151                 drawsubpic(theOrigin,                   width   +     square, pic, '0 0    0', '1 0.25 0', theColor, theAlpha, 0);\r
152                 drawsubpic(theOrigin +          square, theSize - 2 * square, pic, '0 0.25 0', '1 0.5  0', theColor, theAlpha, 0);\r
153                 drawsubpic(theOrigin + height - square, width   +     square, pic, '0 0.75 0', '1 0.25 0', theColor, theAlpha, 0);\r
154         }\r
155 }\r
156 \r
157 // a border picture is a texture containing nine parts:\r
158 //   1/4 width: left part\r
159 //   1/2 width: middle part (stretched)\r
160 //   1/4 width: right part\r
161 // divided into\r
162 //   1/4 height: top part\r
163 //   1/2 height: middle part (stretched)\r
164 //   1/4 height: bottom part\r
165 void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize)\r
166 {\r
167         vector dX, dY;\r
168         vector width, height;\r
169         vector bW, bH;\r
170         pic = draw_UseSkinFor(pic);\r
171         theOrigin = boxToGlobal(theOrigin, draw_shift, draw_scale);\r
172         theSize = boxToGlobalSize(theSize, draw_scale);\r
173         theBorderSize = boxToGlobalSize(theBorderSize, draw_scale);\r
174         theAlpha *= draw_alpha;\r
175         width = eX * theSize_x;\r
176         height = eY * theSize_y;\r
177         if(theSize_x <= theBorderSize_x * 2)\r
178         {\r
179                 // not wide enough... draw just left and right then\r
180                 bW = eX * (0.25 * theSize_x / (theBorderSize_x * 2));\r
181                 if(theSize_y <= theBorderSize_y * 2)\r
182                 {\r
183                         // not high enough... draw just corners\r
184                         bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2));\r
185                         drawsubpic(theOrigin,                 width * 0.5 + height * 0.5, pic, '0 0 0',           bW + bH, theColor, theAlpha, 0);\r
186                         drawsubpic(theOrigin + width   * 0.5, width * 0.5 + height * 0.5, pic, eX - bW,           bW + bH, theColor, theAlpha, 0);\r
187                         drawsubpic(theOrigin + height  * 0.5, width * 0.5 + height * 0.5, pic, eY - bH,           bW + bH, theColor, theAlpha, 0);\r
188                         drawsubpic(theOrigin + theSize * 0.5, width * 0.5 + height * 0.5, pic, eX + eY - bW - bH, bW + bH, theColor, theAlpha, 0);\r
189                 }\r
190                 else\r
191                 {\r
192                         dY = theBorderSize_x * eY;\r
193                         drawsubpic(theOrigin,                             width * 0.5          +     dY, pic, '0 0    0',           '0 0.25 0' + bW, theColor, theAlpha, 0);\r
194                         drawsubpic(theOrigin + width * 0.5,               width * 0.5          +     dY, pic, '0 0    0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);\r
195                         drawsubpic(theOrigin                        + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0',           '0 0.5  0' + bW, theColor, theAlpha, 0);\r
196                         drawsubpic(theOrigin + width * 0.5          + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0' + eX - bW, '0 0.5  0' + bW, theColor, theAlpha, 0);\r
197                         drawsubpic(theOrigin               + height - dY, width * 0.5          +     dY, pic, '0 0.75 0',           '0 0.25 0' + bW, theColor, theAlpha, 0);\r
198                         drawsubpic(theOrigin + width * 0.5 + height - dY, width * 0.5          +     dY, pic, '0 0.75 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);\r
199                 }\r
200         }\r
201         else\r
202         {\r
203                 if(theSize_y <= theBorderSize_y * 2)\r
204                 {\r
205                         // not high enough... draw just top and bottom then\r
206                         bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2));\r
207                         dX = theBorderSize_x * eX;\r
208                         drawsubpic(theOrigin,                                         dX + height * 0.5, pic, '0    0 0',           '0.25 0 0' + bH, theColor, theAlpha, 0);\r
209                         drawsubpic(theOrigin + dX,                        width - 2 * dX + height * 0.5, pic, '0.25 0 0',           '0.5  0 0' + bH, theColor, theAlpha, 0);\r
210                         drawsubpic(theOrigin + width - dX,                            dX + height * 0.5, pic, '0.75 0 0',           '0.25 0 0' + bH, theColor, theAlpha, 0);\r
211                         drawsubpic(theOrigin              + height * 0.5,             dX + height * 0.5, pic, '0    0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);\r
212                         drawsubpic(theOrigin + dX         + height * 0.5, width - 2 * dX + height * 0.5, pic, '0.25 0 0' + eY - bH, '0.5  0 0' + bH, theColor, theAlpha, 0);\r
213                         drawsubpic(theOrigin + width - dX + height * 0.5,             dX + height * 0.5, pic, '0.75 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);\r
214                 }\r
215                 else\r
216                 {\r
217                         dX = theBorderSize_x * eX;\r
218                         dY = theBorderSize_x * eY;\r
219                         drawsubpic(theOrigin,                                        dX          +     dY, pic, '0    0    0', '0.25 0.25 0', theColor, theAlpha, 0);\r
220                         drawsubpic(theOrigin                  + dX,      width - 2 * dX          +     dY, pic, '0.25 0    0', '0.5  0.25 0', theColor, theAlpha, 0);\r
221                         drawsubpic(theOrigin          + width - dX,                  dX          +     dY, pic, '0.75 0    0', '0.25 0.25 0', theColor, theAlpha, 0);\r
222                         drawsubpic(theOrigin          + dY,                          dX + height - 2 * dY, pic, '0    0.25 0', '0.25 0.5  0', theColor, theAlpha, 0);\r
223                         drawsubpic(theOrigin          + dY         + dX, width - 2 * dX + height - 2 * dY, pic, '0.25 0.25 0', '0.5  0.5  0', theColor, theAlpha, 0);\r
224                         drawsubpic(theOrigin          + dY + width - dX,             dX + height - 2 * dY, pic, '0.75 0.25 0', '0.25 0.5  0', theColor, theAlpha, 0);\r
225                         drawsubpic(theOrigin + height - dY,                          dX          +     dY, pic, '0    0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);\r
226                         drawsubpic(theOrigin + height - dY         + dX, width - 2 * dX          +     dY, pic, '0.25 0.75 0', '0.5  0.25 0', theColor, theAlpha, 0);\r
227                         drawsubpic(theOrigin + height - dY + width - dX,             dX          +     dY, pic, '0.75 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);\r
228                 }\r
229         }\r
230 }\r
231 void draw_Text(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)\r
232 {\r
233         vector fs;\r
234         if(theSize_x <= 0 || theSize_y <= 0)\r
235                 error("Drawing zero size text?\n");\r
236         if not(cvar("menu_font_size_snapping_fix")) // FIXME remove this, this is to detect old engines\r
237         {\r
238                 fs = draw_fontscale;\r
239                 draw_fontscale = '1 1 0';\r
240         }\r
241         if(ICanHasKallerz)\r
242                 drawcolorcodedstring(boxToGlobal(theOrigin, draw_shift, draw_scale), theText, globalToBoxSize(boxToGlobalSize(theSize, draw_scale), draw_fontscale), theAlpha * draw_alpha, 0);\r
243         else\r
244                 drawstring(boxToGlobal(theOrigin, draw_shift, draw_scale), theText, globalToBoxSize(boxToGlobalSize(theSize, draw_scale), draw_fontscale), theColor, theAlpha * draw_alpha, 0);\r
245         if not(cvar("menu_font_size_snapping_fix")) // FIXME remove this, this is to detect old engines\r
246         {\r
247                 draw_fontscale = fs;\r
248         }\r
249 }\r
250 void draw_CenterText(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)\r
251 {\r
252         //print(strcat("orig = ", vtos(theOrigin) ," tx = ", ftos(draw_TextWidth(theText, ICanHasKallerz, theSize)), "\n"));\r
253         draw_Text(theOrigin - eX * 0.5 * draw_TextWidth(theText, ICanHasKallerz, theSize), theText, theSize, theColor, theAlpha, ICanHasKallerz);\r
254 }\r
255 \r
256 float draw_TextWidth(string theText, float ICanHasKallerz, vector SizeThxBye)\r
257 {\r
258         //return strlen(theText);\r
259         //print("draw_TextWidth \"", theText, "\"\n");\r
260         vector fs;\r
261         vector v;\r
262         v = '0 0 0';\r
263         //float r;\r
264         if not(cvar("menu_font_size_snapping_fix")) // FIXME remove this, this is to detect old engines\r
265         {\r
266                 fs = draw_fontscale;\r
267                 draw_fontscale = '1 1 0';\r
268         }\r
269         v_x = stringwidth(theText, ICanHasKallerz, boxToGlobalSize(SizeThxBye, draw_scale)) / draw_fontscale_x;\r
270         if not(cvar("menu_font_size_snapping_fix")) // FIXME remove this, this is to detect old engines\r
271         {\r
272                 draw_fontscale = fs;\r
273         }\r
274         v = globalToBoxSize(v, draw_scale);\r
275         return v_x;\r
276 }\r
277 \r
278 float draw_clipSet;\r
279 void draw_SetClip()\r
280 {\r
281         if(draw_clipSet)\r
282                 error("Already clipping, no stack implemented here, sorry");\r
283         drawsetcliparea(draw_shift_x, draw_shift_y, draw_scale_x, draw_scale_y);\r
284         draw_clipSet = 1;\r
285 }\r
286 \r
287 void draw_SetClipRect(vector theOrigin, vector theScale)\r
288 {\r
289         vector o, s;\r
290         if(draw_clipSet)\r
291                 error("Already clipping, no stack implemented here, sorry");\r
292         o = boxToGlobal(theOrigin, draw_shift, draw_scale);\r
293         s = boxToGlobalSize(theScale, draw_scale);\r
294         drawsetcliparea(o_x, o_y, s_x, s_y);\r
295         draw_clipSet = 1;\r
296 }\r
297 \r
298 void draw_ClearClip()\r
299 {\r
300         if(!draw_clipSet)\r
301                 error("Not clipping, can't clear it then");\r
302         drawresetcliparea();\r
303         draw_clipSet = 0;\r
304 }\r
305 \r
306 string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKallerz, vector SizeThxBye)\r
307 {\r
308         /*\r
309         if(draw_TextWidth(theText, ICanHasKallerz, SizeThxBye) <= maxWidth)\r
310                 return theText;\r
311         else\r
312                 return strcat(substring(theText, 0, draw_TextLengthUpToWidth(theText, maxWidth - draw_TextWidth("...", ICanHasKallerz, SizeThxBye), ICanHasKallerz, SizeThxBye)), "...");\r
313         */\r
314         if(ICanHasKallerz)\r
315                 return textShortenToWidth(theText, maxWidth, SizeThxBye, draw_TextWidth_WithColors);\r
316         else\r
317                 return textShortenToWidth(theText, maxWidth, SizeThxBye, draw_TextWidth_WithoutColors);\r
318 }\r
319 \r
320 float draw_TextWidth_WithColors(string s, vector theFontSize)\r
321 {\r
322         return draw_TextWidth(s, TRUE, theFontSize);\r
323 }\r
324 \r
325 float draw_TextWidth_WithoutColors(string s, vector theFontSize)\r
326 {\r
327         return draw_TextWidth(s, FALSE, theFontSize);\r
328 }\r
329 \r
330 float draw_TextLengthUpToWidth(string theText, float maxWidth, float allowColorCodes, vector theFontSize)\r
331 {\r
332         if(allowColorCodes)\r
333                 return textLengthUpToWidth(theText, maxWidth, theFontSize, draw_TextWidth_WithColors);\r
334         else\r
335                 return textLengthUpToWidth(theText, maxWidth, theFontSize, draw_TextWidth_WithoutColors);\r
336 }\r