Chameleon

Chameleon Svn Source Tree

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

Source at commit 1158 created 13 years 16 days ago.
By azimutz, Match nvidia.c with the one on my branch (Chazi) adding dev id's from issue 99 and Asus G74SX (0DF4, 1251).
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: 1158