Files
lba1-classic/LIB386/LIB_3D/P_FUNC.ASM

1260 lines
29 KiB
NASM

.386p
jumps
.model SMALL, SYSCALL
include P_define.ash
.data
include \projet\lib386\lib_sys\lib_sys.ash
Comment @
SqrTab dw 0807Fh,0817Dh,08279h,08374h,0846Ch,08562h,08657h,0874Ah
dw 0883Ch,0892Bh,08A19h,08B06h,08BF1h,08CDAh,08DC2h,08EA9h
dw 08F8Eh,09071h,09153h,09234h,09314h,093F2h,094CFh,095AAh
dw 09684h,0975Dh,09835h,0990Ch,099E2h,09AB6h,09B89h,09C5Bh
dw 09D2Ch,09DFCh,09ECBh,09F99h,0A066h,0A132h,0A1FCh,0A2C6h
dw 0A38Fh,0A457h,0A51Eh,0A5E4h,0A6A9h,0A76Dh,0A830h,0A8F3h
dw 0A9B4h,0AA75h,0AB35h,0ABF4h,0ACB2h,0AD6Fh,0AE2Ch,0AEE7h
dw 0AFA2h,0B05Ch,0B116h,0B1CFh,0B286h,0B33Eh,0B3F4h,0B4AAh
dw 0B55Fh,0B613h,0B6C7h,0B77Ah,0B82Ch,0B8DEh,0B98Fh,0BA3Fh
dw 0BAEEh,0BB9Dh,0BC4Ch,0BCF9h,0BDA6h,0BE53h,0BEFFh,0BFAAh
dw 0C055h,0C0FFh,0C1A8h,0C251h,0C2FAh,0C3A1h,0C449h,0C4EFh
dw 0C595h,0C63Bh,0C6E0h,0C784h,0C828h,0C8CCh,0C96Fh,0CA11h
dw 0CAB3h,0CB55h,0CBF5h,0CC96h,0CD36h,0CDD5h,0CE74h,0CF13h
dw 0CFB1h,0D04Eh,0D0EBh,0D188h,0D224h,0D2C0h,0D35Bh,0D3F6h
dw 0D490h,0D52Ah,0D5C4h,0D65Dh,0D6F5h,0D78Eh,0D825h,0D8BDh
dw 0D954h,0D9EAh,0DA81h,0DB16h,0DBACh,0DC41h,0DCD5h,0DD69h
dw 0DDFDh,0DE91h,0DF24h,0DFB6h,0E049h,0E0DBh,0E16Ch,0E1FDh
dw 0E28Eh,0E31Fh,0E3AFh,0E43Eh,0E4CEh,0E55Dh,0E5EBh,0E67Ah
dw 0E708h,0E795h,0E823h,0E8B0h,0E93Ch,0E9C9h,0EA55h,0EAE0h
dw 0EB6Ch,0EBF7h,0EC82h,0ED0Ch,0ED96h,0EE20h,0EEA9h,0EF32h
dw 0EFBBh,0F044h,0F0CCh,0F154h,0F1DCh,0F263h,0F2EAh,0F371h
dw 0F3F7h,0F47Dh,0F503h,0F589h,0F60Eh,0F693h,0F718h,0F79Ch
dw 0F821h,0F8A4h,0F928h,0F9ABh,0FA2Fh,0FAB1h,0FB34h,0FBB6h
dw 0FC38h,0FCBAh,0FD3Ch,0FDBDh,0FE3Eh,0FEBFh,0FF3Fh,0FFBFh
@
ALIGN 4
public NoLanguage Distance
public NoLanguage Sqr
Distance dd 0000
public NoLanguage EX0
public NoLanguage EY0
EX0 dd 0000
EY0 dd 0000
extrn nolanguage P_SinTab:WORD
;*══════════════════════════════════════════════════════════════════════════*
.code
public NoLanguage Rot2D
public NoLanguage Distance2D
public NoLanguage Distance3D
public NoLanguage GetAngle
public NoLanguage RegleTrois32
public NoLanguage BoundRegleTrois
public NoLanguage InitRealValue
public NoLanguage InitRealAngle
public NoLanguage InitRealAngleConst
public NoLanguage GetRealValue
public NoLanguage GetRealAngle
;*══════════════════════════════════════════════════════════════════════════*
; █▀▀▀█ █▀▀▀▀ █▀▀▀█ █ ▀▀█▀▀ █ █▄ ▄█ █▀▀▀▀
; ██▀█▀ ██▀▀ ██▀▀█ ██ ██ ██ ██▀ █ ██▀▀
; ▀▀ ▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀▀ ▀▀ ▀ ▀▀▀▀▀
;*══════════════════════════════════════════════════════════════════════════*/
;*──────────────────────────────────────────────────────────────────────────*/
InitRealValue proc \
StartValue:DWORD,\
EndValue:DWORD,\
TimeValue:DWORD,\
ptrstruct:DWORD
mov edx, ptrstruct
mov ax, word ptr[StartValue]
mov word ptr[edx], ax
mov ax, word ptr[EndValue]
mov word ptr[edx+2], ax
mov ax, word ptr[TimeValue]
mov word ptr[edx+4], ax
mov eax, [ TimerRef ]
mov dword ptr[edx+6], eax ; memoticks init
ret
InitRealValue endp
comment @
InitRealValue proc uses edi,\
StartValue:DWORD,\
EndValue:DWORD,\
TimeValue:DWORD,\
ptrstruct:DWORD
mov edi, ptrstruct
mov ax, word ptr[StartValue]
mov word ptr[edi], ax
mov ax, word ptr[EndValue]
mov word ptr[edi+2], ax
mov ax, word ptr[TimeValue]
mov word ptr[edi+4], ax
mov eax, [ TimerRef ]
mov dword ptr[edi+6], eax ; memoticks init
ret
InitRealValue endp
@
;*──────────────────────────────────────────────────────────────────────────*/
InitRealAngle proc \
StartValue:DWORD,\
EndValue:DWORD,\
TimeValue:DWORD,\
ptrstruct:DWORD
mov edx, ptrstruct
mov ax, word ptr[StartValue]
and ax, 1023
mov word ptr[edx], ax
mov ax, word ptr[EndValue]
and ax, 1023
mov word ptr[edx+2], ax
mov ax, word ptr[TimeValue]
mov word ptr[edx+4], ax
mov eax, [TimerRef]
mov dword ptr[edx+6], eax ; memoticks init
ret
InitRealAngle endp
comment @
InitRealAngle proc uses edi,\
StartValue:DWORD,\
EndValue:DWORD,\
TimeValue:DWORD,\
ptrstruct:DWORD
mov edi, ptrstruct
mov ax, word ptr[StartValue]
and ax, 1023
mov word ptr[edi], ax
mov ax, word ptr[EndValue]
and ax, 1023
mov word ptr[edi+2], ax
mov ax, word ptr[TimeValue]
mov word ptr[edi+4], ax
mov eax, [TimerRef]
mov dword ptr[edi+6], eax ; memoticks init
ret
InitRealAngle endp
@
;*──────────────────────────────────────────────────────────────────────────*/
InitRealAngleConst proc \
StartValue:DWORD,\
EndValue:DWORD,\
TimeValue:DWORD,\
ptrstruct:DWORD
mov edx, ptrstruct
xor eax, eax ; for imul later on
mov ax, word ptr[StartValue]
and ax, 1023
mov word ptr[edx], ax
mov cx, word ptr[EndValue]
and cx, 1023
mov word ptr[edx+2], cx
sub ax, cx
shl ax, 6
jns short irac0
neg ax
irac0:
shr ax, 6
imul eax, dword ptr[TimeValue]
shr eax, 8 ; /256
mov word ptr[edx+4], ax
mov eax, [TimerRef]
mov dword ptr[edx+6], eax ; memoticks init
ret
InitRealAngleConst endp
comment @
InitRealAngleConst proc uses edi ebx,\
StartValue:DWORD,\
EndValue:DWORD,\
TimeValue:DWORD,\
ptrstruct:DWORD
mov edi, ptrstruct
mov ax, word ptr[StartValue]
and ax, 1023
mov bx, ax
mov word ptr[edi], ax
mov ax, word ptr[EndValue]
and ax, 1023
mov cx, ax
mov word ptr[edi+2], ax
add bx, 1024
sub bx, cx
and bx, 1023
cmp bx, 512
jle irac0
sub bx, 1024
neg bx
irac0: mov ax, word ptr[TimeValue]
imul bx
mov al, ah
mov ah, dl ; /256
mov word ptr[edi+4], ax
mov eax, [TimerRef]
mov dword ptr[edi+6], eax ; memoticks init
ret
InitRealAngleConst endp
@
;*──────────────────────────────────────────────────────────────────────────*
GetRealValue proc uses ebx,\
ptrstruct:DWORD
mov ebx, ptrstruct
movsx eax, word ptr[ebx+2] ; End Value
mov cx, word ptr[ebx+4] ; TimeValue
or cx, cx ; TimeValue Reach = 0
jz elapsed
mov edx, [TimerRef]
sub edx, [ebx+6] ; memoticks
cmp dx, cx ; if step >= nbstep
jae sao2 ; poke EndValue
; nb step = time to come here
sub ax, word ptr[ebx+0] ; start value
imul dx ; resul DX:AX
idiv cx ; /NbStep
add ax, word ptr[ebx+0] ; Valeur1
movsx eax, ax
ret
sao2: mov word ptr[ebx+4], 0 ; TimeValue reset
elapsed: ; return EndValue
ret
GetRealValue endp
comment @
GetRealValue proc uses esi ebx ebp,\
ptrstruct:DWORD
mov esi, ptrstruct
mov dx, word ptr[esi+4] ; TimeValue
or dx, dx ; TimeValue Reach = 0
jz elapsed
mov ecx, [esi+6] ; memoticks
mov eax, [TimerRef]
sub eax, ecx
cmp ax, dx ; if step >= nbstep
jae sao2 ; poke EndValue
movzx ebx, dx ; nb step = time to come here
mov ebp, eax ; step en cours
movsx eax, word ptr[esi+2] ; End Value
movsx ecx, word ptr[esi+0] ; start value
sub eax, ecx
imul ebp ; resul DX:AX
idiv ebx ; /NbStep
add eax, ecx ; cx = Valeur1
ret
sao2: mov word ptr[esi+4], 0 ; TimeValue reset
elapsed: movsx eax, word ptr[esi+2] ; EndValue
ret
GetRealValue endp
@
;*──────────────────────────────────────────────────────────────────────────*
GetRealAngle proc uses ebx,\
ptrstruct:DWORD
mov ebx, ptrstruct
xor eax, eax
mov ax, word ptr[ebx+2] ; EndValue
mov cx, word ptr[ebx+4] ; TimeAngle
or cx, cx ; TimeAngle Reach = 0
jz elapsed
mov edx, [TimerRef]
sub edx, [ebx+6] ; memoticks
cmp dx, cx ; if step >= nbstep
jae sao2 ; poke EndValue
; nb step = time to come here
sub ax, word ptr[ebx+0] ; start value
cmp ax, -512
jl short art1
cmp ax, 512
jle short ok
art0: sub ax, 2048
art1: add ax, 1024
ok:
imul dx ; resul DX:AX
idiv cx ; / NbStep
add ax, word ptr[ebx+0] ; start value
ret
sao2: mov word ptr[ebx+4], 0 ; TimeValue reset
elapsed: ; return EndValue
ret
GetRealAngle endp
comment @
GetRealAngle proc uses esi ebx ebp,\
ptrstruct:DWORD
mov esi, ptrstruct
mov dx, word ptr[esi+4] ; TimeAngle
or dx, dx ; TimeAngle Reach = 0
jz elapsed
mov ecx, [esi+6] ; memoticks
mov eax, [TimerRef]
sub eax, ecx
cmp ax, dx ; if step >= nbstep
jae sao2 ; poke EndValue
mov bx, dx ; nb step = time to come here
mov bp, ax ; step en cours
mov ax, word ptr[esi+2] ; EndValue
and ax, 1023
mov cx, word ptr[esi+0] ; start value
and cx, 1023
mov dx, ax
sub ax, cx
cmp ax, 512
jg art0
cmp ax,-512
jl art1
imul bp ; resul DX:AX
idiv bx ; bx ; /NbStep
add ax, cx ; cx = Valeur1
movzx eax, ax
ret
art0: add cx, 1024
sub dx, cx
mov ax, dx
imul bp ; resul DX:AX
idiv bx ; bx ; /NbStep
add ax, cx ; cx = Valeur1
movzx eax, ax
ret
art1: add dx, 1024
sub dx, cx
mov ax, dx
imul bp ; resul DX:AX
idiv bx ; bx ; /NbStep
add ax, cx ; cx = Valeur1
movzx eax, ax
ret
sao2: mov word ptr[esi+4], 0 ; TimeValue reset
elapsed: movsx eax, word ptr[esi+2] ; EndValue
ret
GetRealAngle endp
@
;*──────────────────────────────────────────────────────────────────────────*
comment #
StopRealValue proc uses ds si,\
value:WORD, ptrstruct:PTR
lds si,ptrstruct
mov bx,ss:word ptr[FlagFlip] ; Cmpt 60 hz
mov ax,value
cmp word ptr[si+0],ax ; start value
jz srv0
mov word ptr[si+0],ax ; start value
mov cx,word ptr[si+6] ; memoticks
mov ax,word ptr[si+4] ; time value
sub bx,cx
sub ax,bx
mov word ptr[si+4],ax ; new time value
srv0: mov word ptr[si+6],bx ; new memoticks
ret
StopRealValue endp
#
;*══════════════════════════════════════════════════════════════════════════*
; █▀▀▀█ █▀▀▀▀ █▀▀▀▀ █ █▀▀▀▀ ▀▀▀██
; ██▀█▀ ██▀▀ ██ ▀█ ██ ██▀▀ ▀▀▀██
; ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀
;*══════════════════════════════════════════════════════════════════════════*
;*──────────────────────────────────────────────────────────────────────────*
BoundRegleTrois proc \
Valeur1:DWORD, Valeur2:DWORD, \
NbStep:DWORD, Step:DWORD
mov eax, Valeur2
mov ecx, Valeur1
mov edx, Step
or edx, edx
jle troppetit
cmp edx, NbStep
jge tropgrand
sub eax, ecx ; delta valeurs
imul edx ; * Step
idiv NbStep ; /NbStep
add eax, ecx ; + Valeur1
tropgrand: ret
troppetit: mov eax, ecx
ret
BoundRegleTrois endp
comment @
BoundRegleTrois proc uses ebx ,\
Valeur1:DWORD, Valeur2:DWORD ,\
NbStep:DWORD, Step:DWORD
mov eax, Valeur2
mov ecx, Valeur1
mov ebx, NbStep
mov edx, Step
or edx, edx
jle troppetit
cmp edx, ebx
jge tropgrand
sub eax, ecx ; delta valeurs
imul edx ; * Step
idiv ebx ; /NbStep
add eax, ecx ; + Valeur1
tropgrand: ret
troppetit: mov eax, ecx
ret
BoundRegleTrois endp
@
RegleTrois32 proc \
Valeur1:DWORD, Valeur2:DWORD, \
NbStep:DWORD, Step:DWORD
mov eax, Valeur2
mov ecx, NbStep
or ecx, ecx ; essai global 8-o
jle short erreur
sub eax, Valeur1
imul Step ; resul DX:AX
idiv ecx ; /NbStep
add eax, Valeur1 ; cx = Valeur1
erreur: ret
RegleTrois32 endp
comment @
RegleTrois32 proc uses ebx ,\
Valeur1:DWORD, Valeur2:DWORD ,\
NbStep:DWORD, Step:DWORD
mov eax, Valeur2
mov ecx, Valeur1
sub eax, ecx
imul Step ; resul DX:AX
mov ebx, NbStep
; dec ebx
or ebx, ebx ; essai global 8-o
jle erreur
idiv ebx ; /NbStep
add eax, ecx ; cx = Valeur1
ret
erreur: mov eax, ecx
ret
RegleTrois32 endp
@
comment #
RegleTrois proc \
Valeur1:WORD, Valeur2:WORD ,\
NbStep:WORD, Step:WORD
mov ax, Valeur2
mov cx, Valeur1
sub ax, cx
imul Step ; resul DX:AX
mov bx, NbStep
dec bx
jbe erreur
idiv bx ; /NbStep
add ax, cx ; cx = Valeur1
ret
erreur: xor ax, ax
ret
RegleTrois endp
#
;*══════════════════════════════════════════════════════════════════════════*
; ██▀▀▀ █▀▀▀█ █▀▀▀█
; ▀▀▀▀█ ██ ▄█ ██▀█▀
; ▀▀▀▀▀ ▀▀▀▀ ▀▀ ▀
;*══════════════════════════════════════════════════════════════════════════*
;*──────────────────────────────────────────────────────────────────────────*
;*══════════════════════════════════════════════════════════════════════════*
; EAX = Sqr(EAX)
Sqr PROC NEAR USES EBX
cmp eax, 3
jbe short asqr_0_1
xor edx, edx
mov ebx, eax
bsr eax, ebx ; cherche dernier bit à 1
mov cl, 33
sub cl, al
and cl, -2 ; calcul de combien decaler
; à gauche pour avoir le
; premier doublet non nul
; dans edx
shld edx, ebx, cl
shl ebx, cl
mov ecx, eax ; doublets restants
shr ecx, 1
mov eax, 1
dec edx
asqr_loop: shld edx, ebx, 2
shl ebx, 2
shl eax, 2
cmp edx, eax
jc short asqr_neg
inc eax
sub edx, eax
jnc short asqr_1
add edx, eax
asqr_neg: shr eax, 1
dec ecx
jnz short asqr_loop
ret
asqr_1: inc eax
shr eax, 1
dec ecx
jnz short asqr_loop
ret
asqr_0_1: or eax, eax
jz short asqr_00
mov eax, 1
asqr_00: ret
Sqr ENDP
comment @
;*══════════════════════════════════════════════════════════════════════════*
; EAX = Sqr(EAX)
Sqr proc near
cmp eax, 3
jbe short asqr_0_1
mov esi, eax
mov eax, 1
xor edx, edx
bsr ebx, esi ; cherche dernier bit à 1
mov cx, 33
sub cx, bx
and cx, -2 ; calcul de combien decaler
; à gauche pour avoir le
; premier doublet non nul
; dans edx
shld edx, esi, cl
shl esi, cl
mov ecx, ebx ; doublets restants
shr ecx, 1
inc cx
dec edx
dec ecx
jnz short asqr_loop
ret
asqr_loop: shld edx, esi, 2
shl esi, 2
shl eax, 1
mov ebx, edx
shr ebx, 1
sub ebx, eax
jc short asqr_neg
mov ebx, eax
stc
rcl ebx, 1
sub edx, ebx
jc short asqr_0
inc eax
dec ecx
jnz short asqr_loop
ret
asqr_0: add edx, ebx
asqr_neg: dec ecx
jnz short asqr_loop
ret
asqr_0_1: or eax, eax
jnz asqr_1
ret
asqr_1: mov eax, 1
ret
Sqr endp
@
comment @
;*══════════════════════════════════════════════════════════════════════════*
; AX = Sqr(DX:AX)
Sqr proc near
xor cx,cx
test dx,dx
jne sq1
test ax,ax
je is0
xchg ax,dx
mov cx,8
sq1:
test dh,dh
jne sq2
xchg dh,dl
xchg dl,ah
xchg ah,al
add cx,4
sq2:
test dh,0f0h
jne sq3
; shld dx, ax, 4
; shl ax, 4
shl ax, 1
rcl dx, 1
shl ax, 1
rcl dx, 1
shl ax, 1
rcl dx, 1
shl ax, 1
rcl dx, 1
add cx,2
sq3:
test dh,0c0h
jne sq4
; shld dx, ax, 2
; shl ax, 2
shl ax, 1
rcl dx, 1
shl ax, 1
rcl dx, 1
inc cx
sq4:
mov bl,dh
xor bh,bh
shl bx,1
mov bx,[ SqrTab + bx-64*2 ]
cmp dx,bx
jae sq5
div bx
add ax,bx
rcr ax,1
shr ax,cl
is0:
ret
sq5:
mov ax,dx
stc
rcr ax,1
shr ax,cl
ret
Sqr endp
@
;*══════════════════════════════════════════════════════════════════════════*
; █▀▀▀▄ █ ██▀▀▀ ▀▀█▀▀ █▀▀▀█ ██▄ █ █▀▀▀▀ █▀▀▀▀
; ██ █ ██ ▀▀▀▀█ ██ ██▀▀█ ██▀██ ██ ██▀▀
; ▀▀▀▀ ▀▀ ▀▀▀▀▀ ▀▀ ▀▀ ▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀
;*══════════════════════════════════════════════════════════════════════════*
;*──────────────────────────────────────────────────────────────────────────*
;*══════════════════════════════════════════════════════════════════════════*
Distance2D proc \
px0:DWORD,py0:DWORD, px1:DWORD,py1:DWORD
mov eax, px1
sub eax, px0 ; Dx = x1-x0
imul eax, eax ; Dx²
mov ecx, py1
sub ecx, py0 ; Dy = y1-y0
imul ecx, ecx ; Dy²
add eax, ecx ; Dx² + Dy²
call Sqr ; eax = √ (Dx²+Dy²)
ret
Distance2D endp
comment @
Distance2D proc uses ebx,\
px0:DWORD,py0:DWORD, px1:DWORD,py1:DWORD
mov eax, px1
sub eax, px0 ; Dx = x1-x0
imul eax, eax ; Dx²
mov ebx, py1
sub ebx, py0 ; Dy = y1-y0
imul ebx, ebx ; Dy²
add eax, ebx ; Dx² + Dy²
call Sqr ; eax = √ (Dx²+Dy²)
ret
Distance2D endp
@
;*══════════════════════════════════════════════════════════════════════════*
Distance3D proc \
px0:DWORD,py0:DWORD,pz0:DWORD, px1:DWORD,py1:DWORD,pz1:DWORD
mov eax, px1
sub eax, px0
imul eax, eax ; Dx²
mov ecx, py1
sub ecx, py0
imul ecx, ecx ; Dy²
add eax, ecx
mov ecx, pz1
sub ecx, pz0
imul ecx, ecx ; Dz²
add eax, ecx
call Sqr ; eax = √ (Dx²+Dy²+Dz²)
ret
Distance3D endp
comment @
Distance3D proc uses ebx,\
px0:DWORD,py0:DWORD,pz0:DWORD, px1:DWORD,py1:DWORD,pz1:DWORD
mov eax, px1
sub eax, px0
imul eax, eax ; Dx²
mov ebx, py1
sub ebx, py0
imul ebx, ebx ; Dy²
add eax, ebx
mov ebx, pz1
sub ebx, pz0
imul ebx, ebx ; Dz²
add eax, ebx
call Sqr ; eax = √ (Dx²+Dy²+Dz²)
ret
Distance3D endp
@
;*══════════════════════════════════════════════════════════════════════════*
; ▀▀█▀▀ █▀▀▀█ █ █▀▀▀▀ █▀▀▀█
; ██ ██▀█▀ ██ ██ ▀█ ██ █
; ▀▀ ▀▀ ▀ ▀▀ ▀▀▀▀▀ ▀▀▀▀▀
;*══════════════════════════════════════════════════════════════════════════*
;*──────────────────────────────────────────────────────────────────────────*
;*══════════════════════════════════════════════════════════════════════════*
GetAngle proc uses esi edi ebx ebp,\
x0:DWORD, z0:DWORD, x1:DWORD, z1:DWORD
mov edx, z1
sub edx, z0 ; z = z1 - z0
mov edi, edx ; save z
mov eax, x1
sub eax, x0 ; x = x1 - x0
mov ebp, eax ; save x
imul eax, eax ; x²
imul edx, edx ; z²
cmp eax, edx
jae noswap
xchg ebp, edi ; permute x z
or ebp, 1
jmp short carre
noswap:
and ebp, -2
carre:
add eax, edx ; eax = x² + z²
call Sqr ; eax = sqr(x² + z²)
mov [Distance], eax
or eax, eax ; si longueur 0 alors angle 0
jz fgetangle
xchg eax, edi
sal eax, 14
cdq
idiv edi
mov esi, offset P_SinTab + 384 * 2
lea edi, [esi+256*2]
ga2: mov ebx, esi
add ebx, edi
shr ebx, 1
cmp ax, [ebx]
jle ga0
mov edi, ebx
jmp short ga1
ga0: mov esi, ebx
je short fgaloop
mov ebx, edi
ga1: sub ebx, esi
dec ebx
jnz short ga2
movsx ebx, word ptr [esi]
movsx edx, word ptr [edi]
add ebx, edx
sar ebx, 1
cmp bx, ax
jg short fgaloop
mov esi, edi
fgaloop: sub esi, offset P_SinTab + 256 * 2
mov eax, esi
shr eax, 1
or ebp, ebp
jns short fga
neg eax
fga:
test ebp, 1
jz short norestore
neg eax
add eax, 256
norestore:
and eax, 1023
fgetangle:
ret
GetAngle endp
comment @
GetAngle proc uses esi edi ebx ebp,\
x0:DWORD, z0:DWORD, x1:DWORD, z1:DWORD
mov edx, z1
sub edx, z0 ; z = z1 - z0
mov edi, edx ; save z
jns nonegedx ; abs(z)
neg edx
nonegedx:
mov eax, x1
sub eax, x0 ; x = x1 - x0
mov ebp, eax ; save x
jns nonegeax ; abs(x)
neg eax
nonegeax:
cmp eax, edx
jae noswap
xchg eax, edx ; permute x z
xchg ebp, edi
or ebp, 1
jmp short carre
noswap:
and ebp, -2
carre:
imul eax, eax
imul edx, edx
add eax, edx ; eax = x² + z²
call Sqr
mov [Distance], eax
or eax, eax ; si longueur 0 alors angle 0
jz fgetangle
xchg eax, edi
sal eax, 14
cdq
idiv edi
mov esi, offset P_SinTab + 384 * 2
mov edi, esi
add edi, 256 * 2
ga2: mov ebx, esi
add ebx, edi
shr ebx, 1
cmp ax, [ebx]
jle ga0
mov edi, ebx
jmp short ga1
ga0: mov esi, ebx
je fgaloop
mov ebx, edi
ga1: sub ebx, esi
dec ebx
jnz ga2
movsx ebx, word ptr [esi]
movsx edx, word ptr [edi]
add ebx, edx
sar ebx, 1
cmp bx, ax
jg fgaloop
mov esi, edi
fgaloop: sub esi, offset P_SinTab + 256 * 2
mov eax, esi
shr eax, 1
or ebp, ebp
jns fga
neg eax
fga:
test ebp, 1
jz norestore
mov ebx, eax
mov eax, 256
sub eax, ebx
norestore:
and eax, 1023
fgetangle:
ret
GetAngle endp
@
comment @
;*══════════════════════════════════════════════════════════════════════════*
; Rotation 2D autour d'un axe
; entrée: eax=X ecx=Y edx=T
;
; sortie: eax = X'=X*cos(T)-Y*sin(T)
; ecx = Y'=X*sin(T)+Y*cos(T)
;
; ( ebx, ebp, edi détruits )
;*══════════════════════════════════════════════════════════════════════════*
RotEXY proc
or edx, edx
jz short norot
and edx, 03FFh
movsx ebx, word ptr[P_SinTab + edx*2] ; ebx = Sin( T )
add dx, 256
and dx, 03FFh
movsx edx, word ptr[P_SinTab + edx*2] ; edx = Cos( T )
mov ebp, eax ; ebp = X
mov edi, ecx ; edi = Y
imul eax, edx ; X*cos(T)
imul edi, ebx ; Y*sin(T)
sub eax, edi
sar eax, 15 ; eax = X' = X*cos(T)-Y*sin(T)
imul ecx, edx ; Y*cos(T)
imul ebp, ebx ; X*sin(T)
add ecx, ebp
sar ecx, 15 ; ecx = Y' = X*sin(T) + Y*cos(T)
norot: ret
RotEXY endp
;*══════════════════════════════════════════════════════════════════════════*
; Rotation 2D autour d'un axe
; entrée: ebx=X ecx=Y ebp=T
;
; sortie: eax = X'=X*cos(T)-Y*sin(T)
; edx = Y'=X*sin(T)+Y*cos(T)
;
; ( ebx, ebp, edi détruits )
;*══════════════════════════════════════════════════════════════════════════*
RotEXY proc
or ebp, ebp
jz norot
mov eax, ebp ; T
and eax, 03FFh
mov edi, offset P_SinTab
movsx ebp, word ptr[ edi+eax*2 ] ; ebp = Sin( T )
add eax, 256
and eax, 03FFh
movsx edx, word ptr[ edi+eax*2 ] ; edx = Cos( T )
; X*cos(T)
mov eax, ebx
imul eax, edx
mov edi, eax
; Y*sin(T)
mov eax, ecx
imul eax, ebp
sub edi, eax
sar edi, 15 ; di= X'= X*cos(T)-Y*sin(T)
; Y*cos(T)
imul edx, ecx
; X*sin(T)
imul ebx, ebp
add edx, ebx ; Y' = X*sin(T) + Y*cos(T)
sar edx, 15 ; edx = Y'
mov eax, edi ; eax = X'
xor ecx, ecx
ret
norot: mov eax, ebx ; ax = X' = X
mov edx, ecx ; dx = Y' = Y
ret
RotEXY endp
@
;*══════════════════════════════════════════════════════════════════════════*
Rot2D proc uses ebx,\
coorx:DWORD,coory:DWORD,angle:DWORD
mov edx, angle
mov eax, coorx
mov ecx, coory
or edx, edx
jz short norot
and edx, 03FFh
movsx ebx, word ptr[P_SinTab + edx*2] ; ebx = Sin( T )
add dx, 256
and dx, 03FFh
movsx edx, word ptr[P_SinTab + edx*2] ; edx = Cos( T )
imul eax, edx ; X*cos(T)
imul ecx, ebx ; Y*sin(T)
sub eax, ecx
sar eax, 15 ; eax = X' = X*cos(T)-Y*sin(T)
mov [EX0], eax
imul edx, coory ; Y*cos(T)
imul ebx, coorx ; X*sin(T)
add edx, ebx
sar edx, 15 ; edx = Y' = X*sin(T) + Y*cos(T)
mov [EY0], edx
ret
norot: mov [EX0], eax
mov [EY0], ecx
ret
Rot2D endp
comment @
Rot2D proc uses ebx ebp edi,\
coorx:DWORD,coory:DWORD,angle:DWORD
mov eax, coorx
mov ecx, coory
mov edx, angle
call RotEXY
mov [EX0], eax
mov [EY0], ecx
ret
Rot2D endp
@
;*══════════════════════════════════════════════════════════════════════════*
END