⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_part.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//100%
{$ALIGN 8}{$MINENUMSIZE 4}
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): r_part.c                                                          }
{                                                                            }
{ Initial conversion by : Gargoylle[LtK](gargoylle_ltk@hotmail.com           }
{ Initial conversion on : 09-Jul-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ 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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ r_main                                                                     }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ * VERRY IMPORTANT: some of the routines in r_part.c are declared as        }
{      __declspec(naked). As far as I know this means that no frame stack    }
{      is created for them. I however have no knoledge of how to do this     }
{      in Delphi so currently __declspec(naked) is IGNORED and the routines  }
{      are just declared as any other normal routines. A suitable solution   }
{      must however be found.                                                }
{ * conversion started on 09-Jul-2002                                        }
{----------------------------------------------------------------------------}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
//  PLEASE NOTE:
//   1) all original comments will be retained. My own comments will begin with
//      "GARGO".
//   2) this file does not have a .H file to go with it
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

unit r_part;

interface

uses
  q_shared,
  ref,
  r_local,
  rw_imp; // see the note at R_DrawParticles

{$IFDEF id386}
{$IFNDEF __linux__}

// GARGO: GARGO_ByteFunc required to declare variables needed by R_DrawParticle
type
  GARGO_ByteFunc = function: byte;

var
  s_prefetch_address: Cardinal;

  // GARGO: the following are the routines declared in r_part.c
  //   As I have mentioned before, some are originally declared
  //   as __declspec(naked). Currently I have ignored it so the
  //   routines are declared as any normal routine would be.
//	procedure BlendParticle33;
//	procedure BlendParticle66;
//	procedure BlendParticle100;
{$ENDIF} // __linux__
{$ELSE}
//	procedure BlendParticle33;
//	procedure BlendParticle66;
//	procedure BlendParticle100;
{$ENDIF}

procedure R_DrawParticles;

implementation

uses
  r_misc,
  r_main,
  DelphiTypes,
  SysUtils;

const
  PARTICLE_33 = 0;
  PARTICLE_66 = 1;
  PARTICLE_OPAQUE = 2;

type
  partparms_p = ^partparms_t;
  ppartparms_t = partparms_p;
  partparms_t = record
    particle: particle_p;
    level: integer;
    color: integer;
  end;
  TPartParms = partparms_t;
  PPartParms = ppartparms_t;

var
  r_pright: vec3_t;
  r_pup: vec3_t;
  r_ppn: vec3_t;
  partparms: partparms_t;

{$IFDEF id386}
{$IFNDEF __linux__}
(*
** BlendParticleXX
**
** Inputs:
** EAX = color
** EDI = pdest
**
** Scratch:
** EBX = scratch (dstcolor)
** EBP = scratch
**
** Outputs:
** none
*)

procedure BlendParticle33;
asm
  //	return vid.alphamap[color + dstcolor*256];
  mov ebp, vid.alphamap
  xor ebx, ebx

  mov bl,  byte ptr [edi]
  shl ebx, 8

  add ebp, ebx
  add ebp, eax

  mov al,  byte ptr [ebp]

  mov byte ptr [edi], al
end;

procedure BlendParticle66;
asm
  //	return vid.alphamap[pcolor*256 + dstcolor];
  mov ebp, vid.alphamap
  xor ebx, ebx

  shl eax,  8
  mov bl,   byte ptr [edi]

  add ebp, ebx
  add ebp, eax

  mov al,  byte ptr [ebp]

  mov byte ptr [edi], al
end;

procedure BlendParticle100;
asm
  mov   byte ptr [edi], al
end;

{
** 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.
**
}

procedure R_DrawParticle;
// GARGO: labels must be defined before they are used, even in
//   assmebler code
label
  blendfunc_33;
label
  blendfunc_66;
label
  done_selecting_blend_func;
label
  check_pix_max;
label
  skip_pix_clamp;
label
  over;
label
  top_of_pix_vert_loop;
label
  top_of_pix_horiz_loop;
label
  end_of_horiz_loop;
label
  end_;
