1 #include <stdint.h>
2 #include "Debug.h"
3 #include "HImage.h"
4 #include "Local.h"
5 #include "MemMan.h"
6 #include "Shading.h"
7 #include "VObject.h"
8 #include "VObject_Blitters.h"
9 #include "VSurface.h"
10 #include "WCheck.h"
11
12
13 SGPRect ClippingRect;
14 //555 565
15 UINT32 guiTranslucentMask=0x3def; //0x7bef; // mask for halving 5,6,5
16
17
18 /*
19 * Difference or Zero
20 * NB: the types of the parameters are int32_t to ensure the compiler can
21 * safely promote 16 bit unsigned integers.
22 */
DoZ(int32_t const a,int32_t const b)23 static uint16_t DoZ(int32_t const a, int32_t const b)
24 {
25 return a > b ? static_cast<uint16_t>(a - b) : 0;
26 }
27
28
29 /* Blit an image into the destination buffer, using an ETRLE brush as a source,
30 * and a 16-bit buffer as a destination. As it is blitting, it checks the Z
31 * value of the ZBuffer, and if the pixel's Z level is below that of the current
32 * pixel, it is written on, and the Z value is NOT updated to the current value,
33 * for any non-transparent pixels. The Z-buffer is 16 bit, and must be the same
34 * dimensions (including pitch) as the destination.
35 * Blits every second pixel ("Translucents"). */
Blt8BPPDataTo16BPPBufferTransZNBClipTranslucent(UINT16 * const buf,UINT32 const uiDestPitchBYTES,UINT16 * const zbuf,UINT16 const zval,HVOBJECT const hSrcVObject,INT32 const iX,INT32 const iY,UINT16 const usIndex,SGPRect const * clipregion)36 void Blt8BPPDataTo16BPPBufferTransZNBClipTranslucent(UINT16* const buf, UINT32 const uiDestPitchBYTES, UINT16* const zbuf, UINT16 const zval, HVOBJECT const hSrcVObject, INT32 const iX, INT32 const iY, UINT16 const usIndex, SGPRect const* clipregion)
37 {
38 Assert(hSrcVObject);
39 Assert(buf);
40
41 // Get offsets from index into structure.
42 ETRLEObject const& e = hSrcVObject->SubregionProperties(usIndex);
43 int32_t const height = e.usHeight; // NB: safe automatic conversion
44 int32_t const width = e.usWidth;
45
46 // Add to start position of dest buffer.
47 int32_t const x = iX + e.sOffsetX;
48 int32_t const y = iY + e.sOffsetY;
49
50 if (!clipregion) clipregion = &ClippingRect;
51
52 /* Calculate rows hanging off each side of the screen and check if the whole
53 * thing is clipped. */
54 UINT16 const left_skip = DoZ(clipregion->iLeft, x);
55 if (left_skip >= width) return;
56 UINT16 top_skip = DoZ(clipregion->iTop, y);
57 if (top_skip >= height) return;
58 UINT16 const right_skip = DoZ(x + width, clipregion->iRight);
59 if (right_skip >= width) return;
60 UINT16 const bottom_skip = DoZ(y + height, clipregion->iBottom);
61 if (bottom_skip >= height) return;
62
63 // Calculate the remaining rows and columns to blit.
64 INT32 const blit_length = width - left_skip - right_skip;
65 INT32 blit_height = height - top_skip - bottom_skip;
66
67 UINT32 const pitch = uiDestPitchBYTES / 2;
68 UINT8 const* src = hSrcVObject->PixData(e);
69 UINT16* dst = buf + pitch * (y + top_skip) + (x + left_skip);
70 UINT16 const* zdst = zbuf + pitch * (y + top_skip) + (x + left_skip);
71 UINT16 const* const pal = hSrcVObject->CurrentShade();
72 UINT32 line_skip = pitch - blit_length;
73
74 for (; top_skip > 0; --top_skip)
75 {
76 for (;;)
77 {
78 UINT32 const px_count = *src++;
79 if (px_count & 0x80) continue;
80 if (px_count == 0) break;
81 src += px_count;
82 }
83 }
84
85 UINT32 const translucent_mask = guiTranslucentMask;
86 do
87 {
88 INT32 ls_count;
89 UINT32 px_count;
90 for (ls_count = left_skip; ls_count > 0; ls_count -= px_count)
91 {
92 px_count = *src++;
93 if (px_count & 0x80)
94 {
95 px_count &= 0x7F;
96 if (px_count > static_cast<UINT32>(ls_count))
97 {
98 px_count -= ls_count;
99 ls_count = blit_length;
100 goto BlitTransparent;
101 }
102 }
103 else
104 {
105 if (px_count > static_cast<UINT32>(ls_count))
106 {
107 src += ls_count;
108 px_count -= ls_count;
109 ls_count = blit_length;
110 goto BlitNonTransLoop;
111 }
112 src += px_count;
113 }
114 }
115
116 ls_count = blit_length;
117 while (ls_count > 0)
118 {
119 px_count = *src++;
120 if (px_count & 0x80)
121 { // Skip transparent pixels.
122 px_count &= 0x7F;
123 BlitTransparent:
124 if (px_count > static_cast<UINT32>(ls_count)) px_count = ls_count;
125 ls_count -= px_count;
126 dst += px_count;
127 zdst += px_count;
128 }
129 else
130 { // Blit non-transparent pixels.
131 BlitNonTransLoop:
132 UINT32 unblitted = 0;
133 if (px_count > static_cast<UINT32>(ls_count))
134 {
135 unblitted = px_count - ls_count;
136 px_count = ls_count;
137 }
138 ls_count -= px_count;
139
140 do
141 {
142 if (*zdst > zval) continue;
143 *dst =
144 (pal[*src] >> 1 & translucent_mask) +
145 (*dst >> 1 & translucent_mask);
146 }
147 while (++src, ++dst, ++zdst, --px_count > 0);
148 src += unblitted;
149 }
150 }
151
152 while (*src++ != 0) {} // Skip along until we hit and end-of-line marker.
153 dst += line_skip;
154 zdst += line_skip;
155 }
156 while (--blit_height > 0);
157 }
158
159
160 /**********************************************************************************************
161 Blt8BPPDataTo16BPPBufferTransZTranslucent
162
163 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
164 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
165 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
166 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
167 must be the same dimensions (including Pitch) as the destination.
168
169 Blits every second pixel ("Translucents").
170
171 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZTranslucent(UINT16 * const buf,UINT32 const uiDestPitchBYTES,UINT16 * const zbuf,UINT16 const zval,HVOBJECT const hSrcVObject,INT32 const iX,INT32 const iY,UINT16 const usIndex)172 void Blt8BPPDataTo16BPPBufferTransZTranslucent( UINT16* const buf, UINT32 const uiDestPitchBYTES, UINT16* const zbuf, UINT16 const zval, HVOBJECT const hSrcVObject, INT32 const iX, INT32 const iY, UINT16 const usIndex )
173 {
174
175 // Assertions
176 Assert( hSrcVObject );
177 Assert( buf );
178
179 // Get Offsets from Index into structure
180 ETRLEObject const& e = hSrcVObject->SubregionProperties(usIndex);
181 UINT32 height = e.usHeight;
182 UINT32 const width = e.usWidth;
183
184 // Add to start position of dest buffer
185 INT32 const x = iX + e.sOffsetX;
186 INT32 const y = iY + e.sOffsetY;
187
188 // Validations
189 CHECKV(x >= 0);
190 CHECKV(y >= 0);
191
192 UINT32 const pitch = uiDestPitchBYTES / 2;
193 UINT8 const* src = hSrcVObject->PixData(e);
194 UINT16 * dst = buf + pitch * y + x;
195 UINT16 * zdst = zbuf + pitch * y + x;
196 UINT16 const* const pal = hSrcVObject->CurrentShade();
197 UINT32 line_skip = pitch - width;
198 UINT32 const translucent_mask = guiTranslucentMask;
199
200 do
201 {
202 for (;;)
203 {
204 UINT8 data = *src++;
205
206 if (data == 0) break;
207 if (data & 0x80)
208 {
209 data &= 0x7F;
210 dst += data;
211 zdst += data;
212 }
213 else
214 {
215 do
216 {
217 if (*zdst > zval) continue;
218 *zdst = zval;
219 *dst =
220 ((pal[*src] >> 1) & translucent_mask) +
221 ((*dst >> 1) & translucent_mask);
222 }
223 while (++src, ++dst, ++zdst, --data > 0);
224 }
225 }
226 dst += line_skip;
227 zdst += line_skip;
228 }
229 while (--height > 0);
230 }
231
232
233 /* Blit an image into the destination buffer, using an ETRLE brush as a source,
234 * and a 16-bit buffer as a destination. As it is blitting, it checks the Z
235 * value of the ZBuffer, and if the pixel's Z level is below that of the current
236 * pixel, it is written on, and the Z value is NOT updated to the current value,
237 * for any non-transparent pixels. The Z-buffer is 16 bit, and must be the same
238 * dimensions (including pitch) as the destination.
239 * Blits every second pixel ("Translucents"). */
Blt8BPPDataTo16BPPBufferTransZNBTranslucent(UINT16 * const buf,UINT32 const uiDestPitchBYTES,UINT16 * const zbuf,UINT16 const zval,HVOBJECT const hSrcVObject,INT32 const iX,INT32 const iY,UINT16 const usIndex)240 void Blt8BPPDataTo16BPPBufferTransZNBTranslucent(UINT16* const buf, UINT32 const uiDestPitchBYTES, UINT16* const zbuf, UINT16 const zval, HVOBJECT const hSrcVObject, INT32 const iX, INT32 const iY, UINT16 const usIndex)
241 {
242 Assert(hSrcVObject);
243 Assert(buf);
244
245 // Get offsets from index into structure.
246 ETRLEObject const& e = hSrcVObject->SubregionProperties(usIndex);
247 UINT32 height = e.usHeight;
248 UINT32 const width = e.usWidth;
249
250 // Add to start position of dest buffer.
251 INT32 const x = iX + e.sOffsetX;
252 INT32 const y = iY + e.sOffsetY;
253
254 CHECKV(x >= 0);
255 CHECKV(y >= 0);
256
257 UINT32 const pitch = uiDestPitchBYTES / 2;
258 UINT8 const* src = hSrcVObject->PixData(e);
259 UINT16* dst = buf + pitch * y + x;
260 UINT16 const* zdst = zbuf + pitch * y + x;
261 UINT16 const* const pal = hSrcVObject->CurrentShade();
262 UINT32 line_skip = pitch - width;
263
264 UINT32 const translucent_mask = guiTranslucentMask;
265 do
266 {
267 for (;;)
268 {
269 UINT8 data = *src++;
270
271 if (data == 0) break;
272 if (data & 0x80)
273 {
274 data &= 0x7F;
275 dst += data;
276 zdst += data;
277 }
278 else
279 {
280 do
281 {
282 if (*zdst > zval) continue;
283 *dst =
284 ((pal[*src] >> 1) & translucent_mask) +
285 ((*dst >> 1) & translucent_mask);
286 }
287 while (++src, ++dst, ++zdst, --data > 0);
288 }
289 }
290 dst += line_skip;
291 zdst += line_skip;
292 }
293 while (--height > 0);
294 }
295
296
InitZBuffer(const UINT32 width,const UINT32 height)297 UINT16* InitZBuffer(const UINT32 width, const UINT32 height)
298 {
299 return new UINT16[width * height]{};
300 }
301
302
ShutdownZBuffer(UINT16 * const pBuffer)303 void ShutdownZBuffer(UINT16* const pBuffer)
304 {
305 delete[] pBuffer;
306 }
307
308
309 /**********************************************************************************************
310 Blt8BPPDataTo16BPPBufferMonoShadowClip
311
312 Uses a bitmap an 8BPP template for blitting. Anywhere a 1 appears in the bitmap, a shadow
313 is blitted to the destination (a black pixel). Any other value above zero is considered a
314 forground color, and zero is background. If the parameter for the background color is zero,
315 transparency is used for the background.
316
317 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferMonoShadowClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion,UINT16 usForeground,UINT16 usBackground,UINT16 usShadow)318 void Blt8BPPDataTo16BPPBufferMonoShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 usForeground, UINT16 usBackground, UINT16 usShadow )
319 {
320 UINT32 Unblitted;
321 UINT8 *DestPtr;
322 UINT32 LineSkip;
323 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
324 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
325
326 // Assertions
327 Assert( hSrcVObject != NULL );
328 Assert( pBuffer != NULL );
329
330 // Get Offsets from Index into structure
331 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
332 UINT32 const usHeight = pTrav.usHeight;
333 UINT32 const usWidth = pTrav.usWidth;
334
335 // Add to start position of dest buffer
336 INT32 const iTempX = iX + pTrav.sOffsetX;
337 INT32 const iTempY = iY + pTrav.sOffsetY;
338
339 if(clipregion==NULL)
340 {
341 ClipX1=ClippingRect.iLeft;
342 ClipY1=ClippingRect.iTop;
343 ClipX2=ClippingRect.iRight;
344 ClipY2=ClippingRect.iBottom;
345 }
346 else
347 {
348 ClipX1=clipregion->iLeft;
349 ClipY1=clipregion->iTop;
350 ClipX2=clipregion->iRight;
351 ClipY2=clipregion->iBottom;
352 }
353
354 // Calculate rows hanging off each side of the screen
355 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
356 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
357 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
358 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
359
360 // calculate the remaining rows and columns to blit
361 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
362 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
363
364 // check if whole thing is clipped
365 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
366 return;
367
368 // check if whole thing is clipped
369 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
370 return;
371
372 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
373 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
374 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
375
376 UINT32 PxCount;
377
378 while (TopSkip > 0)
379 {
380 for (;;)
381 {
382 PxCount = *SrcPtr++;
383 if (PxCount & 0x80) continue;
384 if (PxCount == 0) break;
385 SrcPtr += PxCount;
386 }
387 TopSkip--;
388 }
389
390 do
391 {
392 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
393 {
394 PxCount = *SrcPtr++;
395 if (PxCount & 0x80)
396 {
397 PxCount &= 0x7F;
398 if (PxCount > static_cast<UINT32>(LSCount))
399 {
400 PxCount -= LSCount;
401 LSCount = BlitLength;
402 goto BlitTransparent;
403 }
404 }
405 else
406 {
407 if (PxCount > static_cast<UINT32>(LSCount))
408 {
409 SrcPtr += LSCount;
410 PxCount -= LSCount;
411 LSCount = BlitLength;
412 goto BlitNonTransLoop;
413 }
414 SrcPtr += PxCount;
415 }
416 }
417
418 LSCount = BlitLength;
419 while (LSCount > 0)
420 {
421 PxCount = *SrcPtr++;
422 if (PxCount & 0x80)
423 {
424 BlitTransparent: // skip transparent pixels
425 PxCount &= 0x7F;
426 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
427 LSCount -= PxCount;
428 if (usBackground == 0)
429 {
430 DestPtr += 2 * PxCount;
431 }
432 else
433 {
434 while (PxCount-- != 0)
435 {
436 *(UINT16*)DestPtr = usBackground;
437 DestPtr += 2;
438 }
439 }
440 }
441 else
442 {
443 BlitNonTransLoop: // blit non-transparent pixels
444 if (PxCount > static_cast<UINT32>(LSCount))
445 {
446 Unblitted = PxCount - LSCount;
447 PxCount = LSCount;
448 }
449 else
450 {
451 Unblitted = 0;
452 }
453 LSCount -= PxCount;
454
455 do
456 {
457 switch (*SrcPtr++)
458 {
459 case 0: if (usBackground != 0) *(UINT16*)DestPtr = usBackground; break;
460 case 1: if (usShadow != 0) *(UINT16*)DestPtr = usShadow; break;
461 default: *(UINT16*)DestPtr = usForeground; break;
462 }
463 DestPtr += 2;
464 }
465 while (--PxCount > 0);
466 SrcPtr += Unblitted;
467 }
468 }
469
470 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
471 DestPtr += LineSkip;
472 }
473 while (--BlitHeight > 0);
474 }
475
476
477 /**********************************************************************************************
478 Blt16BPPTo16BPP
479
480 Copies a rect of 16 bit data from a video buffer to a buffer position of the brush
481 in the data area, for later blitting. Used to copy background information for mercs
482 etc. to their unblit buffer, for later reblitting. Does NOT clip.
483
484 **********************************************************************************************/
Blt16BPPTo16BPP(UINT16 * pDest,UINT32 uiDestPitch,UINT16 * pSrc,UINT32 uiSrcPitch,INT32 iDestXPos,INT32 iDestYPos,INT32 iSrcXPos,INT32 iSrcYPos,UINT32 uiWidth,UINT32 uiHeight)485 void Blt16BPPTo16BPP(UINT16 *pDest, UINT32 uiDestPitch, UINT16 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight)
486 {
487 UINT32 i;
488
489 for (i = 0; i < uiHeight; i++)
490 {
491 memcpy(
492 (UINT8*)pDest + uiDestPitch * (iDestYPos + i) + 2 * iDestXPos,
493 (UINT8*)pSrc + uiSrcPitch * (iSrcYPos + i) + 2 * iSrcXPos,
494 uiWidth * 2
495 );
496 }
497 }
498
499
500 /**********************************************************************************************
501 Blt8BPPDataTo16BPPBufferTransZPixelateObscured
502
503 // OK LIKE NORMAL PIXELATE BUT ONLY PIXELATES STUFF BELOW Z level
504
505 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
506 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
507 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
508 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
509 must be the same dimensions (including Pitch) as the destination.
510
511 Blits every second pixel ("pixelates").
512
513 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZPixelateObscured(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)514 void Blt8BPPDataTo16BPPBufferTransZPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
515 {
516 UINT32 LineSkip;
517 UINT8 *DestPtr, *ZPtr;
518 UINT32 uiLineFlag;
519
520 // Assertions
521 Assert( hSrcVObject != NULL );
522 Assert( pBuffer != NULL );
523
524 // Get Offsets from Index into structure
525 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
526 UINT32 usHeight = pTrav.usHeight;
527 UINT32 const usWidth = pTrav.usWidth;
528
529 // Add to start position of dest buffer
530 INT32 const iTempX = iX + pTrav.sOffsetX;
531 INT32 const iTempY = iY + pTrav.sOffsetY;
532
533 // Validations
534 CHECKV(iTempX >= 0);
535 CHECKV(iTempY >= 0);
536
537 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
538 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
539 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
540 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
541 LineSkip=(uiDestPitchBYTES-(usWidth*2));
542 uiLineFlag=(iTempY&1);
543
544 do
545 {
546 for (;;)
547 {
548 UINT8 data = *SrcPtr++;
549
550 if (data == 0) break;
551 if (data & 0x80)
552 {
553 data &= 0x7F;
554 DestPtr += 2 * data;
555 ZPtr += 2 * data;
556 }
557 else
558 {
559 do
560 {
561 if (*(UINT16*)ZPtr < usZValue)
562 {
563 *(UINT16*)ZPtr = usZValue;
564 }
565 else
566 {
567 if (uiLineFlag != (((uintptr_t)DestPtr & 2) != 0)) continue;
568 }
569 *(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
570 }
571 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --data > 0);
572 }
573 }
574 DestPtr += LineSkip;
575 ZPtr += LineSkip;
576 uiLineFlag ^= 1;
577 }
578 while (--usHeight > 0);
579 }
580
581
582 /* Blit an image into the destination buffer, using an ETRLE brush as a source
583 * and a 16-bit buffer as a destination. As it is blitting, it checks the Z-
584 * value of the ZBuffer, and if the pixel's Z level is below that of the current
585 * pixel, it is written on, and the Z value is updated to the current value, for
586 * any non-transparent pixels. The Z-buffer is 16 bit, and must be the same
587 * dimensions (including Pitch) as the destination. */
Blt8BPPDataTo16BPPBufferTransZ(UINT16 * const buf,UINT32 const uiDestPitchBYTES,UINT16 * const zbuf,UINT16 const zval,HVOBJECT const hSrcVObject,INT32 const iX,INT32 const iY,UINT16 const usIndex)588 void Blt8BPPDataTo16BPPBufferTransZ(UINT16* const buf, UINT32 const uiDestPitchBYTES, UINT16* const zbuf, UINT16 const zval, HVOBJECT const hSrcVObject, INT32 const iX, INT32 const iY, UINT16 const usIndex)
589 {
590 Assert(hSrcVObject);
591 Assert(buf);
592
593 // Get offsets from index into structure
594 ETRLEObject const& e = hSrcVObject->SubregionProperties(usIndex);
595 UINT32 height = e.usHeight;
596 UINT32 const width = e.usWidth;
597
598 // Add to start position of dest buffer
599 INT32 const x = iX + e.sOffsetX;
600 INT32 const y = iY + e.sOffsetY;
601
602 // Validations
603 CHECKV(x >= 0);
604 CHECKV(y >= 0);
605
606 UINT8 const* src = hSrcVObject->PixData(e);
607 UINT32 const pitch = uiDestPitchBYTES / 2;
608 UINT16* dst = buf + pitch * y + x;
609 UINT16* zdst = zbuf + pitch * y + x;
610 UINT16 const* const pal = hSrcVObject->CurrentShade();
611 UINT32 line_skip = pitch - width;
612
613 for (;;)
614 {
615 UINT8 data = *src++;
616 if (data == 0)
617 {
618 if (--height == 0) break;
619 dst += line_skip;
620 zdst += line_skip;
621 }
622 else if (data & 0x80)
623 {
624 data &= 0x7F;
625 dst += data;
626 zdst += data;
627 }
628 else
629 {
630 do
631 {
632 if (*zdst <= zval)
633 {
634 *zdst = zval;
635 *dst = pal[*src];
636 }
637 ++src;
638 ++dst;
639 ++zdst;
640 }
641 while (--data != 0);
642 }
643 }
644 }
645
646
647 /**********************************************************************************************
648 Blt8BPPDataTo16BPPBufferTransZNB
649
650 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
651 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
652 pixel's Z level is below that of the current pixel, it is written on. The Z value is
653 NOT updated by this version. The Z-buffer is 16 bit, and must be the same dimensions
654 (including Pitch) as the destination.
655
656 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZNB(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)657 void Blt8BPPDataTo16BPPBufferTransZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
658 {
659 UINT8 *DestPtr, *ZPtr;
660 UINT32 LineSkip;
661
662 // Assertions
663 Assert( hSrcVObject != NULL );
664 Assert( pBuffer != NULL );
665
666 // Get Offsets from Index into structure
667 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
668 UINT32 usHeight = pTrav.usHeight;
669 UINT32 const usWidth = pTrav.usWidth;
670
671 // Add to start position of dest buffer
672 INT32 const iTempX = iX + pTrav.sOffsetX;
673 INT32 const iTempY = iY + pTrav.sOffsetY;
674
675 // Validations
676 CHECKV(iTempX >= 0);
677 CHECKV(iTempY >= 0);
678
679 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
680 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
681 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
682 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
683 LineSkip=(uiDestPitchBYTES-(usWidth*2));
684
685 do
686 {
687 for (;;)
688 {
689 UINT8 data = *SrcPtr++;
690
691 if (data == 0) break;
692 if (data & 0x80)
693 {
694 data &= 0x7F;
695 DestPtr += 2 * data;
696 ZPtr += 2 * data;
697 }
698 else
699 {
700 do
701 {
702 if (*(UINT16*)ZPtr <= usZValue)
703 {
704 *(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
705 }
706 SrcPtr++;
707 DestPtr += 2;
708 ZPtr += 2;
709 }
710 while (--data > 0);
711 }
712 }
713 DestPtr += LineSkip;
714 ZPtr += LineSkip;
715 }
716 while (--usHeight > 0);
717 }
718
719
720 /**********************************************************************************************
721 Blt8BPPDataTo16BPPBufferTransShadow
722
723 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
724 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
725 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
726 updated to the current value, for any non-transparent pixels. If the source pixel is 254,
727 it is considered a shadow, and the destination buffer is darkened rather than blitted on.
728 The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
729
730 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadow(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,const UINT16 * p16BPPPalette)731 void Blt8BPPDataTo16BPPBufferTransShadow(UINT16* pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, const UINT16* p16BPPPalette)
732 {
733 UINT8 *DestPtr;
734 UINT32 LineSkip;
735
736 // Assertions
737 Assert( hSrcVObject != NULL );
738 Assert( pBuffer != NULL );
739
740 // Get Offsets from Index into structure
741 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
742 UINT32 usHeight = pTrav.usHeight;
743 UINT32 const usWidth = pTrav.usWidth;
744
745 // Add to start position of dest buffer
746 INT32 const iTempX = iX + pTrav.sOffsetX;
747 INT32 const iTempY = iY + pTrav.sOffsetY;
748
749 // Validations
750 CHECKV(iTempX >= 0);
751 CHECKV(iTempY >= 0);
752
753 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
754 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
755 LineSkip=(uiDestPitchBYTES-(usWidth*2));
756
757 do
758 {
759 for (;;)
760 {
761 UINT8 data = *SrcPtr++;
762
763 if (data == 0) break;
764 if (data & 0x80)
765 {
766 data &= 0x7F;
767 DestPtr += 2 * data;
768 }
769 else
770 {
771 do
772 {
773 UINT8 px = *SrcPtr++;
774
775 if (px == 254)
776 {
777 *(UINT16*)DestPtr = ShadeTable[2 * (*(UINT16*)DestPtr)];
778 }
779 else
780 {
781 *(UINT16*)DestPtr = p16BPPPalette[2 * px];
782 }
783 DestPtr += 2;
784 }
785 while (--data > 0);
786 }
787 }
788 DestPtr += LineSkip;
789 }
790 while (--usHeight > 0);
791 }
792
793
794 /**********************************************************************************************
795 Blt8BPPDataTo16BPPBufferTransShadowZ
796
797 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
798 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
799 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
800 updated to the current value, for any non-transparent pixels. If the source pixel is 254,
801 it is considered a shadow, and the destination buffer is darkened rather than blitted on.
802 The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
803
804 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZ(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,const UINT16 * p16BPPPalette)805 void Blt8BPPDataTo16BPPBufferTransShadowZ(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, const UINT16* p16BPPPalette)
806 {
807 UINT8 *DestPtr, *ZPtr;
808 UINT32 LineSkip;
809
810 // Assertions
811 Assert( hSrcVObject != NULL );
812 Assert( pBuffer != NULL );
813
814 // Get Offsets from Index into structure
815 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
816 UINT32 usHeight = pTrav.usHeight;
817 UINT32 const usWidth = pTrav.usWidth;
818
819 // Add to start position of dest buffer
820 INT32 const iTempX = iX + pTrav.sOffsetX;
821 INT32 const iTempY = iY + pTrav.sOffsetY;
822
823 // Validations
824 CHECKV(iTempX >= 0);
825 CHECKV(iTempY >= 0);
826
827 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
828 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
829 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
830 LineSkip=(uiDestPitchBYTES-(usWidth*2));
831
832 do
833 {
834 for (;;)
835 {
836 UINT8 data = *SrcPtr++;
837
838 if (data == 0) break;
839 if (data & 0x80)
840 {
841 data &= 0x7F;
842 DestPtr += 2 * data;
843 }
844 else
845 {
846 do
847 {
848 UINT8 px = *SrcPtr++;
849
850 if (px == 254)
851 {
852 if (*(UINT16*)ZPtr < usZValue)
853 {
854 *(UINT16*)DestPtr = ShadeTable[2 * (*(UINT16*)DestPtr)];
855 }
856 }
857 else
858 {
859 if (*(UINT16*)ZPtr <= usZValue)
860 {
861 *(UINT16*)DestPtr = p16BPPPalette[2 * px];
862 }
863 }
864 DestPtr += 2;
865 }
866 while (--data > 0);
867 }
868 }
869 DestPtr += LineSkip;
870 }
871 while (--usHeight > 0);
872 }
873
874
875 /**********************************************************************************************
876 Blt8BPPDataTo16BPPBufferTransShadowZNB
877
878 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
879 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
880 pixel's Z level is below that of the current pixel, it is written on. The Z value is NOT
881 updated. If the source pixel is 254, it is considered a shadow, and the destination
882 buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
883 dimensions (including Pitch) as the destination.
884
885 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZNB(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,const UINT16 * p16BPPPalette)886 void Blt8BPPDataTo16BPPBufferTransShadowZNB(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, const UINT16* p16BPPPalette)
887 {
888 UINT8 *DestPtr, *ZPtr;
889 UINT32 LineSkip;
890
891 // Assertions
892 Assert( hSrcVObject != NULL );
893 Assert( pBuffer != NULL );
894
895 // Get Offsets from Index into structure
896 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
897 UINT32 usHeight = pTrav.usHeight;
898 UINT32 const usWidth = pTrav.usWidth;
899
900 // Add to start position of dest buffer
901 INT32 const iTempX = iX + pTrav.sOffsetX;
902 INT32 const iTempY = iY + pTrav.sOffsetY;
903
904 // Validations
905 CHECKV(iTempX >= 0);
906 CHECKV(iTempY >= 0);
907
908 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
909 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
910 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
911 LineSkip=(uiDestPitchBYTES-(usWidth*2));
912
913 do
914 {
915 for (;;)
916 {
917 UINT8 data = *SrcPtr++;
918
919 if (data == 0) break;
920 if (data & 0x80)
921 {
922 data &= 0x7F;
923 DestPtr += 2 * data;
924 ZPtr += 2 * data;
925 }
926 else
927 {
928 do
929 {
930 UINT8 px = *SrcPtr++;
931
932 if (px == 254)
933 {
934 if (*(UINT16*)ZPtr < usZValue)
935 {
936 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
937 }
938 }
939 else
940 {
941 if (*(UINT16*)ZPtr <= usZValue)
942 {
943 *(UINT16*)DestPtr = p16BPPPalette[px];
944 }
945 }
946 DestPtr += 2;
947 ZPtr += 2;
948 }
949 while (--data > 0);
950 }
951 }
952 DestPtr += LineSkip;
953 ZPtr += LineSkip;
954 }
955 while (--usHeight > 0);
956 }
957
958
959 /**********************************************************************************************
960 Blt8BPPDataTo16BPPBufferTransShadowZNBObscured
961
962 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
963 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
964 pixel's Z level is below that of the current pixel, it is written on. The Z value is NOT
965 updated. If the source pixel is 254, it is considered a shadow, and the destination
966 buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
967 dimensions (including Pitch) as the destination.
968
969 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZNBObscured(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,const UINT16 * p16BPPPalette)970 void Blt8BPPDataTo16BPPBufferTransShadowZNBObscured(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, const UINT16* p16BPPPalette)
971 {
972 UINT8 *DestPtr, *ZPtr;
973 UINT32 LineSkip;
974 UINT32 uiLineFlag;
975
976 // Assertions
977 Assert( hSrcVObject != NULL );
978 Assert( pBuffer != NULL );
979
980 // Get Offsets from Index into structure
981 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
982 UINT32 usHeight = pTrav.usHeight;
983 UINT32 const usWidth = pTrav.usWidth;
984
985 // Add to start position of dest buffer
986 INT32 const iTempX = iX + pTrav.sOffsetX;
987 INT32 const iTempY = iY + pTrav.sOffsetY;
988
989 // Validations
990 CHECKV(iTempX >= 0);
991 CHECKV(iTempY >= 0);
992
993 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
994 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
995 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
996 LineSkip=(uiDestPitchBYTES-(usWidth*2));
997 uiLineFlag=(iTempY&1);
998
999 do
1000 {
1001 for (;;)
1002 {
1003 UINT8 data = *SrcPtr++;
1004
1005 if (data == 0) break;
1006 if (data & 0x80)
1007 {
1008 data &= 0x7F;
1009 DestPtr += 2 * data;
1010 ZPtr += 2 * data;
1011 }
1012 else
1013 {
1014 do
1015 {
1016 UINT8 px = *SrcPtr++;
1017
1018 if (px == 254)
1019 {
1020 if (*(UINT16*)ZPtr < usZValue)
1021 {
1022 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1023 }
1024 }
1025 else
1026 {
1027 if (*(UINT16*)ZPtr <= usZValue ||
1028 uiLineFlag == (((uintptr_t)DestPtr & 2) != 0)) // XXX ugly, can be done better by just examining every other pixel
1029 {
1030 *(UINT16*)DestPtr = p16BPPPalette[px];
1031 }
1032 }
1033 DestPtr += 2;
1034 ZPtr += 2;
1035 }
1036 while (--data > 0);
1037 }
1038 }
1039 DestPtr += LineSkip;
1040 ZPtr += LineSkip;
1041 uiLineFlag ^= 1;
1042 }
1043 while (--usHeight > 0);
1044 }
1045
1046
1047 /**********************************************************************************************
1048 Blt8BPPDataTo16BPPBufferTransShadowZClip
1049
1050 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
1051 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
1052 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
1053 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
1054 must be the same dimensions (including Pitch) as the destination. Pixels with a value of
1055 254 are shaded instead of blitted.
1056
1057 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion,const UINT16 * p16BPPPalette)1058 void Blt8BPPDataTo16BPPBufferTransShadowZClip(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect* clipregion, const UINT16* p16BPPPalette)
1059 {
1060 UINT8 *DestPtr, *ZPtr;
1061 UINT32 LineSkip;
1062 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
1063 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
1064
1065 // Assertions
1066 Assert( hSrcVObject != NULL );
1067 Assert( pBuffer != NULL );
1068
1069 // Get Offsets from Index into structure
1070 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1071 UINT32 const usHeight = pTrav.usHeight;
1072 UINT32 const usWidth = pTrav.usWidth;
1073
1074 // Add to start position of dest buffer
1075 INT32 const iTempX = iX + pTrav.sOffsetX;
1076 INT32 const iTempY = iY + pTrav.sOffsetY;
1077
1078 if(clipregion==NULL)
1079 {
1080 ClipX1=ClippingRect.iLeft;
1081 ClipY1=ClippingRect.iTop;
1082 ClipX2=ClippingRect.iRight;
1083 ClipY2=ClippingRect.iBottom;
1084 }
1085 else
1086 {
1087 ClipX1=clipregion->iLeft;
1088 ClipY1=clipregion->iTop;
1089 ClipX2=clipregion->iRight;
1090 ClipY2=clipregion->iBottom;
1091 }
1092
1093 // Calculate rows hanging off each side of the screen
1094 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
1095 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
1096 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
1097 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
1098
1099 // calculate the remaining rows and columns to blit
1100 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
1101 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
1102
1103 // check if whole thing is clipped
1104 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
1105 return;
1106
1107 // check if whole thing is clipped
1108 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
1109 return;
1110
1111 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1112 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1113 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1114 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
1115
1116 UINT8 PxCount, px = 0;
1117 UINT32 Unblitted, LSCount;
1118
1119
1120 while (TopSkip)
1121 {
1122 px = *SrcPtr++;
1123 if (px & 0x80) continue;
1124 if (px)
1125 {
1126 SrcPtr += px;
1127 continue;
1128 }
1129 TopSkip--;
1130 }
1131
1132 do
1133 {
1134 Unblitted = 0;
1135 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
1136 {
1137 PxCount = *SrcPtr++;
1138 if (PxCount & 0x80)
1139 {
1140 PxCount &= 0x7F;
1141 if (PxCount > static_cast<UINT32>(LSCount))
1142 {
1143 PxCount -= LSCount;
1144 LSCount = BlitLength;
1145 Unblitted = 0;
1146 goto BlitTransparent;
1147 }
1148 }
1149 else
1150 {
1151 if (px > LSCount)
1152 {
1153 SrcPtr += LSCount;
1154 PxCount -= LSCount;
1155 LSCount = BlitLength;
1156 Unblitted = 0;
1157 goto BlitNonTransLoop;
1158 }
1159 SrcPtr += PxCount;
1160 }
1161 }
1162
1163 LSCount = BlitLength;
1164 Unblitted = 0;
1165 while (LSCount > 0)
1166 {
1167 PxCount = *SrcPtr++;
1168 if (PxCount & 0x80)
1169 {
1170 BlitTransparent: // skip transparent pixels
1171 PxCount &= 0x7f;
1172 if (PxCount > static_cast<UINT32>(LSCount))
1173 PxCount = LSCount;
1174
1175 LSCount -= PxCount;
1176 DestPtr += 2 * PxCount;
1177 ZPtr += 2 * PxCount;
1178 }
1179 else
1180 {
1181 BlitNonTransLoop: // blit non-transparent pixels
1182 if (PxCount > static_cast<UINT32>(LSCount))
1183 {
1184 PxCount -= LSCount;
1185 Unblitted = PxCount;
1186 PxCount = LSCount;
1187 }
1188 LSCount -= PxCount;
1189
1190 do
1191 {
1192 if (*ZPtr < usZValue )
1193 {
1194 *ZPtr = usZValue;
1195 px = *SrcPtr++;
1196 if (px != 254)
1197 *(UINT16*)DestPtr = p16BPPPalette[px];
1198 else
1199 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1200 }
1201
1202 DestPtr += 2;
1203 ZPtr += 2;
1204 }
1205 while ( --px > 0 );
1206 SrcPtr += Unblitted;
1207 }
1208 }
1209 while (*SrcPtr++ != 0);
1210 DestPtr += LineSkip;
1211 ZPtr += LineSkip;
1212 }
1213 while ( --BlitHeight > 0 );
1214 }
1215
1216 /**********************************************************************************************
1217 Blt8BPPDataTo16BPPBufferTransShadowClip
1218
1219 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
1220 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
1221 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
1222 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
1223 must be the same dimensions (including Pitch) as the destination. Pixels with a value of
1224 254 are shaded instead of blitted.
1225
1226 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion,const UINT16 * p16BPPPalette)1227 void Blt8BPPDataTo16BPPBufferTransShadowClip(UINT16* pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect* clipregion, const UINT16* p16BPPPalette)
1228 {
1229 UINT8 *DestPtr;
1230 UINT32 LineSkip;
1231 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
1232 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
1233
1234 // Assertions
1235 Assert( hSrcVObject != NULL );
1236 Assert( pBuffer != NULL );
1237
1238 // Get Offsets from Index into structure
1239 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1240 UINT32 const usHeight = pTrav.usHeight;
1241 UINT32 const usWidth = pTrav.usWidth;
1242
1243 // Add to start position of dest buffer
1244 INT32 const iTempX = iX + pTrav.sOffsetX;
1245 INT32 const iTempY = iY + pTrav.sOffsetY;
1246
1247 if(clipregion==NULL)
1248 {
1249 ClipX1=ClippingRect.iLeft;
1250 ClipY1=ClippingRect.iTop;
1251 ClipX2=ClippingRect.iRight;
1252 ClipY2=ClippingRect.iBottom;
1253 }
1254 else
1255 {
1256 ClipX1=clipregion->iLeft;
1257 ClipY1=clipregion->iTop;
1258 ClipX2=clipregion->iRight;
1259 ClipY2=clipregion->iBottom;
1260 }
1261
1262 // Calculate rows hanging off each side of the screen
1263 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
1264 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
1265 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
1266 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
1267
1268 // calculate the remaining rows and columns to blit
1269 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
1270 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
1271
1272 // check if whole thing is clipped
1273 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
1274 return;
1275
1276 // check if whole thing is clipped
1277 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
1278 return;
1279
1280 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1281 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1282 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
1283
1284 UINT8 PxCount, px = 0;
1285 UINT32 Unblitted;
1286 INT32 LSCount;
1287
1288 while (TopSkip)
1289 {
1290 px = *SrcPtr++;
1291 if (px & 0x80) continue;
1292 if (px)
1293 {
1294 SrcPtr += px;
1295 continue;
1296 }
1297 TopSkip--;
1298 }
1299
1300 do
1301 {
1302 Unblitted = 0;
1303 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
1304 {
1305 PxCount = *SrcPtr++;
1306 if (PxCount & 0x80)
1307 {
1308 PxCount &= 0x7F;
1309 if (PxCount > static_cast<UINT32>(LSCount))
1310 {
1311 PxCount -= LSCount;
1312 LSCount = BlitLength;
1313 Unblitted = 0;
1314 goto BlitTransparent;
1315 }
1316 }
1317 else
1318 {
1319 if (px > LSCount)
1320 {
1321 SrcPtr += LSCount;
1322 PxCount -= LSCount;
1323 LSCount = BlitLength;
1324 Unblitted = 0;
1325 goto BlitNonTransLoop;
1326 }
1327 SrcPtr += PxCount;
1328 }
1329 }
1330
1331 LSCount = BlitLength;
1332 Unblitted = 0;
1333 while (LSCount > 0)
1334 {
1335 PxCount = *SrcPtr++;
1336 if (PxCount & 0x80)
1337 {
1338 BlitTransparent: // skip transparent pixels
1339 PxCount &= 0x7f;
1340 if (PxCount > static_cast<UINT32>(LSCount))
1341 PxCount = LSCount;
1342
1343 LSCount -= PxCount;
1344 DestPtr += 2 * PxCount;
1345 }
1346 else
1347 {
1348 BlitNonTransLoop: // blit non-transparent pixels
1349 if (PxCount > static_cast<UINT32>(LSCount))
1350 {
1351 PxCount -= LSCount;
1352 Unblitted = PxCount;
1353 PxCount = LSCount;
1354 }
1355 LSCount -= PxCount;
1356
1357 do
1358 {
1359 px = *SrcPtr++;
1360 if (px != 254)
1361 *(UINT16*)DestPtr = p16BPPPalette[px];
1362 else
1363 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1364 DestPtr += 2;
1365 }
1366 while ( --px > 0 );
1367 SrcPtr += Unblitted;
1368 }
1369 }
1370 while (*SrcPtr++ != 0);
1371 DestPtr += LineSkip;
1372 }
1373 while ( --BlitHeight > 0 );
1374 }
1375
1376 /**********************************************************************************************
1377 Blt8BPPDataTo16BPPBufferTransShadowZNBClip
1378
1379 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
1380 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
1381 pixel's Z level is below that of the current pixel, it is written on.
1382 The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the
1383 destination. Pixels with a value of 254 are shaded instead of blitted. The Z buffer is
1384 NOT updated.
1385
1386 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZNBClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion,const UINT16 * p16BPPPalette)1387 void Blt8BPPDataTo16BPPBufferTransShadowZNBClip(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect* clipregion, const UINT16* p16BPPPalette)
1388 {
1389 UINT32 Unblitted;
1390 UINT8 *DestPtr, *ZPtr;
1391 UINT32 LineSkip;
1392 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
1393 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
1394
1395 // Assertions
1396 Assert( hSrcVObject != NULL );
1397 Assert( pBuffer != NULL );
1398
1399 // Get Offsets from Index into structure
1400 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1401 UINT32 const usHeight = pTrav.usHeight;
1402 UINT32 const usWidth = pTrav.usWidth;
1403
1404 // Add to start position of dest buffer
1405 INT32 const iTempX = iX + pTrav.sOffsetX;
1406 INT32 const iTempY = iY + pTrav.sOffsetY;
1407
1408 if(clipregion==NULL)
1409 {
1410 ClipX1=ClippingRect.iLeft;
1411 ClipY1=ClippingRect.iTop;
1412 ClipX2=ClippingRect.iRight;
1413 ClipY2=ClippingRect.iBottom;
1414 }
1415 else
1416 {
1417 ClipX1=clipregion->iLeft;
1418 ClipY1=clipregion->iTop;
1419 ClipX2=clipregion->iRight;
1420 ClipY2=clipregion->iBottom;
1421 }
1422
1423 // Calculate rows hanging off each side of the screen
1424 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
1425 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
1426 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
1427 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
1428
1429 // calculate the remaining rows and columns to blit
1430 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
1431 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
1432
1433 // check if whole thing is clipped
1434 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
1435 return;
1436
1437 // check if whole thing is clipped
1438 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
1439 return;
1440
1441 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1442 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1443 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1444 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
1445
1446 UINT32 PxCount;
1447
1448 while (TopSkip > 0)
1449 {
1450 for (;;)
1451 {
1452 PxCount = *SrcPtr++;
1453 if (PxCount & 0x80) continue;
1454 if (PxCount == 0) break;
1455 SrcPtr += PxCount;
1456 }
1457 TopSkip--;
1458 }
1459
1460 do
1461 {
1462 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
1463 {
1464 PxCount = *SrcPtr++;
1465 if (PxCount & 0x80)
1466 {
1467 PxCount &= 0x7F;
1468 if (PxCount > static_cast<UINT32>(LSCount))
1469 {
1470 PxCount -= LSCount;
1471 LSCount = BlitLength;
1472 goto BlitTransparent;
1473 }
1474 }
1475 else
1476 {
1477 if (PxCount > static_cast<UINT32>(LSCount))
1478 {
1479 SrcPtr += LSCount;
1480 PxCount -= LSCount;
1481 LSCount = BlitLength;
1482 goto BlitNonTransLoop;
1483 }
1484 SrcPtr += PxCount;
1485 }
1486 }
1487
1488 LSCount = BlitLength;
1489 while (LSCount > 0)
1490 {
1491 PxCount = *SrcPtr++;
1492 if (PxCount & 0x80)
1493 {
1494 BlitTransparent: // skip transparent pixels
1495 PxCount &= 0x7F;
1496 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
1497 LSCount -= PxCount;
1498 DestPtr += 2 * PxCount;
1499 ZPtr += 2 * PxCount;
1500 }
1501 else
1502 {
1503 BlitNonTransLoop: // blit non-transparent pixels
1504 if (PxCount > static_cast<UINT32>(LSCount))
1505 {
1506 Unblitted = PxCount - LSCount;
1507 PxCount = LSCount;
1508 }
1509 else
1510 {
1511 Unblitted = 0;
1512 }
1513 LSCount -= PxCount;
1514
1515 do
1516 {
1517 UINT8 px = *SrcPtr++;
1518
1519 if (px == 254)
1520 {
1521 if (*(UINT16*)ZPtr < usZValue)
1522 {
1523 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1524 }
1525 }
1526 else
1527 {
1528 if (*(UINT16*)ZPtr <= usZValue)
1529 {
1530 *(UINT16*)DestPtr = p16BPPPalette[px];
1531 }
1532 }
1533 DestPtr += 2;
1534 ZPtr += 2;
1535 }
1536 while (--PxCount > 0);
1537 SrcPtr += Unblitted;
1538 }
1539 }
1540
1541 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
1542 DestPtr += LineSkip;
1543 ZPtr += LineSkip;
1544 }
1545 while (--BlitHeight > 0);
1546 }
1547
1548
1549 /**********************************************************************************************
1550 Blt8BPPDataTo16BPPBufferTransShadowZNBClip
1551
1552 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
1553 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
1554 pixel's Z level is below that of the current pixel, it is written on.
1555 The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the
1556 destination. Pixels with a value of 254 are shaded instead of blitted. The Z buffer is
1557 NOT updated.
1558
1559 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion,const UINT16 * p16BPPPalette)1560 void Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect* clipregion, const UINT16* p16BPPPalette)
1561 {
1562 UINT32 Unblitted, uiLineFlag;
1563 UINT8 *DestPtr, *ZPtr;
1564 UINT32 LineSkip;
1565 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
1566 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
1567
1568 // Assertions
1569 Assert( hSrcVObject != NULL );
1570 Assert( pBuffer != NULL );
1571
1572 // Get Offsets from Index into structure
1573 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1574 UINT32 const usHeight = pTrav.usHeight;
1575 UINT32 const usWidth = pTrav.usWidth;
1576
1577 // Add to start position of dest buffer
1578 INT32 const iTempX = iX + pTrav.sOffsetX;
1579 INT32 const iTempY = iY + pTrav.sOffsetY;
1580
1581 if(clipregion==NULL)
1582 {
1583 ClipX1=ClippingRect.iLeft;
1584 ClipY1=ClippingRect.iTop;
1585 ClipX2=ClippingRect.iRight;
1586 ClipY2=ClippingRect.iBottom;
1587 }
1588 else
1589 {
1590 ClipX1=clipregion->iLeft;
1591 ClipY1=clipregion->iTop;
1592 ClipX2=clipregion->iRight;
1593 ClipY2=clipregion->iBottom;
1594 }
1595
1596 // Calculate rows hanging off each side of the screen
1597 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
1598 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
1599 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
1600 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
1601
1602 // calculate the remaining rows and columns to blit
1603 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
1604 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
1605
1606 // check if whole thing is clipped
1607 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
1608 return;
1609
1610 // check if whole thing is clipped
1611 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
1612 return;
1613
1614 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1615 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1616 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1617 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
1618
1619 uiLineFlag = (iTempY + TopSkip) & 1;
1620
1621 UINT32 PxCount;
1622
1623 while (TopSkip > 0)
1624 {
1625 for (;;)
1626 {
1627 PxCount = *SrcPtr++;
1628 if (PxCount & 0x80) continue;
1629 if (PxCount == 0) break;
1630 SrcPtr += PxCount;
1631 }
1632 TopSkip--;
1633 }
1634
1635 do
1636 {
1637 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
1638 {
1639 PxCount = *SrcPtr++;
1640 if (PxCount & 0x80)
1641 {
1642 PxCount &= 0x7F;
1643 if (PxCount > static_cast<UINT32>(LSCount))
1644 {
1645 PxCount -= LSCount;
1646 LSCount = BlitLength;
1647 goto BlitTransparent;
1648 }
1649 }
1650 else
1651 {
1652 if (PxCount > static_cast<UINT32>(LSCount))
1653 {
1654 SrcPtr += LSCount;
1655 PxCount -= LSCount;
1656 LSCount = BlitLength;
1657 goto BlitNonTransLoop;
1658 }
1659 SrcPtr += PxCount;
1660 }
1661 }
1662
1663 LSCount = BlitLength;
1664 while (LSCount > 0)
1665 {
1666 PxCount = *SrcPtr++;
1667 if (PxCount & 0x80)
1668 {
1669 BlitTransparent: // skip transparent pixels
1670 PxCount &= 0x7F;
1671 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
1672 LSCount -= PxCount;
1673 DestPtr += 2 * PxCount;
1674 ZPtr += 2 * PxCount;
1675 }
1676 else
1677 {
1678 BlitNonTransLoop: // blit non-transparent pixels
1679 if (PxCount > static_cast<UINT32>(LSCount))
1680 {
1681 Unblitted = PxCount - LSCount;
1682 PxCount = LSCount;
1683 }
1684 else
1685 {
1686 Unblitted = 0;
1687 }
1688 LSCount -= PxCount;
1689
1690 do
1691 {
1692 UINT8 px = *SrcPtr++;
1693
1694 if (px == 254)
1695 {
1696 if (*(UINT16*)ZPtr < usZValue)
1697 {
1698 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1699 }
1700 }
1701 else
1702 {
1703 if (*(UINT16*)ZPtr <= usZValue ||
1704 uiLineFlag == (((uintptr_t)DestPtr & 2) != 0)) // XXX ugly, can be done better by just examining every other pixel
1705 {
1706 *(UINT16*)DestPtr = p16BPPPalette[px];
1707 }
1708 }
1709 DestPtr += 2;
1710 ZPtr += 2;
1711 }
1712 while (--PxCount > 0);
1713 SrcPtr += Unblitted;
1714 }
1715 }
1716
1717 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
1718 DestPtr += LineSkip;
1719 ZPtr += LineSkip;
1720 uiLineFlag ^= 1;
1721 }
1722 while (--BlitHeight > 0);
1723 }
1724
1725
1726 /**********************************************************************************************
1727 Blt8BPPDataTo16BPPBufferShadowZ
1728
1729 Creates a shadow using a brush, but modifies the destination buffer only if the current
1730 Z level is equal to higher than what's in the Z buffer at that pixel location. It
1731 updates the Z buffer with the new Z level.
1732
1733 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferShadowZ(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)1734 void Blt8BPPDataTo16BPPBufferShadowZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
1735 {
1736 UINT8 *DestPtr, *ZPtr;
1737 UINT32 LineSkip;
1738
1739 // Assertions
1740 Assert( hSrcVObject != NULL );
1741 Assert( pBuffer != NULL );
1742
1743 // Get Offsets from Index into structure
1744 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1745 UINT32 usHeight = pTrav.usHeight;
1746 UINT32 const usWidth = pTrav.usWidth;
1747
1748 // Add to start position of dest buffer
1749 INT32 const iTempX = iX + pTrav.sOffsetX;
1750 INT32 const iTempY = iY + pTrav.sOffsetY;
1751
1752 // Validations
1753 CHECKV(iTempX >= 0);
1754 CHECKV(iTempY >= 0);
1755
1756 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1757 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
1758 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
1759 LineSkip=(uiDestPitchBYTES-(usWidth*2));
1760
1761 do
1762 {
1763 for (;;)
1764 {
1765 UINT8 data = *SrcPtr++;
1766
1767 if (data == 0) break;
1768 if (data & 0x80)
1769 {
1770 data &= 0x7F;
1771 DestPtr += 2 * data;
1772 ZPtr += 2 * data;
1773 }
1774 else
1775 {
1776 SrcPtr += data;
1777 do
1778 {
1779 if (*(UINT16*)ZPtr < usZValue)
1780 {
1781 *(UINT16*)ZPtr = usZValue;
1782 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1783 }
1784 DestPtr += 2;
1785 ZPtr += 2;
1786 }
1787 while (--data > 0);
1788 }
1789 }
1790 DestPtr += LineSkip;
1791 ZPtr += LineSkip;
1792 }
1793 while (--usHeight > 0);
1794 }
1795
1796
1797 /**********************************************************************************************
1798 Blt8BPPDataTo16BPPBufferShadowZClip
1799
1800 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
1801 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
1802 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
1803 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
1804 must be the same dimensions (including Pitch) as the destination.
1805
1806 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferShadowZClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)1807 void Blt8BPPDataTo16BPPBufferShadowZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
1808 {
1809 UINT8 *DestPtr, *ZPtr;
1810 UINT32 LineSkip;
1811 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
1812 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
1813
1814 // Assertions
1815 Assert( hSrcVObject != NULL );
1816 Assert( pBuffer != NULL );
1817
1818 // Get Offsets from Index into structure
1819 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1820 UINT32 const usHeight = pTrav.usHeight;
1821 UINT32 const usWidth = pTrav.usWidth;
1822
1823 // Add to start position of dest buffer
1824 INT32 const iTempX = iX + pTrav.sOffsetX;
1825 INT32 const iTempY = iY + pTrav.sOffsetY;
1826
1827 if(clipregion==NULL)
1828 {
1829 ClipX1=ClippingRect.iLeft;
1830 ClipY1=ClippingRect.iTop;
1831 ClipX2=ClippingRect.iRight;
1832 ClipY2=ClippingRect.iBottom;
1833 }
1834 else
1835 {
1836 ClipX1=clipregion->iLeft;
1837 ClipY1=clipregion->iTop;
1838 ClipX2=clipregion->iRight;
1839 ClipY2=clipregion->iBottom;
1840 }
1841
1842 // Calculate rows hanging off each side of the screen
1843 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
1844 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
1845 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
1846 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
1847
1848 // calculate the remaining rows and columns to blit
1849 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
1850 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
1851
1852 // check if whole thing is clipped
1853 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
1854 return;
1855
1856 // check if whole thing is clipped
1857 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
1858 return;
1859
1860 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1861 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1862 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
1863 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
1864
1865 UINT32 PxCount;
1866
1867 while (TopSkip > 0)
1868 {
1869 for (;;)
1870 {
1871 PxCount = *SrcPtr++;
1872 if (PxCount & 0x80) continue;
1873 if (PxCount == 0) break;
1874 SrcPtr += PxCount;
1875 }
1876 TopSkip--;
1877 }
1878
1879 do
1880 {
1881 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
1882 {
1883 PxCount = *SrcPtr++;
1884 if (PxCount & 0x80)
1885 {
1886 PxCount &= 0x7F;
1887 if (PxCount > static_cast<UINT32>(LSCount))
1888 {
1889 PxCount -= LSCount;
1890 LSCount = BlitLength;
1891 goto BlitTransparent;
1892 }
1893 }
1894 else
1895 {
1896 if (PxCount > static_cast<UINT32>(LSCount))
1897 {
1898 SrcPtr += LSCount;
1899 PxCount -= LSCount;
1900 LSCount = BlitLength;
1901 goto BlitNonTransLoop;
1902 }
1903 SrcPtr += PxCount;
1904 }
1905 }
1906
1907 LSCount = BlitLength;
1908 while (LSCount > 0)
1909 {
1910 PxCount = *SrcPtr++;
1911 if (PxCount & 0x80)
1912 {
1913 BlitTransparent: // skip transparent pixels
1914 PxCount &= 0x7F;
1915 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
1916 LSCount -= PxCount;
1917 DestPtr += 2 * PxCount;
1918 ZPtr += 2 * PxCount;
1919 }
1920 else
1921 {
1922 BlitNonTransLoop: // blit non-transparent pixels
1923 SrcPtr += PxCount;
1924 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
1925 LSCount -= PxCount;
1926
1927 do
1928 {
1929 if (*(UINT16*)ZPtr < usZValue)
1930 {
1931 *(UINT16*)ZPtr = usZValue;
1932 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
1933 }
1934 DestPtr += 2;
1935 ZPtr += 2;
1936 }
1937 while (--PxCount > 0);
1938 }
1939 }
1940
1941 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
1942 DestPtr += LineSkip;
1943 ZPtr += LineSkip;
1944 }
1945 while (--BlitHeight > 0);
1946 }
1947
1948
1949 /**********************************************************************************************
1950 Blt8BPPDataTo16BPPBufferShadowZNB
1951
1952 Creates a shadow using a brush, but modifies the destination buffer only if the current
1953 Z level is equal to higher than what's in the Z buffer at that pixel location. It does
1954 NOT update the Z buffer with the new Z value.
1955
1956 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferShadowZNB(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)1957 void Blt8BPPDataTo16BPPBufferShadowZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
1958 {
1959 UINT8 *DestPtr, *ZPtr;
1960 UINT32 LineSkip;
1961
1962 // Assertions
1963 Assert( hSrcVObject != NULL );
1964 Assert( pBuffer != NULL );
1965
1966 // Get Offsets from Index into structure
1967 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
1968 UINT32 usHeight = pTrav.usHeight;
1969 UINT32 const usWidth = pTrav.usWidth;
1970
1971 // Add to start position of dest buffer
1972 INT32 const iTempX = iX + pTrav.sOffsetX;
1973 INT32 const iTempY = iY + pTrav.sOffsetY;
1974
1975 // Validations
1976 CHECKV(iTempX >= 0);
1977 CHECKV(iTempY >= 0);
1978
1979 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
1980 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
1981 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
1982 LineSkip=(uiDestPitchBYTES-(usWidth*2));
1983
1984 do
1985 {
1986 for (;;)
1987 {
1988 UINT8 data = *SrcPtr++;
1989
1990 if (data == 0) break;
1991 if (data & 0x80)
1992 {
1993 data &= 0x7F;
1994 DestPtr += 2 * data;
1995 ZPtr += 2 * data;
1996 }
1997 else
1998 {
1999 do
2000 {
2001 if (*(UINT16*)ZPtr < usZValue)
2002 {
2003 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
2004 }
2005 }
2006 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --data > 0);
2007 }
2008 }
2009 DestPtr += LineSkip;
2010 ZPtr += LineSkip;
2011 }
2012 while (--usHeight > 0);
2013 }
2014
2015
2016 /**********************************************************************************************
2017 Blt8BPPDataTo16BPPBufferShadowZNBClip
2018
2019 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
2020 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
2021 pixel's Z level is below that of the current pixel, it is written on, the Z value is
2022 not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and must be the
2023 same dimensions (including Pitch) as the destination.
2024
2025 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferShadowZNBClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)2026 void Blt8BPPDataTo16BPPBufferShadowZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
2027 {
2028 UINT32 Unblitted;
2029 UINT8 *DestPtr, *ZPtr;
2030 UINT32 LineSkip;
2031 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
2032 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
2033
2034 // Assertions
2035 Assert( hSrcVObject != NULL );
2036 Assert( pBuffer != NULL );
2037
2038 // Get Offsets from Index into structure
2039 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
2040 UINT32 const usHeight = pTrav.usHeight;
2041 UINT32 const usWidth = pTrav.usWidth;
2042
2043 // Add to start position of dest buffer
2044 INT32 const iTempX = iX + pTrav.sOffsetX;
2045 INT32 const iTempY = iY + pTrav.sOffsetY;
2046
2047 if(clipregion==NULL)
2048 {
2049 ClipX1=ClippingRect.iLeft;
2050 ClipY1=ClippingRect.iTop;
2051 ClipX2=ClippingRect.iRight;
2052 ClipY2=ClippingRect.iBottom;
2053 }
2054 else
2055 {
2056 ClipX1=clipregion->iLeft;
2057 ClipY1=clipregion->iTop;
2058 ClipX2=clipregion->iRight;
2059 ClipY2=clipregion->iBottom;
2060 }
2061
2062 // Calculate rows hanging off each side of the screen
2063 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
2064 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
2065 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
2066 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
2067
2068 // calculate the remaining rows and columns to blit
2069 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
2070 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
2071
2072 // check if whole thing is clipped
2073 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
2074 return;
2075
2076 // check if whole thing is clipped
2077 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
2078 return;
2079
2080 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
2081 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2082 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2083 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
2084
2085 UINT32 PxCount;
2086
2087 while (TopSkip > 0)
2088 {
2089 for (;;)
2090 {
2091 PxCount = *SrcPtr++;
2092 if (PxCount & 0x80) continue;
2093 if (PxCount == 0) break;
2094 SrcPtr += PxCount;
2095 }
2096 TopSkip--;
2097 }
2098
2099 do
2100 {
2101 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
2102 {
2103 PxCount = *SrcPtr++;
2104 if (PxCount & 0x80)
2105 {
2106 PxCount &= 0x7F;
2107 if (PxCount > static_cast<UINT32>(LSCount))
2108 {
2109 PxCount -= LSCount;
2110 LSCount = BlitLength;
2111 goto BlitTransparent;
2112 }
2113 }
2114 else
2115 {
2116 if (PxCount > static_cast<UINT32>(LSCount))
2117 {
2118 SrcPtr += LSCount;
2119 PxCount -= LSCount;
2120 LSCount = BlitLength;
2121 goto BlitNonTransLoop;
2122 }
2123 SrcPtr += PxCount;
2124 }
2125 }
2126
2127 LSCount = BlitLength;
2128 while (LSCount > 0)
2129 {
2130 PxCount = *SrcPtr++;
2131 if (PxCount & 0x80)
2132 {
2133 BlitTransparent: // skip transparent pixels
2134 PxCount &= 0x7F;
2135 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
2136 LSCount -= PxCount;
2137 DestPtr += 2 * PxCount;
2138 ZPtr += 2 * PxCount;
2139 }
2140 else
2141 {
2142 BlitNonTransLoop: // blit non-transparent pixels
2143 if (PxCount > static_cast<UINT32>(LSCount))
2144 {
2145 Unblitted = PxCount - LSCount;
2146 PxCount = LSCount;
2147 }
2148 else
2149 {
2150 Unblitted = 0;
2151 }
2152 LSCount -= PxCount;
2153
2154 do
2155 {
2156 if (*(UINT16*)ZPtr < usZValue)
2157 {
2158 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
2159 }
2160 }
2161 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --PxCount > 0);
2162 SrcPtr += Unblitted;
2163 }
2164 }
2165
2166 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
2167 DestPtr += LineSkip;
2168 ZPtr += LineSkip;
2169 }
2170 while (--BlitHeight > 0);
2171 }
2172
2173
2174 /**********************************************************************************************
2175 Blt8BPPDataTo16BPPBufferTransZClip
2176
2177 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
2178 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
2179 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
2180 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
2181 must be the same dimensions (including Pitch) as the destination.
2182
2183 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)2184 void Blt8BPPDataTo16BPPBufferTransZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
2185 {
2186 UINT32 Unblitted;
2187 UINT8 *DestPtr, *ZPtr;
2188 UINT32 LineSkip;
2189 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
2190 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
2191
2192 // Assertions
2193 Assert( hSrcVObject != NULL );
2194 Assert( pBuffer != NULL );
2195
2196 // Get Offsets from Index into structure
2197 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
2198 UINT32 const usHeight = pTrav.usHeight;
2199 UINT32 const usWidth = pTrav.usWidth;
2200
2201 // Add to start position of dest buffer
2202 INT32 const iTempX = iX + pTrav.sOffsetX;
2203 INT32 const iTempY = iY + pTrav.sOffsetY;
2204
2205 if(clipregion==NULL)
2206 {
2207 ClipX1=ClippingRect.iLeft;
2208 ClipY1=ClippingRect.iTop;
2209 ClipX2=ClippingRect.iRight;
2210 ClipY2=ClippingRect.iBottom;
2211 }
2212 else
2213 {
2214 ClipX1=clipregion->iLeft;
2215 ClipY1=clipregion->iTop;
2216 ClipX2=clipregion->iRight;
2217 ClipY2=clipregion->iBottom;
2218 }
2219
2220 // Calculate rows hanging off each side of the screen
2221 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
2222 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
2223 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
2224 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
2225
2226 // calculate the remaining rows and columns to blit
2227 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
2228 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
2229
2230 // check if whole thing is clipped
2231 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
2232 return;
2233
2234 // check if whole thing is clipped
2235 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
2236 return;
2237
2238 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
2239 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2240 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2241 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
2242 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
2243
2244 UINT32 PxCount;
2245
2246 while (TopSkip > 0)
2247 {
2248 for (;;)
2249 {
2250 PxCount = *SrcPtr++;
2251 if (PxCount & 0x80) continue;
2252 if (PxCount == 0) break;
2253 SrcPtr += PxCount;
2254 }
2255 TopSkip--;
2256 }
2257
2258 do
2259 {
2260 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
2261 {
2262 PxCount = *SrcPtr++;
2263 if (PxCount & 0x80)
2264 {
2265 PxCount &= 0x7F;
2266 if (PxCount > static_cast<UINT32>(LSCount))
2267 {
2268 PxCount -= LSCount;
2269 LSCount = BlitLength;
2270 goto BlitTransparent;
2271 }
2272 }
2273 else
2274 {
2275 if (PxCount > static_cast<UINT32>(LSCount))
2276 {
2277 SrcPtr += LSCount;
2278 PxCount -= LSCount;
2279 LSCount = BlitLength;
2280 goto BlitNonTransLoop;
2281 }
2282 SrcPtr += PxCount;
2283 }
2284 }
2285
2286 LSCount = BlitLength;
2287 while (LSCount > 0)
2288 {
2289 PxCount = *SrcPtr++;
2290 if (PxCount & 0x80)
2291 {
2292 BlitTransparent: // skip transparent pixels
2293 PxCount &= 0x7F;
2294 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
2295 LSCount -= PxCount;
2296 DestPtr += 2 * PxCount;
2297 ZPtr += 2 * PxCount;
2298 }
2299 else
2300 {
2301 BlitNonTransLoop: // blit non-transparent pixels
2302 if (PxCount > static_cast<UINT32>(LSCount))
2303 {
2304 Unblitted = PxCount - LSCount;
2305 PxCount = LSCount;
2306 }
2307 else
2308 {
2309 Unblitted = 0;
2310 }
2311 LSCount -= PxCount;
2312
2313 do
2314 {
2315 if (*(UINT16*)ZPtr <= usZValue)
2316 {
2317 *(UINT16*)ZPtr = usZValue;
2318 *(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
2319 }
2320 SrcPtr++;
2321 DestPtr += 2;
2322 ZPtr += 2;
2323 }
2324 while (--PxCount > 0);
2325 SrcPtr += Unblitted;
2326 }
2327 }
2328
2329 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
2330 DestPtr += LineSkip;
2331 ZPtr += LineSkip;
2332 }
2333 while (--BlitHeight > 0);
2334 }
2335
2336
2337 /**********************************************************************************************
2338 Blt8BPPDataTo16BPPBufferTransZNBClip
2339
2340 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
2341 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
2342 pixel's Z level is below that of the current pixel, it is written on. The Z value is NOT
2343 updated in this version. The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
2344
2345 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZNBClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)2346 void Blt8BPPDataTo16BPPBufferTransZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
2347 {
2348 UINT32 Unblitted;
2349 UINT8 *DestPtr, *ZPtr;
2350 UINT32 LineSkip;
2351 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
2352 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
2353
2354 // Assertions
2355 Assert( hSrcVObject != NULL );
2356 Assert( pBuffer != NULL );
2357
2358 // Get Offsets from Index into structure
2359 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
2360 UINT32 const usHeight = pTrav.usHeight;
2361 UINT32 const usWidth = pTrav.usWidth;
2362
2363 // Add to start position of dest buffer
2364 INT32 const iTempX = iX + pTrav.sOffsetX;
2365 INT32 const iTempY = iY + pTrav.sOffsetY;
2366
2367 if(clipregion==NULL)
2368 {
2369 ClipX1=ClippingRect.iLeft;
2370 ClipY1=ClippingRect.iTop;
2371 ClipX2=ClippingRect.iRight;
2372 ClipY2=ClippingRect.iBottom;
2373 }
2374 else
2375 {
2376 ClipX1=clipregion->iLeft;
2377 ClipY1=clipregion->iTop;
2378 ClipX2=clipregion->iRight;
2379 ClipY2=clipregion->iBottom;
2380 }
2381
2382 // Calculate rows hanging off each side of the screen
2383 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
2384 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
2385 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
2386 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
2387
2388 // calculate the remaining rows and columns to blit
2389 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
2390 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
2391
2392 // check if whole thing is clipped
2393 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
2394 return;
2395
2396 // check if whole thing is clipped
2397 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
2398 return;
2399
2400 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
2401 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2402 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2403 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
2404 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
2405
2406 UINT32 PxCount;
2407
2408 while (TopSkip > 0)
2409 {
2410 for (;;)
2411 {
2412 PxCount = *SrcPtr++;
2413 if (PxCount & 0x80) continue;
2414 if (PxCount == 0) break;
2415 SrcPtr += PxCount;
2416 }
2417 TopSkip--;
2418 }
2419
2420 do
2421 {
2422 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
2423 {
2424 PxCount = *SrcPtr++;
2425 if (PxCount & 0x80)
2426 {
2427 PxCount &= 0x7F;
2428 if (PxCount > static_cast<UINT32>(LSCount))
2429 {
2430 PxCount -= LSCount;
2431 LSCount = BlitLength;
2432 goto BlitTransparent;
2433 }
2434 }
2435 else
2436 {
2437 if (PxCount > static_cast<UINT32>(LSCount))
2438 {
2439 SrcPtr += LSCount;
2440 PxCount -= LSCount;
2441 LSCount = BlitLength;
2442 goto BlitNonTransLoop;
2443 }
2444 SrcPtr += PxCount;
2445 }
2446 }
2447
2448 LSCount = BlitLength;
2449 while (LSCount > 0)
2450 {
2451 PxCount = *SrcPtr++;
2452 if (PxCount & 0x80)
2453 {
2454 BlitTransparent: // skip transparent pixels
2455 PxCount &= 0x7F;
2456 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
2457 LSCount -= PxCount;
2458 DestPtr += 2 * PxCount;
2459 ZPtr += 2 * PxCount;
2460 }
2461 else
2462 {
2463 BlitNonTransLoop: // blit non-transparent pixels
2464 if (PxCount > static_cast<UINT32>(LSCount))
2465 {
2466 Unblitted = PxCount - LSCount;
2467 PxCount = LSCount;
2468 }
2469 else
2470 {
2471 Unblitted = 0;
2472 }
2473 LSCount -= PxCount;
2474
2475 do
2476 {
2477 if (*(UINT16*)ZPtr <= usZValue)
2478 {
2479 *(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
2480 }
2481 SrcPtr++;
2482 DestPtr += 2;
2483 ZPtr += 2;
2484 }
2485 while (--PxCount > 0);
2486 SrcPtr += Unblitted;
2487 }
2488 }
2489
2490 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
2491 DestPtr += LineSkip;
2492 ZPtr += LineSkip;
2493 }
2494 while (--BlitHeight > 0);
2495 }
2496
2497
2498 /* Blit a subrect from a flat 8 bit surface to a 16-bit buffer. */
Blt8BPPDataSubTo16BPPBuffer(UINT16 * const buf,UINT32 const uiDestPitchBYTES,SGPVSurface * const hSrcVSurface,UINT8 * const pSrcBuffer,UINT32 const src_pitch,INT32 const x,INT32 const y,SGPBox const * const rect)2499 void Blt8BPPDataSubTo16BPPBuffer(UINT16* const buf, UINT32 const uiDestPitchBYTES, SGPVSurface* const hSrcVSurface, UINT8* const pSrcBuffer, UINT32 const src_pitch, INT32 const x, INT32 const y, SGPBox const* const rect)
2500 {
2501 Assert(hSrcVSurface);
2502 Assert(pSrcBuffer);
2503 Assert(buf);
2504
2505 CHECKV(x >= 0);
2506 CHECKV(y >= 0);
2507
2508 UINT32 const LeftSkip = rect->x;
2509 UINT32 const TopSkip = rect->y * src_pitch;
2510 UINT32 const BlitLength = rect->w;
2511 UINT32 BlitHeight = rect->h;
2512 UINT32 const src_skip = src_pitch - BlitLength;
2513
2514 UINT32 const pitch = uiDestPitchBYTES / 2;
2515 UINT8 const* src = pSrcBuffer + TopSkip + LeftSkip;
2516 UINT16* dst = buf + pitch * y + x;
2517 UINT16 const* const pal = hSrcVSurface->p16BPPPalette;
2518 UINT32 line_skip = pitch - BlitLength;
2519
2520 do
2521 {
2522 UINT32 w = BlitLength;
2523 do
2524 {
2525 *dst++ = pal[*src++];
2526 }
2527 while (--w != 0);
2528 src += src_skip;
2529 dst += line_skip;
2530 }
2531 while (--BlitHeight != 0);
2532 }
2533
2534
2535 /**********************************************************************************************
2536 Blt8BPPDataTo16BPPBuffer
2537
2538 Blits from a flat surface to a 16-bit buffer.
2539
2540 **********************************************************************************************/
Blt8BPPDataTo16BPPBuffer(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,SGPVSurface * hSrcVSurface,UINT8 * pSrcBuffer,INT32 iX,INT32 iY)2541 void Blt8BPPDataTo16BPPBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPVSurface* hSrcVSurface, UINT8 *pSrcBuffer, INT32 iX, INT32 iY)
2542 {
2543 INT32 iTempX, iTempY;
2544
2545 // Assertions
2546 Assert( hSrcVSurface != NULL );
2547 Assert( pSrcBuffer != NULL );
2548 Assert( pBuffer != NULL );
2549
2550 // Get Offsets from Index into structure
2551 UINT32 const usWidth = hSrcVSurface->Width();
2552 UINT32 const usHeight = hSrcVSurface->Height();
2553
2554 // Add to start position of dest buffer
2555 iTempX = iX;
2556 iTempY = iY;
2557
2558 // Validations
2559 CHECKV(iTempX >= 0);
2560 CHECKV(iTempY >= 0);
2561
2562 UINT8* SrcPtr = pSrcBuffer;
2563 UINT16* DestPtr = pBuffer + uiDestPitchBYTES / 2 * iTempY + iTempX;
2564 UINT16* p16BPPPalette = hSrcVSurface->p16BPPPalette;
2565
2566 for (size_t h = usHeight; h != 0; --h)
2567 {
2568 for (size_t w = 0; w != usWidth; ++w)
2569 {
2570 DestPtr[w] = p16BPPPalette[SrcPtr[w]];
2571 }
2572
2573 SrcPtr += usWidth;
2574 DestPtr += uiDestPitchBYTES / 2;
2575 }
2576 }
2577
2578
2579 /* Blit from a flat surface to a 16-bit buffer, dividing the source image into
2580 * exactly half the size, optionally from a sub-region.
2581 * - Source rect is in source units.
2582 * - In order to make sure the same pixels are skipped, always align the top and
2583 * left coordinates to the same factor of two.
2584 * - A rect specifying an odd number of pixels will divide out to an even number
2585 * of pixels blitted to the destination. */
Blt8BPPDataTo16BPPBufferHalf(UINT16 * const dst_buf,UINT32 const uiDestPitchBYTES,SGPVSurface * const src_surface,UINT8 const * const src_buf,UINT32 const src_pitch,INT32 const x,INT32 const y,SGPBox const * const rect)2586 void Blt8BPPDataTo16BPPBufferHalf(UINT16* const dst_buf, UINT32 const uiDestPitchBYTES, SGPVSurface* const src_surface, UINT8 const* const src_buf, UINT32 const src_pitch, INT32 const x, INT32 const y, SGPBox const* const rect)
2587 {
2588 Assert(src_surface);
2589 Assert(src_buf);
2590 Assert(dst_buf);
2591
2592 CHECKV(x >= 0);
2593 CHECKV(y >= 0);
2594
2595 UINT8 const* src = src_buf;
2596 UINT32 width;
2597 UINT32 height;
2598 if (rect)
2599 {
2600 width = rect->w;
2601 height = rect->h;
2602 CHECKV(0 < width && width <= src_surface->Width());
2603 CHECKV(0 < height && height <= src_surface->Height());
2604
2605 src += src_pitch * rect->y + rect->x;
2606 }
2607 else
2608 {
2609 width = src_surface->Width();
2610 height = src_surface->Height();
2611 }
2612
2613 UINT16* dst = dst_buf + uiDestPitchBYTES / 2 * y + x;
2614 UINT32 const src_skip = (src_pitch - width / 2) * 2;
2615 UINT32 const dst_skip = uiDestPitchBYTES / 2 - width / 2;
2616 UINT16 const* const pal = src_surface->p16BPPPalette;
2617
2618 height /= 2;
2619 do
2620 {
2621 UINT32 w = width / 2;
2622 do
2623 {
2624 *dst++ = pal[*src];
2625 src += 2;
2626 }
2627 while (--w > 0);
2628 src += src_skip;
2629 dst += dst_skip;
2630 }
2631 while (--height > 0);
2632 }
2633
2634
SetClippingRect(SGPRect * clip)2635 void SetClippingRect(SGPRect *clip)
2636 {
2637 Assert(clip!=NULL);
2638 Assert(clip->iLeft < clip->iRight);
2639 Assert(clip->iTop < clip->iBottom);
2640 ClippingRect = *clip;
2641 }
2642
2643
GetClippingRect(SGPRect * clip)2644 void GetClippingRect(SGPRect *clip)
2645 {
2646 Assert(clip!=NULL);
2647 *clip = ClippingRect;
2648 }
2649
2650
2651 /**********************************************************************************************
2652 Blt16BPPBufferPixelateRectWithColor
2653
2654 Given an 8x8 pattern and a color, pixelates an area by repeatedly "applying the color" to pixels whereever there
2655 is a non-zero value in the pattern.
2656
2657 KM: Added Nov. 23, 1998
2658 This is all the code that I moved from Blt16BPPBufferPixelateRect().
2659 This function now takes a color field (which previously was
2660 always black. The 3rd assembler line in this function:
2661
2662 mov ax, usColor // color of pixel
2663
2664 used to be:
2665
2666 xor eax, eax // color of pixel (black or 0)
2667
2668 This was the only internal modification I made other than adding the usColor argument.
2669
2670 *********************************************************************************************/
Blt16BPPBufferPixelateRectWithColor(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,SGPRect * area,const UINT8 Pattern[8][8],UINT16 usColor)2671 static void Blt16BPPBufferPixelateRectWithColor(UINT16* pBuffer, UINT32 uiDestPitchBYTES, SGPRect* area, const UINT8 Pattern[8][8], UINT16 usColor)
2672 {
2673 INT32 width, height;
2674 UINT32 LineSkip;
2675 UINT16 *DestPtr;
2676 INT32 iLeft, iTop, iRight, iBottom;
2677
2678 // Assertions
2679 Assert( pBuffer != NULL );
2680 Assert( Pattern != NULL );
2681
2682 iLeft=__max(ClippingRect.iLeft, area->iLeft);
2683 iTop=__max(ClippingRect.iTop, area->iTop);
2684 iRight=__min(ClippingRect.iRight-1, area->iRight);
2685 iBottom=__min(ClippingRect.iBottom-1, area->iBottom);
2686
2687 DestPtr=(pBuffer+(iTop*(uiDestPitchBYTES/2))+iLeft);
2688 width=iRight-iLeft+1;
2689 height=iBottom-iTop+1;
2690 LineSkip=(uiDestPitchBYTES-(width*2));
2691
2692 CHECKV(width >= 1);
2693 CHECKV(height >= 1);
2694
2695 UINT32 row = 0;
2696 do
2697 {
2698 UINT32 col = 0;
2699 UINT32 w = width;
2700
2701 do
2702 {
2703 if (Pattern[row][col] != 0) *DestPtr = usColor;
2704 DestPtr++;
2705 col = (col + 1) % 8;
2706 }
2707 while (--w > 0);
2708 DestPtr += LineSkip / 2;
2709 row = (row + 1) % 8;
2710 }
2711 while (--height > 0);
2712 }
2713
2714
2715 //Uses black hatch color
Blt16BPPBufferHatchRect(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,SGPRect * area)2716 void Blt16BPPBufferHatchRect(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area )
2717 {
2718 const UINT8 Pattern[8][8] =
2719 {
2720 { 1,0,1,0,1,0,1,0 },
2721 { 0,1,0,1,0,1,0,1 },
2722 { 1,0,1,0,1,0,1,0 },
2723 { 0,1,0,1,0,1,0,1 },
2724 { 1,0,1,0,1,0,1,0 },
2725 { 0,1,0,1,0,1,0,1 },
2726 { 1,0,1,0,1,0,1,0 },
2727 { 0,1,0,1,0,1,0,1 }
2728 };
2729 Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, 0 );
2730 }
2731
Blt16BPPBufferLooseHatchRectWithColor(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,SGPRect * area,UINT16 usColor)2732 void Blt16BPPBufferLooseHatchRectWithColor(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area, UINT16 usColor )
2733 {
2734 const UINT8 Pattern[8][8] =
2735 {
2736 { 1,0,0,0,1,0,0,0 },
2737 { 0,0,0,0,0,0,0,0 },
2738 { 0,0,1,0,0,0,1,0 },
2739 { 0,0,0,0,0,0,0,0 },
2740 { 1,0,0,0,1,0,0,0 },
2741 { 0,0,0,0,0,0,0,0 },
2742 { 0,0,1,0,0,0,1,0 },
2743 { 0,0,0,0,0,0,0,0 }
2744 };
2745 Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, usColor );
2746 }
2747
2748
2749 /**********************************************************************************************
2750 Blt8BPPDataTo16BPPBufferShadow
2751
2752 Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
2753 image as a mask. Any Non-zero index pixels are used to darken destination pixels.
2754
2755 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferShadow(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)2756 void Blt8BPPDataTo16BPPBufferShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex)
2757 {
2758 UINT8 *DestPtr;
2759 UINT32 LineSkip;
2760
2761 // Assertions
2762 Assert( hSrcVObject != NULL );
2763 Assert( pBuffer != NULL );
2764
2765 // Get Offsets from Index into structure
2766 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
2767 UINT32 usHeight = pTrav.usHeight;
2768 UINT32 const usWidth = pTrav.usWidth;
2769
2770 // Add to start position of dest buffer
2771 INT32 const iTempX = iX + pTrav.sOffsetX;
2772 INT32 const iTempY = iY + pTrav.sOffsetY;
2773
2774 // Validations
2775 CHECKV(iTempX >= 0);
2776 CHECKV(iTempY >= 0);
2777
2778 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
2779 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
2780 LineSkip=(uiDestPitchBYTES-(usWidth*2));
2781
2782 do
2783 {
2784 for (;;)
2785 {
2786 UINT8 data = *SrcPtr++;
2787
2788 if (data == 0) break;
2789 if (data & 0x80)
2790 {
2791 data &= 0x7F;
2792 DestPtr += 2 * data;
2793 }
2794 else
2795 {
2796 SrcPtr += data;
2797 do
2798 {
2799 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
2800 DestPtr += 2;
2801 }
2802 while (--data > 0);
2803 }
2804 }
2805 DestPtr += LineSkip;
2806 }
2807 while (--usHeight > 0);
2808 }
2809
2810
2811 /* Blit an image into the destination buffer, using an ETRLE brush as a source
2812 * and a 16-bit buffer as a destination. */
Blt8BPPDataTo16BPPBufferTransparent(UINT16 * const buf,UINT32 const uiDestPitchBYTES,SGPVObject const * const hSrcVObject,INT32 const iX,INT32 const iY,UINT16 const usIndex)2813 void Blt8BPPDataTo16BPPBufferTransparent(UINT16* const buf, UINT32 const uiDestPitchBYTES, SGPVObject const* const hSrcVObject, INT32 const iX, INT32 const iY, UINT16 const usIndex)
2814 {
2815 Assert(hSrcVObject);
2816 Assert(buf);
2817
2818 // Get offsets from index into structure
2819 ETRLEObject const& e = hSrcVObject->SubregionProperties(usIndex);
2820 UINT32 height = e.usHeight;
2821 UINT32 const width = e.usWidth;
2822
2823 // Add to start position of dest buffer
2824 INT32 const x = iX + e.sOffsetX;
2825 INT32 const y = iY + e.sOffsetY;
2826
2827 CHECKV(x >= 0);
2828 CHECKV(y >= 0);
2829
2830 UINT32 const pitch = uiDestPitchBYTES / 2;
2831 UINT8 const* src = hSrcVObject->PixData(e);
2832 UINT16* dst = buf + pitch * y + x;
2833 UINT16 const* const pal = hSrcVObject->CurrentShade();
2834 UINT32 line_skip = pitch - width;
2835
2836 for (;;)
2837 {
2838 UINT8 data = *src++;
2839 if (data == 0)
2840 {
2841 if (--height == 0) break;
2842 dst += line_skip;
2843 }
2844 else if (data & 0x80)
2845 { // Transparent
2846 dst += data & 0x7F;
2847 }
2848 else
2849 {
2850 do
2851 {
2852 *dst++ = pal[*src++];
2853 }
2854 while (--data != 0);
2855 }
2856 }
2857 }
2858
2859
2860 /**********************************************************************************************
2861 Blt8BPPDataTo16BPPBufferTransparentClip
2862
2863 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
2864 buffer as a destination. Clips the brush.
2865
2866 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransparentClip(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,const SGPVObject * const hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const SGPRect * const clipregion)2867 void Blt8BPPDataTo16BPPBufferTransparentClip(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, const SGPVObject* const hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const SGPRect* const clipregion)
2868 {
2869 UINT32 Unblitted;
2870 UINT8 *DestPtr;
2871 UINT32 LineSkip;
2872 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
2873 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
2874
2875 // Assertions
2876 Assert( hSrcVObject != NULL );
2877 Assert( pBuffer != NULL );
2878
2879 // Get Offsets from Index into structure
2880 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
2881 UINT32 const usHeight = pTrav.usHeight;
2882 UINT32 const usWidth = pTrav.usWidth;
2883
2884 // Add to start position of dest buffer
2885 INT32 const iTempX = iX + pTrav.sOffsetX;
2886 INT32 const iTempY = iY + pTrav.sOffsetY;
2887
2888 if(clipregion==NULL)
2889 {
2890 ClipX1=ClippingRect.iLeft;
2891 ClipY1=ClippingRect.iTop;
2892 ClipX2=ClippingRect.iRight;
2893 ClipY2=ClippingRect.iBottom;
2894 }
2895 else
2896 {
2897 ClipX1=clipregion->iLeft;
2898 ClipY1=clipregion->iTop;
2899 ClipX2=clipregion->iRight;
2900 ClipY2=clipregion->iBottom;
2901 }
2902
2903 // Calculate rows hanging off each side of the screen
2904 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
2905 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
2906 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
2907 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
2908
2909 // calculate the remaining rows and columns to blit
2910 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
2911 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
2912
2913 // check if whole thing is clipped
2914 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
2915 return;
2916
2917 // check if whole thing is clipped
2918 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
2919 return;
2920
2921 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
2922 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
2923 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
2924 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
2925
2926 UINT32 LSCount;
2927 UINT32 PxCount;
2928
2929 while (TopSkip > 0)
2930 {
2931 for (;;)
2932 {
2933 PxCount = *SrcPtr++;
2934 if (PxCount & 0x80) continue;
2935 if (PxCount == 0) break;
2936 SrcPtr += PxCount;
2937 }
2938 TopSkip--;
2939 }
2940
2941 do
2942 {
2943 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
2944 {
2945 PxCount = *SrcPtr++;
2946 if (PxCount & 0x80)
2947 {
2948 PxCount &= 0x7F;
2949 if (PxCount > static_cast<UINT32>(LSCount))
2950 {
2951 PxCount -= LSCount;
2952 LSCount = BlitLength;
2953 goto BlitTransparent;
2954 }
2955 }
2956 else
2957 {
2958 if (PxCount > static_cast<UINT32>(LSCount))
2959 {
2960 SrcPtr += LSCount;
2961 PxCount -= LSCount;
2962 LSCount = BlitLength;
2963 goto BlitNonTransLoop;
2964 }
2965 SrcPtr += PxCount;
2966 }
2967 }
2968
2969 LSCount = BlitLength;
2970 while (LSCount > 0)
2971 {
2972 PxCount = *SrcPtr++;
2973 if (PxCount & 0x80)
2974 {
2975 BlitTransparent: // skip transparent pixels
2976 PxCount &= 0x7F;
2977 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
2978 LSCount -= PxCount;
2979 DestPtr += 2 * PxCount;
2980 }
2981 else
2982 {
2983 BlitNonTransLoop: // blit non-transparent pixels
2984 if (PxCount > static_cast<UINT32>(LSCount))
2985 {
2986 Unblitted = PxCount - LSCount;
2987 PxCount = LSCount;
2988 }
2989 else
2990 {
2991 Unblitted = 0;
2992 }
2993 LSCount -= PxCount;
2994
2995 do
2996 {
2997 *(UINT16*)DestPtr = p16BPPPalette[*SrcPtr++];
2998 DestPtr += 2;
2999 }
3000 while (--PxCount > 0);
3001 SrcPtr += Unblitted;
3002 }
3003 }
3004
3005 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
3006 DestPtr += LineSkip;
3007 }
3008 while (--BlitHeight > 0);
3009 }
3010
3011
3012 /**********************************************************************************************
3013 BltIsClipped
3014
3015 Determines whether a given blit will need clipping or not. Returns TRUE/FALSE.
3016
3017 **********************************************************************************************/
BltIsClipped(const SGPVObject * const hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const SGPRect * const clipregion)3018 BOOLEAN BltIsClipped(const SGPVObject* const hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const SGPRect* const clipregion)
3019 {
3020 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3021
3022 // Assertions
3023 Assert( hSrcVObject != NULL );
3024
3025 // Get Offsets from Index into structure
3026 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3027 UINT32 const usHeight = pTrav.usHeight;
3028 UINT32 const usWidth = pTrav.usWidth;
3029
3030 // Add to start position of dest buffer
3031 INT32 const iTempX = iX + pTrav.sOffsetX;
3032 INT32 const iTempY = iY + pTrav.sOffsetY;
3033
3034 if(clipregion==NULL)
3035 {
3036 ClipX1=ClippingRect.iLeft;
3037 ClipY1=ClippingRect.iTop;
3038 ClipX2=ClippingRect.iRight;
3039 ClipY2=ClippingRect.iBottom;
3040 }
3041 else
3042 {
3043 ClipX1=clipregion->iLeft;
3044 ClipY1=clipregion->iTop;
3045 ClipX2=clipregion->iRight;
3046 ClipY2=clipregion->iBottom;
3047 }
3048
3049
3050 // Calculate rows hanging off each side of the screen
3051 if(__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth))
3052 return(TRUE);
3053
3054 if(__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth))
3055 return(TRUE);
3056
3057 if(__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight))
3058 return(TRUE);
3059
3060 if(__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight))
3061 return(TRUE);
3062
3063 return(FALSE);
3064 }
3065
3066
3067
3068 /**********************************************************************************************
3069 Blt8BPPDataTo16BPPBufferShadowClip
3070
3071 Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
3072 image as a mask. Any Non-zero index pixels are used to darken destination pixels. Blitter
3073 clips brush if it doesn't fit on the viewport.
3074
3075 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferShadowClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)3076 void Blt8BPPDataTo16BPPBufferShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
3077 {
3078 UINT8 *DestPtr;
3079 UINT32 LineSkip;
3080 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
3081 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3082
3083 // Assertions
3084 Assert( hSrcVObject != NULL );
3085 Assert( pBuffer != NULL );
3086
3087 // Get Offsets from Index into structure
3088 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3089 UINT32 const usHeight = pTrav.usHeight;
3090 UINT32 const usWidth = pTrav.usWidth;
3091
3092 // Add to start position of dest buffer
3093 INT32 const iTempX = iX + pTrav.sOffsetX;
3094 INT32 const iTempY = iY + pTrav.sOffsetY;
3095
3096 if(clipregion==NULL)
3097 {
3098 ClipX1=ClippingRect.iLeft;
3099 ClipY1=ClippingRect.iTop;
3100 ClipX2=ClippingRect.iRight;
3101 ClipY2=ClippingRect.iBottom;
3102 }
3103 else
3104 {
3105 ClipX1=clipregion->iLeft;
3106 ClipY1=clipregion->iTop;
3107 ClipX2=clipregion->iRight;
3108 ClipY2=clipregion->iBottom;
3109 }
3110
3111 // Calculate rows hanging off each side of the screen
3112 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
3113 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
3114 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
3115 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
3116
3117 // calculate the remaining rows and columns to blit
3118 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
3119 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
3120
3121 // whole thing is clipped
3122 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
3123 return;
3124
3125 // whole thing is clipped
3126 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
3127 return;
3128
3129 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
3130 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3131 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
3132
3133 UINT32 LSCount;
3134 UINT32 PxCount;
3135
3136 while (TopSkip > 0)
3137 {
3138 for (;;)
3139 {
3140 PxCount = *SrcPtr++;
3141 if (PxCount & 0x80) continue;
3142 if (PxCount == 0) break;
3143 SrcPtr += PxCount;
3144 }
3145 TopSkip--;
3146 }
3147
3148 do
3149 {
3150 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
3151 {
3152 PxCount = *SrcPtr++;
3153 if (PxCount & 0x80)
3154 {
3155 PxCount &= 0x7F;
3156 if (PxCount > static_cast<UINT32>(LSCount))
3157 {
3158 PxCount -= LSCount;
3159 LSCount = BlitLength;
3160 goto BlitTransparent;
3161 }
3162 }
3163 else
3164 {
3165 if (PxCount > static_cast<UINT32>(LSCount))
3166 {
3167 SrcPtr += LSCount;
3168 PxCount -= LSCount;
3169 LSCount = BlitLength;
3170 goto BlitNonTransLoop;
3171 }
3172 SrcPtr += PxCount;
3173 }
3174 }
3175
3176 LSCount = BlitLength;
3177 while (LSCount > 0)
3178 {
3179 PxCount = *SrcPtr++;
3180 if (PxCount & 0x80)
3181 {
3182 BlitTransparent: // skip transparent pixels
3183 PxCount &= 0x7F;
3184 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
3185 LSCount -= PxCount;
3186 DestPtr += 2 * PxCount;
3187 }
3188 else
3189 {
3190 BlitNonTransLoop: // blit non-transparent pixels
3191 SrcPtr += PxCount;
3192 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
3193 LSCount -= PxCount;
3194
3195 do
3196 {
3197 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
3198 DestPtr += 2;
3199 }
3200 while (--PxCount > 0);
3201 }
3202 }
3203
3204 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
3205 DestPtr += LineSkip;
3206 }
3207 while (--BlitHeight > 0);
3208 }
3209
3210
Blt16BPPBufferFilterRect(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,const UINT16 * filter_table,SGPRect * area)3211 void Blt16BPPBufferFilterRect(UINT16* pBuffer, UINT32 uiDestPitchBYTES, const UINT16* filter_table, SGPRect* area)
3212 {
3213 INT32 width, height;
3214 UINT32 LineSkip;
3215 UINT16 *DestPtr;
3216
3217 // Assertions
3218 Assert( pBuffer != NULL );
3219
3220 // Clipping
3221 if( area->iLeft < ClippingRect.iLeft )
3222 area->iLeft = ClippingRect.iLeft;
3223 if( area->iTop < ClippingRect.iTop )
3224 area->iTop = ClippingRect.iTop;
3225 if( area->iRight >= ClippingRect.iRight )
3226 area->iRight = ClippingRect.iRight - 1;
3227 if( area->iBottom >= ClippingRect.iBottom )
3228 area->iBottom = ClippingRect.iBottom - 1;
3229 //CHECKF(area->iLeft >= ClippingRect.iLeft );
3230 //CHECKF(area->iTop >= ClippingRect.iTop );
3231 //CHECKF(area->iRight <= ClippingRect.iRight );
3232 //CHECKF(area->iBottom <= ClippingRect.iBottom );
3233
3234 DestPtr=(pBuffer+(area->iTop*(uiDestPitchBYTES/2))+area->iLeft);
3235 width=area->iRight-area->iLeft+1;
3236 height=area->iBottom-area->iTop+1;
3237 LineSkip=(uiDestPitchBYTES-(width*2));
3238
3239 CHECKV(width >= 1);
3240 CHECKV(height >= 1);
3241
3242 do
3243 {
3244 UINT32 w = width;
3245
3246 do
3247 {
3248 *DestPtr = filter_table[*DestPtr];
3249 DestPtr++;
3250 }
3251 while (--w > 0);
3252 DestPtr = (UINT16*)((UINT8*)DestPtr + LineSkip);
3253 }
3254 while (--height > 0);
3255 }
3256
3257
3258 /**********************************************************************************************
3259 BltIsClippedOrOffScreen
3260
3261 Determines whether a given blit will need clipping or not. Returns TRUE/FALSE.
3262
3263 **********************************************************************************************/
BltIsClippedOrOffScreen(HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)3264 CHAR8 BltIsClippedOrOffScreen( HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion )
3265 {
3266 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3267
3268 // Assertions
3269 Assert( hSrcVObject != NULL );
3270
3271 // Get Offsets from Index into structure
3272 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3273 UINT32 const usHeight = pTrav.usHeight;
3274 UINT32 const usWidth = pTrav.usWidth;
3275
3276 // Add to start position of dest buffer
3277 INT32 const iTempX = iX + pTrav.sOffsetX;
3278 INT32 const iTempY = iY + pTrav.sOffsetY;
3279
3280 if(clipregion==NULL)
3281 {
3282 ClipX1=ClippingRect.iLeft;
3283 ClipY1=ClippingRect.iTop;
3284 ClipX2=ClippingRect.iRight;
3285 ClipY2=ClippingRect.iBottom;
3286 }
3287 else
3288 {
3289 ClipX1=clipregion->iLeft;
3290 ClipY1=clipregion->iTop;
3291 ClipX2=clipregion->iRight;
3292 ClipY2=clipregion->iBottom;
3293 }
3294
3295
3296 // Calculate rows hanging off each side of the screen
3297 INT32 gLeftSkip = __min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
3298 INT32 gTopSkip = __min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
3299 INT32 gRightSkip = __min( MAX(ClipX2, iTempX + (INT32)usWidth) - ClipX2, (INT32)usWidth);
3300 INT32 gBottomSkip = __min(__max(ClipY2, iTempY + (INT32)usHeight) - ClipY2, (INT32)usHeight);
3301
3302 // check if whole thing is clipped
3303 if((gLeftSkip >=(INT32)usWidth) || (gRightSkip >=(INT32)usWidth))
3304 return(-1 );
3305
3306 // check if whole thing is clipped
3307 if((gTopSkip >=(INT32)usHeight) || (gBottomSkip >=(INT32)usHeight))
3308 return(-1 );
3309
3310
3311 if ( gLeftSkip )
3312 return( TRUE );
3313
3314 if ( gRightSkip )
3315 return( TRUE );
3316
3317 if ( gTopSkip )
3318 return( TRUE );
3319
3320 if ( gBottomSkip )
3321 return( TRUE );
3322
3323
3324 return(FALSE);
3325 }
3326
3327
3328 // ATE New blitter for rendering a differrent color for value 254. Can be transparent if outline is SGP_TRANSPARENT
Blt8BPPDataTo16BPPBufferOutline(UINT16 * const buf,UINT32 const uiDestPitchBYTES,SGPVObject const * const hSrcVObject,INT32 const iX,INT32 const iY,UINT16 const usIndex,INT16 const outline)3329 void Blt8BPPDataTo16BPPBufferOutline(UINT16* const buf, UINT32 const uiDestPitchBYTES, SGPVObject const* const hSrcVObject, INT32 const iX, INT32 const iY, UINT16 const usIndex, INT16 const outline)
3330 {
3331 Assert(hSrcVObject);
3332 Assert(buf);
3333
3334 // Get offsets from index into structure
3335 ETRLEObject const& e = hSrcVObject->SubregionProperties(usIndex);
3336 UINT32 height = e.usHeight;
3337 UINT32 const width = e.usWidth;
3338
3339 // Add to start position of dest buffer
3340 INT32 const x = iX + e.sOffsetX;
3341 INT32 const y = iY + e.sOffsetY;
3342
3343 CHECKV(x >= 0);
3344 CHECKV(y >= 0);
3345
3346 UINT8 const* src = hSrcVObject->PixData(e);
3347 UINT32 const pitch = uiDestPitchBYTES / 2;
3348 UINT16* dst = buf + pitch * y + x;
3349 UINT32 line_skip = pitch - width;
3350 UINT16 const* const pal = hSrcVObject->CurrentShade();
3351
3352 for (;;)
3353 {
3354 UINT8 data = *src++;
3355 if (data == 0)
3356 {
3357 if (--height == 0) break;
3358 dst += line_skip;
3359 }
3360 else if (data & 0x80)
3361 {
3362 dst += data & 0x7F;
3363 }
3364 else
3365 {
3366 do
3367 {
3368 UINT8 const px = *src++;
3369 if (px != 254)
3370 {
3371 *dst = pal[px];
3372 }
3373 else if (outline != SGP_TRANSPARENT)
3374 {
3375 *dst = outline;
3376 }
3377 ++dst;
3378 }
3379 while (--data != 0);
3380 }
3381 }
3382 }
3383
3384
3385 // ATE New blitter for rendering a differrent color for value 254. Can be transparent if s16BPPColor is SGP_TRANSPARENT
Blt8BPPDataTo16BPPBufferOutlineClip(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,const SGPVObject * const hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const INT16 s16BPPColor,const SGPRect * const clipregion)3386 void Blt8BPPDataTo16BPPBufferOutlineClip(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, const SGPVObject* const hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const INT16 s16BPPColor, const SGPRect* const clipregion)
3387 {
3388 UINT32 Unblitted;
3389 UINT8 *DestPtr;
3390 UINT32 LineSkip;
3391 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
3392 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3393
3394 // Assertions
3395 Assert( hSrcVObject != NULL );
3396 Assert( pBuffer != NULL );
3397
3398 // Get Offsets from Index into structure
3399 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3400 UINT32 const usHeight = pTrav.usHeight;
3401 UINT32 const usWidth = pTrav.usWidth;
3402
3403 // Add to start position of dest buffer
3404 INT32 const iTempX = iX + pTrav.sOffsetX;
3405 INT32 const iTempY = iY + pTrav.sOffsetY;
3406
3407 if(clipregion==NULL)
3408 {
3409 ClipX1=ClippingRect.iLeft;
3410 ClipY1=ClippingRect.iTop;
3411 ClipX2=ClippingRect.iRight;
3412 ClipY2=ClippingRect.iBottom;
3413 }
3414 else
3415 {
3416 ClipX1=clipregion->iLeft;
3417 ClipY1=clipregion->iTop;
3418 ClipX2=clipregion->iRight;
3419 ClipY2=clipregion->iBottom;
3420 }
3421
3422 // Calculate rows hanging off each side of the screen
3423 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
3424 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
3425 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
3426 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
3427
3428 // calculate the remaining rows and columns to blit
3429 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
3430 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
3431
3432 // check if whole thing is clipped
3433 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
3434 return;
3435
3436 // check if whole thing is clipped
3437 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
3438 return;
3439
3440 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
3441 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3442 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
3443 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
3444
3445 UINT32 PxCount;
3446
3447 while (TopSkip > 0)
3448 {
3449 for (;;)
3450 {
3451 PxCount = *SrcPtr++;
3452 if (PxCount & 0x80) continue;
3453 if (PxCount == 0) break;
3454 SrcPtr += PxCount;
3455 }
3456 TopSkip--;
3457 }
3458
3459 do
3460 {
3461 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
3462 {
3463 PxCount = *SrcPtr++;
3464 if (PxCount & 0x80)
3465 {
3466 PxCount &= 0x7F;
3467 if (PxCount > static_cast<UINT32>(LSCount))
3468 {
3469 PxCount -= LSCount;
3470 LSCount = BlitLength;
3471 goto BlitTransparent;
3472 }
3473 }
3474 else
3475 {
3476 if (PxCount > static_cast<UINT32>(LSCount))
3477 {
3478 SrcPtr += LSCount;
3479 PxCount -= LSCount;
3480 LSCount = BlitLength;
3481 goto BlitNonTransLoop;
3482 }
3483 SrcPtr += PxCount;
3484 }
3485 }
3486
3487 LSCount = BlitLength;
3488 while (LSCount > 0)
3489 {
3490 PxCount = *SrcPtr++;
3491 if (PxCount & 0x80)
3492 {
3493 BlitTransparent: // skip transparent pixels
3494 PxCount &= 0x7F;
3495 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
3496 LSCount -= PxCount;
3497 DestPtr += 2 * PxCount;
3498 }
3499 else
3500 {
3501 BlitNonTransLoop: // blit non-transparent pixels
3502 if (PxCount > static_cast<UINT32>(LSCount))
3503 {
3504 Unblitted = PxCount - LSCount;
3505 PxCount = LSCount;
3506 }
3507 else
3508 {
3509 Unblitted = 0;
3510 }
3511 LSCount -= PxCount;
3512
3513 do
3514 {
3515 UINT32 src = *SrcPtr++;
3516
3517 if (src != 254)
3518 {
3519 *(UINT16*)DestPtr = p16BPPPalette[src];
3520 }
3521 else if (s16BPPColor != SGP_TRANSPARENT)
3522 {
3523 *(UINT16*)DestPtr = s16BPPColor;
3524 }
3525 DestPtr += 2;
3526 }
3527 while (--PxCount > 0);
3528 SrcPtr += Unblitted;
3529 }
3530 }
3531
3532 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
3533 DestPtr += LineSkip;
3534 }
3535 while (--BlitHeight > 0);
3536 }
3537
3538
Blt8BPPDataTo16BPPBufferOutlineZClip(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,UINT16 * const pZBuffer,const UINT16 usZValue,const HVOBJECT hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const INT16 s16BPPColor,const SGPRect * const clipregion)3539 void Blt8BPPDataTo16BPPBufferOutlineZClip(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, UINT16* const pZBuffer, const UINT16 usZValue, const HVOBJECT hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const INT16 s16BPPColor, const SGPRect* const clipregion)
3540 {
3541 UINT32 Unblitted;
3542 UINT8 *DestPtr, *ZPtr;
3543 UINT32 LineSkip;
3544 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
3545 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3546
3547 // Assertions
3548 Assert( hSrcVObject != NULL );
3549 Assert( pBuffer != NULL );
3550
3551 // Get Offsets from Index into structure
3552 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3553 UINT32 const usHeight = pTrav.usHeight;
3554 UINT32 const usWidth = pTrav.usWidth;
3555
3556 // Add to start position of dest buffer
3557 INT32 const iTempX = iX + pTrav.sOffsetX;
3558 INT32 const iTempY = iY + pTrav.sOffsetY;
3559
3560 if(clipregion==NULL)
3561 {
3562 ClipX1=ClippingRect.iLeft;
3563 ClipY1=ClippingRect.iTop;
3564 ClipX2=ClippingRect.iRight;
3565 ClipY2=ClippingRect.iBottom;
3566 }
3567 else
3568 {
3569 ClipX1=clipregion->iLeft;
3570 ClipY1=clipregion->iTop;
3571 ClipX2=clipregion->iRight;
3572 ClipY2=clipregion->iBottom;
3573 }
3574
3575 // Calculate rows hanging off each side of the screen
3576 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
3577 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
3578 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
3579 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
3580
3581 // calculate the remaining rows and columns to blit
3582 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
3583 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
3584
3585 // check if whole thing is clipped
3586 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
3587 return;
3588
3589 // check if whole thing is clipped
3590 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
3591 return;
3592
3593 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
3594 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3595 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3596
3597 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
3598 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
3599
3600 UINT32 PxCount;
3601
3602 while (TopSkip > 0)
3603 {
3604 for (;;)
3605 {
3606 PxCount = *SrcPtr++;
3607 if (PxCount & 0x80) continue;
3608 if (PxCount == 0) break;
3609 SrcPtr += PxCount;
3610 }
3611 TopSkip--;
3612 }
3613
3614 do
3615 {
3616 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
3617 {
3618 PxCount = *SrcPtr++;
3619 if (PxCount & 0x80)
3620 {
3621 PxCount &= 0x7F;
3622 if (PxCount > static_cast<UINT32>(LSCount))
3623 {
3624 PxCount -= LSCount;
3625 LSCount = BlitLength;
3626 goto BlitTransparent;
3627 }
3628 }
3629 else
3630 {
3631 if (PxCount > static_cast<UINT32>(LSCount))
3632 {
3633 SrcPtr += LSCount;
3634 PxCount -= LSCount;
3635 LSCount = BlitLength;
3636 goto BlitNonTransLoop;
3637 }
3638 SrcPtr += PxCount;
3639 }
3640 }
3641
3642 LSCount = BlitLength;
3643 while (LSCount > 0)
3644 {
3645 PxCount = *SrcPtr++;
3646 if (PxCount & 0x80)
3647 {
3648 BlitTransparent: // skip transparent pixels
3649 PxCount &= 0x7F;
3650 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
3651 LSCount -= PxCount;
3652 DestPtr += 2 * PxCount;
3653 ZPtr += 2 * PxCount;
3654 }
3655 else
3656 {
3657 BlitNonTransLoop: // blit non-transparent pixels
3658 if (PxCount > static_cast<UINT32>(LSCount))
3659 {
3660 Unblitted = PxCount - LSCount;
3661 PxCount = LSCount;
3662 }
3663 else
3664 {
3665 Unblitted = 0;
3666 }
3667 LSCount -= PxCount;
3668
3669 do
3670 {
3671 if (*(UINT16*)ZPtr <= usZValue)
3672 {
3673 UINT32 src = *SrcPtr;
3674
3675 if (src != 254)
3676 {
3677 *(UINT16*)ZPtr = usZValue;
3678 *(UINT16*)DestPtr = p16BPPPalette[src];
3679 }
3680 else
3681 {
3682 *(UINT16*)DestPtr = s16BPPColor;
3683 }
3684 }
3685 SrcPtr++;
3686 DestPtr += 2;
3687 ZPtr += 2;
3688 }
3689 while (--PxCount > 0);
3690 SrcPtr += Unblitted;
3691 }
3692 }
3693
3694 while (*SrcPtr++ != 0) {} // skip along until we hit an end-of-line marker
3695 DestPtr += LineSkip;
3696 ZPtr += LineSkip;
3697 }
3698 while (--BlitHeight > 0);
3699 }
3700
3701
Blt8BPPDataTo16BPPBufferOutlineZPixelateObscuredClip(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,UINT16 * const pZBuffer,const UINT16 usZValue,const HVOBJECT hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const INT16 s16BPPColor,const SGPRect * const clipregion)3702 void Blt8BPPDataTo16BPPBufferOutlineZPixelateObscuredClip(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, UINT16* const pZBuffer, const UINT16 usZValue, const HVOBJECT hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const INT16 s16BPPColor, const SGPRect* const clipregion)
3703 {
3704 UINT32 Unblitted;
3705 UINT8 *DestPtr, *ZPtr;
3706 UINT32 LineSkip;
3707 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
3708 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3709 UINT32 uiLineFlag;
3710
3711 // Assertions
3712 Assert( hSrcVObject != NULL );
3713 Assert( pBuffer != NULL );
3714
3715 // Get Offsets from Index into structure
3716 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3717 UINT32 const usHeight = pTrav.usHeight;
3718 UINT32 const usWidth = pTrav.usWidth;
3719
3720 // Add to start position of dest buffer
3721 INT32 const iTempX = iX + pTrav.sOffsetX;
3722 INT32 const iTempY = iY + pTrav.sOffsetY;
3723
3724 if(clipregion==NULL)
3725 {
3726 ClipX1=ClippingRect.iLeft;
3727 ClipY1=ClippingRect.iTop;
3728 ClipX2=ClippingRect.iRight;
3729 ClipY2=ClippingRect.iBottom;
3730 }
3731 else
3732 {
3733 ClipX1=clipregion->iLeft;
3734 ClipY1=clipregion->iTop;
3735 ClipX2=clipregion->iRight;
3736 ClipY2=clipregion->iBottom;
3737 }
3738
3739 // Calculate rows hanging off each side of the screen
3740 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
3741 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
3742 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
3743 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
3744
3745 // calculate the remaining rows and columns to blit
3746 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
3747 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
3748
3749 // check if whole thing is clipped
3750 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
3751 return;
3752
3753 // check if whole thing is clipped
3754 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
3755 return;
3756
3757 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
3758 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3759 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3760
3761 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
3762 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
3763 uiLineFlag=(iTempY&1);
3764
3765
3766 uiLineFlag = (iTempY + TopSkip) & 1;
3767
3768 UINT32 PxCount;
3769
3770 while (TopSkip > 0)
3771 {
3772 for (;;)
3773 {
3774 PxCount = *SrcPtr++;
3775 if (PxCount & 0x80) continue;
3776 if (PxCount == 0) break;
3777 SrcPtr += PxCount;
3778 }
3779 TopSkip--;
3780 }
3781
3782 do
3783 {
3784 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
3785 {
3786 PxCount = *SrcPtr++;
3787 if (PxCount & 0x80)
3788 {
3789 PxCount &= 0x7F;
3790 if (PxCount > static_cast<UINT32>(LSCount))
3791 {
3792 PxCount -= LSCount;
3793 LSCount = BlitLength;
3794 goto BlitTransparent;
3795 }
3796 }
3797 else
3798 {
3799 if (PxCount > static_cast<UINT32>(LSCount))
3800 {
3801 SrcPtr += LSCount;
3802 PxCount -= LSCount;
3803 LSCount = BlitLength;
3804 goto BlitNonTransLoop;
3805 }
3806 SrcPtr += PxCount;
3807 }
3808 }
3809
3810 LSCount = BlitLength;
3811 while (LSCount > 0)
3812 {
3813 PxCount = *SrcPtr++;
3814 if (PxCount & 0x80)
3815 {
3816 BlitTransparent: // skip transparent pixels
3817 PxCount &= 0x7F;
3818 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
3819 LSCount -= PxCount;
3820 DestPtr += 2 * PxCount;
3821 ZPtr += 2 * PxCount;
3822 }
3823 else
3824 {
3825 BlitNonTransLoop: // blit non-transparent pixels
3826 if (PxCount > static_cast<UINT32>(LSCount))
3827 {
3828 Unblitted = PxCount - LSCount;
3829 PxCount = LSCount;
3830 }
3831 else
3832 {
3833 Unblitted = 0;
3834 }
3835 LSCount -= PxCount;
3836
3837 do
3838 {
3839 if (*(UINT16*)ZPtr <= usZValue)
3840 {
3841 *(UINT16*)ZPtr = usZValue;
3842 }
3843 else
3844 {
3845 // XXX original code updates Z value in one of two cases on this path, seems wrong
3846 if (uiLineFlag != (((uintptr_t)DestPtr & 2) != 0)) continue;
3847 }
3848
3849 UINT8 px = *SrcPtr;
3850 if (px == 254)
3851 {
3852 *(UINT16*)DestPtr = s16BPPColor;
3853 }
3854 else
3855 {
3856 // XXX original code writes garbage (lower 8 bit are the colour index) into the Z buffer at this point
3857 *(UINT16*)DestPtr = p16BPPPalette[px];
3858 }
3859 }
3860 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --PxCount > 0);
3861 SrcPtr += Unblitted;
3862 }
3863 }
3864
3865 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
3866 DestPtr += LineSkip;
3867 ZPtr += LineSkip;
3868 uiLineFlag ^= 1;
3869 }
3870 while (--BlitHeight > 0);
3871 }
3872
3873
Blt8BPPDataTo16BPPBufferOutlineShadow(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,const SGPVObject * const hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex)3874 void Blt8BPPDataTo16BPPBufferOutlineShadow(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, const SGPVObject* const hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex)
3875 {
3876 UINT8 *DestPtr;
3877 UINT32 LineSkip;
3878
3879 // Assertions
3880 Assert( hSrcVObject != NULL );
3881 Assert( pBuffer != NULL );
3882
3883 // Get Offsets from Index into structure
3884 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3885 UINT32 usHeight = pTrav.usHeight;
3886 UINT32 const usWidth = pTrav.usWidth;
3887
3888 // Add to start position of dest buffer
3889 INT32 const iTempX = iX + pTrav.sOffsetX;
3890 INT32 const iTempY = iY + pTrav.sOffsetY;
3891
3892 // Validations
3893 CHECKV(iTempX >= 0);
3894 CHECKV(iTempY >= 0);
3895
3896 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
3897 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
3898 LineSkip=(uiDestPitchBYTES-(usWidth*2));
3899
3900 do
3901 {
3902 for (;;)
3903 {
3904 UINT8 data = *SrcPtr++;
3905
3906 if (data == 0) break;
3907 if (data & 0x80)
3908 {
3909 data &= 0x7F;
3910 DestPtr += data * 2;
3911 }
3912 else
3913 {
3914 do
3915 {
3916 if (*SrcPtr++ != 254)
3917 {
3918 *(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
3919 }
3920 DestPtr += 2;
3921 }
3922 while (--data > 0);
3923 }
3924 }
3925 DestPtr += LineSkip;
3926 }
3927 while (--usHeight > 0);
3928 }
3929
3930
Blt8BPPDataTo16BPPBufferOutlineShadowClip(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,const SGPVObject * const hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const SGPRect * const clipregion)3931 void Blt8BPPDataTo16BPPBufferOutlineShadowClip(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, const SGPVObject* const hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const SGPRect* const clipregion)
3932 {
3933 #if 1 // XXX TODO
3934 UNIMPLEMENTED
3935 #else
3936 UINT8 *DestPtr;
3937 UINT32 LineSkip;
3938 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
3939 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
3940
3941 // Assertions
3942 Assert( hSrcVObject != NULL );
3943 Assert( pBuffer != NULL );
3944
3945 // Get Offsets from Index into structure
3946 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
3947 UINT32 const usHeight = pTrav.usHeight;
3948 UINT32 const usWidth = pTrav.usWidth;
3949
3950 // Add to start position of dest buffer
3951 INT32 const iTempX = iX + pTrav.sOffsetX;
3952 INT32 const iTempY = iY + pTrav.sOffsetY;
3953
3954 if(clipregion==NULL)
3955 {
3956 ClipX1=ClippingRect.iLeft;
3957 ClipY1=ClippingRect.iTop;
3958 ClipX2=ClippingRect.iRight;
3959 ClipY2=ClippingRect.iBottom;
3960 }
3961 else
3962 {
3963 ClipX1=clipregion->iLeft;
3964 ClipY1=clipregion->iTop;
3965 ClipX2=clipregion->iRight;
3966 ClipY2=clipregion->iBottom;
3967 }
3968
3969 // Calculate rows hanging off each side of the screen
3970 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
3971 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
3972 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
3973 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
3974
3975 // calculate the remaining rows and columns to blit
3976 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
3977 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
3978
3979 // whole thing is clipped
3980 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
3981 return;
3982
3983 // whole thing is clipped
3984 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
3985 return;
3986
3987 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
3988 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
3989 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
3990
3991 UINT32 Unblitted;
3992 __asm {
3993
3994 mov esi, SrcPtr
3995 mov edi, DestPtr
3996 mov edx, OFFSET ShadeTable
3997 xor eax, eax
3998 mov ebx, TopSkip
3999 xor ecx, ecx
4000
4001 or ebx, ebx // check for nothing clipped on top
4002 jz LeftSkipSetup
4003
4004 TopSkipLoop: // Skips the number of lines clipped at the top
4005
4006 mov cl, [esi]
4007 inc esi
4008 or cl, cl
4009 js TopSkipLoop
4010 jz TSEndLine
4011
4012
4013 // Check for outline as well
4014 mov cl, [esi]
4015 cmp cl, 254
4016 je TopSkipLoop
4017 //
4018
4019 add esi, ecx
4020 jmp TopSkipLoop
4021
4022 TSEndLine:
4023 dec ebx
4024 jnz TopSkipLoop
4025
4026
4027
4028
4029 LeftSkipSetup:
4030
4031 mov Unblitted, 0
4032 mov ebx, LeftSkip // check for nothing clipped on the left
4033 or ebx, ebx
4034 jz BlitLineSetup
4035
4036 LeftSkipLoop:
4037
4038 mov cl, [esi]
4039 inc esi
4040
4041 or cl, cl
4042 js LSTrans
4043
4044 cmp ecx, ebx
4045 je LSSkip2 // if equal, skip whole, and start blit with new run
4046 jb LSSkip1 // if less, skip whole thing
4047
4048 add esi, ebx // skip partial run, jump into normal loop for rest
4049 sub ecx, ebx
4050 mov ebx, BlitLength
4051 mov Unblitted, 0
4052 jmp BlitNonTransLoop
4053
4054 LSSkip2:
4055 add esi, ecx // skip whole run, and start blit with new run
4056 jmp BlitLineSetup
4057
4058
4059 LSSkip1:
4060 add esi, ecx // skip whole run, continue skipping
4061 sub ebx, ecx
4062 jmp LeftSkipLoop
4063
4064
4065 LSTrans:
4066 and ecx, 07fH
4067 cmp ecx, ebx
4068 je BlitLineSetup // if equal, skip whole, and start blit with new run
4069 jb LSTrans1 // if less, skip whole thing
4070
4071 sub ecx, ebx // skip partial run, jump into normal loop for rest
4072 mov ebx, BlitLength
4073 jmp BlitTransparent
4074
4075
4076 LSTrans1:
4077 sub ebx, ecx // skip whole run, continue skipping
4078 jmp LeftSkipLoop
4079
4080
4081
4082
4083 BlitLineSetup: // Does any actual blitting (trans/non) for the line
4084 mov ebx, BlitLength
4085 mov Unblitted, 0
4086
4087 BlitDispatch:
4088
4089 or ebx, ebx // Check to see if we're done blitting
4090 jz RightSkipLoop
4091
4092 mov cl, [esi]
4093 inc esi
4094 or cl, cl
4095 js BlitTransparent
4096
4097 BlitNonTransLoop:
4098
4099 cmp ecx, ebx
4100 jbe BNTrans1
4101
4102 sub ecx, ebx
4103 mov Unblitted, ecx
4104 mov ecx, ebx
4105
4106 BNTrans1:
4107 sub ebx, ecx
4108
4109 clc
4110 rcr cl, 1
4111 jnc BlitNTL2
4112
4113 mov ax, [edi]
4114 mov ax, [edx+eax*2]
4115 mov [edi], ax
4116
4117 inc esi
4118 add edi, 2
4119
4120 BlitNTL2:
4121 clc
4122 rcr cl, 1
4123 jnc BlitNTL3
4124
4125 mov ax, [edi]
4126 mov ax, [edx+eax*2]
4127 mov [edi], ax
4128
4129 mov ax, [edi+2]
4130 mov ax, [edx+eax*2]
4131 mov [edi+2], ax
4132
4133 add esi, 2
4134 add edi, 4
4135
4136 BlitNTL3:
4137
4138 or cl, cl
4139 jz BlitLineEnd
4140
4141 BlitNTL4:
4142
4143 mov ax, [edi]
4144 mov ax, [edx+eax*2]
4145 mov [edi], ax
4146
4147 mov ax, [edi+2]
4148 mov ax, [edx+eax*2]
4149 mov [edi+2], ax
4150
4151 mov ax, [edi+4]
4152 mov ax, [edx+eax*2]
4153 mov [edi+4], ax
4154
4155 mov ax, [edi+6]
4156 mov ax, [edx+eax*2]
4157 mov [edi+6], ax
4158
4159 add esi, 4
4160 add edi, 8
4161 dec cl
4162 jnz BlitNTL4
4163
4164 BlitLineEnd:
4165 add esi, Unblitted
4166 jmp BlitDispatch
4167
4168 BlitTransparent:
4169
4170 and ecx, 07fH
4171 cmp ecx, ebx
4172 jbe BTrans1
4173
4174 mov ecx, ebx
4175
4176 BTrans1:
4177
4178 sub ebx, ecx
4179 // shl ecx, 1
4180 add ecx, ecx
4181 add edi, ecx
4182 jmp BlitDispatch
4183
4184
4185 RightSkipLoop:
4186
4187
4188 RSLoop1:
4189 mov al, [esi]
4190 inc esi
4191 or al, al
4192 jnz RSLoop1
4193
4194 dec BlitHeight
4195 jz BlitDone
4196 add edi, LineSkip
4197
4198 jmp LeftSkipSetup
4199
4200
4201 BlitDone:
4202 }
4203 #endif
4204 }
4205
4206
Blt8BPPDataTo16BPPBufferOutlineZ(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,UINT16 * const pZBuffer,const UINT16 usZValue,const HVOBJECT hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const INT16 s16BPPColor)4207 void Blt8BPPDataTo16BPPBufferOutlineZ(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, UINT16* const pZBuffer, const UINT16 usZValue, const HVOBJECT hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const INT16 s16BPPColor)
4208 {
4209 UINT8 *DestPtr, *ZPtr;
4210 UINT32 LineSkip;
4211
4212 // Assertions
4213 Assert( hSrcVObject != NULL );
4214 Assert( pBuffer != NULL );
4215
4216 // Get Offsets from Index into structure
4217 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
4218 UINT32 usHeight = pTrav.usHeight;
4219 UINT32 const usWidth = pTrav.usWidth;
4220
4221 // Add to start position of dest buffer
4222 INT32 const iTempX = iX + pTrav.sOffsetX;
4223 INT32 const iTempY = iY + pTrav.sOffsetY;
4224
4225 // Validations
4226 CHECKV(iTempX >= 0);
4227 CHECKV(iTempY >= 0);
4228
4229 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
4230 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4231 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4232 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
4233 LineSkip=(uiDestPitchBYTES-(usWidth*2));
4234
4235 #if 1 // XXX TODO
4236 do
4237 {
4238 for (;;)
4239 {
4240 UINT8 data = *SrcPtr++;
4241
4242 if (data == 0) break;
4243 if (data & 0x80)
4244 {
4245 data &= 0x7F;
4246 DestPtr += 2 * data;
4247 ZPtr += 2 * data;
4248 }
4249 else
4250 {
4251 do
4252 {
4253 if (*(UINT16*)ZPtr <= usZValue)
4254 {
4255 UINT8 px = *SrcPtr;
4256
4257 if (px == 254)
4258 {
4259 *(UINT16*)DestPtr = s16BPPColor;
4260 }
4261 else
4262 {
4263 *(UINT16*)ZPtr = usZValue; // XXX TODO original code writes garbage into the Z buffer, but comment says don't write at all
4264 *(UINT16*)DestPtr = p16BPPPalette[px];
4265 }
4266 }
4267 SrcPtr++;
4268 DestPtr += 2;
4269 ZPtr += 2;
4270 }
4271 while (--data > 0);
4272 }
4273 }
4274 DestPtr += LineSkip;
4275 ZPtr += LineSkip;
4276 }
4277 while (--usHeight > 0);
4278 #else
4279 __asm {
4280
4281 mov esi, SrcPtr
4282 mov edi, DestPtr
4283 mov edx, p16BPPPalette
4284 xor eax, eax
4285 mov ebx, ZPtr
4286 xor ecx, ecx
4287
4288 BlitDispatch:
4289
4290 mov cl, [esi]
4291 inc esi
4292 or cl, cl
4293 js BlitTransparent
4294 jz BlitDoneLine
4295
4296 //BlitNonTransLoop:
4297
4298 xor eax, eax
4299
4300 BlitNTL4:
4301
4302 mov ax, usZValue
4303 cmp ax, [ebx]
4304 jb BlitNTL5
4305
4306 // CHECK FOR OUTLINE, BLIT DIFFERENTLY IF WE WANT IT TO!
4307 mov al, [esi]
4308 cmp al, 254
4309 jne BlitNTL6
4310
4311 // DO OUTLINE
4312 // ONLY IF WE WANT IT!
4313 mov al, fDoOutline;
4314 cmp al, 1
4315 jne BlitNTL5
4316
4317 mov ax, s16BPPColor
4318 mov [edi], ax
4319 jmp BlitNTL5
4320
4321 BlitNTL6:
4322
4323 //Donot write to z-buffer
4324 mov [ebx], ax
4325
4326 xor ah, ah
4327 mov al, [esi]
4328 mov ax, [edx+eax*2]
4329 mov [edi], ax
4330
4331 BlitNTL5:
4332 inc esi
4333 inc edi
4334 inc ebx
4335 inc edi
4336 inc ebx
4337
4338 dec cl
4339 jnz BlitNTL4
4340
4341 jmp BlitDispatch
4342
4343
4344 BlitTransparent:
4345
4346 and ecx, 07fH
4347 // shl ecx, 1
4348 add ecx, ecx
4349 add edi, ecx
4350 add ebx, ecx
4351 jmp BlitDispatch
4352
4353
4354 BlitDoneLine:
4355
4356 dec usHeight
4357 jz BlitDone
4358 add edi, LineSkip
4359 add ebx, LineSkip
4360 jmp BlitDispatch
4361
4362
4363 BlitDone:
4364 }
4365 #endif
4366 }
4367
4368
Blt8BPPDataTo16BPPBufferOutlineZPixelateObscured(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,UINT16 * const pZBuffer,const UINT16 usZValue,const HVOBJECT hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex,const INT16 s16BPPColor)4369 void Blt8BPPDataTo16BPPBufferOutlineZPixelateObscured(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, UINT16* const pZBuffer, const UINT16 usZValue, const HVOBJECT hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex, const INT16 s16BPPColor)
4370 {
4371 UINT8 *DestPtr, *ZPtr;
4372 UINT32 LineSkip;
4373 UINT32 uiLineFlag;
4374
4375 // Assertions
4376 Assert( hSrcVObject != NULL );
4377 Assert( pBuffer != NULL );
4378
4379 // Get Offsets from Index into structure
4380 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
4381 UINT32 usHeight = pTrav.usHeight;
4382 UINT32 const usWidth = pTrav.usWidth;
4383
4384 // Add to start position of dest buffer
4385 INT32 const iTempX = iX + pTrav.sOffsetX;
4386 INT32 const iTempY = iY + pTrav.sOffsetY;
4387
4388 // Validations
4389 CHECKV(iTempX >= 0);
4390 CHECKV(iTempY >= 0);
4391
4392 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
4393 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4394 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4395 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
4396 LineSkip=(uiDestPitchBYTES-(usWidth*2));
4397 uiLineFlag=(iTempY&1);
4398
4399 #if 1 // XXX TODO
4400 do
4401 {
4402 for (;;)
4403 {
4404 UINT8 data = *SrcPtr++;
4405
4406 if (data == 0) break;
4407 if (data & 0x80)
4408 {
4409 data &= 0x7F;
4410 DestPtr += 2 * data;
4411 ZPtr += 2 * data;
4412 }
4413 else
4414 {
4415 do
4416 {
4417 if (*(UINT16*)ZPtr < usZValue)
4418 {
4419 *(UINT16*)ZPtr = usZValue;
4420 }
4421 else
4422 {
4423 // XXX original code updates Z value in one of two cases on this path, seems wrong
4424 if (uiLineFlag != (((uintptr_t)DestPtr & 2) != 0)) continue;
4425 }
4426
4427 UINT8 px = *SrcPtr;
4428 if (px == 254)
4429 {
4430 *(UINT16*)DestPtr = s16BPPColor;
4431 }
4432 else
4433 {
4434 *(UINT16*)DestPtr = p16BPPPalette[px];
4435 }
4436 }
4437 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --data > 0);
4438 }
4439 }
4440 DestPtr += LineSkip;
4441 ZPtr += LineSkip;
4442 uiLineFlag ^= 1;
4443 }
4444 while (--usHeight > 0);
4445 #else
4446 __asm {
4447
4448 mov esi, SrcPtr
4449 mov edi, DestPtr
4450 mov edx, p16BPPPalette
4451 xor eax, eax
4452 mov ebx, ZPtr
4453 xor ecx, ecx
4454
4455 BlitDispatch:
4456
4457 mov cl, [esi]
4458 inc esi
4459 or cl, cl
4460 js BlitTransparent
4461 jz BlitDoneLine
4462
4463 //BlitNonTransLoop:
4464
4465 xor eax, eax
4466
4467 BlitNTL4:
4468
4469 mov ax, usZValue
4470 cmp ax, [ebx]
4471 jbe BlitNTL8
4472
4473 // Write it now!
4474 jmp BlitNTL7
4475
4476 BlitNTL8:
4477
4478 test uiLineFlag, 1
4479 jz BlitNTL6
4480
4481 test edi, 2
4482 jz BlitNTL5
4483 jmp BlitNTL9
4484
4485
4486 BlitNTL6:
4487
4488 test edi, 2
4489 jnz BlitNTL5
4490
4491 BlitNTL7:
4492
4493 mov [ebx], ax
4494
4495 BlitNTL9:
4496
4497 // CHECK FOR OUTLINE, BLIT DIFFERENTLY IF WE WANT IT TO!
4498 mov al, [esi]
4499 cmp al, 254
4500 jne BlitNTL12
4501
4502 // DO OUTLINE
4503 // ONLY IF WE WANT IT!
4504 mov al, fDoOutline;
4505 cmp al, 1
4506 jne BlitNTL5
4507
4508 mov ax, s16BPPColor
4509 mov [edi], ax
4510 jmp BlitNTL5
4511
4512 BlitNTL12:
4513
4514 xor ah, ah
4515 mov al, [esi]
4516 mov ax, [edx+eax*2]
4517 mov [edi], ax
4518
4519 BlitNTL5:
4520 inc esi
4521 inc edi
4522 inc ebx
4523 inc edi
4524 inc ebx
4525
4526 dec cl
4527 jnz BlitNTL4
4528
4529 jmp BlitDispatch
4530
4531
4532 BlitTransparent:
4533
4534 and ecx, 07fH
4535 // shl ecx, 1
4536 add ecx, ecx
4537 add edi, ecx
4538 add ebx, ecx
4539 jmp BlitDispatch
4540
4541
4542 BlitDoneLine:
4543
4544 dec usHeight
4545 jz BlitDone
4546 add edi, LineSkip
4547 add ebx, LineSkip
4548 xor uiLineFlag, 1
4549 jmp BlitDispatch
4550
4551
4552 BlitDone:
4553 }
4554 #endif
4555 }
4556
4557
4558 // This is the same as above, but DONOT WRITE to Z!
Blt8BPPDataTo16BPPBufferOutlineZNB(UINT16 * const pBuffer,const UINT32 uiDestPitchBYTES,UINT16 * const pZBuffer,const UINT16 usZValue,const HVOBJECT hSrcVObject,const INT32 iX,const INT32 iY,const UINT16 usIndex)4559 void Blt8BPPDataTo16BPPBufferOutlineZNB(UINT16* const pBuffer, const UINT32 uiDestPitchBYTES, UINT16* const pZBuffer, const UINT16 usZValue, const HVOBJECT hSrcVObject, const INT32 iX, const INT32 iY, const UINT16 usIndex)
4560 {
4561 UINT8 *DestPtr, *ZPtr;
4562 UINT32 LineSkip;
4563
4564 // Assertions
4565 Assert( hSrcVObject != NULL );
4566 Assert( pBuffer != NULL );
4567
4568 // Get Offsets from Index into structure
4569 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
4570 UINT32 usHeight = pTrav.usHeight;
4571 UINT32 const usWidth = pTrav.usWidth;
4572
4573 // Add to start position of dest buffer
4574 INT32 const iTempX = iX + pTrav.sOffsetX;
4575 INT32 const iTempY = iY + pTrav.sOffsetY;
4576
4577 // Validations
4578 CHECKV(iTempX >= 0);
4579 CHECKV(iTempY >= 0);
4580
4581 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
4582 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4583 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4584 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
4585 LineSkip=(uiDestPitchBYTES-(usWidth*2));
4586
4587 do
4588 {
4589 for (;;)
4590 {
4591 UINT8 data = *SrcPtr++;
4592
4593 if (data == 0) break;
4594 if (data & 0x80)
4595 {
4596 data &= 0x7F;
4597 DestPtr += 2 * data;
4598 ZPtr += 2 * data;
4599 }
4600 else
4601 {
4602 do
4603 {
4604 if (*(UINT16*)ZPtr < usZValue)
4605 {
4606 UINT8 px = *SrcPtr;
4607 if (px != 254)
4608 {
4609 *(UINT16*)DestPtr = p16BPPPalette[px];
4610 }
4611 }
4612 }
4613 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --data > 0);
4614 }
4615 }
4616 DestPtr += LineSkip;
4617 ZPtr += LineSkip;
4618 }
4619 while (--usHeight > 0);
4620 }
4621
4622
4623 /**********************************************************************************************
4624 Blt8BPPDataTo16BPPBufferIntensityZ
4625
4626 Creates a shadow using a brush, but modifies the destination buffer only if the current
4627 Z level is equal to higher than what's in the Z buffer at that pixel location. It
4628 updates the Z buffer with the new Z level.
4629
4630 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferIntensityZ(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)4631 void Blt8BPPDataTo16BPPBufferIntensityZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
4632 {
4633 #if 1 // XXX TODO
4634 UNIMPLEMENTED
4635 #else
4636 UINT8 *DestPtr, *ZPtr;
4637 UINT32 LineSkip;
4638
4639 // Assertions
4640 Assert( hSrcVObject != NULL );
4641 Assert( pBuffer != NULL );
4642
4643 // Get Offsets from Index into structure
4644 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
4645 UINT32 const usHeight = pTrav.usHeight;
4646 UINT32 const usWidth = pTrav.usWidth;
4647
4648 // Add to start position of dest buffer
4649 INT32 const iTempX = iX + pTrav.sOffsetX;
4650 INT32 const iTempY = iY + pTrav.sOffsetY;
4651
4652 // Validations
4653 CHECKV(iTempX >= 0);
4654 CHECKV(iTempY >= 0);
4655
4656 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
4657 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4658 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
4659 LineSkip=(uiDestPitchBYTES-(usWidth*2));
4660
4661 __asm {
4662
4663 mov esi, SrcPtr
4664 mov edi, DestPtr
4665 mov edx, OFFSET IntensityTable
4666 xor eax, eax
4667 mov ebx, ZPtr
4668 xor ecx, ecx
4669
4670 BlitDispatch:
4671
4672 mov cl, [esi]
4673 inc esi
4674 or cl, cl
4675 js BlitTransparent
4676 jz BlitDoneLine
4677
4678 //BlitNonTransLoop:
4679
4680 BlitNTL4:
4681
4682 mov ax, [ebx]
4683 cmp ax, usZValue
4684 jae BlitNTL5
4685
4686 xor eax, eax
4687 mov ax, [edi]
4688 mov ax, [edx+eax*2]
4689 mov [edi], ax
4690 mov ax, usZValue
4691 mov [ebx], ax
4692
4693 BlitNTL5:
4694 inc esi
4695 add edi, 2
4696 add ebx, 2
4697 dec cl
4698 jnz BlitNTL4
4699
4700 jmp BlitDispatch
4701
4702
4703 BlitTransparent:
4704
4705 and ecx, 07fH
4706 // shl ecx, 1
4707 add ecx, ecx
4708 add edi, ecx
4709 add ebx, ecx
4710 jmp BlitDispatch
4711
4712
4713 BlitDoneLine:
4714
4715 dec usHeight
4716 jz BlitDone
4717 add edi, LineSkip
4718 add ebx, LineSkip
4719 jmp BlitDispatch
4720
4721
4722 BlitDone:
4723 }
4724 #endif
4725 }
4726
4727
4728 /**********************************************************************************************
4729 Blt8BPPDataTo16BPPBufferIntensityZClip
4730
4731 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
4732 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
4733 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
4734 updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
4735 must be the same dimensions (including Pitch) as the destination.
4736
4737 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferIntensityZClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)4738 void Blt8BPPDataTo16BPPBufferIntensityZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
4739 {
4740 #if 1 // XXX TODO
4741 UNIMPLEMENTED
4742 #else
4743 UINT8 *DestPtr, *ZPtr;
4744 UINT32 LineSkip;
4745 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
4746 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
4747
4748 // Assertions
4749 Assert( hSrcVObject != NULL );
4750 Assert( pBuffer != NULL );
4751
4752 // Get Offsets from Index into structure
4753 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
4754 UINT32 const usHeight = pTrav.usHeight;
4755 UINT32 const usWidth = pTrav.usWidth;
4756
4757 // Add to start position of dest buffer
4758 INT32 const iTempX = iX + pTrav.sOffsetX;
4759 INT32 const iTempY = iY + pTrav.sOffsetY;
4760
4761 if(clipregion==NULL)
4762 {
4763 ClipX1=ClippingRect.iLeft;
4764 ClipY1=ClippingRect.iTop;
4765 ClipX2=ClippingRect.iRight;
4766 ClipY2=ClippingRect.iBottom;
4767 }
4768 else
4769 {
4770 ClipX1=clipregion->iLeft;
4771 ClipY1=clipregion->iTop;
4772 ClipX2=clipregion->iRight;
4773 ClipY2=clipregion->iBottom;
4774 }
4775
4776 // Calculate rows hanging off each side of the screen
4777 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
4778 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
4779 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
4780 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
4781
4782 // calculate the remaining rows and columns to blit
4783 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
4784 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
4785
4786 // check if whole thing is clipped
4787 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
4788 return;
4789
4790 // check if whole thing is clipped
4791 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
4792 return;
4793
4794 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
4795 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
4796 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
4797 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
4798
4799 UINT32 Unblitted;
4800 INT32 LSCount;
4801 __asm {
4802
4803 mov esi, SrcPtr
4804 mov edi, DestPtr
4805 mov edx, OFFSET IntensityTable
4806 xor eax, eax
4807 mov ebx, ZPtr
4808 xor ecx, ecx
4809
4810 cmp TopSkip, 0 // check for nothing clipped on top
4811 je LeftSkipSetup
4812
4813 TopSkipLoop: // Skips the number of lines clipped at the top
4814
4815 mov cl, [esi]
4816 inc esi
4817 or cl, cl
4818 js TopSkipLoop
4819 jz TSEndLine
4820
4821 add esi, ecx
4822 jmp TopSkipLoop
4823
4824 TSEndLine:
4825 dec TopSkip
4826 jnz TopSkipLoop
4827
4828 LeftSkipSetup:
4829
4830 mov Unblitted, 0
4831 mov eax, LeftSkip
4832 mov LSCount, eax
4833 or eax, eax
4834 jz BlitLineSetup
4835
4836 LeftSkipLoop:
4837
4838 mov cl, [esi]
4839 inc esi
4840
4841 or cl, cl
4842 js LSTrans
4843
4844 cmp ecx, LSCount
4845 je LSSkip2 // if equal, skip whole, and start blit with new run
4846 jb LSSkip1 // if less, skip whole thing
4847
4848 add esi, LSCount // skip partial run, jump into normal loop for rest
4849 sub ecx, LSCount
4850 mov eax, BlitLength
4851 mov LSCount, eax
4852 mov Unblitted, 0
4853 jmp BlitNonTransLoop
4854
4855 LSSkip2:
4856 add esi, ecx // skip whole run, and start blit with new run
4857 jmp BlitLineSetup
4858
4859
4860 LSSkip1:
4861 add esi, ecx // skip whole run, continue skipping
4862 sub LSCount, ecx
4863 jmp LeftSkipLoop
4864
4865
4866 LSTrans:
4867 and ecx, 07fH
4868 cmp ecx, LSCount
4869 je BlitLineSetup // if equal, skip whole, and start blit with new run
4870 jb LSTrans1 // if less, skip whole thing
4871
4872 sub ecx, LSCount // skip partial run, jump into normal loop for rest
4873 mov eax, BlitLength
4874 mov LSCount, eax
4875 mov Unblitted, 0
4876 jmp BlitTransparent
4877
4878
4879 LSTrans1:
4880 sub LSCount, ecx // skip whole run, continue skipping
4881 jmp LeftSkipLoop
4882
4883
4884 BlitLineSetup: // Does any actual blitting (trans/non) for the line
4885 mov eax, BlitLength
4886 mov LSCount, eax
4887 mov Unblitted, 0
4888
4889 BlitDispatch:
4890
4891 cmp LSCount, 0 // Check to see if we're done blitting
4892 je RightSkipLoop
4893
4894 mov cl, [esi]
4895 inc esi
4896 or cl, cl
4897 js BlitTransparent
4898
4899 BlitNonTransLoop: // blit non-transparent pixels
4900
4901 cmp ecx, LSCount
4902 jbe BNTrans1
4903
4904 sub ecx, LSCount
4905 mov Unblitted, ecx
4906 mov ecx, LSCount
4907
4908 BNTrans1:
4909 sub LSCount, ecx
4910
4911 BlitNTL1:
4912
4913 mov ax, [ebx]
4914 cmp ax, usZValue
4915 jae BlitNTL2
4916
4917 mov ax, usZValue
4918 mov [ebx], ax
4919
4920 xor eax, eax
4921
4922 mov ax, [edi]
4923 mov ax, [edx+eax*2]
4924 mov [edi], ax
4925
4926 BlitNTL2:
4927 inc esi
4928 add edi, 2
4929 add ebx, 2
4930 dec cl
4931 jnz BlitNTL1
4932
4933 //BlitLineEnd:
4934 add esi, Unblitted
4935 jmp BlitDispatch
4936
4937 BlitTransparent: // skip transparent pixels
4938
4939 and ecx, 07fH
4940 cmp ecx, LSCount
4941 jbe BTrans1
4942
4943 mov ecx, LSCount
4944
4945 BTrans1:
4946
4947 sub LSCount, ecx
4948 // shl ecx, 1
4949 add ecx, ecx
4950 add edi, ecx
4951 add ebx, ecx
4952 jmp BlitDispatch
4953
4954
4955 RightSkipLoop: // skip along until we hit and end-of-line marker
4956
4957
4958 RSLoop1:
4959 mov al, [esi]
4960 inc esi
4961 or al, al
4962 jnz RSLoop1
4963
4964 dec BlitHeight
4965 jz BlitDone
4966 add edi, LineSkip
4967 add ebx, LineSkip
4968
4969 jmp LeftSkipSetup
4970
4971
4972 BlitDone:
4973 }
4974 #endif
4975 }
4976
4977
4978 /**********************************************************************************************
4979 Blt8BPPDataTo16BPPBufferIntensityZNB
4980
4981 Creates a shadow using a brush, but modifies the destination buffer only if the current
4982 Z level is equal to higher than what's in the Z buffer at that pixel location. It does
4983 NOT update the Z buffer with the new Z value.
4984
4985 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferIntensityZNB(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)4986 void Blt8BPPDataTo16BPPBufferIntensityZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
4987 {
4988 #if 1 // XXX TODO
4989 UNIMPLEMENTED
4990 #else
4991 UINT8 *DestPtr, *ZPtr;
4992 UINT32 LineSkip;
4993
4994 // Assertions
4995 Assert( hSrcVObject != NULL );
4996 Assert( pBuffer != NULL );
4997
4998 // Get Offsets from Index into structure
4999 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
5000 UINT32 const usHeight = pTrav.usHeight;
5001 UINT32 const usWidth = pTrav.usWidth;
5002
5003 // Add to start position of dest buffer
5004 INT32 const iTempX = iX + pTrav.sOffsetX;
5005 INT32 const iTempY = iY + pTrav.sOffsetY;
5006
5007 // Validations
5008 CHECKV(iTempX >= 0);
5009 CHECKV(iTempY >= 0);
5010
5011 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
5012 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
5013 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
5014 LineSkip=(uiDestPitchBYTES-(usWidth*2));
5015
5016 __asm {
5017
5018 mov esi, SrcPtr
5019 mov edi, DestPtr
5020 mov edx, OFFSET IntensityTable
5021 xor eax, eax
5022 mov ebx, ZPtr
5023 xor ecx, ecx
5024
5025 BlitDispatch:
5026
5027 mov cl, [esi]
5028 inc esi
5029 or cl, cl
5030 js BlitTransparent
5031 jz BlitDoneLine
5032
5033 //BlitNonTransLoop:
5034
5035 BlitNTL4:
5036
5037 mov ax, [ebx]
5038 cmp ax, usZValue
5039 jae BlitNTL5
5040
5041 xor eax, eax
5042 mov ax, [edi]
5043 mov ax, [edx+eax*2]
5044 mov [edi], ax
5045
5046 BlitNTL5:
5047 inc esi
5048 add edi, 2
5049 add ebx, 2
5050 dec cl
5051 jnz BlitNTL4
5052
5053 jmp BlitDispatch
5054
5055
5056 BlitTransparent:
5057
5058 and ecx, 07fH
5059 // shl ecx, 1
5060 add ecx, ecx
5061 add edi, ecx
5062 add ebx, ecx
5063 jmp BlitDispatch
5064
5065
5066 BlitDoneLine:
5067
5068 dec usHeight
5069 jz BlitDone
5070 add edi, LineSkip
5071 add ebx, LineSkip
5072 jmp BlitDispatch
5073
5074
5075 BlitDone:
5076 }
5077 #endif
5078 }
5079
5080
5081 /**********************************************************************************************
5082 Blt8BPPDataTo16BPPBufferIntensityClip
5083
5084 Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
5085 image as a mask. Any Non-zero index pixels are used to darken destination pixels. Blitter
5086 clips brush if it doesn't fit on the viewport.
5087
5088 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferIntensityClip(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)5089 void Blt8BPPDataTo16BPPBufferIntensityClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
5090 {
5091 #if 1 // XXX TODO
5092 UNIMPLEMENTED
5093 #else
5094 UINT8 *DestPtr;
5095 UINT32 LineSkip;
5096 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
5097 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
5098
5099 // Assertions
5100 Assert( hSrcVObject != NULL );
5101 Assert( pBuffer != NULL );
5102
5103 // Get Offsets from Index into structure
5104 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
5105 UINT32 const usHeight = pTrav.usHeight;
5106 UINT32 const usWidth = pTrav.usWidth;
5107
5108 // Add to start position of dest buffer
5109 INT32 const iTempX = iX + pTrav.sOffsetX;
5110 INT32 const iTempY = iY + pTrav.sOffsetY;
5111
5112 if(clipregion==NULL)
5113 {
5114 ClipX1=ClippingRect.iLeft;
5115 ClipY1=ClippingRect.iTop;
5116 ClipX2=ClippingRect.iRight;
5117 ClipY2=ClippingRect.iBottom;
5118 }
5119 else
5120 {
5121 ClipX1=clipregion->iLeft;
5122 ClipY1=clipregion->iTop;
5123 ClipX2=clipregion->iRight;
5124 ClipY2=clipregion->iBottom;
5125 }
5126
5127 // Calculate rows hanging off each side of the screen
5128 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
5129 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
5130 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
5131 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
5132
5133 // calculate the remaining rows and columns to blit
5134 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
5135 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
5136
5137 // whole thing is clipped
5138 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
5139 return;
5140
5141 // whole thing is clipped
5142 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
5143 return;
5144
5145 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
5146 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
5147 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
5148
5149 UINT32 Unblitted;
5150 __asm {
5151
5152 mov esi, SrcPtr
5153 mov edi, DestPtr
5154 mov edx, OFFSET IntensityTable
5155 xor eax, eax
5156 mov ebx, TopSkip
5157 xor ecx, ecx
5158
5159 or ebx, ebx // check for nothing clipped on top
5160 jz LeftSkipSetup
5161
5162 TopSkipLoop: // Skips the number of lines clipped at the top
5163
5164 mov cl, [esi]
5165 inc esi
5166 or cl, cl
5167 js TopSkipLoop
5168 jz TSEndLine
5169
5170 add esi, ecx
5171 jmp TopSkipLoop
5172
5173 TSEndLine:
5174 dec ebx
5175 jnz TopSkipLoop
5176
5177
5178
5179
5180 LeftSkipSetup:
5181
5182 mov Unblitted, 0
5183 mov ebx, LeftSkip // check for nothing clipped on the left
5184 or ebx, ebx
5185 jz BlitLineSetup
5186
5187 LeftSkipLoop:
5188
5189 mov cl, [esi]
5190 inc esi
5191
5192 or cl, cl
5193 js LSTrans
5194
5195 cmp ecx, ebx
5196 je LSSkip2 // if equal, skip whole, and start blit with new run
5197 jb LSSkip1 // if less, skip whole thing
5198
5199 add esi, ebx // skip partial run, jump into normal loop for rest
5200 sub ecx, ebx
5201 mov ebx, BlitLength
5202 mov Unblitted, 0
5203 jmp BlitNonTransLoop
5204
5205 LSSkip2:
5206 add esi, ecx // skip whole run, and start blit with new run
5207 jmp BlitLineSetup
5208
5209
5210 LSSkip1:
5211 add esi, ecx // skip whole run, continue skipping
5212 sub ebx, ecx
5213 jmp LeftSkipLoop
5214
5215
5216 LSTrans:
5217 and ecx, 07fH
5218 cmp ecx, ebx
5219 je BlitLineSetup // if equal, skip whole, and start blit with new run
5220 jb LSTrans1 // if less, skip whole thing
5221
5222 sub ecx, ebx // skip partial run, jump into normal loop for rest
5223 mov ebx, BlitLength
5224 jmp BlitTransparent
5225
5226
5227 LSTrans1:
5228 sub ebx, ecx // skip whole run, continue skipping
5229 jmp LeftSkipLoop
5230
5231
5232
5233
5234 BlitLineSetup: // Does any actual blitting (trans/non) for the line
5235 mov ebx, BlitLength
5236 mov Unblitted, 0
5237
5238 BlitDispatch:
5239
5240 or ebx, ebx // Check to see if we're done blitting
5241 jz RightSkipLoop
5242
5243 mov cl, [esi]
5244 inc esi
5245 or cl, cl
5246 js BlitTransparent
5247
5248 BlitNonTransLoop:
5249
5250 cmp ecx, ebx
5251 jbe BNTrans1
5252
5253 sub ecx, ebx
5254 mov Unblitted, ecx
5255 mov ecx, ebx
5256
5257 BNTrans1:
5258 sub ebx, ecx
5259
5260 clc
5261 rcr cl, 1
5262 jnc BlitNTL2
5263
5264 mov ax, [edi]
5265 mov ax, [edx+eax*2]
5266 mov [edi], ax
5267
5268 inc esi
5269 add edi, 2
5270
5271 BlitNTL2:
5272 clc
5273 rcr cl, 1
5274 jnc BlitNTL3
5275
5276 mov ax, [edi]
5277 mov ax, [edx+eax*2]
5278 mov [edi], ax
5279
5280 mov ax, [edi+2]
5281 mov ax, [edx+eax*2]
5282 mov [edi+2], ax
5283
5284 add esi, 2
5285 add edi, 4
5286
5287 BlitNTL3:
5288
5289 or cl, cl
5290 jz BlitLineEnd
5291
5292 BlitNTL4:
5293
5294 mov ax, [edi]
5295 mov ax, [edx+eax*2]
5296 mov [edi], ax
5297
5298 mov ax, [edi+2]
5299 mov ax, [edx+eax*2]
5300 mov [edi+2], ax
5301
5302 mov ax, [edi+4]
5303 mov ax, [edx+eax*2]
5304 mov [edi+4], ax
5305
5306 mov ax, [edi+6]
5307 mov ax, [edx+eax*2]
5308 mov [edi+6], ax
5309
5310 add esi, 4
5311 add edi, 8
5312 dec cl
5313 jnz BlitNTL4
5314
5315 BlitLineEnd:
5316 add esi, Unblitted
5317 jmp BlitDispatch
5318
5319 BlitTransparent:
5320
5321 and ecx, 07fH
5322 cmp ecx, ebx
5323 jbe BTrans1
5324
5325 mov ecx, ebx
5326
5327 BTrans1:
5328
5329 sub ebx, ecx
5330 // shl ecx, 1
5331 add ecx, ecx
5332 add edi, ecx
5333 jmp BlitDispatch
5334
5335
5336 RightSkipLoop:
5337
5338
5339 RSLoop1:
5340 mov al, [esi]
5341 inc esi
5342 or al, al
5343 jnz RSLoop1
5344
5345 dec BlitHeight
5346 jz BlitDone
5347 add edi, LineSkip
5348
5349 jmp LeftSkipSetup
5350
5351
5352 BlitDone:
5353 }
5354 #endif
5355 }
5356
5357
5358 /**********************************************************************************************
5359 Blt8BPPDataTo16BPPBufferIntensity
5360
5361 Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
5362 image as a mask. Any Non-zero index pixels are used to darken destination pixels.
5363
5364 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferIntensity(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex)5365 void Blt8BPPDataTo16BPPBufferIntensity( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex)
5366 {
5367 #if 1 // XXX TODO
5368 UNIMPLEMENTED
5369 #else
5370 UINT8 *DestPtr;
5371 UINT32 LineSkip;
5372
5373 // Assertions
5374 Assert( hSrcVObject != NULL );
5375 Assert( pBuffer != NULL );
5376
5377 // Get Offsets from Index into structure
5378 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
5379 UINT32 const usHeight = pTrav.usHeight;
5380 UINT32 const usWidth = pTrav.usWidth;
5381
5382 // Add to start position of dest buffer
5383 INT32 const iTempX = iX + pTrav.sOffsetX;
5384 INT32 const iTempY = iY + pTrav.sOffsetY;
5385
5386 // Validations
5387 CHECKV(iTempX >= 0);
5388 CHECKV(iTempY >= 0);
5389
5390 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
5391 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
5392 LineSkip=(uiDestPitchBYTES-(usWidth*2));
5393
5394 __asm {
5395
5396 mov esi, SrcPtr
5397 mov edi, DestPtr
5398 xor eax, eax
5399 mov ebx, usHeight
5400 xor ecx, ecx
5401 mov edx, OFFSET IntensityTable
5402
5403 BlitDispatch:
5404
5405
5406 mov cl, [esi]
5407 inc esi
5408 or cl, cl
5409 js BlitTransparent
5410 jz BlitDoneLine
5411
5412 //BlitNonTransLoop:
5413
5414 xor eax, eax
5415
5416 add esi, ecx
5417
5418 clc
5419 rcr cl, 1
5420 jnc BlitNTL2
5421
5422 mov ax, [edi]
5423 mov ax, [edx+eax*2]
5424 mov [edi], ax
5425
5426 add edi, 2
5427
5428 BlitNTL2:
5429 clc
5430 rcr cl, 1
5431 jnc BlitNTL3
5432
5433 mov ax, [edi]
5434 mov ax, [edx+eax*2]
5435 mov [edi], ax
5436
5437 mov ax, [edi+2]
5438 mov ax, [edx+eax*2]
5439 mov [edi+2], ax
5440
5441 add edi, 4
5442
5443 BlitNTL3:
5444
5445 or cl, cl
5446 jz BlitDispatch
5447
5448 BlitNTL4:
5449
5450 mov ax, [edi]
5451 mov ax, [edx+eax*2]
5452 mov [edi], ax
5453
5454 mov ax, [edi+2]
5455 mov ax, [edx+eax*2]
5456 mov [edi+2], ax
5457
5458 mov ax, [edi+4]
5459 mov ax, [edx+eax*2]
5460 mov [edi+4], ax
5461
5462 mov ax, [edi+6]
5463 mov ax, [edx+eax*2]
5464 mov [edi+6], ax
5465
5466 add edi, 8
5467 dec cl
5468 jnz BlitNTL4
5469
5470 jmp BlitDispatch
5471
5472 BlitTransparent:
5473
5474 and ecx, 07fH
5475 // shl ecx, 1
5476 add ecx, ecx
5477 add edi, ecx
5478 jmp BlitDispatch
5479
5480
5481 BlitDoneLine:
5482
5483 dec ebx
5484 jz BlitDone
5485 add edi, LineSkip
5486 jmp BlitDispatch
5487
5488
5489 BlitDone:
5490 }
5491 #endif
5492 }
5493
5494
5495 /**********************************************************************************************
5496 Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured
5497
5498 Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
5499 buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
5500 pixel's Z level is below that of the current pixel, it is written on, and the Z value is
5501 NOT updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
5502 must be the same dimensions (including Pitch) as the destination.
5503
5504 Blits every second pixel ("pixelates").
5505
5506 **********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured(UINT16 * pBuffer,UINT32 uiDestPitchBYTES,UINT16 * pZBuffer,UINT16 usZValue,HVOBJECT hSrcVObject,INT32 iX,INT32 iY,UINT16 usIndex,SGPRect * clipregion)5507 void Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
5508 {
5509 UINT32 uiLineFlag;
5510 UINT32 Unblitted;
5511 UINT8 *DestPtr, *ZPtr;
5512 UINT32 LineSkip;
5513 INT32 LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
5514 INT32 ClipX1, ClipY1, ClipX2, ClipY2;
5515
5516 // Assertions
5517 Assert( hSrcVObject != NULL );
5518 Assert( pBuffer != NULL );
5519
5520 // Get Offsets from Index into structure
5521 ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
5522 UINT32 const usHeight = pTrav.usHeight;
5523 UINT32 const usWidth = pTrav.usWidth;
5524
5525 // Add to start position of dest buffer
5526 INT32 const iTempX = iX + pTrav.sOffsetX;
5527 INT32 const iTempY = iY + pTrav.sOffsetY;
5528
5529 if(clipregion==NULL)
5530 {
5531 ClipX1=ClippingRect.iLeft;
5532 ClipY1=ClippingRect.iTop;
5533 ClipX2=ClippingRect.iRight;
5534 ClipY2=ClippingRect.iBottom;
5535 }
5536 else
5537 {
5538 ClipX1=clipregion->iLeft;
5539 ClipY1=clipregion->iTop;
5540 ClipX2=clipregion->iRight;
5541 ClipY2=clipregion->iBottom;
5542 }
5543
5544 // Calculate rows hanging off each side of the screen
5545 LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
5546 RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
5547 TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
5548 BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
5549
5550 // calculate the remaining rows and columns to blit
5551 BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
5552 BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
5553
5554 // check if whole thing is clipped
5555 if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
5556 return;
5557
5558 // check if whole thing is clipped
5559 if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
5560 return;
5561
5562 UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
5563 DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
5564 ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
5565 UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
5566 LineSkip=(uiDestPitchBYTES-(BlitLength*2));
5567 uiLineFlag=(iTempY&1);
5568
5569 uiLineFlag = (iTempY + TopSkip) & 1;
5570
5571 UINT32 PxCount;
5572
5573 while (TopSkip > 0)
5574 {
5575 for (;;)
5576 {
5577 PxCount = *SrcPtr++;
5578 if (PxCount & 0x80) continue;
5579 if (PxCount == 0) break;
5580 SrcPtr += PxCount;
5581 }
5582 TopSkip--;
5583 }
5584
5585 do
5586 {
5587 for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
5588 {
5589 PxCount = *SrcPtr++;
5590 if (PxCount & 0x80)
5591 {
5592 PxCount &= 0x7F;
5593 if (PxCount > static_cast<UINT32>(LSCount))
5594 {
5595 PxCount -= LSCount;
5596 LSCount = BlitLength;
5597 goto BlitTransparent;
5598 }
5599 }
5600 else
5601 {
5602 if (PxCount > static_cast<UINT32>(LSCount))
5603 {
5604 SrcPtr += LSCount;
5605 PxCount -= LSCount;
5606 LSCount = BlitLength;
5607 goto BlitNonTransLoop;
5608 }
5609 SrcPtr += PxCount;
5610 }
5611 }
5612
5613 LSCount = BlitLength;
5614 while (LSCount > 0)
5615 {
5616 PxCount = *SrcPtr++;
5617 if (PxCount & 0x80)
5618 {
5619 BlitTransparent: // skip transparent pixels
5620 PxCount &= 0x7F;
5621 if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
5622 LSCount -= PxCount;
5623 DestPtr += 2 * PxCount;
5624 ZPtr += 2 * PxCount;
5625 }
5626 else
5627 {
5628 BlitNonTransLoop: // blit non-transparent pixels
5629 if (PxCount > static_cast<UINT32>(LSCount))
5630 {
5631 Unblitted = PxCount - LSCount;
5632 PxCount = LSCount;
5633 }
5634 else
5635 {
5636 Unblitted = 0;
5637 }
5638 LSCount -= PxCount;
5639
5640 do
5641 {
5642 if (*(UINT16*)ZPtr < usZValue)
5643 {
5644 *(UINT16*)ZPtr = usZValue;
5645 }
5646 else
5647 {
5648 if (uiLineFlag != (((uintptr_t)DestPtr & 2) != 0)) continue;
5649 }
5650 *(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
5651 }
5652 while (SrcPtr++, DestPtr += 2, ZPtr += 2, --PxCount > 0);
5653 SrcPtr += Unblitted;
5654 }
5655 }
5656
5657 while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
5658 DestPtr += LineSkip;
5659 ZPtr += LineSkip;
5660 uiLineFlag ^= 1;
5661 }
5662 while (--BlitHeight > 0);
5663 }
5664