|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: Strips.c
3: *
4: *
5: * Copyright (c) 1992 Microsoft Corporation
6: \**************************************************************************/
7:
8: #include "driver.h"
9: #include "lines.h"
10:
11: USHORT usMaskWord(LINESTATE *pLineState, LONG cPels);
12:
13: VOID vDumpLineData(PPDEV ppdev, STRIP *Strip, LINESTATE *LineState);
14:
15: /******************************************************************************
16: *
17: *****************************************************************************/
18: VOID vSetStrips(
19: PPDEV ppdev,
20: LINEATTRS *pla,
21: INT color,
22: INT mix)
23: {
24: USHORT wS3Mix;
25:
26: wS3Mix = Rop2ToS3Rop[(mix & 0xFF)-1];
27:
28: // Wait for just enough room in the FIFO
29:
30: FIFOWAIT(FIFO_3_EMPTY);
31:
32: // Send out some of the commands.
33:
34: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | wS3Mix);
35: TEST_AND_SET_FRGD_COLOR(color);
36:
37: if ((pla->fl & LA_ALTERNATE) ||
38: (pla->pstyle != (FLOAT_LONG*) NULL))
39: {
40: TEST_AND_SET_BKGD_MIX(LEAVE_ALONE);
41: SET_BKGD_COLOR(0);
42: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
43: }
44: else
45: {
46: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
47: }
48:
49: return;
50: }
51:
52: /******************************************************************************
53: *
54: *****************************************************************************/
55: VOID vssSolidHorizontal(
56: PPDEV ppdev,
57: STRIP *pStrip,
58: LINESTATE *pLineState)
59: {
60: LONG i, cStrips;
61: PLONG pStrips;
62: LONG xPels, xSumPels, yDir;
63: USHORT Cmd, ssCmd, dirDraw, dirSkip;
64:
65: Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
66: DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
67: BUS_SIZE_16 | BYTE_SWAP;
68:
69: cStrips = pStrip->cStrips;
70:
71: FIFOWAIT(FIFO_3_EMPTY);
72:
73: OUTPW(CUR_X, pStrip->ptlStart.x);
74: OUTPW(CUR_Y, pStrip->ptlStart.y);
75: OUTPW(CMD, Cmd);
76:
77: // Setup the drawing direction and the skip direction.
78:
79: dirDraw = 0x10;
80:
81: if (!(pStrip->flFlips & FL_FLIP_V))
82: {
83: yDir = 1;
84: dirSkip = 0xC100;
85: }
86: else
87: {
88: dirSkip = 0x4100;
89: yDir = -1;
90: }
91:
92: // Output the short stroke commands.
93:
94: xSumPels = 0;
95: pStrips = pStrip->alStrips;
96: for (i = 0; i < cStrips; i++)
97: {
98: xPels = *pStrips++;
99: xSumPels += xPels;
100: ssCmd = (USHORT) (dirSkip | dirDraw | xPels);
101: FIFOWAIT(FIFO_4_EMPTY);
102: OUTPW(SHORT_STROKE_REG, ssCmd);
103: }
104:
105: pStrip->ptlStart.x += xSumPels;
106: pStrip->ptlStart.y += cStrips * yDir;
107:
108: }
109:
110:
111: /******************************************************************************
112: *
113: *****************************************************************************/
114: VOID vrlSolidHorizontal(
115: PPDEV ppdev,
116: STRIP *pStrip,
117: LINESTATE *pLineState)
118: {
119: LONG cStrips;
120: USHORT Cmd;
121: LONG i, yInc, x, y;
122: PLONG pStrips;
123:
124:
125: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
126: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_0 |
127: WRITE;
128:
129: cStrips = pStrip->cStrips;
130:
131: x = pStrip->ptlStart.x;
132: y = pStrip->ptlStart.y;
133:
134: yInc = 1;
135: if (pStrip->flFlips & FL_FLIP_V)
136: yInc = -1;
137:
138: pStrips = pStrip->alStrips;
139:
140: for (i = 0; i < cStrips; i++)
141: {
142: FIFOWAIT(FIFO_4_EMPTY);
143:
144: OUTPW(CUR_X, x);
145: OUTPW(CUR_Y, y);
146: OUTPW(LINE_MAX, *pStrips);
147: OUTPW(CMD, Cmd);
148:
149: x += *pStrips++;
150: y += yInc;
151: }
152:
153: pStrip->ptlStart.x = x;
154: pStrip->ptlStart.y = y;
155:
156: }
157:
158: /******************************************************************************
159: *
160: *****************************************************************************/
161: VOID vssSolidVertical(
162: PPDEV ppdev,
163: STRIP *pStrip,
164: LINESTATE *pLineState)
165: {
166: LONG i, cStrips;
167: PLONG pStrips;
168: LONG yPels, ySumPels, yDir;
169: USHORT Cmd, ssCmd, dirDraw, dirSkip;
170:
171: Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
172: DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
173: BUS_SIZE_16 | BYTE_SWAP;
174:
175: cStrips = pStrip->cStrips;
176:
177: FIFOWAIT(FIFO_3_EMPTY);
178:
179: OUTPW(CUR_X, pStrip->ptlStart.x);
180: OUTPW(CUR_Y, pStrip->ptlStart.y);
181: OUTPW(CMD, Cmd);
182:
183: // Setup the drawing direction and the skip direction.
184:
185: if (!(pStrip->flFlips & FL_FLIP_V))
186: {
187: yDir = 1;
188: dirDraw = 0xD0;
189: }
190: else
191: {
192: yDir = -1;
193: dirDraw = 0x50;
194: }
195:
196: dirSkip = 0x0100;
197:
198: // Output the short stroke commands.
199:
200: ySumPels = 0;
201: pStrips = pStrip->alStrips;
202: for (i = 0; i < cStrips; i++)
203: {
204: yPels = *pStrips++;
205: ySumPels += yPels;
206: ssCmd = (USHORT) (dirSkip | dirDraw | yPels);
207: FIFOWAIT(FIFO_4_EMPTY);
208: OUTPW(SHORT_STROKE_REG, ssCmd);
209: }
210:
211: pStrip->ptlStart.x += cStrips;
212: pStrip->ptlStart.y += ySumPels * yDir;
213:
214: }
215:
216:
217: /******************************************************************************
218: *
219: *****************************************************************************/
220: VOID vrlSolidVertical(
221: PPDEV ppdev,
222: STRIP *pStrip,
223: LINESTATE *pLineState)
224: {
225: LONG cStrips;
226: USHORT Cmd;
227: LONG i, x, y;
228: PLONG pStrips;
229:
230: cStrips = pStrip->cStrips;
231: pStrips = pStrip->alStrips;
232:
233: x = pStrip->ptlStart.x;
234: y = pStrip->ptlStart.y;
235:
236: if (!(pStrip->flFlips & FL_FLIP_V))
237: {
238: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
239: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_270 |
240: WRITE;
241:
242: for (i = 0; i < cStrips; i++)
243: {
244: FIFOWAIT(FIFO_4_EMPTY);
245:
246: OUTPW(CUR_X, x);
247: OUTPW(CUR_Y, y);
248: OUTPW(LINE_MAX, *pStrips);
249: OUTPW(CMD, Cmd);
250:
251: y += *pStrips++;
252: x++;
253: }
254:
255: }
256: else
257: {
258: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
259: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_90 |
260: WRITE;
261:
262: for (i = 0; i < cStrips; i++)
263: {
264: FIFOWAIT(FIFO_4_EMPTY);
265:
266: OUTPW(CUR_X, x);
267: OUTPW(CUR_Y, y);
268: OUTPW(LINE_MAX, *pStrips);
269: OUTPW(CMD, Cmd);
270:
271: y -= *pStrips++;
272: x++;
273: }
274: }
275:
276: pStrip->ptlStart.x = x;
277: pStrip->ptlStart.y = y;
278:
279: }
280:
281:
282: /******************************************************************************
283: *
284: *****************************************************************************/
285: VOID vssSolidDiagonalHorizontal(
286: PPDEV ppdev,
287: STRIP *pStrip,
288: LINESTATE *pLineState)
289: {
290: LONG i, cStrips;
291: PLONG pStrips;
292: LONG Pels, SumPels, yDir;
293: USHORT Cmd, ssCmd, dirDraw, dirSkip;
294:
295: Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
296: DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
297: BUS_SIZE_16 | BYTE_SWAP;
298:
299: cStrips = pStrip->cStrips;
300:
301: FIFOWAIT(FIFO_3_EMPTY);
302:
303: OUTPW(CUR_X, pStrip->ptlStart.x);
304: OUTPW(CUR_Y, pStrip->ptlStart.y);
305: OUTPW(CMD, Cmd);
306:
307: // Setup the drawing direction and the skip direction.
308:
309: if (!(pStrip->flFlips & FL_FLIP_V))
310: {
311: yDir = 1;
312: dirDraw = 0xF0;
313: dirSkip = 0x4100;
314:
315: }
316: else
317: {
318: yDir = -1;
319: dirDraw = 0x30;
320: dirSkip = 0xC100;
321:
322: }
323:
324: // Output the short stroke commands.
325:
326: SumPels = 0;
327: pStrips = pStrip->alStrips;
328: for (i = 0; i < cStrips; i++)
329: {
330: Pels = *pStrips++;
331: SumPels += Pels;
332: ssCmd = (USHORT)(dirSkip | dirDraw | Pels);
333: FIFOWAIT(FIFO_4_EMPTY);
334: OUTPW(SHORT_STROKE_REG, ssCmd);
335: }
336:
337: pStrip->ptlStart.x += SumPels;
338: pStrip->ptlStart.y += (SumPels - cStrips) * yDir;
339:
340: }
341:
342:
343: /******************************************************************************
344: *
345: *****************************************************************************/
346: VOID vrlSolidDiagonalHorizontal(
347: PPDEV ppdev,
348: STRIP *pStrip,
349: LINESTATE *pLineState)
350: {
351: LONG cStrips;
352: USHORT Cmd;
353: LONG i, x, y;
354: PLONG pStrips;
355:
356: cStrips = pStrip->cStrips;
357: pStrips = pStrip->alStrips;
358:
359: x = pStrip->ptlStart.x;
360: y = pStrip->ptlStart.y;
361:
362: if (!(pStrip->flFlips & FL_FLIP_V))
363: {
364: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
365: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_315 |
366: WRITE;
367:
368: for (i = 0; i < cStrips; i++)
369: {
370: FIFOWAIT(FIFO_4_EMPTY);
371:
372: OUTPW(CUR_X, x);
373: OUTPW(CUR_Y, y);
374: OUTPW(LINE_MAX, *pStrips);
375: OUTPW(CMD, Cmd);
376:
377: y += *pStrips - 1;
378: x += *pStrips++;
379: }
380:
381: }
382: else
383: {
384: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
385: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_45 |
386: WRITE;
387:
388: for (i = 0; i < cStrips; i++)
389: {
390: FIFOWAIT(FIFO_4_EMPTY);
391:
392: OUTPW(CUR_X, x);
393: OUTPW(CUR_Y, y);
394: OUTPW(LINE_MAX, *pStrips);
395: OUTPW(CMD, Cmd);
396:
397: y -= *pStrips - 1;
398: x += *pStrips++;
399: }
400: }
401:
402: pStrip->ptlStart.x = x;
403: pStrip->ptlStart.y = y;
404:
405: }
406:
407:
408: /******************************************************************************
409: *
410: *****************************************************************************/
411: VOID vssSolidDiagonalVertical(
412: PPDEV ppdev,
413: STRIP *pStrip,
414: LINESTATE *pLineState)
415: {
416: LONG i, cStrips;
417: PLONG pStrips;
418: LONG Pels, SumPels, yDir;
419: USHORT Cmd, ssCmd, dirDraw, dirSkip;
420:
421: Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
422: DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
423: BUS_SIZE_16 | BYTE_SWAP;
424:
425: cStrips = pStrip->cStrips;
426:
427: FIFOWAIT(FIFO_3_EMPTY);
428:
429: OUTPW(CUR_X, pStrip->ptlStart.x);
430: OUTPW(CUR_Y, pStrip->ptlStart.y);
431: OUTPW(CMD, Cmd);
432:
433: // Setup the drawing direction and the skip direction.
434:
435: if (!(pStrip->flFlips & FL_FLIP_V))
436: {
437: yDir = 1;
438: dirDraw = 0xF0;
439: }
440: else
441: {
442: yDir = -1;
443: dirDraw = 0x30;
444: }
445:
446: dirSkip = 0x8100;
447:
448: // Output the short stroke commands.
449:
450: SumPels = 0;
451: pStrips = pStrip->alStrips;
452: for (i = 0; i < cStrips; i++)
453: {
454: Pels = *pStrips++;
455: SumPels += Pels;
456: ssCmd = (USHORT)(dirSkip | dirDraw | Pels);
457: FIFOWAIT(FIFO_4_EMPTY);
458: OUTPW(SHORT_STROKE_REG, ssCmd);
459: }
460:
461: pStrip->ptlStart.x += SumPels - cStrips;
462: pStrip->ptlStart.y += SumPels * yDir;
463:
464: }
465:
466: /******************************************************************************
467: *
468: *****************************************************************************/
469: VOID vrlSolidDiagonalVertical(
470: PPDEV ppdev,
471: STRIP *pStrip,
472: LINESTATE *pLineState)
473: {
474: LONG cStrips;
475: USHORT Cmd;
476: LONG i, x, y;
477: PLONG pStrips;
478:
479: cStrips = pStrip->cStrips;
480: pStrips = pStrip->alStrips;
481:
482: x = pStrip->ptlStart.x;
483: y = pStrip->ptlStart.y;
484:
485: if (!(pStrip->flFlips & FL_FLIP_V))
486: {
487: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
488: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_315 |
489: WRITE;
490:
491: for (i = 0; i < cStrips; i++)
492: {
493: FIFOWAIT(FIFO_4_EMPTY);
494:
495: OUTPW(CUR_X, x);
496: OUTPW(CUR_Y, y);
497: OUTPW(LINE_MAX, *pStrips);
498: OUTPW(CMD, Cmd);
499:
500: y += *pStrips;
501: x += *pStrips++ - 1;
502: }
503:
504: }
505: else
506: {
507: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
508: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_45 |
509: WRITE;
510:
511: for (i = 0; i < cStrips; i++)
512: {
513: FIFOWAIT(FIFO_4_EMPTY);
514:
515: OUTPW(CUR_X, x);
516: OUTPW(CUR_Y, y);
517: OUTPW(LINE_MAX, *pStrips);
518: OUTPW(CMD, Cmd);
519:
520: y -= *pStrips;
521: x += *pStrips++ - 1;
522: }
523: }
524:
525:
526: pStrip->ptlStart.x = x;
527: pStrip->ptlStart.y = y;
528:
529: }
530:
531: /******************************************************************************
532: *
533: *****************************************************************************/
534: VOID vStripStyledHorizontal(
535: PPDEV ppdev,
536: STRIP *pStrip,
537: LINESTATE *pLineState)
538: {
539: LONG cStrips;
540: USHORT Cmd;
541: LONG i, yInc, x, y, cPels;
542: PLONG pStrips;
543:
544: DISPDBG((3, "\nvStripStyledHorizontal - Entry\n"));
545:
546: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
547: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_0 |
548: WRITE |
549: BUS_SIZE_16 | WAIT;
550:
551: cStrips = pStrip->cStrips;
552:
553: x = pStrip->ptlStart.x;
554: y = pStrip->ptlStart.y;
555:
556: yInc = 1;
557: if (pStrip->flFlips & FL_FLIP_V)
558: yInc = -1;
559:
560: pStrips = pStrip->alStrips;
561:
562: for (i = 0; i < cStrips; i++)
563: {
564: cPels = *pStrips;
565:
566: FIFOWAIT(FIFO_4_EMPTY);
567:
568: OUTPW(CUR_X, x);
569: OUTPW(CUR_Y, y);
570: OUTPW(LINE_MAX, cPels);
571: OUTPW(CMD, Cmd);
572:
573: x += cPels;
574: y += yInc;
575:
576: while (cPels >= 0)
577: {
578: FIFOWAIT(FIFO_1_EMPTY);
579: OUTPW(PIXEL_TRANSFER, usMaskWord(pLineState, cPels));
580: cPels -= 16;
581: }
582:
583: pStrips++;
584: }
585:
586: pStrip->ptlStart.x = x;
587: pStrip->ptlStart.y = y;
588:
589: }
590:
591: /******************************************************************************
592: *
593: *****************************************************************************/
594: VOID vStripStyledVertical(
595: PPDEV ppdev,
596: STRIP *pStrip,
597: LINESTATE *pLineState)
598: {
599: LONG cStrips;
600: USHORT Cmd;
601: LONG i, x, y, cPels;
602: PLONG pStrips;
603:
604: DISPDBG((3, "\nvStripStyledVertical - Entry\n"));
605:
606: cStrips = pStrip->cStrips;
607: pStrips = pStrip->alStrips;
608:
609: x = pStrip->ptlStart.x;
610: y = pStrip->ptlStart.y;
611:
612: if (!(pStrip->flFlips & FL_FLIP_V))
613: {
614: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
615: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_270 |
616: WRITE |
617: BUS_SIZE_16 | WAIT;
618:
619: for (i = 0; i < cStrips; i++)
620: {
621: cPels = *pStrips;
622:
623: FIFOWAIT(FIFO_4_EMPTY);
624:
625: OUTPW(CUR_X, x);
626: OUTPW(CUR_Y, y);
627: OUTPW(LINE_MAX, cPels);
628: OUTPW(CMD, Cmd);
629:
630: y += cPels;
631: x++;
632:
633: while (cPels >= 0)
634: {
635: FIFOWAIT(FIFO_1_EMPTY);
636: OUTPW(PIXEL_TRANSFER, usMaskWord(pLineState, cPels));
637: cPels -= 16;
638: }
639:
640: pStrips++;
641: }
642:
643: }
644: else
645: {
646: Cmd = DRAW_LINE | DRAW | DIR_TYPE_RADIAL |
647: LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_90 |
648: WRITE |
649: BUS_SIZE_16 | WAIT;
650:
651:
652: for (i = 0; i < cStrips; i++)
653: {
654: cPels = *pStrips;
655:
656: FIFOWAIT(FIFO_4_EMPTY);
657:
658: OUTPW(CUR_X, x);
659: OUTPW(CUR_Y, y);
660: OUTPW(LINE_MAX, cPels);
661: OUTPW(CMD, Cmd);
662:
663: y -= cPels;
664: x++;
665:
666: while (cPels >= 0)
667: {
668: FIFOWAIT(FIFO_1_EMPTY);
669: OUTPW(PIXEL_TRANSFER, usMaskWord(pLineState, cPels));
670: cPels -= 16;
671: }
672:
673: pStrips++;
674: }
675: }
676:
677: pStrip->ptlStart.x = x;
678: pStrip->ptlStart.y = y;
679:
680: }
681:
682: /******************************************************************************
683: *
684: * This is a good example of how not to compute the mask for styled lines.
685: *
686: * The masks should be precomputed on entry to DrvStrokePath; computing
687: * the pattern mask to be output to the pixel transfer register would then
688: * be a couple of shifts and an Or. Also, the style state would be updated
689: * at the end of the strip function.
690: *
691: *****************************************************************************/
692:
693: USHORT usMaskWord(
694: LINESTATE* pls,
695: LONG cPels)
696: {
697: ULONG ulMask = 0; // Accumulating mask
698: ULONG ulBit = 0x8000; // Rotating bit
699: LONG i;
700:
701: // The S3 takes a word mask that accounts for at most 16 pixels:
702:
703: if (cPels > 16)
704: cPels = 16;
705:
706: for (i = cPels; i--; i > 0)
707: {
708: ulMask |= (ulBit & pls->ulStyleMask);
709: ulBit >>= 1;
710: if (--pls->spRemaining == 0)
711: {
712: // Okay, we're onto the next entry in the style array, so if
713: // we were working on a gap, we're now working on a dash (or
714: // vice versa):
715:
716: pls->ulStyleMask = ~pls->ulStyleMask;
717:
718: // See if we've reached the end of the style array, and have to
719: // wrap back around to the beginning:
720:
721: if (++pls->psp > pls->pspEnd)
722: pls->psp = pls->pspStart;
723:
724: // Get the length of our new dash or gap, in pixels:
725:
726: pls->spRemaining = *pls->psp;
727: }
728: }
729:
730: // Return the inverted result, because pls->ulStyleMask is inverted from
731: // the way you would expect it to be:
732:
733: return((USHORT) ~ulMask);
734: }
735:
736: #if DBG
737:
738: /******************************************************************************
739: *
740: *****************************************************************************/
741: VOID vDumpLineData(
742: PPDEV ppdev,
743: STRIP *Strip,
744: LINESTATE *LineState)
745: {
746: LONG flFlips;
747: PLONG plStrips;
748: LONG i;
749:
750: DISPDBG((2, "Strip->cStrips: %d\n", Strip->cStrips));
751:
752: flFlips = Strip->flFlips;
753:
754: DISPDBG((2, "Strip->flFlips: %s%s%s%s%s\n",
755: (flFlips & FL_FLIP_D)? "FL_FLIP_D | " : "",
756: (flFlips & FL_FLIP_V)? "FL_FLIP_V | " : "",
757: (flFlips & FL_FLIP_SLOPE_ONE)? "FL_FLIP_SLOPE_ONE | ": "",
758: (flFlips & FL_FLIP_HALF)? "FL_FLIP_HALF | " : "",
759: (flFlips & FL_FLIP_H)? "FL_FLIP_H " : ""));
760:
761: DISPDBG((2, "Strip->ptlStart: (%d, %d)\n",
762: Strip->ptlStart.x,
763: Strip->ptlStart.y));
764:
765: plStrips = Strip->alStrips;
766:
767: for (i = 0; i < Strip->cStrips; i++)
768: {
769: DISPDBG((2, "\talStrips[%d]: %d\n", i, plStrips[i]));
770: }
771: }
772:
773: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.