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