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