3 namespace gfx::drivers;
6 #pragma warning(disable:4244)
7 #pragma warning(disable:4018)
13 public define LIGHTSHIFT = 5;
14 public define LIGHTSTEPS = 1<<LIGHTSHIFT;
16 /*#ifndef ECERE_VANILLA
18 static bool rgbLookupSet = true;
20 /*static */byte defaultRGBLookup[32768];
21 /*static */bool rgbLookupSet = false;
24 #if defined(ECERE_VANILLA)
25 #define ECERE_NOTRUETYPE
28 #if !defined(ECERE_NOTRUETYPE)
29 import "fontManagement"
30 import "fontRendering"
32 public class Font : struct { }
38 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA) && !defined(ECERE_ONEDRIVER) && defined(__WIN32__)
39 import "OpenGLDisplayDriver"
41 #if !defined(_GLES) && !defined(ECERE_STATIC)
42 import "Direct3D8DisplayDriver"
43 import "Direct3D9DisplayDriver"
48 public class LFBDisplay : struct
52 byte rgbLookup[32768];
53 byte lightTable[256][LIGHTSTEPS];
57 void (* displayCallback)(Display display, Box updateBox);
60 public class LFBSystem : struct
65 byte rgbLookup[32768];
72 ColorAlpha * palette = GetDefaultPalette();
73 for(c = 16; c < 232; c++)
75 Color555 color = palette[c].color;
76 for(r = Max(0, color.r - 2); r <= Min(31, color.r + 4); r++)
77 for(g = Max(0, color.g - 2); g <= Min(31, color.g + 4); g++)
78 for(b = Max(0, color.b - 2); b <= Min(31, color.b + 4); b++)
79 defaultRGBLookup[r * 32 * 32 + g * 32 + b] = (byte)c;
81 for(c = 232; c < 246; c++)
83 Color555 color = palette[c].color;
84 defaultRGBLookup[color] = (byte)c;
87 for(c = 246; c < 256; c++)
89 Color555 color = palette[c].color;
90 defaultRGBLookup[color] = (byte)c;
92 for(c = 0; c < 16; c++)
94 Color555 color = palette[c].color;
95 defaultRGBLookup[color] = (byte)c;
98 for(c = 0; c<32768; c++)
100 Color color = (Color)(Color555)c;
101 defaultRGBLookup[c] = 16 + (color.r * 5 / 255) * 36 + (color.g * 5 / 255) * 6 + (color.b * 5 / 255);
102 // defaultRGBLookup[c] = (byte)BestColorMatch(palette, 0, 255, (Color)(Color555)c);
110 public class LFBSurface : struct
113 // For compatibility with 3D drivers as well
122 // Drawing attributes
123 uint foreground, background;
124 ColorAlpha foregroundRgb;
127 byte * paletteShades;
132 static int CompareHit(GLHitRecord * recordA, GLHitRecord * recordB, const void * nothing)
134 if(recordA->zMin > recordB->zMin)
136 else if(recordA->zMin < recordB->zMin)
138 else if(recordA > recordB)
140 else if(recordA < recordB)
147 public class LFBDisplayDriver : DisplayDriver
149 class_property(name) = "LFB";
151 bool CreateDisplaySystem(DisplaySystem displaySystem)
153 displaySystem.flags.memBackBuffer = true;
154 // displaySystem.pixelFormat = pixelFormat888;
158 void DestroyDisplaySystem(DisplaySystem displaySystem)
162 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
164 delete bitmap.picture;
165 if(bitmap.allocatePalette)
166 delete bitmap.palette;
169 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
174 switch(GetColorDepthShifts(format))
176 case 0: stride = (width + 3) & 0xFFFFFFFC; break;
177 case 1: stride = (width + 1) & 0xFFFFFFFE; break;
178 case 2: stride = width; break;
181 bitmap.stride = stride;
182 bitmap.width = width;
183 bitmap.height = height;
184 bitmap.size = (uint32) stride * (uint32)height;
185 bitmap.sizeBytes = bitmap.size << GetColorDepthShifts(format);
186 bitmap.pixelFormat = format;
187 bitmap.transparent = false;
189 surface.box.left = surface.box.top = 0;
190 surface.box.right = width - 1;
191 surface.box.bottom = height - 1;
193 bitmap.picture = new0 byte[bitmap.sizeBytes];
196 bitmap.allocatePalette = allocatePalette;
199 bitmap.palette = new ColorAlpha[256];
202 CopyBytesBy4(bitmap.palette, GetDefaultPalette(), 256);
208 bitmap.palette = GetDefaultPalette();
213 FreeBitmap(displaySystem, bitmap);
217 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
220 LFBSystem lfbSystem = displaySystem ? displaySystem.driverData : null;
224 if((src.pixelFormat == format) && (format != pixelFormat8 || !palette))
226 if(src.transparent && src.pixelFormat == pixelFormat888)
230 DWORD * picture = (DWORD *)src.picture;
232 for(c = 0; c<src.size; c++, picture++)
234 if(*picture & 0xFFFFFF)
235 *picture = *picture | 0xFF000000;
237 *picture = *picture & 0xFFFFFF;
246 if(bitmap.Allocate(null, src.width, src.height, 0, format, false))
248 if(format == pixelFormat8)
251 bitmap.palette = palette;
252 else if(lfbSystem && lfbSystem.palette)
253 bitmap.palette = lfbSystem.palette;
255 bitmap.palette = src.palette;
258 if(converters_table[src.pixelFormat][bitmap.pixelFormat])
260 converters_table[src.pixelFormat][bitmap.pixelFormat](lfbSystem, src, bitmap);
261 bitmap.transparent = src.transparent;
262 bitmap.alphaBlend = src.alphaBlend && format != pixelFormat8;
264 if(src.palette != bitmap.palette)
266 if(src.allocatePalette)
268 src.allocatePalette = false;
270 src.picture = bitmap.picture;
271 src.palette = bitmap.palette;
272 src.stride = bitmap.stride;
273 src.size = bitmap.size;
274 src.sizeBytes = bitmap.sizeBytes;
275 src.pixelFormat = bitmap.pixelFormat;
280 bitmap.palette = null;
281 bitmap.picture = null;
289 void DestroyDisplay(Display display)
291 LFBDisplay lfbDisplay = display.driverData;
292 delete lfbDisplay.bitmap.palette;
295 bool CreateDisplay(Display display)
298 LFBDisplay lfbDisplay = display.driverData;
301 lfbDisplay = display.driverData = LFBDisplay { };
302 lfbDisplay.selfManaged = true;
303 lfbDisplay.bitmap.pixelFormat = pixelFormatRGBA;
306 if((lfbDisplay.bitmap.palette = new ColorAlpha[256]))
308 CopyBytesBy4(lfbDisplay.bitmap.palette, GetDefaultPalette(), 256);
314 bool DisplaySize(Display display, int width, int height)
316 LFBDisplay lfbDisplay = display.driverData;
317 //display.width = width;
318 //display.height = height;
319 lfbDisplay.bitmap.width = width;
320 lfbDisplay.bitmap.height = height;
322 lfbDisplay.updateBox.left = display.width;
323 lfbDisplay.updateBox.top = display.height;
324 lfbDisplay.updateBox.right = 0;
325 lfbDisplay.updateBox.bottom = 0;
328 if(lfbDisplay.selfManaged)
330 lfbDisplay.bitmap.picture = (byte *)renew lfbDisplay.bitmap.picture int[width * height];
331 lfbDisplay.bitmap.stride = width;
333 lfbDisplay.bitmap.size = lfbDisplay.bitmap.stride * lfbDisplay.bitmap.height;
337 void DisplayPosition(Display display, int x, int y)
339 LFBDisplay lfbDisplay = display.driverData;
344 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
346 LFBDisplay lfbDisplay = display.driverData;
353 LFBSystem lfbSystem = display.displaySystem ? display.displaySystem.driverData : null;
354 palette = lfbSystem ? lfbSystem.palette : GetDefaultPalette();
355 CopyBytes(lfbDisplay.rgbLookup, defaultRGBLookup, 32768);
358 for(c = 0; c<32768; c++)
359 lfbDisplay.rgbLookup[c] = (byte)BestColorMatch(palette, 1, 255, (Color)(Color555)c);
364 for(i=0; i<LIGHTSTEPS; i++)
366 lfbDisplay.lightTable[c][i] = lfbDisplay.rgbLookup[(uint16)(Color555) Color {
367 (byte)(((uint16)palette[c].color.r * i) >> LIGHTSHIFT),
368 (byte)(((uint16)palette[c].color.g * i) >> LIGHTSHIFT),
369 (byte)(((uint16)palette[c].color.b * i) >> LIGHTSHIFT) }];
373 if(lfbDisplay.bitmap.palette)
374 CopyBytesBy4(lfbDisplay.bitmap.palette, palette ? palette : GetDefaultPalette(), 256);
377 void Update(Display display, Box updateBox)
379 LFBDisplay lfbDisplay = display.driverData;
380 if(lfbDisplay.displayCallback)
382 if(updateBox == null)
384 Box box { 0,0, display.width,display.height };
385 lfbDisplay.displayCallback(display, box);
388 lfbDisplay.displayCallback(display, updateBox);
392 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps, int cubeMapFace)
394 if(bitmap.pixelFormat != pixelFormatAlpha)
396 if(!ConvertBitmap(displaySystem, bitmap, /*bitmap.alphaBlend ? pixelFormat888 : */displaySystem.pixelFormat, null))
398 FreeBitmap(displaySystem, bitmap);
405 void ReleaseSurface(Display display, Surface surface)
407 LFBSurface lfbSurface = surface.driverData;
409 surface.driverData = null;
412 bool GetSurface(Display display, Surface surface, int x, int y, Box clip)
414 LFBDisplay lfbDisplay = display.driverData;
415 LFBSurface lfbSurface = surface.driverData;
418 lfbSurface = surface.driverData = LFBSurface { };
421 lfbSurface.bitmap = lfbDisplay.bitmap;
423 surface.offset.x = x;
424 surface.offset.y = y;
426 if(lfbDisplay.bitmap.pixelFormat == pixelFormatText)
428 surface.offset.x /= textCellW;
429 surface.offset.y /= textCellH;
430 surface.box.left /= textCellW;
431 surface.box.top /= textCellH;
432 surface.box.right /= textCellW;
433 surface.box.bottom /= textCellH;
437 lfbDisplay.updateBox.left = Min(x + clip.left, lfbDisplay.updateBox.left);
438 lfbDisplay.updateBox.top = Min(y + clip.top, lfbDisplay.updateBox.top);
439 lfbDisplay.updateBox.right = Max(x + clip.right, lfbDisplay.updateBox.right);
440 lfbDisplay.updateBox.bottom = Max(y + clip.bottom, lfbDisplay.updateBox.bottom);
443 surface.unclippedBox = surface.box;
444 lfbSurface.drawingChar = 219;
448 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x,int y, Box clip)
451 LFBSurface lfbSurface = surface.driverData;
452 if(lfbSurface || (surface.driverData = lfbSurface = LFBSurface { }))
454 lfbSurface.bitmap = bitmap;
456 surface.offset.x = x;
457 surface.offset.y = y;
459 if(bitmap.pixelFormat == pixelFormatText)
461 surface.offset.x /= textCellW;
462 surface.offset.y /= textCellH;
463 surface.box.left /= textCellW;
464 surface.box.top /= textCellH;
465 surface.box.right /= textCellW;
466 surface.box.bottom /= textCellH;
469 surface.unclippedBox = *&surface.box;
470 lfbSurface.drawingChar = 219;
477 void Clip(Display display, Surface surface, Box clip)
479 LFBSurface lfbSurface = surface.driverData;
484 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
486 box.left /= textCellW;
487 box.top /= textCellH;
488 box.right /= textCellW;
489 box.bottom /= textCellH;
491 box.Clip(surface.unclippedBox);
495 surface.box = surface.unclippedBox;
498 void SetForeground(Display display, Surface surface, ColorAlpha color)
500 LFBDisplay lfbDisplay = display ? display.driverData : null;
501 LFBSurface lfbSurface = surface.driverData;
503 //if(display) color = color & 0xFFFFFF;
504 lfbSurface.foregroundRgb = color;
506 if(lfbSurface.font && lfbDisplay)
508 index = lfbDisplay.rgbLookup[(uint16)(Color555)lfbSurface.foregroundRgb];
509 lfbSurface.paletteShades = lfbDisplay.lightTable[index];
512 switch(lfbSurface.bitmap.pixelFormat)
516 lfbSurface.foreground = lfbDisplay.rgbLookup[(uint16)(Color555)color];
518 lfbSurface.foreground = BestColorMatch(lfbSurface.bitmap.palette,0,255,color);
520 case pixelFormat444: lfbSurface.foreground = (Color444)color; break;
521 case pixelFormat555: lfbSurface.foreground = (Color555)color; break;
522 case pixelFormat565: lfbSurface.foreground = (Color565)color; break;
523 case pixelFormat888: lfbSurface.foreground = color; break;
524 case pixelFormatRGBA: lfbSurface.foreground = (ColorRGBA)color; break;
525 case pixelFormatText:
527 lfbSurface.foreground = BestColorMatch(lfbDisplay.bitmap.palette,0,15,color) << 8;
529 lfbSurface.foreground = BestColorMatch(lfbSurface.bitmap.palette,0,15,color) << 8;
534 void SetBackground(Display display, Surface surface, ColorAlpha color)
536 LFBDisplay lfbDisplay = display ? display.driverData : null;
537 LFBSurface lfbSurface = surface.driverData;
538 //color = color & 0xFFFFFF;
539 switch(lfbSurface.bitmap.pixelFormat)
543 lfbSurface.background = lfbDisplay.rgbLookup[(uint16)(Color555)color];
545 lfbSurface.background = BestColorMatch(lfbSurface.bitmap.palette,0,255,color);
547 case pixelFormat444: lfbSurface.background = (Color444)color; break;
548 case pixelFormat555: lfbSurface.background = (Color555)color; break;
549 case pixelFormat565: lfbSurface.background = (Color565)color; break;
550 case pixelFormat888: lfbSurface.background = color; break;
551 case pixelFormatRGBA: lfbSurface.background = (ColorRGBA)color; break;
552 case pixelFormatText:
554 lfbSurface.background = BestColorMatch(lfbDisplay.bitmap.palette,0,15,color) << 12;
556 lfbSurface.background = BestColorMatch(lfbSurface.bitmap.palette,0,15,color) << 12;
561 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
563 LFBSurface lfbSurface = surface.driverData;
564 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
569 if((x <= surface.box.right) && (y <= surface.box.bottom) && (x >= surface.box.left) && (y >= surface.box.top))
571 x += surface.offset.x;
572 y += surface.offset.y;
573 if(lfbSurface.bitmap.picture)
575 switch(lfbSurface.bitmap.pixelFormat)
577 case pixelFormatText:
579 if(!lfbSurface.bitmap.palette) return 0;
580 return lfbSurface.bitmap.palette[((byte *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x]];
581 case pixelFormat444: return ((Color444 *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x];
582 case pixelFormat555: return ((Color555 *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x];
583 case pixelFormat565: return ((Color565 *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x];
584 case pixelFormat888: return ((ColorAlpha *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride+x];
591 void PutPixel(Display display, Surface surface,int x,int y)
593 LFBSurface lfbSurface = surface.driverData;
594 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
599 if((x <= surface.box.right) && (y <= surface.box.bottom) && (x >= surface.box.left) && (y >= surface.box.top))
601 x += surface.offset.x;
602 y += surface.offset.y;
603 if(lfbSurface.bitmap.picture)
605 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
608 ((byte *)lfbSurface.bitmap.picture)[(uint) y * lfbSurface.bitmap.stride + x] = (byte)lfbSurface.foreground;
611 ((uint16 *)lfbSurface.bitmap.picture)[(uint)y * lfbSurface.bitmap.stride + x] = (uint16)lfbSurface.foreground;
614 if(((uint32 *)lfbSurface.bitmap.picture)[(uint32) y * lfbSurface.bitmap.stride + x] != (uint32)lfbSurface.foreground)
615 ((uint32 *)lfbSurface.bitmap.picture)[(uint32) y * lfbSurface.bitmap.stride + x] = (uint32)lfbSurface.foreground;
622 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
624 LFBSurface lfbSurface = surface.driverData;
630 uint color = lfbSurface.foreground;
631 uint16 stipple = lfbSurface.stipple ? lfbSurface.stipple : 0xFFFF;
633 if(!lfbSurface.bitmap.picture) return;
634 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
640 if(surface.textOpacity)
641 color |= lfbSurface.background;
642 color |= lfbSurface.drawingChar;
646 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; invert = true; }
648 if((y1>surface.box.bottom)||(y1<surface.box.top))return;
649 if((x1>surface.box.right)||(x2<surface.box.left))return;
650 if(x1<surface.box.left)x1=surface.box.left;
651 if(x2>surface.box.right)x2=surface.box.right;
655 offset=(y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
656 if(stipple != 0xFFFF)
659 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
662 for(x=x1; x<=x2; x++, offset++)
665 ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color;
667 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
669 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
673 for(x=x1; x<=x2; x++, offset++)
676 ((uint16 *)lfbSurface.bitmap.picture)[offset] = (uint16)color;
678 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
680 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
684 for(x=x1; x<=x2; x++, offset++)
687 ((uint32 *)lfbSurface.bitmap.picture)[offset] = color;
689 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
691 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
698 if(lfbSurface.bitmap.pixelFormat != pixelFormatText || surface.textOpacity)
700 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
702 case 0: FillBytes(((byte *)lfbSurface.bitmap.picture)+offset,(byte)color,x2-x1+1); break;
703 case 1: FillBytesBy2(((uint16 *)lfbSurface.bitmap.picture)+offset,(uint16)color,x2-x1+1); break;
704 case 2: FillBytesBy4(((uint32 *)lfbSurface.bitmap.picture)+offset,color,x2-x1+1); break;
710 for(x = x1; x <= x2; x++, offset++)
712 ((uint16 *)lfbSurface.bitmap.picture)[offset] =
713 (((uint16 *)lfbSurface.bitmap.picture)[offset] & 0xF000) | (uint16)color;
722 if(y1>y2) { int tmp = y2; y2 = y1; y1 = tmp; invert = true; }
724 if((x1>surface.box.right)||(x1<surface.box.left))return;
725 if((y1>surface.box.bottom)||(y2<surface.box.top))return;
726 if(y1<surface.box.top)y1=surface.box.top;
727 if(y2>surface.box.bottom)y2=surface.box.bottom;
729 offset=(y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
730 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
733 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
736 ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color;
738 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
740 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
744 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
748 if(lfbSurface.bitmap.pixelFormat != pixelFormatText || surface.textOpacity)
749 ((uint16 *)lfbSurface.bitmap.picture)[offset]=(uint16)color;
752 ((uint16 *)lfbSurface.bitmap.picture)[offset] =
753 (((uint16 *)lfbSurface.bitmap.picture)[offset] & 0xF000) | (uint16)color;
757 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
759 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
763 if(stipple != 0xFFFF)
765 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
768 ((uint32*)lfbSurface.bitmap.picture)[offset]=color;
770 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
772 stipple = ((stipple & 0xFFFE)>>1) | ((stipple & 0x0001)<<15);
777 for(y=y1; y<=y2; y++, offset+=lfbSurface.bitmap.stride)
778 ((uint32*)lfbSurface.bitmap.picture)[offset]=color;
787 if(x1 < surface.box.left)
789 if(x2 < surface.box.left)
791 y1 += (y2 - y1) * (surface.box.left - x1) / (x2 - x1);
792 x1 = surface.box.left;
794 if(x2 > surface.box.right)
796 if(x1 > surface.box.right)
798 y2 -= (y2 - y1) * (x2 - surface.box.right) / (x2 - x1);
799 x2 = surface.box.right;
803 if(y1 < surface.box.top)
805 if(y2 < surface.box.top)
807 x1 += (x2 - x1) * (surface.box.top - y1) / (y2 - y1);
808 y1 = surface.box.top;
810 if(y2 > surface.box.bottom)
812 if(y1 > surface.box.bottom)
814 x2 -= (x2 - x1) * (y2 - surface.box.bottom) / (y2 - y1);
815 y2 = surface.box.bottom;
820 if(y1 > surface.box.bottom)
822 if(y2 > surface.box.bottom)
824 x1 -= (x1 - x2) * (y1 - surface.box.bottom) / (y1 - y2);
825 y1 = surface.box.bottom;
827 if(y2 < surface.box.top)
829 if(y1 < surface.box.top)
831 x2 += (x1 - x2) * (surface.box.top - y2) / (y1 - y2);
832 y2 = surface.box.top;
838 if(x1 > surface.box.right)
840 if(x2 > surface.box.right)
842 y1 -= (y1 - y2) * (x1 - surface.box.right) / (x1 - x2);
843 x1 = surface.box.right;
845 if(x2 < surface.box.left)
847 if(x1 < surface.box.left)
849 y2 += (y1 - y2) * (surface.box.left - x2) / (x1 - x2);
850 x2 = surface.box.left;
854 if(y1 < surface.box.top)
856 if(y2 < surface.box.top)
858 x1 += (x2 - x1) * (surface.box.top - y1) / (y2 - y1);
859 y1 = surface.box.top;
861 if(y2 > surface.box.bottom)
863 if(y1 > surface.box.bottom)
865 x2 -= (x2 - x1) * (y2 - surface.box.bottom) / (y2 - y1);
866 y2 = surface.box.bottom;
871 if(y1 > surface.box.bottom)
873 if(y2 > surface.box.bottom)
875 x1 -= (x1 - x2) * (y1 - surface.box.bottom) / (y1 - y2);
876 y1 = surface.box.bottom;
878 if(y2 < surface.box.top)
880 if(y1 < surface.box.top)
882 x2 += (x1 - x2) * (surface.box.top - y2) / (y1 - y2);
883 y2 = surface.box.top;
901 yu=-(int)lfbSurface.bitmap.stride;
904 yu=lfbSurface.bitmap.stride;
906 offset=(y1+surface.offset.y)*lfbSurface.bitmap.stride+x1+surface.offset.x;
912 for(i=0; i<=length; i++)
915 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
917 case 0: ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color; break;
918 case 1: ((uint16 *)lfbSurface.bitmap.picture)[offset]=(uint16)color; break;
919 case 2: ((uint32*)lfbSurface.bitmap.picture)[offset]=(uint32)color; break;
928 stipple = ((stipple & 0x7FFF)<<1) | ((stipple & 0x8000)>>15);
934 for(i=0; i<=length; i++)
937 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
939 case 0: ((byte *)lfbSurface.bitmap.picture)[offset]=(byte)color; break;
940 case 1: ((uint16 *)lfbSurface.bitmap.picture)[offset]=(uint16)color; break;
941 case 2: ((uint32*)lfbSurface.bitmap.picture)[offset]=(uint32)color; break;
955 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
957 DrawLine(display, surface,x1,y1,x2,y1);
958 DrawLine(display, surface,x2,y1,x2,y2);
959 DrawLine(display, surface,x2,y2,x1,y2);
960 DrawLine(display, surface,x1,y2,x1,y1);
963 #if !defined(__GNUC__)
965 void memset_32_aligned(void *buf, int val, int dwords)
970 *((uint32 *)(buf)) = val;
971 buf = ((uint32 *)(buf))+1;
997 if (dwords & 1) *((int*)(buf)) = val;
1003 void memset_32_aligned(uint32 *buf, uint32 val, uint32 dwords)
1007 if(((uint32)buf) & 0x7F)
1009 for( ; ((uint32)buf) & 0x7F && dwords; buf++)
1035 sub edx,ebx ; edx holds # of overflow bytes
1054 movdqa [edi+16],xmm0
1055 movdqa [edi+32],xmm0
1056 movdqa [edi+48],xmm0
1057 movdqa [edi+64],xmm0
1058 movdqa [edi+80],xmm0
1059 movdqa [edi+96],xmm0
1060 movdqa [edi+112],xmm0
1084 void memset_32(void *buf, uint32 val, uint32 dwords)
1087 if ((uint32)(buf) & 3)
1092 if (((uint32)(buf) & 1))
1094 *(byte *)(buf) = (byte)(val&0xFF);
1095 buf = ((byte *)(buf))+1;
1096 val = ((val& 0xFF) << 24) || ((val& 0xFFFFFF00) >> 8);
1099 if (((uint32)(buf) & 2))
1101 *(uint16 *)(buf) = (uint16)(val&0xFFFF);
1102 buf = ((uint16 *)(buf))+1;
1103 val = ((val& 0xFFFF) << 16) || ((val& 0xFFFF0000) >> 16);
1107 memset_32_aligned(buf,val,dwords);
1112 *(byte *)(buf) = (byte)(val&0xFF);
1116 *(uint16 *)(buf) = (uint16)(val&0xFFFF);
1117 if (align & 1) *((byte *)(buf)+2) = (byte)((val>>16)&0xFF);
1124 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
1126 LFBSurface lfbSurface = surface.driverData;
1127 uint32 color = lfbSurface.background;
1129 if(lfbSurface.bitmap.pixelFormat == pixelFormatText)
1131 color |= lfbSurface.foreground | lfbSurface.drawingChar;
1137 if(x1>x2) { int tmp = x2; x2 = x1; x1 = tmp; }
1139 if(x1<surface.box.left) x1=surface.box.left;
1140 if(x2>surface.box.right) x2=surface.box.right;
1141 if(y1<surface.box.top) y1=surface.box.top;
1142 if(y2>surface.box.bottom) y2=surface.box.bottom;
1144 if(x2>=x1 && y2>=y1)
1152 x1 += surface.offset.x;
1153 x2 += surface.offset.x;
1154 y1 += surface.offset.y;
1155 y2 += surface.offset.y;
1156 if(lfbSurface.bitmap.picture)
1158 if(!surface.writeColor)
1160 ColorAlpha * picture = (((ColorAlpha *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1161 for(y = y1; y<= y2; y++)
1164 for(c = 0; c < w; c++, picture++)
1166 picture->a = (byte)((color & 0xFF000000) >> 24);
1167 picture += lfbSurface.bitmap.stride - w;
1172 if(!surface.blend || surface.background.a == 255 || lfbSurface.clearing)
1174 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
1177 theOffset = ((byte *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1;
1178 for(y = y1; y<= y2; y++)
1180 FillBytes(theOffset,(byte)color,w);
1181 theOffset += lfbSurface.bitmap.stride;
1185 theOffset = (byte *) (((uint16 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1186 for(y = y1; y<= y2; y++)
1188 FillBytesBy2((uint16 *) theOffset,(uint16)color,w);
1189 theOffset += lfbSurface.bitmap.stride * sizeof(uint16);
1193 theOffset = (byte *) (((uint32 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1194 for(y = y1; y<= y2; y++)
1196 #if defined(__GNUC__)
1197 FillBytesBy4((uint32 *) theOffset,color,w);
1199 memset_32((uint32 *) theOffset,color,w);
1201 theOffset += lfbSurface.bitmap.stride * sizeof(uint32);
1207 int bla = (lfbSurface.bitmap.stride - w) * sizeof(uint32);
1208 //memset_32((uint32 *) theOffset,color,w);
1244 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
1247 theOffset = ((byte *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1;
1248 for(y = y1; y<= y2; y++)
1250 // TODO: IMPLEMENT THIS
1251 FillBytes(theOffset,(byte)color,w);
1252 theOffset += lfbSurface.bitmap.stride;
1257 uint16 * dest = (((uint16 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1258 ColorAlpha c = surface.background;
1263 PixelFormat pixelFormat = lfbSurface.bitmap.pixelFormat;
1265 for(y = y1; y <= y2; y++)
1268 for(c = 0; c < w; c++, dest++)
1270 Color destColor = 0;
1271 if(pixelFormat == pixelFormat565) { destColor = (Color)*(Color565 *)dest; }
1272 else if(pixelFormat == pixelFormat555) { destColor = (Color)*(Color555 *)dest; }
1273 else if(pixelFormat == pixelFormat444) { destColor = (Color)*(Color444 *)dest; }
1275 int r = a * cr / 255 + ((255 - a) * destColor.r / 255);
1276 int g = a * cg / 255 + ((255 - a) * destColor.g / 255);
1277 int b = a * cb / 255 + ((255 - a) * destColor.b / 255);
1279 if(r > 255) r = 255;
1280 if(g > 255) g = 255;
1281 if(b > 255) b = 255;
1283 destColor = { (byte)r, (byte)g, (byte)b };
1285 if(pixelFormat == pixelFormat565) { *dest = (Color565)destColor; }
1286 else if(pixelFormat == pixelFormat555) { *dest = (Color555)destColor; }
1287 else if(pixelFormat == pixelFormat444) { *dest = (Color444)destColor; }
1290 dest += (lfbSurface.bitmap.stride - w);
1296 ColorAlpha * dest = (ColorAlpha *)(((uint32 *)lfbSurface.bitmap.picture) + y1 * lfbSurface.bitmap.stride + x1);
1297 AlphaWriteMode alphaWrite = surface.alphaWrite;
1298 ColorAlpha c = surface.background;
1303 for(y = y1; y <= y2; y++)
1306 for(c = 0; c < w; c++, dest++)
1308 int dr = dest->color.r;
1309 int dg = dest->color.g;
1310 int db = dest->color.b;
1311 int r = a * cr / 255 + ((255 - a) * dr / 255);
1312 int g = a * cg / 255 + ((255 - a) * dg / 255);
1313 int b = a * cb / 255 + ((255 - a) * db / 255);
1315 if(r > 255) r = 255;
1316 if(g > 255) g = 255;
1317 if(b > 255) b = 255;
1318 dest->color = { (byte)r, (byte)g, (byte)b };
1320 if(alphaWrite == blend)
1322 int ca = (int)(a + ((255 - a) * dest->a / 255));
1323 if(ca > 255) ca = 255;
1329 dest += (lfbSurface.bitmap.stride - w);
1338 void Clear(Display display, Surface surface, ClearType type)
1340 LFBSurface lfbSurface = surface.driverData;
1342 lfbSurface.clearing = true;
1343 if(surface.offset.x == 0 && surface.offset.y == 0 &&
1344 surface.box.left == 0 && surface.box.top == 0 &&
1345 surface.box.right == surface.width-1 &&
1346 surface.box.bottom == surface.height-1)
1348 uint32 color = /*0xFF000000 | */lfbSurface.background;
1349 if(type != depthBuffer)
1351 if(lfbSurface.bitmap.stride != surface.width)
1352 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);
1355 switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
1358 FillBytes(lfbSurface.bitmap.picture, (byte)color, lfbSurface.bitmap.size);
1360 case 1: FillBytesBy2((uint16 *)lfbSurface.bitmap.picture, (uint16)color, lfbSurface.bitmap.size); break;
1361 case 2: FillBytesBy4((uint32 *)lfbSurface.bitmap.picture, color, lfbSurface.bitmap.size); break;
1366 if((flags & CLEAR_Z) && zbuffer)
1367 FillBytesBy4((DWORD *)zbuffer,0,(sizeof(float)*(DWORD)display.width * display.Height)>>2);
1372 if(type != depthBuffer)
1373 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);
1375 if((flags & CLEAR_Z))
1378 uint32 w = surface.box.right-surface.box.left+1;
1379 float * offset = zbuffer + ((surface.box.top +surface.offset.y) * (DWORD)DISPLAY.Width)
1380 + surface.box.left+surface.offset.x;
1381 for(y = surface.box.top; y<= surface.box.bottom; y++)
1383 FillBytesBy4((uint32 *) offset,0,(sizeof(float)>>2)*w);
1384 offset += DISPLAY.Width;
1389 lfbSurface.clearing = false;
1392 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1394 LFBSurface lfbSurface = surface.driverData;
1397 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return;
1399 if(w < 0) { w = -w; flip = true; }
1401 //Clip against the edges of the source
1414 if(sx+w>src.width-1)
1415 w-=sx+w-(src.width-1)-1;
1416 if(sy+h>src.height-1)
1417 h-=sy+h-(src.height-1)-1;
1418 //Clip against the edges of the destination
1419 if(dx<surface.box.left)
1421 if(!flip) sx+=surface.box.left-dx;
1422 w-=surface.box.left-dx;
1423 dx=surface.box.left;
1425 if(dy<surface.box.top)
1427 sy+=surface.box.top-dy;
1428 h-=surface.box.top-dy;
1431 if((dx+w)>surface.box.right)
1433 if(flip) sx+=(uint32)(dx+w)-surface.box.right-1;
1434 w-=((uint32)(dx+w)-surface.box.right-1);
1436 if((dy+h)>surface.box.bottom)
1437 h-=((dy+h)-surface.box.bottom-1);
1441 dx += surface.offset.x;
1442 dy += surface.offset.y;
1444 if(lfbSurface.bitmap.picture)
1446 AlphaWriteMode alphaWrite = surface.alphaWrite;
1447 if(src.alphaBlend && surface.blend)
1450 if(src.pixelFormat == pixelFormatAlpha)
1452 if(lfbSurface.bitmap.pixelFormat == pixelFormat888)
1454 ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1455 byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
1456 ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
1457 for(y = 0; y < h; y++)
1459 for(x = 0; x < w; x++, picture++, source++)
1461 int a = *source * color.a;
1462 ColorAlpha dest = *picture;
1463 int r = (a * color.color.r + ((255 * 255 - a) * dest.color.r)) / (255 * 255);
1464 int g = (a * color.color.g + ((255 * 255 - a) * dest.color.g)) / (255 * 255);
1465 int b = (a * color.color.b + ((255 * 255 - a) * dest.color.b)) / (255 * 255);
1466 if(r > 255) r = 255;
1467 if(g > 255) g = 255;
1468 if(b > 255) b = 255;
1469 picture->color = { (byte)r, (byte)g, (byte)b };
1470 if(alphaWrite == blend)
1472 int ca = (a * 255 + (255 * 255 - a) * dest.a) / (255 * 255);
1473 if(ca > 255) ca = 255;
1474 picture->a = (byte)ca;
1477 picture->a = (byte)(a / 255);
1479 picture += lfbSurface.bitmap.stride - w;
1480 source += src.stride - w;
1483 else if(lfbSurface.bitmap.pixelFormat == pixelFormat555)
1485 Color555 * picture = ((Color555 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1486 byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
1487 ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
1488 for(y = 0; y < h; y++)
1490 for(x = 0; x < w; x++, picture++, source++)
1492 int a = *source * color.a;
1493 Color dest = *picture;
1494 int r = (a * color.color.r + ((255 * 255 - a) * dest.r)) / (255 * 255);
1495 int g = (a * color.color.g + ((255 * 255 - a) * dest.g)) / (255 * 255);
1496 int b = (a * color.color.b + ((255 * 255 - a) * dest.b)) / (255 * 255);
1497 if(r > 255) r = 255;
1498 if(g > 255) g = 255;
1499 if(b > 255) b = 255;
1500 *picture = Color { (byte)r, (byte)g, (byte)b };
1502 picture += lfbSurface.bitmap.stride - w;
1503 source += src.stride - w;
1506 else if(lfbSurface.bitmap.pixelFormat == pixelFormat565)
1508 Color565 * picture = ((Color565 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1509 byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
1510 ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
1511 for(y = 0; y < h; y++)
1513 for(x = 0; x < w; x++, picture++, source++)
1515 int a = *source * color.a;
1516 Color dest = *picture;
1517 int r = (a * color.color.r + ((255 * 255 - a) * dest.r)) / (255 * 255);
1518 int g = (a * color.color.g + ((255 * 255 - a) * dest.g)) / (255 * 255);
1519 int b = (a * color.color.b + ((255 * 255 - a) * dest.b)) / (255 * 255);
1520 if(r > 255) r = 255;
1521 if(g > 255) g = 255;
1522 if(b > 255) b = 255;
1523 *picture = Color { (byte)r, (byte)g, (byte)b };
1525 picture += lfbSurface.bitmap.stride - w;
1526 source += src.stride - w;
1532 ColorAlpha * source = ((ColorAlpha *)src.picture) + (src.stride * sy) + sx;
1533 if(lfbSurface.bitmap.pixelFormat == pixelFormat888)
1535 ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1536 for(y = 0; y < h; y++)
1538 for(x = 0; x < w; x++, picture++, source++)
1540 ColorAlpha src = *source;
1541 ColorAlpha dest = *picture;
1542 int r = src.a * src.color.r / 255 + ((255 - src.a) * dest.color.r / 255);
1543 int g = src.a * src.color.g / 255 + ((255 - src.a) * dest.color.g / 255);
1544 int b = src.a * src.color.b / 255 + ((255 - src.a) * dest.color.b / 255);
1545 if(r > 255) r = 255;
1546 if(g > 255) g = 255;
1547 if(b > 255) b = 255;
1548 picture->color = { (byte)r, (byte)g, (byte)b };
1549 if(alphaWrite == blend)
1551 int a = src.a + ((255 - src.a) * dest.a / 255);
1552 if(a > 255) a = 255;
1553 picture->a = (byte)a;
1558 picture += lfbSurface.bitmap.stride - w;
1559 source += src.stride - w;
1562 else if(lfbSurface.bitmap.pixelFormat == pixelFormat565)
1564 Color565 * picture = ((Color565 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1565 for(y = 0; y < h; y++)
1567 for(x = 0; x < w; x++, picture++, source++)
1569 ColorAlpha src = *source;
1570 Color565 dest = *picture;
1571 int r = src.a * src.color.r * 31 / 255 + ((255 - src.a) * dest.r);
1572 int g = src.a * src.color.g * 63 / 255 + ((255 - src.a) * dest.g);
1573 int b = src.a * src.color.b * 31 / 255 + ((255 - src.a) * dest.b);
1574 if(r > 255 * 31) r = 255 * 31;
1575 if(g > 255 * 63) g = 255 * 63;
1576 if(b > 255 * 31) b = 255 * 31;
1577 *picture = { (byte)(r / 255), (byte)(g / 255), (byte)(b / 255) };
1579 picture += lfbSurface.bitmap.stride - w;
1580 source += src.stride - w;
1583 else if(lfbSurface.bitmap.pixelFormat == pixelFormat555)
1585 Color555 * picture = ((Color555 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
1586 for(y = 0; y < h; y++)
1588 for(x = 0; x < w; x++, picture++, source++)
1590 ColorAlpha psrc = *source;
1591 Color555 dest = *picture;
1592 int r = psrc.a * psrc.color.r * 31 / 255 + ((255 - psrc.a) * dest.r);
1593 int g = psrc.a * psrc.color.g * 31 / 255 + ((255 - psrc.a) * dest.g);
1594 int b = psrc.a * psrc.color.b * 31 / 255 + ((255 - psrc.a) * dest.b);
1595 if(r > 255 * 31) r = 255 * 31;
1596 if(g > 255 * 31) g = 255 * 31;
1597 if(b > 255 * 31) b = 255 * 31;
1598 *picture = { (byte)(r / 255), (byte)(g / 255), (byte)(b / 255) };
1600 picture += lfbSurface.bitmap.stride - w;
1601 source += src.stride - w;
1606 else if(src.paletteShades)
1607 shades_blit_table[lfbSurface.bitmap.pixelFormat][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h);
1608 else if(src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1609 blits_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h);
1610 else if(src.pixelFormat == pixelFormat8)
1611 blits_8bit_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h);
1615 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
1617 bool result = false;
1618 LFBDisplay lfbDisplay = display.driverData;
1620 if(bitmap.pixelFormat != lfbDisplay.bitmap.pixelFormat || bitmap.width < w || bitmap.height < h)
1623 bitmap.Allocate(null, w,h,w, lfbDisplay.bitmap.pixelFormat,
1624 (lfbDisplay.bitmap.pixelFormat == pixelFormat8)?true:false);
1628 Surface surface = bitmap.GetSurface(0,0,null);
1631 Blit(display, surface, lfbDisplay.bitmap, 0,0,x,y,w,h);
1632 if(bitmap.palette && lfbDisplay.bitmap.pixelFormat == pixelFormat8 && lfbDisplay.bitmap.palette)
1633 CopyBytesBy4(bitmap.palette, lfbDisplay.bitmap.palette, 256);
1641 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1643 LFBSurface lfbSurface = surface.driverData;
1646 float s2dw,s2dh,d2sw,d2sh;
1648 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return;
1650 if(Sgn(w) != Sgn(sw))
1662 //Clip against the edges of the source
1665 dx+=(int)((0-sx) * s2dw);
1666 w-=(int)((0-sx) * s2dw);
1672 dy+=(int)((0-sy) * s2dh);
1673 h-=(int)((0-sy) * s2dh);
1678 if(sx+sw>src.width-1)
1680 w-=(int)((sx+sw-(src.width-1)-1)*s2dw);
1681 sw-=sx+sw-(src.width-1)-1;
1683 if(sy+sh>(src.height-1))
1685 h-=(int)((sy+sh-(src.height-1)-1)*s2dh);
1686 sh-=sy+sh-(src.height-1)-1;
1688 //Clip against the edges of the destination
1689 if(dx<surface.box.left)
1691 if(!flip) sx+=(int)((surface.box.left-dx)*d2sw);
1692 sw-=(int)((surface.box.left-dx)*d2sw);
1693 w-=surface.box.left-dx;
1694 dx=surface.box.left;
1696 if(dy<surface.box.top)
1698 sy+=(int)((surface.box.top-dy)*d2sh);
1699 sh-=(int)((surface.box.top-dy)*d2sh);
1700 h-=surface.box.top-dy;
1703 if((dx+w)>surface.box.right)
1705 if(flip) sx+=(int)(((dx+w)-surface.box.right-1)*d2sw);
1706 sw-=(int)(((dx+w)-surface.box.right-1)*d2sw);
1707 w-=((dx+w)-surface.box.right-1);
1709 if((dy+h)>surface.box.bottom)
1711 sh-=(int)(((dy+h)-surface.box.bottom-1)*d2sh);
1712 h-=((dy+h)-surface.box.bottom-1);
1714 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
1716 dx+=surface.offset.x;
1717 dy+=surface.offset.y;
1719 if(lfbSurface.bitmap.picture)
1721 AlphaWriteMode alphaWrite = surface.alphaWrite;
1722 if(src.alphaBlend && surface.blend)
1726 uint adddest = lfbSurface.bitmap.stride, addsource = src.stride;
1727 ColorAlpha * backsrc;
1728 ColorAlpha * source = ((ColorAlpha *) src.picture) + sy * addsource + sx;
1729 ColorAlpha * dest = ((ColorAlpha *) lfbSurface.bitmap.picture) + dy * adddest + dx;
1730 if(flip) source += sw-1;
1748 ColorAlpha src = *source;
1749 ColorAlpha dst = *dest;
1750 int r = src.a * src.color.r / 255 + ((255 - src.a) * dst.color.r / 255);
1751 int g = src.a * src.color.g / 255 + ((255 - src.a) * dst.color.g / 255);
1752 int b = src.a * src.color.b / 255 + ((255 - src.a) * dst.color.b / 255);
1753 if(r > 255) r = 255;
1754 if(g > 255) g = 255;
1755 if(b > 255) b = 255;
1756 dest->color = { (byte)r, (byte)g, (byte)b };
1757 if(alphaWrite == blend)
1759 int a = src.a + ((255 - src.a) * dst.a / 255);
1760 if(a > 255) a = 255;
1773 source += addsource;
1776 else if(src.paletteShades)
1777 shades_stretch_table[lfbSurface.bitmap.pixelFormat][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1778 else if(src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1779 stretches_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1780 else if(src.pixelFormat == pixelFormat8 && lfbSurface.bitmap.pixelFormat != pixelFormatText)
1781 stretches_8bit_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1785 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1787 LFBSurface lfbSurface = surface.driverData;
1790 float s2dw,s2dh,d2sw,d2sh;
1792 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return;
1794 if(Sgn(w) != Sgn(sw))
1806 //Clip against the edges of the source
1809 dx+=(int)((0-sx) * s2dw);
1810 w-=(int)((0-sx) * s2dw);
1816 dy+=(int)((0-sy) * s2dh);
1817 h-=(int)((0-sy) * s2dh);
1822 if(sx+sw>src.width-1)
1824 w-=(int)((sx+sw-(src.width-1)-1)*s2dw);
1825 sw-=sx+sw-(src.width-1)-1;
1827 if(sy+sh>(src.height-1))
1829 h-=(int)((sy+sh-(src.height-1)-1)*s2dh);
1830 sh-=sy+sh-(src.height-1)-1;
1832 //Clip against the edges of the destination
1833 if(dx<surface.box.left)
1835 if(!flip) sx+=(int)((surface.box.left-dx)*d2sw);
1836 sw-=(int)((surface.box.left-dx)*d2sw);
1837 w-=surface.box.left-dx;
1838 dx=surface.box.left;
1840 if(dy<surface.box.top)
1842 sy+=(int)((surface.box.top-dy)*d2sh);
1843 sh-=(int)((surface.box.top-dy)*d2sh);
1844 h-=surface.box.top-dy;
1847 if((dx+w)>surface.box.right)
1849 if(flip) sx+=(int)(((dx+w)-surface.box.right-1)*d2sw);
1850 sw-=(int)(((dx+w)-surface.box.right-1)*d2sw);
1851 w-=((dx+w)-surface.box.right-1);
1853 if((dy+h)>surface.box.bottom)
1855 sh-=(int)(((dy+h)-surface.box.bottom-1)*d2sh);
1856 h-=((dy+h)-surface.box.bottom-1);
1858 if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
1860 dx+=surface.offset.x;
1861 dy+=surface.offset.y;
1863 if(lfbSurface.bitmap.picture)
1865 AlphaWriteMode alphaWrite = surface.alphaWrite;
1866 if(src.alphaBlend && surface.blend)
1868 uint adddest = lfbSurface.bitmap.stride, addsource = src.stride;
1869 ColorAlpha * source = ((ColorAlpha *) src.picture) + sy * addsource + sx;
1870 ColorAlpha * dest = ((ColorAlpha *) lfbSurface.bitmap.picture) + dy * adddest + dx;
1871 float scaleX = (float)sw / w;
1872 float scaleY = (float)sh / h;
1880 if (w > sw && h > sh)
1883 for (y = 0; y < h; y++)
1885 int y0 = y * sh / h;
1886 int y1 = Min(y0 + 1, sh - 1);
1887 float alpha = y * scaleY - y0;
1889 for(x = 0; x < w; x++, dest += 1)
1891 int x0 = x * sw / w;
1892 int x1 = Min(x0 + 1, sw - 1);
1893 float beta = x * scaleX - x0;
1894 ColorAlpha src00, src01, src10, src11;
1895 float a1,r1,g1,b1,a2,r2,g2,b2;
1897 src00 = source[y0 * src.stride + x0];
1898 src01 = source[y0 * src.stride + x1];
1899 src10 = source[y1 * src.stride + x0];
1900 src11 = source[y1 * src.stride + x1];
1901 a1 = (src00.a) * (1.0f - beta) + (src01.a) * beta;
1902 r1 = (src00.color.r) * (1.0f - beta) + (src01.color.r) * beta;
1903 g1 = (src00.color.g) * (1.0f - beta) + (src01.color.g) * beta;
1904 b1 = (src00.color.b) * (1.0f - beta) + (src01.color.b) * beta;
1905 a2 = (src10.a) * (1.0f - beta) + (src11.a) * beta;
1906 r2 = (src10.color.r) * (1.0f - beta) + (src11.color.r) * beta;
1907 g2 = (src10.color.g) * (1.0f - beta) + (src11.color.g) * beta;
1908 b2 = (src10.color.b) * (1.0f - beta) + (src11.color.b) * beta;
1909 a = a1 * (1.0f - alpha) + a2 * alpha;
1910 r = r1 * (1.0f - alpha) + r2 * alpha;
1911 g = g1 * (1.0f - alpha) + g2 * alpha;
1912 b = b1 * (1.0f - alpha) + b2 * alpha;
1914 ColorAlpha dst = *dest;
1915 int cr = (int)(a * r / 255 + ((255 - a) * dst.color.r / 255));
1916 int cg = (int)(a * g / 255 + ((255 - a) * dst.color.g / 255));
1917 int cb = (int)(a * b / 255 + ((255 - a) * dst.color.b / 255));
1918 if(cr > 255) cr = 255;
1919 if(cg > 255) cg = 255;
1920 if(cb > 255) cb = 255;
1921 dest->color = { (byte)cr, (byte)cg, (byte)cb };
1923 if(alphaWrite == blend)
1925 int ca = (int)(a + ((255 - a) * dst.a / 255));
1926 if(ca > 255) ca = 255;
1939 for (y = 0; y < h; y++)
1941 int y0 = Min((int)((y + 1) * scaleY), sh - 1);
1942 int y1 = Min(y0 + 1, sh - 1);
1944 for (x = 0; x < w; x++, dest += 1)
1946 int x0 = Min((int)((x + 1) * scaleX), sw - 1);
1947 int x1 = Min(x0 + 1, sw - 1);
1948 float a = 0, r = 0, g = 0, b = 0;
1951 for (i = y0; i <= y1; i++)
1952 for (j = x0; j <= x1; j++)
1954 ColorAlpha pixel = source[i * src.stride + j];
1966 ColorAlpha dst = *dest;
1967 int cr = (int)(a * r / 255 + ((255 - a) * dst.color.r / 255));
1968 int cg = (int)(a * g / 255 + ((255 - a) * dst.color.g / 255));
1969 int cb = (int)(a * b / 255 + ((255 - a) * dst.color.b / 255));
1970 if(cr > 255) cr = 255;
1971 if(cg > 255) cg = 255;
1972 if(cb > 255) cb = 255;
1973 dest->color = { (byte)cr, (byte)cg, (byte)cb };
1974 if(alphaWrite == blend)
1976 int ca = (int)(a + ((255 - a) * dst.a / 255));
1977 if(ca > 255) ca = 255;
1988 else if(!src.paletteShades && src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1989 filters_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1990 // Fail back on Stretch
1991 else if(src.paletteShades)
1992 shades_stretch_table[lfbSurface.bitmap.pixelFormat][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1993 else if(src.pixelFormat == lfbSurface.bitmap.pixelFormat)
1994 stretches_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
1995 else if(src.pixelFormat == pixelFormat8 && lfbSurface.bitmap.pixelFormat != pixelFormatText)
1996 stretches_8bit_table[lfbSurface.bitmap.pixelFormat][src.transparent][flip](src,lfbSurface.bitmap,dx,dy,sx,sy,w,h,sw,sh);
2000 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
2002 Blit(display, surface, src, dx, dy, sx, sy, w, h);
2005 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2007 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
2010 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
2012 Filter(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
2015 void UnloadFont(DisplaySystem displaySystem, Font font)
2020 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
2022 #ifndef ECERE_NOTRUETYPE
2023 return Font::Load(displaySystem, faceName, size, flags, outlineSize, outlineFade);
2029 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * adv)
2031 if(displaySystem && displaySystem.flags.text && len)
2036 *width = num * textCellW;
2038 if(height) *height = textCellH;
2040 #if !defined(ECERE_NOTRUETYPE)
2041 else if(font && len)
2045 int w = 0, advance = 0;
2046 font.ProcessString(displaySystem, (const byte *)text, len, false, null, null, &w, 0, prevGlyph, rPrevGlyph, &advance);
2047 if(adv) *adv = advance >> 6;
2048 //*width = (w + 64 - w % 64) >> 6;
2052 *height = font.height;
2057 if(width) *width = 0;
2058 if(height) *height = 0;
2062 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
2064 LFBSurface lfbSurface = surface.driverData;
2065 if(display && display.displaySystem.flags.text)
2067 LFBDisplay lfbDisplay = display.driverData;
2068 uint16 * coffset = (uint16 *)lfbDisplay.bitmap.picture;
2074 if(y > surface.box.bottom || y < surface.box.top)
2076 coffset += (y+surface.offset.y) * lfbSurface.bitmap.stride + x + surface.offset.x;
2077 for(c=0; (c<len && x < surface.box.left); c++, x++,coffset++);
2078 for(; (c<len && x <= surface.box.right); c++, x++,coffset++)
2080 if(surface.textOpacity)
2081 *coffset = (uint16) (lfbSurface.background|lfbSurface.foreground|text[c]);
2083 *coffset = (uint16) (((*coffset)&0xF000)|lfbSurface.foreground|text[c]);
2088 lfbSurface.writingText = true;
2089 #if !defined(ECERE_NOTRUETYPE)
2092 if(surface.font.outlineSize)
2094 ColorAlpha backForeground = surface.foreground;
2096 lfbSurface.writingOutline = true;
2097 surface.foreground = surface.outlineColor;
2098 lfbSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &fx, y, prevGlyph, rPrevGlyph, null);
2099 lfbSurface.writingOutline = false;
2100 surface.foreground = backForeground;
2103 lfbSurface.font.ProcessString(surface.displaySystem, (const byte *)text, len, true, surface, display, &x, y, prevGlyph, rPrevGlyph, null);
2105 lfbSurface.writingText = false;
2109 void TextFont(Display display, Surface surface, Font font)
2111 LFBSurface lfbSurface = surface.driverData;
2112 lfbSurface.font = font;
2115 void TextOpacity(Display display, Surface surface, bool opaque)
2120 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * advance)
2122 LFBSurface lfbSurface = surface.driverData;
2123 FontExtent(surface.displaySystem, lfbSurface.font, text, len, width, height, prevGlyph, rPrevGlyph, advance);
2126 void DrawingChar(Display display, Surface surface, byte character)
2128 LFBSurface lfbSurface = surface.driverData;
2129 lfbSurface.drawingChar = character;
2132 void LineStipple(Display display, Surface surface, uint32 stipple)
2134 LFBSurface lfbSurface = surface.driverData;
2135 lfbSurface.stipple = (uint16)stipple;
2138 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
2139 void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
2141 if(mesh.vertices && !mesh.flags.vertices)
2142 delete mesh.vertices;
2143 if(mesh.normals && !mesh.flags.normals)
2144 delete mesh.normals;
2145 if(mesh.texCoords && !mesh.flags.texCoords1)
2146 delete mesh.texCoords;
2147 if(mesh.tangents && !mesh.flags.tangents)
2148 delete mesh.tangents;
2149 if(mesh.colors && !mesh.flags.colors)
2151 if(mesh.lightVectors && !mesh.flags.lightVectors)
2152 delete mesh.lightVectors;
2155 bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
2157 bool result = false;
2158 if(mesh.nVertices == nVertices)
2161 // Same number of vertices, adding features (Leaves the other features pointers alone)
2162 if(mesh.flags != flags)
2164 if(!mesh.flags.vertices && flags.vertices)
2166 if(flags.doubleVertices)
2168 mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
2171 mesh.vertices = new Vector3Df[nVertices];
2173 if(!mesh.flags.normals && flags.normals)
2175 if(flags.doubleNormals)
2177 mesh.normals = (Vector3Df *)new Vector3D[nVertices];
2180 mesh.normals = new Vector3Df[nVertices];
2182 if(!mesh.flags.texCoords1 && flags.texCoords1)
2183 mesh.texCoords = new Pointf[nVertices];
2184 if(!mesh.flags.colors && flags.colors)
2185 mesh.colors = new ColorRGBAf[nVertices];
2191 // New number of vertices, reallocate all current and new features
2192 flags |= mesh.flags;
2195 if(flags.doubleVertices)
2197 mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
2200 mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
2204 if(flags.doubleNormals)
2206 mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
2209 mesh.normals = renew mesh.normals Vector3Df[nVertices];
2211 if(flags.texCoords1)
2212 mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
2214 mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
2219 bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures features)
2224 void FreeIndices(DisplaySystem displaySystem, uint16 * indices)
2229 uint16 * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
2231 return (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
2233 uint16 * LockIndices(DisplaySystem displaySystem, void * indices)