1 namespace gfx::drivers;
4 #pragma warning(disable:4244)
5 #pragma warning(disable:4018)
11 public define LIGHTSHIFT = 5;
12 public define LIGHTSTEPS = 1<<LIGHTSHIFT;
14 /*#ifndef ECERE_VANILLA
16 static bool rgbLookupSet = true;
18 /*static */byte defaultRGBLookup[32768];
19 /*static */bool rgbLookupSet = false;
22 #if defined(ECERE_VANILLA)
23 #define ECERE_NOTRUETYPE
26 #if !defined(ECERE_NOTRUETYPE)
27 import "fontManagement"
28 import "fontRendering"
30 public class Font : struct { }
36 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA) && defined(__WIN32__)
37 import "OpenGLDisplayDriver"
39 #if !defined(_GLES) && !defined(ECERE_STATIC)
40 import "Direct3D8DisplayDriver"
41 import "Direct3D9DisplayDriver"
46 public class LFBDisplay : struct
50 byte rgbLookup[32768];
51 byte lightTable[256][LIGHTSTEPS];
55 void (* displayCallback)(Display display, Box updateBox);
58 public class LFBSystem : struct
63 byte rgbLookup[32768];
70 ColorAlpha * palette = GetDefaultPalette();
71 for(c = 16; c < 232; c++)
73 Color555 color = palette[c].color;
74 for(r = Max(0, color.r - 2); r <= Min(31, color.r + 4); r++)
75 for(g = Max(0, color.g - 2); g <= Min(31, color.g + 4); g++)
76 for(b = Max(0, color.b - 2); b <= Min(31, color.b + 4); b++)
77 defaultRGBLookup[r * 32 * 32 + g * 32 + b] = (byte)c;
79 for(c = 232; c < 246; c++)
81 Color555 color = palette[c].color;
82 defaultRGBLookup[color] = (byte)c;
85 for(c = 246; c < 256; c++)
87 Color555 color = palette[c].color;
88 defaultRGBLookup[color] = (byte)c;
90 for(c = 0; c < 16; c++)
92 Color555 color = palette[c].color;
93 defaultRGBLookup[color] = (byte)c;
96 for(c = 0; c<32768; c++)
98 Color color = (Color)(Color555)c;
99 defaultRGBLookup[c] = 16 + (color.r * 5 / 255) * 36 + (color.g * 5 / 255) * 6 + (color.b * 5 / 255);
100 // defaultRGBLookup[c] = (byte)BestColorMatch(palette, 0, 255, (Color)(Color555)c);
108 public class LFBSurface : struct
111 // For compatibility with 3D drivers as well
119 // Drawing attributes
120 uint foreground, background;
121 ColorAlpha foregroundRgb;
124 byte * paletteShades;
129 static int CompareHit(GLHitRecord * recordA, GLHitRecord * recordB, const void * nothing)
131 if(recordA->zMin > recordB->zMin)
133 else if(recordA->zMin < recordB->zMin)
135 else if(recordA > recordB)
137 else if(recordA < recordB)
144 public class LFBDisplayDriver : DisplayDriver
146 class_property(name) = "LFB";
148 bool CreateDisplaySystem(DisplaySystem displaySystem)
150 displaySystem.flags.memBackBuffer = true;
151 // displaySystem.pixelFormat = pixelFormat888;
155 void DestroyDisplaySystem(DisplaySystem displaySystem)
159 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
161 delete bitmap.picture;
162 if(bitmap.allocatePalette)
163 delete bitmap.palette;
166 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
171 switch(GetColorDepthShifts(format))
173 case 0: stride = (width + 3) & 0xFFFFFFFC; break;
174 case 1: stride = (width + 1) & 0xFFFFFFFE; break;
175 case 2: stride = width; break;
178 bitmap.stride = stride;
179 bitmap.width = width;
180 bitmap.height = height;
181 bitmap.size = (uint32) stride * (uint32)height;
182 bitmap.sizeBytes = bitmap.size << GetColorDepthShifts(format);
183 bitmap.pixelFormat = format;
184 bitmap.transparent = false;
186 surface.box.left = surface.box.top = 0;
187 surface.box.right = width - 1;
188 surface.box.bottom = height - 1;
190 bitmap.picture = new0 byte[bitmap.sizeBytes];
193 bitmap.allocatePalette = allocatePalette;
196 bitmap.palette = new ColorAlpha[256];
199 CopyBytesBy4(bitmap.palette, GetDefaultPalette(), 256);
205 bitmap.palette = GetDefaultPalette();
210 FreeBitmap(displaySystem, bitmap);
214 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
217 LFBSystem lfbSystem = displaySystem ? displaySystem.driverData : null;
221 if((src.pixelFormat == format) && (format != pixelFormat8 || !palette))
223 if(src.transparent && src.pixelFormat == pixelFormat888)
227 DWORD * picture = (DWORD *)src.picture;
229 for(c = 0; c<src.size; c++, picture++)
231 if(*picture & 0xFFFFFF)
232 *picture = *picture | 0xFF000000;
234 *picture = *picture & 0xFFFFFF;
243 if(bitmap.Allocate(null, src.width, src.height, 0, format, false))
245 if(format == pixelFormat8)
248 bitmap.palette = palette;
249 else if(lfbSystem && lfbSystem.palette)
250 bitmap.palette = lfbSystem.palette;
252 bitmap.palette = src.palette;
255 if(converters_table[src.pixelFormat][bitmap.pixelFormat])
257 converters_table[src.pixelFormat][bitmap.pixelFormat](lfbSystem, src, bitmap);
258 bitmap.transparent = src.transparent;
259 bitmap.alphaBlend = src.alphaBlend && format != pixelFormat8;
261 if(src.palette != bitmap.palette)
263 if(src.allocatePalette)
265 src.allocatePalette = false;
267 src.picture = bitmap.picture;
268 src.palette = bitmap.palette;
269 src.stride = bitmap.stride;
270 src.size = bitmap.size;
271 src.sizeBytes = bitmap.sizeBytes;
272 src.pixelFormat = bitmap.pixelFormat;
277 bitmap.palette = null;
278 bitmap.picture = null;
286 void DestroyDisplay(Display display)
288 LFBDisplay lfbDisplay = display.driverData;
289 delete lfbDisplay.bitmap.palette;
292 bool CreateDisplay(Display display)
295 LFBDisplay lfbDisplay = display.driverData;
298 lfbDisplay = display.driverData = LFBDisplay { };
299 lfbDisplay.selfManaged = true;
300 lfbDisplay.bitmap.pixelFormat = pixelFormatRGBA;
303 if((lfbDisplay.bitmap.palette = new ColorAlpha[256]))
305 CopyBytesBy4(lfbDisplay.bitmap.palette, GetDefaultPalette(), 256);
311 bool DisplaySize(Display display, int width, int height)
313 LFBDisplay lfbDisplay = display.driverData;
314 //display.width = width;
315 //display.height = height;
316 lfbDisplay.bitmap.width = width;
317 lfbDisplay.bitmap.height = height;
319 lfbDisplay.updateBox.left = display.width;
320 lfbDisplay.updateBox.top = display.height;
321 lfbDisplay.updateBox.right = 0;
322 lfbDisplay.updateBox.bottom = 0;
325 if(lfbDisplay.selfManaged)
327 lfbDisplay.bitmap.picture = (byte *)renew lfbDisplay.bitmap.picture int[width * height];
328 lfbDisplay.bitmap.stride = width;
330 lfbDisplay.bitmap.size = lfbDisplay.bitmap.stride * lfbDisplay.bitmap.height;
334 void DisplayPosition(Display display, int x, int y)
336 LFBDisplay lfbDisplay = display.driverData;
341 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
343 LFBDisplay lfbDisplay = display.driverData;
350 LFBSystem lfbSystem = display.displaySystem ? display.displaySystem.driverData : null;
351 palette = lfbSystem ? lfbSystem.palette : GetDefaultPalette();
352 CopyBytes(lfbDisplay.rgbLookup, defaultRGBLookup, 32768);
355 for(c = 0; c<32768; c++)
356 lfbDisplay.rgbLookup[c] = (byte)BestColorMatch(palette, 1, 255, (Color)(Color555)c);
361 for(i=0; i<LIGHTSTEPS; i++)
363 lfbDisplay.lightTable[c][i] = lfbDisplay.rgbLookup[(uint16)(Color555) Color {
364 (byte)(((uint16)palette[c].color.r * i) >> LIGHTSHIFT),
365 (byte)(((uint16)palette[c].color.g * i) >> LIGHTSHIFT),
366 (byte)(((uint16)palette[c].color.b * i) >> LIGHTSHIFT) }];
370 if(lfbDisplay.bitmap.palette)
371 CopyBytesBy4(lfbDisplay.bitmap.palette, palette ? palette : GetDefaultPalette(), 256);
374 void Update(Display display, Box updateBox)
376 LFBDisplay lfbDisplay = display.driverData;
377 if(lfbDisplay.displayCallback)
379 if(updateBox == null)
381 Box box { 0,0, display.width,display.height };
382 lfbDisplay.displayCallback(display, box);
385 lfbDisplay.displayCallback(display, updateBox);
389 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
391 if(bitmap.pixelFormat != pixelFormatAlpha)
393 if(!ConvertBitmap(displaySystem, bitmap, /*bitmap.alphaBlend ? pixelFormat888 : */displaySystem.pixelFormat, null))
395 FreeBitmap(displaySystem, bitmap);
402 void ReleaseSurface(Display display, Surface surface)
404 LFBSurface lfbSurface = surface.driverData;
406 surface.driverData = null;
409 bool GetSurface(Display display, Surface surface, int x, int y, Box clip)
411 LFBDisplay lfbDisplay = display.driverData;
412 LFBSurface lfbSurface = surface.driverData;
415 lfbSurface = surface.driverData = LFBSurface { };
418 lfbSurface.bitmap = lfbDisplay.bitmap;
420 surface.offset.x = x;
421 surface.offset.y = y;
423 if(lfbDisplay.bitmap.pixelFormat == pixelFormatText)
425 surface.offset.x /= textCellW;
426 surface.offset.y /= textCellH;
427 surface.box.left /= textCellW;
428 surface.box.top /= textCellH;
429 surface.box.right /= textCellW;
430 surface.box.bottom /= textCellH;
434 lfbDisplay.updateBox.left = Min(x + clip.left, lfbDisplay.updateBox.left);
435 lfbDisplay.updateBox.top = Min(y + clip.top, lfbDisplay.updateBox.top);
436 lfbDisplay.updateBox.right = Max(x + clip.right, lfbDisplay.updateBox.right);
437 lfbDisplay.updateBox.bottom = Max(y + clip.bottom, lfbDisplay.updateBox.bottom);
440 surface.unclippedBox = surface.box;
441 lfbSurface.drawingChar = 219;
445 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x,int y, Box clip)
448 LFBSurface lfbSurface = surface.driverData;
449 if(lfbSurface || (surface.driverData = lfbSurface = LFBSurface { }))
451 lfbSurface.bitmap = bitmap;
453 surface.offset.x = x;
454 surface.offset.y = y;
456 if(bitmap.pixelFormat == pixelFormatText)
458 surface.offset.x /= textCellW;
459 surface.offset.y /= textCellH;
460 surface.box.left /= textCellW;
461 surface.box.top /= textCellH;
462 surface.box.right /= textCellW;
463 surface.box.bottom /= textCellH;
466 surface.unclippedBox = *&surface.box;
467 lfbSurface.drawingChar = 219;
474 void Clip(Display display, Surface surface, Box clip)
476 LFBSurface lfbSurface = surface.driverData;
481 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
483 box.left /= textCellW;
484 box.top /= textCellH;
485 box.right /= textCellW;
486 box.bottom /= textCellH;
488 box.Clip(surface.unclippedBox);
492 surface.box = surface.unclippedBox;
495 void SetForeground(Display display, Surface surface, ColorAlpha color)
497 LFBDisplay lfbDisplay = display ? display.driverData : null;
498 LFBSurface lfbSurface = surface.driverData;
500 //if(display) color = color & 0xFFFFFF;
501 lfbSurface.foregroundRgb = color;
503 if(lfbSurface.font && lfbDisplay)
505 index = lfbDisplay.rgbLookup[(uint16)(Color555)lfbSurface.foregroundRgb];
506 lfbSurface.paletteShades = lfbDisplay.lightTable[index];
509 switch(lfbSurface.bitmap.pixelFormat)
513 lfbSurface.foreground = lfbDisplay.rgbLookup[(uint16)(Color555)color];
515 lfbSurface.foreground = BestColorMatch(lfbSurface.bitmap.palette,0,255,color);
517 case pixelFormat444: lfbSurface.foreground = (Color444)color; break;
518 case pixelFormat555: lfbSurface.foreground = (Color555)color; break;
519 case pixelFormat565: lfbSurface.foreground = (Color565)color; break;
520 case pixelFormat888: lfbSurface.foreground = color; break;
521 case pixelFormatRGBA: lfbSurface.foreground = (ColorRGBA)color; break;
522 case pixelFormatText:
524 lfbSurface.foreground = BestColorMatch(lfbDisplay.bitmap.palette,0,15,color) << 8;
526 lfbSurface.foreground = BestColorMatch(lfbSurface.bitmap.palette,0,15,color) << 8;
531 void SetBackground(Display display, Surface surface, ColorAlpha color)
533 LFBDisplay lfbDisplay = display ? display.driverData : null;
534 LFBSurface lfbSurface = surface.driverData;
535 //color = color & 0xFFFFFF;
536 switch(lfbSurface.bitmap.pixelFormat)
540 lfbSurface.background = lfbDisplay.rgbLookup[(uint16)(Color555)color];
542 lfbSurface.background = BestColorMatch(lfbSurface.bitmap.palette,0,255,color);
544 case pixelFormat444: lfbSurface.background = (Color444)color; break;
545 case pixelFormat555: lfbSurface.background = (Color555)color; break;
546 case pixelFormat565: lfbSurface.background = (Color565)color; break;
547 case pixelFormat888: lfbSurface.background = color; break;
548 case pixelFormatRGBA: lfbSurface.background = (ColorRGBA)color; break;
549 case pixelFormatText:
551 lfbSurface.background = BestColorMatch(lfbDisplay.bitmap.palette,0,15,color) << 12;
553 lfbSurface.background = BestColorMatch(lfbSurface.bitmap.palette,0,15,color) << 12;
558 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
560 LFBSurface lfbSurface = surface.driverData;
561 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
566 if((x <= surface.box.right) && (y <= surface.box.bottom) && (x >= surface.box.left) && (y >= surface.box.top))
568 x += surface.offset.x;
569 y += surface.offset.y;
570 if(lfbSurface.bitmap.picture)
572 switch(lfbSurface.bitmap.pixelFormat)
574 case pixelFormatText:
576 if(!lfbSurface.bitmap.palette) return 0;
577 return lfbSurface.bitmap.palette[((byte *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x]];
578 case pixelFormat444: return ((Color444 *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x];
579 case pixelFormat555: return ((Color555 *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x];
580 case pixelFormat565: return ((Color565 *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x];
581 case pixelFormat888: return ((ColorAlpha *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride+x];
588 void PutPixel(Display display, Surface surface,int x,int y)
590 LFBSurface lfbSurface = surface.driverData;
591 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
596 if((x <= surface.box.right) && (y <= surface.box.bottom) && (x >= surface.box.left) && (y >= surface.box.top))
598 x += surface.offset.x;
599 y += surface.offset.y;
600 if(lfbSurface.bitmap.picture)
602 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
605 ((byte *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x] = (byte)lfbSurface.foreground;
608 ((uint16 *)lfbSurface.bitmap.picture)[(uint)y * lfbSurface.bitmap.stride + x] = (uint16)lfbSurface.foreground;
611 if(((uint32 *)lfbSurface.bitmap.picture)[(uint32) y * lfbSurface.bitmap.stride + x] != (uint32)lfbSurface.foreground)
612 ((uint32 *)lfbSurface.bitmap.picture)[(uint32) y * lfbSurface.bitmap.stride + x] = (uint32)lfbSurface.foreground;
619 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
621 LFBSurface lfbSurface = surface.driverData;
627 uint color = lfbSurface.foreground;
628 uint16 stipple = lfbSurface.stipple ? lfbSurface.stipple : 0xFFFF;
630 if(!lfbSurface.bitmap.picture) return;
631 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
637 if(surface.textOpacity)
638 color |= lfbSurface.background;
639 color |= lfbSurface.drawingChar;
643 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; invert = true; }
645 if((y1>surface.box.bottom)||(y1<surface.box.top))return;
646 if((x1>surface.box.right)||(x2<surface.box.left))return;
647 if(x1<surface.box.left)x1=surface.box.left;
648 if(x2>surface.box.right)x2=surface.box.right;
652 offset=(y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
653 if(stipple != 0xFFFF)
656 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
659 for(x=x1; x<=x2; x++, offset++)
662 ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color;
664 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
666 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
670 for(x=x1; x<=x2; x++, offset++)
673 ((uint16 *)lfbSurface.bitmap.picture)[offset] = (uint16)color;
675 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
677 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
681 for(x=x1; x<=x2; x++, offset++)
684 ((uint32 *)lfbSurface.bitmap.picture)[offset] = color;
686 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
688 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
695 if(lfbSurface.bitmap.pixelFormat != pixelFormatText || surface.textOpacity)
697 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
699 case 0: FillBytes(((byte *)lfbSurface.bitmap.picture)+offset,(byte)color,x2-x1+1); break;
700 case 1: FillBytesBy2(((uint16 *)lfbSurface.bitmap.picture)+offset,(uint16)color,x2-x1+1); break;
701 case 2: FillBytesBy4(((uint32 *)lfbSurface.bitmap.picture)+offset,color,x2-x1+1); break;
707 for(x = x1; x <= x2; x++, offset++)
709 ((uint16 *)lfbSurface.bitmap.picture)[offset] =
710 (((uint16 *)lfbSurface.bitmap.picture)[offset] & 0xF000) | (uint16)color;
719 if(y1>y2) { int tmp = y2; y2 = y1; y1 = tmp; invert = true; }
721 if((x1>surface.box.right)||(x1<surface.box.left))return;
722 if((y1>surface.box.bottom)||(y2<surface.box.top))return;
723 if(y1<surface.box.top)y1=surface.box.top;
724 if(y2>surface.box.bottom)y2=surface.box.bottom;
726 offset=(y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
727 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
730 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
733 ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color;
735 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
737 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
741 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
745 if(lfbSurface.bitmap.pixelFormat != pixelFormatText || surface.textOpacity)
746 ((uint16 *)lfbSurface.bitmap.picture)[offset]=(uint16)color;
749 ((uint16 *)lfbSurface.bitmap.picture)[offset] =
750 (((uint16 *)lfbSurface.bitmap.picture)[offset] & 0xF000) | (uint16)color;
754 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
756 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
760 if(stipple != 0xFFFF)
762 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
765 ((uint32*)lfbSurface.bitmap.picture)[offset]=color;
767 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
769 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
774 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
775 ((uint32*)lfbSurface.bitmap.picture)[offset]=color;
784 if(x1 < surface.box.left)
786 if(x2 < surface.box.left)
788 y1 += (y2 - y1) * (surface.box.left - x1) / (x2 - x1);
789 x1 = surface.box.left;
791 if(x2 > surface.box.right)
793 if(x1 > surface.box.right)
795 y2 -= (y2 - y1) * (x2 - surface.box.right) / (x2 - x1);
796 x2 = surface.box.right;
800 if(y1 < surface.box.top)
802 if(y2 < surface.box.top)
804 x1 += (x2 - x1) * (surface.box.top - y1) / (y2 - y1);
805 y1 = surface.box.top;
807 if(y2 > surface.box.bottom)
809 if(y1 > surface.box.bottom)
811 x2 -= (x2 - x1) * (y2 - surface.box.bottom) / (y2 - y1);
812 y2 = surface.box.bottom;
817 if(y1 > surface.box.bottom)
819 if(y2 > surface.box.bottom)
821 x1 -= (x1 - x2) * (y1 - surface.box.bottom) / (y1 - y2);
822 y1 = surface.box.bottom;
824 if(y2 < surface.box.top)
826 if(y1 < surface.box.top)
828 x2 += (x1 - x2) * (surface.box.top - y2) / (y1 - y2);
829 y2 = surface.box.top;
835 if(x1 > surface.box.right)
837 if(x2 > surface.box.right)
839 y1 -= (y1 - y2) * (x1 - surface.box.right) / (x1 - x2);
840 x1 = surface.box.right;
842 if(x2 < surface.box.left)
844 if(x1 < surface.box.left)
846 y2 += (y1 - y2) * (surface.box.left - x2) / (x1 - x2);
847 x2 = surface.box.left;
851 if(y1 < surface.box.top)
853 if(y2 < surface.box.top)
855 x1 += (x2 - x1) * (surface.box.top - y1) / (y2 - y1);
856 y1 = surface.box.top;
858 if(y2 > surface.box.bottom)
860 if(y1 > surface.box.bottom)
862 x2 -= (x2 - x1) * (y2 - surface.box.bottom) / (y2 - y1);
863 y2 = surface.box.bottom;
868 if(y1 > surface.box.bottom)
870 if(y2 > surface.box.bottom)
872 x1 -= (x1 - x2) * (y1 - surface.box.bottom) / (y1 - y2);
873 y1 = surface.box.bottom;
875 if(y2 < surface.box.top)
877 if(y1 < surface.box.top)
879 x2 += (x1 - x2) * (surface.box.top - y2) / (y1 - y2);
880 y2 = surface.box.top;
898 yu=-(int)lfbSurface.bitmap.stride;
901 yu=lfbSurface.bitmap.stride;
903 offset=(y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
909 for(i=0; i<=length; i++)
912 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
914 case 0: ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color; break;
915 case 1: ((uint16 *)lfbSurface.bitmap.picture)[offset]=(uint16)color; break;
916 case 2: ((uint32*)lfbSurface.bitmap.picture)[offset]=(uint32)color; break;
925 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
931 for(i=0; i<=length; i++)
934 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
936 case 0: ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color; break;
937 case 1: ((uint16 *)lfbSurface.bitmap.picture)[offset]=(uint16)color; break;
938 case 2: ((uint32*)lfbSurface.bitmap.picture)[offset]=(uint32)color; break;
952 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
954 DrawLine(display, surface,x1,y1,x2,y1);
955 DrawLine(display, surface,x2,y1,x2,y2);
956 DrawLine(display, surface,x2,y2,x1,y2);
957 DrawLine(display, surface,x1,y2,x1,y1);
960 #if !defined(__GNUC__)
962 void memset_32_aligned(void *buf, int val, int dwords)
967 *((uint32 *)(buf)) = val;
968 buf = ((uint32 *)(buf))+1;
994 if (dwords & 1) *((int*)(buf)) = val;
1000 void memset_32_aligned(uint32 *buf, uint32 val, uint32 dwords)
1004 if(((uint32)buf) & 0x7F)
1006 for( ; ((uint32)buf) & 0x7F && dwords; buf++)
1032 sub edx,ebx ; edx holds # of overflow bytes
1051 movdqa [edi+16],xmm0
1052 movdqa [edi+32],xmm0
1053 movdqa [edi+48],xmm0
1054 movdqa [edi+64],xmm0
1055 movdqa [edi+80],xmm0
1056 movdqa [edi+96],xmm0
1057 movdqa [edi+112],xmm0
1081 void memset_32(void *buf, uint32 val, uint32 dwords)
1084 if ((uint32)(buf) & 3)
1089 if (((uint32)(buf) & 1))
1091 *(byte *)(buf) = (byte)(val&0xFF);
1092 buf = ((byte *)(buf))+1;
1093 val = ((val& 0xFF) << 24) || ((val& 0xFFFFFF00) >> 8);
1096 if (((uint32)(buf) & 2))
1098 *(uint16 *)(buf) = (uint16)(val&0xFFFF);
1099 buf = ((uint16 *)(buf))+1;
1100 val = ((val& 0xFFFF) << 16) || ((val& 0xFFFF0000) >> 16);
1104 memset_32_aligned(buf,val,dwords);
1109 *(byte *)(buf) = (byte)(val&0xFF);
1113 *(uint16 *)(buf) = (uint16)(val&0xFFFF);
1114 if (align & 1) *((byte *)(buf)+2) = (byte)((val>>16)&0xFF);
1121 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
1123 LFBSurface lfbSurface = surface.driverData;
1124 uint32 color = lfbSurface.background;
1126 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
1128 color |= lfbSurface.foreground | lfbSurface.drawingChar;
1134 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
1136 if(x1<surface.box.left) x1=surface.box.left;
1137 if(x2>surface.box.right) x2=surface.box.right;
1138 if(y1<surface.box.top) y1=surface.box.top;
1139 if(y2>surface.box.bottom) y2=surface.box.bottom;
1141 if(x2>=x1 && y2>=y1)
1149 x1 += surface.offset.x;
1150 x2 += surface.offset.x;
1151 y1 += surface.offset.y;
1152 y2 += surface.offset.y;
1153 if(lfbSurface.bitmap.picture)
1155 if(!surface.writeColor)
1157 ColorAlpha * picture = (((ColorAlpha *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1158 for(y = y1; y<= y2; y++)
1161 for(c = 0; c < w; c++, picture++)
1163 picture->a = (byte)((color & 0xFF000000) >> 24);
1164 picture += lfbSurface.bitmap.stride - w;
1169 if(!surface.blend || surface.background.a == 255 || lfbSurface.clearing)
1171 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
1174 theOffset = ((byte *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1;
1175 for(y = y1; y<= y2; y++)
1177 FillBytes(theOffset,(byte)color,w);
1178 theOffset += lfbSurface.bitmap.stride;
1182 theOffset = (byte *) (((uint16 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1183 for(y = y1; y<= y2; y++)
1185 FillBytesBy2((uint16 *) theOffset,(uint16)color,w);
1186 theOffset += lfbSurface.bitmap.stride * sizeof(uint16);
1190 theOffset = (byte *) (((uint32 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1191 for(y = y1; y<= y2; y++)
1193 #if defined(__GNUC__)
1194 FillBytesBy4((uint32 *) theOffset,color,w);
1196 memset_32((uint32 *) theOffset,color,w);
1198 theOffset += lfbSurface.bitmap.stride * sizeof(uint32);
1204 int bla = (lfbSurface.bitmap.stride - w) * sizeof(uint32);
1205 //memset_32((uint32 *) theOffset,color,w);
1241 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
1244 theOffset = ((byte *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1;
1245 for(y = y1; y<= y2; y++)
1247 // TODO: IMPLEMENT THIS
1248 FillBytes(theOffset,(byte)color,w);
1249 theOffset += lfbSurface.bitmap.stride;
1254 uint16 * dest = (((uint16 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1255 ColorAlpha c = surface.background;
1260 PixelFormat pixelFormat = lfbSurface.bitmap.pixelFormat;
1262 for(y = y1; y <= y2; y++)
1265 for(c = 0; c < w; c++, dest++)
1267 Color destColor = 0;
1268 if(pixelFormat == pixelFormat565) { destColor = (Color)*(Color565 *)dest; }
1269 else if(pixelFormat == pixelFormat555) { destColor = (Color)*(Color555 *)dest; }
1270 else if(pixelFormat == pixelFormat444) { destColor = (Color)*(Color444 *)dest; }
1272 int r = a * cr / 255 + ((255 - a) * destColor.r / 255);
1273 int g = a * cg / 255 + ((255 - a) * destColor.g / 255);
1274 int b = a * cb / 255 + ((255 - a) * destColor.b / 255);
1276 if(r > 255) r = 255;
1277 if(g > 255) g = 255;
1278 if(b > 255) b = 255;
1280 destColor = { (byte)r, (byte)g, (byte)b };
1282 if(pixelFormat == pixelFormat565) { *dest = (Color565)destColor; }
1283 else if(pixelFormat == pixelFormat555) { *dest = (Color555)destColor; }
1284 else if(pixelFormat == pixelFormat444) { *dest = (Color444)destColor; }
1287 dest += (lfbSurface.bitmap.stride - w);
1293 ColorAlpha * dest = (ColorAlpha *)(((uint32 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1294 AlphaWriteMode alphaWrite = surface.alphaWrite;
1295 ColorAlpha c = surface.background;
1300 for(y = y1; y <= y2; y++)
1303 for(c = 0; c < w; c++, dest++)
1305 int dr = dest->color.r;
1306 int dg = dest->color.g;
1307 int db = dest->color.b;
1308 int r = a * cr / 255 + ((255 - a) * dr / 255);
1309 int g = a * cg / 255 + ((255 - a) * dg / 255);
1310 int b = a * cb / 255 + ((255 - a) * db / 255);
1312 if(r > 255) r = 255;
1313 if(g > 255) g = 255;
1314 if(b > 255) b = 255;
1315 dest->color = { (byte)r, (byte)g, (byte)b };
1317 if(alphaWrite == blend)
1319 int ca = (int)(a + ((255 - a) * dest->a / 255));
1320 if(ca > 255) ca = 255;
1326 dest += (lfbSurface.bitmap.stride - w);
1335 void Clear(Display display, Surface surface, ClearType type)
1337 LFBSurface lfbSurface = surface.driverData;
1339 lfbSurface.clearing = true;
1340 if(surface.offset.x == 0 && surface.offset.y == 0 &&
1341 surface.box.left == 0 && surface.box.top == 0 &&
1342 surface.box.right == surface.width-1 &&
1343 surface.box.bottom == surface.height-1)
1345 uint32 color = /*0xFF000000 | */lfbSurface.background;
1346 if(type != depthBuffer)
1348 if(lfbSurface.bitmap.stride != surface.width)
1349 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);
1352 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
1355 FillBytes(lfbSurface.bitmap.picture, (byte)color, lfbSurface.bitmap.size);
1357 case 1: FillBytesBy2((uint16 *)lfbSurface.bitmap.picture, (uint16)color, lfbSurface.bitmap.size); break;
1358 case 2: FillBytesBy4((uint32 *)lfbSurface.bitmap.picture, color, lfbSurface.bitmap.size); break;
1363 if((flags & CLEAR_Z) && zbuffer)
1364 FillBytesBy4((DWORD *)zbuffer,0,(sizeof(float)*(DWORD)display.width * display.Height)>>2);
1369 if(type != depthBuffer)
1370 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);
1372 if((flags & CLEAR_Z))
1375 uint32 w = surface.box.right-surface.box.left+1;
1376 float * offset = zbuffer + ((surface.box.top +surface.offset.y) * (DWORD)DISPLAY.Width)
1377 + surface.box.left+surface.offset.x;
1378 for(y = surface.box.top; y<= surface.box.bottom; y++)
1380 FillBytesBy4((uint32 *) offset,0,(sizeof(float)>>2)*w);
1381 offset += DISPLAY.Width;
1386 lfbSurface.clearing = false;
1389 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1391 LFBSurface lfbSurface = surface.driverData;
1394 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return;
1396 if(w < 0) { w = -w; flip = true; }
1398 //Clip against the edges of the source
1411 if(sx+w>src.width-1)
1412 w-=sx+w-(src.width-1)-1;
1413 if(sy+h>src.height-1)
1414 h-=sy+h-(src.height-1)-1;
1415 //Clip against the edges of the destination
1416 if(dx<surface.box.left)
1418 if(!flip) sx+=surface.box.left-dx;
1419 w-=surface.box.left-dx;
1420 dx=surface.box.left;
1422 if(dy<surface.box.top)
1424 sy+=surface.box.top-dy;
1425 h-=surface.box.top-dy;
1428 if((dx+w)>surface.box.right)
1430 if(flip) sx+=(uint32)(dx+w)-surface.box.right-1;
1431 w-=((uint32)(dx+w)-surface.box.right-1);
1433 if((dy+h)>surface.box.bottom)
1434 h-=((dy+h)-surface.box.bottom-1);
1438 dx += surface.offset.x;
1439 dy += surface.offset.y;
1441 if(lfbSurface.bitmap.picture)
1443 AlphaWriteMode alphaWrite = surface.alphaWrite;
1444 if(src.alphaBlend && surface.blend)
1447 if(src.pixelFormat == pixelFormatAlpha)
1449 if(lfbSurface.bitmap.pixelFormat == pixelFormat888)
1451 ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1452 byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
1453 ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
1454 for(y = 0; y < h; y++)
1456 for(x = 0; x < w; x++, picture++, source++)
1458 int a = *source * color.a;
1459 ColorAlpha dest = *picture;
1460 int r = (a * color.color.r + ((255 * 255 - a) * dest.color.r)) / (255 * 255);
1461 int g = (a * color.color.g + ((255 * 255 - a) * dest.color.g)) / (255 * 255);
1462 int b = (a * color.color.b + ((255 * 255 - a) * dest.color.b)) / (255 * 255);
1463 if(r > 255) r = 255;
1464 if(g > 255) g = 255;
1465 if(b > 255) b = 255;
1466 picture->color = { (byte)r, (byte)g, (byte)b };
1467 if(alphaWrite == blend)
1469 int ca = (a * 255 + (255 * 255 - a) * dest.a) / (255 * 255);
1470 if(ca > 255) ca = 255;
1471 picture->a = (byte)ca;
1474 picture->a = (byte)(a / 255);
1476 picture += lfbSurface.bitmap.stride - w;
1477 source += src.stride - w;
1480 else if(lfbSurface.bitmap.pixelFormat == pixelFormat555)
1482 Color555 * picture = ((Color555 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1483 byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
1484 ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
1485 for(y = 0; y < h; y++)
1487 for(x = 0; x < w; x++, picture++, source++)
1489 int a = *source * color.a;
1490 Color dest = *picture;
1491 int r = (a * color.color.r + ((255 * 255 - a) * dest.r)) / (255 * 255);
1492 int g = (a * color.color.g + ((255 * 255 - a) * dest.g)) / (255 * 255);
1493 int b = (a * color.color.b + ((255 * 255 - a) * dest.b)) / (255 * 255);
1494 if(r > 255) r = 255;
1495 if(g > 255) g = 255;
1496 if(b > 255) b = 255;
1497 *picture = Color { (byte)r, (byte)g, (byte)b };
1499 picture += lfbSurface.bitmap.stride - w;
1500 source += src.stride - w;
1503 else if(lfbSurface.bitmap.pixelFormat == pixelFormat565)
1505 Color565 * picture = ((Color565 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1506 byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
1507 ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
1508 for(y = 0; y < h; y++)
1510 for(x = 0; x < w; x++, picture++, source++)
1512 int a = *source * color.a;
1513 Color dest = *picture;
1514 int r = (a * color.color.r + ((255 * 255 - a) * dest.r)) / (255 * 255);
1515 int g = (a * color.color.g + ((255 * 255 - a) * dest.g)) / (255 * 255);
1516 int b = (a * color.color.b + ((255 * 255 - a) * dest.b)) / (255 * 255);
1517 if(r > 255) r = 255;
1518 if(g > 255) g = 255;
1519 if(b > 255) b = 255;
1520 *picture = Color { (byte)r, (byte)g, (byte)b };
1522 picture += lfbSurface.bitmap.stride - w;
1523 source += src.stride - w;
1529 ColorAlpha * source = ((ColorAlpha *)src.picture) + (src.stride * sy) + sx;
1530 if(lfbSurface.bitmap.pixelFormat == pixelFormat888)
1532 ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1533 for(y = 0; y < h; y++)
1535 for(x = 0; x < w; x++, picture++, source++)
1537 ColorAlpha src = *source;
1538 ColorAlpha dest = *picture;
1539 int r = src.a * src.color.r / 255 + ((255 - src.a) * dest.color.r / 255);
1540 int g = src.a * src.color.g / 255 + ((255 - src.a) * dest.color.g / 255);
1541 int b = src.a * src.color.b / 255 + ((255 - src.a) * dest.color.b / 255);
1542 if(r > 255) r = 255;
1543 if(g > 255) g = 255;
1544 if(b > 255) b = 255;
1545 picture->color = { (byte)r, (byte)g, (byte)b };
1546 if(alphaWrite == blend)
1548 int a = src.a + ((255 - src.a) * dest.a / 255);
1549 if(a > 255) a = 255;
1550 picture->a = (byte)a;
1555 picture += lfbSurface.bitmap.stride - w;
1556 source += src.stride - w;
1559 else if(lfbSurface.bitmap.pixelFormat == pixelFormat565)
1561 Color565 * picture = ((Color565 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1562 for(y = 0; y < h; y++)
1564 for(x = 0; x < w; x++, picture++, source++)
1566 ColorAlpha src = *source;
1567 Color565 dest = *picture;
1568 int r = src.a * src.color.r * 31 / 255 + ((255 - src.a) * dest.r);
1569 int g = src.a * src.color.g * 63 / 255 + ((255 - src.a) * dest.g);
1570 int b = src.a * src.color.b * 31 / 255 + ((255 - src.a) * dest.b);
1571 if(r > 255 * 31) r = 255 * 31;
1572 if(g > 255 * 63) g = 255 * 63;
1573 if(b > 255 * 31) b = 255 * 31;
1574 *picture = { (byte)(r / 255), (byte)(g / 255), (byte)(b / 255) };
1576 picture += lfbSurface.bitmap.stride - w;
1577 source += src.stride - w;
1580 else if(lfbSurface.bitmap.pixelFormat == pixelFormat555)
1582 Color555 * picture = ((Color555 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1583 for(y = 0; y < h; y++)
1585 for(x = 0; x < w; x++, picture++, source++)
1587 ColorAlpha psrc = *source;
1588 Color555 dest = *picture;
1589 int r = psrc.a * psrc.color.r * 31 / 255 + ((255 - psrc.a) * dest.r);
1590 int g = psrc.a * psrc.color.g * 31 / 255 + ((255 - psrc.a) * dest.g);
1591 int b = psrc.a * psrc.color.b * 31 / 255 + ((255 - psrc.a) * dest.b);
1592 if(r > 255 * 31) r = 255 * 31;
1593 if(g > 255 * 31) g = 255 * 31;
1594 if(b > 255 * 31) b = 255 * 31;
1595 *picture = { (byte)(r / 255), (byte)(g / 255), (byte)(b / 255) };
1597 picture += lfbSurface.bitmap.stride - w;
1598 source += src.stride - w;
1603 else if(src.paletteShades)
1604 shades_blit_table[lfbSurface.bitmap.pixelFormat][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h);
1605 else if(src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1606 blits_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h);
1607 else if(src.pixelFormat == pixelFormat8)
1608 blits_8bit_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h);
1612 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
1614 bool result = false;
1615 LFBDisplay lfbDisplay = display.driverData;
1617 if(bitmap.pixelFormat != lfbDisplay.bitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
1620 bitmap.Allocate(null, w,h,w, lfbDisplay.bitmap.pixelFormat,
1621 (lfbDisplay.bitmap.pixelFormat == pixelFormat8)?true:false);
1625 Surface surface = bitmap.GetSurface(0,0,null);
1628 Blit(display, surface, lfbDisplay.bitmap, 0,0,x,y,w,h);
1629 if(bitmap.palette && lfbDisplay.bitmap.pixelFormat == pixelFormat8 && lfbDisplay.bitmap.palette)
1630 CopyBytesBy4(bitmap.palette, lfbDisplay.bitmap.palette, 256);
1638 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1640 LFBSurface lfbSurface = surface.driverData;
1643 float s2dw,s2dh,d2sw,d2sh;
1645 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return;
1647 if(Sgn(w) != Sgn(sw))
1659 //Clip against the edges of the source
1662 dx+=(int)((0-sx) * s2dw);
1663 w-=(int)((0-sx) * s2dw);
1669 dy+=(int)((0-sy) * s2dh);
1670 h-=(int)((0-sy) * s2dh);
1675 if(sx+sw>src.width-1)
1677 w-=(int)((sx+sw-(src.width-1)-1)*s2dw);
1678 sw-=sx+sw-(src.width-1)-1;
1680 if(sy+sh>(src.height-1))
1682 h-=(int)((sy+sh-(src.height-1)-1)*s2dh);
1683 sh-=sy+sh-(src.height-1)-1;
1685 //Clip against the edges of the destination
1686 if(dx<surface.box.left)
1688 if(!flip) sx+=(int)((surface.box.left-dx)*d2sw);
1689 sw-=(int)((surface.box.left-dx)*d2sw);
1690 w-=surface.box.left-dx;
1691 dx=surface.box.left;
1693 if(dy<surface.box.top)
1695 sy+=(int)((surface.box.top-dy)*d2sh);
1696 sh-=(int)((surface.box.top-dy)*d2sh);
1697 h-=surface.box.top-dy;
1700 if((dx+w)>surface.box.right)
1702 if(flip) sx+=(int)(((dx+w)-surface.box.right-1)*d2sw);
1703 sw-=(int)(((dx+w)-surface.box.right-1)*d2sw);
1704 w-=((dx+w)-surface.box.right-1);
1706 if((dy+h)>surface.box.bottom)
1708 sh-=(int)(((dy+h)-surface.box.bottom-1)*d2sh);
1709 h-=((dy+h)-surface.box.bottom-1);
1711 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
1713 dx+=surface.offset.x;
1714 dy+=surface.offset.y;
1716 if(lfbSurface.bitmap.picture)
1718 AlphaWriteMode alphaWrite = surface.alphaWrite;
1719 if(src.alphaBlend && surface.blend)
1723 uint adddest = lfbSurface.bitmap.stride, addsource = src.stride;
1724 ColorAlpha * backsrc;
1725 ColorAlpha * source = ((ColorAlpha *) src.picture) + sy * addsource + sx;
1726 ColorAlpha * dest = ((ColorAlpha *) lfbSurface.bitmap.picture) + dy * adddest + dx;
1727 if(flip) source += sw-1;
1745 ColorAlpha src = *source;
1746 ColorAlpha dst = *dest;
1747 int r = src.a * src.color.r / 255 + ((255 - src.a) * dst.color.r / 255);
1748 int g = src.a * src.color.g / 255 + ((255 - src.a) * dst.color.g / 255);
1749 int b = src.a * src.color.b / 255 + ((255 - src.a) * dst.color.b / 255);
1750 if(r > 255) r = 255;
1751 if(g > 255) g = 255;
1752 if(b > 255) b = 255;
1753 dest->color = { (byte)r, (byte)g, (byte)b };
1754 if(alphaWrite == blend)
1756 int a = src.a + ((255 - src.a) * dst.a / 255);
1757 if(a > 255) a = 255;
1770 source += addsource;
1773 else if(src.paletteShades)
1774 shades_stretch_table[lfbSurface.bitmap.pixelFormat][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1775 else if(src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1776 stretches_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1777 else if(src.pixelFormat == pixelFormat8 && lfbSurface.bitmap.pixelFormat != pixelFormatText)
1778 stretches_8bit_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1782 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1784 LFBSurface lfbSurface = surface.driverData;
1787 float s2dw,s2dh,d2sw,d2sh;
1789 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return;
1791 if(Sgn(w) != Sgn(sw))
1803 //Clip against the edges of the source
1806 dx+=(int)((0-sx) * s2dw);
1807 w-=(int)((0-sx) * s2dw);
1813 dy+=(int)((0-sy) * s2dh);
1814 h-=(int)((0-sy) * s2dh);
1819 if(sx+sw>src.width-1)
1821 w-=(int)((sx+sw-(src.width-1)-1)*s2dw);
1822 sw-=sx+sw-(src.width-1)-1;
1824 if(sy+sh>(src.height-1))
1826 h-=(int)((sy+sh-(src.height-1)-1)*s2dh);
1827 sh-=sy+sh-(src.height-1)-1;
1829 //Clip against the edges of the destination
1830 if(dx<surface.box.left)
1832 if(!flip) sx+=(int)((surface.box.left-dx)*d2sw);
1833 sw-=(int)((surface.box.left-dx)*d2sw);
1834 w-=surface.box.left-dx;
1835 dx=surface.box.left;
1837 if(dy<surface.box.top)
1839 sy+=(int)((surface.box.top-dy)*d2sh);
1840 sh-=(int)((surface.box.top-dy)*d2sh);
1841 h-=surface.box.top-dy;
1844 if((dx+w)>surface.box.right)
1846 if(flip) sx+=(int)(((dx+w)-surface.box.right-1)*d2sw);
1847 sw-=(int)(((dx+w)-surface.box.right-1)*d2sw);
1848 w-=((dx+w)-surface.box.right-1);
1850 if((dy+h)>surface.box.bottom)
1852 sh-=(int)(((dy+h)-surface.box.bottom-1)*d2sh);
1853 h-=((dy+h)-surface.box.bottom-1);
1855 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
1857 dx+=surface.offset.x;
1858 dy+=surface.offset.y;
1860 if(lfbSurface.bitmap.picture)
1862 AlphaWriteMode alphaWrite = surface.alphaWrite;
1863 if(src.alphaBlend && surface.blend)
1865 uint adddest = lfbSurface.bitmap.stride, addsource = src.stride;
1866 ColorAlpha * source = ((ColorAlpha *) src.picture) + sy * addsource + sx;
1867 ColorAlpha * dest = ((ColorAlpha *) lfbSurface.bitmap.picture) + dy * adddest + dx;
1868 float scaleX = (float)sw / w;
1869 float scaleY = (float)sh / h;
1877 if (w > sw && h > sh)
1880 for (y = 0; y < h; y++)
1882 int y0 = y * sh / h;
1883 int y1 = Min(y0 + 1, sh - 1);
1884 float alpha = y * scaleY - y0;
1886 for(x = 0; x < w; x++, dest += 1)
1888 int x0 = x * sw / w;
1889 int x1 = Min(x0 + 1, sw - 1);
1890 float beta = x * scaleX - x0;
1891 ColorAlpha src00, src01, src10, src11;
1892 float a1,r1,g1,b1,a2,r2,g2,b2;
1894 src00 = source[y0 * src.stride + x0];
1895 src01 = source[y0 * src.stride + x1];
1896 src10 = source[y1 * src.stride + x0];
1897 src11 = source[y1 * src.stride + x1];
1898 a1 = (src00.a) * (1.0f - beta) + (src01.a) * beta;
1899 r1 = (src00.color.r) * (1.0f - beta) + (src01.color.r) * beta;
1900 g1 = (src00.color.g) * (1.0f - beta) + (src01.color.g) * beta;
1901 b1 = (src00.color.b) * (1.0f - beta) + (src01.color.b) * beta;
1902 a2 = (src10.a) * (1.0f - beta) + (src11.a) * beta;
1903 r2 = (src10.color.r) * (1.0f - beta) + (src11.color.r) * beta;
1904 g2 = (src10.color.g) * (1.0f - beta) + (src11.color.g) * beta;
1905 b2 = (src10.color.b) * (1.0f - beta) + (src11.color.b) * beta;
1906 a = a1 * (1.0f - alpha) + a2 * alpha;
1907 r = r1 * (1.0f - alpha) + r2 * alpha;
1908 g = g1 * (1.0f - alpha) + g2 * alpha;
1909 b = b1 * (1.0f - alpha) + b2 * alpha;
1911 ColorAlpha dst = *dest;
1912 int cr = (int)(a * r / 255 + ((255 - a) * dst.color.r / 255));
1913 int cg = (int)(a * g / 255 + ((255 - a) * dst.color.g / 255));
1914 int cb = (int)(a * b / 255 + ((255 - a) * dst.color.b / 255));
1915 if(cr > 255) cr = 255;
1916 if(cg > 255) cg = 255;
1917 if(cb > 255) cb = 255;
1918 dest->color = { (byte)cr, (byte)cg, (byte)cb };
1920 if(alphaWrite == blend)
1922 int ca = (int)(a + ((255 - a) * dst.a / 255));
1923 if(ca > 255) ca = 255;
1936 for (y = 0; y < h; y++)
1938 int y0 = Min((int)((y + 1) * scaleY), sh - 1);
1939 int y1 = Min(y0 + 1, sh - 1);
1941 for (x = 0; x < w; x++, dest += 1)
1943 int x0 = Min((int)((x + 1) * scaleX), sw - 1);
1944 int x1 = Min(x0 + 1, sw - 1);
1945 float a = 0, r = 0, g = 0, b = 0;
1948 for (i = y0; i <= y1; i++)
1949 for (j = x0; j <= x1; j++)
1951 ColorAlpha pixel = source[i * src.stride + j];
1963 ColorAlpha dst = *dest;
1964 int cr = (int)(a * r / 255 + ((255 - a) * dst.color.r / 255));
1965 int cg = (int)(a * g / 255 + ((255 - a) * dst.color.g / 255));
1966 int cb = (int)(a * b / 255 + ((255 - a) * dst.color.b / 255));
1967 if(cr > 255) cr = 255;
1968 if(cg > 255) cg = 255;
1969 if(cb > 255) cb = 255;
1970 dest->color = { (byte)cr, (byte)cg, (byte)cb };
1971 if(alphaWrite == blend)
1973 int ca = (int)(a + ((255 - a) * dst.a / 255));
1974 if(ca > 255) ca = 255;
1985 else if(!src.paletteShades && src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1986 filters_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1987 // Fail back on Stretch
1988 else if(src.paletteShades)
1989 shades_stretch_table[lfbSurface.bitmap.pixelFormat][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1990 else if(src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1991 stretches_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1992 else if(src.pixelFormat == pixelFormat8 && lfbSurface.bitmap.pixelFormat != pixelFormatText)
1993 stretches_8bit_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1997 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1999 Blit(display, surface, src, dx, dy, sx, sy, w, h);
2002 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2004 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
2007 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2009 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
2012 void UnloadFont(DisplaySystem displaySystem, Font font)
2017 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
2019 #ifndef ECERE_NOTRUETYPE
2020 return Font::Load(displaySystem, faceName, size, flags);
2026 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2028 if(displaySystem && displaySystem.flags.text && len)
2033 *width = num * textCellW;
2035 if(height) *height = textCellH;
2037 #if !defined(ECERE_NOTRUETYPE)
2038 else if(font && len)
2042 int w = 0, advance = 0;
2043 font.ProcessString(displaySystem, (const byte *)text, len, null, null, null, &w, 0, prevGlyph, rPrevGlyph, &advance);
2044 if(adv) *adv = advance >> 6;
2045 //*width = (w + 64 - w % 64) >> 6;
2049 *height = font.height;
2054 if(width) *width = 0;
2055 if(height) *height = 0;
2059 #if !defined(ECERE_NOTRUETYPE)
2060 void ::OutputGlyph(Surface surface, Display display, int x, int y, Glyph glyph, Bitmap bitmap)
2062 surface.driver.Blit(display, surface, bitmap, x + glyph.left, y + glyph.top, glyph.x, glyph.y, glyph.w, glyph.h);
2066 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2068 LFBSurface lfbSurface = surface.driverData;
2069 if(display && display.displaySystem.flags.text)
2071 LFBDisplay lfbDisplay = display.driverData;
2072 uint16 * coffset = (uint16 *)lfbDisplay.bitmap.picture;
2078 if(y > surface.box.bottom || y < surface.box.top)
2080 coffset += (y+surface.offset.y) * lfbSurface.bitmap.stride + x + surface.offset.x;
2081 for(c=0; (c<len && x < surface.box.left); c++, x++,coffset++);
2082 for(; (c<len && x <= surface.box.right); c++, x++,coffset++)
2084 if(surface.textOpacity)
2085 *coffset = (uint16) (lfbSurface.background|lfbSurface.foreground|text[c]);
2087 *coffset = (uint16) (((*coffset)&0xF000)|lfbSurface.foreground|text[c]);
2093 lfbSurface.writingText = true;
2094 #if !defined(ECERE_NOTRUETYPE)
2096 lfbSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, OutputGlyph, surface, display, &x, y, prevGlyph, rPrevGlyph, &adv);
2099 lfbSurface.writingText = false;
2103 void TextFont(Display display, Surface surface, Font font)
2105 LFBSurface lfbSurface = surface.driverData;
2106 lfbSurface.font = font;
2109 void TextOpacity(Display display, Surface surface, bool opaque)
2114 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * advance)
2116 LFBSurface lfbSurface = surface.driverData;
2117 FontExtent(surface.displaySystem, lfbSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, advance);
2120 void DrawingChar(Display display, Surface surface, byte character)
2122 LFBSurface lfbSurface = surface.driverData;
2123 lfbSurface.drawingChar = character;
2126 void LineStipple(Display display, Surface surface, uint32 stipple)
2128 LFBSurface lfbSurface = surface.driverData;
2129 lfbSurface.stipple = (uint16)stipple;
2132 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
2133 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
2135 if(mesh.vertices && !mesh.flags.vertices)
2136 delete mesh.vertices;
2137 if(mesh.normals && !mesh.flags.normals)
2138 delete mesh.normals;
2139 if(mesh.texCoords && !mesh.flags.texCoords1)
2140 delete mesh.texCoords;
2143 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
2145 bool result = false;
2146 if(mesh.nVertices == nVertices)
2149 // Same number of vertices, adding features (Leaves the other features pointers alone)
2150 if(mesh.flags != flags)
2152 if(!mesh.flags.vertices && flags.vertices)
2154 if(flags.doubleVertices)
2156 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
2159 mesh.vertices = new Vector3Df[nVertices];
2161 if(!mesh.flags.normals && flags.normals)
2163 if(flags.doubleNormals)
2165 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
2168 mesh.normals = new Vector3Df[nVertices];
2170 if(!mesh.flags.texCoords1 && flags.texCoords1)
2171 mesh.texCoords = new Pointf[nVertices];
2172 if(!mesh.flags.colors && flags.colors)
2173 mesh.colors = new ColorRGBAf[nVertices];
2179 // New number of vertices, reallocate all current and new features
2180 flags |= mesh.flags;
2183 if(flags.doubleVertices)
2185 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
2188 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
2192 if(flags.doubleNormals)
2194 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
2197 mesh.normals = renew mesh.normals Vector3Df[nVertices];
2199 if(flags.texCoords1)
2200 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
2202 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
2207 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures features)
2212 void FreeIndices(DisplaySystem displaySystem, uint16 * indices)
2217 uint16 * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
2219 return (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
2221 uint16 * LockIndices(DisplaySystem displaySystem, void * indices)