X-Git-Url: http://4ch.mooo.com/gitweb/?a=blobdiff_plain;f=16%2Fxw_%2Fmodex%2FTHREED.ASM;fp=16%2Fxw_%2Fmodex%2FTHREED.ASM;h=0000000000000000000000000000000000000000;hb=4b23f27092a9470a741e3a18261ad389fd1929db;hp=5ecd3ba3a0097f19c786ff7a095b4f9b279dcbe4;hpb=5d8d1deb6c3520abadbad86d202ea453df77bfc2;p=16.git diff --git a/16/xw_/modex/THREED.ASM b/16/xw_/modex/THREED.ASM deleted file mode 100755 index 5ecd3ba3..00000000 --- a/16/xw_/modex/THREED.ASM +++ /dev/null @@ -1,872 +0,0 @@ -COMMENT / - Fixed-point math functions and 3D transforms - Copyright (c) 1993,94 by Alessandro Scotti -/ -WARN PRO -P386 -JUMPS -LOCALS - -INCLUDE MATH.INC - -PUBLIC tdFixedMul -PUBLIC tdGetNormal -PUBLIC tdRotate -PUBLIC tdGetSurfaceLight -PUBLIC tdSetLight -PUBLIC tdSetRotation -PUBLIC tdSetTranslation -PUBLIC tdTransform -PUBLIC tdTransformToImage -PUBLIC tdTransformLight -PUBLIC tdBackPlaneCull -PUBLIC tdSetPerspective - -;----------------------------------------------------------- -; -; Data segment -; -MATH_DATA SEGMENT USE16 PARA PUBLIC 'DATA' - ASSUME ds:MATH_DATA - -INCLUDE SINCOS.INC ; Fixed 8:24 sin/cos table - -XRotation TPOINT <> ; 3x3 rotation matrix -YRotation TPOINT <> -ZRotation TPOINT <> - -Translation TPOINT <> ; Translation vector - -Light TPOINT <> ; Light vector -AmbientLight DW 00 ; Ambient light - -XScale DD 10000h ; Scaling factor for X coordinate -YScale DD 10000h ; Scaling factor for Y coordinate -PerspectiveDistance DD 20000000h - -MATH_DATA ENDS - -;----------------------------------------------------------- -; -; Code segment -; -MATH_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' - ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING - -tdSetPerspective PROC PASCAL FAR - ARG Perspective:DWORD, \ - ScaleX:DWORD, \ - ScaleY:DWORD - USES ds - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - mov eax, [Perspective] - mov [PerspectiveDistance], eax - mov eax, [ScaleX] - mov [XScale], eax - mov eax, [ScaleY] - mov [YScale], eax - - ret -tdSetPerspective ENDP - - -;----------------------------------------------------------- -; -; Sets the rotation matrix. -; -; Input: -; RX = X-axis rotation angle -; RY = X-axis rotation angle -; RZ = X-axis rotation angle -; Output: -; none -; -tdSetRotation PROC PASCAL FAR - ARG RX:WORD, \ - RY:WORD, \ - RZ:WORD - USES ds, si, di - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - mov bx, [RZ] - mov si, [RY] - mov di, [RX] - shl bx, 2 - shl si, 2 - shl di, 2 - - push ebp ; We use EBP as a scratch register - -; Set X rotation - mov eax, tblCos[bx] - imul tblCos[si] - mov [XRotation.X], edx - - mov eax, tblSin[bx] - imul tblCos[si] - mov [XRotation.Y], edx - - mov eax, tblSin[si] - sar eax, 8 ; Convert fixed 8:24 to fixed 16:16 - mov [XRotation.Z], eax - -; Set Y rotation - mov eax, tblCos[bx] - imul tblSin[si] ; EDX:EAX = fixed 16:48 - shrd eax, edx, 24 ; EAX = fixed 8:24 - imul tblSin[di] ; EDX:EAX = fixed 16:48 - mov ebp, eax - mov ecx, edx - mov eax, tblSin[bx] - imul tblCos[di] - add eax, ebp - adc edx, ecx ; EDX:EAX = fixed 16:48 - neg edx - mov [YRotation.X], edx - - mov eax, tblSin[bx] - imul tblSin[si] - shrd eax, edx, 24 - imul tblSin[di] - mov ebp, eax - mov ecx, edx - mov eax, tblCos[bx] - imul tblCos[di] - sub eax, ebp - sbb edx, ecx - mov [YRotation.Y], edx - - mov eax, tblCos[si] - imul tblSin[di] - mov [YRotation.Z], edx - -; Set Z rotation - mov eax, tblCos[bx] - imul tblSin[si] - shrd eax, edx, 24 - imul tblCos[di] - mov ebp, eax - mov ecx, edx - mov eax, tblSin[bx] - imul tblSin[di] - sub eax, ebp - sbb edx, ecx - mov [ZRotation.X], edx - - mov eax, tblSin[bx] - imul tblSin[si] - shrd eax, edx, 24 - imul tblCos[di] - mov ebp, eax - mov ecx, edx - mov eax, tblCos[bx] - imul tblSin[di] - add eax, ebp - add edx, ecx - neg edx - mov [ZRotation.Y], edx - - mov eax, tblCos[si] - imul tblCos[di] - mov [ZRotation.Z], edx - - pop ebp ; Restore EBP - - ret -tdSetRotation ENDP - -;----------------------------------------------------------- -; -; Sets the translation vector. -; -; Input: -; TV = pointer to translation vector -; Output: -; none -; -tdSetTranslation PROC PASCAL FAR - ARG TV:DWORD - USES ds, es, di - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - les di, [TV] - mov eax, es:[di].X - mov [Translation.X], eax - mov eax, es:[di].Y - mov [Translation.Y], eax - mov eax, es:[di].Z - mov [Translation.Z], eax - - ret -tdSetTranslation ENDP - -;----------------------------------------------------------- -; -; Transforms an array of TPOINT. -; -; Input: -; Source = pointer to source array of TPOINT -; Dest = pointer to destination array of TPOINT -; Count = number of entries to transform -; Output: -; none -; -tdTransform PROC PASCAL FAR - ARG Source:DWORD, \ - Dest:DWORD, \ - Count:WORD - LOCAL Adjust:DWORD - USES ds, si, es, di, fs - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - lfs si, [Source] - les di, [Dest] - - ALIGN DWORD -@@Loop: -; Transform Z coordinate - mov eax, fs:[si].X - imul [ZRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, fs:[si].Y - imul [ZRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, fs:[si].Z - imul [ZRotation.Z] - add eax, ecx - adc edx, ebx - mov ebx, eax - shrd eax, edx, 16 - add eax, [Translation.Z] ; EAX = new Z coord (fixed 16:16) - mov es:[di].Z, eax -; Get perspective factor - mov ebx, [PerspectiveDistance] - sub eax, ebx - neg eax ; EAX = PD - Z - xor edx, edx - shld edx, eax, 16 - shl eax, 16 - idiv ebx ; EAX = fixed 16:16 result - mov [Adjust], eax - -; Transform X coordinate - mov eax, fs:[si].X - imul [XRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, fs:[si].Y - imul [XRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, fs:[si].Z - imul [XRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - add eax, [Translation.X] - imul [Adjust] - shrd eax, edx, 16 - mov es:[di].X, eax - -; Transform Y coordinate - mov eax, fs:[si].X - imul [YRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, fs:[si].Y - imul [YRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, fs:[si].Z - imul [YRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - add eax, [Translation.Y] - imul [Adjust] - shrd eax, edx, 16 - mov es:[di].Y, eax - - add si, SIZE TPOINT - add di, SIZE TPOINT - dec [Count] - jnz @@Loop - - ret -tdTransform ENDP - -;----------------------------------------------------------- -; -; Transforms an array of TPOINT into an array of TIMAGEPOINT. -; -; Input: -; Source = pointer to source array of TPOINT -; Dest = pointer to destination array of TIMAGEPOINT -; Count = number of entries to transform -; DeltaX = translation distance for the X coordinate -; DeltaY = translation distance for the Y coordinate -; Output: -; the maximum Z value -; -tdTransformToImage PROC PASCAL FAR - ARG Source:DWORD, \ - Dest:DWORD, \ - Count:WORD, \ - DeltaX:WORD, \ - DeltaY:WORD - LOCAL Adjust:DWORD, \ - Max:DWORD - USES ds, si, es, di, fs - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - lfs si, [Source] - les di, [Dest] - mov [Max], 80000000h - -@@Loop: -; Check max Z - mov eax, fs:[si].Z - cmp eax, [Max] - jle @@1 - mov [Max], eax -@@1: - -; Transform X coordinate - mov ax, WORD PTR fs:[si].X[2] - add ax, [DeltaX] - mov es:[di].IX, ax - -; Transform Y coordinate - mov ax, WORD PTR fs:[si].Y[2] - add ax, [DeltaY] - mov es:[di].IY, ax - - add si, SIZE TPOINT - add di, SIZE TIMAGEPOINT - dec [Count] - jnz @@Loop - - mov eax, [Max] - shld edx, eax, 16 - ret -tdTransformToImage ENDP - -;----------------------------------------------------------- -; -; Sets the light source. -; -; Input: -; Light = pointer to light vector -; Output: -; none -; -tdSetLight PROC PASCAL FAR - ARG L:DWORD - USES ds, es, di - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - les di, [L] - mov eax, es:[di].X - mov [Light.X], eax - mov eax, es:[di].Y - mov [Light.Y], eax - mov eax, es:[di].Z - mov [Light.Z], eax - - ret -tdSetLight ENDP - -;----------------------------------------------------------- -; -; Computes light intensity for an array of surfaces. -; -; Input: -; Normals = pointer to an array of surface normals -; Lights = pointer to an array of integer to be filled with -; light intensity -; Count = number of elements to transform -; Output: -; none -; -tdTransformLight PROC PASCAL FAR - ARG Normals:DWORD, \ - Lights:DWORD, \ - Count:WORD - USES ds, si, es, di, fs - - mov ax, SEG MATH_DATA - mov fs, ax - ASSUME fs:MATH_DATA - - lds si, [Normals] - les di, [Lights] - ASSUME ds:NOTHING - -; Intensity is given by the dot product between the Light vector and -; the surface normal -@@Loop: - mov eax, ds:[si].Z - imul [Light.Z] - mov ebx, eax - mov ecx, edx - mov eax, ds:[si].Y - imul [Light.Y] - add ebx, eax - adc ecx, edx - mov eax, ds:[si].X - imul [Light.X] - add eax, ebx - adc edx, ecx ; EDX:EAX = fixed 32:32 intensity - add dx, [AmbientLight] - test dx, dx - jg @@1 - xor dx, dx ; Return 0 for no light -@@1: - mov es:[di], dx - inc di - inc di - add si, SIZE TPOINT - dec [Count] - jnz @@Loop - - ASSUME fs:NOTHING - ret -tdTransformLight ENDP - -;----------------------------------------------------------- -; -; Returns the light value given the normal to a surface. -; -; Input: -; Normal = pointer to TPOINT surface normal vector -; Output: -; AX = light intensity (>=0) -; Notes: -; the normal is rotated according to the current setting. -; -tdGetSurfaceLight PROC PASCAL FAR - ARG Normal:DWORD - USES ds, esi, es, di - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - les di, [Normal] - -; Transform Z coordinate - mov eax, es:[di].X - imul [ZRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, es:[di].Y - imul [ZRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, es:[di].Z - imul [ZRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - imul [Light.Z] - shrd eax, edx, 16 - mov esi, eax - -; Transform X coordinate - mov eax, es:[di].X - imul [XRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, es:[di].Y - imul [XRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, es:[di].Z - imul [XRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - imul [Light.X] - shrd eax, edx, 16 - add esi, eax - -; Transform Y coordinate - mov eax, es:[di].X - imul [YRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, es:[di].Y - imul [YRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, es:[di].Z - imul [YRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - imul [Light.X] - shrd eax, edx, 16 - add eax, esi - shr eax, 16 - -; Add ambient light - add ax, [AmbientLight] - test ax, ax - jge @@Exit - xor ax, ax - -@@Exit: - ret -tdGetSurfaceLight ENDP - -;----------------------------------------------------------- -; -; Rotates an array of TPOINT. -; -; Input: -; Source = pointer to source array of TPOINT -; Dest = pointer to destination array of TPOINT -; Count = number of entries to transform -; Output: -; none -; -tdRotate PROC PASCAL FAR - ARG Source:DWORD, \ - Dest:DWORD, \ - Count:WORD - USES ds, si, es, di, fs - - mov ax, SEG MATH_DATA - mov ds, ax - ASSUME ds:MATH_DATA - - lfs si, [Source] - les di, [Dest] - -@@Loop: -; Transform Z coordinate - mov eax, fs:[si].X - imul [ZRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, fs:[si].Y - imul [ZRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, fs:[si].Z - imul [ZRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - mov es:[di].Z, eax - -; Transform X coordinate - mov eax, fs:[si].X - imul [XRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, fs:[si].Y - imul [XRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, fs:[si].Z - imul [XRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - mov es:[di].X, eax - -; Transform Y coordinate - mov eax, fs:[si].X - imul [YRotation.X] - mov ecx, eax - mov ebx, edx - mov eax, fs:[si].Y - imul [YRotation.Y] - add ecx, eax - adc ebx, edx - mov eax, fs:[si].Z - imul [YRotation.Z] - add eax, ecx - adc edx, ebx - shrd eax, edx, 16 - mov es:[di].Y, eax - - add si, SIZE TPOINT - add di, SIZE TPOINT - dec [Count] - jnz @@Loop - - ret -tdRotate ENDP - -tdFixedMul PROC PASCAL FAR - ARG F1:DWORD, \ - F2:DWORD - - mov eax, [F1] - imul [F2] - shr eax, 16 - - ret -tdFixedMul ENDP - -;----------------------------------------------------------- -; -; Returns in EAX the square root of EDX:EAX. -; -subSqrt PROC NEAR - push esi - push edi - - add eax, eax - adc edx, 0 - mov eax, edx ; Just discard the low bits - - mov esi, eax - xor edi, edi - shld edi, esi, 16 - shl esi, 16 -@@Loop: - mov ebx, eax - mul eax - add eax, esi - adc edx, edi - shrd eax, edx, 1 - shr edx, 1 - div ebx - cmp eax, ebx - jne @@Loop - -; Adjust EAX - shl eax, 8 - - pop edi - pop esi - ret -subSqrt ENDP - -;----------------------------------------------------------- -; -; Finds the unitary normal to a given surface. -; -; Input: -; Dest = pointer to TPOINT (vector) result -; P1, P2, P3 = pointer to TPOINT points on surface -; Output: -; none -; Notes: -; the normal is given by the cross-product between (P3-P1) and -; (P2-P1), so its orientation depends on the parameters order. -; -tdGetNormal PROC PASCAL FAR - ARG Dest:DWORD, \ - P1:DWORD, \ - P2:DWORD, \ - P3:DWORD - LOCAL V1:TPOINT, \ - V2:TPOINT, \ - N:TPOINT - USES ds, si, es, di - -; Get vector V1 - lds si, [P1] - les di, [P3] - mov eax, es:[di].X - sub eax, ds:[si].X - mov [V1.X], eax - mov eax, es:[di].Y - sub eax, ds:[si].Y - mov [V1.Y], eax - mov eax, es:[di].Z - sub eax, ds:[si].Z - mov [V1.Z], eax - -; Get vector V2 - les di, [P2] - mov eax, es:[di].X - sub eax, ds:[si].X - mov [V2.X], eax - mov eax, es:[di].Y - sub eax, ds:[si].Y - mov [V2.Y], eax - mov eax, es:[di].Z - sub eax, ds:[si].Z - mov [V2.Z], eax - -; Get normal vector (V1 x V2) - mov eax, [V1.Z] - imul [V2.Y] - mov ebx, eax - mov ecx, edx - mov eax, [V1.Y] - imul [V2.Z] - sub eax, ebx - sbb edx, ecx - shrd eax, edx, 16 - mov [N.X], eax - - mov eax, [V1.X] - imul [V2.Z] - mov ebx, eax - mov ecx, edx - mov eax, [V1.Z] - imul [V2.X] - sub eax, ebx - sbb edx, ecx - shrd eax, edx, 16 - mov [N.Y], eax - - mov eax, [V1.Y] - imul [V2.X] - mov ebx, eax - mov ecx, edx - mov eax, [V1.X] - imul [V2.Y] - sub eax, ebx - sbb edx, ecx - shrd eax, edx, 16 - mov [N.Z], eax - -; Get normal length - mov eax, [N.X] - imul eax - mov ebx, eax - mov ecx, edx - mov eax, [N.Y] - imul eax - add ebx, eax - adc ecx, edx - mov eax, [N.Z] - imul eax - add eax, ebx - adc edx, ecx ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z - call subSqrt ; EAX = normal length - mov ebx, eax - -; Adjust vector and save it - les di, [Dest] - mov eax, [N.X] - cdq - shld edx, eax, 16 - shl eax, 16 - idiv ebx - mov es:[di].X, eax - mov eax, [N.Y] - cdq - shld edx, eax, 16 - shl eax, 16 - idiv ebx - mov es:[di].Y, eax - mov eax, [N.Z] - cdq - shld edx, eax, 16 - shl eax, 16 - idiv ebx - mov es:[di].Z, eax - - ret -tdGetNormal ENDP - -TPOLY STRUC - Vtx DW 4 DUP(?) -TPOLY ENDS - -;----------------------------------------------------------- -; -; Performs surface removal on an array of polygons. -; -; Input: -; Poly = pointer to an array of TPOLY -; Vertex = pointer to an array of TPOINT -; Dest = pointer to an array of integer -; Count = number of polygons to check -; Step = size of TPOLY structure -; Output: -; if the n-th polygon is invisible the n-th entry of the -; Dest array is set to -1, other entries are not modified -; (so it's possible to use the Light array for Dest, because -; the light intensity is always >= 0) -; -tdBackPlaneCull PROC PASCAL FAR - ARG Step:WORD, \ - Poly:DWORD, \ - Vertex:DWORD, \ - Dest:DWORD, \ - Count:WORD - USES ds, si, es, di, fs - ASSUME ds:NOTHING - - mov ds, WORD PTR Vertex[2] - les di, [Poly] - mov fs, WORD PTR Dest[2] - -@@Loop: - mov ax, es:[di].Vtx[2] ; Index of 2nd vertex - shl ax, 2 - mov bx, ax - shl ax, 1 - add bx, ax ; BX = index*SIZE TPOINT - add bx, WORD PTR [Vertex] ; BX = offset of 2nd vertex - mov ax, es:[di].Vtx[4] ; Index of 3rd vertex - shl ax, 2 - mov si, ax - shl ax, 1 - add si, ax - add si, WORD PTR [Vertex] ; SI = offset of 3rd vertex - mov ecx, ds:[si].X - sub ecx, ds:[bx].X ; ECX = V3.X-V2.X - mov edx, ds:[si].Y - sub edx, ds:[bx].Y ; EDX = V3.Y-V2.Y - mov ax, es:[di].Vtx[0] ; Index of 1st vertex - shl ax, 2 - mov si, ax - shl ax, 1 - add si, ax - add si, WORD PTR [Vertex] ; SI = offset of 1st vertex - mov eax, ds:[si].X - sub eax, ds:[bx].X ; EAX = V1.X-V2.X - mov esi, ds:[si].Y - sub esi, ds:[bx].Y ; ESI = V1.Y-V2.Y - imul edx - mov ebx, eax - xchg ecx, edx ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y) - mov eax, esi - imul edx ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X) - sub eax, ebx - sbb edx, ecx - jl @@Next ; Polygon is visible - mov bx, WORD PTR [Dest] ; FS:BX -> current Dest entry - mov WORD PTR fs:[bx], -1 ; Remove polygon -@@Next: - add WORD PTR [Dest], 2 ; Next entry for dest - add di, [Step] ; Next polygon - dec [Count] - jnz @@Loop - - ret -tdBackPlaneCull ENDP - -MATH_TEXT ENDS -END