Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 789