|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: Stroke.c ! 3: * ! 4: * DrvStrokePath for VGA driver ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: \**************************************************************************/ ! 8: ! 9: #include "driver.h" ! 10: ! 11: #include "lines.h" ! 12: ! 13: // External calls ! 14: ! 15: VOID vSetStrips(ULONG, ULONG); ! 16: VOID vClearStrips(ULONG); ! 17: ! 18: #define MIN(A,B) ((A) < (B) ? (A) : (B)) ! 19: ! 20: // Prototypes to go to the screen: ! 21: ! 22: VOID vStripSolidHorizontal(STRIP*, LINESTATE*, LONG*); ! 23: VOID vStripSolidHorizontalSet(STRIP*, LINESTATE*, LONG*); ! 24: VOID vStripSolidVertical(STRIP*, LINESTATE*, LONG*); ! 25: VOID vStripSolidDiagonalHorizontal(STRIP*, LINESTATE*, LONG*); ! 26: VOID vStripSolidDiagonalVertical(STRIP*, LINESTATE*, LONG*); ! 27: ! 28: VOID vStripStyledHorizontal(STRIP*, LINESTATE*, LONG*); ! 29: VOID vStripStyledVertical(STRIP*, LINESTATE*, LONG*); ! 30: ! 31: VOID vStripMaskedHorizontal(STRIP*, LINESTATE*, LONG*); ! 32: VOID vStripMaskedVertical(STRIP*, LINESTATE*, LONG*); ! 33: ! 34: PFNSTRIP gapfnStripSolidSet[] = { ! 35: ! 36: // Special strip drawers for solid lines with SET style ROPs: ! 37: ! 38: vStripSolidHorizontalSet, ! 39: vStripSolidVertical, ! 40: vStripSolidDiagonalHorizontal, ! 41: vStripSolidDiagonalVertical ! 42: }; ! 43: ! 44: PFNSTRIP gapfnStrip[] = { ! 45: ! 46: // The order of these first 3 sets of strip drawers is determined by ! 47: // the FL_STYLE_MASK bits of the line flags: ! 48: ! 49: vStripSolidHorizontal, ! 50: vStripSolidVertical, ! 51: vStripSolidDiagonalHorizontal, ! 52: vStripSolidDiagonalVertical, ! 53: ! 54: vStripStyledHorizontal, ! 55: vStripStyledVertical, ! 56: NULL, // Diagonal goes here ! 57: NULL, // Diagonal goes here ! 58: ! 59: vStripMaskedHorizontal, ! 60: vStripMaskedVertical, ! 61: NULL, // Diagonal goes here ! 62: NULL, // Diagonal goes here ! 63: }; ! 64: ! 65: // Prototypes to go to a device-format bitmap: ! 66: ! 67: VOID vBitmapSolidHorizontal(STRIP*, LINESTATE*, LONG*); ! 68: VOID vBitmapSolidVertical(STRIP*, LINESTATE*, LONG*); ! 69: VOID vBitmapSolidDiagonal(STRIP*, LINESTATE*, LONG*); ! 70: ! 71: VOID vBitmapStyledHorizontal(STRIP*, LINESTATE*, LONG*); ! 72: VOID vBitmapStyledVertical(STRIP*, LINESTATE*, LONG*); ! 73: ! 74: // For two-pass ROPs: ! 75: ! 76: VOID vCatchTwoPass(STRIP*, LINESTATE*, LONG*); ! 77: ! 78: PFNSTRIP gapfnCatchTwoPass[] = { ! 79: vCatchTwoPass, ! 80: vCatchTwoPass, ! 81: vCatchTwoPass, ! 82: vCatchTwoPass ! 83: }; ! 84: ! 85: // VGA ulVgaMode constants: ! 86: ! 87: #define DR_SET 0x00 ! 88: #define DR_AND 0x08 ! 89: #define DR_OR 0x10 ! 90: #define DR_XOR 0x18 ! 91: ! 92: // Bit flag set if two passes needed: ! 93: ! 94: #define DR_2PASS 0x80 ! 95: ! 96: // Table to convert ROP to usable information: ! 97: ! 98: static struct { ! 99: ULONG ulColorAnd; ! 100: ULONG ulColorXor; ! 101: ULONG ulVgaMode; ! 102: } arop[] = { ! 103: {0x00, 0xff, DR_SET}, // 1 R2_WHITE ! 104: {0x00, 0x00, DR_SET}, // 0 R2_BLACK ! 105: {0xff, 0xff, DR_AND|DR_2PASS}, // DPon R2_NOTMERGEPEN Dest invert + DPna ! 106: {0xff, 0xff, DR_AND}, // DPna R2_MASKNOTPEN ! 107: {0xff, 0xff, DR_SET}, // PN R2_NOTCOPYPEN ! 108: {0xff, 0x00, DR_AND|DR_2PASS}, // PDna R2_MASKPENNOT Dest invert + DPa ! 109: {0x00, 0xff, DR_XOR}, // Dn R2_NOT Invert dest without pen ! 110: {0xff, 0x00, DR_XOR}, // DPx R2_XORPEN ! 111: {0xff, 0xff, DR_OR|DR_2PASS}, // DPan R2_NOTMASKPEN Dest invert + DPno ! 112: {0xff, 0x00, DR_AND}, // DPa R2_MASKPEN ! 113: {0xff, 0xff, DR_XOR}, // DPxn R2_NOTXORPEN DPxn == DPnx ! 114: {0x00, 0x00, DR_OR}, // D R2_NOP Silliness! ! 115: {0xff, 0xff, DR_OR}, // DPno R2_MERGENOTPEN ! 116: {0xff, 0x00, DR_SET}, // P R2_COPYPEN ! 117: {0xff, 0x00, DR_OR|DR_2PASS}, // PDno R2_MERGEPENNOT Dest invert + DPo ! 118: {0xff, 0x00, DR_OR}, // DPo R2_MERGEPEN ! 119: }; ! 120: ! 121: // The gaulAndXorTable contains and-masks and xor-masks for setting ! 122: // pels to one of four possible values. The and-masks have been ! 123: // inverted, and are stored in the low byte of each word. The ! 124: // xor-masks are stored in the high bytes. ! 125: // ! 126: // ROP XOR ~AND ! 127: // ------------------- ! 128: // DDx 00 FF Set to zero ! 129: // Dn FF 00 Not destination ! 130: // D 00 00 Leave alone ! 131: // DDxn FF FF Set to one ! 132: ! 133: ULONG gaulAndXorTable[] = { ! 134: 0x00ff, // Set to zero ! 135: 0xff00, // Not destination ! 136: 0x0000, // Leave alone ! 137: 0xffff // Set to one ! 138: }; ! 139: ! 140: ULONG gaulInitMasksLtoR[] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; ! 141: ULONG gaulInitMasksRtoL[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; ! 142: ! 143: /******************************Public*Routine******************************\ ! 144: * BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrushOrg, pla, mix) ! 145: * ! 146: * Strokes the path. ! 147: * ! 148: \**************************************************************************/ ! 149: ! 150: BOOL DrvStrokePath( ! 151: SURFOBJ* pso, ! 152: PATHOBJ* ppo, ! 153: CLIPOBJ* pco, ! 154: XFORMOBJ* pxo, ! 155: BRUSHOBJ* pbo, ! 156: POINTL* pptlBrushOrg, ! 157: LINEATTRS* pla, ! 158: MIX mix) ! 159: { ! 160: STYLEPOS aspLtoR[STYLE_MAX_COUNT]; ! 161: STYLEPOS aspRtoL[STYLE_MAX_COUNT]; ! 162: LINESTATE ls; ! 163: PFNSTRIP* apfn; ! 164: FLONG fl; ! 165: PDEVSURF pdsurf; ! 166: ULONG ulVgaMode; ! 167: ! 168: UNREFERENCED_PARAMETER(pxo); ! 169: UNREFERENCED_PARAMETER(pptlBrushOrg); ! 170: ! 171: // Verify that things are as they should be: ! 172: ! 173: // ASSERT(pso != (SURFOBJ*) NULL, "DrvStrokePath: surface"); ! 174: // ASSERT(ppo != (PATHOBJ*) NULL, "DrvStrokePath: path"); ! 175: // ASSERT(pco != (CLIPOBJ*) NULL, "DrvStrokePath: clipobj"); ! 176: // ASSERT(pbo != (BRUSHOBJ*) NULL, "DrvStrokePath: brushobj"); ! 177: // ASSERT(pla != (LINEATTRS*) NULL && !(pla->fl & LA_GEOMETRIC), ! 178: // "DrvStrokePath: lineattrs"); ! 179: // ASSERT(pbo->iSolidColor != 0xffffffff, ! 180: // "DrvStrokePath: brushobj isn't solid"); ! 181: ! 182: // Get the device ready: ! 183: ! 184: pdsurf = (PDEVSURF) pso->dhsurf; ! 185: // ASSERT(pdsurf != (PDEVSURF) NULL, "DrvStrokePath: no surface"); ! 186: ! 187: fl = 0; ! 188: ! 189: // Look after styling initialization: ! 190: ! 191: if (pla->fl & LA_ALTERNATE) ! 192: { ! 193: // ASSERT(pla->pstyle == (FLOAT_LONG*) NULL && pla->cstyle == 0, ! 194: // "Non-empty style array for PS_ALTERNATE"); ! 195: ! 196: ls.spTotal = 1; ! 197: ls.spTotal2 = 2; ! 198: ls.xyDensity = 1; ! 199: fl |= (FL_ALTERNATESTYLED | FL_MASKSTYLED); ! 200: } ! 201: else if (pla->pstyle != (FLOAT_LONG*) NULL) ! 202: { ! 203: PFLOAT_LONG pstyle; ! 204: ! 205: // ASSERT(pla->cstyle <= STYLE_MAX_COUNT, "Style array too large"); ! 206: ! 207: pstyle = &pla->pstyle[pla->cstyle]; ! 208: ! 209: ls.xyDensity = STYLE_DENSITY; ! 210: ls.spTotal = 0; ! 211: while (pstyle-- > pla->pstyle) ! 212: { ! 213: ls.spTotal += pstyle->l; ! 214: } ! 215: ls.spTotal *= STYLE_DENSITY; ! 216: ls.spTotal2 = 2 * ls.spTotal; ! 217: ! 218: // Compute starting style position (this is guaranteed not to overflow): ! 219: ! 220: ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY + ! 221: LOWORD(pla->elStyleState.l); ! 222: ! 223: // We optimize the style arrays that are even length and sum to 8. We ! 224: // also don't have any masked strip drawers for DFBs: ! 225: ! 226: if (ls.spTotal == (8 * STYLE_DENSITY) && ! 227: (pla->cstyle & 1) == 0) ! 228: { ! 229: // Do "masked" styles. ! 230: // ------------------- ! 231: // ! 232: // This case is merely an optimization; you can remove it and ! 233: // all style lines will still work. It just so happens that the ! 234: // default styles (such as PS_DOT, PS_DASHDOT, etc.) will all ! 235: // sum to 8, and there are some optimizations we can do on the ! 236: // VGA for that case. ! 237: // ! 238: // We make an 8 bit mask that represents each style unit in the ! 239: // style array, and we pass this to the "Masked" strip drawers ! 240: // (instead of calling the "Styled" strip drawers which still ! 241: // handle the arbitrary styles). ! 242: ! 243: LONG ii; ! 244: ! 245: ls.ulStyleMaskLtoR = 0; ! 246: ls.ulStyleMaskRtoL = 0; ! 247: ! 248: for (pstyle = pla->pstyle, ii = 8; ii > 0;) ! 249: { ! 250: LONG l1 = (pstyle++)->l; ! 251: LONG l2 = (pstyle++)->l; ! 252: ! 253: ls.ulStyleMaskRtoL >>= l1 + l2; ! 254: ls.ulStyleMaskRtoL |= gaulInitMasksRtoL[l2]; ! 255: ! 256: ls.ulStyleMaskLtoR <<= l1 + l2; ! 257: ls.ulStyleMaskLtoR |= gaulInitMasksLtoR[l2]; ! 258: ! 259: ii -= (l1 + l2); ! 260: } ! 261: ! 262: // Replicate byte and initialize to style position zero: ! 263: ! 264: ls.ulStyleMaskLtoR |= (ls.ulStyleMaskLtoR << 8); ! 265: ls.ulStyleMaskLtoR |= (ls.ulStyleMaskLtoR << 16); ! 266: ! 267: ls.ulStyleMaskRtoL |= (ls.ulStyleMaskRtoL << 8); ! 268: ls.ulStyleMaskRtoL |= (ls.ulStyleMaskRtoL << 16); ! 269: ! 270: // Check if we should start with a gap or start with a dash: ! 271: ! 272: if (pla->fl & LA_STARTGAP) ! 273: { ! 274: ls.ulStyleMaskLtoR = ~ls.ulStyleMaskLtoR; ! 275: ls.ulStyleMaskRtoL = ~ls.ulStyleMaskRtoL; ! 276: } ! 277: ! 278: // Initialize some other state: ! 279: ! 280: fl |= FL_MASKSTYLED; ! 281: } ! 282: else ! 283: ! 284: // Okay, we've got to do it the slow way: ! 285: ! 286: { ! 287: // Handle Arbitrary Styles ! 288: // ----------------------- ! 289: // ! 290: // Because arbitrary styles are new to Win32, many apps won't ! 291: // know about them and will use the default styles (which will ! 292: // be handled by the "Masked" optimization case above), and so ! 293: // this code path won't get exercised too often. (See GDI's ! 294: // ExtCreatePen API.) ! 295: // ! 296: // But you still have to handle them, and do them right! ! 297: ! 298: FLOAT_LONG* pstyle; ! 299: STYLEPOS* pspDown; ! 300: STYLEPOS* pspUp; ! 301: ! 302: fl |= FL_ARBITRARYSTYLED; ! 303: ls.cStyle = pla->cstyle; ! 304: ls.aspRtoL = aspRtoL; ! 305: ls.aspLtoR = aspLtoR; ! 306: ! 307: if (pla->fl & LA_STARTGAP) ! 308: ls.ulStartMask = 0xffffffffL; ! 309: else ! 310: ls.ulStartMask = 0L; ! 311: ! 312: pstyle = pla->pstyle; ! 313: pspDown = &ls.aspRtoL[ls.cStyle - 1]; ! 314: pspUp = &ls.aspLtoR[0]; ! 315: ! 316: // We always draw strips left-to-right, but styles have to be laid ! 317: // down in the direction of the original line. This means that in ! 318: // the strip code we have to traverse the style array in the ! 319: // opposite direction; ! 320: ! 321: while (pspDown >= &ls.aspRtoL[0]) ! 322: { ! 323: // ASSERT(pstyle->l > 0 && pstyle->l <= STYLE_MAX_VALUE, ! 324: // "Illegal style array value"); ! 325: ! 326: *pspDown = pstyle->l * STYLE_DENSITY; ! 327: *pspUp = *pspDown; ! 328: ! 329: pspUp++; ! 330: pspDown--; ! 331: pstyle++; ! 332: } ! 333: } ! 334: } ! 335: ! 336: { ! 337: ULONG iColor; ! 338: ULONG iStripIndex; ! 339: ! 340: fl |= FL_PHYSICAL_DEVICE; ! 341: ! 342: // Compute the pointer to the correct strip drawing table. We ! 343: // have a special table for solid lines done with VGA mode == SET: ! 344: ! 345: iStripIndex = 4 * ((fl & FL_STYLE_MASK) >> FL_STYLE_SHIFT); ! 346: apfn = &gapfnStrip[iStripIndex]; ! 347: ! 348: mix &= 0xf; ! 349: ulVgaMode = arop[mix].ulVgaMode; ! 350: ! 351: if (ulVgaMode == DR_SET && iStripIndex == 0) ! 352: apfn = &gapfnStripSolidSet[0]; ! 353: ! 354: // Compute the correct color, based on the ROP we're doing: ! 355: ! 356: iColor = (pbo->iSolidColor & arop[mix].ulColorAnd) ! 357: ^ (arop[mix].ulColorXor); ! 358: ! 359: if (!(ulVgaMode & DR_2PASS)) ! 360: vSetStrips(iColor, ulVgaMode); ! 361: else ! 362: { ! 363: // If the ROP requires 2 passes, we sneakily change our strip ! 364: // table pointer to point to only our own routine, and it ! 365: // handles calling the appropriate strip routines twice: ! 366: ! 367: ls.ulVgaMode = ulVgaMode ^ DR_2PASS; ! 368: ls.iColor = iColor; ! 369: ls.apfnStrip = apfn; ! 370: apfn = gapfnCatchTwoPass; ! 371: } ! 372: } ! 373: ! 374: // Set up to enumerate the path: ! 375: ! 376: if (pco->iDComplexity != DC_COMPLEX) ! 377: { ! 378: RECTL arclClip[4]; // For rectangular clipping ! 379: PATHDATA pd; ! 380: RECTL* prclClip = (RECTL*) NULL; ! 381: BOOL bMore; ! 382: ULONG cptfx; ! 383: POINTFIX ptfxStartFigure; ! 384: POINTFIX ptfxLast; ! 385: POINTFIX* pptfxFirst; ! 386: POINTFIX* pptfxBuf; ! 387: ! 388: if (pco->iDComplexity == DC_RECT) ! 389: { ! 390: fl |= FL_SIMPLE_CLIP; ! 391: ! 392: arclClip[0] = pco->rclBounds; ! 393: ! 394: // FL_FLIP_D: ! 395: ! 396: arclClip[1].top = pco->rclBounds.left; ! 397: arclClip[1].left = pco->rclBounds.top; ! 398: arclClip[1].bottom = pco->rclBounds.right; ! 399: arclClip[1].right = pco->rclBounds.bottom; ! 400: ! 401: // FL_FLIP_V: ! 402: ! 403: arclClip[2].top = -pco->rclBounds.bottom + 1; ! 404: arclClip[2].left = pco->rclBounds.left; ! 405: arclClip[2].bottom = -pco->rclBounds.top + 1; ! 406: arclClip[2].right = pco->rclBounds.right; ! 407: ! 408: // FL_FLIP_V | FL_FLIP_D: ! 409: ! 410: arclClip[3].top = pco->rclBounds.left; ! 411: arclClip[3].left = -pco->rclBounds.bottom + 1; ! 412: arclClip[3].bottom = pco->rclBounds.right; ! 413: arclClip[3].right = -pco->rclBounds.top + 1; ! 414: ! 415: prclClip = arclClip; ! 416: } ! 417: ! 418: PATHOBJ_vEnumStart(ppo); ! 419: ! 420: do { ! 421: bMore = PATHOBJ_bEnum(ppo, &pd); ! 422: ! 423: cptfx = pd.count; ! 424: if (cptfx == 0) ! 425: { ! 426: // ASSERT(!bMore, "Empty path record in non-empty path"); ! 427: break; ! 428: } ! 429: ! 430: if (pd.flags & PD_BEGINSUBPATH) ! 431: { ! 432: ptfxStartFigure = *pd.pptfx; ! 433: pptfxFirst = pd.pptfx; ! 434: pptfxBuf = pd.pptfx + 1; ! 435: cptfx--; ! 436: } ! 437: else ! 438: { ! 439: pptfxFirst = &ptfxLast; ! 440: pptfxBuf = pd.pptfx; ! 441: } ! 442: ! 443: if (pd.flags & PD_RESETSTYLE) ! 444: ls.spNext = 0; ! 445: ! 446: // We have to check for cptfx == 0 because the only point in the ! 447: // subpath may have been the StartFigure point: ! 448: ! 449: if (cptfx > 0) ! 450: { ! 451: if (!bLines(pdsurf, ! 452: pptfxFirst, ! 453: pptfxBuf, ! 454: (RUN*) NULL, ! 455: cptfx, ! 456: &ls, ! 457: prclClip, ! 458: apfn, ! 459: fl)) ! 460: return(FALSE); ! 461: } ! 462: ! 463: ptfxLast = pd.pptfx[pd.count - 1]; ! 464: ! 465: if (pd.flags & PD_CLOSEFIGURE) ! 466: { ! 467: if (!bLines(pdsurf, ! 468: &ptfxLast, ! 469: &ptfxStartFigure, ! 470: (RUN*) NULL, ! 471: 1, ! 472: &ls, ! 473: prclClip, ! 474: apfn, ! 475: fl)) ! 476: return(FALSE); ! 477: } ! 478: } while (bMore); ! 479: ! 480: if (fl & FL_STYLED) ! 481: { ! 482: // Save the style state: ! 483: ! 484: ULONG ulHigh; ! 485: ULONG ulLow; ! 486: ! 487: // !!! The engine handles unnormalized style states. This can ! 488: // !!! be removed. Might have to remove some asserts in the ! 489: // !!! engine. ! 490: ! 491: // Masked styles don't normalize the style state. It's a good ! 492: // thing to do, so let's do it now: ! 493: ! 494: if ((ULONG) ls.spNext >= (ULONG) ls.spTotal2) ! 495: ls.spNext = (ULONG) ls.spNext % (ULONG) ls.spTotal2; ! 496: ! 497: ulHigh = ls.spNext / ls.xyDensity; ! 498: ulLow = ls.spNext % ls.xyDensity; ! 499: ! 500: pla->elStyleState.l = MAKELONG(ulLow, ulHigh); ! 501: } ! 502: } ! 503: else ! 504: { ! 505: // Local state for path enumeration: ! 506: ! 507: BOOL bMore; ! 508: union { ! 509: BYTE aj[offsetof(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)]; ! 510: CLIPLINE cl; ! 511: } cl; ! 512: ! 513: fl |= FL_COMPLEX_CLIP; ! 514: ! 515: // We use the clip object when non-simple clipping is involved: ! 516: ! 517: PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla); ! 518: ! 519: do { ! 520: bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl); ! 521: if (cl.cl.c != 0) ! 522: { ! 523: if (fl & FL_STYLED) ! 524: { ! 525: ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity ! 526: + LOWORD(cl.cl.lStyleState); ! 527: } ! 528: if (!bLines(pdsurf, ! 529: &cl.cl.ptfxA, ! 530: &cl.cl.ptfxB, ! 531: &cl.cl.arun[0], ! 532: cl.cl.c, ! 533: &ls, ! 534: (RECTL*) NULL, ! 535: apfn, ! 536: fl)) ! 537: return(FALSE); ! 538: } ! 539: } while (bMore); ! 540: } ! 541: ! 542: if (fl & FL_PHYSICAL_DEVICE) ! 543: vClearStrips(ulVgaMode); ! 544: ! 545: return(TRUE); ! 546: } ! 547: ! 548: /******************************Public*Routine******************************\ ! 549: * VOID vCatchTwoPass(pstrip, pls, plStripEnd) ! 550: * ! 551: * Handles ROPs that cannot be done in a single pass using the VGA ! 552: * hardware. In order not to have a check in our main drawing loop for ! 553: * two-pass ROPs, we change the strip function table so that this function ! 554: * intercepts the call to draw the strips. ! 555: * ! 556: * This routine then figures out the appropriate actual strip drawer, and ! 557: * makes two calls to it: first to invert the destination, then to do the ! 558: * rest of the ROP. ! 559: * ! 560: \**************************************************************************/ ! 561: ! 562: VOID vCatchTwoPass(STRIP* pstrip, LINESTATE* pls, LONG* plStripEnd) ! 563: { ! 564: BYTE* pjScreen = pstrip->pjScreen; ! 565: BYTE jBitMask = pstrip->jBitMask; ! 566: BYTE jStyleMask = pstrip->jStyleMask; ! 567: STYLEPOS* psp = pstrip->psp; ! 568: STYLEPOS spRemaining = pstrip->spRemaining; ! 569: ! 570: // Figure out the actual strip routine we're supposed to call: ! 571: ! 572: PFNSTRIP pfn = pls->apfnStrip[(pstrip->flFlips & FL_STRIP_MASK) >> ! 573: FL_STRIP_SHIFT]; ! 574: ! 575: // On the first pass, we invert the destination: ! 576: ! 577: vSetStrips(0xff, DR_XOR); ! 578: ! 579: (*pfn)(pstrip, pls, plStripEnd); ! 580: ! 581: // We reset our strip variables for the second pass and handle the rest ! 582: // of the ROP: ! 583: ! 584: pstrip->pjScreen = pjScreen; ! 585: pstrip->jBitMask = jBitMask; ! 586: pstrip->jStyleMask = jStyleMask; ! 587: pstrip->psp = psp; ! 588: pstrip->spRemaining = spRemaining; ! 589: ! 590: vSetStrips(pls->iColor, pls->ulVgaMode); ! 591: ! 592: (*pfn)(pstrip, pls, plStripEnd); ! 593: } ! 594:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.