ff94bd310fd699369ee2ff81a6896843a2d8ec2c
[reactos.git] / reactos / tools / gendib / gendib.c
1 /*
2 * Copyright 2005 Ge van Geldorp (gvg@reactos.com).
3 *
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the
6 * Free Software Foundation; either version 2.1 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 /*
19 * This is a code generator. It outputs C code which can be compiled using the
20 * standard build tools. It is used to generate code for the DIB Blt routines.
21 * There are a lot of possible Blt routines (256 rop codes, for 6 different
22 * bit depths). It is possible to use a generic Blt routine which handles all
23 * rop codes and all depths. The drawback is that it will be relatively slow.
24 * The other extreme is to write (generate) a separate Blt routine for each
25 * rop code/depth combination. This will result in a extremely large amount
26 * of code. So, we opt for something in between: named rops get their own
27 * routine, unnamed rops are handled by a generic routine.
28 * Basically, what happens is that generic code which looks like:
29 *
30 * for (...)
31 * {
32 * if (CondA)
33 * {
34 * doSomethingA;
35 * }
36 * for (...)
37 * {
38 * if (CondB)
39 * {
40 * doSomethingB;
41 * }
42 * else
43 * {
44 * doSomethingElseB;
45 * }
46 * }
47 * }
48 *
49 * is specialized for named rops to look like:
50 *
51 * if (condC)
52 * {
53 * if (condD)
54 * {
55 * for (...)
56 * {
57 * for (...)
58 * {
59 * pumpSomeBytes;
60 * }
61 * }
62 * }
63 * else
64 * {
65 * for (...)
66 * {
67 * for (...)
68 * {
69 * pumpSomeBytesSlightlyDifferentE;
70 * }
71 * }
72 * }
73 * }
74 *
75 * i.e. we make the inner loops as tight as possible.
76 * Another optimization is to try to load/store 32 alligned bits at a time from
77 * video memory. Accessing video memory from the CPU is slooooooow, so let's
78 * try to do this as little as possible, even if that means we have to do some
79 * extra operations using main memory.
80 */
81
82 #include <stdarg.h>
83 #include <stdio.h>
84 #include <stdlib.h>
85 #include <string.h>
86
87 #define NDEBUG
88
89 #define USES_DEST(RopCode) ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55))
90 #define USES_SOURCE(RopCode) ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33))
91 #define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f))
92
93 #ifdef NDEBUG
94 #define MARK(Out)
95 #else
96 #define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \
97 __FUNCTION__, __LINE__);
98 #endif
99
100 #define ROPCODE_BLACKNESS 0x00
101 #define ROPCODE_NOTSRCERASE 0x11
102 #define ROPCODE_NOTSRCCOPY 0x33
103 #define ROPCODE_SRCERASE 0x44
104 #define ROPCODE_DSTINVERT 0x55
105 #define ROPCODE_PATINVERT 0x5a
106 #define ROPCODE_SRCINVERT 0x66
107 #define ROPCODE_SRCAND 0x88
108 #define ROPCODE_NOOP 0xaa
109 #define ROPCODE_MERGEPAINT 0xbb
110 #define ROPCODE_MERGECOPY 0xc0
111 #define ROPCODE_SRCCOPY 0xcc
112 #define ROPCODE_SRCPAINT 0xee
113 #define ROPCODE_PATCOPY 0xf0
114 #define ROPCODE_PATPAINT 0xfb
115 #define ROPCODE_WHITENESS 0xff
116
117 #define ROPCODE_GENERIC 256 /* Special case */
118
119 typedef struct _ROPINFO
120 {
121 unsigned RopCode;
122 char *Name;
123 char *Operation;
124 int UsesDest;
125 int UsesSource;
126 int UsesPattern;
127 }
128 ROPINFO, *PROPINFO;
129
130 #define FLAG_PATTERNSURFACE 0x01
131 #define FLAG_TRIVIALXLATE 0x02
132 #define FLAG_BOTTOMUP 0x04
133 #define FLAG_FORCENOUSESSOURCE 0x08
134 #define FLAG_FORCERAWSOURCEAVAIL 0x10
135
136 static PROPINFO
137 FindRopInfo(unsigned RopCode)
138 {
139 static ROPINFO KnownCodes[] =
140 {
141 { ROPCODE_BLACKNESS, "BLACKNESS", "0", 0, 0, 0 },
142 { ROPCODE_NOTSRCERASE, "NOTSRCERASE","~(D | S)", 1, 1, 0 },
143 { ROPCODE_NOTSRCCOPY, "NOTSRCCOPY", "~S", 0, 1, 0 },
144 { ROPCODE_SRCERASE, "SRCERASE", "(~D) & S", 1, 1, 0 },
145 { ROPCODE_DSTINVERT, "DSTINVERT", "~D", 1, 0, 0 },
146 { ROPCODE_PATINVERT, "PATINVERT", "D ^ P", 1, 0, 1 },
147 { ROPCODE_SRCINVERT, "SRCINVERT", "D ^ S", 1, 1, 0 },
148 { ROPCODE_SRCAND, "SRCAND", "D & S", 1, 1, 0 },
149 { ROPCODE_NOOP, "NOOP", "D", 1, 0, 0 },
150 { ROPCODE_MERGEPAINT, "MERGEPAINT", "D & (~S)", 1, 1, 0 },
151 { ROPCODE_MERGECOPY, "MERGECOPY", "S & P", 0, 1, 1 },
152 { ROPCODE_SRCCOPY, "SRCCOPY", "S", 0, 1, 0 },
153 { ROPCODE_SRCPAINT, "SRCPAINT", "D | S", 1, 1, 0 },
154 { ROPCODE_PATCOPY, "PATCOPY", "P", 0, 0, 1 },
155 { ROPCODE_PATPAINT, "PATPAINT", "D | (~S) | P", 1, 1, 1 },
156 { ROPCODE_WHITENESS, "WHITENESS", "0xffffffff", 0, 0, 0 },
157 { ROPCODE_GENERIC, NULL, NULL, 1, 1, 1 }
158 };
159 unsigned Index;
160
161 for (Index = 0; Index < sizeof(KnownCodes) / sizeof(KnownCodes[0]); Index++)
162 {
163 if (RopCode == KnownCodes[Index].RopCode)
164 {
165 return KnownCodes + Index;
166 }
167 }
168
169 return NULL;
170 }
171
172 static void
173 Output(FILE *Out, char *Fmt, ...)
174 {
175 static unsigned Indent = 0;
176 static int AtBOL = 1;
177 unsigned n;
178 va_list Args;
179
180 if (NULL != strchr(Fmt, '{') && 0 != Indent)
181 {
182 Indent += 2;
183 }
184 else if (NULL != strchr(Fmt, '}'))
185 {
186 Indent -= 2;
187 }
188 if (AtBOL)
189 {
190 for (n = 0; n < Indent; n++)
191 {
192 putc(' ', Out);
193 }
194 AtBOL = 0;
195 }
196
197 va_start(Args, Fmt);
198 vfprintf(Out, Fmt, Args);
199 va_end(Args);
200
201 if (NULL != strchr(Fmt, '{'))
202 {
203 Indent += 2;
204 }
205 else if (NULL != strchr(Fmt, '}') && 0 != Indent)
206 {
207 Indent -= 2;
208 }
209 AtBOL = '\n' == Fmt[strlen(Fmt) - 1];
210 }
211
212 static void
213 PrintRoutineName(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
214 {
215 if (NULL != RopInfo && ROPCODE_GENERIC != RopInfo->RopCode)
216 {
217 Output(Out, "DIB_%uBPP_BitBlt_%s", Bpp, RopInfo->Name);
218 }
219 else
220 {
221 Output(Out, "DIB_%uBPP_BitBlt_Generic", Bpp);
222 }
223 }
224
225 static void
226 CreateShiftTables(FILE *Out)
227 {
228 Output(Out, "\n");
229 Output(Out, "static unsigned Shift1Bpp[] =\n");
230 Output(Out, "{\n");
231 Output(Out, "0,\n");
232 Output(Out, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n");
233 Output(Out, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n");
234 Output(Out, "};\n");
235 Output(Out, "static unsigned Shift4Bpp[] =\n");
236 Output(Out, "{\n");
237 Output(Out, "0,\n");
238 Output(Out, "24, 28, 16, 20, 8, 12, 0, 4\n");
239 Output(Out, "};\n");
240 Output(Out, "static unsigned Shift8Bpp[] =\n");
241 Output(Out, "{\n");
242 Output(Out, "0,\n");
243 Output(Out, "24, 16, 8, 0\n");
244 Output(Out, "};\n");
245 Output(Out, "static unsigned Shift16Bpp[] =\n");
246 Output(Out, "{\n");
247 Output(Out, "0,\n");
248 Output(Out, "16, 0\n");
249 Output(Out, "};\n");
250 }
251
252 static void
253 CreateOperation(FILE *Out, unsigned Bpp, PROPINFO RopInfo, unsigned SourceBpp,
254 unsigned Bits)
255 {
256 char *Cast;
257 char *Dest;
258 char *Template;
259
260 MARK(Out);
261 if (32 == Bits)
262 {
263 Cast = "";
264 Dest = "*DestPtr";
265 }
266 else
267 {
268 Cast = "(USHORT) ";
269 Dest = "*((PUSHORT) DestPtr)";
270 }
271 Output(Out, "%s = ", Dest);
272 if (ROPCODE_GENERIC == RopInfo->RopCode)
273 {
274 Output(Out, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)",
275 Cast, Dest);
276 }
277 else
278 {
279 Template = RopInfo->Operation;
280 while ('\0' != *Template)
281 {
282 switch(*Template)
283 {
284 case 'S':
285 Output(Out, "%sSource", Cast);
286 break;
287 case 'P':
288 Output(Out, "%sPattern", Cast);
289 break;
290 case 'D':
291 Output(Out, "%s", Dest);
292 break;
293 default:
294 Output(Out, "%c", *Template);
295 break;
296 }
297 Template++;
298 }
299 }
300 }
301
302 static void
303 CreateBase(FILE *Out, int Source, int Flags, unsigned Bpp)
304 {
305 char *What = (Source ? "Source" : "Dest");
306
307 MARK(Out);
308 Output(Out, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What, What);
309 if (0 == (Flags & FLAG_BOTTOMUP))
310 {
311 if (Source)
312 {
313 Output(Out, " BltInfo->SourcePoint.y *\n");
314 }
315 else
316 {
317 Output(Out, " BltInfo->DestRect.top *\n");
318 }
319 }
320 else
321 {
322 if (Source)
323 {
324 Output(Out, " (BltInfo->SourcePoint.y +\n");
325 Output(Out, " BltInfo->DestRect.bottom -\n");
326 Output(Out, " BltInfo->DestRect.top - 1) *\n");
327 }
328 else
329 {
330 Output(Out, " (BltInfo->DestRect.bottom - 1) *\n");
331 }
332 }
333 Output(Out, " %sBltInfo->%sSurface->lDelta +\n",
334 Source ? " " : "", What);
335 if (Source)
336 {
337 Output(Out, " %sBltInfo->SourcePoint.x",
338 16 < Bpp ? "" : "((");
339 }
340 else
341 {
342 Output(Out, " BltInfo->DestRect.left");
343 }
344 if (Bpp < 8)
345 {
346 Output(Out, " / %u", 8 / Bpp);
347 }
348 else if (8 < Bpp)
349 {
350 Output(Out, " * %u", Bpp / 8);
351 }
352 if (Source && Bpp <= 16)
353 {
354 Output(Out, ") & ~ 0x3)");
355 }
356 Output(Out, ";\n", Bpp / 8);
357 if (Source && Bpp <= 16)
358 {
359 Output(Out, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n",
360 32 / Bpp, 32 / Bpp - 1);
361 }
362 }
363
364 static void
365 CreateGetSource(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
366 unsigned SourceBpp, unsigned Shift)
367 {
368 char *AssignOp;
369 char *Before;
370 char After[8];
371
372 MARK(Out);
373 if (0 == Shift)
374 {
375 AssignOp = "=";
376 Before = "";
377 After[0] = '\0';
378 }
379 else
380 {
381 AssignOp = "|=";
382 Before = "(";
383 sprintf(After, ") << %u", Shift);
384 }
385
386 if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
387 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
388 {
389 if (0 == (Flags & FLAG_FORCERAWSOURCEAVAIL) && SourceBpp <= 16)
390 {
391 Output(Out, "if (0 == SourcePixels)\n");
392 Output(Out, "{\n");
393 Output(Out, "RawSource = *SourcePtr++;\n");
394 Output(Out, "SourcePixels = %u;\n", 32 / SourceBpp);
395 Output(Out, "}\n");
396 }
397 Output(Out, "Source %s (%s", AssignOp, Before);
398 if (0 == (Flags & FLAG_TRIVIALXLATE))
399 {
400 Output(Out, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s",
401 16 < SourceBpp ? "" : "(");
402 }
403 if (32 == SourceBpp)
404 {
405 Output(Out, "*SourcePtr++");
406 }
407 else if (24 == SourceBpp)
408 {
409 Output(Out, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)");
410 }
411 else
412 {
413 Output(Out, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp);
414 }
415 if (0 == (Flags & FLAG_TRIVIALXLATE))
416 {
417 if (16 < SourceBpp)
418 {
419 Output(Out, ")");
420 }
421 else
422 {
423 Output(Out, ") & 0x%x)", (1 << SourceBpp) - 1);
424 }
425 }
426 Output(Out, " & 0xffff)%s;\n", After);
427 if (SourceBpp <= 16)
428 {
429 Output(Out, "SourcePixels--;\n");
430 }
431 else if (24 == SourceBpp)
432 {
433 Output(Out, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n");
434 }
435 }
436 }
437
438 static void
439 CreateCounts(FILE *Out)
440 {
441 MARK(Out);
442 Output(Out, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n");
443 Output(Out, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
444 Output(Out, " LeftCount) / 2;\n");
445 Output(Out, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
446 Output(Out, " LeftCount - 2 * CenterCount);\n");
447 }
448
449 static void
450 CreateBitCase(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
451 unsigned SourceBpp)
452 {
453 MARK(Out);
454 if (RopInfo->UsesSource)
455 {
456 if (0 == (Flags & FLAG_FORCENOUSESSOURCE))
457 {
458 CreateBase(Out, 1, Flags, SourceBpp);
459 }
460 CreateBase(Out, 0, Flags, Bpp);
461 CreateCounts(Out);
462 MARK(Out);
463 }
464 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
465 {
466 if (0 == (Flags & FLAG_BOTTOMUP))
467 {
468 Output(Out, "PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %%\n");
469 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
470 }
471 else
472 {
473 Output(Out, "PatternY = (BltInfo->DestRect.bottom - 1 +\n");
474 Output(Out, " BltInfo->BrushOrigin.y) %%\n");
475 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
476 }
477 }
478 if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
479 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
480 {
481 Output(Out, "CenterCount = 2 * (BltInfo->DestRect.right -\n");
482 Output(Out, " BltInfo->DestRect.left);\n");
483 }
484 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
485 {
486 Output(Out, "BasePatternX = (BltInfo->DestRect.left + BltInfo->BrushOrigin.x) %%\n");
487 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cx;\n");
488 }
489
490 Output(Out, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n");
491 Output(Out, "{\n");
492 if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
493 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
494 {
495 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
496 {
497 Output(Out, "SourcePtr = (PULONG) SourceBase;\n");
498 if (SourceBpp <= 16)
499 {
500 Output(Out, "RawSource = *SourcePtr++;\n");
501 Output(Out, "SourcePixels = BaseSourcePixels;\n");
502 }
503 }
504 Output(Out, "DestPtr = (PULONG) DestBase;\n");
505 }
506
507 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
508 {
509 Output(Out, "PatternX = BasePatternX;\n");
510 }
511
512 if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
513 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
514 {
515 Output(Out, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n");
516 Output(Out, "\n");
517 }
518 else
519 {
520 Output(Out, "\n");
521 Output(Out, "if (0 != LeftCount)\n");
522 Output(Out, "{\n");
523 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
524 {
525 CreateGetSource(Out, Bpp, RopInfo, Flags | FLAG_FORCERAWSOURCEAVAIL,
526 SourceBpp, 0);
527 MARK(Out);
528 }
529 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
530 {
531 Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
532 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
533 Output(Out, "{\n");
534 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
535 Output(Out, "}\n");
536 }
537 if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE) &&
538 Bpp != SourceBpp) ||
539 (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
540 {
541 Output(Out, "\n");
542 }
543 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
544 Output(Out, ";\n");
545 MARK(Out);
546 Output(Out, "\n");
547 Output(Out, "DestPtr = (PULONG)((char *) DestPtr + 2);\n");
548 Output(Out, "}\n");
549 Output(Out, "\n");
550 Output(Out, "for (i = 0; i < CenterCount; i++)\n");
551 Output(Out, "{\n");
552 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
553 {
554 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
555 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 16);
556 MARK(Out);
557 Output(Out, "\n");
558 }
559 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
560 {
561 Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
562 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
563 Output(Out, "{\n");
564 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
565 Output(Out, "}\n");
566 Output(Out, "Pattern |= DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest) << 16;\n");
567 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
568 Output(Out, "{\n");
569 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
570 Output(Out, "}\n");
571 Output(Out, "\n");
572 }
573 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 32);
574 Output(Out, ";\n");
575 MARK(Out);
576 Output(Out, "\n");
577 Output(Out, "DestPtr++;\n");
578 Output(Out, "}\n");
579 Output(Out, "\n");
580 Output(Out, "if (0 != RightCount)\n");
581 Output(Out, "{\n");
582 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
583 {
584 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
585 MARK(Out);
586 }
587 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
588 {
589 Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
590 }
591 if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) ||
592 (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
593 {
594 Output(Out, "\n");
595 }
596 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
597 Output(Out, ";\n");
598 MARK(Out);
599 Output(Out, "}\n");
600 Output(Out, "\n");
601 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
602 {
603 if (0 == (Flags & FLAG_BOTTOMUP))
604 {
605 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n");
606 Output(Out, "{\n");
607 Output(Out, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n");
608 Output(Out, "}\n");
609 }
610 else
611 {
612 Output(Out, "if (0 == PatternY--)\n");
613 Output(Out, "{\n");
614 Output(Out, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n");
615 Output(Out, "}\n");
616 }
617 }
618 }
619 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
620 {
621 Output(Out, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n",
622 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
623 }
624 Output(Out, "DestBase %c= BltInfo->DestSurface->lDelta;\n",
625 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
626 Output(Out, "}\n");
627 }
628
629 static void
630 CreateActionBlock(FILE *Out, unsigned Bpp, PROPINFO RopInfo,
631 int Flags)
632 {
633 static unsigned SourceBpp[ ] =
634 { 1, 4, 8, 16, 24, 32 };
635 unsigned BppIndex;
636
637 MARK(Out);
638 if (RopInfo->UsesSource)
639 {
640 if (ROPCODE_GENERIC == RopInfo->RopCode)
641 {
642 Output(Out, "if (UsesSource)\n");
643 Output(Out, "{\n");
644 }
645 Output(Out, "switch (BltInfo->SourceSurface->iBitmapFormat)\n");
646 Output(Out, "{\n");
647 for (BppIndex = 0;
648 BppIndex < sizeof(SourceBpp) / sizeof(unsigned);
649 BppIndex++)
650 {
651 Output(Out, "case BMF_%uBPP:\n", SourceBpp[BppIndex]);
652 Output(Out, "{\n");
653 if (Bpp == SourceBpp[BppIndex])
654 {
655 Output(Out, "if (NULL == BltInfo->XlateSourceToDest ||\n");
656 Output(Out, " 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n");
657 Output(Out, "{\n");
658 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
659 Output(Out, "{\n");
660 CreateBitCase(Out, Bpp, RopInfo,
661 Flags | FLAG_TRIVIALXLATE,
662 SourceBpp[BppIndex]);
663 MARK(Out);
664 Output(Out, "}\n");
665 Output(Out, "else\n");
666 Output(Out, "{\n");
667 CreateBitCase(Out, Bpp, RopInfo,
668 Flags | FLAG_BOTTOMUP | FLAG_TRIVIALXLATE,
669 SourceBpp[BppIndex]);
670 MARK(Out);
671 Output(Out, "}\n");
672 Output(Out, "}\n");
673 Output(Out, "else\n");
674 Output(Out, "{\n");
675 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
676 Output(Out, "{\n");
677 CreateBitCase(Out, Bpp, RopInfo, Flags, SourceBpp[BppIndex]);
678 MARK(Out);
679 Output(Out, "}\n");
680 Output(Out, "else\n");
681 Output(Out, "{\n");
682 CreateBitCase(Out, Bpp, RopInfo,
683 Flags | FLAG_BOTTOMUP,
684 SourceBpp[BppIndex]);
685 MARK(Out);
686 Output(Out, "}\n");
687 Output(Out, "}\n");
688 }
689 else
690 {
691 CreateBitCase(Out, Bpp, RopInfo, Flags,
692 SourceBpp[BppIndex]);
693 MARK(Out);
694 }
695 Output(Out, "break;\n");
696 Output(Out, "}\n");
697 }
698 Output(Out, "}\n");
699 if (ROPCODE_GENERIC == RopInfo->RopCode)
700 {
701 Output(Out, "}\n");
702 Output(Out, "else\n");
703 Output(Out, "{\n");
704 CreateBitCase(Out, Bpp, RopInfo, Flags | FLAG_FORCENOUSESSOURCE, 0);
705 MARK(Out);
706 Output(Out, "}\n");
707 }
708 }
709 else
710 {
711 CreateBitCase(Out, Bpp, RopInfo, Flags, 0);
712 }
713 }
714
715 static void
716 CreatePrimitive(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
717 {
718 int First;
719
720 MARK(Out);
721 Output(Out, "\n");
722 Output(Out, "static void\n");
723 PrintRoutineName(Out, Bpp, RopInfo);
724 Output(Out, "(PBLTINFO BltInfo)\n");
725 Output(Out, "{\n");
726 if (ROPCODE_BLACKNESS == RopInfo->RopCode)
727 {
728 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
729 "&BltInfo->DestRect, 0x0);\n", Bpp);
730 }
731 else if (ROPCODE_WHITENESS == RopInfo->RopCode)
732 {
733 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
734 "&BltInfo->DestRect, ~0);\n", Bpp);
735 }
736 else if (ROPCODE_NOOP == RopInfo->RopCode)
737 {
738 Output(Out, "return;\n");
739 }
740 else
741 {
742 Output(Out, "ULONG LineIndex, LineCount;\n");
743 Output(Out, "ULONG i;\n");
744 #ifdef TODO
745 if (RopInfo->UsesSource)
746 {
747 Output(Out, "ULONG SourceX, SourceY;\n");
748 }
749 #endif
750 if (RopInfo->UsesPattern)
751 {
752 Output(Out, "ULONG PatternX =0, PatternY = 0, BasePatternX = 0;\n");
753 }
754 First = 1;
755 if (RopInfo->UsesSource)
756 {
757 Output(Out, "ULONG Source = 0");
758 First = 0;
759 }
760 if (RopInfo->UsesPattern)
761 {
762 Output(Out, "%s Pattern = 0", First ? "ULONG" : ",");
763 First = 0;
764 }
765 if (! First)
766 {
767 Output(Out, ";\n");
768 }
769 Output(Out, "char *DestBase;\n");
770 Output(Out, "PULONG DestPtr;\n");
771 if (RopInfo->UsesSource)
772 {
773 Output(Out, "char *SourceBase;\n");
774 Output(Out, "PULONG SourcePtr;\n");
775 Output(Out, "ULONG RawSource;\n");
776 Output(Out, "unsigned SourcePixels, BaseSourcePixels;\n");
777 }
778 Output(Out, "ULONG LeftCount, CenterCount, RightCount;\n");
779 if (ROPCODE_GENERIC == RopInfo->RopCode)
780 {
781 Output(Out, "BOOLEAN UsesDest, UsesSource, UsesPattern;\n");
782 Output(Out, "\n");
783 Output(Out, "UsesDest = ROP4_USES_DEST(BltInfo->Rop4);\n");
784 Output(Out, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n");
785 Output(Out, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n");
786 }
787 Output(Out, "\n");
788 if (! RopInfo->UsesSource)
789 {
790 CreateBase(Out, 0, 0, Bpp);
791 CreateCounts(Out);
792 MARK(Out);
793 }
794 Output(Out, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n");
795
796 Output(Out, "\n");
797 if (RopInfo->UsesPattern)
798 {
799 if (ROPCODE_GENERIC == RopInfo->RopCode)
800 {
801 Output(Out, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n");
802 }
803 else
804 {
805 Output(Out, "if (NULL != BltInfo->PatternSurface)\n");
806 }
807 Output(Out, "{\n");
808 CreateActionBlock(Out, Bpp, RopInfo, FLAG_PATTERNSURFACE);
809 MARK(Out);
810 Output(Out, "}\n");
811 Output(Out, "else\n");
812 Output(Out, "{\n");
813 if (ROPCODE_GENERIC == RopInfo->RopCode)
814 {
815 Output(Out, "if (UsesPattern)\n");
816 Output(Out, "{\n");
817 }
818 Output(Out, "Pattern = BltInfo->Brush->iSolidColor |\n");
819 Output(Out, " (BltInfo->Brush->iSolidColor << 16);\n");
820 if (ROPCODE_PATINVERT == RopInfo->RopCode ||
821 ROPCODE_MERGECOPY == RopInfo->RopCode)
822 {
823 Output(Out, "if (0 == Pattern)\n");
824 Output(Out, "{\n");
825 if (ROPCODE_MERGECOPY == RopInfo->RopCode)
826 {
827 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
828 "&BltInfo->DestRect, 0x0);\n", Bpp);
829 }
830 Output(Out, "return;\n");
831 Output(Out, "}\n");
832 }
833 else if (ROPCODE_PATPAINT == RopInfo->RopCode)
834 {
835 Output(Out, "if ((~0) == Pattern)\n");
836 Output(Out, "{\n");
837 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
838 "&BltInfo->DestRect, ~0);\n", Bpp);
839 Output(Out, "return;\n");
840 Output(Out, "}\n");
841 }
842 if (ROPCODE_GENERIC == RopInfo->RopCode)
843 {
844 Output(Out, "}\n");
845 }
846 CreateActionBlock(Out, Bpp, RopInfo, 0);
847 MARK(Out);
848 Output(Out, "}\n");
849 }
850 else
851 {
852 CreateActionBlock(Out, Bpp, RopInfo, 0);
853 MARK(Out);
854 }
855 }
856 Output(Out, "}\n");
857 }
858
859 static void
860 CreateTable(FILE *Out, unsigned Bpp)
861 {
862 unsigned RopCode;
863
864 MARK(Out);
865 Output(Out, "\n");
866 Output(Out, "static void (*PrimitivesTable[256])(PBLTINFO) =\n");
867 Output(Out, " {\n");
868 for (RopCode = 0; RopCode < 256; RopCode++)
869 {
870 Output(Out, " ");
871 PrintRoutineName(Out, Bpp, FindRopInfo(RopCode));
872 if (RopCode < 255)
873 {
874 putc(',', Out);
875 }
876 putc('\n', Out);
877 }
878 Output(Out, " };\n");
879 }
880
881 static void
882 CreateBitBlt(FILE *Out, unsigned Bpp)
883 {
884 MARK(Out);
885 Output(Out, "\n");
886 Output(Out, "BOOLEAN\n");
887 Output(Out, "DIB_%uBPP_BitBlt(PBLTINFO BltInfo)\n", Bpp);
888 Output(Out, "{\n");
889 Output(Out, " PrimitivesTable[BltInfo->Rop4 & 0xff](BltInfo);\n");
890 Output(Out, "\n");
891 Output(Out, " return TRUE;\n");
892 Output(Out, "}\n");
893 }
894
895 int
896 main(int argc, char *argv[])
897 {
898 FILE *Out;
899 unsigned RopCode;
900 unsigned Bpp;
901 PROPINFO RopInfo;
902
903 Bpp = 16;
904 Out = fopen(argv[1], "w");
905 if (NULL == Out)
906 {
907 perror("Error opening output file");
908 exit(1);
909 }
910
911 MARK(Out);
912 Output(Out, "/* This is a generated file. Please do not edit */\n");
913 Output(Out, "\n");
914 Output(Out, "#include \"w32k.h\"\n");
915 CreateShiftTables(Out);
916
917 RopInfo = FindRopInfo(ROPCODE_GENERIC);
918 CreatePrimitive(Out, Bpp, RopInfo);
919 for (RopCode = 0; RopCode < 256; RopCode++)
920 {
921 RopInfo = FindRopInfo(RopCode);
922 if (NULL != RopInfo)
923 {
924 CreatePrimitive(Out, Bpp, RopInfo);
925 }
926 }
927 CreateTable(Out, Bpp);
928 CreateBitBlt(Out, Bpp);
929
930 fclose(Out);
931
932 return 0;
933 }