asm
    // GARGO: statics declared here moved to the interface area
    {
    ** save trashed variables
    }
    mov  ebpsave, ebp
    push esi
    push edi

    {
    ** transform the particle
    }
    // VectorSubtract (pparticle->origin, r_origin, local);
    mov  esi, partparms.particle
    fld  dword ptr [esi+0]          // p_o.x
    fsub dword ptr [r_origin+0]     // p_o.x-r_o.x
    fld  dword ptr [esi+4]          // p_o.y | p_o.x-r_o.x
    fsub dword ptr [r_origin+4]     // p_o.y-r_o.y | p_o.x-r_o.x
    fld  dword ptr [esi+8]          // p_o.z | p_o.y-r_o.y | p_o.x-r_o.x
    fsub dword ptr [r_origin+8]     // p_o.z-r_o.z | p_o.y-r_o.y | p_o.x-r_o.x
    fxch st(2)                      // p_o.x-r_o.x | p_o.y-r_o.y | p_o.z-r_o.z
    fstp dword ptr [local+0]        // p_o.y-r_o.y | p_o.z-r_o.z
    fstp dword ptr [local+4]        // p_o.z-r_o.z
    fstp dword ptr [local+8]        // (empty)

	// transformed[0] = DotProduct(local, r_pright);
	// transformed[1] = DotProduct(local, r_pup);
	// transformed[2] = DotProduct(local, r_ppn);
    fld  dword ptr [local+0]        // l.x
    fmul dword ptr [r_pright+0]     // l.x*pr.x
    fld  dword ptr [local+4]        // l.y | l.x*pr.x
    fmul dword ptr [r_pright+4]     // l.y*pr.y | l.x*pr.x
    fld  dword ptr [local+8]        // l.z | l.y*pr.y | l.x*pr.x
    fmul dword ptr [r_pright+8]     // l.z*pr.z | l.y*pr.y | l.x*pr.x
    fxch st(2)                      // l.x*pr.x | l.y*pr.y | l.z*pr.z
    faddp st(1), st                 // l.x*pr.x + l.y*pr.y | l.z*pr.z
    faddp st(1), st                 // l.x*pr.x + l.y*pr.y + l.z*pr.z
    fstp  dword ptr [transformed+0] // (empty)

    fld  dword ptr [local+0]        // l.x
    fmul dword ptr [r_pup+0]        // l.x*pr.x
    fld  dword ptr [local+4]        // l.y | l.x*pr.x
    fmul dword ptr [r_pup+4]        // l.y*pr.y | l.x*pr.x
    fld  dword ptr [local+8]        // l.z | l.y*pr.y | l.x*pr.x
    fmul dword ptr [r_pup+8]        // l.z*pr.z | l.y*pr.y | l.x*pr.x
    fxch st(2)                      // l.x*pr.x | l.y*pr.y | l.z*pr.z
    faddp st(1), st                 // l.x*pr.x + l.y*pr.y | l.z*pr.z
    faddp st(1), st                 // l.x*pr.x + l.y*pr.y + l.z*pr.z
    fstp  dword ptr [transformed+4] // (empty)

    fld  dword ptr [local+0]        // l.x
    fmul dword ptr [r_ppn+0]        // l.x*pr.x
    fld  dword ptr [local+4]        // l.y | l.x*pr.x
    fmul dword ptr [r_ppn+4]        // l.y*pr.y | l.x*pr.x
    fld  dword ptr [local+8]        // l.z | l.y*pr.y | l.x*pr.x
    fmul dword ptr [r_ppn+8]        // l.z*pr.z | l.y*pr.y | l.x*pr.x
    fxch st(2)                      // l.x*pr.x | l.y*pr.y | l.z*pr.z
    faddp st(1), st                 // l.x*pr.x + l.y*pr.y | l.z*pr.z
    faddp st(1), st                 // l.x*pr.x + l.y*pr.y + l.z*pr.z
    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;

    mov  eax, dword ptr [transformed+8]
    and  eax, eax
    js   end_
    cmp  eax, particle_z_clip
    jl   end_

    {
    ** project the point by initiating the 1/z calc
    }
    //	zi = 1.0 / transformed[2];
    fld   one
    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;

    cmp partparms.level, PARTICLE_66
    je  blendfunc_66
    jl  blendfunc_33
    lea ebx, BlendParticle100
    jmp done_selecting_blend_func
blendfunc_33:
    lea ebx, BlendParticle33
    jmp done_selecting_blend_func
blendfunc_66:
    lea ebx, BlendParticle66
done_selecting_blend_func:
    mov blendfunc, ebx

    // prefetch the next particle
    mov ebp, s_prefetch_address
    mov ebp, [ebp]

    // finish the above divide
    fstp  zi

    // u = (int)(xcenter + zi * transformed[0] + 0.5);
    // v = (int)(ycenter - zi * transformed[1] + 0.5);
    fld   zi                           // zi
    fmul  dword ptr [transformed+0]    // zi * transformed[0]
    fld   zi                           // zi | zi * transformed[0]
    fmul  dword ptr [transformed+4]    // zi * transformed[1] | zi * transformed[0]
    fxch  st(1)                        // zi * transformed[0] | zi * transformed[1]
    fadd  xcenter                      // xcenter + zi * transformed[0] | zi * transformed[1]
    fxch  st(1)                        // zi * transformed[1] | xcenter + zi * transformed[0]
    fld   ycenter                      // ycenter | zi * transformed[1] | xcenter + zi * transformed[0]
    fsubrp st(1), st(0)                // ycenter - zi * transformed[1] | xcenter + zi * transformed[0]
    fxch  st(1)                        // xcenter + zi * transformed[0] | ycenter + zi * transformed[1]
    fadd  point_five                   // xcenter + zi * transformed[0] + 0.5 | ycenter - zi * transformed[1]
    fxch  st(1)                        // ycenter - zi * transformed[1] | xcenter + zi * transformed[0] + 0.5
    fadd  point_five                   // ycenter - zi * transformed[1] + 0.5 | xcenter + zi * transformed[0] + 0.5
    fxch  st(1)                        // u | v
    fistp dword ptr [u]                // v
    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;
    //	}

    mov ebx, u
    mov ecx, v
    cmp ecx, d_vrectbottom_particle
    jg  end_
    cmp ecx, d_vrecty
    jl  end_
    cmp ebx, d_vrectright_particle
    jg  end_
    cmp ebx, d_vrectx
    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;
    mov esi, d_pzbuffer             // esi = d_pzbuffer
    mov eax, d_zwidth               // eax = d_zwidth
    mul ecx                         // eax = d_zwidth*v
    add eax, ebx                    // eax = d_zwidth*v+u
    shl eax, 1                      // eax = 2*(d_zwidth*v+u)
    add esi, eax                    // ; esi = ( short * ) ( d_pzbuffer + ( d_zwidth * v ) + u )

    // initiate
    // izi = (int)(zi * 0x8000);
    fld  zi
    fmul eight_thousand_hex

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -