SecondReality/VISU/ACALC.ASM
2017-09-24 01:45:36 +02:00

887 lines
20 KiB
NASM
Raw Permalink Blame History

;/****************************************************************************
;** MODULE: acalc.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Calculations
;**
;****************************************************************************/
include a.inc
asm_code SEGMENT para public use16 'CODE'
ASSUME cs:asm_code
;entry: bx=angle (0..65535)
; exit: ax=sin(angle) [range -unit..unit]
sin PROC NEAR
shr bx,4-1
and bx,not 1
mov ax,ds:_sintable[bx]
ret
sin ENDP
;entry: bx=angle (0..65535)
; exit: ax=cos(angle) [range -unit..unit]
cos PROC NEAR
shr bx,4-1
add bx,1024*2
and bx,not (8192 or 1)
mov ax,ds:_sintable[bx]
ret
cos ENDP
;entry: bx=angle (0..65535)
; exit: ax=sin(angle) [range -unit..unit]
; bx=cos(angle) [range -unit..unit]
sincos PROC NEAR
shr bx,4-1
and bx,not 1
mov ax,ds:_sintable[bx]
add bx,1024*2
and bx,not (8192 or 1)
mov bx,ds:_sintable[bx]
ret
sincos ENDP
;used for matrix multiply EXPECTS the matrices to be of integer size
mulmacro MACRO row,col
mov eax,ds:[si+0+row*12]
imul dword ptr es:[di+0+col*4]
mov ebx,eax
mov eax,ds:[si+4+row*12]
imul dword ptr es:[di+12+col*4]
add ebx,eax
mov eax,ds:[si+8+row*12]
imul dword ptr es:[di+24+col*4]
add ebx,eax
sar ebx,unitshr
ENDM
;entry: fs:si=matrix1, es:di=matrix2
; exit: fs:si=matrix1*matrix2 (matrix 1 overwritten)
mulmatrices PROC NEAR
push ds
mov ax,fs
mov ds,ax
mulmacro 0,0
push ebx
mulmacro 0,1
push ebx
mulmacro 0,2
push ebx
mulmacro 1,0
push ebx
mulmacro 1,1
push ebx
mulmacro 1,2
push ebx
mulmacro 2,0
push ebx
mulmacro 2,1
push ebx
mulmacro 2,2
mov ds:[si+8+24],ebx
pop dword ptr ds:[si+4+24]
pop dword ptr ds:[si+0+24]
pop dword ptr ds:[si+8+12]
pop dword ptr ds:[si+4+12]
pop dword ptr ds:[si+0+12]
pop dword ptr ds:[si+8]
pop dword ptr ds:[si+4]
pop dword ptr ds:[si+0]
pop ds
ret
mulmatrices ENDP
;entry: fs:si=matrix1, es:di=matrix2
; exit: es:di=matrix1*matrix2 (matrix 2 overwritten)
mulmatrices2 PROC NEAR
push ds
mov ax,fs
mov ds,ax
mulmacro 0,0
push ebx
mulmacro 0,1
push ebx
mulmacro 0,2
push ebx
mulmacro 1,0
push ebx
mulmacro 1,1
push ebx
mulmacro 1,2
push ebx
mulmacro 2,0
push ebx
mulmacro 2,1
push ebx
mulmacro 2,2
mov es:[di+8+24],ebx
pop dword ptr es:[di+4+24]
pop dword ptr es:[di+0+24]
pop dword ptr es:[di+8+12]
pop dword ptr es:[di+4+12]
pop dword ptr es:[di+0+12]
pop dword ptr es:[di+8]
pop dword ptr es:[di+4]
pop dword ptr es:[di+0]
pop ds
ret
mulmatrices2 ENDP
;entry: ax=rotx, bx=roty, cx=rotz, es:di=rmatrix.m
; exit: (writes rmatrix.m)
calcmatrixsep PROC NEAR ;calc 3 separate matrices
push bp
mov bp,sp
sub sp,12 ;for local variables
push ds
push di
push bx
push cx
mov bx,ax
neg bx
call sincos
mov ss:[bp-12+0],ax ;rxsin
mov ss:[bp-12+2],bx ;rxcos
pop bx
neg bx
call sincos
mov ss:[bp-12+4],ax ;rysin
mov ss:[bp-12+6],bx ;rycos
pop bx
neg bx
call sincos
mov ss:[bp-12+8],ax ;rzsin
mov ss:[bp-12+10],bx ;rzcos
mov ebx,0
mov ecx,unit
mov ax,es
mov ds,ax
;rX
mov ds:[di+2*0],ecx
mov ds:[di+2*2],ebx
mov ds:[di+2*4],ebx
mov ds:[di+2*6],ebx
movsx eax,word ptr ss:[bp-12+2]
mov ds:[di+2*8],eax
movsx eax,word ptr ss:[bp-12+0]
mov ds:[di+2*10],eax
mov ds:[di+2*12],ebx
movsx eax,word ptr ss:[bp-12+0]
neg eax
mov ds:[di+2*14],eax
movsx eax,word ptr ss:[bp-12+2]
mov ds:[di+2*16],eax
add di,36
;rY
movsx eax,word ptr ss:[bp-12+6]
mov ds:[di+2*0],eax
mov ds:[di+2*2],ebx
movsx eax,word ptr ss:[bp-12+4]
neg eax
mov ds:[di+2*4],eax
mov ds:[di+2*6],ebx
mov ds:[di+2*8],ecx
mov ds:[di+2*10],ebx
movsx eax,word ptr ss:[bp-12+4]
mov ds:[di+2*12],eax
mov ds:[di+2*14],ebx
movsx eax,word ptr ss:[bp-12+6]
mov ds:[di+2*16],eax
add di,36
;rZ
movsx eax,word ptr ss:[bp-12+10]
mov ds:[di+2*0],eax
movsx eax,word ptr ss:[bp-12+8]
mov ds:[di+2*2],eax
mov ds:[di+2*4],ebx
movsx eax,word ptr ss:[bp-12+8]
neg eax
mov ds:[di+2*6],eax
movsx eax,word ptr ss:[bp-12+10]
mov ds:[di+2*8],eax
mov ds:[di+2*10],ebx
mov ds:[di+2*12],ebx
mov ds:[di+2*14],ebx
mov ds:[di+2*16],ecx
pop di
pop ds
mov sp,bp
pop bp
ret
calcmatrixsep ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_setrmatrix_ident(rmatrix *matrix) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: matrix=destination matrix (only rotation fields modified)
; exit: (data written to matrix)
;descr: Writes an identity rotation matrix to rmatrix
_calc_setrmatrix_ident PROC FAR
CBEG
lespar di,0
mov edx,unit
xor eax,eax
mov es:[di+rmatrix_m+0*4],edx
mov es:[di+rmatrix_m+1*4],eax
mov es:[di+rmatrix_m+2*4],eax
mov es:[di+rmatrix_m+3*4],eax
mov es:[di+rmatrix_m+4*4],edx
mov es:[di+rmatrix_m+5*4],eax
mov es:[di+rmatrix_m+6*4],eax
mov es:[di+rmatrix_m+7*4],eax
mov es:[di+rmatrix_m+8*4],edx
CEND
_calc_setrmatrix_ident ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_setrmatrix_rotyxz(rmatrix *matrix,angle rotx,angle roty,angle rotz) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: matrix=destination matrix (only rotation fields modified)
; rotx/y/z=rotation angles
; exit: (data written to matrix)
;descr: Calculates a rotation matrix
_calc_setrmatrix_rotyxz PROC FAR
CBEGR 36*3
mov ax,ss
mov es,ax
mov fs,ax
movpar ax,2
movpar bx,3
movpar cx,4
lea di,[bp-36*3]
call calcmatrixsep
lea si,[bp-36*3+36*1]
lea di,[bp-36*3+36*0]
call mulmatrices ;Y*=X
lea si,[bp-36*3+36*1]
lea di,[bp-36*3+36*2]
call mulmatrices ;Y*=Z
lespar di,0
zzz=0
REPT 9
mov eax,fs:[si+zzz]
mov es:[di+rmatrix_m+zzz],eax
zzz=zzz+4
ENDM
CENDR
_calc_setrmatrix_rotyxz ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_setrmatrix_rotxyz(rmatrix *matrix,angle rotx,angle roty,angle rotz) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: matrix=destination matrix (only rotation fields modified)
; rotx/y/z=rotation angles
; exit: (data written to matrix)
;descr: Calculates a rotation matrix
_calc_setrmatrix_rotxyz PROC FAR
CBEGR 36*3
mov ax,ss
mov es,ax
mov fs,ax
movpar ax,2
movpar bx,3
movpar cx,4
lea di,[bp-36*3]
call calcmatrixsep
lea si,[bp-36*3+36*0]
lea di,[bp-36*3+36*1]
call mulmatrices ;X*=Y
lea si,[bp-36*3+36*0]
lea di,[bp-36*3+36*2]
call mulmatrices ;X*=Z
lespar di,0
zzz=0
REPT 9
mov eax,fs:[si+zzz]
mov es:[di+rmatrix_m+zzz],eax
zzz=zzz+4
ENDM
CENDR
_calc_setrmatrix_rotxyz ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_setrmatrix_rotzyx(rmatrix *matrix,
; angle rotx,angle roty,angle rotz) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: matrix=destination matrix (only rotation fields modified)
; rotx/y/z=rotation angles
; exit: (data written to matrix)
;descr: Calculates a rotation matrix
_calc_setrmatrix_rotzyx PROC FAR
CBEGR 36*3
mov ax,ss
mov es,ax
mov fs,ax
movpar ax,2
movpar bx,3
movpar cx,4
lea di,[bp-36*3]
call calcmatrixsep
lea si,[bp-36*3+36*2]
lea di,[bp-36*3+36*1]
call mulmatrices ;Z*=Y
lea si,[bp-36*3+36*2]
lea di,[bp-36*3+36*0]
call mulmatrices ;Z*=X
lespar di,0
zzz=0
REPT 9
mov eax,fs:[si+zzz]
mov es:[di+rmatrix_m+zzz],eax
zzz=zzz+4
ENDM
CENDR
_calc_setrmatrix_rotzyx ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_mulrmatrix(rmatrix *dest, rmatrix *source) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: dest=destination matrix (matrix modified)
; source=source matrix (modifying matrix)
; exit: (data written to dest matrix)
;descr: dest=source*dest. Transposition first, rotation second.
_calc_mulrmatrix PROC FAR
CBEG
;fs:si=dest, es:di=source
lfspar si,0
lespar di,2
call mulmatrices
;fs:si now has the new rotation matrix, next rotate position
push bp
lespar di,0
add di,rmatrix_x
ldspar si,2 ;DS destroyed
lfspar bp,0
add bp,rmatrix_x
call rotatesingle
pop bp
;translate (inverse)
lespar di,2
lfspar si,0
mov eax,es:[di+rmatrix_x]
add fs:[si+rmatrix_x],eax
mov eax,es:[di+rmatrix_y]
add fs:[si+rmatrix_y],eax
mov eax,es:[di+rmatrix_z]
add fs:[si+rmatrix_z],eax
@@x: CEND
_calc_mulrmatrix ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_applyrmatrix(rmatrix *dest, rmatrix *apply) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: dest=destination matrix (matrix modified)
; apply=apply matrix (modifying matrix)
; exit: (data written to dest matrix)
;descr: The apply matrix is the camera matrix, the dest contains
; the objects own rotation/position, which is modified
; according to the camera.
_calc_applyrmatrix PROC FAR
CBEG
;fs:si=source, es:di=dest
lfspar si,2
lespar di,0
call mulmatrices2
;es:di now has the new rotation matrix, next rotate position
push bp
lespar di,0
add di,rmatrix_x
ldspar si,2 ;rotate according to apply matrix
lfspar bp,0
add bp,rmatrix_x
call rotatesingle
pop bp
;translate
lespar di,2
lfspar si,0
mov eax,es:[di+rmatrix_x]
add fs:[si+rmatrix_x],eax
mov eax,es:[di+rmatrix_y]
add fs:[si+rmatrix_y],eax
mov eax,es:[di+rmatrix_z]
add fs:[si+rmatrix_z],eax
@@x: CEND
_calc_applyrmatrix ENDP
rotatesingle PROC NEAR
;ds:si=rmatrix
;fs:bp=source[]: x,y,z (long)
;es:di=destination[]: x,y,z (long)
;destination and source can be same
mov eax,fs:[bp+0]
imul dword ptr ds:[si+rmatrix_m+2*0]
mov ebx,eax
mov ecx,edx
mov eax,fs:[bp+4]
imul dword ptr ds:[si+rmatrix_m+2*2]
add ebx,eax
adc ecx,edx
mov eax,fs:[bp+8]
imul dword ptr ds:[si+rmatrix_m+2*4]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
push ebx
mov eax,fs:[bp+0]
imul dword ptr ds:[si+rmatrix_m+2*6]
mov ebx,eax
mov ecx,edx
mov eax,fs:[bp+4]
imul dword ptr ds:[si+rmatrix_m+2*8]
add ebx,eax
adc ecx,edx
mov eax,fs:[bp+8]
imul dword ptr ds:[si+rmatrix_m+2*10]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
push ebx
mov eax,fs:[bp+0]
imul dword ptr ds:[si+rmatrix_m+2*12]
mov ebx,eax
mov ecx,edx
mov eax,fs:[bp+4]
imul dword ptr ds:[si+rmatrix_m+2*14]
add ebx,eax
adc ecx,edx
mov eax,fs:[bp+8]
imul dword ptr ds:[si+rmatrix_m+2*16]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
mov es:[di+8],ebx
pop dword ptr es:[di+4]
pop dword ptr es:[di+0]
ret
rotatesingle ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_sftranslate(int count,vlist *dest,long tx,long ty,long tz) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: count=number of vertices to sftranslate
; dest=destination 3D list
; matrix=rmatrix containing rotation / moving
; exit: -
;descr: Translates dest with matrix and and (starfield)
_calc_sftranslate PROC FAR
CBEG
movpar ax,0
or ax,ax
jz @@0
ldspar si,1 ;destination
movpar bx,3
movpar cx,5
movpar dx,7
mov bp,ax
@@1:
mov ax,ds:[si+vlist_x]
add ax,bx
mov ds:[si+vlist_x],ax
mov ax,ds:[si+vlist_y]
add ax,cx
mov ds:[si+vlist_y],ax
mov ax,ds:[si+vlist_z]
add ax,dx
mov ds:[si+vlist_z],ax
add si,vlist_size
dec bp
jnz @@1
@@0: CEND
_calc_sftranslate ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_rotate(int count,vlist *dest,vlist *source,rmatrix *matrix) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: count=number of vertices to rotate/move
; dest=destination 3D list
; source=source 3D list
; matrix=rmatrix containing rotation / moving
; exit: -
;descr: Rotates (and moves) the given list
_calc_rotate PROC FAR
CBEG
movpar cx,0
jcxz @@0
lespar di,1 ;destination
ldspar si,5 ;matrix - dataseg not used in procedure, so DS can be used
lfspar bp,3 ;source - NOTE: bp/parameter pointer destroyed!
@@1: push cx
movsx eax,word ptr ds:[si+rmatrix_m+2*0]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*2]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*4]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_x]
mov dword ptr es:[di+vlist_x],ebx
movsx eax,word ptr ds:[si+rmatrix_m+2*6]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*8]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*10]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_y]
mov dword ptr es:[di+vlist_y],ebx
movsx eax,word ptr ds:[si+rmatrix_m+2*12]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*14]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*16]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_z]
mov dword ptr es:[di+vlist_z],ebx
mov ax,word ptr fs:[bp+vlist_normal]
mov word ptr es:[di+vlist_normal],ax
;next point
add bp,vlist_size
add di,vlist_size
pop cx
loop @@1
@@0: CEND
_calc_rotate ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_singlez(int vertex,vlist *vertexlist,rmatrix *matrix) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: vertex=number of vertex to process
; vertexlist=list from which to pick the vertex
; exit: -
;descr: Rotates the single vertex and returns the resulting Z coordinate.
_calc_singlez PROC FAR
CBEG
ldspar si,3 ;matrix - dataseg not used in procedure, so DS can be used
movpar ax,0
lfspar bp,1 ;source - NOTE: bp/parameter pointer destroyed!
shl ax,vlist_sizeshl
add bp,ax
mov eax,ds:[si+rmatrix_m+24]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
mov eax,ds:[si+rmatrix_m+28]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
mov eax,ds:[si+rmatrix_m+32]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_z]
mov ax,bx
shr ebx,16
mov dx,bx
CEND
_calc_singlez ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_nrotate(int count,nlist *dest,nlist *source,rmatrix *matrix) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: count=number of normals to rotate
; dest=destination 3Dnormal list
; source=source 3Dnormal list
; matrix=rmatrix containing rotation (moving part of rmatrix not used)
; exit: -
;descr: Rotates the given normal list
_calc_nrotate PROC FAR
CBEG
movpar cx,0
jcxz @@0
lespar di,1 ;destination
ldspar si,5 ;matrix - dataseg not used in procedure, so DS can be used
lfspar bp,3 ;source - NOTE: bp/parameter pointer destroyed!
@@1: push cx
mov ax,word ptr fs:[bp+nlist_x]
imul word ptr ds:[si+rmatrix_m+2*0]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+nlist_y]
imul word ptr ds:[si+rmatrix_m+2*2]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+nlist_z]
imul word ptr ds:[si+rmatrix_m+2*4]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+nlist_x],bx
mov ax,word ptr fs:[bp+nlist_x]
imul word ptr ds:[si+rmatrix_m+2*6]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+nlist_y]
imul word ptr ds:[si+rmatrix_m+2*8]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+nlist_z]
imul word ptr ds:[si+rmatrix_m+2*10]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+nlist_y],bx
mov ax,word ptr fs:[bp+nlist_x]
imul word ptr ds:[si+rmatrix_m+2*12]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+nlist_y]
imul word ptr ds:[si+rmatrix_m+2*14]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+nlist_z]
imul word ptr ds:[si+rmatrix_m+2*16]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+nlist_z],bx
;next point
add bp,nlist_size
add di,nlist_size
pop cx
loop @@1
@@0: CEND
_calc_nrotate ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_rotate16(int count,nlist *dest,nlist *source,rmatrix *matrix) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: count=number of normals to rotate
; dest=destination 3Dnormal list
; source=source 3Dnormal list
; matrix=rmatrix containing rotation (moving part of rmatrix not used)
; exit: -
;descr: Rotates the given normal list
_calc_rotate16 PROC FAR
CBEG
movpar cx,0
jcxz @@0
lespar di,1 ;destination
ldspar si,5 ;matrix - dataseg not used in procedure, so DS can be used
lfspar bp,3 ;source - NOTE: bp/parameter pointer destroyed!
@@1: push cx
mov ax,word ptr fs:[bp+vlist_x]
imul word ptr ds:[si+rmatrix_m+2*0]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+vlist_y]
imul word ptr ds:[si+rmatrix_m+2*2]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+vlist_z]
imul word ptr ds:[si+rmatrix_m+2*4]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+vlist_x],bx
mov ax,word ptr fs:[bp+vlist_x]
imul word ptr ds:[si+rmatrix_m+2*6]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+vlist_y]
imul word ptr ds:[si+rmatrix_m+2*8]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+vlist_z]
imul word ptr ds:[si+rmatrix_m+2*10]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+vlist_y],bx
mov ax,word ptr fs:[bp+vlist_x]
imul word ptr ds:[si+rmatrix_m+2*12]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+vlist_y]
imul word ptr ds:[si+rmatrix_m+2*14]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+vlist_z]
imul word ptr ds:[si+rmatrix_m+2*16]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+vlist_z],bx
;next point
add bp,vlist_size
add di,vlist_size
pop cx
loop @@1
@@0: CEND
_calc_rotate16 ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_project(int count,pvlist *dest,vlist *source) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: count=number of vertices to project
; dest=destination projected list
; source=source 3D list
; (_proj* variables in data segment define the projection)
; exit: logical and of visibility flags for all vertices (!=0 == object invis.)
;descr: Projects the given list = does perspective transformation
_calc_project PROC FAR
CBEG
lfspar si,3
lespar di,1
mov ax,0ffffh
movpar cx,0
jcxz @@0
@@1: push cx
push ax
mov ecx,fs:[si+vlist_x]
mov eax,fs:[si+vlist_y]
mov ebx,fs:[si+vlist_z]
xor bp,bp
cmp ebx,ds:_projclipz[CLIPMIN]
jge @@21
or bp,VF_NEAR
mov ebx,ds:_projclipz[CLIPMIN]
jmp @@22
@@21: cmp ebx,ds:_projclipz[CLIPMAX]
jle @@22
or bp,VF_FAR
@@22: ;
imul ds:_projmuly
idiv ebx
add eax,ds:_projaddy
cmp eax,ds:_projclipy[CLIPMAX]
jng @@41
or bp,VF_DOWN
@@41: cmp eax,ds:_projclipy[CLIPMIN]
jnl @@42
or bp,VF_UP
@@42: mov es:[di+pvlist_y],ax ;store Y
;
mov eax,ds:_projmulx
imul ecx
idiv ebx
add eax,ds:_projaddx
cmp eax,ds:_projclipx[CLIPMAX]
jng @@43
or bp,VF_RIGHT
@@43: cmp eax,ds:_projclipx[CLIPMIN]
jnl @@44
or bp,VF_LEFT
@@44: mov es:[di+pvlist_x],ax ;store X
@@5: mov es:[di+pvlist_vf],bp ;store visiblity flags
;next point
add si,vlist_size
add di,pvlist_size
pop ax
pop cx
and ax,bp
loop @@1
@@0: CEND
_calc_project ENDP
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _calc_project16(int count,pvlist *dest,vlist *source) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;entry: count=number of vertices to project
; dest=destination projected list
; source=source 3D list
; (_proj* variables in data segment define the projection)
; exit: logical and of visibility flags for all vertices (!=0 == object invis.)
;descr: Projects the given list = does perspective transformation
_calc_project16 PROC FAR
CBEG
lfspar si,3
lespar di,1
mov ax,0ffffh
movpar cx,0
jcxz @@0
@@1: push cx
push ax
movsx ecx,word ptr fs:[si+vlist_x]
movsx eax,word ptr fs:[si+vlist_y]
movsx ebx,word ptr fs:[si+vlist_z]
xor bp,bp
cmp ebx,ds:_projclipz[CLIPMIN]
jge @@21
or bp,VF_NEAR
mov ebx,ds:_projclipz[CLIPMIN]
jmp @@22
@@21: cmp ebx,ds:_projclipz[CLIPMAX]
jle @@22
or bp,VF_FAR
@@22: ;
imul ds:_projmuly
idiv ebx
add eax,ds:_projaddy
cmp eax,ds:_projclipy[CLIPMAX]
jng @@41
or bp,VF_DOWN
@@41: cmp eax,ds:_projclipy[CLIPMIN]
jnl @@42
or bp,VF_UP
@@42: mov es:[di+pvlist_y],ax ;store Y
;
mov eax,ds:_projmulx
imul ecx
idiv ebx
add eax,ds:_projaddx
cmp eax,ds:_projclipx[CLIPMAX]
jng @@43
or bp,VF_RIGHT
@@43: cmp eax,ds:_projclipx[CLIPMIN]
jnl @@44
or bp,VF_LEFT
@@44: mov es:[di+pvlist_x],ax ;store X
@@5: mov es:[di+pvlist_vf],bp ;store visiblity flags
;next point
add si,vlist_size
add di,pvlist_size
pop ax
pop cx
and ax,bp
loop @@1
@@0: CEND
_calc_project16 ENDP
asm_code ENDS
END