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