Code generator for 16bpp DIB Blt operations
Modified: trunk/reactos/Makefile
Modified: trunk/reactos/subsys/win32k/dib/dib16bpp.c
Modified: trunk/reactos/subsys/win32k/include/inteng.h
Modified: trunk/reactos/subsys/win32k/win32k.xml
Added: trunk/reactos/tools/gendib/
Added: trunk/reactos/tools/gendib/gendib.c
Added: trunk/reactos/tools/gendib/gendib.mak
Modified: trunk/reactos/tools/tools.mak

Modified: trunk/reactos/Makefile
--- trunk/reactos/Makefile	2005-07-05 17:08:48 UTC (rev 16429)
+++ trunk/reactos/Makefile	2005-07-05 17:08:58 UTC (rev 16430)
@@ -169,6 +169,7 @@
   ECHO_MKHIVE  =@echo $(QUOTE)[MKHIVE]   $@$(QUOTE)
   ECHO_REGTESTS=@echo $(QUOTE)[REGTESTS] $@$(QUOTE)
   ECHO_TEST    =@echo $(QUOTE)[TEST]     $@$(QUOTE)
+  ECHO_GENDIB  =@echo $(QUOTE)[GENDIB]   $@$(QUOTE)
 else
   ECHO_CP      =
   ECHO_MKDIR   =
@@ -196,6 +197,7 @@
   ECHO_MKHIVE  =
   ECHO_REGTESTS=
   ECHO_TEST    =
+  ECHO_GENDIB  =
 endif
 
 
@@ -297,7 +299,8 @@
 	$(BUGCODES_RC) \
 	$(ERRCODES_H) \
 	$(ERRCODES_RC) \
-	$(NCI_SERVICE_FILES)
+	$(NCI_SERVICE_FILES) \
+	$(GENDIB_DIB_FILES)
 
 makefile.auto: $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES)
 	$(ECHO_RBUILD)
Property changes on: trunk/reactos/subsys/win32k/dib
___________________________________________________________________
Name: svn:ignore
   - *.d
*.o
*.sym
   + *.d
*.o
*.sym
dib16gen.c

Modified: trunk/reactos/subsys/win32k/dib/dib16bpp.c
--- trunk/reactos/subsys/win32k/dib/dib16bpp.c	2005-07-05 17:08:48 UTC (rev 16429)
+++ trunk/reactos/subsys/win32k/dib/dib16bpp.c	2005-07-05 17:08:58 UTC (rev 16430)
@@ -16,7 +16,6 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id$ */
 
 #include <w32k.h>
 
@@ -337,99 +336,6 @@
   return TRUE;
 }
 
-BOOLEAN
-DIB_16BPP_BitBlt(PBLTINFO BltInfo)
-{
-   ULONG DestX, DestY;
-   ULONG SourceX, SourceY;
-   ULONG PatternY = 0;
-   ULONG Dest, Source = 0, Pattern = 0;
-   BOOL UsesSource;
-   BOOL UsesPattern;
-   PULONG DestBits;
-   ULONG RoundedRight;
-
-   UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
-   UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
-
-   RoundedRight = BltInfo->DestRect.right -
-                  ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 0x1);
-   SourceY = BltInfo->SourcePoint.y;
-   DestBits = (PULONG)(
-      (PBYTE)BltInfo->DestSurface->pvScan0 +
-      (BltInfo->DestRect.left << 1) +
-      BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
-
-   if (UsesPattern)
-   {
-      if (BltInfo->PatternSurface)
-      {
-         PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
-                    BltInfo->PatternSurface->sizlBitmap.cy;
-      }
-      else
-      {
-         Pattern = BltInfo->Brush->iSolidColor |
-                   (BltInfo->Brush->iSolidColor << 16);
-      }
-   }
-
-   for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
-   {
-      SourceX = BltInfo->SourcePoint.x;
-
-      for (DestX = BltInfo->DestRect.left; DestX < RoundedRight; DestX += 2, DestBits++, SourceX += 2)
-      {
-         Dest = *DestBits;
-
-         if (UsesSource)
-         {
-            Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
-            Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + 1, SourceY, BltInfo->XlateSourceToDest) << 16;
-         }
-
-         if (BltInfo->PatternSurface)
-	 {
-            Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
-            Pattern |= DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 1) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest) << 16;
-         }
-
-         *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
-      }
-
-      if (DestX < BltInfo->DestRect.right)
-      {
-         Dest = *((PUSHORT)DestBits);
-
-         if (UsesSource)
-         {
-            Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
-         }
-
-         if (BltInfo->PatternSurface)
-         {
-            Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
-         }
-
-         DIB_16BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFF);
-         DestBits = (PULONG)((ULONG_PTR)DestBits + 2);
-      }
-
-      SourceY++;
-      if (BltInfo->PatternSurface)
-      {
-         PatternY++;
-         PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
-      }
-      DestBits = (PULONG)(
-         (ULONG_PTR)DestBits -
-         ((BltInfo->DestRect.right - BltInfo->DestRect.left) << 1) +
-         BltInfo->DestSurface->lDelta);
-   }
-
-   return TRUE;
-}
-
 /* Optimize for bitBlt */
 BOOLEAN
 DIB_16BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)

