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

📄 r_edgea.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit r_edgea;
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): r_edgea.asm                                                          }
{                                                                            }
{ Initial conversion by : CodeFusion (michael@skovslund.dk)                  }
{ Initial conversion on : 16-July-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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updated on :                                                               }
{ Updated by :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{  r_local,                                                                  }
{  r_main,                                                                   }
{  cvar,                                                                     }
{  r_model,                                                                  }
{----------------------------------------------------------------------------}
{  These variables has been moved from Edge.pas to this one because otherwise}
{  we would have had circular references.                                    }
{                                                                            }
{  edge_head           : edge_t;                                             }
{  edge_tail           : edge_t;                                             }
{  edge_aftertail      : edge_t;                                             }
{  edge_head_u_shift20 : Integer;                                            }
{  edge_tail_u_shift20 : Integer;                                            }
{  current_iv          : Integer;                                            }
{  fv                  : Single;                                             }
{  span_p              : espan_p;                                            }
{	 surfaces            : surf_p;                                             }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ Types and variables has been created here for the source to compile.       }
{ Remove all lines marked with (*R*).                                        }
{----------------------------------------------------------------------------}

interface

uses
  qasm_inc,
  r_local,
  r_main,
  r_model,
  r_varsa;

type
  TEdgeCode = procedure;

var
  edge_head: edge_t;
  edge_tail: edge_t;
  edge_aftertail: edge_t;
  edge_head_u_shift20: Integer;
  edge_tail_u_shift20: Integer;

  current_iv: Integer;
  fv: Single;
  span_p: espan_p;

  surfaces: surf_p;

{$IFDEF	id386}
var
  R_EdgeCodeStart: TEdgeCode;
  R_EdgeCodeEnd: TEdgeCode;

procedure R_InsertNewEdges(edgestoadd: edge_p; edgelist: edge_p);
procedure R_RemoveEdges(pedge: edge_p);
procedure R_StepActiveU(pedge: edge_p);
procedure R_GenerateSpans;
procedure R_SurfacePatch;
{$ENDIF}

implementation

{$IFDEF	id386}
var
  Ltemp: Integer; // 0
  float_1_div_0100000h: Single; //035800000h	; 1.0/(float)0x100000
  float_point_999: Single; // 0.999
  float_1_point_001: Single; // 1.001

// FIX, for code self modification, used in original asm code.
  LPatch0_Value: Pointer;
  LPatch2_Value: Pointer;
  LPatch3_Value: Pointer;
  LPatch4_Value: Pointer;

procedure R_InsertNewEdges(edgestoadd: edge_p; edgelist: edge_p);
const
  edgestoadd_ = 4 + 8; //note odd stack offsets because of interleaving
  edgelist_ = 8 + 12; //with pushes
asm
@_R_EdgeCodeStart:
  push  edi
  push  esi	// preserve register variables

  mov   edx,ds:dword ptr[edgestoadd_+ebp]
  push  ebx
  mov   ecx,ds:dword ptr[edgelist_+ebp]

@LDoNextEdge:
  mov   eax,ds:dword ptr[et_u+edx]
  mov   edi,edx

@LContinueSearch:
  mov   ebx,ds:dword ptr[et_u+ecx]
  mov   esi,ds:dword ptr[et_next+ecx]
  cmp   eax,ebx
  jle   @LAddedge
  mov   ebx,ds:dword ptr[et_u+esi]
  mov   ecx,ds:dword ptr[et_next+esi]
  cmp   eax,ebx
  jle   @LAddedge2
  mov   ebx,ds:dword ptr[et_u+ecx]
  mov   esi,ds:dword ptr[et_next+ecx]
  cmp   eax,ebx
  jle   @LAddedge
  mov   ebx,ds:dword ptr[et_u+esi]
  mov   ecx,ds:dword ptr[et_next+esi]
  cmp   eax,ebx
  jg    @LContinueSearch

@LAddedge2:
  mov   edx,ds:dword ptr[et_next+edx]
  mov   ebx,ds:dword ptr[et_prev+esi]
  mov   ds:dword ptr[et_next+edi],esi
  mov   ds:dword ptr[et_prev+edi],ebx
  mov   ds:dword ptr[et_next+ebx],edi
  mov   ds:dword ptr[et_prev+esi],edi
  mov   ecx,esi

  cmp   edx,0
  jnz   @LDoNextEdge
  jmp   @LDone

  {$align 4}
@LAddedge:
  mov   edx,ds:dword ptr[et_next+edx]
  mov   ebx,ds:dword ptr[et_prev+ecx]
  mov   ds:dword ptr[et_next+edi],ecx
  mov   ds:dword ptr[et_prev+edi],ebx
  mov   ds:dword ptr[et_next+ebx],edi
  mov   ds:dword ptr[et_prev+ecx],edi

  cmp   edx,0
  jnz   @LDoNextEdge

