Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/modules/GUI/graphic_utils.c

Source at commit 735 created 13 years 2 months ago.
By meklort, GUI module bugfixes. Kext Patcher additions.
1
2/* Graphic utility functions and data types
3 * Prashant Vaibhav (C) 12/12/2008
4 * Chameleon
5 */
6#include "boot.h"
7#include "graphic_utils.h"
8#include "graphics.h"
9#include "vbe.h"
10#include "gui.h"
11
12#define VIDEO(x) (bootArgs->Video.v_ ## x)
13
14#define MIN(x, y) ((x) < (y) ? (x) : (y))
15
16
17
18int
19convertImage( unsigned short width,
20 unsigned short height,
21 const unsigned char *imageData,
22 unsigned char **newImageData )
23{
24 int cnt;
25 unsigned char *img = 0;
26 unsigned short *img16;
27 unsigned long *img32;
28
29 switch ( VIDEO(depth) ) {
30case 16 :
31img16 = malloc(width * height * 2);
32if ( !img16 ) break;
33for (cnt = 0; cnt < (width * height); cnt++)
34img16[cnt] = lookUpCLUTIndex(imageData[cnt], 16);
35img = (unsigned char *)img16;
36break;
37
38case 32 :
39img32 = malloc(width * height * 4);
40if ( !img32 ) break;
41for (cnt = 0; cnt < (width * height); cnt++)
42img32[cnt] = lookUpCLUTIndex(imageData[cnt], 32);
43img = (unsigned char *)img32;
44break;
45
46default :
47img = malloc(width * height);
48bcopy(imageData, img, width * height);
49break;
50 }
51 *newImageData = img;
52 return 0;
53}
54
55
56//==========================================================================
57//
58void
59printVBEModeInfo()
60{
61 VBEInfoBlock vbeInfo;
62 unsigned short * modePtr;
63 VBEModeInfoBlock modeInfo;
64 int err;
65 int line;
66
67 bzero( &vbeInfo, sizeof(vbeInfo) );
68 strcpy( (char*)&vbeInfo, "VBE2" );
69 err = getVBEInfo( &vbeInfo );
70 if ( err != errSuccess )
71 return;
72
73 line = 0;
74
75 // Activate and clear page 1
76 setActiveDisplayPage(1);
77 clearScreenRows(0, 24);
78 setCursorPosition( 0, 0, 1 );
79
80printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr));
81
82// Loop through the mode list, and find the matching mode.
83
84 for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
85 *modePtr != modeEndOfList; modePtr++ )
86 {
87 // Get mode information.
88
89 bzero( &modeInfo, sizeof(modeInfo) );
90 err = getVBEModeInfo( *modePtr, &modeInfo );
91 if ( err != errSuccess )
92 {
93 continue;
94 }
95
96 printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
97 *modePtr, modeInfo.XResolution, modeInfo.YResolution,
98 modeInfo.BitsPerPixel, modeInfo.MemoryModel,
99 modeInfo.ModeAttributes);
100
101 if (line++ >= 20) {
102 pause();
103 line = 0;
104 clearScreenRows(0, 24);
105 setCursorPosition( 0, 0, 1 );
106 }
107 }
108 if (line != 0) {
109 pause();
110 }
111 setActiveDisplayPage(0);
112}
113
114
115
116char *getVBEModeInfoString()
117{
118VBEInfoBlock vbeInfo;
119 unsigned short * modePtr;
120 VBEModeInfoBlock modeInfo;
121 int err;
122
123 bzero( &vbeInfo, sizeof(vbeInfo) );
124 strcpy( (char*)&vbeInfo, "VBE2" );
125 err = getVBEInfo( &vbeInfo );
126 if ( err != errSuccess )
127 return 0;
128
129char *buff=malloc(sizeof(char)*3072);
130if(!buff) return 0;
131
132// Loop through the mode list, and find the matching mode.
133 for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
134 *modePtr != modeEndOfList; modePtr++ )
135 {
136 // Get mode information.
137
138 bzero( &modeInfo, sizeof(modeInfo) );
139 err = getVBEModeInfo( *modePtr, &modeInfo );
140 if ( err != errSuccess )
141 {
142 continue;
143 }
144
145 sprintf(buff+strlen(buff), "Mode %x: %dx%dx%d mm:%d attr:%x\n",
146*modePtr, modeInfo.XResolution, modeInfo.YResolution,
147modeInfo.BitsPerPixel, modeInfo.MemoryModel,
148modeInfo.ModeAttributes);
149
150 }
151return buff;
152}
153
154
155void blendImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
156uint8_t *data)
157{
158 uint16_t drawWidth;
159 uint8_t *vram = (uint8_t *) VIDEO(baseAddr) + VIDEO(rowBytes) * y + 4 * x;
160
161 drawWidth = MIN(width, VIDEO(width) - x);
162 height = MIN(height, VIDEO(height) - y);
163 while (height--) {
164switch (VIDEO (depth))
165{
166case 32: /* Optimized version*/
167{
168uint32_t s; uint32_t* d; // Source (img) and destination (bkgd) pixels
169uint32_t a; // Alpha
170uint32_t dstrb, dstg, srcrb, srcg, drb, dg, rb, g, tempB; // Intermediate variables
171uint16_t pos;
172
173for (pos = 0; pos < drawWidth * 4; pos += 4) {
174// Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html
175s = *((uint32_t*) (data + pos));
176d = (uint32_t*) (vram + pos);
177
178// Flip B and R in source
179// TODO: use XCHG and inline assembly to do this in a faster, saner way
180tempB = (s & 0xFF0000); // save B
181s = (s & 0xFF00FFFF) | ((s & 0xFF) << 16); // put R in B
182s = (s & 0xFFFFFF00) | (tempB >> 16); // put B in R
183
184a = (s >> 24) + 1;
185
186dstrb = *d & 0xFF00FF; dstg = *d & 0xFF00;
187srcrb = s & 0xFF00FF; srcg = s & 0xFF00;
188
189drb = srcrb - dstrb;
190dg = srcg - dstg;
191drb *= a; dg *= a;
192drb >>= 8; dg >>= 8;
193
194rb = (drb + dstrb) & 0xFF00FF;
195g = (dg + dstg) & 0xFF00;
196
197*d = rb | g;
198}
199}
200break;
201
202default: /*Universal version*/
203{
204uint32_t s;
205uint32_t a; // Alpha
206uint32_t dr, dg, db, sr, sg, sb; // Intermediate variables
207uint16_t pos;
208int bpp = (VIDEO (depth) + 7)/8;
209
210for (pos = 0; pos < drawWidth; pos ++) {
211// Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html
212s = *((uint32_t*) (data + 4*pos));
213
214sb = (s & 0xFF0000) >> 16;
215sg = (s & 0xFF00) >> 8;
216sr = (s & 0xFF);
217
218a = (s >> 24) + 1;
219
220switch (VIDEO (depth))
221{
222case 24:
223db = ((*(uint32_t *)(vram + bpp*pos))&0xff);
224dg = ((*(uint32_t *)(vram + bpp*pos))&0xff00)>>8;
225dr = ((*(uint32_t *)(vram + bpp*pos))&0xff0000)>>16;
226break;
227case 16://16-bit seems to be 15-bit
228/*db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3;
229 dg = ((*(uint16_t *)(vram + bpp*pos))&0x07e0)>>3;
230 dr = ((*(uint16_t *)(vram + bpp*pos))&0xf800)>>8;
231 break;*/
232case 15:
233db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3;
234dg = ((*(uint16_t *)(vram + bpp*pos))&0x03e0)>>2;
235dr = ((*(uint16_t *)(vram + bpp*pos))&0x7c00)>>7;
236break;
237default:
238return;
239}
240
241dr = (((sr - dr) * a) >> 8) + dr;
242dg = (((sg - dg) * a) >> 8) + dg;
243db = (((sb - db) * a) >> 8) + db;
244switch (VIDEO (depth))
245{
246case 24:
247*(uint32_t *)(vram + bpp*pos) = (*(uint32_t *)(vram + bpp*pos) &0xff000000)
248| (db&0xff) | ((dg&0xff)<<8) | ((dr&0xff)<<16);
249break;
250case 16:
251//*(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xfc)<<3) | ((dr&0xf8)<<8);
252//break;
253case 15:
254*(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xf8)<<2) | ((dr&0xf8)<<7);
255break;
256}
257
258}
259}
260break;
261 }
262 vram += VIDEO(rowBytes);
263 data += width * 4;
264 }
265}
266
267void drawCheckerBoard()
268{
269 uint32_t *vram = (uint32_t *) VIDEO(baseAddr);
270 uint16_t x, y;
271 uint8_t color;
272
273 for (y = 0; y < VIDEO(height); y++, vram += VIDEO(width)) {
274 for (x = 0; x < VIDEO(width); x++) {
275 color = 204 + 51 * (((x / 8) % 2) == ((y / 8) % 2));
276 vram[x] = (color << 16) | (color << 8) | color;
277 }
278 }
279}
280
281
282//==========================================================================
283// drawDataRectangle
284
285void drawDataRectangle( unsigned short x,
286 unsigned short y,
287 unsigned short width,
288 unsigned short height,
289 unsigned char * data )
290{
291 unsigned short drawWidth;
292 long pixelBytes = VIDEO(depth) / 8;
293 unsigned char * vram = (unsigned char *) VIDEO(baseAddr) +
294VIDEO(rowBytes) * y + pixelBytes * x;
295
296 drawWidth = MIN(width, VIDEO(width) - x);
297 height = MIN(height, VIDEO(height) - y);
298 while ( height-- ) {
299 bcopy( data, vram, drawWidth * pixelBytes );
300 vram += VIDEO(rowBytes);
301 data += width * pixelBytes;
302 }
303}
304
305
306
307void getGraphicModeParams(unsigned long params[]) {
308
309params[3] = 0;
310
311VBEModeInfoBlock minfo;
312
313 unsigned short vesaVersion;
314 unsigned short mode = modeEndOfList;
315
316getNumberArrayFromProperty( kGraphicsModeKey, params, 4);
317
318mode = getVESAModeWithProperties( params[0], params[1], params[2],
319 maColorModeBit |
320 maModeIsSupportedBit |
321 maGraphicsModeBit |
322 maLinearFrameBufferAvailBit,
323 0,
324 &minfo, &vesaVersion );
325
326params[0] = minfo.XResolution;
327params[1] = minfo.YResolution;
328params[2] = 32;
329}
330
331
332//==========================================================================
333// getVBEInfoString
334
335char *getVBEInfoString()
336{
337VBEInfoBlock vbeInfo;
338int err, small;
339char *buff = malloc(sizeof(char)*256);
340if(!buff) return 0;
341
342bzero( &vbeInfo, sizeof(vbeInfo) );
343strcpy( (char*)&vbeInfo, "VBE2" );
344err = getVBEInfo( &vbeInfo );
345if (err != errSuccess)
346return 0;
347
348if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) )
349return 0;
350
351small = (vbeInfo.TotalMemory < 16);
352
353sprintf(buff, "VESA v%d.%d %d%s (%s)\n",
354vbeInfo.VESAVersion >> 8,
355vbeInfo.VESAVersion & 0xf,
356small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16),
357small ? "KB" : "MB",
358VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
359
360return buff;
361}
362
363
364void blend( const pixmap_t *blendThis, // Source image
365 pixmap_t *blendInto, // Dest image
366 const position_t position) // Where to place the source image
367{
368 uint16_t sx, sy, dx, dy;
369 uint32_t dstrb, dstag, srcrb, srcag, drb, dag, rb, ag, alpha;
370
371uint16_t width = (blendThis->width + position.x < blendInto->width) ? blendThis->width: blendInto->width-position.x;
372uint16_t height = (blendThis->height + position.y < blendInto->height) ? blendThis->height: blendInto->height-position.y;
373
374 for (dy = position.y, sy = 0; sy < height; dy++, sy++)
375{
376 for (dx = position.x, sx = 0; sx < width; dx++, sx++)
377{
378 alpha = (pixel(blendThis, sx, sy).ch.a);
379
380/* Skip blending for fully transparent pixel */
381if (alpha == 0) continue;
382
383/* For fully opaque pixel, there is no need to interpolate */
384if (alpha == 255)
385{
386pixel(blendInto, dx, dy).value = pixel(blendThis, sx, sy).value;
387continue;
388}
389
390/* For semi-transparent pixels, do a full blend */
391//alpha++
392/* This is needed to spread the alpha over [0..256] instead of [0..255]
393 Boundary conditions were handled above */
394 dstrb = pixel(blendInto, dx, dy).value & 0xFF00FF;
395 dstag = (pixel(blendInto, dx, dy).value >> 8) & 0xFF00FF;
396 srcrb = pixel(blendThis, sx, sy).value & 0xFF00FF;
397 srcag = (pixel(blendThis, sx, sy).value >> 8) & 0xFF00FF;
398 drb = srcrb - dstrb;
399 dag = srcag - dstag;
400 drb *= alpha; dag *= alpha;
401 drb >>= 8; dag >>= 8;
402 rb = (drb + dstrb) & 0x00FF00FF;
403 ag = ((dag + dstag) << 8) & 0xFF00FF00;
404 pixel(blendInto, dx, dy).value = (rb | ag);
405 }
406 }
407}
408
409position_t centeredIn( const pixmap_t *background, const pixmap_t *toCenter )
410{
411 position_t centered;
412 centered.x = ( background->width - toCenter->width ) / 2;
413 centered.y = ( background->height - toCenter->height ) / 2;
414 return centered;
415}
416
417position_t centeredAt( const pixmap_t *pixmap, const position_t center )
418{
419 position_t topleft;
420 topleft.x = center.x - (pixmap->width / 2);
421 topleft.y = center.y - (pixmap->height / 2);
422 return topleft;
423}
424
425position_t pos(const uint16_t x, const uint16_t y) { position_t p; p.x = x; p.y = y; return p; }
426
427void flipRB(pixmap_t *p)
428{
429//if(testForQemu()) return;
430
431uint32_t x;
432 register uint8_t tempB;
433for (x = 0; x < (p->height) * (p->width) ; x++) {
434tempB = (p->pixels[x]).ch.b;
435 (p->pixels[x]).ch.b = (p->pixels[x]).ch.r;
436 (p->pixels[x]).ch.r = tempB;
437}
438}
439

Archive Download this file

Revision: 735