Modified: trunk/reactos/subsys/win32k/include/inteng.h
--- trunk/reactos/subsys/win32k/include/inteng.h	2005-07-05 17:08:48 UTC (rev 16429)
+++ trunk/reactos/subsys/win32k/include/inteng.h	2005-07-05 17:08:58 UTC (rev 16430)
@@ -24,6 +24,8 @@
 #define R4_MASK ((R3_OPINDEX_NOOP << 8) | R3_OPINDEX_SRCCOPY)
 
 #define ROP2_TO_MIX(Rop2) (((Rop2) << 8) | (Rop2))
+#define ROP3_USES_DEST(Rop3)   ((((Rop3) & 0xAA0000) >> 1) != ((Rop3) & 0x550000))
+#define ROP4_USES_DEST(Rop4)   (((((Rop4) & 0xAA) >> 1) != ((Rop4) & 0x55)) || ((((Rop4) & 0xAA00) >> 1) != ((Rop4) & 0x5500)))
 #define ROP3_USES_SOURCE(Rop3) ((((Rop3) & 0xCC0000) >> 2) != ((Rop3) & 0x330000))
 #define ROP4_USES_SOURCE(Rop4) (((((Rop4) & 0xCC) >> 2) != ((Rop4) & 0x33)) || ((((Rop4) & 0xCC00) >> 2) != ((Rop4) & 0x3300)))
 #define ROP3_USES_PATTERN(Rop3) ((((Rop3) & 0xF00000) >> 4) != ((Rop3) & 0x0F0000))

Modified: trunk/reactos/subsys/win32k/win32k.xml
--- trunk/reactos/subsys/win32k/win32k.xml	2005-07-05 17:08:48 UTC (rev 16429)
+++ trunk/reactos/subsys/win32k/win32k.xml	2005-07-05 17:08:58 UTC (rev 16430)
@@ -15,6 +15,7 @@
 		<file>dib4bpp.c</file>
 		<file>dib8bpp.c</file>
 		<file>dib16bpp.c</file>
+		<file>dib16gen.c</file>
 		<file>dib24bpp.c</file>
 		<file>dib32bpp.c</file>
 		<file>dib.c</file>
Property changes on: trunk/reactos/tools/gendib
___________________________________________________________________
Name: svn:ignore
   + gendib
*.exe
*.sym
*.map

