2 // Miscellaneous GUI utility functions
12 #include "guielements.h" // Make this go away...
13 #include "sdlemu_opengl.h"
14 #include "vj_title_small.c"
18 // Case insensitive string compare function
19 // Taken straight out of Thinking In C++ by Bruce Eckel. Thanks Bruce!
22 int stringCmpi(const std::string &s1, const std::string &s2)
24 // Select the first element of each string:
25 std::string::const_iterator p1 = s1.begin(), p2 = s2.begin();
27 while (p1 != s1.end() && p2 != s2.end()) // Don�t run past the end
29 if (toupper(*p1) != toupper(*p2)) // Compare upper-cased chars
30 return (toupper(*p1) < toupper(*p2) ? -1 : 1);// Report which was lexically greater
36 // If they match up to the detected eos, say which was longer. Return 0 if the same.
37 return s2.size() - s1.size();
41 // Draw text at the given x/y coordinates. Can invert text as well.
43 void DrawString(uint32 * screen, uint32 x, uint32 y, bool invert, const char * text, ...)
49 vsprintf(string, text, arg);
52 uint32 pitch = sdlemuGetOverlayWidthInPixels();//GetSDLScreenWidthInPixels();
53 uint32 length = strlen(string), address = x + (y * pitch);
55 uint32 color1 = 0x0080FF;
56 uint8 nBlue = (color1 >> 16) & 0xFF, nGreen = (color1 >> 8) & 0xFF, nRed = color1 & 0xFF;
57 uint8 xorMask = (invert ? 0xFF : 0x00);
59 for(uint32 i=0; i<length; i++)
62 uint32 fontAddr = (uint32)(c < 32 ? 0 : c - 32) * FONT_WIDTH * FONT_HEIGHT;
64 for(uint32 yy=0; yy<FONT_HEIGHT; yy++)
66 for(uint32 xx=0; xx<FONT_WIDTH; xx++)
68 uint32 existingColor = *(screen + address + xx + (yy * pitch));
70 uint8 eBlue = (existingColor >> 16) & 0xFF,
71 eGreen = (existingColor >> 8) & 0xFF,
72 eRed = existingColor & 0xFF;
74 uint8 trans = font2[fontAddr] ^ xorMask;
75 uint8 invTrans = trans ^ 0xFF;
77 uint32 bRed = (eRed * invTrans + nRed * trans) / 255,
78 bGreen = (eGreen * invTrans + nGreen * trans) / 255,
79 bBlue = (eBlue * invTrans + nBlue * trans) / 255;
81 *(screen + address + xx + (yy * pitch)) = 0xFF000000 | (bBlue << 16) | (bGreen << 8) | bRed;
86 address += FONT_WIDTH;
91 // Draw text at the given x/y coordinates, using FG/BG colors.
93 void DrawStringOpaque(uint32 * screen, uint32 x, uint32 y, uint32 color1, uint32 color2, const char * text, ...)
99 vsprintf(string, text, arg);
102 uint32 pitch = sdlemuGetOverlayWidthInPixels();
103 uint32 length = strlen(string), address = x + (y * pitch);
105 uint8 eBlue = (color2 >> 16) & 0xFF, eGreen = (color2 >> 8) & 0xFF, eRed = color2 & 0xFF,
106 nBlue = (color1 >> 16) & 0xFF, nGreen = (color1 >> 8) & 0xFF, nRed = color1 & 0xFF;
108 for(uint32 i=0; i<length; i++)
111 c = (c < 32 ? 0 : c - 32);
112 uint32 fontAddr = (uint32)c * FONT_WIDTH * FONT_HEIGHT;
114 for(uint32 yy=0; yy<FONT_HEIGHT; yy++)
116 for(uint32 xx=0; xx<FONT_WIDTH; xx++)
118 uint8 trans = font2[fontAddr++];
119 uint8 invTrans = trans ^ 0xFF;
121 uint32 bRed = (eRed * invTrans + nRed * trans) / 255;
122 uint32 bGreen = (eGreen * invTrans + nGreen * trans) / 255;
123 uint32 bBlue = (eBlue * invTrans + nBlue * trans) / 255;
125 *(screen + address + xx + (yy * pitch)) = 0xFF000000 | (bBlue << 16) | (bGreen << 8) | bRed;
129 address += FONT_WIDTH;
134 // Draw text at the given x/y coordinates with transparency (0 is fully opaque, 32 is fully transparent).
136 void DrawStringTrans(uint32 * screen, uint32 x, uint32 y, uint32 color, uint8 trans, const char * text, ...)
142 vsprintf(string, text, arg);
145 uint32 pitch = sdlemuGetOverlayWidthInPixels();//GetSDLScreenWidthInPixels();
146 uint32 length = strlen(string), address = x + (y * pitch);
148 for(uint32 i=0; i<length; i++)
150 uint32 fontAddr = (uint32)string[i] * 64;
152 for(uint32 yy=0; yy<8; yy++)
154 for(uint32 xx=0; xx<8; xx++)
158 uint32 existingColor = *(screen + address + xx + (yy * pitch));
160 uint8 eBlue = (existingColor >> 16) & 0xFF,
161 eGreen = (existingColor >> 8) & 0xFF,
162 eRed = existingColor & 0xFF,
163 //This could be done ahead of time, instead of on each pixel...
164 nBlue = (color >> 16) & 0xFF,
165 nGreen = (color >> 8) & 0xFF,
168 //This could be sped up by using a table of 5 + 5 + 5 bits (32 levels transparency -> 32768 entries)
169 //Here we've modified it to have 33 levels of transparency (could have any # we want!)
170 //because dividing by 32 is faster than dividing by 31...!
171 uint8 invTrans = 32 - trans;
173 uint32 bRed = (eRed * trans + nRed * invTrans) / 32;
174 uint32 bGreen = (eGreen * trans + nGreen * invTrans) / 32;
175 uint32 bBlue = (eBlue * trans + nBlue * invTrans) / 32;
177 *(screen + address + xx + (yy * pitch)) = 0xFF000000 | (bBlue << 16) | (bGreen << 8) | bRed;
189 // Draw text at the given x/y coordinates, using FG color and overlay alpha blending.
191 void DrawString2(uint32 * screen, uint32 x, uint32 y, uint32 color, uint8 transparency, const char * text, ...)
197 vsprintf(string, text, arg);
200 uint32 pitch = sdlemuGetOverlayWidthInPixels();
201 uint32 length = strlen(string), address = x + (y * pitch);
203 color &= 0x00FFFFFF; // Just in case alpha was passed in...
205 for(uint32 i=0; i<length; i++)
208 c = (c < 32 ? 0 : c - 32);
209 uint32 fontAddr = (uint32)c * FONT_WIDTH * FONT_HEIGHT;
211 for(uint32 yy=0; yy<FONT_HEIGHT; yy++)
213 for(uint32 xx=0; xx<FONT_WIDTH; xx++)
215 uint8 fontTrans = font2[fontAddr++];
216 uint32 newTrans = (fontTrans * transparency / 255) << 24;
217 uint32 pixel = newTrans | color;
219 *(screen + address + xx + (yy * pitch)) = pixel;
223 address += FONT_WIDTH;
229 // Uses zero as transparent color
230 // Can also use an optional alpha channel
231 // Alpha channel is now mandatory! ;-)
233 //void DrawTransparentBitmap(int16 * screen, uint32 x, uint32 y, uint16 * bitmap, uint8 * alpha/*=NULL*/)
234 /*void DrawTransparentBitmap(uint32 * screen, uint32 x, uint32 y, uint32 * bitmap, uint8 * alpha)
236 uint32 width = bitmap[0], height = bitmap[1];
239 // uint32 pitch = GetSDLScreenPitch() / 2; // Returns pitch in bytes but we need words...
240 uint32 pitch = sdlemuGetOverlayWidthInPixels();//GetSDLScreenWidthInPixels();
241 uint32 address = x + (y * pitch);
243 for(uint32 yy=0; yy<height; yy++)
245 for(uint32 xx=0; xx<width; xx++)
249 if (*bitmap && x + xx < pitch) // NOTE: Still doesn't clip the Y val...
250 *(screen + address + xx + (yy * pitch)) = *bitmap;
254 uint8 trans = *alpha;
255 uint32 color = *bitmap;
256 uint32 existingColor = *(screen + address + xx + (yy * pitch));
258 uint8 eRed = existingColor & 0xFF,
259 eGreen = (existingColor >> 8) & 0xFF,
260 eBlue = (existingColor >> 16) & 0xFF,
263 nGreen = (color >> 8) & 0xFF,
264 nBlue = (color >> 16) & 0xFF;
266 uint8 invTrans = 255 - trans;
267 uint32 bRed = (eRed * trans + nRed * invTrans) / 255;
268 uint32 bGreen = (eGreen * trans + nGreen * invTrans) / 255;
269 uint32 bBlue = (eBlue * trans + nBlue * invTrans) / 255;
271 uint32 blendedColor = 0xFF000000 | bRed | (bGreen << 8) | (bBlue << 16);
273 *(screen + address + xx + (yy * pitch)) = blendedColor;
282 void DrawTransparentBitmapDeprecated(uint32 * screen, uint32 x, uint32 y, uint32 * bitmap)
284 uint32 width = bitmap[0], height = bitmap[1];
287 uint32 pitch = sdlemuGetOverlayWidthInPixels();//GetSDLScreenWidthInPixels();
288 uint32 address = x + (y * pitch);
290 for(uint32 yy=0; yy<height; yy++)
292 for(uint32 xx=0; xx<width; xx++)
294 uint32 color = *bitmap;
295 uint32 blendedColor = color;
296 uint32 existingColor = *(screen + address + xx + (yy * pitch));
298 if (existingColor >> 24 != 0x00) // Pixel needs blending
300 uint8 trans = color >> 24;
301 uint8 invTrans = trans ^ 0xFF;//255 - trans;
303 uint8 eRed = existingColor & 0xFF,
304 eGreen = (existingColor >> 8) & 0xFF,
305 eBlue = (existingColor >> 16) & 0xFF,
308 nGreen = (color >> 8) & 0xFF,
309 nBlue = (color >> 16) & 0xFF;
311 uint32 bRed = (eRed * invTrans + nRed * trans) / 255;
312 uint32 bGreen = (eGreen * invTrans + nGreen * trans) / 255;
313 uint32 bBlue = (eBlue * invTrans + nBlue * trans) / 255;
315 blendedColor = 0xFF000000 | bRed | (bGreen << 8) | (bBlue << 16);
318 *(screen + address + xx + (yy * pitch)) = blendedColor;
324 void DrawTransparentBitmap(uint32 * screen, uint32 x, uint32 y, const void * bitmap)
326 uint32 pitch = sdlemuGetOverlayWidthInPixels();
327 uint32 address = x + (y * pitch);
330 for(uint32 yy=0; yy<((Bitmap *)bitmap)->height; yy++)
332 for(uint32 xx=0; xx<((Bitmap *)bitmap)->width; xx++)
334 uint32 color = ((uint32 *)((Bitmap *)bitmap)->pixelData)[count];
335 uint32 blendedColor = color;
336 uint32 existingColor = *(screen + address + xx + (yy * pitch));
338 if (existingColor >> 24 != 0x00) // Pixel needs blending
340 uint8 trans = color >> 24;
341 uint8 invTrans = trans ^ 0xFF;
343 uint8 eRed = existingColor & 0xFF,
344 eGreen = (existingColor >> 8) & 0xFF,
345 eBlue = (existingColor >> 16) & 0xFF,
348 nGreen = (color >> 8) & 0xFF,
349 nBlue = (color >> 16) & 0xFF;
351 uint32 bRed = (eRed * invTrans + nRed * trans) / 255;
352 uint32 bGreen = (eGreen * invTrans + nGreen * trans) / 255;
353 uint32 bBlue = (eBlue * invTrans + nBlue * trans) / 255;
355 // Instead of $FF, should use the alpha from the destination pixel as the final alpha value...
356 blendedColor = 0xFF000000 | bRed | (bGreen << 8) | (bBlue << 16);
359 *(screen + address + xx + (yy * pitch)) = blendedColor;
366 // Draw a bitmap without using blending
368 void DrawBitmap(uint32 * screen, uint32 x, uint32 y, const void * bitmap)
370 uint32 pitch = sdlemuGetOverlayWidthInPixels();
371 uint32 address = x + (y * pitch);
374 for(uint32 yy=0; yy<((Bitmap *)bitmap)->height; yy++)
376 for(uint32 xx=0; xx<((Bitmap *)bitmap)->width; xx++)
378 *(screen + address + xx + (yy * pitch)) = ((uint32 *)((Bitmap *)bitmap)->pixelData)[count];
385 // Fill a portion of the screen with the passed in color
387 void FillScreenRectangle(uint32 * screen, uint32 x, uint32 y, uint32 w, uint32 h, uint32 color)
388 //void ClearScreenRectangle(uint32 * screen, uint32 x, uint32 y, uint32 w, uint32 h)
390 uint32 pitch = sdlemuGetOverlayWidthInPixels();
391 uint32 address = x + (y * pitch);
393 for(uint32 yy=0; yy<h; yy++)
394 for(uint32 xx=0; xx<w; xx++)
395 *(screen + address + xx + (yy * pitch)) = color;