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

📄 r_draw16.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): r_main.c                                                          }
{                                                                            }
{ Initial conversion by : CodeFusion - Michael@Skovslund.dk                  }
{ Initial conversion on : 9-Aug-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:                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{  Implement asm code into functions.                                        }
{----------------------------------------------------------------------------}
unit r_draw16;

interface

uses
  r_local;

procedure D_DrawSpans16(pspan: espan_p);
procedure D_DrawZSpans(pspan: espan_p);

implementation

procedure D_DrawSpans16(pspan: espan_p);
begin
end;

procedure D_DrawZSpans(pspan: espan_p);
begin
end;

(*
 .386P
 .model FLAT
;
; d_draw16.s
; x86 assembly-language horizontal 8-bpp span-drawing code, with 16-pixel
; subdivision.
;

include qasm.inc
include d_if.inc

if	id386

;----------------------------------------------------------------------
; 8-bpp horizontal span drawing code for polygons, with no transparency and
; 16-pixel subdivision.
;
; Assumes there is at least one span in pspans, and that every span
; contains at least one pixel
;----------------------------------------------------------------------

_DATA SEGMENT

_DATA ENDS
_TEXT SEGMENT

; out-of-line, rarely-needed clamping code

LClampHigh0:
 mov esi,ds:dword ptr[_bbextents]
 jmp LClampReentry0
LClampHighOrLow0:
 jg LClampHigh0
 xor esi,esi
 jmp LClampReentry0

LClampHigh1:
 mov edx,ds:dword ptr[_bbextentt]
 jmp LClampReentry1
LClampHighOrLow1:
 jg LClampHigh1
 xor edx,edx
 jmp LClampReentry1

LClampLow2:
 mov ebp,4096
 jmp LClampReentry2
LClampHigh2:
 mov ebp,ds:dword ptr[_bbextents]
 jmp LClampReentry2

LClampLow3:
 mov ecx,4096
 jmp LClampReentry3
LClampHigh3:
 mov ecx,ds:dword ptr[_bbextentt]
 jmp LClampReentry3

LClampLow4:
 mov eax,4096
 jmp LClampReentry4
LClampHigh4:
 mov eax,ds:dword ptr[_bbextents]
 jmp LClampReentry4

LClampLow5:
 mov ebx,4096
 jmp LClampReentry5
LClampHigh5:
 mov ebx,ds:dword ptr[_bbextentt]
 jmp LClampReentry5

pspans	equ		4+16

 align 4
 public _D_DrawSpans16
_D_DrawSpans16:
 push ebp	; preserve caller's stack frame
 push edi
 push esi	; preserve register variables
 push ebx

;
; set up scaled-by-16 steps, for 16-long segments; also set up cacheblock
; and span list pointers
;
; TODO: any overlap from rearranging?
 fld ds:dword ptr[_d_sdivzstepu]
 fmul ds:dword ptr[fp_16]
 mov edx,ds:dword ptr[_cacheblock]
 fld ds:dword ptr[_d_tdivzstepu]
 fmul ds:dword ptr[fp_16]
 mov ebx,ds:dword ptr[pspans+esp]	; point to the first span descriptor
 fld ds:dword ptr[_d_zistepu]
 fmul ds:dword ptr[fp_16]
 mov ds:dword ptr[pbase],edx	; pbase = cacheblock
 fstp ds:dword ptr[zi16stepu]
 fstp ds:dword ptr[tdivz16stepu]
 fstp ds:dword ptr[sdivz16stepu]

LSpanLoop:
;
; set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
; initial s and t values
;
; FIXME: pipeline FILD?
 fild ds:dword ptr[espan_t_v+ebx]
 fild ds:dword ptr[espan_t_u+ebx]

 fld st(1)	; dv | du | dv
 fmul ds:dword ptr[_d_sdivzstepv]	; dv*d_sdivzstepv | du | dv
 fld st(1)	; du | dv*d_sdivzstepv | du | dv
 fmul ds:dword ptr[_d_sdivzstepu]	; du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
 fld st(2)	; du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
 fmul ds:dword ptr[_d_tdivzstepu]	; du*d_tdivzstepu | du*d_sdivzstepu |
;  dv*d_sdivzstepv | du | dv
 fxch st(1)	; du*d_sdivzstepu | du*d_tdivzstepu |
;  dv*d_sdivzstepv | du | dv
 faddp st(2),st(0)	; du*d_tdivzstepu |
;  du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
 fxch st(1)	; du*d_sdivzstepu + dv*d_sdivzstepv |
;  du*d_tdivzstepu | du | dv
 fld st(3)	; dv | du*d_sdivzstepu + dv*d_sdivzstepv |
;  du*d_tdivzstepu | du | dv
 fmul ds:dword ptr[_d_tdivzstepv]	; dv*d_tdivzstepv |
;  du*d_sdivzstepu + dv*d_sdivzstepv |
;  du*d_tdivzstepu | du | dv
 fxch st(1)	; du*d_sdivzstepu + dv*d_sdivzstepv |
;  dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
 fadd ds:dword ptr[_d_sdivzorigin]	; sdivz = d_sdivzorigin + dv*d_sdivzstepv +
;  du*d_sdivzstepu; stays in %st(2) at end
 fxch st(4)	; dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
;  s/z
 fmul ds:dword ptr[_d_zistepv]	; dv*d_zistepv | dv*d_tdivzstepv |
;  du*d_tdivzstepu | du | s/z
 fxch st(1)	; dv*d_tdivzstepv |  dv*d_zistepv |
;  du*d_tdivzstepu | du | s/z
 faddp st(2),st(0)	; dv*d_zistepv |
;  dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
 fxch st(2)	; du | dv*d_tdivzstepv + du*d_tdivzstepu |
;  dv*d_zistepv | s/z
 fmul ds:dword ptr[_d_zistepu]	; du*d_zistepu |
;  dv*d_tdivzstepv + du*d_tdivzstepu |
;  dv*d_zistepv | s/z
 fxch st(1)	; dv*d_tdivzstepv + du*d_tdivzstepu |
;  du*d_zistepu | dv*d_zistepv | s/z
 fadd ds:dword ptr[_d_tdivzorigin]	; tdivz = d_tdivzorigin + dv*d_tdivzstepv +
;  du*d_tdivzstepu; stays in %st(1) at end
 fxch st(2)	; dv*d_zistepv | du*d_zistepu | t/z | s/z
 faddp st(1),st(0)	; dv*d_zistepv + du*d_zistepu | t/z | s/z

 fld ds:dword ptr[fp_64k]	; fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
 fxch st(1)	; dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
 fadd ds:dword ptr[_d_ziorigin]	; zi = d_ziorigin + dv*d_zistepv +
;  du*d_zistepu; stays in %st(0) at end
; 1/z | fp_64k | t/z | s/z
;
; calculate and clamp s & t
;
 fdiv st(1),st(0)	; 1/z | z*64k | t/z | s/z

;
; point %edi to the first pixel in the span
;
 mov ecx,ds:dword ptr[_d_viewbuffer]
 mov eax,ds:dword ptr[espan_t_v+ebx]
 mov ds:dword ptr[pspantemp],ebx	; preserve spans pointer

 mov edx,ds:dword ptr[_tadjust]
 mov esi,ds:dword ptr[_sadjust]
 mov edi,ds:dword ptr[_d_scantable+eax*4]	; v * screenwidth
 add edi,ecx
 mov ecx,ds:dword ptr[espan_t_u+ebx]
 add edi,ecx	; pdest = &pdestspan[scans->u];
 mov ecx,ds:dword ptr[espan_t_count+ebx]

;
; now start the FDIV for the end of the span
;
 cmp ecx,16
 ja LSetupNotLast1

 dec ecx
 jz LCleanup1	; if only one pixel, no need to start an FDIV
 mov ds:dword ptr[spancountminus1],ecx

; finish up the s and t calcs
 fxch st(1)	; z*64k | 1/z | t/z | s/z

 fld st(0)	; z*64k | z*64k | 1/z | t/z | s/z
 fmul st(0),st(4)	; s | z*64k | 1/z | t/z | s/z
 fxch st(1)	; z*64k | s | 1/z | t/z | s/z
 fmul st(0),st(3)	; t | s | 1/z | t/z | s/z
 fxch st(1)	; s | t | 1/z | t/z | s/z
 fistp ds:dword ptr[s]	; 1/z | t | t/z | s/z
 fistp ds:dword ptr[t]	; 1/z | t/z | s/z

 fild ds:dword ptr[spancountminus1]

 fld ds:dword ptr[_d_tdivzstepu]	; C(d_tdivzstepu) | spancountminus1
 fld ds:dword ptr[_d_zistepu]	; C(d_zistepu) | C(d_tdivzstepu) | spancountminus1
 fmul st(0),st(2)	; C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1
 fxch st(1)	; C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
 fmul st(0),st(2)	; C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
 fxch st(2)	; scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1
 fmul ds:dword ptr[_d_sdivzstepu]	; C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 |
;  C(d_tdivzstepu)*scm1
 fxch st(1)	; C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 |
;  C(d_tdivzstepu)*scm1
 faddp st(3),st(0)	; C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
 fxch st(1)	; C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
 faddp st(3),st(0)	; C(d_sdivzstepu)*scm1
 faddp st(3),st(0)

 fld ds:dword ptr[fp_64k]
 fdiv st(0),st(1)	; this is what we've gone to all this trouble to
;  overlap
 jmp LFDIVInFlight1

LCleanup1:
; finish up the s and t calcs
 fxch st(1)	; z*64k | 1/z | t/z | s/z

 fld st(0)	; z*64k | z*64k | 1/z | t/z | s/z
 fmul st(0),st(4)	; s | z*64k | 1/z | t/z | s/z
 fxch st(1)	; z*64k | s | 1/z | t/z | s/z
 fmul st(0),st(3)	; t | s | 1/z | t/z | s/z
 fxch st(1)	; s | t | 1/z | t/z | s/z
 fistp ds:dword ptr[s]	; 1/z | t | t/z | s/z
 fistp ds:dword ptr[t]	; 1/z | t/z | s/z
 jmp LFDIVInFlight1

 align 4
LSetupNotLast1:
; finish up the s and t calcs
 fxch st(1)	; z*64k | 1/z | t/z | s/z

 fld st(0)	; z*64k | z*64k | 1/z | t/z | s/z
 fmul st(0),st(4)	; s | z*64k | 1/z | t/z | s/z
 fxch st(1)	; z*64k | s | 1/z | t/z | s/z
 fmul st(0),st(3)	; t | s | 1/z | t/z | s/z
 fxch st(1)	; s | t | 1/z | t/z | s/z
 fistp ds:dword ptr[s]	; 1/z | t | t/z | s/z
 fistp ds:dword ptr[t]	; 1/z | t/z | s/z

 fadd ds:dword ptr[zi16stepu]
 fxch st(2)
 fadd ds:dword ptr[sdivz16stepu]
 fxch st(2)
 fld ds:dword ptr[tdivz16stepu]
 faddp st(2),st(0)
 fld ds:dword ptr[fp_64k]
 fdiv st(0),st(1)	; z = 1/1/z
; this is what we've gone to all this trouble to
;  overlap
LFDIVInFlight1:

 add esi,ds:dword ptr[s]
 add edx,ds:dword ptr[t]
 mov ebx,ds:dword ptr[_bbextents]
 mov ebp,ds:dword ptr[_bbextentt]
 cmp esi,ebx
 ja LClampHighOrLow0
LClampReentry0:
 mov ds:dword ptr[s],esi
 mov ebx,ds:dword ptr[pbase]
 shl esi,16
 cmp edx,ebp
 mov ds:dword ptr[sfracf],esi
 ja LClampHighOrLow1
LClampReentry1:
 mov ds:dword ptr[t],edx
 mov esi,ds:dword ptr[s]	; sfrac = scans->sfrac;
 shl edx,16
 mov eax,ds:dword ptr[t]	; tfrac = scans->tfrac;
 sar esi,16
 mov ds:dword ptr[tfracf],edx

;
; calculate the texture starting address
;
 sar eax,16
 mov edx,ds:dword ptr[_cachewidth]
 imul eax,edx	; (tfrac >> 16) * cachewidth
 add esi,ebx
 add esi,eax	; psource = pbase + (sfrac >> 16) +
;           ((tfrac >> 16) * cachewidth);
;
; determine whether last span or not
;
 cmp ecx,16
 jna LLastSegment

;
; not the last segment; do full 16-wide segment
;
LNotLastSegment:

;
; advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
; get there
;

; pick up after the FDIV that was left in flight previously

 fld st(0)	; duplicate it
 fmul st(0),st(4)	; s = s/z * z
 fxch st(1)
 fmul st(0),st(3)	; t = t/z * z
 fxch st(1)
 fistp ds:dword ptr[snext]
 fistp ds:dword ptr[tnext]
 mov eax,ds:dword ptr[snext]
 mov edx,ds:dword ptr[tnext]

 mov bl,ds:byte ptr[esi]	; get first source texel
 sub ecx,16	; count off this segments' pixels
 mov ebp,ds:dword ptr[_sadjust]
 mov ds:dword ptr[counttemp],ecx	; remember count of remaining pixels

 mov ecx,ds:dword ptr[_tadjust]
 mov ds:byte ptr[edi],bl	; store first dest pixel

 add ebp,eax
 add ecx,edx

 mov eax,ds:dword ptr[_bbextents]
 mov edx,ds:dword ptr[_bbextentt]

 cmp ebp,4096
 jl LClampLow2
 cmp ebp,eax
 ja LClampHigh2
LClampReentry2:

 cmp ecx,4096
 jl LClampLow3
 cmp ecx,edx
 ja LClampHigh3
LClampReentry3:

 mov ds:dword ptr[snext],ebp
 mov ds:dword ptr[tnext],ecx

 sub ebp,ds:dword ptr[s]
 sub ecx,ds:dword ptr[t]

;
; set up advancetable
;
 mov eax,ecx
 mov edx,ebp
 sar eax,20	; tstep >>= 16;
 jz LZero
 sar edx,20	; sstep >>= 16;
 mov ebx,ds:dword ptr[_cachewidth]
 imul eax,ebx
 jmp LSetUp1

LZero:
 sar edx,20	; sstep >>= 16;
 mov ebx,ds:dword ptr[_cachewidth]

LSetUp1:

 add eax,edx	; add in sstep
; (tstep >> 16) * cachewidth + (sstep >> 16);
 mov edx,ds:dword ptr[tfracf]
 mov ds:dword ptr[advancetable+4],eax	; advance base in t
 add eax,ebx	; ((tstep >> 16) + 1) * cachewidth +
;  (sstep >> 16);
 shl ebp,12	; left-justify sstep fractional part
 mov ebx,ds:dword ptr[sfracf]

⌨️ 快捷键说明

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