@LDone:
  pop   ebx	// restore register variables
  pop   esi
  pop   edi
end;

procedure R_RemoveEdges(pedge: edge_p);
const
  predge = 4 + 4;
asm
  push  ebx
  mov   eax,ds:dword ptr[predge+ebp]

@Lre_loop:
  mov   ecx,ds:dword ptr[et_next+eax]
  mov   ebx,ds:dword ptr[et_nextremove+eax]
  mov   edx,ds:dword ptr[et_prev+eax]
  test  ebx,ebx
  mov   ds:dword ptr[et_prev+ecx],edx
  jz    @Lre_done
  mov   ds:dword ptr[et_next+edx],ecx

  mov   ecx,ds:dword ptr[et_next+ebx]
  mov   edx,ds:dword ptr[et_prev+ebx]
  mov   eax,ds:dword ptr[et_nextremove+ebx]
  mov   ds:dword ptr[et_prev+ecx],edx
  test  eax,eax
  mov   ds:dword ptr[et_next+edx],ecx
  jnz   @Lre_loop

  jmp   @Done

@Lre_done:
  mov   ds:dword ptr[et_next+edx],ecx
@Done:
  pop   ebx
end;

procedure R_StepActiveU(pedge: edge_p);
const
  pedgelist = 4 + 4; // note odd stack offset because of interleaving
                    // with pushes
asm
  push  edi
  mov   edx,ds:dword ptr[pedgelist+ebp]
  push  esi	// preserve register variables
  push  ebx

  mov   esi,ds:dword ptr[et_prev+edx]

@LNewEdge:
  mov   edi,ds:dword ptr[et_u+esi]

@LNextEdge:
  mov   eax,ds:dword ptr[et_u+edx]
  mov   ebx,ds:dword ptr[et_u_step+edx]
  add   eax,ebx
  mov   esi,ds:dword ptr[et_next+edx]
  mov   ds:dword ptr[et_u+edx],eax
  cmp   eax,edi
  jl    @LPushBack

  mov   edi,ds:dword ptr[et_u+esi]
  mov   ebx,ds:dword ptr[et_u_step+esi]
  add   edi,ebx
  mov   edx,ds:dword ptr[et_next+esi]
  mov   ds:dword ptr[et_u+esi],edi
  cmp   edi,eax
  jl    @LPushBack2

  mov   eax,ds:dword ptr[et_u+edx]
  mov   ebx,ds:dword ptr[et_u_step+edx]
  add   eax,ebx
  mov   esi,ds:dword ptr[et_next+edx]
  mov   ds:dword ptr[et_u+edx],eax
  cmp   eax,edi
  jl    @LPushBack

  mov   edi,ds:dword ptr[et_u+esi]
  mov   ebx,ds:dword ptr[et_u_step+esi]
  add   edi,ebx
  mov   edx,ds:dword ptr[et_next+esi]
  mov   ds:dword ptr[et_u+esi],edi
  cmp   edi,eax
  jnl   @LNextEdge

@LPushBack2:
  mov   ebx,edx
  mov   eax,edi
  mov   edx,esi
  mov   esi,ebx

@LPushBack:
// push it back to keep it sorted
  mov   ecx,ds:dword ptr[et_prev+edx]
  mov   ebx,ds:dword ptr[et_next+edx]

// done if the -1 in edge_aftertail triggered this
  cmp   edx,offset edge_aftertail
  jz    @LUDone

// pull the edge out of the edge list
  mov   edi,ds:dword ptr[et_prev+ecx]
  mov   ds:dword ptr[et_prev+esi],ecx
  mov   ds:dword ptr[et_next+ecx],ebx

// find out where the edge goes in the edge list
@LPushBackLoop:
  mov   ecx,ds:dword ptr[et_prev+edi]
  mov   ebx,ds:dword ptr[et_u+edi]
  cmp   eax,ebx
  jnl   @LPushBackFound

  mov   edi,ds:dword ptr[et_prev+ecx]
  mov   ebx,ds:dword ptr[et_u+ecx]
  cmp   eax,ebx
  jl    @LPushBackLoop

  mov   edi,ecx

// put the edge back into the edge list
@LPushBackFound:
  mov   ebx,ds:dword ptr[et_next+edi]
  mov   ds:dword ptr[et_prev+edx],edi
  mov   ds:dword ptr[et_next+edx],ebx
  mov   ds:dword ptr[et_next+edi],edx
  mov   ds:dword ptr[et_prev+ebx],edx

  mov   edx,esi
  mov   esi,ds:dword ptr[et_prev+esi]

  cmp   edx,offset edge_tail
  jnz   @LNewEdge

