mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-20 15:41:56 +00:00
286 lines
7.3 KiB
Plaintext
286 lines
7.3 KiB
Plaintext
|
/***********************************************************************************************
|
|||
|
*
|
|||
|
* Copyright <20> DreamWorks Interactive, 1997.
|
|||
|
*
|
|||
|
* Contents:
|
|||
|
* Specialized (non-template) versions of the DrawSubtriangle function.
|
|||
|
* Optimized for the Pentium PRO Processor
|
|||
|
*
|
|||
|
***********************************************************************************************
|
|||
|
*
|
|||
|
* $Log:: /JP2_PC/Source/Lib/Renderer/Primitives/P6/DrawSubTriangleGourEx.cpp $
|
|||
|
*
|
|||
|
* 7 97/12/23 5:51p Mmouni
|
|||
|
*
|
|||
|
* 6 97.12.22 9:08p Mmouni
|
|||
|
* Fixed error with destination of terrain gouraud shading primitive.
|
|||
|
*
|
|||
|
* 5 97.12.22 6:07p Mmouni
|
|||
|
* Changed terrain gouraud shading routines so that they don't always draw to the screen.
|
|||
|
*
|
|||
|
* 4 97.12.22 2:53p Mmouni
|
|||
|
* Added new terrain gouraud shading primitive.
|
|||
|
*
|
|||
|
* 3 9/01/97 8:05p Rwyatt
|
|||
|
*
|
|||
|
* 2 97/07/18 3:29p Pkeet
|
|||
|
* Removed use of the 'b_right' parameter from DrawSubTriangle.
|
|||
|
*
|
|||
|
* 1 7/08/97 1:15p Rwyatt
|
|||
|
* Initial Implementation of Pentium Pro rendering specific optimizations
|
|||
|
*
|
|||
|
***********************************************************************************************
|
|||
|
***********************************************************************************************
|
|||
|
*
|
|||
|
* 5 97/06/12 5:56p Pkeet
|
|||
|
* Added capability to render only every other scanline and to double the number of scanlines.
|
|||
|
*
|
|||
|
* 4 97/06/11 11:41p Pkeet
|
|||
|
* Added more optimal inner loop code.
|
|||
|
*
|
|||
|
* 3 97/06/11 11:27p Pkeet
|
|||
|
* Initial assembly version.
|
|||
|
*
|
|||
|
* 2 97/06/11 11:20p Pkeet
|
|||
|
* Simplified the C++ version.
|
|||
|
*
|
|||
|
* 1 97/06/11 10:15p Pkeet
|
|||
|
* Initial C++ versions of primitives.
|
|||
|
*
|
|||
|
**********************************************************************************************/
|
|||
|
|
|||
|
#include "Common.hpp"
|
|||
|
|
|||
|
#include "Lib/View/Raster.hpp"
|
|||
|
#include "Lib/Renderer/Primitives/DrawTriangle.hpp"
|
|||
|
|
|||
|
//
|
|||
|
// Temporary Globals.
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
// These variables should be arraigned along with the external globals for maximum
|
|||
|
// cache efficiency.
|
|||
|
//
|
|||
|
static fixed fx_gour_inc;
|
|||
|
static int i_line_pixels;
|
|||
|
static uint16* ppix_clut;
|
|||
|
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void DrawSubtriangle(TGour* pscan, CDrawPolygon<TGour>* pdtri)
|
|||
|
{
|
|||
|
int i_x_from;
|
|||
|
int i_x_to;
|
|||
|
int i_screen_index;
|
|||
|
int i_pixel;
|
|||
|
uint16* apix_screen;
|
|||
|
fixed fx_intensity;
|
|||
|
|
|||
|
uint16* ppix_clut = ((uint16*)pvClutConversion) + u4ConstColour;
|
|||
|
|
|||
|
//
|
|||
|
// Iterate through the scanlines that intersect the subtriangle.
|
|||
|
//
|
|||
|
do
|
|||
|
{
|
|||
|
if (bRIGHT_TO_LEFT)
|
|||
|
{
|
|||
|
i_x_from = (pscan->fxX.i4Fx - pdtri->fxLineLength.i4Fx)>>16;
|
|||
|
i_x_to = (pscan->fxX.i4Fx)>>16;
|
|||
|
i_screen_index = pdtri->iLineStartIndex + i_x_from - 1;
|
|||
|
i_pixel = i_x_to - i_x_from;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
i_x_from = (pscan->fxX.i4Fx)>>16;
|
|||
|
i_x_to = (pscan->fxX.i4Fx + pdtri->fxLineLength.i4Fx)>>16;
|
|||
|
i_screen_index = pdtri->iLineStartIndex + i_x_to;
|
|||
|
i_pixel = i_x_from - i_x_to;
|
|||
|
}
|
|||
|
|
|||
|
// Draw if there are pixels to draw.
|
|||
|
if (i_x_to > i_x_from && !(bEvenScanlinesOnly && ((pdtri->iY & 1) == 0)))
|
|||
|
{
|
|||
|
|
|||
|
// Get the start address for the scanline on the destination raster.
|
|||
|
apix_screen = (uint16*)pdtri->prasScreen->pSurface;
|
|||
|
apix_screen += i_screen_index;
|
|||
|
|
|||
|
// Get the starting gouraud shading value.
|
|||
|
fx_intensity.i4Fx = pscan->gourIntensity.fxIntensity.i4Fx;
|
|||
|
|
|||
|
__asm
|
|||
|
{
|
|||
|
mov edx, [fx_intensity]
|
|||
|
xor ebx, ebx
|
|||
|
mov esi, [apix_screen]
|
|||
|
mov edi, [i_pixel]
|
|||
|
mov ecx, [ppix_clut]
|
|||
|
push ebp
|
|||
|
mov ebp, [i4ScanlineDirection]
|
|||
|
mov eax, 0xFFFF0000
|
|||
|
|
|||
|
BEGIN_INNER_LOOP:
|
|||
|
|
|||
|
and eax, edx
|
|||
|
add edx, [fxDeltaXIntensity]
|
|||
|
|
|||
|
shr eax, 8
|
|||
|
|
|||
|
mov bx, [ecx + eax*2]
|
|||
|
mov eax, 0xFFFF0000
|
|||
|
|
|||
|
mov [esi + edi*2], bx
|
|||
|
|
|||
|
add edi, ebp
|
|||
|
|
|||
|
jnz short BEGIN_INNER_LOOP
|
|||
|
pop ebp
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Increment the base edge.
|
|||
|
++*pdtri->pedgeBase;
|
|||
|
|
|||
|
// Set the new length of the line to be rasterized.
|
|||
|
pdtri->fxLineLength.i4Fx += pdtri->fxDeltaLineLength.i4Fx;
|
|||
|
|
|||
|
// Get new starting pixel TIndex for the scanline.
|
|||
|
pdtri->iLineStartIndex += pdtri->prasScreen->iLinePixels;
|
|||
|
}
|
|||
|
while (++pdtri->iY < pdtri->iYTo);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
// Gouraud shaded triangle function that draws to a composite texture map.
|
|||
|
//
|
|||
|
void DrawSubtriangle(TShadeTerrain* pscan, CDrawPolygon<TShadeTerrain>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TShadeTerrain> TAccess;
|
|||
|
static TShadeTerrain* pscanGlbl;
|
|||
|
static CDrawPolygon<TShadeTerrain>* pdtriGlbl;
|
|||
|
|
|||
|
fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
fx_gour_inc = pdtri->pedgeBase->lineIncrement.gourIntensity.fxIntensity;
|
|||
|
i_line_pixels = pdtri->prasScreen->iLinePixels;
|
|||
|
pscanGlbl = pscan;
|
|||
|
pdtriGlbl = pdtri;
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
mov edx,[pdtri]
|
|||
|
mov ecx,[pscan]
|
|||
|
|
|||
|
mov eax,[edx]CDrawPolygonBase.iY
|
|||
|
mov edi,[edx]CDrawPolygonBase.iLineStartIndex
|
|||
|
// ecx, edi, eax and edx are also set from the loop end.
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// scan line start
|
|||
|
NEXT_SCAN:
|
|||
|
and eax,[bEvenScanlinesOnly]
|
|||
|
jnz short SKIP_LOOP
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// Calculate start, length of edge.
|
|||
|
mov esi,[ecx]TGour.fxX.i4Fx
|
|||
|
mov eax,[edx]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
|
|||
|
add eax,esi
|
|||
|
|
|||
|
sar eax,16
|
|||
|
mov ebx,[edx]TAccess.prasScreen
|
|||
|
|
|||
|
sar esi,16
|
|||
|
add edi,eax
|
|||
|
|
|||
|
mov ebx,[ebx]CRasterBase.pSurface
|
|||
|
|
|||
|
sub esi,eax
|
|||
|
jge short SKIP_LOOP
|
|||
|
|
|||
|
// Get the starting gouraud shading value.
|
|||
|
mov edx,[ecx]TShadeTerrain.gourIntensity.fxIntensity.i4Fx
|
|||
|
lea edi,[edi*2+ebx]
|
|||
|
|
|||
|
mov [pvBaseOfLine],edi
|
|||
|
mov eax,[fxDeltaXIntensity]
|
|||
|
|
|||
|
//
|
|||
|
// Write intensity value to every other pixel.
|
|||
|
//
|
|||
|
INNER_LOOP:
|
|||
|
mov ebx,edx // Copy intensity value
|
|||
|
add edx,eax // Step intensity value
|
|||
|
|
|||
|
shr ebx,16 // Shift intensity value
|
|||
|
|
|||
|
mov [edi + esi*2 + 1],bl // Store integer intensity byte
|
|||
|
inc esi // Step count
|
|||
|
|
|||
|
jnz short INNER_LOOP
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// Loop control an sub pixel correction for edges
|
|||
|
SKIP_LOOP:
|
|||
|
mov edx,[pdtriGlbl]
|
|||
|
mov ecx,[pscanGlbl]
|
|||
|
|
|||
|
mov esi,[ecx]TShadeTerrain.gourIntensity.fxIntensity.i4Fx
|
|||
|
mov ebx,[ecx]TShadeTerrain.fxXDifference
|
|||
|
|
|||
|
add esi,[fx_gour_inc]
|
|||
|
add ebx,[fx_diff]
|
|||
|
|
|||
|
mov eax,[fxIModDiv]
|
|||
|
jge short NO_UNDERFLOW
|
|||
|
|
|||
|
// Undeflow of fxXDifference.
|
|||
|
add ebx,0x00010000
|
|||
|
add esi,eax
|
|||
|
|
|||
|
jmp short DONE_Y
|
|||
|
|
|||
|
NO_UNDERFLOW:
|
|||
|
cmp ebx,0x00010000
|
|||
|
jl short DONE_Y
|
|||
|
|
|||
|
// Overflow of fxXDifference.
|
|||
|
sub ebx,0x00010000
|
|||
|
add esi,eax
|
|||
|
|
|||
|
DONE_Y:
|
|||
|
// Store modified variables.
|
|||
|
mov [ecx]TShadeTerrain.gourIntensity.fxIntensity.i4Fx,esi
|
|||
|
mov [ecx]TShadeTerrain.fxXDifference,ebx
|
|||
|
|
|||
|
// Step length, line starting address.
|
|||
|
mov ebx,[edx]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
mov edi,[edx]CDrawPolygonBase.iLineStartIndex
|
|||
|
|
|||
|
add ebx,[edx]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
add edi,[i_line_pixels]
|
|||
|
|
|||
|
mov [edx]CDrawPolygonBase.fxLineLength.i4Fx,ebx
|
|||
|
mov [edx]CDrawPolygonBase.iLineStartIndex,edi
|
|||
|
|
|||
|
mov ebx,[ecx]TShadeTerrain.fxX
|
|||
|
mov esi,[fx_inc]
|
|||
|
|
|||
|
add ebx,esi
|
|||
|
mov eax,[edx]CDrawPolygonBase.iY
|
|||
|
|
|||
|
mov [ecx]TShadeTerrain.fxX,ebx
|
|||
|
inc eax
|
|||
|
|
|||
|
mov ebx,[edx]CDrawPolygonBase.iYTo
|
|||
|
mov [edx]CDrawPolygonBase.iY,eax
|
|||
|
|
|||
|
// ecx, edi, eax and edx are set for the next interation of the loop.
|
|||
|
cmp eax,ebx
|
|||
|
jl NEXT_SCAN
|
|||
|
}
|
|||
|
}
|