home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-09-04 | 28.5 KB | 1,224 lines |
- ;math.inc - general math functions.
-
- ; point rotation is 16 bit and uses vmatrix
- ; camera rotation is 32 bit and uses ematrix
- ; frotate uses rotation along a plane and uses ematrix with precal147
-
- ; point rotation
- ; bx = x cx = y bp = z 16 bit!
- ; clobbers dx,si,ax
-
- ; remember , matrix offsets are:
- ;
- ; 0 1 2 multiply those by 4 four the doublewords
- ; 3 4 5
- ; 6 7 8
- ;
- align 4
-
- public rotate
-
- rotate:
- movsx ebx,bx ; x
- movsx ecx,cx ; y
- movsx ebp,bp ; z
-
- mov eax,vmatrix+8 ; solve x = bx(0)+cx(1)+bp(2)
- imul ebp
- shr eax,14
- movsx edi,ax
- mov eax,vmatrix+4
- imul ecx
- shr eax,14
- movsx eax,ax
- add edi,eax
- mov eax,vmatrix+0
- imul ebx
- shr eax,14
- movsx eax,ax
- add edi,eax ; di = new x
-
- mov eax,vmatrix+20 ; solve y = bx(3)+cx(4)+bp(5)
- imul ebp
- shr eax,14
- movsx esi,ax
- mov eax,vmatrix+16
- imul ecx
- shr eax,14
- movsx eax,ax
- add esi,eax
- mov eax,vmatrix+12
- imul ebx
- shr eax,14
- movsx eax,ax
- add esi,eax ; si = new y
-
- mov eax,vmatrix+32 ; solve z = bx(6)+cx(7)+bp(8)
- imul ebp
- shr eax,14
- movsx ebp,ax
- mov eax,vmatrix+28
- imul ecx
- shr eax,14
- movsx eax,ax
- add ebp,eax
- mov eax,vmatrix+24
- imul ebx
- shr eax,14
- movsx eax,ax
- add ebp,eax ; bp = new z
-
- mov ecx,esi
- mov ebx,edi
-
- ret
-
- align 4
-
- ; fast ratiox and ratioy are 320x and 464y
- ; multiplication has been substituted with fast lea
-
- ; trashes eax,edx,edi
-
- public make3d
- public make3dx
- public make3dy
-
- make3d: ; bp must always be positive
- if ratiox eq 320
-
- lea eax,[ebx*4+ebx] ; 320 = %1 0100 0000
- shl eax,6
- cdq
-
- elseif not ratiox eq 320
- imul eax,ratiox
- display "Note: Slow X multiplication used in make3d routine"
- endif
-
- idiv ebp
- mov ebx,eax
- make3dy:
- if ratioy eq 464
- lea eax,[ecx*8+ecx] ; 464 = %1 1101 0000
- shl ecx,2
- lea ecx,[ecx*4+ecx]
- add eax,ecx
- shl eax,4
- cdq
-
- elseif not ratioy eq 464
- mov eax,ecx
- mov ecx,ratioy
- imul ecx
- display "Note: Slow Y multiplication used in make3dy routine"
- endif
-
- idiv ebp
- mov ecx,eax
-
- ret
-
- make3dx: ; bp must always be positive
- if ratiox eq 320
-
- lea eax,[edi*4+edi] ; 320 = %1 0100 0000, eax=320*edi
- shl eax,6
- cdq
-
- elseif not ratiox eq 320
- mov eax,edi
- mov edi,ratiox
- imul edi
- display "Note: Slow X multiplication used in make3dx routine"
- endif
-
- idiv esi
- mov edi,eax
- ret
-
- ; checks if a side is visible.
- ; DI, SI, DX = x's
- ; BP, DS, ES = y's
- ; return: cx register...
- ; cx > 0: side visible...else not...routine courtesy of "RAZOR"
- ; eg:
- ; call checkfront
- ; cmp cx,0
- ; jng dontdraw
-
- align 4
-
- checkfront:
- cmp di,si
- jng s cfc
- mov ax,di
- mov di,si
- mov si,dx
- mov dx,ax
- mov ax,bp
- mov bp,dsq
- mov bx,esq
- mov dsq,bx
- mov esq,ax
- cfc:
- cmp di,si
- jng s cfc2
- mov ax,di
- mov di,si
- mov si,dx
- mov dx,ax
- mov ax,bp
- mov bp,dsq
- mov bx,esq
- mov dsq,bx
- mov esq,ax
- cfc2:
- mov ax,dx ; ax = x3
- sub ax,di ; ax = x3 - x1
- mov bx,dsq ; bx = y2
- sub bx,bp ; bx = y2 - y1
- movsx eax,ax ; modification to allow large checks
- movsx ebx,bx
- imul ebx ; ax = (x3-x1)*(y2-y1)
- mov ecx,eax ; save it...
- mov ax,si ; ax = x2
- sub ax,di ; ax = x2 - x1
- mov bx,esq ; bx = y3
- sub bx,bp ; bx = y3 - y1
- movsx eax,ax
- movsx ebx,bx
- imul ebx ; ax = (x2-x1)*(y3-y1)
- sub ecx,eax ; cx = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1)
- ret
-
- ; point rotation for eye - solves all x,y,z parameters
- ; ebx = x ecx = y ebp = z 32 bit rotation!
- ; clobbers dx,si,di,ax
-
- align 4
-
- public erotate
-
- erotate:
- mov eax,ematrix+8
- imul ebp
- shrd eax,edx,14
- mov edi,eax
- if usez eq yes
- mov eax,ematrix+4
- imul ecx
- shrd eax,edx,14
- add edi,eax
- endif
- mov eax,ematrix+0
- imul ebx
- shrd eax,edx,14
- add edi,eax ; di = new x
-
- mov eax,ematrix+20
- imul ebp
- shrd eax,edx,14
- mov esi,eax
- mov eax,ematrix+16
- imul ecx
- shrd eax,edx,14
- add esi,eax
- mov eax,ematrix+12
- imul ebx
- shrd eax,edx,14
- add esi,eax ; si = new y
-
- mov eax,ematrix+32
- imul ebp
- shrd eax,edx,14
- mov ebp,eax
- mov eax,ematrix+28
- imul ecx
- shrd eax,edx,14
- add ebp,eax
- mov eax,ematrix+24
- imul ebx
- shrd eax,edx,14
- add ebp,eax ; bp = new z
-
- mov ecx,esi
- mov ebx,edi
-
- ret
-
- ; solve z from ematrix - same as above erotate but only solves z for fast
- ; test of where object is - result is in esi
-
- align 4
-
- public zsolve
- public ysolve
- public xsolve
-
- zsolve:
- mov eax,ematrix+32
- imul ebp
- shrd eax,edx,14
- mov esi,eax
- mov eax,ematrix+28
- imul ecx
- shrd eax,edx,14
- add esi,eax
- mov eax,ematrix+24
- imul ebx
- shrd eax,edx,14
- add esi,eax ; si = new z
- ret
-
- ; if object z test from above routine is positive, this routine will solve
- ; the rest of the rotation matrix. this is so we don't waste time solving
- ; for x and y locations if the object is not within screen parameters.
- ; saves imuls
-
- align 4
- xsolve:
- mov eax,ematrix+8
- imul ebp
- shrd eax,edx,14
- mov edi,eax
- if usez eq yes
- mov eax,ematrix+4
- imul ecx
- shrd eax,edx,14
- add edi,eax
- endif
- mov eax,ematrix+0
- imul ebx
- shrd eax,edx,14
- add edi,eax ; di = new x
- ret
-
- align 4
- ysolve:
- mov eax,ematrix+16
- imul ecx
- shrd eax,edx,14
- mov ecx,eax
- mov eax,ematrix+12
- imul ebx
- shrd eax,edx,14
- add ecx,eax
- mov eax,ematrix+20
- imul ebp
- shrd eax,edx,14
- add ecx,eax ; cx = new y
-
- mov ebx,edi ; final test, move into appropriate regs
- mov ebp,esi
-
- ret
-
- ; calculate sign into eax, from ax, smashes bx
- ; after imul by sign, shr eax,14 to compensate for decimal factor!
-
- align 4
-
- public cosign
- public sign
-
- cosign:
- add ax,4000h
- sign:
- shr ax,2
- cmp ax,2000h
- jge s q3o4 ; quadrant 3 or 4
-
- cmp ax,1000h
- jl s q0 ; quad 1
-
- mov bx,1fffh
- sub bx,ax
- jmp s halfsign ; quad 2
- q0:
- mov bx,ax
- jmp s halfsign
- q3o4:
- cmp ax,3000h
- jl s q3
- mov bx,3fffh
- sub bx,ax
- call halfsign ; quad 4
- neg eax
- ret
- q3:
- and ax,0fffh
- mov bx,ax ; quad 3
- call halfsign
- neg eax
- ret
- halfsign:
- shl bx,1
- movsx eax,w sinus[bx]
- ret
-
- ; arctan, cx=rise,ax=run, returns ax as angle of triangle
- ; smashes cx,ax,dx,si
-
- align 4
-
- public arctan
-
- arctan:
- cmp ax,0
- jl s qd2or3
- cmp cx,0
- jge s halftax ; quadrant 1
- neg cx ; quadrant 4, ax=-ax
- call halftan
- neg ax
- shl ax,2
- ret
- qd2or3:
- neg ax
- cmp cx,0
- jge s qd2
- neg cx ; quad 3, ax=ax+8192
- call halftan
- add ax,8192
- shl ax,2
- ret
- qd2:
- call halftan
- neg ax
- add ax,8192
- shl ax,2
- ret
- halftax:
- call halftan
- shl ax,2
- ret
-
- align 4
-
- halftan:
- movsx eax,ax
- movsx ecx,cx
- mov edx,0
-
- ; cx=rise positive
- ; ax=run positive
-
- cmp eax,ecx
- jl s opptan ; greater than 45 degrees, other side...
-
- xchg ecx,eax ; ax<cx
- shl eax,10 ; *2048
- div ecx
- mov si,ax
- shl si,2
- mov ax,w negtan[si] ; resulting angle (0-512 is 0-45) in ax
- ret
-
- align 4
-
- opptan:
- shl eax,10 ; *2048
-
- div ecx
- mov si,ax ; ax remainder
- shl si,2
- mov cx,w negtan[si]
- mov ax,1000h
- sub ax,cx ; resulting angle (2048-4096 is 45-90) in ax
- ret
-
- align 4
-
- ; generate object matrix, 12 imul's first
-
- ; x y z
- ;
- ;x= cz * cy - sx * sy * sz - sz * cy - sx * sy * cz - cx * sy
- ;
- ;y= sz * cx cx * cz - sx
- ;
- ;z= cz * sy + sx * sz * cy - sy * sz + sx * cy * cz cx * cy
- ;
- ;then perform matrix multiply by negative x and z matricies
- ;
- ; -x matrix -z matrix
- ; x y z x y z
- ;
- ;x 1 0 0 cz sz 0
- ;
- ;y 0 cx sx -sz cz 0
- ;
- ;z 0 -sx cx 0 0 1
- ;
- ; notice original object matrix takes 12 imuls, camera modify takes 24, can
- ; you do this faster? (less imuls)
-
- public compound
-
- compound:
- push esi
-
- mov ax,vxs[esi]
- neg ax
- push ax
- call cosign
- mov vcosx,eax
- pop ax
- call sign
- mov vsinx,eax
- mov ebp,eax ; bp = sx
- neg eax
- mov [vmatrix+20],eax
-
- mov ax,vzs[esi]
- neg ax
- push ax
- call cosign
- mov vcosz,eax
- mov edi,eax ; di = cz
- pop ax
- call sign
- mov vsinz,eax
- mov edx,eax ; dx = sz
-
- mov ax,vys[esi]
- neg ax
- add ax,eyeay
- push ax
- call cosign
- mov vcosy,eax
- pop ax
- call sign
- mov vsiny,eax ; ax = sy
-
- mov ebx,edx ; save sz
-
- mov ecx,eax ; save sy
-
- imul ebx ; bx = - sy * sz
- shr eax,14
- movsx ebx,ax
- neg ebx
- mov [vmatrix+28],ebx
-
- mov eax,ecx ; si = cz * sy
- imul edi
- shr eax,14
- movsx esi,ax
- mov [vmatrix+24],esi
-
- mov eax,vcosy
-
- imul edi ; di = cy * cz
- shr eax,14
- movsx edi,ax
- mov [vmatrix+0],edi
-
- mov eax,vsinz
- mov ecx,vcosy
-
- imul ecx ; cx = - sz * cy
- shr eax,14
- movsx ecx,ax
- neg ecx
- mov [vmatrix+4],ecx
-
- mov eax,ebp
- imul esi
- shr eax,14
- movsx esi,ax
- neg esi
- add [vmatrix+4],esi
-
- mov eax,ebp
- imul edi
- shr eax,14
- movsx edi,ax
- add [vmatrix+28],edi
-
- mov eax,ebp
- imul ebx
- shr eax,14
- movsx ebx,ax
- add [vmatrix+0],ebx
-
- mov eax,ebp
- imul ecx
- shr eax,14
- movsx ecx,ax
- neg ecx
- add [vmatrix+24],ecx
-
- mov esi,vcosx
-
- mov eax,vcosy
- imul esi ; cx * cy
- shr eax,14
- movsx eax,ax
- mov [vmatrix+32],eax
-
- mov eax,vsiny
- imul esi ;-cx * sy
- shr eax,14
- movsx eax,ax
- neg eax
- mov [vmatrix+8],eax
-
- mov eax,vsinz
- imul esi ; cx * sz
- shr eax,14
- movsx eax,ax
- mov [vmatrix+12],eax
-
- mov eax,vcosz
- imul esi ; cx * cz
- shr eax,14
- movsx eax,ax
- mov [vmatrix+16],eax
-
- mov edi,ecosx ; now perform camera x rotation,12 imuls
- mov esi,esinx
- mov ebp,esi
- neg ebp
-
- mov eax,[vmatrix+12]
- imul edi
- shr eax,14
- movsx ecx,ax
-
- mov eax,[vmatrix+24]
- imul esi
- shr eax,14
- movsx eax,ax
-
- add ecx,eax ; ecx = new vmatrix+12
-
- mov eax,[vmatrix+12]
- imul ebp
- shr eax,14
- movsx ebx,ax
-
- mov eax,[vmatrix+24]
- imul edi
- shr eax,14
- movsx eax,ax
-
- add ebx,eax ; ebx = new vmatrix+24
-
- mov [vmatrix+12],ecx
- mov [vmatrix+24],ebx
-
- mov eax,[vmatrix+16]
- imul edi
- shr eax,14
- movsx ecx,ax
-
- mov eax,[vmatrix+28]
- imul esi
- shr eax,14
- movsx eax,ax
-
- add ecx,eax ; ecx = new vmatrix+16
-
- mov eax,[vmatrix+16]
- imul ebp
- shr eax,14
- movsx ebx,ax
-
- mov eax,[vmatrix+28]
- imul edi
- shr eax,14
- movsx eax,ax
-
- add ebx,eax ; ebx = new vmatrix+28
-
- mov [vmatrix+16],ecx
- mov [vmatrix+28],ebx
-
- mov eax,[vmatrix+20]
- imul edi
- shr eax,14
- movsx ecx,ax
-
- mov eax,[vmatrix+32]
- imul esi
- shr eax,14
- movsx eax,ax
-
- add ecx,eax ; ecx = new vmatrix+20
-
- mov eax,[vmatrix+20]
- imul ebp
- shr eax,14
- movsx ebx,ax
-
- mov eax,[vmatrix+32]
- imul edi
- shr eax,14
- movsx eax,ax
-
- add ebx,eax ; ebx = new vmatrix+32
-
- mov [vmatrix+20],ecx
- mov [vmatrix+32],ebx
-
- if usez eq yes
-
- mov edi,ecosz ; now perform camera z rotation,12 imuls
- mov esi,esinz
- mov ebp,esi
- neg esi
-
- mov eax,[vmatrix+0]
- imul edi
- shr eax,14
- movsx ecx,ax
-
- mov eax,[vmatrix+12]
- imul esi
- shr eax,14
- movsx eax,ax
-
- add ecx,eax
-
- mov eax,[vmatrix+0]
- imul ebp
- shr eax,14
- movsx ebx,ax
-
- mov eax,[vmatrix+12]
- imul edi
- shr eax,14
- movsx eax,ax
-
- add ebx,eax
-
- mov [vmatrix+0],ecx
- mov [vmatrix+12],ebx
-
- mov eax,[vmatrix+4]
- imul edi
- shr eax,14
- movsx ecx,ax
-
- mov eax,[vmatrix+16]
- imul esi
- shr eax,14
- movsx eax,ax
-
- add ecx,eax
-
- mov eax,[vmatrix+4]
- imul ebp
- shr eax,14
- movsx ebx,ax
-
- mov eax,[vmatrix+16]
- imul edi
- shr eax,14
- movsx eax,ax
-
- add ebx,eax
-
- mov [vmatrix+4],ecx
- mov [vmatrix+16],ebx
-
- mov eax,[vmatrix+8]
- imul edi
- shr eax,14
- movsx ecx,ax
-
- mov eax,[vmatrix+20]
- imul esi
- shr eax,14
- movsx eax,ax
-
- add ecx,eax
-
- mov eax,[vmatrix+8]
- imul ebp
- shr eax,14
- movsx ebx,ax
-
- mov eax,[vmatrix+20]
- imul edi
- shr eax,14
- movsx eax,ax
-
- add ebx,eax
-
- mov [vmatrix+8],ecx
- mov [vmatrix+20],ebx
-
- endif
-
- pop esi
- ret
-
- ; generate rotation matrix for y,x,z camera rotation
- ; called only once every frame. completed in 12 multiplys
- ; matrix is also used for objects with no rotation (always angle 0,0,0)
- ;
- ; where is my postcard! see readme.doc for info.
- ;
- ; x y z
- ;
- ;x= cz * cy + sx * sy * sz -cx * sz - sy * cz + sx * cy * sz
- ;
- ;y= sz * cy - sx * sy * cz cx * cz - sy * sz - sz * cy * cz
- ;
- ;z= cx * sy sx cx * cy
- ;
-
- ; matrix offsets:
- ;
- ; x y z
- ;
- ;x 0 4 8
- ;y 12 16 20
- ;z 24 28 32
-
- align 4
-
- public setsincose
-
- setsincose:
-
- mov ax,eyeax
- call cosign
- mov ecosx,eax ; ecosx and such are used by object rotation
- mov ax,eyeax ; ematrix is used to find where object is
- call sign
- mov esinx,eax
- mov [ematrix+28],eax
- mov ebp,eax ; bp = sx
-
- if usez eq yes
- mov ax,eyeaz
- call cosign
- mov ecosz,eax
- mov edi,eax ; di = cz
- mov ax,eyeaz
- call sign
- mov esinz,eax
- mov edx,eax ; dx = sz
- endif
-
- if usez eq no
- mov edi,4000h ; di = cos 0
- mov ecosz,4000h
- xor edx,edx ; dx = sin 0
- mov esinz,0
- endif
-
- mov ax,eyeay
- call cosign
- mov ecosy,eax
- mov ax,eyeay
- call sign
- mov esiny,eax ; ax = sy
-
- mov ebx,edx ; save sz
-
- mov ecx,eax ; save sy
-
- imul ebx ; bx = sy * sz
- shr eax,14
- movsx ebx,ax
- neg ebx
- mov [ematrix+20],ebx
- neg ebx
-
- mov eax,ecx ; si = - (cz * sy)
- imul edi
- shr eax,14
- movsx esi,ax
- neg esi
- mov [ematrix+8],esi
-
- mov eax,ecosy
-
- imul edi ; di = cy * cz
- shr eax,14
- movsx edi,ax
- mov [ematrix+0],edi
-
- mov eax,esinz
- mov ecx,ecosy
-
- imul ecx ; cx = sz * cy
- shr eax,14
- movsx ecx,ax
- mov [ematrix+12],ecx
-
- mov eax,ebp
- imul esi
- shr eax,14
- movsx esi,ax
- add [ematrix+12],esi
-
- mov eax,ebp
- imul edi
- shr eax,14
- movsx edi,ax
- neg edi
- add [ematrix+20],edi
-
- mov eax,ebp
- imul ebx
- shr eax,14
- movsx ebx,ax
- add [ematrix+0],ebx
-
- mov eax,ebp
- imul ecx
- shr eax,14
- movsx ecx,ax
- add [ematrix+8],ecx
-
- mov esi,ecosx
-
- mov eax,ecosy
- imul esi ; cx * cy
- shr eax,14
- movsx eax,ax
- mov [ematrix+32],eax
-
- mov eax,esiny
- imul esi ; cx * sy
- shr eax,14
- movsx eax,ax
- mov [ematrix+24],eax
-
- mov eax,esinz
- imul esi ;-cx * sz
- shr eax,14
- movsx eax,ax
- neg eax
- mov [ematrix+4],eax
-
- mov eax,ecosz
- imul esi ; cx * cz
- shr eax,14
- movsx eax,ax
- mov [ematrix+16],eax
-
- neg esinx ; reverse angles for object rotation
- neg esiny
-
- ret
-
- ;getroot: ; get square root of ax, where ax = 0-65535
- ; cmp ax,0fe01h ; since ax cannot be negative anyway!
- ; jae sqr255 ; routine requires squares tables.
- ; mov si,offset squares
- ; mov cx,ax
- ; inc cx
- ; cld
- ;nextroot:
- ; lodsw
- ; cmp ax,cx
- ; jbe nextroot ; jb is exact but jbe is better approximation
- ; mov ax,si
- ; sub ax,offset squares+3
- ; sar ax,1
- ; ret
- ;sqr255:
- ; mov ax,255
- ; ret
-
- ; routine courtesy TRAN
- ;
- ; square root
- ; in:
- ; eax - number to take root of
- ; out:
- ; eax - root
- ;
- sqrtbasetbl db 0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225
-
- public sqrt
-
- align 4
-
- sqrt:
- pushad
- mov ebp,eax
- bsr ebx,eax
- jnz short sqrtf0
- xor ebx,ebx
- sqrtf0:
- shr ebx,3
- lea eax,[ebx*8]
- mov cl,32
- sub cl,al
- rol ebp,cl
- mov eax,ebp
- movzx eax,al
- mov edi,offset sqrtbasetbl
- mov ecx,10h
- sqrtl0:
- scasb
- je short sqrtl0d
- jb short sqrtl0d2
- loop sqrtl0
- inc edi
- sqrtl0d2:
- dec edi
- inc cl
- sqrtl0d:
- movzx edx,byte ptr [edi-1]
- dec cl
- xor cl,0fh
- mov edi,ecx
- mov ecx,ebx
- jecxz short sqrtdone
- sub eax,edx
- sqrtml:
- shld eax,ebp,8
- rol ebp,8
- mov ebx,edi
- shl ebx,5
- xor edx,edx
- mov esi,eax
- div ebx
- rol edi,4
- add edi,eax
- add ebx,eax
- sqrtf2:
- imul eax,ebx
- mov edx,eax
- mov eax,esi
- sub eax,edx
- jc short sqrtf1
- loop sqrtml
- sqrtdone:
- mov [esp+28],edi
- popad
- ret
- sqrtf1:
- dec ebx
- dec edi
- movzx eax,bl
- and al,1fh
- jmp sqrtf2
-
- ; solve for z when x = bx (takes a point/object on a y plane and figures
- ; where it would be if z = 16, y = precal7, only good for square translations)
- ; uses ematrix as rotation matrix
-
- ; cs set if not possible
-
- ; formula is inverse of z = bx6+cx7+bp8. where precal7 is y*7
- ; (16-bx(6)-precal7)/(8)=z
-
- public set_precal7
- public set_precal147
- public frotate
- public z16x
- public z16z
-
- public precal1
- public precal4
- public precal7
-
- align 4
-
- precal1 dd 0
- precal4 dd 0
- precal7 dd 0
-
- z16x:
- cmp ematrix+32,0
- je abort_attempt
-
- mov eax,ematrix+24
- imul ebx
- shrd eax,edx,14
-
- neg eax
- add eax,16
- sub eax,precal7
-
- cdq
- shld edx,eax,14
- mov ebx,ematrix+32
- idiv ebx
-
- stc
- ret
- abort_attempt:
- clc
- ret
-
- ; solve for x when z = bp (takes a point/object on a y plane and figures
- ; where it would be if z = 16, y = precal7, only good for square translations)
- ; uses ematrix as rotation matrix. output solves for z = 16
-
- ; cs set if not possible
-
- ; formula is inverse of z = bx6+cx7+bp8. where precal7 is y*7
- ; (16-bp(8)-precal7)/(6)=x
-
- align 4
-
- z16z:
- cmp ematrix+24,0
- je abort_attempt
-
- mov eax,ematrix+32
- imul ebp
- shrd eax,edx,14
-
- neg eax
- add eax,16
- sub eax,precal7
-
- cdq
- shld edx,eax,14
- mov ebx,ematrix+24
- idiv ebx
-
- stc
- ret
-
- ; set precal7 for plane transformation - plane is ecx and allows above formulas
- ; to determine where a point/object would be along that plane if z is negative
-
- ; good for runway translations or super huge background polygons - not used
- ; by regular 3d.asm routines
-
- ; how to use: lets say you've got a million background objects that are
- ; on the ground (or all on the same y plane). you call set_precal147
- ; with that y plane location and use frotate instead of erotate to
- ; determine where points rotated along that plane will end up. this
- ; speeds the routine up by 33% by cutting out 3 imuls.
-
- align 4
-
- set_precal147:
- if usez eq yes
- mov eax,ecx
- sub eax,eyey
- imul ematrix+4
- shr eax,14
- mov precal1,eax
- endif
-
- mov eax,ecx
- sub eax,eyey
- imul ematrix+16
- shr eax,14
- mov precal4,eax
-
- set_precal7:
- sub ecx,eyey
- mov eax,ecx
- imul ematrix+28
- shr eax,14
- mov precal7,eax
- ret
-
- align 4
-
- ; fast object/point rotation along pre-calculated y plane
-
- frotate:
- mov eax,ematrix+8
- imul ebp
- shrd eax,edx,14
- mov edi,eax
- if usez eq yes
- add edi,precal1
- endif
- mov eax,ematrix+0
- imul ebx
- shrd eax,edx,14
- add edi,eax ; di = new x
-
- mov eax,ematrix+20
- imul ebp
- shrd eax,edx,14
- mov esi,eax
- add esi,precal4
- mov eax,ematrix+12
- imul ebx
- shrd eax,edx,14
- add esi,eax ; si = new y
-
- mov eax,ematrix+32
- imul ebp
- shrd eax,edx,14
- mov ebp,eax
- add ebp,precal7
- mov eax,ematrix+24
- imul ebx
- shrd eax,edx,14
- add ebp,eax ; bp = new z
-
- mov ecx,esi
- mov ebx,edi
-
- ret
-
- ; fast solve for single matrix variable similar to erotate but uses frotate
- ; plane matrix with precal147
- ;
- ; remember , matrix offsets are:
- ;
- ; 0 1 2 multiply those by 4 four the doublewords
- ; 3 4 5
- ; 6 7 8
- ;
- public fzsolve
- public fxsolve
- public fysolve
-
- align 4
-
- fzsolve:
- mov eax,ematrix+32 ; solve z = bx(6)+cx(7)+bp(8)
- imul ebp
- shrd eax,edx,14
- mov esi,eax
- add esi,precal7
- mov eax,ematrix+24
- imul ebx
- shrd eax,edx,14
- add esi,eax ; si = new z
- ret
-
- align 4
- fxsolve:
- mov eax,ematrix+8 ; solve x = bx(0)+cx(1)+bp(2)
- imul ebp
- shrd eax,edx,14
- mov edi,eax
- if usez eq yes
- add edi,precal1
- endif
- mov eax,ematrix+0
- imul ebx
- shrd eax,edx,14
- add edi,eax ; di = new x
- ret
-
- align 4
- fysolve:
- mov eax,ematrix+20 ; solve y = bx(3)+cx(4)+bp(5)
- imul ebp
- shrd eax,edx,14
- mov ecx,eax
- add ecx,precal4
- mov eax,ematrix+12
- imul ebx
- shrd eax,edx,14
- add ecx,eax ; cx = new y
-
- mov ebx,edi
- mov ebp,esi
-
- ret
-