@LUDone:
  pop   ebx	// restore register variables
  pop   esi
  pop   edi
end;

procedure R_GenerateSpans;
const
  surf = 4; // note this is loaded before any pushes
asm
  jmp     @_R_GenerateSpans

  {$align 4}
// Called within this function
@TrailingEdge:
  mov     eax,ds:dword ptr[st_spanstate+esi]	// check for edge inversion
  dec     eax
  jnz     @LInverted

  mov     ds:dword ptr[st_spanstate+esi],eax
  mov     ecx,ds:dword ptr[st_insubmodel+esi]
//  mov     edx,ds:dword ptr[12345678h]	// surfaces[1].st_next
  mov     edx,ds:dword ptr[LPatch0_Value]	// surfaces[1].st_next

@LPatch0:
  mov     eax,ds:dword ptr[_r_bmodelactive]
  sub     eax,ecx
  cmp     edx,esi
  mov     ds:dword ptr[_r_bmodelactive],eax
  jnz     @LNoEmit	// surface isn't on top, just remove

// emit a span (current top going away)
  mov     eax,ds:dword ptr[et_u+ebx]
  shr     eax,20	// iu = integral pixel u
  mov     edx,ds:dword ptr[st_last_u+esi]
  mov     ecx,ds:dword ptr[st_next+esi]
  cmp     eax,edx
  jle     @LNoEmit2	// iu <= surf->last_u, so nothing to emit

  mov     ds:dword ptr[st_last_u+ecx],eax	// surf->next->last_u = iu;
  sub     eax,edx
  mov     ds:dword ptr[espan_t_u+ebp],edx	// span->u = surf->last_u;

  mov     ds:dword ptr[espan_t_count+ebp],eax	// span->count = iu - span->u;
  mov     eax,ds:dword ptr[current_iv]
  mov     ds:dword ptr[espan_t_v+ebp],eax	// span->v = current_iv;
  mov     eax,ds:dword ptr[st_spans+esi]
  mov     ds:dword ptr[espan_t_pnext+ebp],eax	// span->pnext = surf->spans;
  mov     ds:dword ptr[st_spans+esi],ebp	// surf->spans = span;
  add     ebp,offset espan_t_size

  mov     edx,ds:dword ptr[st_next+esi]	// remove the surface from the surface
  mov     esi,ds:dword ptr[st_prev+esi]	// stack

  mov     ds:dword ptr[st_next+esi],edx
  mov     ds:dword ptr[st_prev+edx],esi
  ret

@LNoEmit2:
  mov     ds:dword ptr[st_last_u+ecx],eax	// surf->next->last_u = iu;
  mov     edx,ds:dword ptr[st_next+esi]	// remove the surface from the surface
  mov     esi,ds:dword ptr[st_prev+esi]	// stack

  mov     ds:dword ptr[st_next+esi],edx
  mov     ds:dword ptr[st_prev+edx],esi
  ret

@LNoEmit:
  mov     edx,ds:dword ptr[st_next+esi]	// remove the surface from the surface
  mov     esi,ds:dword ptr[st_prev+esi]	// stack

  mov     ds:dword ptr[st_next+esi],edx
  mov     ds:dword ptr[st_prev+edx],esi
  ret

@LInverted:
  mov     ds:dword ptr[st_spanstate+esi],eax
  ret

//--------------------------------------------------------------------

// trailing edge only
@Lgs_trailing:
  push    offset @Lgs_nextedge
  jmp     @TrailingEdge

// Entry point for this function.
{$align 4}
@_R_GenerateSpans:
  push    ebp	// preserve caller's stack frame
  push    edi
  push    esi	// preserve register variables
  push    ebx

// clear active surfaces to just the background surface
  mov     eax,ds:dword ptr[surfaces]
  mov     edx,ds:dword ptr[edge_head_u_shift20]
  add     eax,offset st_size
// %ebp = span_p throughout
  mov     ebp,ds:dword ptr[span_p]

  mov     ds:dword ptr[_r_bmodelactive],0

  mov     ds:dword ptr[st_next+eax],eax
  mov     ds:dword ptr[st_prev+eax],eax
  mov     ds:dword ptr[st_last_u+eax],edx
  mov     ebx,ds:dword ptr[edge_head+et_next]	// edge=edge_head.next

// generate spans
  cmp     ebx,offset edge_tail	// done if empty list
  jz      @Lgs_lastspan

⌨️ 快捷键说明

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