Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1137 lines
36 KiB

page ,132
;------------------------------Module-Header----------------------------;
; Module Name: xform.asm ;
; ;
; The assembly version of xformer.cxx. Contains the transform related ;
; calculation routines. This is the NT version of ChuckWh's ;
; xformers.asm for PM. ;
; ;
; Created: 13-Nov-1990 13:42:27 ;
; Author: Wendy Wu [wendywu] ;
; ;
; Copyright (c) 1990 Microsoft Corporation ;
;-----------------------------------------------------------------------;
.386
.model small,c
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
assume fs:nothing,gs:nothing
.xlist
include callconv.inc
include gdii386.inc
.list
.code
EXTRNP mulff,0
EXTRNP addff,0
;-----------------------------------------------------------------------;
; MULEFBYDWORD
;
; Multiply an EFLOAT number by a 32-bit number. The result is kept in
; the FIX type. If the 32-bit number is a LONG integer, the EFLOAT is
; a "FIX number in EFLOAT type". If the 32-bit is a FIX number, the
; EFLOAT is a "LONG integer in EFLOAT type". Note that this macro can
; be invoked with eax and edx exchanged with the same result.
;
; Entry:
; EDX = LONG integer or EDX = FIX number
; EAX = EFLOAT.lMant EAX = EFLOAT.lMant
; ECX = EFLOAT.lExp(already added by 4) ECX = EFLOAT.lExp
; Returns:
; EAX = product in FIX type
;
; Registers Destroyed:
; ECX,EDX
;-----------------------------------------------------------------------;
; CR!!! If we can have a tight loop to check for overflow before we
; CR!!! do the conversion, it might be faster. Not sure which way to
; CR!!! go. Will have to decide at performance tuning time.
MULEFBYDWORD MACRO err_out
LOCAL shift31orfewer
LOCAL done
neg ecx
imul edx ; EDX.EAX
add ecx,32 ; If we shift EDX.EAX right by 32-exp
; then we get the final result in EAX
jz short done ; no shift, we're done.
jc short shift31orfewer
js err_out ; overflow if 32-exp < 0
; we are here if ecx >= 32. return 0 if ecx > 62.
cmp ecx,63
jb @F
xor eax,eax ; shift by too much, result will be zero
jmp short done
@@:
shrd eax, edx, 31
sar edx, 31
sub ecx, 31
shift31orfewer:
shrd eax,edx,cl ; shift edx:eax right by cl bits
adc eax, 0 ; and round appropriately
jo err_out ; overflow?
sar edx,cl ; check for overflow
adc edx,0
jnz err_out
done:
ENDM
;-----------------------------Public-Routine----------------------------;
; lCvt (ef,ll) ;
; ;
; A simple routine to scale a long by an EFLOAT. ;
; ;
; Arguments: ;
; ;
; EFLOAT ef The floating point multiplier. ;
; LONG ll The long to multiply. ;
; ;
; Entry: ;
; None ;
; Returns: ;
; EAX = product ;
; Error Returns: ;
; None. ;
; Registers Destroyed: ;
; ECX,EDX ;
; Calls: ;
; None ;
; History: ;
; Wed 26-May-1993 00:00:00 -by- Paul Butzi and Charles Whitmer
; changed to call MULEFBYDWORD, which we recently fixed
;
; Wed 18-Mar-1992 07:31:13 -by- Charles Whitmer [chuckwh] ;
; Added the simple shifting case. I think we can call this case faster ;
; than we could recognize in C that a shift is required. ;
; ;
; Thu 12-Mar-1992 20:35:03 -by- Charles Whitmer [chuckwh] ;
; Created by pirating MULEFBYDWORD. ;
;-----------------------------------------------------------------------;
lCvt_frame struc
pRet dd ? ; Return address
ef db size EFLOAT dup (?) ; EFLOAT multiplier
ll dd ? ; LONG multiplier
lCvt_frame ends
cvtargs equ (size lCvt_frame / 4 - 1)
cPublicProc lCvt,cvtargs
mov eax,dword ptr [esp].ef.ef_lMant
mov ecx,dword ptr [esp].ef.ef_lExp
mov edx, dword ptr [esp].ll
MULEFBYDWORD lCvtNext
lCvtNext:
stdRET lCvt
stdENDP lCvt
;-----------------------------Public-Routine----------------------------;
; bCvtPts1
;
; Apply the given transform matrix to a list of points.
;
; Arguments:
; pmx points to the matrix
; pptl points to the list of points
; cptl number of points in the list
;
; Entry:
; None
; Returns:
; EAX = 1
; Error Returns:
; EAX = 0
; Registers Destroyed:
; ECX,EDX
; Calls:
; None
; History:
; 17-Dec-1992 -by- Wendy Wu [wendywu]
; Created.
;-----------------------------------------------------------------------;
cPublicProc bCvtPts1,3,< \
uses ebx esi edi, \
pmx: ptr MATRIX, \
pptl: ptr POINTL, \
cptl: dword >
local fxResult:dword
mov esi,pptl
mov ebx,pmx
mov ecx,[ebx].mx_flAccel
and ecx,XFORM_SCALE+XFORM_UNITY+XFORM_FORMAT_LTOFX
jmp accelerator_table_pts1[ecx*4]
.errnz (size POINTL) - 8
xform_non_units_ltofx_pts1::
mov edi,cptl
; ESI = points to the source array of points
; EDI = number of points in the array
; EBX = points to the matrix
align 4
xform_non_units_ltofx_loop_pts1:
; compute x'
mov edx,[esi].ptl_x ; get source x
mov ecx,[ebx].mx_efM11.ef_lExp
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow_pts1 ; x*M11
add eax,[ebx].mx_fxDx ; x*M11+Dx
add eax,8 ; FXTOLROUND
sar eax,4
; compute y'
mov edx,[esi].ptl_y ; get source y
mov [esi].ptl_x,eax ; store x'
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow_pts1 ; y*M22
add eax,[ebx].mx_fxDy ; y*M22+Dy
add eax,8 ; FXTOLROUND
sar eax,4
mov [esi].ptl_y,eax ; store y'
add esi,SIZE POINTL
dec edi
jnz xform_non_units_lTofx_loop_pts1
mov eax,1
stdRET bCvtPts1
align 4
xform_units_ltofx_pts1::
mov eax,[ebx].mx_fxDx
mov edx,[ebx].mx_fxDy
add eax,8 ; FXTOLROUND
add edx,8
sar eax,4
sar edx,4
mov ecx,cptl
; ESI = points to the array of points
; ECX = number of points in the array
; EAX = x translation
; EDX = y translation
align 4
xform_units_ltofx_loop_pts1:
add [esi].ptl_x,eax ; x' = x + Dx
add [esi].ptl_y,edx ; y' = y + Dy
add esi,SIZE POINTL
dec ecx
jnz short xform_units_ltofx_loop_pts1
mov eax,1
stdRET bCvtPts1
xform_general_ltofx_pts1::
mov edi,cptl
; ESI = points to the source array of points
; EDI = number of points in the array
; EBX = points to the matrix
xform_general_ltofx_loop_pts1:
; compute x'
mov edx,[esi].ptl_x ; get source x
mov ecx,[ebx].mx_efM11.ef_lExp
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow_pts1 ; x * M11
mov fxResult,eax
mov edx,[esi].ptl_y ; get source y
mov ecx,[ebx].mx_efM21.ef_lExp
mov eax,[ebx].mx_efM21.ef_lMant
MULEFBYDWORD overflow_pts1 ; y*M21
add eax,fxResult ; x*M11 + y*M21
add eax,[ebx].mx_fxDx ; x*M11 + y*M21 + Dx
add eax,8 ; FXTOLROUND
sar eax,4
; compute y'
mov edx,[esi].ptl_x ; get source x
mov [esi].ptl_x,eax ; store x'
mov ecx,[ebx].mx_efM12.ef_lExp
mov eax,[ebx].mx_efM12.ef_lMant
MULEFBYDWORD overflow_pts1 ; x * M12
mov fxResult,eax
mov edx,[esi].ptl_y ; get source y
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow_pts1 ; y * M22
add eax,fxResult ; x*M12 + y*M22
add eax,[ebx].mx_fxDy ; x*M12 + y*M22 + Dy
add eax,8 ; FXTOLROUND
sar eax,4
mov [esi].ptl_y,eax ; store y'
add esi,SIZE POINTL
dec edi
jnz xform_general_ltofx_loop_pts1
mov eax,1
stdRET bCvtPts1
xform_non_units_fxtol_pts1::
mov edi,cptl
; ESI = points to the source array of points
; EDI = number of points in the array
; EBX = points to the matrix
align 4
xform_non_units_fxtol_loop_pts1:
; compute x'
mov edx,[esi].ptl_x ; get source x
mov ecx,[ebx].mx_efM11.ef_lExp
sal edx,4 ; LTOFX
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow_pts1 ; x*M11
add eax,[ebx].mx_fxDx ; x*M11+Dx
; compute y'
mov edx,[esi].ptl_y ; get source y
mov [esi].ptl_x,eax ; store x'
sal edx,4 ; LTOFX
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow_pts1 ; y*M22
add eax,[ebx].mx_fxDy ; y*M22+Dy
mov [esi].ptl_y,eax ; store y'
add esi,SIZE POINTL
dec edi
jnz xform_non_units_fxtol_loop_pts1
mov eax,1
stdRET bCvtPts1
align 4
xform_units_fxtol_pts1::
mov eax,[ebx].mx_fxDx
mov edx,[ebx].mx_fxDy
mov ecx,cptl
; ESI = points to the array of points
; ECX = number of points in the array
; EAX = x translation
; EDX = y translation
align 4
xform_units_fxtol_loop_pts1:
add [esi].ptl_x,eax ; x' = x + Dx
add [esi].ptl_y,edx ; y' = y + Dy
add esi,SIZE POINTL
dec ecx
jnz short xform_units_fxtol_loop_pts1
mov eax,1
stdRET bCvtPts1
xform_general_fxtol_pts1::
mov edi,cptl
; ESI = points to the source array of points
; EDI = number of points in the array
; EBX = points to the matrix
xform_general_fxtol_loop_pts1:
; compute x'
mov edx,[esi].ptl_x ; get source x
mov ecx,[ebx].mx_efM11.ef_lExp
sal edx,4 ; LTOFX
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow_pts1 ; x * M11
mov fxResult,eax
mov edx,[esi].ptl_y ; get source y
mov ecx,[ebx].mx_efM21.ef_lExp
sal edx,4 ; LTOFX
mov eax,[ebx].mx_efM21.ef_lMant
MULEFBYDWORD overflow_pts1 ; y*M21
add eax,fxResult ; x*M11 + y*M21
add eax,[ebx].mx_fxDx ; x*M11 + y*M21 + Dx
; compute y'
mov edx,[esi].ptl_x ; get source x
mov [esi].ptl_x,eax ; store x'
sal edx,4 ; LTOFX
mov ecx,[ebx].mx_efM12.ef_lExp
mov eax,[ebx].mx_efM12.ef_lMant
MULEFBYDWORD overflow_pts1 ; x * M12
mov fxResult,eax
mov edx,[esi].ptl_y ; get source y
mov ecx,[ebx].mx_efM22.ef_lExp
sal edx,4 ; LTOFX
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow_pts1 ; y * M22
add eax,fxResult ; x*M12 + y*M22
add eax,[ebx].mx_fxDy ; x*M12 + y*M22 + Dy
mov [esi].ptl_y,eax ; store y'
add esi,SIZE POINTL
dec edi
jnz xform_general_fxtol_loop_pts1
mov eax,1
stdRET bCvtPts1
overflow_pts1:
xor eax,eax
stdRET bCvtPts1
ifdef DOS_PLATFORM
.errnz XFORM_SCALE - 1
.errnz XFORM_UNITY - 2
.errnz XFORM_Y_NEG - 4
.errnz XFORM_FORMAT_LTOFX - 8
accelerator_table_pts1 label dword ; ltofx -y units scale
dd offset FLAT:xform_general_fxtol_pts1 ; 0 0 0 0
dd offset FLAT:xform_non_units_fxtol_pts1 ; 0 0 0 1
dd offset FLAT:xform_rip_pts ; 0 0 1 0
dd offset FLAT:xform_units_fxtol_pts1 ; 0 0 1 1
dd offset FLAT:xform_rip_pts ; 0 0 0 0
dd offset FLAT:xform_rip_pts ; 0 0 0 1
dd offset FLAT:xform_rip_pts ; 0 0 1 0
dd offset FLAT:xform_rip_pts ; 0 0 1 1
dd offset FLAT:xform_general_ltofx_pts1 ; 1 0 0 0
dd offset FLAT:xform_non_units_ltofx_pts1 ; 1 0 0 1
dd offset FLAT:xform_rip_pts ; 1 0 1 0
dd offset FLAT:xform_units_ltofx_pts1 ; 1 0 1 1
dd offset FLAT:xform_rip_pts ; 1 1 0 0
dd offset FLAT:xform_rip_pts ; 1 1 0 1
dd offset FLAT:xform_rip_pts ; 1 1 1 0
dd offset FLAT:xform_rip_pts ; 1 1 1 1
endif; DOS_PLATFORM
stdENDP bCvtPts1
ifndef DOS_PLATFORM
.errnz XFORM_SCALE - 1
.errnz XFORM_UNITY - 2
.errnz XFORM_Y_NEG - 4
.errnz XFORM_FORMAT_LTOFX - 8
accelerator_table_pts label dword ; ltofx -y units scale
dd xform_general_pts ; 0 0 0 0
dd xform_non_units_pts ; 0 0 0 1
dd xform_rip_pts ; 0 0 1 0
dd xform_units_fxtol_pts ; 0 0 1 1
dd xform_rip_pts ; 0 1 0 0
dd xform_rip_pts ; 0 1 0 1
dd xform_rip_pts ; 0 1 1 0
dd xform_units_neg_y_fxtol_pts ; 0 1 1 1
dd xform_general_pts ; 1 0 0 0
dd xform_non_units_pts ; 1 0 0 1
dd xform_rip_pts ; 1 0 1 0
dd xform_units_ltofx_pts ; 1 0 1 1
dd xform_rip_pts ; 1 1 0 0
dd xform_rip_pts ; 1 1 0 1
dd xform_rip_pts ; 1 1 1 0
dd xform_units_neg_y_ltofx_pts ; 1 1 1 1
accelerator_table_pts1 label dword ; ltofx -y units scale
dd xform_general_fxtol_pts1 ; 0 x 0 0
dd xform_non_units_fxtol_pts1 ; 0 x 0 1
dd xform_rip_pts ; 0 x 1 0
dd xform_units_fxtol_pts1 ; 0 x 1 1
dd xform_rip_pts ; 0 x 0 0
dd xform_rip_pts ; 0 x 0 1
dd xform_rip_pts ; 0 x 1 0
dd xform_rip_pts ; 0 x 1 1
dd xform_general_ltofx_pts1 ; 1 x 0 0
dd xform_non_units_ltofx_pts1 ; 1 x 0 1
dd xform_rip_pts ; 1 x 1 0
dd xform_units_ltofx_pts1 ; 1 x 1 1
dd xform_rip_pts ; 1 x 0 0
dd xform_rip_pts ; 1 x 0 1
dd xform_rip_pts ; 1 x 1 0
dd xform_rip_pts ; 1 x 1 1
accelerator_table_vts label dword ; -y units scale
dd xform_general_vts ; 0 0 0
dd xform_non_units_vts ; 0 0 1
dd xform_rip_vts ; 0 1 0
dd xform_rip_vts ; 0 1 1 handled by caller
dd xform_rip_vts ; 1 0 0
dd xform_rip_vts ; 1 0 1
dd xform_rip_vts ; 1 1 0
dd xform_units_neg_y_ltofx_vts ; 1 1 1
endif; DOS_PLATFORM
;-----------------------------Public-Routine----------------------------;
; bCvtPts
;
; Apply the given transform matrix to a list of points.
;
; Arguments:
; pmx points to the matrix
; pptlSrc points to the source list of points
; pptlDst points to the dest list of points
; cptl number of points in the list
; pptlSrc, pptlDst can both point to the same array of points
;
; Entry:
; None
; Returns:
; EAX = 1
; Error Returns:
; EAX = 0
; Registers Destroyed:
; ECX,EDX
; Calls:
; None
; History:
; 13-Nov-1990 -by- Wendy Wu [wendywu]
; Created.
;-----------------------------------------------------------------------;
cPublicProc bCvtPts,4,< \
uses ebx esi edi, \
pmx: ptr MATRIX, \
pptlSrc: ptr POINTL, \
pptlDst: ptr POINTL, \
cptl: dword >
local fxResult :dword
mov esi,pptlSrc
mov edi,pptlDst
mov ebx,pmx
mov ecx,[ebx].mx_flAccel
and ecx,XFORM_SCALE+XFORM_UNITY+XFORM_Y_NEG+XFORM_FORMAT_LTOFX
jmp accelerator_table_pts[ecx*4]
.errnz (size POINTL) - 8
align 4
xform_non_units_pts::
; ESI = points to the source array of points
; EDI = points to the destination array of points
; EBX = points to the matrix
align 4
xform_non_units_loop_pts:
; compute x'
mov edx,[esi] ; get source x
add esi,4
mov ecx,[ebx].mx_efM11.ef_lExp
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow_pts ; x*M11
add eax,[ebx].mx_fxDx ; x*M11+Dx
mov [edi],eax ; store x'
add edi,4
; compute y'
mov edx,[esi] ; get source y
add esi,4
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow_pts ; y*M22
add eax,[ebx].mx_fxDy ; y*M22+Dy
mov [edi],eax ; store y'
add edi,4
dec cptl
jnz xform_non_units_loop_pts
mov eax,1
stdRET bCvtPts
xform_rip_pts::
; should RIP here!!!
overflow_pts:
xor eax,eax
stdRET bCvtPts
align 4
xform_units_ltofx_pts::
mov ecx,cptl
mov edx,[ebx].mx_fxDy
mov ebx,[ebx].mx_fxDx
; ESI = points to the source array of points
; EDI = points to the destination array of points
; ECX = number of points in the array
; EBX = x translation
; EDX = y translation
align 4
xform_units_ltofx_loop_pts:
mov eax,[esi]
add esi,4
sal eax,4
add eax,ebx ; x' = x + Dx
mov [edi],eax ; store x'
add edi,4
mov eax,[esi]
add esi,4
sal eax,4
add eax,edx ; y' = y + Dy
mov [edi],eax ; store y'
add edi,4
dec ecx
jnz short xform_units_ltofx_loop_pts
mov eax,1
stdRET bCvtPts
align 4
xform_units_neg_y_ltofx_pts::
mov ecx,cptl
mov edx,[ebx].mx_fxDy
mov ebx,[ebx].mx_fxDx
; ESI = points to the source array of points
; EDI = points to the destination array of points
; ECX = number of points in the array
; EBX = x translation
; EDX = y translation
align 4
xform_units_neg_y_ltofx_loop_pts:
mov eax,[esi]
add esi,4
sal eax,4
add eax,ebx ; x' = x + Dx
mov [edi],eax ; store x'
add edi,4
mov eax,[esi]
add esi,4
sal eax,4
neg eax ; y' = -y + Dy
add eax,edx
mov [edi],eax ; store y'
add edi,4
dec ecx
jnz short xform_units_neg_y_ltofx_loop_pts
mov eax,1
stdRET bCvtPts
overflow1_pts:
jmp overflow_pts
align 4
xform_units_fxtol_pts::
mov ecx,cptl
mov edx,[ebx].mx_fxDy
mov ebx,[ebx].mx_fxDx
; ESI = points to the source array of points
; EDI = points to the destination array of points
; ECX = number of points in the array
; EBX = x translation
; EDX = y translation
align 4
xform_units_fxtol_loop_pts:
mov eax,[esi]
add esi,4
add eax,8 ; FXTOLROUND()
sar eax,4
add eax,ebx ; x' = x + Dx
mov [edi],eax ; store x'
add edi,4
mov eax,[esi]
add esi,4
add eax,8 ; FXTOLROUND()
sar eax,4
add eax,edx ; y' = y + Dy
mov [edi],eax ; store y'
add edi,4
dec ecx
jnz short xform_units_fxtol_loop_pts
mov eax,1
stdRET bCvtPts
align 4
xform_units_neg_y_fxtol_pts::
mov ecx,cptl
mov edx,[ebx].mx_fxDy
mov ebx,[ebx].mx_fxDx
; ESI = points to the source array of points
; EDI = points to the destination array of points
; ECX = number of points in the array
; EBX = x translation
; EDX = y translation
align 4
xform_units_neg_y_fxtol_loop_pts:
mov eax,[esi]
add esi,4
add eax,8 ; FXTOLROUND()
sar eax,4
add eax,ebx ; x' = x + Dx
mov [edi],eax ; store x'
add edi,4
mov eax,[esi]
add esi,4
neg eax ; y' = -y
add eax,8 ; FXTOLROUND()
sar eax,4
add eax,edx ; y' = -y + Dy
mov [edi],eax ; store y'
add edi,4
dec ecx
jnz short xform_units_neg_y_fxtol_loop_pts
mov eax,1
stdRET bCvtPts
overflow2_pts:
jmp overflow_pts
xform_general_pts::
; ESI = points to the source array of points
; EDI = points to the dest array of points
; EBX = points to the matrix
xform_general_loop_pts:
; compute x'
mov edx,[esi].ptl_x ; get source x
mov ecx,[ebx].mx_efM11.ef_lExp
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow2_pts ; x * M11
mov fxResult,eax
mov edx,[esi].ptl_y ; get source y
mov ecx,[ebx].mx_efM21.ef_lExp
mov eax,[ebx].mx_efM21.ef_lMant
MULEFBYDWORD overflow2_pts ; y*M21
add eax,fxResult ; x*M11 + y*M21
add eax,[ebx].mx_fxDx ; x*M11 + y*M21 + Dx
; compute y'
mov edx,[esi].ptl_x ; get source x
mov [edi].ptl_x,eax ; store x'
mov ecx,[ebx].mx_efM12.ef_lExp
mov eax,[ebx].mx_efM12.ef_lMant
MULEFBYDWORD overflow3_pts ; x * M12
mov fxResult,eax
mov edx,[esi].ptl_y ; get source y
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow3_pts ; y * M22
add eax,fxResult ; x*M12 + y*M22
add eax,[ebx].mx_fxDy ; x*M12 + y*M22 + Dy
mov [edi].ptl_y,eax ; store y'
add esi,SIZE POINTL
add edi,SIZE POINTL
dec cptl
jnz xform_general_loop_pts
mov eax,1
stdRET bCvtPts
overflow3_pts:
jmp overflow_pts
ifdef DOS_PLATFORM
.errnz XFORM_SCALE - 1
.errnz XFORM_UNITY - 2
.errnz XFORM_Y_NEG - 4
.errnz XFORM_FORMAT_LTOFX - 8
accelerator_table_pts label dword ; ltofx -y units simple
dd offset FLAT:xform_general_pts ; 0 0 0 0
dd offset FLAT:xform_non_units_pts ; 0 0 0 1
dd offset FLAT:xform_rip_pts ; 0 0 1 0
dd offset FLAT:xform_units_fxtol_pts ; 0 0 1 1
dd offset FLAT:xform_rip_pts ; 0 1 0 0
dd offset FLAT:xform_rip_pts ; 0 1 0 1
dd offset FLAT:xform_rip_pts ; 0 1 1 0
dd offset FLAT:xform_units_neg_y_fxtol_pts ; 0 1 1 1
dd offset FLAT:xform_general_pts ; 1 0 0 0
dd offset FLAT:xform_non_units_pts ; 1 0 0 1
dd offset FLAT:xform_rip_pts ; 1 0 1 0
dd offset FLAT:xform_units_ltofx_pts ; 1 0 1 1
dd offset FLAT:xform_rip_pts ; 1 1 0 0
dd offset FLAT:xform_rip_pts ; 1 1 0 1
dd offset FLAT:xform_rip_pts ; 1 1 1 0
dd offset FLAT:xform_units_neg_y_ltofx_pts ; 1 1 1 1
endif; DOS_PLATFORM
stdENDP bCvtPts
;-----------------------------Public-Routine----------------------------;
; bCvtVts
;
; Apply the given transform matrix to a list of vectors.
;
; Arguments:
; pmx points to the matrix
; pvtlSrc points to the source list of vectors
; pvtlDst points to the dest list of vectors
; cvtl number of vectors in the list
; pvtlSrc, pvtlDst can both point to the same array of vectors
;
; Entry:
; None
; Returns:
; EAX = 1
; Error Returns:
; EAX = 0
; Registers Destroyed:
; ECX,EDX
; Calls:
; None
; History:
; 28-Jan-1992 -by- Wendy Wu [wendywu]
; Created.
;-----------------------------------------------------------------------;
cPublicProc bCvtVts,4,< \
uses ebx esi edi, \
pmx: ptr MATRIX, \
pvtlSrc: ptr VECTORL, \
pvtlDst: ptr VECTORL, \
cvtl: dword >
local fxResult :dword
mov esi,pvtlSrc
mov edi,pvtlDst
mov ebx,pmx
mov ecx,[ebx].mx_flAccel
and ecx,XFORM_SCALE+XFORM_UNITY+XFORM_Y_NEG
jmp accelerator_table_vts[ecx*4]
.errnz (size POINTL) - 8
align 4
xform_non_units_vts::
; ESI = points to the source array of vectors
; EDI = points to the destination array of vectors
; EBX = points to the matrix
xform_non_units_loop_vts:
mov edx,[esi] ; get source x
add esi,4
mov ecx,[ebx].mx_efM11.ef_lExp
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow_vts ; x*M11
mov [edi],eax ; store x'
add edi,4
mov edx,[esi] ; get source y
add esi,4
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow_vts ; y*M22
mov [edi],eax ; store y'
add edi,4
dec cvtl
jnz xform_non_units_loop_vts
mov eax,1
stdRET bCvtVts
xform_rip_vts::
; should RIP here!!!
overflow_vts:
xor eax,eax
stdRET bCvtVts
align 4
xform_units_neg_y_ltofx_vts::
mov ecx,cvtl
; ESI = points to the source array of vectors
; EDI = points to the destination array of vectors
; ECX = number of points in the array
align 4
xform_units_neg_y_ltofx_loop_vts:
mov eax,[esi]
add esi,4
sal eax,4
mov [edi],eax ; store x'
add edi,4
mov eax,[esi]
add esi,4
sal eax,4
neg eax ; y' = -y + Dy
mov [edi],eax ; store y'
add edi,4
dec ecx
jnz short xform_units_neg_y_ltofx_loop_vts
mov eax,1
stdRET bCvtVts
overflow1_vts:
jmp overflow_vts
xform_general_vts::
; ESI = points to the source array of vectors
; EDI = points to the dest array of vectors
; EBX = points to the matrix
xform_general_loop_vts:
; compute x'
mov edx,[esi].vl_x ; get source x
mov ecx,[ebx].mx_efM11.ef_lExp
mov eax,[ebx].mx_efM11.ef_lMant
MULEFBYDWORD overflow1_vts ; x * M11
mov fxResult,eax
mov edx,[esi].vl_y ; get source y
mov ecx,[ebx].mx_efM21.ef_lExp
mov eax,[ebx].mx_efM21.ef_lMant
MULEFBYDWORD overflow1_vts ; y*M21
add eax,fxResult ; x*M11 + y*M21
; compute y'
mov edx,[esi].vl_x ; get source x
mov [edi].vl_x,eax ; store x'
mov ecx,[ebx].mx_efM12.ef_lExp
mov eax,[ebx].mx_efM12.ef_lMant
MULEFBYDWORD overflow2_vts ; x * M12
mov fxResult,eax
mov edx,[esi].vl_y ; get source y
mov ecx,[ebx].mx_efM22.ef_lExp
mov eax,[ebx].mx_efM22.ef_lMant
MULEFBYDWORD overflow2_vts ; y * M22
add eax,fxResult ; x*M12 + y*M22
mov [edi].vl_y,eax ; store y'
add esi,SIZE VECTORL
add edi,SIZE VECTORL
dec cvtl
jnz xform_general_loop_vts
mov eax,1
stdRET bCvtVts
overflow2_vts:
jmp overflow_vts
ifdef DOS_PLATFORM
.errnz XFORM_SCALE - 1
.errnz XFORM_UNITY - 2
.errnz XFORM_Y_NEG - 4
accelerator_table_vts label dword ; -y units simple
dd offset FLAT:xform_general_vts ; 0 0 0
dd offset FLAT:xform_non_units_vts ; 0 0 1
dd offset FLAT:xform_rip_vts ; 0 1 0
dd offset FLAT:xform_rip_vts ; 0 1 1
dd offset FLAT:xform_rip_vts ; 1 0 0
dd offset FLAT:xform_rip_vts ; 1 0 1
dd offset FLAT:xform_rip_vts ; 1 1 0
dd offset FLAT:xform_units_neg_y_ltofx_vts ; 1 1 1
endif; DOS_PLATFORM
stdENDP bCvtVts
;-----------------------------Public-Routine----------------------------;
; bCvtVts_FlToFl
;
; Apply the given transform matrix to a list of vectors. The source
; and dest vectors are of VECTORFL types.
; The coefficients of the matrix are "LONG integers in EFLOAT type".
;
; Arguments:
; pmx points to the matrix
; pvtflSrc points to the source list of vectors
; pvtflDest points to the dest list of vectors
; cvtl number of vectors in the list
;
; ptflSrc, ptflDest can both point to the same array of vectors
;
; Entry:
; None
; Returns:
; EAX = 1
; Error Returns:
; EAX = 0
; Registers Destroyed:
; ECX,EDX
; Calls:
; mulff, addff
; History:
; 13-Nov-1990 -by- Wendy Wu [wendywu]
; Created.
;-----------------------------------------------------------------------;
cPublicProc bCvtVts_FlToFl,4,< \
uses ebx esi edi, \
pmx: ptr MATRIX, \
pvtflSrc: ptr VECTORFL, \
pvtflDest: ptr VECTORFL, \
cvtl: dword >
local lMantResult :dword
local lExpResult :dword
mov esi,pvtflSrc
mov edi,pmx
; ESI -> source array of vectors
; EDI -> matrix
convert_vectors_loop:
; compute x'
mov edx,[esi].vfl_x.ef_lMant ; get x
mov ebx,[esi].vfl_x.ef_lExp
mov eax,[edi].mx_efM11.ef_lMant
mov ecx,[edi].mx_efM11.ef_lExp
stdCall mulff ; x * M11
mov lMantResult,eax
mov lExpResult,ecx
mov edx,[esi].vfl_y.ef_lMant ; get y
mov ebx,[esi].vfl_y.ef_lExp
mov eax,[edi].mx_efM21.ef_lMant
mov ecx,[edi].mx_efM21.ef_lExp
stdCall mulff ; y * M21
mov edx,lMantResult
mov ebx,lExpResult
stdCall addff ; x*M11 + y*M21
; compute y'
mov ebx,pvtflDest ; get x before storing x'
mov edx,[esi].vfl_x.ef_lMant ; x.lMant
mov [ebx].vfl_x.ef_lMant,eax
mov eax,[esi].vfl_x.ef_lExp ; x.lExp
mov [ebx].vfl_x.ef_lExp,ecx
mov ebx,eax ; edx:ebx = x.lMant:x.lExp
mov eax,[edi].mx_efM12.ef_lMant
mov ecx,[edi].mx_efM12.ef_lExp
stdCall mulff ; x * M12
mov lMantResult,eax
mov lExpResult,ecx
mov edx,[esi].vfl_y.ef_lMant ; get y
mov ebx,[esi].vfl_y.ef_lExp
mov eax,[edi].mx_efM22.ef_lMant
mov ecx,[edi].mx_efM22.ef_lExp
stdCall mulff ; y * M22
mov edx,lMantResult
mov ebx,lExpResult
stdCall addff ; x*M12 + y*M22
mov ebx, pvtflDest
mov [ebx].vfl_y.ef_lMant,eax
mov [ebx].vfl_y.ef_lExp,ecx
add esi,SIZE VECTORFL
add pvtflDest,SIZE VECTORFL
dec cvtl
jnz convert_vectors_loop
mov eax,1
stdRET bCvtVts_FlToFl
overflow:
xor eax,eax
stdRET bCvtVts_FlToFl
stdENDP bCvtVts_FlToFl
end