Added: trunk/reactos/tools/gendib/gendib.c
--- trunk/reactos/tools/gendib/gendib.c	2005-07-05 17:08:48 UTC (rev 16429)
+++ trunk/reactos/tools/gendib/gendib.c	2005-07-05 17:08:58 UTC (rev 16430)
@@ -0,0 +1,926 @@
+/*
+ *  Copyright 2005 Ge van Geldorp (gvg@reactos.com).
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * This is a code generator. It outputs C code which can be compiled using the
+ * standard build tools. It is used to generate code for the DIB Blt routines.
+ * There are a lot of possible Blt routines (256 rop codes, for 6 different
+ * bit depths). It is possible to use a generic Blt routine which handles all
+ * rop codes and all depths. The drawback is that it will be relatively slow.
+ * The other extreme is to write (generate) a separate Blt routine for each
+ * rop code/depth combination. This will result in a extremely large amount
+ * of code. So, we opt for something in between: named rops get their own
+ * routine, unnamed rops are handled by a generic routine.
+ * Basically, what happens is that generic code which looks like:
+ *
+ * for (...)
+ *   {
+ *     if (CondA)
+ *       {
+ *         doSomethingA;
+ *       }
+ *     for (...)
+ *       {
+ *         if (CondB)
+ *           {
+ *             doSomethingB;
+ *           }
+ *         else
+ *           {
+ *             doSomethingElseB;
+ *           }
+ *       }
+ *   }
+ *
+ * is specialized for named rops to look like:
+ *
+ * if (condC)
+ *   {
+ *     if (condD)
+ *       {
+ *         for (...)
+ *           {
+ *             for (...)
+ *               {
+ *                 pumpSomeBytes;
+ *               }
+ *           }
+ *       }
+ *     else
+ *       {
+ *         for (...)
+ *           {
+ *             for (...)
+ *               {
+ *                 pumpSomeBytesSlightlyDifferentE;
+ *               }
+ *           }
+ *       }
+ *   }
+ *
+ * i.e. we make the inner loops as tight as possible.
+ * Another optimization is to try to load/store 32 alligned bits at a time from
+ * video memory. Accessing video memory from the CPU is slooooooow, so let's
+ * try to do this as little as possible, even if that means we have to do some
+ * extra operations using main memory.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NDEBUG
+
+#define USES_DEST(RopCode)    ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55))
+#define USES_SOURCE(RopCode)  ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33))
+#define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f))
+
+#ifdef NDEBUG
+#define MARK(Out)
+#else
+#define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \
+                         __FUNCTION__, __LINE__);
+#endif
+
+#define ROPCODE_BLACKNESS   0x00
+#define ROPCODE_NOTSRCERASE 0x11
+#define ROPCODE_NOTSRCCOPY  0x33
+#define ROPCODE_SRCERASE    0x44
+#define ROPCODE_DSTINVERT   0x55
+#define ROPCODE_PATINVERT   0x5a
+#define ROPCODE_SRCINVERT   0x66
+#define ROPCODE_SRCAND      0x88
+#define ROPCODE_NOOP        0xaa
+#define ROPCODE_MERGEPAINT  0xbb
+#define ROPCODE_MERGECOPY   0xc0
+#define ROPCODE_SRCCOPY     0xcc
+#define ROPCODE_SRCPAINT    0xee
+#define ROPCODE_PATCOPY     0xf0
+#define ROPCODE_PATPAINT    0xfb
+#define ROPCODE_WHITENESS   0xff
+
+#define ROPCODE_GENERIC     256 /* Special case */
+
+typedef struct _ROPINFO
+  {
+    unsigned RopCode;
+    char *Name;
+    char *Operation;
+    int UsesDest;
+    int UsesSource;
+    int UsesPattern;
+  }
+ROPINFO, *PROPINFO;
+
+#define FLAG_PATTERNSURFACE      0x01
+#define FLAG_TRIVIALXLATE        0x02
+#define FLAG_BOTTOMUP            0x04
+#define FLAG_FORCENOUSESSOURCE   0x08
+#define FLAG_FORCERAWSOURCEAVAIL 0x10
+
+static PROPINFO
+FindRopInfo(unsigned RopCode)
+{
+  static ROPINFO KnownCodes[] =
+    {
+      { ROPCODE_BLACKNESS,   "BLACKNESS",  "0",            0, 0, 0 },
+      { ROPCODE_NOTSRCERASE, "NOTSRCERASE","~(D | S)",     1, 1, 0 },
+      { ROPCODE_NOTSRCCOPY,  "NOTSRCCOPY", "~S",           0, 1, 0 },
+      { ROPCODE_SRCERASE,    "SRCERASE",   "(~D) & S",     1, 1, 0 },
+      { ROPCODE_DSTINVERT,   "DSTINVERT",  "~D",           1, 0, 0 },
+      { ROPCODE_PATINVERT,   "PATINVERT",  "D ^ P",        1, 0, 1 },
+      { ROPCODE_SRCINVERT,   "SRCINVERT",  "D ^ S",        1, 1, 0 },
+      { ROPCODE_SRCAND,      "SRCAND",     "D & S",        1, 1, 0 },
+      { ROPCODE_NOOP,        "NOOP",       "D",            1, 0, 0 },
+      { ROPCODE_MERGEPAINT,  "MERGEPAINT", "D & (~S)",     1, 1, 0 },
+      { ROPCODE_MERGECOPY,   "MERGECOPY",  "S & P",        0, 1, 1 },
+      { ROPCODE_SRCCOPY,     "SRCCOPY",    "S",            0, 1, 0 },
+      { ROPCODE_SRCPAINT,    "SRCPAINT",   "D | S",        1, 1, 0 },
+      { ROPCODE_PATCOPY,     "PATCOPY",    "P",            0, 0, 1 },
+      { ROPCODE_PATPAINT,    "PATPAINT",   "D | (~S) | P", 1, 1, 1 },
+      { ROPCODE_WHITENESS,   "WHITENESS",  "0xffffffff",   0, 0, 0 },
+      { ROPCODE_GENERIC,     NULL,         NULL,           1, 1, 1 }
+    };
+  unsigned Index;
+
+  for (Index = 0; Index < sizeof(KnownCodes) / sizeof(KnownCodes[0]); Index++)
+    {
+      if (RopCode == KnownCodes[Index].RopCode)
+        {
+          return KnownCodes + Index;
+        }
+    }
+
+  return NULL;
+}
+
+static void
+Output(FILE *Out, char *Fmt, ...)
+{
+  static unsigned Indent = 0;
+  static int AtBOL = 1;
+  unsigned n;
+  va_list Args;
+
+  if (NULL != strchr(Fmt, '{') && 0 != Indent)
+    {
+      Indent += 2;
+    }
+  else if (NULL != strchr(Fmt, '}'))
+    {
+      Indent -= 2;
+    }
+  if (AtBOL)
+    {
+      for (n = 0; n < Indent; n++)
+        {
+          putc(' ', Out);
+        }
+      AtBOL = 0;
+    }
+
+  va_start(Args, Fmt);
+  vfprintf(Out, Fmt, Args);
+  va_end(Args);
+
+  if (NULL != strchr(Fmt, '{'))
+    {
+      Indent += 2;
+    }
+  else if (NULL != strchr(Fmt, '}') && 0 != Indent)
+    {
+      Indent -= 2;
+    }
+  AtBOL = '\n' == Fmt[strlen(Fmt) - 1];
+}
+
+static void
+PrintRoutineName(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
+{
+  if (NULL != RopInfo && ROPCODE_GENERIC != RopInfo->RopCode)
+    {
+      Output(Out, "DIB_%uBPP_BitBlt_%s", Bpp, RopInfo->Name);
+    }
+  else
+    {
+      Output(Out, "DIB_%uBPP_BitBlt_Generic", Bpp);
+    }
+}
+
+static void
+CreateShiftTables(FILE *Out)
+{
+  Output(Out, "\n");
+  Output(Out, "static unsigned Shift1Bpp[] =\n");
+  Output(Out, "{\n");
+  Output(Out, "0,\n");
+  Output(Out, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n");
+  Output(Out, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n");
+  Output(Out, "};\n");
+  Output(Out, "static unsigned Shift4Bpp[] =\n");
+  Output(Out, "{\n");
+  Output(Out, "0,\n");
+  Output(Out, "24, 28, 16, 20, 8, 12, 0, 4\n");
+  Output(Out, "};\n");
+  Output(Out, "static unsigned Shift8Bpp[] =\n");
+  Output(Out, "{\n");
+  Output(Out, "0,\n");
+  Output(Out, "24, 16, 8, 0\n");
+  Output(Out, "};\n");
+  Output(Out, "static unsigned Shift16Bpp[] =\n");
+  Output(Out, "{\n");
+  Output(Out, "0,\n");
+  Output(Out, "16, 0\n");
+  Output(Out, "};\n");
+}
+
+static void
+CreateOperation(FILE *Out, unsigned Bpp, PROPINFO RopInfo, unsigned SourceBpp,
+                unsigned Bits)
+{
+  char *Cast;
+  char *Dest;
+  char *Template;
+
+  MARK(Out);
+  if (32 == Bits)
+    {
+      Cast = "";
+      Dest = "*DestPtr";
+    }
+  else
+    {
+      Cast = "(USHORT) ";
+      Dest = "*((PUSHORT) DestPtr)";
+    }
+  Output(Out, "%s = ", Dest);
+  if (ROPCODE_GENERIC == RopInfo->RopCode)
+    {
+      Output(Out, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)",
+             Cast, Dest);
+    }
+  else
+    {
+      Template = RopInfo->Operation;
+      while ('\0' != *Template)
+        {
+          switch(*Template)
+            {
+            case 'S':
+              Output(Out, "%sSource", Cast);
+              break;
+            case 'P':
+              Output(Out, "%sPattern", Cast);
+              break;
+            case 'D':
+              Output(Out, "%s", Dest);
+              break;
+            default:
+              Output(Out, "%c", *Template);
+              break;
+            }
+          Template++;
+        }
+    }
+}
+
+static void
+CreateBase(FILE *Out, int Source, int Flags, unsigned Bpp)
+{
+  char *What = (Source ? "Source" : "Dest");
+
+  MARK(Out);
+  Output(Out, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What, What);
+  if (0 == (Flags & FLAG_BOTTOMUP))
+    {
+      if (Source)
+        {
+          Output(Out, "             BltInfo->SourcePoint.y *\n");
+        }
+      else
+        {
+          Output(Out, "           BltInfo->DestRect.top *\n");
+        }
+    }
+  else
+    {
+      if (Source)
+        {
+          Output(Out, "             (BltInfo->SourcePoint.y +\n");
+          Output(Out, "              BltInfo->DestRect.bottom -\n");
+          Output(Out, "              BltInfo->DestRect.top - 1) *\n");
+        }
+      else
+        {
+          Output(Out, "           (BltInfo->DestRect.bottom - 1) *\n");
+        }
+    }
+  Output(Out, "           %sBltInfo->%sSurface->lDelta +\n",
+         Source ? "  " : "", What);
+  if (Source)
+    {
+      Output(Out, "             %sBltInfo->SourcePoint.x",
+             16 < Bpp ? "" : "((");
+    }
+  else
+    {
+      Output(Out, "           BltInfo->DestRect.left");
+    }
+  if (Bpp < 8)
+    {
+      Output(Out, " / %u", 8 / Bpp);
+    }
+  else if (8 < Bpp)
+    {
+      Output(Out, " * %u", Bpp / 8);
+    }
+  if (Source && Bpp <= 16)
+    {
+      Output(Out, ") & ~ 0x3)");
+    }
+  Output(Out, ";\n", Bpp / 8);
+  if (Source && Bpp <= 16)
+    {
+      Output(Out, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n",
+             32 / Bpp, 32 / Bpp - 1);
+    }
+}
+
+static void
+CreateGetSource(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
+                unsigned SourceBpp, unsigned Shift)
+{
+  char *AssignOp;
+  char *Before;
+  char After[8];
+
+  MARK(Out);
+  if (0 == Shift)
+    {
+      AssignOp = "=";
+      Before = "";
+      After[0] = '\0';
+    }
+  else
+    {
+      AssignOp = "|=";
+      Before = "(";
+      sprintf(After, ") << %u", Shift);
+    }
+
+  if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
+      0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
+    {
+      if (0 == (Flags & FLAG_FORCERAWSOURCEAVAIL) && SourceBpp <= 16)
+        {
+          Output(Out, "if (0 == SourcePixels)\n");
+          Output(Out, "{\n");
+          Output(Out, "RawSource = *SourcePtr++;\n");
+          Output(Out, "SourcePixels = %u;\n", 32 / SourceBpp);
+          Output(Out, "}\n");
+        }
+      Output(Out, "Source %s (%s", AssignOp, Before);
+      if (0 == (Flags & FLAG_TRIVIALXLATE))
+        {
+          Output(Out, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s",
+                 16 < SourceBpp ? "" : "(");
+        }
+      if (32 == SourceBpp)
+        {
+          Output(Out, "*SourcePtr++");
+        }
+      else if (24 == SourceBpp)
+        {
+          Output(Out, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)");
+        }
+      else
+        {
+          Output(Out, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp);
+        }
+      if (0 == (Flags & FLAG_TRIVIALXLATE))
+        {
+          if (16 < SourceBpp)
+            {
+              Output(Out, ")");
+            }
+          else
+            {
+              Output(Out, ") & 0x%x)", (1 << SourceBpp) - 1);
+            }
+        }
+      Output(Out, " & 0xffff)%s;\n", After);
+      if (SourceBpp <= 16)
+        {
+          Output(Out, "SourcePixels--;\n");
+        }
+      else if (24 == SourceBpp)
+        {
+          Output(Out, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n");
+        }
+    }
+}
+
+static void
+CreateCounts(FILE *Out)
+{
+  MARK(Out);
+  Output(Out, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n");
+  Output(Out, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
+  Output(Out, "               LeftCount) / 2;\n");
+  Output(Out, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
+  Output(Out, "              LeftCount - 2 * CenterCount);\n");
+}
+
+static void
+CreateBitCase(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
+              unsigned SourceBpp)
+{
+  MARK(Out);
+  if (RopInfo->UsesSource)
+    {
+      if (0 == (Flags & FLAG_FORCENOUSESSOURCE))
+        {
+          CreateBase(Out, 1, Flags, SourceBpp);
+        }
+      CreateBase(Out, 0, Flags, Bpp);
+      CreateCounts(Out);
+      MARK(Out);
+    }
+  if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+    {
+      if (0 == (Flags & FLAG_BOTTOMUP))
+        {
+          Output(Out, "PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %%\n");
+          Output(Out, "           BltInfo->PatternSurface->sizlBitmap.cy;\n");
+        }
+      else
+        {
+          Output(Out, "PatternY = (BltInfo->DestRect.bottom - 1 +\n");
+          Output(Out, "            BltInfo->BrushOrigin.y) %%\n");
+          Output(Out, "           BltInfo->PatternSurface->sizlBitmap.cy;\n");
+        }
+    }
+  if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
+      0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
+    {
+      Output(Out, "CenterCount = 2 * (BltInfo->DestRect.right -\n");
+      Output(Out, "                   BltInfo->DestRect.left);\n");
+    }
+  Output(Out, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n");
+  Output(Out, "{\n");
+  if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
+      0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
+    {
+      if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+        {
+          Output(Out, "SourcePtr = (PULONG) SourceBase;\n");
+          if (SourceBpp <= 16)
+            {
+            Output(Out, "RawSource = *SourcePtr++;\n");
+            Output(Out, "SourcePixels = BaseSourcePixels;\n");
+            }
+        }
+      Output(Out, "DestPtr = (PULONG) DestBase;\n");
+    }
+  if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+    {
+      Output(Out, "PatternX = (BltInfo->DestRect.left + BltInfo->BrushOrigin.x) %%\n");
+      Output(Out, "           BltInfo->PatternSurface->sizlBitmap.cx;\n");
+    }
+  if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
+      0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
+    {
+      Output(Out, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n");
+      Output(Out, "\n");
+    }
+  else
+    {
+      Output(Out, "\n");
+      Output(Out, "if (0 != LeftCount)\n");
+      Output(Out, "{\n");
+      if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+        {
+          CreateGetSource(Out, Bpp, RopInfo, Flags | FLAG_FORCERAWSOURCEAVAIL,
+                          SourceBpp, 0);
+          MARK(Out);
+        }
+      if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+        {
+          Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
+          Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
+          Output(Out, "{\n");
+          Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
+          Output(Out, "}\n");
+        }
+      if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE) &&
+           Bpp != SourceBpp) ||
+          (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
+        {
+          Output(Out, "\n");
+        }
+      CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
+      Output(Out, ";\n");
+      MARK(Out);
+      Output(Out, "\n");
+      Output(Out, "DestPtr = (PULONG)((char *) DestPtr + 2);\n");
+      Output(Out, "}\n");
+      Output(Out, "\n");
+      Output(Out, "for (i = 0; i < CenterCount; i++)\n");
+      Output(Out, "{\n");
+      if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+        {
+          CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
+          CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 16);
+          MARK(Out);
+          Output(Out, "\n");
+        }
+      if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+        {
+          Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
+          Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
+          Output(Out, "{\n");
+          Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
+          Output(Out, "}\n");
+          Output(Out, "Pattern |= DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest) << 16;\n");
+          Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
+          Output(Out, "{\n");
+          Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
+          Output(Out, "}\n");
+          Output(Out, "\n");
+        }
+      CreateOperation(Out, Bpp, RopInfo, SourceBpp, 32);
+      Output(Out, ";\n");
+      MARK(Out);
+      Output(Out, "\n");
+      Output(Out, "DestPtr++;\n");
+      Output(Out, "}\n");
+      Output(Out, "\n");
+      Output(Out, "if (0 != RightCount)\n");
+      Output(Out, "{\n");
+      if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+        {
+          CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
+          MARK(Out);
+        }
+      if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+        {
+          Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
+        }
+      if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) ||
+          (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
+        {
+          Output(Out, "\n");
+        }
+      CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
+      Output(Out, ";\n");
+      MARK(Out);
+      Output(Out, "}\n");
+      Output(Out, "\n");
+      if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+        {
+          if (0 == (Flags & FLAG_BOTTOMUP))
+            {
+              Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n");
+              Output(Out, "{\n");
+              Output(Out, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n");
+              Output(Out, "}\n");
+            }
+          else
+            {
+              Output(Out, "if (0 == PatternY--)\n");
+              Output(Out, "{\n");
+              Output(Out, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n");
+              Output(Out, "}\n");
+            }
+        }
+    }
+  if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+    {
+      Output(Out, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n",
+             0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
+    }
+  Output(Out, "DestBase %c= BltInfo->DestSurface->lDelta;\n",
+         0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
+  Output(Out, "}\n");
+}
+
+static void
+CreateActionBlock(FILE *Out, unsigned Bpp, PROPINFO RopInfo,
+                  int Flags)
+{
+  static unsigned SourceBpp[ ] =
+    { 1, 4, 8, 16, 24, 32 };
+  unsigned BppIndex;
+
+  MARK(Out);
+  if (RopInfo->UsesSource)
+    {
+      if (ROPCODE_GENERIC == RopInfo->RopCode)
+        {
+          Output(Out, "if (UsesSource)\n");
+          Output(Out, "{\n");
+        }
+      Output(Out, "switch (BltInfo->SourceSurface->iBitmapFormat)\n");
+      Output(Out, "{\n");
+      for (BppIndex = 0;
+           BppIndex < sizeof(SourceBpp) / sizeof(unsigned);
+           BppIndex++)
+        {
+          Output(Out, "case BMF_%uBPP:\n", SourceBpp[BppIndex]);
+          Output(Out, "{\n");
+          if (Bpp == SourceBpp[BppIndex])
+            {
+              Output(Out, "if (NULL == BltInfo->XlateSourceToDest ||\n");
+              Output(Out, "    0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n");
+              Output(Out, "{\n");
+              Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
+              Output(Out, "{\n");
+              CreateBitCase(Out, Bpp, RopInfo,
+                            Flags | FLAG_TRIVIALXLATE,
+                            SourceBpp[BppIndex]);
+              MARK(Out);
+              Output(Out, "}\n");
+              Output(Out, "else\n");
+              Output(Out, "{\n");
+              CreateBitCase(Out, Bpp, RopInfo,
+                            Flags | FLAG_BOTTOMUP | FLAG_TRIVIALXLATE,
+                            SourceBpp[BppIndex]);
+              MARK(Out);
+              Output(Out, "}\n");
+              Output(Out, "}\n");
+              Output(Out, "else\n");
+              Output(Out, "{\n");
+              Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
+              Output(Out, "{\n");
+              CreateBitCase(Out, Bpp, RopInfo, Flags, SourceBpp[BppIndex]);
+              MARK(Out);
+              Output(Out, "}\n");
+              Output(Out, "else\n");
+              Output(Out, "{\n");
+              CreateBitCase(Out, Bpp, RopInfo,
+                            Flags | FLAG_BOTTOMUP,
+                            SourceBpp[BppIndex]);
+              MARK(Out);
+              Output(Out, "}\n");
+              Output(Out, "}\n");
+            }
+          else
+            {
+              CreateBitCase(Out, Bpp, RopInfo, Flags,
+                            SourceBpp[BppIndex]);
+              MARK(Out);
+            }
+          Output(Out, "break;\n");
+          Output(Out, "}\n");
+        }
+      Output(Out, "}\n");
+      if (ROPCODE_GENERIC == RopInfo->RopCode)
+        {
+          Output(Out, "}\n");
+          Output(Out, "else\n");
+          Output(Out, "{\n");
+          CreateBitCase(Out, Bpp, RopInfo, Flags | FLAG_FORCENOUSESSOURCE, 0);
+          MARK(Out);
+          Output(Out, "}\n");
+        }
+    }
+  else
+    {
+      CreateBitCase(Out, Bpp, RopInfo, Flags, 0);
+    }
+}
+
+static void
+CreatePrimitive(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
+{
+  int First;
+
+  MARK(Out);
+  Output(Out, "\n");
+  Output(Out, "static void\n");
+  PrintRoutineName(Out, Bpp, RopInfo);
+  Output(Out, "(PBLTINFO BltInfo)\n");
+  Output(Out, "{\n");
+  if (ROPCODE_BLACKNESS == RopInfo->RopCode)
+    {
+      Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
+                  "&BltInfo->DestRect, 0x0);\n", Bpp);
+    }
+  else if (ROPCODE_WHITENESS == RopInfo->RopCode)
+    {
+      Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
+                  "&BltInfo->DestRect, ~0);\n", Bpp);
+    }
+  else if (ROPCODE_NOOP == RopInfo->RopCode)
+    {
+      Output(Out, "return;\n");
+    }
+  else
+    {
+      Output(Out, "ULONG LineIndex, LineCount;\n");
+      Output(Out, "ULONG i;\n");
+#ifdef TODO
+      if (RopInfo->UsesSource)
+        {
+          Output(Out, "ULONG SourceX, SourceY;\n");
+        }
+#endif
+      if (RopInfo->UsesPattern)
+        {
+          Output(Out, "ULONG PatternX, PatternY = 0;\n");
+        }
+      First = 1;
+      if (RopInfo->UsesSource)
+        {
+          Output(Out, "ULONG Source = 0");
+          First = 0;
+        }
+      if (RopInfo->UsesPattern)
+        {
+          Output(Out, "%s Pattern = 0", First ? "ULONG" : ",");
+          First = 0;
+        }
+      if (! First)
+        {
+          Output(Out, ";\n");
+        }
+      Output(Out, "char *DestBase;\n");
+      Output(Out, "PULONG DestPtr;\n");
+      if (RopInfo->UsesSource)
+        {
+          Output(Out, "char *SourceBase;\n");
+          Output(Out, "PULONG SourcePtr;\n");
+          Output(Out, "ULONG RawSource;\n");
+          Output(Out, "unsigned SourcePixels, BaseSourcePixels;\n");
+        }
+      Output(Out, "ULONG LeftCount, CenterCount, RightCount;\n");
+      if (ROPCODE_GENERIC == RopInfo->RopCode)
+        {
+          Output(Out, "BOOLEAN UsesDest, UsesSource, UsesPattern;\n");
+          Output(Out, "\n");
+          Output(Out, "UsesDest = ROP4_USES_DEST(BltInfo->Rop4);\n");
+          Output(Out, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n");
+          Output(Out, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n");
+        }
+      Output(Out, "\n");
+      if (! RopInfo->UsesSource)
+        {
+          CreateBase(Out, 0, 0, Bpp);
+          CreateCounts(Out);
+          MARK(Out);
+        }
+      Output(Out, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n");
+    
+      Output(Out, "\n");
+      if (RopInfo->UsesPattern)
+        {
+          if (ROPCODE_GENERIC == RopInfo->RopCode)
+            {
+              Output(Out, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n");
+            }
+          else
+            {
+              Output(Out, "if (NULL != BltInfo->PatternSurface)\n");
+            }
+          Output(Out, "{\n");
+          CreateActionBlock(Out, Bpp, RopInfo, FLAG_PATTERNSURFACE);
+          MARK(Out);
+          Output(Out, "}\n");
+          Output(Out, "else\n");
+          Output(Out, "{\n");
+          if (ROPCODE_GENERIC == RopInfo->RopCode)
+            {
+              Output(Out, "if (UsesPattern)\n");
+              Output(Out, "{\n");
+            }
+          Output(Out, "Pattern = BltInfo->Brush->iSolidColor |\n");
[truncated at 1000 lines; 191 more skipped]