2 string draw_mousepointer;
4 string draw_UseSkinFor(string pic)
6 if(substring(pic, 0, 1) == "/")
7 return substring(pic, 1, strlen(pic)-1);
9 return strcat(draw_currentSkin, "/", pic);
12 void draw_setMousePointer(string pic)
14 draw_mousepointer = strzone(draw_UseSkinFor(pic));
17 void draw_drawMousePointer(vector where)
19 drawpic(boxToGlobal(where, draw_shift, draw_scale), draw_mousepointer, '32 32 0', '1 1 1', draw_alpha, 0);
26 draw_scale = '1 0 0' * cvar("vid_conwidth") + '0 1 0' * cvar("vid_conheight");
30 vector globalToBox(vector v, vector theOrigin, vector theScale)
38 vector globalToBoxSize(vector v, vector theScale)
45 vector boxToGlobal(vector v, vector theOrigin, vector theScale)
53 vector boxToGlobalSize(vector v, vector theScale)
60 void draw_PreloadPicture(string pic)
62 pic = draw_UseSkinFor(pic);
66 void draw_Picture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)
68 pic = draw_UseSkinFor(pic);
69 drawpic(boxToGlobal(theOrigin, draw_shift, draw_scale), pic, boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0);
72 vector draw_PictureSize(string pic)
74 pic = draw_UseSkinFor(pic);
75 return drawgetimagesize(pic);
78 void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha)
80 drawfill(boxToGlobal(theOrigin, draw_shift, draw_scale), boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0);
83 // a button picture is a texture containing three parts:
84 // 1/4 width: left part
85 // 1/2 width: middle part (stretched)
86 // 1/4 width: right part
87 // it is assumed to be 4x as wide as high for aspect ratio purposes, which
88 // means, the parts are a square, two squares and a square.
89 void draw_ButtonPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)
94 pic = draw_UseSkinFor(pic);
95 theOrigin = boxToGlobal(theOrigin, draw_shift, draw_scale);
96 theSize = boxToGlobalSize(theSize, draw_scale);
97 theAlpha *= draw_alpha;
98 width = eX * theSize_x;
99 height = eY * theSize_y;
100 if(theSize_x <= theSize_y * 2)
102 // button not wide enough
103 // draw just left and right part then
104 square = eX * theSize_x * 0.5;
105 bW = eX * (0.25 * theSize_x / (theSize_y * 2));
106 drawsubpic(theOrigin, square + height, pic, '0 0 0', eY + bW, theColor, theAlpha, 0);
107 drawsubpic(theOrigin + square, square + height, pic, eX - bW, eY + bW, theColor, theAlpha, 0);
111 square = eX * theSize_y;
112 drawsubpic(theOrigin, height + square, pic, '0 0 0', '0.25 1 0', theColor, theAlpha, 0);
113 drawsubpic(theOrigin + square, theSize - 2 * square, pic, '0.25 0 0', '0.5 1 0', theColor, theAlpha, 0);
114 drawsubpic(theOrigin + width - square, height + square, pic, '0.75 0 0', '0.25 1 0', theColor, theAlpha, 0);
118 // a vertical button picture is a texture containing three parts:
119 // 1/4 height: left part
120 // 1/2 height: middle part (stretched)
121 // 1/4 height: right part
122 // it is assumed to be 4x as high as wide for aspect ratio purposes, which
123 // means, the parts are a square, two squares and a square.
124 void draw_VertButtonPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)
127 vector width, height;
129 pic = draw_UseSkinFor(pic);
130 theOrigin = boxToGlobal(theOrigin, draw_shift, draw_scale);
131 theSize = boxToGlobalSize(theSize, draw_scale);
132 theAlpha *= draw_alpha;
133 width = eX * theSize_x;
134 height = eY * theSize_y;
135 if(theSize_y <= theSize_x * 2)
137 // button not high enough
138 // draw just upper and lower part then
139 square = eY * theSize_y * 0.5;
140 bH = eY * (0.25 * theSize_y / (theSize_x * 2));
141 drawsubpic(theOrigin, square + width, pic, '0 0 0', eX + bH, theColor, theAlpha, 0);
142 drawsubpic(theOrigin + square, square + width, pic, eY - bH, eX + bH, theColor, theAlpha, 0);
146 square = eY * theSize_x;
147 drawsubpic(theOrigin, width + square, pic, '0 0 0', '1 0.25 0', theColor, theAlpha, 0);
148 drawsubpic(theOrigin + square, theSize - 2 * square, pic, '0 0.25 0', '1 0.5 0', theColor, theAlpha, 0);
149 drawsubpic(theOrigin + height - square, width + square, pic, '0 0.75 0', '1 0.25 0', theColor, theAlpha, 0);
153 // a border picture is a texture containing nine parts:
154 // 1/4 width: left part
155 // 1/2 width: middle part (stretched)
156 // 1/4 width: right part
158 // 1/4 height: top part
159 // 1/2 height: middle part (stretched)
160 // 1/4 height: bottom part
161 void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize)
164 vector width, height;
166 pic = draw_UseSkinFor(pic);
167 theOrigin = boxToGlobal(theOrigin, draw_shift, draw_scale);
168 theSize = boxToGlobalSize(theSize, draw_scale);
169 theBorderSize = boxToGlobalSize(theBorderSize, draw_scale);
170 theAlpha *= draw_alpha;
171 width = eX * theSize_x;
172 height = eY * theSize_y;
173 if(theSize_x <= theBorderSize_x * 2)
175 // not wide enough... draw just left and right then
176 bW = eX * (0.25 * theSize_x / (theBorderSize_x * 2));
177 if(theSize_y <= theBorderSize_y * 2)
179 // not high enough... draw just corners
180 bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2));
181 drawsubpic(theOrigin, width * 0.5 + height * 0.5, pic, '0 0 0', bW + bH, theColor, theAlpha, 0);
182 drawsubpic(theOrigin + width * 0.5, width * 0.5 + height * 0.5, pic, eX - bW, bW + bH, theColor, theAlpha, 0);
183 drawsubpic(theOrigin + height * 0.5, width * 0.5 + height * 0.5, pic, eY - bH, bW + bH, theColor, theAlpha, 0);
184 drawsubpic(theOrigin + theSize * 0.5, width * 0.5 + height * 0.5, pic, eX + eY - bW - bH, bW + bH, theColor, theAlpha, 0);
188 dY = theBorderSize_x * eY;
189 drawsubpic(theOrigin, width * 0.5 + dY, pic, '0 0 0', '0 0.25 0' + bW, theColor, theAlpha, 0);
190 drawsubpic(theOrigin + width * 0.5, width * 0.5 + dY, pic, '0 0 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);
191 drawsubpic(theOrigin + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0);
192 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);
193 drawsubpic(theOrigin + height - dY, width * 0.5 + dY, pic, '0 0.75 0', '0 0.25 0' + bW, theColor, theAlpha, 0);
194 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);
199 if(theSize_y <= theBorderSize_y * 2)
201 // not high enough... draw just top and bottom then
202 bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2));
203 dX = theBorderSize_x * eX;
204 drawsubpic(theOrigin, dX + height * 0.5, pic, '0 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0);
205 drawsubpic(theOrigin + dX, width - 2 * dX + height * 0.5, pic, '0.25 0 0', '0.5 0 0' + bH, theColor, theAlpha, 0);
206 drawsubpic(theOrigin + width - dX, dX + height * 0.5, pic, '0.75 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0);
207 drawsubpic(theOrigin + height * 0.5, dX + height * 0.5, pic, '0 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);
208 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);
209 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);
213 dX = theBorderSize_x * eX;
214 dY = theBorderSize_x * eY;
215 drawsubpic(theOrigin, dX + dY, pic, '0 0 0', '0.25 0.25 0', theColor, theAlpha, 0);
216 drawsubpic(theOrigin + dX, width - 2 * dX + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0);
217 drawsubpic(theOrigin + width - dX, dX + dY, pic, '0.75 0 0', '0.25 0.25 0', theColor, theAlpha, 0);
218 drawsubpic(theOrigin + dY, dX + height - 2 * dY, pic, '0 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0);
219 drawsubpic(theOrigin + dY + dX, width - 2 * dX + height - 2 * dY, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0);
220 drawsubpic(theOrigin + dY + width - dX, dX + height - 2 * dY, pic, '0.75 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0);
221 drawsubpic(theOrigin + height - dY, dX + dY, pic, '0 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);
222 drawsubpic(theOrigin + height - dY + dX, width - 2 * dX + dY, pic, '0.25 0.75 0', '0.5 0.25 0', theColor, theAlpha, 0);
223 drawsubpic(theOrigin + height - dY + width - dX, dX + dY, pic, '0.75 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);
227 void draw_Text(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)
229 if(theSize_x <= 0 || theSize_y <= 0)
230 error("Drawing zero size text?\n");
232 drawcolorcodedstring(boxToGlobal(theOrigin, draw_shift, draw_scale), theText, boxToGlobalSize(theSize, draw_scale), theAlpha * draw_alpha, 0);
234 drawstring(boxToGlobal(theOrigin, draw_shift, draw_scale), theText, boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0);
236 void draw_CenterText(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)
238 draw_Text(theOrigin - eX * theSize_x * 0.5 * draw_TextWidth(theText, ICanHasKallerz), theText, theSize, theColor, theAlpha, ICanHasKallerz);
241 float draw_TextWidth(string theText, float ICanHasKallerz)
243 //return strlen(theText);
244 //print("draw_TextWidth \"", theText, "\"\n");
245 return stringwidth(theText, ICanHasKallerz);
252 error("Already clipping, no stack implemented here, sorry");
253 drawsetcliparea(draw_shift_x, draw_shift_y, draw_scale_x, draw_scale_y);
257 void draw_SetClipRect(vector theOrigin, vector theScale)
261 error("Already clipping, no stack implemented here, sorry");
262 o = boxToGlobal(theOrigin, draw_shift, draw_scale);
263 s = boxToGlobalSize(theScale, draw_scale);
264 drawsetcliparea(o_x, o_y, s_x, s_y);
268 void draw_ClearClip()
271 error("Not clipping, can't clear it then");
276 string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKallerz)
278 if(draw_TextWidth(theText, ICanHasKallerz) <= maxWidth)
281 return strcat(substring(theText, 0, draw_TextLengthUpToWidth(theText, maxWidth - draw_TextWidth("...", ICanHasKallerz), ICanHasKallerz)), "...");
284 float draw_TextLengthUpToWidth(string theText, float maxWidth, float ICanHasKallerz)
287 // The following function is SLOW.
288 // For your safety and for the protection of those around you...
289 // DO NOT CALL THIS AT HOME.
291 if(draw_TextWidth(theText, ICanHasKallerz) <= maxWidth)
292 return strlen(theText); // yeah!
294 // binary search for right place to cut string
295 float left, right, middle; // this always works
297 right = strlen(theText); // this always fails
300 middle = floor((left + right) / 2);
301 if(draw_TextWidth(substring(theText, 0, middle), ICanHasKallerz) <= maxWidth)
306 while(left < right - 1);
308 // NOTE: when color codes are involved, this binary search is,
309 // mathematically, BROKEN. However, it is obviously guaranteed to
310 // terminate, as the range still halves each time - but nevertheless, it is
311 // guaranteed that it finds ONE valid cutoff place (where "left" is in
312 // range, and "right" is outside).