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;
281default:
282break;
283}
284
285}
286}
287break;
288 }
289 vram += VIDEO(rowBytes);
290 data += width * 4;
291 }
292}
293
294void drawCheckerBoard()
295{
296 uint32_t *vram = (uint32_t *) VIDEO(baseAddr);
297 uint16_t x, y;
298 uint8_t color;
299
300 for (y = 0; y < VIDEO(height); y++, vram += VIDEO(width)) {
301 for (x = 0; x < VIDEO(width); x++) {
302 color = 204 + 51 * (((x / 8) % 2) == ((y / 8) % 2));
303 vram[x] = (color << 16) | (color << 8) | color;
304 }
305 }
306}
307
308void getGraphicModeParams(unsigned long params[]) {
309
310params[3] = 0;
311
312VBEModeInfoBlock minfo;
313
314 unsigned short vesaVersion;
315 unsigned short mode = modeEndOfList;
316
317getNumberArrayFromProperty( kGraphicsModeKey, params, 4);
318
319mode = getVESAModeWithProperties( params[0], params[1], params[2],
320 maColorModeBit |
321 maModeIsSupportedBit |
322 maGraphicsModeBit |
323 maLinearFrameBufferAvailBit,
324 0,
325 &minfo, &vesaVersion );
326
327params[0] = minfo.XResolution;
328params[1] = minfo.YResolution;
329params[2] = 32;
330}
331
332
333//==========================================================================
334// getVBEInfoString
335
336char *getVBEInfoString()
337{
338VBEInfoBlock vbeInfo;
339int err, small;
340char *buff = malloc(sizeof(char)*256);
341if(!buff) return 0;
342
343bzero( &vbeInfo, sizeof(vbeInfo) );
344strcpy( (char*)&vbeInfo, "VBE2" );
345err = getVBEInfo( &vbeInfo );
346if (err != errSuccess)
347return 0;
348
349if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) )
350return 0;
351
352small = (vbeInfo.TotalMemory < 16);
353
354sprintf(buff, "VESA v%d.%d %d%s (%s)\n",
355vbeInfo.VESAVersion >> 8,
356vbeInfo.VESAVersion & 0xf,
357small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16),
358small ? "KB" : "MB",
359VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
360
361return buff;
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
374for (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 < (unsigned long)(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: 1119