mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-10 11:59:58 -05:00
Quack 3
This commit is contained in:
committed by
GitHub
parent
e8bd66b89c
commit
0bf99969fd
638
ref_soft/r_part.c
Normal file
638
ref_soft/r_part.c
Normal file
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include "r_local.h"
|
||||
|
||||
vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
#define PARTICLE_33 0
|
||||
#define PARTICLE_66 1
|
||||
#define PARTICLE_OPAQUE 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
particle_t *particle;
|
||||
int level;
|
||||
int color;
|
||||
} partparms_t;
|
||||
|
||||
static partparms_t partparms;
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
|
||||
static unsigned s_prefetch_address;
|
||||
|
||||
/*
|
||||
** BlendParticleXX
|
||||
**
|
||||
** Inputs:
|
||||
** EAX = color
|
||||
** EDI = pdest
|
||||
**
|
||||
** Scratch:
|
||||
** EBX = scratch (dstcolor)
|
||||
** EBP = scratch
|
||||
**
|
||||
** Outputs:
|
||||
** none
|
||||
*/
|
||||
__declspec(naked) void BlendParticle33( void )
|
||||
{
|
||||
// return vid.alphamap[color + dstcolor*256];
|
||||
__asm mov ebp, vid.alphamap
|
||||
__asm xor ebx, ebx
|
||||
|
||||
__asm mov bl, byte ptr [edi]
|
||||
__asm shl ebx, 8
|
||||
|
||||
__asm add ebp, ebx
|
||||
__asm add ebp, eax
|
||||
|
||||
__asm mov al, byte ptr [ebp]
|
||||
|
||||
__asm mov byte ptr [edi], al
|
||||
|
||||
__asm ret
|
||||
}
|
||||
|
||||
__declspec(naked) void BlendParticle66( void )
|
||||
{
|
||||
// return vid.alphamap[pcolor*256 + dstcolor];
|
||||
__asm mov ebp, vid.alphamap
|
||||
__asm xor ebx, ebx
|
||||
|
||||
__asm shl eax, 8
|
||||
__asm mov bl, byte ptr [edi]
|
||||
|
||||
__asm add ebp, ebx
|
||||
__asm add ebp, eax
|
||||
|
||||
__asm mov al, byte ptr [ebp]
|
||||
|
||||
__asm mov byte ptr [edi], al
|
||||
|
||||
__asm ret
|
||||
}
|
||||
|
||||
__declspec(naked) void BlendParticle100( void )
|
||||
{
|
||||
__asm mov byte ptr [edi], al
|
||||
__asm ret
|
||||
}
|
||||
|
||||
/*
|
||||
** R_DrawParticle (asm version)
|
||||
**
|
||||
** Since we use __declspec( naked ) we don't have a stack frame
|
||||
** that we can use. Since I want to reserve EBP anyway, I tossed
|
||||
** all the important variables into statics. This routine isn't
|
||||
** meant to be re-entrant, so this shouldn't cause any problems
|
||||
** other than a slightly higher global memory footprint.
|
||||
**
|
||||
*/
|
||||
__declspec(naked) void R_DrawParticle( void )
|
||||
{
|
||||
static vec3_t local, transformed;
|
||||
static float zi;
|
||||
static int u, v, tmp;
|
||||
static short izi;
|
||||
static int ebpsave;
|
||||
|
||||
static byte (*blendfunc)(void);
|
||||
|
||||
/*
|
||||
** must be memvars since x86 can't load constants
|
||||
** directly. I guess I could use fld1, but that
|
||||
** actually costs one more clock than fld [one]!
|
||||
*/
|
||||
static float particle_z_clip = PARTICLE_Z_CLIP;
|
||||
static float one = 1.0F;
|
||||
static float point_five = 0.5F;
|
||||
static float eight_thousand_hex = 0x8000;
|
||||
|
||||
/*
|
||||
** save trashed variables
|
||||
*/
|
||||
__asm mov ebpsave, ebp
|
||||
__asm push esi
|
||||
__asm push edi
|
||||
|
||||
/*
|
||||
** transform the particle
|
||||
*/
|
||||
// VectorSubtract (pparticle->origin, r_origin, local);
|
||||
__asm mov esi, partparms.particle
|
||||
__asm fld dword ptr [esi+0] ; p_o.x
|
||||
__asm fsub dword ptr [r_origin+0] ; p_o.x-r_o.x
|
||||
__asm fld dword ptr [esi+4] ; p_o.y | p_o.x-r_o.x
|
||||
__asm fsub dword ptr [r_origin+4] ; p_o.y-r_o.y | p_o.x-r_o.x
|
||||
__asm fld dword ptr [esi+8] ; p_o.z | p_o.y-r_o.y | p_o.x-r_o.x
|
||||
__asm fsub dword ptr [r_origin+8] ; p_o.z-r_o.z | p_o.y-r_o.y | p_o.x-r_o.x
|
||||
__asm fxch st(2) ; p_o.x-r_o.x | p_o.y-r_o.y | p_o.z-r_o.z
|
||||
__asm fstp dword ptr [local+0] ; p_o.y-r_o.y | p_o.z-r_o.z
|
||||
__asm fstp dword ptr [local+4] ; p_o.z-r_o.z
|
||||
__asm fstp dword ptr [local+8] ; (empty)
|
||||
|
||||
// transformed[0] = DotProduct(local, r_pright);
|
||||
// transformed[1] = DotProduct(local, r_pup);
|
||||
// transformed[2] = DotProduct(local, r_ppn);
|
||||
__asm fld dword ptr [local+0] ; l.x
|
||||
__asm fmul dword ptr [r_pright+0] ; l.x*pr.x
|
||||
__asm fld dword ptr [local+4] ; l.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pright+4] ; l.y*pr.y | l.x*pr.x
|
||||
__asm fld dword ptr [local+8] ; l.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pright+8] ; l.z*pr.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fxch st(2) ; l.x*pr.x | l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y + l.z*pr.z
|
||||
__asm fstp dword ptr [transformed+0] ; (empty)
|
||||
|
||||
__asm fld dword ptr [local+0] ; l.x
|
||||
__asm fmul dword ptr [r_pup+0] ; l.x*pr.x
|
||||
__asm fld dword ptr [local+4] ; l.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pup+4] ; l.y*pr.y | l.x*pr.x
|
||||
__asm fld dword ptr [local+8] ; l.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_pup+8] ; l.z*pr.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fxch st(2) ; l.x*pr.x | l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y + l.z*pr.z
|
||||
__asm fstp dword ptr [transformed+4] ; (empty)
|
||||
|
||||
__asm fld dword ptr [local+0] ; l.x
|
||||
__asm fmul dword ptr [r_ppn+0] ; l.x*pr.x
|
||||
__asm fld dword ptr [local+4] ; l.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_ppn+4] ; l.y*pr.y | l.x*pr.x
|
||||
__asm fld dword ptr [local+8] ; l.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fmul dword ptr [r_ppn+8] ; l.z*pr.z | l.y*pr.y | l.x*pr.x
|
||||
__asm fxch st(2) ; l.x*pr.x | l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y | l.z*pr.z
|
||||
__asm faddp st(1), st ; l.x*pr.x + l.y*pr.y + l.z*pr.z
|
||||
__asm fstp dword ptr [transformed+8] ; (empty)
|
||||
|
||||
/*
|
||||
** make sure that the transformed particle is not in front of
|
||||
** the particle Z clip plane. We can do the comparison in
|
||||
** integer space since we know the sign of one of the inputs
|
||||
** and can figure out the sign of the other easily enough.
|
||||
*/
|
||||
// if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
// return;
|
||||
|
||||
__asm mov eax, dword ptr [transformed+8]
|
||||
__asm and eax, eax
|
||||
__asm js end
|
||||
__asm cmp eax, particle_z_clip
|
||||
__asm jl end
|
||||
|
||||
/*
|
||||
** project the point by initiating the 1/z calc
|
||||
*/
|
||||
// zi = 1.0 / transformed[2];
|
||||
__asm fld one
|
||||
__asm fdiv dword ptr [transformed+8]
|
||||
|
||||
/*
|
||||
** bind the blend function pointer to the appropriate blender
|
||||
** while we're dividing
|
||||
*/
|
||||
//if ( level == PARTICLE_33 )
|
||||
// blendparticle = BlendParticle33;
|
||||
//else if ( level == PARTICLE_66 )
|
||||
// blendparticle = BlendParticle66;
|
||||
//else
|
||||
// blendparticle = BlendParticle100;
|
||||
|
||||
__asm cmp partparms.level, PARTICLE_66
|
||||
__asm je blendfunc_66
|
||||
__asm jl blendfunc_33
|
||||
__asm lea ebx, BlendParticle100
|
||||
__asm jmp done_selecting_blend_func
|
||||
blendfunc_33:
|
||||
__asm lea ebx, BlendParticle33
|
||||
__asm jmp done_selecting_blend_func
|
||||
blendfunc_66:
|
||||
__asm lea ebx, BlendParticle66
|
||||
done_selecting_blend_func:
|
||||
__asm mov blendfunc, ebx
|
||||
|
||||
// prefetch the next particle
|
||||
__asm mov ebp, s_prefetch_address
|
||||
__asm mov ebp, [ebp]
|
||||
|
||||
// finish the above divide
|
||||
__asm fstp zi
|
||||
|
||||
// u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
// v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
__asm fld zi ; zi
|
||||
__asm fmul dword ptr [transformed+0] ; zi * transformed[0]
|
||||
__asm fld zi ; zi | zi * transformed[0]
|
||||
__asm fmul dword ptr [transformed+4] ; zi * transformed[1] | zi * transformed[0]
|
||||
__asm fxch st(1) ; zi * transformed[0] | zi * transformed[1]
|
||||
__asm fadd xcenter ; xcenter + zi * transformed[0] | zi * transformed[1]
|
||||
__asm fxch st(1) ; zi * transformed[1] | xcenter + zi * transformed[0]
|
||||
__asm fld ycenter ; ycenter | zi * transformed[1] | xcenter + zi * transformed[0]
|
||||
__asm fsubrp st(1), st(0) ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0]
|
||||
__asm fxch st(1) ; xcenter + zi * transformed[0] | ycenter + zi * transformed[1]
|
||||
__asm fadd point_five ; xcenter + zi * transformed[0] + 0.5 | ycenter - zi * transformed[1]
|
||||
__asm fxch st(1) ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0] + 0.5
|
||||
__asm fadd point_five ; ycenter - zi * transformed[1] + 0.5 | xcenter + zi * transformed[0] + 0.5
|
||||
__asm fxch st(1) ; u | v
|
||||
__asm fistp dword ptr [u] ; v
|
||||
__asm fistp dword ptr [v] ; (empty)
|
||||
|
||||
/*
|
||||
** clip out the particle
|
||||
*/
|
||||
|
||||
// if ((v > d_vrectbottom_particle) ||
|
||||
// (u > d_vrectright_particle) ||
|
||||
// (v < d_vrecty) ||
|
||||
// (u < d_vrectx))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
__asm mov ebx, u
|
||||
__asm mov ecx, v
|
||||
__asm cmp ecx, d_vrectbottom_particle
|
||||
__asm jg end
|
||||
__asm cmp ecx, d_vrecty
|
||||
__asm jl end
|
||||
__asm cmp ebx, d_vrectright_particle
|
||||
__asm jg end
|
||||
__asm cmp ebx, d_vrectx
|
||||
__asm jl end
|
||||
|
||||
/*
|
||||
** compute addresses of zbuffer, framebuffer, and
|
||||
** compute the Z-buffer reference value.
|
||||
**
|
||||
** EBX = U
|
||||
** ECX = V
|
||||
**
|
||||
** Outputs:
|
||||
** ESI = Z-buffer address
|
||||
** EDI = framebuffer address
|
||||
*/
|
||||
// ESI = d_pzbuffer + (d_zwidth * v) + u;
|
||||
__asm mov esi, d_pzbuffer ; esi = d_pzbuffer
|
||||
__asm mov eax, d_zwidth ; eax = d_zwidth
|
||||
__asm mul ecx ; eax = d_zwidth*v
|
||||
__asm add eax, ebx ; eax = d_zwidth*v+u
|
||||
__asm shl eax, 1 ; eax = 2*(d_zwidth*v+u)
|
||||
__asm add esi, eax ; esi = ( short * ) ( d_pzbuffer + ( d_zwidth * v ) + u )
|
||||
|
||||
// initiate
|
||||
// izi = (int)(zi * 0x8000);
|
||||
__asm fld zi
|
||||
__asm fmul eight_thousand_hex
|
||||
|
||||
// EDI = pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
__asm lea edi, [d_scantable+ecx*4]
|
||||
__asm mov edi, [edi]
|
||||
__asm add edi, d_viewbuffer
|
||||
__asm add edi, ebx
|
||||
|
||||
// complete
|
||||
// izi = (int)(zi * 0x8000);
|
||||
__asm fistp tmp
|
||||
__asm mov eax, tmp
|
||||
__asm mov izi, ax
|
||||
|
||||
/*
|
||||
** determine the screen area covered by the particle,
|
||||
** which also means clamping to a min and max
|
||||
*/
|
||||
// pix = izi >> d_pix_shift;
|
||||
__asm xor edx, edx
|
||||
__asm mov dx, izi
|
||||
__asm mov ecx, d_pix_shift
|
||||
__asm shr dx, cl
|
||||
|
||||
// if (pix < d_pix_min)
|
||||
// pix = d_pix_min;
|
||||
__asm cmp edx, d_pix_min
|
||||
__asm jge check_pix_max
|
||||
__asm mov edx, d_pix_min
|
||||
__asm jmp skip_pix_clamp
|
||||
|
||||
// else if (pix > d_pix_max)
|
||||
// pix = d_pix_max;
|
||||
check_pix_max:
|
||||
__asm cmp edx, d_pix_max
|
||||
__asm jle skip_pix_clamp
|
||||
__asm mov edx, d_pix_max
|
||||
|
||||
skip_pix_clamp:
|
||||
|
||||
/*
|
||||
** render the appropriate pixels
|
||||
**
|
||||
** ECX = count (used for inner loop)
|
||||
** EDX = count (used for outer loop)
|
||||
** ESI = zbuffer
|
||||
** EDI = framebuffer
|
||||
*/
|
||||
__asm mov ecx, edx
|
||||
|
||||
__asm cmp ecx, 1
|
||||
__asm ja over
|
||||
|
||||
over:
|
||||
|
||||
/*
|
||||
** at this point:
|
||||
**
|
||||
** ECX = count
|
||||
*/
|
||||
__asm push ecx
|
||||
__asm push edi
|
||||
__asm push esi
|
||||
|
||||
top_of_pix_vert_loop:
|
||||
|
||||
top_of_pix_horiz_loop:
|
||||
|
||||
// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
// {
|
||||
// for (i=0 ; i<pix ; i++)
|
||||
// {
|
||||
// if (pz[i] <= izi)
|
||||
// {
|
||||
// pdest[i] = blendparticle( color, pdest[i] );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
__asm xor eax, eax
|
||||
|
||||
__asm mov ax, word ptr [esi]
|
||||
|
||||
__asm cmp ax, izi
|
||||
__asm jg end_of_horiz_loop
|
||||
|
||||
#if ENABLE_ZWRITES_FOR_PARTICLES
|
||||
__asm mov bp, izi
|
||||
__asm mov word ptr [esi], bp
|
||||
#endif
|
||||
|
||||
__asm mov eax, partparms.color
|
||||
|
||||
__asm call [blendfunc]
|
||||
|
||||
__asm add edi, 1
|
||||
__asm add esi, 2
|
||||
|
||||
end_of_horiz_loop:
|
||||
|
||||
__asm dec ecx
|
||||
__asm jnz top_of_pix_horiz_loop
|
||||
|
||||
__asm pop esi
|
||||
__asm pop edi
|
||||
|
||||
__asm mov ebp, d_zwidth
|
||||
__asm shl ebp, 1
|
||||
|
||||
__asm add esi, ebp
|
||||
__asm add edi, [r_screenwidth]
|
||||
|
||||
__asm pop ecx
|
||||
__asm push ecx
|
||||
|
||||
__asm push edi
|
||||
__asm push esi
|
||||
|
||||
__asm dec edx
|
||||
__asm jnz top_of_pix_vert_loop
|
||||
|
||||
__asm pop ecx
|
||||
__asm pop ecx
|
||||
__asm pop ecx
|
||||
|
||||
end:
|
||||
__asm pop edi
|
||||
__asm pop esi
|
||||
__asm mov ebp, ebpsave
|
||||
__asm ret
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static byte BlendParticle33( int pcolor, int dstcolor )
|
||||
{
|
||||
return vid.alphamap[pcolor + dstcolor*256];
|
||||
}
|
||||
|
||||
static byte BlendParticle66( int pcolor, int dstcolor )
|
||||
{
|
||||
return vid.alphamap[pcolor*256+dstcolor];
|
||||
}
|
||||
|
||||
static byte BlendParticle100( int pcolor, int dstcolor )
|
||||
{
|
||||
dstcolor = dstcolor;
|
||||
return pcolor;
|
||||
}
|
||||
|
||||
/*
|
||||
** R_DrawParticle
|
||||
**
|
||||
** Yes, this is amazingly slow, but it's the C reference
|
||||
** implementation and should be both robust and vaguely
|
||||
** understandable. The only time this path should be
|
||||
** executed is if we're debugging on x86 or if we're
|
||||
** recompiling and deploying on a non-x86 platform.
|
||||
**
|
||||
** To minimize error and improve readability I went the
|
||||
** function pointer route. This exacts some overhead, but
|
||||
** it pays off in clean and easy to understand code.
|
||||
*/
|
||||
void R_DrawParticle( void )
|
||||
{
|
||||
particle_t *pparticle = partparms.particle;
|
||||
int level = partparms.level;
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
int color = pparticle->color;
|
||||
int i, izi, pix, count, u, v;
|
||||
byte (*blendparticle)( int, int );
|
||||
|
||||
/*
|
||||
** transform the particle
|
||||
*/
|
||||
VectorSubtract (pparticle->origin, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct(local, r_pright);
|
||||
transformed[1] = DotProduct(local, r_pup);
|
||||
transformed[2] = DotProduct(local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
/*
|
||||
** bind the blend function pointer to the appropriate blender
|
||||
*/
|
||||
if ( level == PARTICLE_33 )
|
||||
blendparticle = BlendParticle33;
|
||||
else if ( level == PARTICLE_66 )
|
||||
blendparticle = BlendParticle66;
|
||||
else
|
||||
blendparticle = BlendParticle100;
|
||||
|
||||
/*
|
||||
** project the point
|
||||
*/
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int)(xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int)(ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) ||
|
||||
(v < d_vrecty) ||
|
||||
(u < d_vrectx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** compute addresses of zbuffer, framebuffer, and
|
||||
** compute the Z-buffer reference value.
|
||||
*/
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
izi = (int)(zi * 0x8000);
|
||||
|
||||
/*
|
||||
** determine the screen area covered by the particle,
|
||||
** which also means clamping to a min and max
|
||||
*/
|
||||
pix = izi >> d_pix_shift;
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
/*
|
||||
** render the appropriate pixels
|
||||
*/
|
||||
count = pix;
|
||||
|
||||
switch (level) {
|
||||
case PARTICLE_33 :
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
|
||||
{
|
||||
//FIXME--do it in blocks of 8?
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = vid.alphamap[color + ((int)pdest[i]<<8)];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PARTICLE_66 :
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = vid.alphamap[(color<<8) + (int)pdest[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: //100
|
||||
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
|
||||
{
|
||||
for (i=0 ; i<pix ; i++)
|
||||
{
|
||||
if (pz[i] <= izi)
|
||||
{
|
||||
pz[i] = izi;
|
||||
pdest[i] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !id386
|
||||
|
||||
/*
|
||||
** R_DrawParticles
|
||||
**
|
||||
** Responsible for drawing all of the particles in the particle list
|
||||
** throughout the world. Doesn't care if we're using the C path or
|
||||
** if we're using the asm path, it simply assigns a function pointer
|
||||
** and goes.
|
||||
*/
|
||||
void R_DrawParticles (void)
|
||||
{
|
||||
particle_t *p;
|
||||
int i;
|
||||
extern unsigned long fpu_sp24_cw, fpu_chop_cw;
|
||||
|
||||
VectorScale( vright, xscaleshrink, r_pright );
|
||||
VectorScale( vup, yscaleshrink, r_pup );
|
||||
VectorCopy( vpn, r_ppn );
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
__asm fldcw word ptr [fpu_sp24_cw]
|
||||
#endif
|
||||
|
||||
for (p=r_newrefdef.particles, i=0 ; i<r_newrefdef.num_particles ; i++,p++)
|
||||
{
|
||||
|
||||
if ( p->alpha > 0.66 )
|
||||
partparms.level = PARTICLE_OPAQUE;
|
||||
else if ( p->alpha > 0.33 )
|
||||
partparms.level = PARTICLE_66;
|
||||
else
|
||||
partparms.level = PARTICLE_33;
|
||||
|
||||
partparms.particle = p;
|
||||
partparms.color = p->color;
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
if ( i < r_newrefdef.num_particles-1 )
|
||||
s_prefetch_address = ( unsigned int ) ( p + 1 );
|
||||
else
|
||||
s_prefetch_address = ( unsigned int ) r_newrefdef.particles;
|
||||
#endif
|
||||
|
||||
R_DrawParticle();
|
||||
}
|
||||
|
||||
#if id386 && !defined __linux__
|
||||
__asm fldcw word ptr [fpu_chop_cw]
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user