home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / F_IMATH.ZIP / MATH.INC < prev    next >
Encoding:
Text File  |  1995-01-03  |  79.6 KB  |  3,116 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : Math.inc
  4. ; Description  : General 3D math functions.
  5. ;
  6. ; Written by: John McCarthy
  7. ;             1316 Redwood Lane
  8. ;             Pickering, Ontario.
  9. ;             Canada, Earth, Milky Way (for those out-of-towners)
  10. ;             L1X 1C5
  11. ;
  12. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  13. ;         Fidonet:  Brian McCarthy 1:229/15
  14. ;   RIME/Relaynet: ->CRS
  15. ;
  16. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  17. ;
  18. ; Send me your protected mode source code!
  19. ; Send me your Objects!
  20. ; But most of all, Send me a postcard!!!!
  21. ;
  22. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  23.  
  24.          public _rotate_point               ; _rotate_point using _vmatrix
  25.          public _user3d                     ; calculate 3d ?actual*?/z (both x and y)
  26.          public _user3dx                    ; xactual*x/z
  27.          public _user3dy                    ; yactual*y/z
  28.          public _rotate_by_camera           ; 32 bit _rotate_point using _ematrix
  29.          public _zsolve                     ; solve single equation variable
  30.          public _ysolve
  31.          public _xsolve
  32.          public _cosine
  33.          public _sine
  34.          public _arctan
  35.          public _compound                   ; generate rotation matrix (includes camera)
  36.          public _setsincose                 ; set camera matrix
  37.          public _temp_matrix                ; set user defined/temporary matrix
  38.          public _temp_rotate_point          ; rotate point by temp matrix (tmatrix)
  39.          public _matrix_multiply            ; multiply _tmatrix by _vmatrix
  40.          public _null_y_matrix
  41.          public _inverse_rotate
  42.          public _rotate_x
  43.          public _rotate_y
  44.          public _rotate_z
  45.          public _point_z                    ; align z angle to point EBX,ECX and EBP
  46.          public _sqrt                       ; eax=sqr(eax), thanks to TRAN!
  47.  
  48.          public _pre_cal_lambert            ; scan object si and calculate surface normals
  49.          public _calc_normal                ; guess...from 3 points, returns vector ebx,ecx,ebp
  50.          public _calc_d                     ; calculate D from plane equation
  51.          public _lambert                    ; calculate surface normal rotation matrix for object si
  52.          public _set_up_all_lambert         ; scans objects from si to di and calls _pre_cal_lambert
  53.          public _l_rotate_point             ; given normal for surface, figures out intensity
  54.  
  55.          public _lx1                        ; points to load up before calling _calc_normal
  56.          public _ly1
  57.          public _lz1
  58.          public _lx2
  59.          public _ly2
  60.          public _lz2
  61.          public _lx3
  62.          public _ly3
  63.          public _lz3
  64.  
  65.          align 4
  66.  
  67. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  68. ;
  69. ; _rotate_point - 32 bit _rotate_point point using _vmatrix
  70. ; In:
  71. ;    EBX - x point
  72. ;    ECX - y point
  73. ;    EBP - z point
  74. ;     _vmatrix - 32 bit rotation matrix - set up by "_compound" routine
  75. ; Out:
  76. ;    EBX - x point
  77. ;    ECX - y point
  78. ;    EBP - z point
  79. ;
  80. ; Notes:
  81. ;
  82. ; All rotations (_rotate_by_camera,_rotate_point,_temp_rotate_point) are 32 bit.
  83. ; _f_rotate_point uses rotation along a plane and uses _ematrix with _precal147
  84. ;
  85. ; point rotation
  86. ; ebx = x   ecx = y   ebp = z    32 bit rotation!
  87. ; clobbers edx,esi,eax
  88. ;
  89. ; remember , matrix offsets are:
  90. ;
  91. ;  0 1 2     multiply those by 4 for the word address of the matrix
  92. ;  3 4 5
  93. ;  6 7 8
  94. ;
  95. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  96.  
  97. _rotate_point:
  98.          mov eax,_vmatrix+8                 ; solve x = bx(0)+cx(1)+bp(2)
  99.          imul ebp
  100.          shrd eax,edx,14
  101.          mov edi,eax
  102.          mov eax,_vmatrix+4
  103.          imul ecx
  104.          shrd eax,edx,14
  105.          add edi,eax
  106.          mov eax,_vmatrix+0
  107.          imul ebx
  108.          shrd eax,edx,14
  109.          add edi,eax                        ; di = new x
  110.  
  111.          mov eax,_vmatrix+20                ; solve y = bx(3)+cx(4)+bp(5)
  112.          imul ebp
  113.          shrd eax,edx,14
  114.          mov esi,eax
  115.          mov eax,_vmatrix+16
  116.          imul ecx
  117.          shrd eax,edx,14
  118.          add esi,eax
  119.          mov eax,_vmatrix+12
  120.          imul ebx
  121.          shrd eax,edx,14
  122.          add esi,eax                        ; si = new y
  123.  
  124.          mov eax,_vmatrix+32                ; solve z = bx(6)+cx(7)+bp(8)
  125.          imul ebp
  126.          shrd eax,edx,14
  127.          mov ebp,eax
  128.          mov eax,_vmatrix+28
  129.          imul ecx
  130.          shrd eax,edx,14
  131.          add ebp,eax
  132.          mov eax,_vmatrix+24
  133.          imul ebx
  134.          shrd eax,edx,14
  135.          add ebp,eax                        ; bp = new z
  136.  
  137.          mov ecx,esi
  138.          mov ebx,edi
  139.  
  140.          ret
  141.  
  142. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  143. ;
  144. ; _user3d - scale 3d point into 2d point
  145. ; In:
  146. ;    EBX - x point
  147. ;    ECX - y point
  148. ;    EBP - z point
  149. ; Out:
  150. ;    EBX - x point
  151. ;    ECX - y point
  152. ;    EBP - z point
  153. ;
  154. ; Notes:
  155. ;
  156. ; fast ratios found in macros.inc since
  157. ; multiplication has been substituted with fast lea
  158. ;
  159. ; trashes eax,edx,edi
  160. ;
  161. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  162.  
  163. _user3d:                                    ; bp must always be non-zero
  164.          cmul eax,ebx,ratiox                ; use fast constant multiply
  165.  
  166.          idiv ebp
  167.          mov ebx,eax
  168.  
  169. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  170. ;
  171. ; _user3dy - scale 3d point into 2d point on x axis only
  172. ; In:
  173. ;    ECX - y point
  174. ;    EBP - z point
  175. ; Out:
  176. ;    ECX - y point
  177. ;    EBP - z point
  178. ;
  179. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  180. _user3dy:
  181.          cmul eax,ecx,ratioy
  182.  
  183.          idiv ebp
  184.          mov ecx,eax
  185.  
  186.          ret
  187.  
  188. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  189. ;
  190. ; _user3dx - scale 3d point into 2d point on y axis only
  191. ; In:
  192. ;    EDI - x point
  193. ;    ESI - z point
  194. ; Out:
  195. ;    EDI - x point
  196. ;    ESI - z point
  197. ;
  198. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  199.  
  200. _user3dx:                                   ; bp must always be non-zero
  201.          cmul eax,edi,ratiox
  202.  
  203.          idiv esi
  204.          mov edi,eax
  205.  
  206.          ret
  207.  
  208. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  209. ;
  210. ; Checkfront: checks if a side is visible. (counter-clockwise)
  211. ;
  212. ; In:
  213. ;   (EDI,EBP) - xy of point 1
  214. ;   (ESI,ECX) - xy of point 2
  215. ;   (EDX,EBX) - xy of point 3
  216. ; Out:
  217. ;   ECX < 0 if side counter-clockwise
  218. ;
  219. ; Notes: routine courtesy of "RAZOR"
  220. ; eg:
  221. ;          call checkfront
  222. ;          cmp ecx,0
  223. ;          jng dontdraw
  224. ;
  225. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  226.  
  227.  
  228.          align 4
  229.  
  230. checkfront:
  231.          cmp edi,esi
  232.          jng s cfc
  233.          mov eax,edi
  234.          mov edi,esi
  235.          mov esi,edx
  236.          mov edx,eax
  237.          mov eax,ebp
  238.          mov ebp,ecx
  239.          mov ecx,ebx
  240.          mov ebx,eax
  241. cfc:
  242.          mov eax,edx                        ; ax = x3
  243.          sub eax,edi                        ; ax = x3 - _x1
  244.          sub ecx,ebp                        ; cx = _y2 - _y1
  245.          imul ecx                           ; ax = (x3-_x1)*(_y2-_y1)
  246.          mov ecx,eax                        ; save it...
  247.          mov eax,esi                        ; ax = _x2
  248.          sub eax,edi                        ; ax = _x2 - _x1
  249.          sub ebx,ebp                        ; bx = y3 - _y1
  250.          imul ebx                           ; ax = (_x2-_x1)*(y3-_y1)
  251.          sub ecx,eax                        ; cx = (x3-_x1)*(_y2-_y1)-(_x2-_x1)*(y3-_y1)
  252.          ret
  253.  
  254. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  255. ;
  256. ; _rotate_by_camera - 32 bit _rotate_point point using _ematrix
  257. ; In:
  258. ;    EBX - x point
  259. ;    ECX - y point
  260. ;    EBP - z point
  261. ;     _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  262. ; Out:
  263. ;    EBX - x point
  264. ;    ECX - y point
  265. ;    EBP - z point
  266. ;
  267. ; Notes:
  268. ;
  269. ; point rotation for eye - solves all x,y,z parameters
  270. ; camera rotation is 32 bit and uses _ematrix
  271. ;
  272. ; remember , matrix offsets are:
  273. ;
  274. ;  0 1 2     multiply those by 4 for the doubleword address of the matrix
  275. ;  3 4 5
  276. ;  6 7 8
  277. ;
  278. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  279.  
  280.          align 4
  281.  
  282. _rotate_by_camera:
  283.          mov eax,_ematrix+8
  284.          imul ebp
  285.          shrd eax,edx,14
  286.          mov edi,eax
  287.          if usez eq yes
  288.          mov eax,_ematrix+4
  289.          imul ecx
  290.          shrd eax,edx,14
  291.          add edi,eax
  292.          endif
  293.          mov eax,_ematrix+0
  294.          imul ebx
  295.          shrd eax,edx,14
  296.          add edi,eax                        ; di = new x
  297.  
  298.          mov eax,_ematrix+20
  299.          imul ebp
  300.          shrd eax,edx,14
  301.          mov esi,eax
  302.          mov eax,_ematrix+16
  303.          imul ecx
  304.          shrd eax,edx,14
  305.          add esi,eax
  306.          mov eax,_ematrix+12
  307.          imul ebx
  308.          shrd eax,edx,14
  309.          add esi,eax                        ; si = new y
  310.  
  311.          mov eax,_ematrix+32
  312.          imul ebp
  313.          shrd eax,edx,14
  314.          mov ebp,eax
  315.          mov eax,_ematrix+28
  316.          imul ecx
  317.          shrd eax,edx,14
  318.          add ebp,eax
  319.          mov eax,_ematrix+24
  320.          imul ebx
  321.          shrd eax,edx,14
  322.          add ebp,eax                        ; bp = new z
  323.  
  324.          mov ecx,esi
  325.          mov ebx,edi
  326.  
  327.          ret
  328.  
  329. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  330. ;
  331. ; _zsolve - 32 bit rotate point using _ematrix - solve one variable only
  332. ; In:
  333. ;    EBX - x point
  334. ;    ECX - y point
  335. ;    EBP - z point
  336. ;    _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  337. ;
  338. ; Out:
  339. ;    EBX - x point (same as entry)
  340. ;    ECX - y point (same as entry)
  341. ;    EBP - z point (same as entry)
  342. ;    ESI - new z point/location
  343. ;
  344. ; Notes:
  345. ;
  346. ; solve z from _ematrix - same as above _rotate_by_camera but only solves z for fast
  347. ; test of where object is - result is in esi
  348. ;
  349. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  350.  
  351.          align 4
  352.  
  353. _zsolve:
  354.          mov eax,_ematrix+32
  355.          imul ebp
  356.          shrd eax,edx,14
  357.          mov esi,eax
  358.          mov eax,_ematrix+28
  359.          imul ecx
  360.          shrd eax,edx,14
  361.          add esi,eax
  362.          mov eax,_ematrix+24
  363.          imul ebx
  364.          shrd eax,edx,14
  365.          add esi,eax                        ; si = new z
  366.          ret
  367.  
  368. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  369. ;
  370. ; _xsolve - 32 bit rotate point using _ematrix - solve one variable only
  371. ; In:
  372. ;    EBX - x point
  373. ;    ECX - y point
  374. ;    EBP - z point
  375. ;    _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  376. ;
  377. ; Out:
  378. ;    EBX - x point (same as entry)
  379. ;    ECX - y point (same as entry)
  380. ;    EBP - z point (same as entry)
  381. ;    EDI - new x point/location
  382. ;
  383. ; Notes:
  384. ; If object z test from above routine is positive, this routine will solve
  385. ; the rest of the rotation matrix.  this is so we don't waste time solving
  386. ; for x and y locations if the object is behind the camera anyway.
  387. ; Saves imuls.
  388. ;
  389. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  390.  
  391.          align 4
  392. _xsolve:
  393.          mov eax,_ematrix+8
  394.          imul ebp
  395.          shrd eax,edx,14
  396.          mov edi,eax
  397.          if usez eq yes
  398.          mov eax,_ematrix+4
  399.          imul ecx
  400.          shrd eax,edx,14
  401.          add edi,eax
  402.          endif
  403.          mov eax,_ematrix+0
  404.          imul ebx
  405.          shrd eax,edx,14
  406.          add edi,eax                        ; di = new x
  407.          ret
  408.  
  409. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  410. ;
  411. ; _ysolve - 32 bit rotate point using _ematrix - solve one variable only
  412. ; In:
  413. ;    EBX - x point
  414. ;    ECX - y point
  415. ;    EBP - z point
  416. ;    ESI - new z point
  417. ;    EDI - new x point
  418. ;    _ematrix - 32 bit rotation matrix - set up by "_setsincose" routine
  419. ;
  420. ; Out:
  421. ;    EBX - x new point from EDI
  422. ;    ECX - y new point
  423. ;    EBP - z new point from ESI
  424. ;
  425. ; Notes:
  426. ;
  427. ; Solve y from _ematrix - same as above _xsolve but solves y for fast
  428. ; test of where object is.  Final variables are then cleaned up to
  429. ; immitate the _rotate_by_camera function in parts.
  430. ;
  431. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  432.  
  433.          align 4
  434. _ysolve:
  435.          mov eax,_ematrix+16
  436.          imul ecx
  437.          shrd eax,edx,14
  438.          mov ecx,eax
  439.          mov eax,_ematrix+12
  440.          imul ebx
  441.          shrd eax,edx,14
  442.          add ecx,eax
  443.          mov eax,_ematrix+20
  444.          imul ebp
  445.          shrd eax,edx,14
  446.          add ecx,eax                        ; cx = new y
  447.  
  448.          mov ebx,edi                        ; final test, move into appropriate regs
  449.          mov ebp,esi
  450.  
  451.          ret
  452.  
  453. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  454. ;
  455. ;   _sine - 16 bit theta to 32bit sin(@)
  456. ; In:
  457. ;     AX - theta  0 - 65536 (0-360)
  458. ; Out:
  459. ;    EAX - sin (@)   (-4000h to 4000h)
  460. ;
  461. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  462. ;
  463. ; _cosine - 16 bit theta to 32bit cos(@)
  464. ; In:
  465. ;     AX - theta  0 - 65536 (0-360)
  466. ; Out:
  467. ;    EAX - cos (@)   (-4000h to 4000h)
  468. ;
  469. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  470. ;
  471. ; Notes:
  472. ; calculate sin into eax, from ax, smashes bx
  473. ; after imul by sin, shr eax,14 to compensate for decimal factor!
  474. ;  eg:
  475. ;    mov eax,sin(@)
  476. ;    mov ebx,32bitnumber
  477. ;    imul ebx
  478. ;    shrd eax,edx,14
  479. ;    eax = ebx*sin(@)
  480. ;
  481. ;    mov ax,sin(@)
  482. ;    mov bx,16bitnumber
  483. ;    imul bx
  484. ;    shrd ax,dx,14
  485. ;    eax = bx*sin(@)
  486. ;
  487. ; eax is only a sign extended ax and will contain either ffffxxxx or 0000xxxx
  488. ;
  489. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  490.  
  491.          align 4
  492.  
  493. _cosine:
  494.          add ax,4000h
  495. _sine:
  496.          shr ax,2
  497.          cmp ax,2000h
  498.          jge s q3o4                         ; quadrant 3 or 4
  499.  
  500.          cmp ax,1000h
  501.          jl s q0                            ; quad 1
  502.  
  503.          mov ebx,1fffh
  504.          sub bx,ax
  505.          jmp s half_sine                    ; quad 2
  506. q0:
  507.          movzx ebx,ax
  508.          jmp s half_sine
  509. q3o4:
  510.          cmp ax,3000h
  511.          jl s q3
  512.          mov ebx,3fffh
  513.          sub bx,ax
  514.          call half_sine                     ; quad 4
  515.          neg eax
  516.          ret
  517. q3:
  518.          and ax,0fffh
  519.          movzx ebx,ax                       ; quad 3
  520.          call half_sine
  521.          neg eax
  522.          ret
  523. half_sine:
  524.          xor eax,eax
  525.          mov ax,w sinus[ebx*2]
  526.          ret
  527.  
  528. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  529. ;
  530. ; Arctan - 32 bit rise/run to 16bit arctan(rise/run)
  531. ; In:
  532. ;    EAX - Run
  533. ;    ECX - Rise
  534. ; Out:
  535. ;     AX - arctan(ECX/EAX)
  536. ;
  537. ; Notes:
  538. ; smashes cx,ax,dx,si
  539. ; arctan(ecx/0) is valid and tested for
  540. ;
  541. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  542.  
  543.          align 4
  544.  
  545. _arctan:
  546.          or eax,eax
  547.          jl s qd2or3
  548.          je findmax
  549.          or ecx,ecx
  550.          jge s halftax                      ; quadrant 1
  551.          neg ecx                            ; quadrant 4, ax=-ax
  552.          call halftan
  553.          neg ax
  554.          shl eax,2
  555.          ret
  556. qd2or3:
  557.          neg eax
  558.          or ecx,ecx
  559.          jge s qd2
  560.          neg ecx                            ; quad 3, ax=ax+8192
  561.          call halftan
  562.          add ax,8192
  563.          shl eax,2
  564.          ret
  565. qd2:
  566.          call halftan
  567.          neg ax
  568.          add ax,8192
  569.          shl eax,2
  570.          ret
  571. halftax:
  572.          call halftan
  573.          shl eax,2
  574.          ret
  575.  
  576.          align 4
  577.  
  578. halftan:
  579.          xor edx,edx
  580.  
  581. ; cx=rise  positive
  582. ; ax=run   positive
  583.  
  584.          cmp eax,ecx
  585.          jl s opptan                        ; greater than 45 degrees, other side...
  586.  
  587.          xchg ecx,eax                       ; ax<cx
  588.          shld edx,eax,11                    ; *2048 edx = high dword for divide
  589.          shl eax,11                         ; *2048
  590.          div ecx
  591.          movzx esi,ax
  592.          mov ax,w negtan[esi*2]             ; resulting angle (0-512 is 0-45) in ax
  593.          ret
  594.  
  595.          align 4
  596.  
  597. opptan:
  598.          shld edx,eax,11                    ; *2048 edx = high dword for divide
  599.          shl eax,11                         ; *2048
  600.  
  601.          div ecx
  602.          movzx esi,ax                       ; ax remainder
  603.          mov cx,w negtan[esi*2]
  604.          mov eax,1000h
  605.          sub ax,cx                          ; resulting angle (2048-4096 is 45-90) in ax
  606.          ret
  607.  
  608. findmax:
  609.          mov eax,16384
  610.          or ecx,ecx
  611.          jge _ret
  612.          neg eax
  613.          ret
  614.  
  615.          align 4
  616.  
  617. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  618. ;
  619. ; _compound - generate object matrix, 12 imul's first
  620. ; In:
  621. ;    ESI - Object # to get angles from
  622. ;    v_vxs[esi*2] - object x angle (0-65536)
  623. ;    v_vys[esi*2] - object y angle (0-65536)
  624. ;    v_vzs[esi*2] - object z angle (0-65536)
  625. ; Out:
  626. ;    _vmatrix - resulting rotation matrix including camera matrix
  627. ;    ESI = ESI
  628. ;
  629. ; Notes:
  630. ;              x                         y                      z
  631. ;
  632. ;x=  cz * cy - sx * sy * sz   - sz * cy - sx * sy * cz     - cx * sy
  633. ;
  634. ;y=         sz * cx                   cx * cz                - sx
  635. ;
  636. ;z=  cz * sy + sx * sz * cy   - sy * sz + sx * cy * cz       cx * cy
  637. ;
  638. ;then perform matrix multiply by negative x and z matricies
  639. ;
  640. ; -x matrix                             -z matrix
  641. ;     x       y       z                   x       y       z
  642. ;
  643. ;x    1       0       0                cz     sz       0
  644. ;
  645. ;y    0      cx       sx              -sz     cz       0
  646. ;
  647. ;z    0     -sx       cx                0      0       1
  648. ;
  649. ; Notice original object matrix takes 12 imuls, camera modify takes 24, can
  650. ; you do this faster? (less imuls)
  651. ;
  652. ; A call to _setsincose MUST have taken place for this routine to calculate
  653. ; the camera matrix correctly.
  654. ;
  655. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  656.  
  657. _compound:
  658.          push esi
  659.  
  660.          mov ax,v_vxs[esi*2]
  661.          neg ax
  662.          push eax
  663.          call _cosine
  664.          mov vcosx,eax
  665.          pop eax
  666.          call _sine
  667.          mov vsinx,eax
  668.          mov ebp,eax                        ; bp = sx
  669.          neg eax
  670.          mov [_vmatrix+20],eax
  671.  
  672.          mov ax,v_vzs[esi*2]
  673.          neg ax
  674.          push eax
  675.          call _cosine
  676.          mov vcosz,eax
  677.          mov edi,eax                        ; di = cz
  678.          pop eax
  679.          call _sine
  680.          mov vsinz,eax
  681.          mov edx,eax                        ; dx = sz
  682.  
  683.          mov ax,v_vys[esi*2]
  684.          neg ax
  685.          add ax,eyeay
  686.          push eax
  687.          call _cosine
  688.          mov vcosy,eax
  689.          pop eax
  690.          call _sine
  691.          mov vsiny,eax                      ; ax = sy
  692.  
  693.          mov ebx,edx                        ; save sz
  694.  
  695.          mov ecx,eax                        ; save sy
  696.  
  697.          imul ebx                           ; bx = - sy * sz
  698.          shrd eax,edx,14
  699.          mov ebx,eax
  700.          neg ebx
  701.          mov [_vmatrix+28],ebx
  702.  
  703.          mov eax,ecx                        ; si = cz * sy
  704.          imul edi
  705.          shrd eax,edx,14
  706.          mov esi,eax
  707.          mov [_vmatrix+24],esi
  708.  
  709.          mov eax,vcosy
  710.  
  711.          imul edi                           ; di = cy * cz
  712.          shrd eax,edx,14
  713.          mov edi,eax
  714.          mov [_vmatrix+0],edi
  715.  
  716.          mov eax,vsinz
  717.          mov ecx,vcosy
  718.  
  719.          imul ecx                           ; cx = - sz * cy
  720.          shrd eax,edx,14
  721.          mov ecx,eax
  722.          neg ecx
  723.          mov [_vmatrix+4],ecx
  724.  
  725.          mov eax,ebp
  726.          imul esi
  727.          shrd eax,edx,14
  728.          mov esi,eax
  729.          neg esi
  730.          add [_vmatrix+4],esi
  731.  
  732.          mov eax,ebp
  733.          imul edi
  734.          shrd eax,edx,14
  735.          mov edi,eax
  736.          add [_vmatrix+28],edi
  737.  
  738.          mov eax,ebp
  739.          imul ebx
  740.          shrd eax,edx,14
  741.          mov ebx,eax
  742.          add [_vmatrix+0],ebx
  743.  
  744.          mov eax,ebp
  745.          imul ecx
  746.          shrd eax,edx,14
  747.          mov ecx,eax
  748.          neg ecx
  749.          add [_vmatrix+24],ecx
  750.  
  751.          mov esi,vcosx
  752.  
  753.          mov eax,vcosy
  754.          imul esi                           ; cx * cy
  755.          shrd eax,edx,14
  756.          mov [_vmatrix+32],eax
  757.  
  758.          mov eax,vsiny
  759.          imul esi                           ;-cx * sy
  760.          shrd eax,edx,14
  761.          neg eax
  762.          mov [_vmatrix+8],eax
  763.  
  764.          mov eax,vsinz
  765.          imul esi                           ; cx * sz
  766.          shrd eax,edx,14
  767.          mov [_vmatrix+12],eax
  768.  
  769.          mov eax,vcosz
  770.          imul esi                           ; cx * cz
  771.          shrd eax,edx,14
  772.          mov [_vmatrix+16],eax
  773.  
  774.          mov edi,_ecosx                      ; now perform camera x rotation,12 imuls
  775.          mov esi,_esinx
  776.          mov ebp,esi
  777.          neg ebp
  778.  
  779.          mov eax,[_vmatrix+12]
  780.          imul edi
  781.          shrd eax,edx,14
  782.          mov ecx,eax
  783.  
  784.          mov eax,[_vmatrix+24]
  785.          imul esi
  786.          shrd eax,edx,14
  787.  
  788.          add ecx,eax                        ; ecx = new _vmatrix+12
  789.  
  790.          mov eax,[_vmatrix+12]
  791.          imul ebp
  792.          shrd eax,edx,14
  793.          mov ebx,eax
  794.  
  795.          mov eax,[_vmatrix+24]
  796.          imul edi
  797.          shrd eax,edx,14
  798.  
  799.          add ebx,eax                        ; ebx = new _vmatrix+24
  800.  
  801.          mov [_vmatrix+12],ecx
  802.          mov [_vmatrix+24],ebx
  803.  
  804.          mov eax,[_vmatrix+16]
  805.          imul edi
  806.          shrd eax,edx,14
  807.          mov ecx,eax
  808.  
  809.          mov eax,[_vmatrix+28]
  810.          imul esi
  811.          shrd eax,edx,14
  812.  
  813.          add ecx,eax                        ; ecx = new _vmatrix+16
  814.  
  815.          mov eax,[_vmatrix+16]
  816.          imul ebp
  817.          shrd eax,edx,14
  818.          mov ebx,eax
  819.  
  820.          mov eax,[_vmatrix+28]
  821.          imul edi
  822.          shrd eax,edx,14
  823.  
  824.          add ebx,eax                        ; ebx = new _vmatrix+28
  825.  
  826.          mov [_vmatrix+16],ecx
  827.          mov [_vmatrix+28],ebx
  828.  
  829.          mov eax,[_vmatrix+20]
  830.          imul edi
  831.          shrd eax,edx,14
  832.          mov ecx,eax
  833.  
  834.          mov eax,[_vmatrix+32]
  835.          imul esi
  836.          shrd eax,edx,14
  837.  
  838.          add ecx,eax                        ; ecx = new _vmatrix+20
  839.  
  840.          mov eax,[_vmatrix+20]
  841.          imul ebp
  842.          shrd eax,edx,14
  843.          mov ebx,eax
  844.  
  845.          mov eax,[_vmatrix+32]
  846.          imul edi
  847.          shrd eax,edx,14
  848.  
  849.          add ebx,eax                        ; ebx = new _vmatrix+32
  850.  
  851.          mov [_vmatrix+20],ecx
  852.          mov [_vmatrix+32],ebx
  853.  
  854.          if usez eq yes
  855.          cmp eyeaz,0
  856.          je cp_noz
  857.  
  858.          mov edi,_ecosz                      ; now perform camera z rotation,12 imuls
  859.          mov esi,_esinz
  860.          mov ebp,esi
  861.          neg esi
  862.  
  863.          mov eax,[_vmatrix+0]
  864.          imul edi
  865.          shrd eax,edx,14
  866.          mov ecx,eax
  867.  
  868.          mov eax,[_vmatrix+12]
  869.          imul esi
  870.          shrd eax,edx,14
  871.  
  872.          add ecx,eax
  873.  
  874.          mov eax,[_vmatrix+0]
  875.          imul ebp
  876.          shrd eax,edx,14
  877.          mov ebx,eax
  878.  
  879.          mov eax,[_vmatrix+12]
  880.          imul edi
  881.          shrd eax,edx,14
  882.  
  883.          add ebx,eax
  884.  
  885.          mov [_vmatrix+0],ecx
  886.          mov [_vmatrix+12],ebx
  887.  
  888.          mov eax,[_vmatrix+4]
  889.          imul edi
  890.          shrd eax,edx,14
  891.          mov ecx,eax
  892.  
  893.          mov eax,[_vmatrix+16]
  894.          imul esi
  895.          shr eax,14
  896.          movsx eax,ax
  897.  
  898.          add ecx,eax
  899.  
  900.          mov eax,[_vmatrix+4]
  901.          imul ebp
  902.          shrd eax,edx,14
  903.          mov ebx,eax
  904.  
  905.          mov eax,[_vmatrix+16]
  906.          imul edi
  907.          shrd eax,edx,14
  908.  
  909.          add ebx,eax
  910.  
  911.          mov [_vmatrix+4],ecx
  912.          mov [_vmatrix+16],ebx
  913.  
  914.          mov eax,[_vmatrix+8]
  915.          imul edi
  916.          shrd eax,edx,14
  917.          mov ecx,eax
  918.  
  919.          mov eax,[_vmatrix+20]
  920.          imul esi
  921.          shrd eax,edx,14
  922.  
  923.          add ecx,eax
  924.  
  925.          mov eax,[_vmatrix+8]
  926.          imul ebp
  927.          shrd eax,edx,14
  928.          mov ebx,eax
  929.  
  930.          mov eax,[_vmatrix+20]
  931.          imul edi
  932.          shrd eax,edx,14
  933.  
  934.          add ebx,eax
  935.  
  936.          mov [_vmatrix+8],ecx
  937.          mov [_vmatrix+20],ebx
  938.  
  939.          endif
  940. cp_noz:
  941.          pop esi
  942.          ret
  943.  
  944. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  945. ;
  946. ; _setsincose - generate rotation matrix for  y,x,z  camera rotation
  947. ;
  948. ; In:
  949. ;    eyeax - camera x angle (0-65536)
  950. ;    eyeay - camera y angle (0-65536)
  951. ;    eyeaz - camera z angle (0-65536)
  952. ; Out:
  953. ;    _vmatrix - resulting rotation matrix including camera matrix
  954. ;
  955. ; Notes:
  956. ; called only once every frame.  completed in 12 multiplys
  957. ; matrix is also used for objects with no rotation (always angle 0,0,0)
  958. ;
  959. ; where is my postcard! see readme.doc for info.
  960. ;
  961. ;              x                    y                    z
  962. ;
  963. ; x=  cz * cy + sx * sy * sz     -cx * sz     - sy * cz + sx * cy * sz
  964. ;
  965. ; y=  sz * cy - sx * sy * cz      cx * cz     - sy * sz - sx * cy * cz
  966. ;
  967. ; z=         cx * sy                 sx                cx * cy
  968. ;
  969. ;
  970. ;  matrix offsets: (doublewords)
  971. ;
  972. ;     x  y  z
  973. ;
  974. ; x    0  4  8
  975. ; y   12 16 20
  976. ; z   24 28 32
  977. ;
  978. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  979.  
  980.          align 4
  981.  
  982. _setsincose:
  983.          mov ax,eyeax
  984.          call _cosine
  985.          mov _ecosx,eax                     ; _ecosx and such are used by object rotation
  986.          mov ax,eyeax                      ; _ematrix is used to find where object is
  987.          call _sine
  988.          mov _esinx,eax
  989.          mov [_ematrix+28],eax
  990.          mov ebp,eax                        ; bp = sx
  991.  
  992.          if usez eq yes
  993.          mov ax,eyeaz
  994.          call _cosine
  995.          mov _ecosz,eax
  996.          mov edi,eax                        ; di = cz
  997.          mov ax,eyeaz
  998.          call _sine
  999.          mov _esinz,eax
  1000.          mov edx,eax                        ; dx = sz
  1001.          endif
  1002.  
  1003.          if usez eq no
  1004.          mov edi,4000h                      ; di = cos 0
  1005.          mov _ecosz,4000h
  1006.          xor edx,edx                        ; dx = sin 0
  1007.          mov _esinz,0
  1008.          endif
  1009.  
  1010.          mov ax,eyeay
  1011.          call _cosine
  1012.          mov _ecosy,eax
  1013.          mov ax,eyeay
  1014.          call _sine
  1015.          mov _esiny,eax                      ; ax = sy
  1016.  
  1017.          mov ebx,edx                        ; save sz
  1018.  
  1019.          mov ecx,eax                        ; save sy
  1020.  
  1021.          imul ebx                           ; bx = sy * sz
  1022.          shrd eax,edx,14
  1023.          mov ebx,eax
  1024.          neg ebx
  1025.          mov [_ematrix+20],ebx
  1026.          neg ebx
  1027.  
  1028.          mov eax,ecx                        ; si = - (cz * sy)
  1029.          imul edi
  1030.          shrd eax,edx,14
  1031.          mov esi,eax
  1032.          neg esi
  1033.          mov [_ematrix+8],esi
  1034.  
  1035.          mov eax,_ecosy
  1036.  
  1037.          imul edi                           ; di = cy * cz
  1038.          shrd eax,edx,14
  1039.          mov edi,eax
  1040.          mov [_ematrix+0],edi
  1041.  
  1042.          mov eax,_esinz
  1043.          mov ecx,_ecosy
  1044.  
  1045.          imul ecx                           ; cx = sz * cy
  1046.          shrd eax,edx,14
  1047.          mov ecx,eax
  1048.          mov [_ematrix+12],ecx
  1049.  
  1050.          mov eax,ebp
  1051.          imul esi
  1052.          shrd eax,edx,14
  1053.          mov esi,eax
  1054.          add [_ematrix+12],esi
  1055.  
  1056.          mov eax,ebp
  1057.          imul edi
  1058.          shrd eax,edx,14
  1059.          mov edi,eax
  1060.          neg edi
  1061.          add [_ematrix+20],edi
  1062.  
  1063.          mov eax,ebp
  1064.          imul ebx
  1065.          shrd eax,edx,14
  1066.          mov ebx,eax
  1067.          add [_ematrix+0],ebx
  1068.  
  1069.          mov eax,ebp
  1070.          imul ecx
  1071.          shrd eax,edx,14
  1072.          mov ecx,eax
  1073.          add [_ematrix+8],ecx
  1074.  
  1075.          mov esi,_ecosx
  1076.  
  1077.          mov eax,_ecosy
  1078.          imul esi                           ; cx * cy
  1079.          shrd eax,edx,14
  1080.          mov [_ematrix+32],eax
  1081.  
  1082.          mov eax,_esiny
  1083.          imul esi                           ; cx * sy
  1084.          shrd eax,edx,14
  1085.          mov [_ematrix+24],eax
  1086.  
  1087.          mov eax,_esinz
  1088.          imul esi                           ;-cx * sz
  1089.          shrd eax,edx,14
  1090.          neg eax
  1091.          mov [_ematrix+4],eax
  1092.  
  1093.          mov eax,_ecosz
  1094.          imul esi                           ; cx * cz
  1095.          shrd eax,edx,14
  1096.          mov [_ematrix+16],eax
  1097.  
  1098.          neg _esinx                         ; reverse angles for object rotation
  1099.          neg _esiny
  1100.  
  1101.          ret
  1102.  
  1103. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1104. ;
  1105. ; _temp_matrix: generate temp matrix, 12 imul's, from object esi
  1106. ;
  1107. ; In:
  1108. ;    ESI - Object # to get angles from
  1109. ;    v_vxs[esi*2] - object x angle (0-65536)
  1110. ;    v_vys[esi*2] - object y angle (0-65536)
  1111. ;    v_vzs[esi*2] - object z angle (0-65536)
  1112. ; Out:
  1113. ;    _tmatrix - resulting rotation matrix (excluding camera matrix)
  1114. ;    ESI = ESI
  1115. ;
  1116. ; Notes:
  1117. ;              x                         y                      z
  1118. ;
  1119. ;x=  cz * cy - sx * sy * sz   - sz * cy - sx * sy * cz     - cx * sy
  1120. ;
  1121. ;y=         sz * cx                   cx * cz                - sx
  1122. ;
  1123. ;z=  cz * sy + sx * sz * cy   - sy * sz + sx * cy * cz       cx * cy
  1124. ;
  1125. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1126.  
  1127. _temp_matrix:
  1128.          push esi
  1129.  
  1130.          mov ax,v_vxs[esi*2]
  1131.          neg ax
  1132.          push eax
  1133.          call _cosine
  1134.          mov vcosx,eax
  1135.          pop eax
  1136.          call _sine
  1137.          mov vsinx,eax
  1138.          mov ebp,eax                        ; bp = sx
  1139.          neg eax
  1140.          mov [_tmatrix+20],eax
  1141.  
  1142.          mov ax,v_vzs[esi*2]
  1143.          neg ax
  1144.          push eax
  1145.          call _cosine
  1146.          mov vcosz,eax
  1147.          mov edi,eax                        ; di = cz
  1148.          pop eax
  1149.          call _sine
  1150.          mov vsinz,eax
  1151.          mov edx,eax                        ; dx = sz
  1152.  
  1153.          mov ax,v_vys[esi*2]
  1154.          neg ax
  1155.          push eax
  1156.          call _cosine
  1157.          mov vcosy,eax
  1158.          pop eax
  1159.          call _sine
  1160.          mov vsiny,eax                      ; ax = sy
  1161.  
  1162.          mov ebx,edx                        ; save sz
  1163.  
  1164.          mov ecx,eax                        ; save sy
  1165.  
  1166.          imul ebx                           ; bx = - sy * sz
  1167.          shr eax,14
  1168.          movsx ebx,ax
  1169.          neg ebx
  1170.          mov [_tmatrix+28],ebx
  1171.  
  1172.          mov eax,ecx                        ; si = cz * sy
  1173.          imul edi
  1174.          shr eax,14
  1175.          movsx esi,ax
  1176.          mov [_tmatrix+24],esi
  1177.  
  1178.          mov eax,vcosy
  1179.  
  1180.          imul edi                           ; di = cy * cz
  1181.          shr eax,14
  1182.          movsx edi,ax
  1183.          mov [_tmatrix+0],edi
  1184.  
  1185.          mov eax,vsinz
  1186.          mov ecx,vcosy
  1187.  
  1188.          imul ecx                           ; cx = - sz * cy
  1189.          shr eax,14
  1190.          movsx ecx,ax
  1191.          neg ecx
  1192.          mov [_tmatrix+4],ecx
  1193.  
  1194.          mov eax,ebp
  1195.          imul esi
  1196.          shr eax,14
  1197.          movsx esi,ax
  1198.          neg esi
  1199.          add [_tmatrix+4],esi
  1200.  
  1201.          mov eax,ebp
  1202.          imul edi
  1203.          shr eax,14
  1204.          movsx edi,ax
  1205.          add [_tmatrix+28],edi
  1206.  
  1207.          mov eax,ebp
  1208.          imul ebx
  1209.          shr eax,14
  1210.          movsx ebx,ax
  1211.          add [_tmatrix+0],ebx
  1212.  
  1213.          mov eax,ebp
  1214.          imul ecx
  1215.          shr eax,14
  1216.          movsx ecx,ax
  1217.          neg ecx
  1218.          add [_tmatrix+24],ecx
  1219.  
  1220.          mov esi,vcosx
  1221.  
  1222.          mov eax,vcosy
  1223.          imul esi                           ; cx * cy
  1224.          shr eax,14
  1225.          movsx eax,ax
  1226.          mov [_tmatrix+32],eax
  1227.  
  1228.          mov eax,vsiny
  1229.          imul esi                           ;-cx * sy
  1230.          shr eax,14
  1231.          movsx eax,ax
  1232.          neg eax
  1233.          mov [_tmatrix+8],eax
  1234.  
  1235.          mov eax,vsinz
  1236.          imul esi                           ; cx * sz
  1237.          shr eax,14
  1238.          movsx eax,ax
  1239.          mov [_tmatrix+12],eax
  1240.  
  1241.          mov eax,vcosz
  1242.          imul esi                           ; cx * cz
  1243.          shr eax,14
  1244.          movsx eax,ax
  1245.          mov [_tmatrix+16],eax
  1246.  
  1247.          pop esi
  1248.          ret
  1249.  
  1250. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1251. ;
  1252. ; _temp_rotate_point - 32 bit _rotate_point point using _tmatrix
  1253. ; In:
  1254. ;    EBX - x point
  1255. ;    ECX - y point
  1256. ;    EBP - z point
  1257. ;     _tmatrix - 32 bit rotation matrix - set up by "_temp_matrix" routine
  1258. ; Out:
  1259. ;    EBX - x point
  1260. ;    ECX - y point
  1261. ;    EBP - z point
  1262. ;
  1263. ; Notes:
  1264. ;  Same as _rotate_point and _rotate_by_camera
  1265. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1266.  
  1267. _temp_rotate_point:
  1268.          mov eax,_tmatrix+8                 ; solve x = bx(0)+cx(1)+bp(2)
  1269.          imul ebp
  1270.          shrd eax,edx,14
  1271.          mov edi,eax
  1272.          mov eax,_tmatrix+4
  1273.          imul ecx
  1274.          shrd eax,edx,14
  1275.          add edi,eax
  1276.          mov eax,_tmatrix+0
  1277.          imul ebx
  1278.          shrd eax,edx,14
  1279.          add edi,eax                        ; di = new x
  1280.  
  1281.          mov eax,_tmatrix+20                ; solve y = bx(3)+cx(4)+bp(5)
  1282.          imul ebp
  1283.          shrd eax,edx,14
  1284.          mov esi,eax
  1285.          mov eax,_tmatrix+16
  1286.          imul ecx
  1287.          shrd eax,edx,14
  1288.          add esi,eax
  1289.          mov eax,_tmatrix+12
  1290.          imul ebx
  1291.          shrd eax,edx,14
  1292.          add esi,eax                        ; si = new y
  1293.  
  1294.          mov eax,_tmatrix+32                ; solve z = bx(6)+cx(7)+bp(8)
  1295.          imul ebp
  1296.          shrd eax,edx,14
  1297.          mov ebp,eax
  1298.          mov eax,_tmatrix+28
  1299.          imul ecx
  1300.          shrd eax,edx,14
  1301.          add ebp,eax
  1302.          mov eax,_tmatrix+24
  1303.          imul ebx
  1304.          shrd eax,edx,14
  1305.          add ebp,eax                        ; bp = new z
  1306.  
  1307.          mov ecx,esi
  1308.          mov ebx,edi
  1309.  
  1310.          ret
  1311.  
  1312. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1313. ;
  1314. ; _matrix_multiply: multiply _tmatrix by _vmatrix, [_vmatrix]=[_tmatrix][_vmatrix]
  1315. ;
  1316. ; In:
  1317. ;    _vmatrix - rotation matrix
  1318. ;    _tmatrix - rotation matrix
  1319. ; Out:
  1320. ;    _vmatrix - resulting rotation matrix
  1321. ;
  1322. ; Notes:
  1323. ;
  1324. ; [ _tmatrix+ 0 _tmatrix+ 2 _tmatrix+ 4 ] [ _vmatrix+ 0 _vmatrix+ 2 _vmatrix+ 4 ]
  1325. ; [                                  ] [                                  ]
  1326. ; [ _tmatrix+ 6 _tmatrix+ 8 _tmatrix+10 ] [ _vmatrix+ 6 _vmatrix+ 8 _vmatrix+10 ]
  1327. ; [                                  ] [                                  ]
  1328. ; [ _tmatrix+12 _tmatrix+14 _tmatrix+16 ] [ _vmatrix+12 _vmatrix+14 _vmatrix+16 ]
  1329. ;
  1330. ; Think of it this way, this routine will generate a resulting matrix as  if
  1331. ; you _rotate_pointd an  object by _tmatrix, then _rotate_pointd  the  object  by  _vmatrix.
  1332. ; Instead, call this routine then you will only have to _rotate_point the object by
  1333. ; _vmatrix!.
  1334. ;
  1335. ; Notice _tmatrix is done before _vmatrix!!  This is used for calculating the
  1336. ; positions of arms on bodies, hands on arms, fingers on hands...etc...
  1337. ;
  1338. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1339.  
  1340. _matrix_multiply:
  1341.  
  1342.          mov ebx,[_vmatrix+0]
  1343.          mov ecx,[_vmatrix+4]
  1344.          mov ebp,[_vmatrix+8]
  1345.  
  1346.          mov eax,[_tmatrix+0]
  1347.          imul ebx
  1348.          shrd eax,edx,14
  1349.          mov esi,eax
  1350.  
  1351.          mov eax,[_tmatrix+12]
  1352.          imul ecx
  1353.          shrd eax,edx,14
  1354.          add esi,eax
  1355.  
  1356.          mov eax,[_tmatrix+24]
  1357.          imul ebp
  1358.          shrd eax,edx,14
  1359.          add esi,eax
  1360.  
  1361.          push esi                           ; _tmatrix+0
  1362.  
  1363.          mov eax,[_tmatrix+4]
  1364.          imul ebx
  1365.          shrd eax,edx,14
  1366.          mov esi,eax
  1367.  
  1368.          mov eax,[_tmatrix+16]
  1369.          imul ecx
  1370.          shrd eax,edx,14
  1371.          add esi,eax
  1372.  
  1373.          mov eax,[_tmatrix+28]
  1374.          imul ebp
  1375.          shrd eax,edx,14
  1376.          add esi,eax
  1377.  
  1378.          push esi                           ; _tmatrix+4
  1379.  
  1380.          mov eax,[_tmatrix+8]
  1381.          imul ebx
  1382.          shrd eax,edx,14
  1383.          mov esi,eax
  1384.  
  1385.          mov eax,[_tmatrix+20]
  1386.          imul ecx
  1387.          shrd eax,edx,14
  1388.          add esi,eax
  1389.  
  1390.          mov eax,[_tmatrix+32]
  1391.          imul ebp
  1392.          shrd eax,edx,14
  1393.          add esi,eax
  1394.  
  1395.          push esi                           ; _tmatrix+8
  1396.  
  1397.          mov ebx,[_vmatrix+12]
  1398.          mov ecx,[_vmatrix+16]
  1399.          mov ebp,[_vmatrix+20]
  1400.  
  1401.          mov eax,[_tmatrix+0]
  1402.          imul ebx
  1403.          shrd eax,edx,14
  1404.          mov esi,eax
  1405.  
  1406.          mov eax,[_tmatrix+12]
  1407.          imul ecx
  1408.          shrd eax,edx,14
  1409.          add esi,eax
  1410.  
  1411.          mov eax,[_tmatrix+24]
  1412.          imul ebp
  1413.          shrd eax,edx,14
  1414.          add esi,eax
  1415.  
  1416.          push esi                           ; _tmatrix+12
  1417.  
  1418.          mov eax,[_tmatrix+4]
  1419.          imul ebx
  1420.          shrd eax,edx,14
  1421.          mov esi,eax
  1422.  
  1423.          mov eax,[_tmatrix+16]
  1424.          imul ecx
  1425.          shrd eax,edx,14
  1426.          add esi,eax
  1427.  
  1428.          mov eax,[_tmatrix+28]
  1429.          imul ebp
  1430.          shrd eax,edx,14
  1431.          add esi,eax
  1432.  
  1433.          push esi                           ; _tmatrix+16
  1434.  
  1435.          mov eax,[_tmatrix+8]
  1436.          imul ebx
  1437.          shrd eax,edx,14
  1438.          mov esi,eax
  1439.  
  1440.          mov eax,[_tmatrix+20]
  1441.          imul ecx
  1442.          shrd eax,edx,14
  1443.          add esi,eax
  1444.  
  1445.          mov eax,[_tmatrix+32]
  1446.          imul ebp
  1447.          shrd eax,edx,14
  1448.          add esi,eax
  1449.  
  1450.          push esi                           ; _tmatrix+20
  1451.  
  1452.          mov ebx,[_vmatrix+24]
  1453.          mov ecx,[_vmatrix+28]
  1454.          mov ebp,[_vmatrix+32]
  1455.  
  1456.          mov eax,[_tmatrix+0]
  1457.          imul ebx
  1458.          shrd eax,edx,14
  1459.          mov esi,eax
  1460.  
  1461.          mov eax,[_tmatrix+12]
  1462.          imul ecx
  1463.          shrd eax,edx,14
  1464.          add esi,eax
  1465.  
  1466.          mov eax,[_tmatrix+24]
  1467.          imul ebp
  1468.          shrd eax,edx,14
  1469.          add esi,eax
  1470.  
  1471.          push esi                           ; _tmatrix+24
  1472.  
  1473.          mov eax,[_tmatrix+4]
  1474.          imul ebx
  1475.          shrd eax,edx,14
  1476.          mov esi,eax
  1477.  
  1478.          mov eax,[_tmatrix+16]
  1479.          imul ecx
  1480.          shrd eax,edx,14
  1481.          add esi,eax
  1482.  
  1483.          mov eax,[_tmatrix+28]
  1484.          imul ebp
  1485.          shrd eax,edx,14
  1486.          add esi,eax
  1487.  
  1488.          push esi                           ; _tmatrix+28
  1489.  
  1490.          mov eax,[_tmatrix+8]
  1491.          imul ebx
  1492.          shrd eax,edx,14
  1493.          mov esi,eax
  1494.  
  1495.          mov eax,[_tmatrix+20]
  1496.          imul ecx
  1497.          shrd eax,edx,14
  1498.          add esi,eax
  1499.  
  1500.          mov eax,[_tmatrix+32]
  1501.          imul ebp
  1502.          shrd eax,edx,14
  1503.          add esi,eax
  1504.  
  1505. ;        push esi             ; _tmatrix+32
  1506.  
  1507. ;        pop esi
  1508.          mov [_vmatrix+32],esi
  1509.          pop esi
  1510.          mov [_vmatrix+28],esi
  1511.          pop esi
  1512.          mov [_vmatrix+24],esi
  1513.          pop esi
  1514.          mov [_vmatrix+20],esi
  1515.          pop esi
  1516.          mov [_vmatrix+16],esi
  1517.          pop esi
  1518.          mov [_vmatrix+12],esi
  1519.          pop esi
  1520.          mov [_vmatrix+ 8],esi
  1521.          pop esi
  1522.          mov [_vmatrix+ 4],esi
  1523.          pop esi
  1524.          mov [_vmatrix+ 0],esi
  1525.          ret
  1526.  
  1527. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1528. ;
  1529. ; _sqrt: Routine courtesy TRAN
  1530. ;
  1531. ; In:
  1532. ;   EAX - number to take root of
  1533. ; Out:
  1534. ;   EAX - root
  1535. ;
  1536. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1537. _sqrtbasetbl db 0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225
  1538.  
  1539.          align 4
  1540. _sqrt:
  1541.          pushad
  1542.          mov ebp,eax
  1543.          bsr ebx,eax
  1544.          jnz short _sqrtf0
  1545.          xor ebx,ebx
  1546. _sqrtf0:
  1547.          shr ebx,3
  1548.          lea eax,[ebx*8]
  1549.          mov cl,32
  1550.          sub cl,al
  1551.          rol ebp,cl
  1552.          mov eax,ebp
  1553.          movzx eax,al
  1554.          mov edi,offset _sqrtbasetbl
  1555.          mov ecx,10h
  1556. _sqrtl0:
  1557.          scasb
  1558.          je short _sqrtl0d
  1559.          jb short _sqrtl0d2
  1560.          loop _sqrtl0
  1561.          inc edi
  1562. _sqrtl0d2:
  1563.          dec edi
  1564.          inc cl
  1565. _sqrtl0d:
  1566.          movzx edx,byte ptr [edi-1]
  1567.          dec cl
  1568.          xor cl,0fh
  1569.          mov edi,ecx
  1570.          mov ecx,ebx
  1571.          jecxz short _sqrtdone
  1572.          sub eax,edx
  1573. _sqrtml:
  1574.          shld eax,ebp,8
  1575.          rol ebp,8
  1576.          mov ebx,edi
  1577.          shl ebx,5
  1578.          xor edx,edx
  1579.          mov esi,eax
  1580.          div ebx
  1581.          rol edi,4
  1582.          add edi,eax
  1583.          add ebx,eax
  1584. _sqrtf2:
  1585.          imul eax,ebx
  1586.          mov edx,eax
  1587.          mov eax,esi
  1588.          sub eax,edx
  1589.          jc short _sqrtf1
  1590.          loop _sqrtml
  1591. _sqrtdone:
  1592.          mov [esp+28],edi
  1593.          popad
  1594.          ret
  1595. _sqrtf1:
  1596.          dec ebx
  1597.          dec edi
  1598.          movzx eax,bl
  1599.          and al,1fh
  1600.          jmp _sqrtf2
  1601.  
  1602. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1603. ;
  1604. ; _lambert: generate _lambert shading 1x3 matrix, completed in 6 imuls
  1605. ;
  1606. ; In:
  1607. ;    ESI - Object # to get angles from
  1608. ;    v_vxs[esi*2] - object x angle (0-65536)
  1609. ;    v_vys[esi*2] - object y angle (0-65536)
  1610. ;    v_vzs[esi*2] - object z angle (0-65536)
  1611. ;    _y_angle_of_sun - (0-65536)
  1612. ;
  1613. ; Out:
  1614. ;    _lmatrix  - shading matrix
  1615. ;    ESI - ?
  1616. ;
  1617. ; Notes:
  1618. ;
  1619. ;z= ( sz ( cx + ( sx * cy )) + cz * sy ) * 45degrees  [x]
  1620. ;   ( cz ( cx + ( sx * cy )) - sz * sy ) * 45degrees  [y]
  1621. ;   ( cx * cy - sx ) * 45 degrees                     [z]
  1622. ;
  1623. ;note cos45=sin45=2d41h, but we will use 2d00h (99.2% accurate)
  1624. ; you can change the y angle of the sun/light but not the x angle.
  1625. ; changing the x angle would require a new formula.
  1626. ;
  1627. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1628.  
  1629. _lambert:
  1630.          mov ax,v_vxs[esi*2]
  1631.          neg ax
  1632.          push eax
  1633.          call _cosine
  1634.          mov vcosx,eax
  1635.          pop eax
  1636.          call _sine
  1637.          mov vsinx,eax
  1638.          mov ebp,eax                        ; ebp = sx
  1639.  
  1640.          mov ax,v_vzs[esi*2]
  1641.          neg ax
  1642.          push eax
  1643.          call _cosine
  1644.          mov vcosz,eax
  1645.          mov edi,eax                        ; edi = cz
  1646.          pop eax
  1647.          call _sine
  1648.          mov vsinz,eax
  1649.          mov edx,eax                        ; edx = sz
  1650.  
  1651.          mov ax,v_vys[esi*2]
  1652.          neg ax
  1653.          add eax,_y_angle_of_sun            ; 2000h = 45 degrees y angle for light source
  1654.          push eax
  1655.          call _cosine
  1656.          mov vcosy,eax
  1657.          mov esi,eax                        ; esi = cy
  1658.          pop eax
  1659.          call _sine
  1660.          mov vsiny,eax                      ; eax = sy
  1661.  
  1662.          mov ebx,edx                        ; ebx = sz
  1663.  
  1664.          mov ecx,eax                        ; ecx = sy
  1665.  
  1666.          mov eax,ebp                        ; get sx
  1667.  
  1668.          imul esi                           ; eax = sx * cy
  1669.          shrd eax,edx,14
  1670.          sub eax,vcosx                      ; eax = cx + ( sx * cy)
  1671.  
  1672.          push eax
  1673.  
  1674.          imul ebx                           ; cx + ( sx * cy) * sz
  1675.          shrd eax,edx,14
  1676.          mov _lmatrix+0,eax
  1677.  
  1678.          pop eax
  1679.  
  1680.          imul edi                           ; di = cz
  1681.          shrd eax,edx,14
  1682.          mov _lmatrix+4,eax                 ; cx + ( sx * cy) * cz
  1683.  
  1684.          mov eax,ebx
  1685.          imul ecx                           ; - sz * sy
  1686.          shrd eax,edx,14
  1687.          sub _lmatrix+4,eax
  1688.  
  1689.          mov eax,edi
  1690.          imul ecx                           ; cz * sy
  1691.          shrd eax,edx,14
  1692.          add _lmatrix+0,eax
  1693.  
  1694.          mov eax,vcosx                      ; (cx * cy - sx) * 45deg
  1695.          imul esi
  1696.          shrd eax,edx,14
  1697.          mov ebx,eax
  1698.          add ebx,ebp
  1699.  
  1700.          cmul eax,ebx,2d00h                 ; * 45degrees
  1701.          shrd eax,edx,14
  1702.          movsx eax,ax
  1703.          mov _lmatrix+8,eax
  1704.  
  1705.          mov ebx,_lmatrix+4
  1706.          cmul eax,ebx,2d00h
  1707.          shrd eax,edx,14
  1708.          mov _lmatrix+4,eax
  1709.  
  1710.          mov ebx,_lmatrix+0
  1711.          cmul eax,ebx,2d00h
  1712.          shrd eax,edx,14
  1713.          mov _lmatrix+0,eax
  1714.  
  1715.          ret
  1716.  
  1717. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1718. ;
  1719. ; _pre_cal_lambert: Pre-calculate all neccessary stuff for object DI
  1720. ;
  1721. ; In:
  1722. ;    EDI - Object # to pre-calculate normals for
  1723. ;    _objbase[esi*4] -> offset of object data
  1724. ; Out:
  1725. ;    ESI -> minimum address of object data
  1726. ;    EDI -> maximum address of object data
  1727. ;    EBP -> points to header for object
  1728. ;
  1729. ; Notes:
  1730. ;
  1731. ; Precalculate surface normals for object di.  This  is  so  you  don't
  1732. ; have to type them in when de_sineing new objects. Imagine, 400 points,
  1733. ; with 350 surfaces, calculating them all manually?  This routine  also
  1734. ; figures out the iteration skip offset (if you have surfaces dependant
  1735. ; on other surfaces) and also sets bit 1 if it is a line (two  points),
  1736. ; and sets bit 4 if 1 point.This routine also sets the number of points
  1737. ; to skip if an iteration is found. It  counts  the  number  of  points
  1738. ; within iterations (even iterations within iterations)  and  sets  the
  1739. ; skip value so any iterations skipped will have a pre-calculated point
  1740. ; offset.  Did that make sense?
  1741. ;
  1742. ; Things done here:
  1743. ;
  1744. ; set point command if only 1 connection
  1745. ; set line  command if only 2 connections
  1746. ; set normal bit in commands if shading used in texture
  1747. ; calculate and set shading normals
  1748. ; calculate offsets for iteration jumps (in case surface not visible)
  1749. ; calculate number of points to skip for iterations (in case surface not visible)
  1750. ; set offset flag if iteration uses a point offset (4'th future use word)
  1751. ; calculate and set auto-intensity of color if auto_s bit set
  1752. ;
  1753. ; Most of the above is done so the user (you) wont have to calculate this stuff
  1754. ; yourself - makes object modification much easier.
  1755. ;
  1756. ; If you find the routine to be sloppy remember it is only used
  1757. ; for object initialization.
  1758. ;
  1759. ; This routine  will probably crash if your object is not set up correctly
  1760. ; The entire 3dvect source will crash if this routine  isn't run  and  the
  1761. ; chances of you knowing how to do all that  this  routine  does  manually
  1762. ; are pretty slim since most of you out there are doughheads.
  1763. ;
  1764. ; The minimum and maximum addresses are returned in ESI and EDI so you can
  1765. ; output the resulting object to a binary file. EBP points to the starting
  1766. ; header of the object (usually, but not neccessaraly, the minimum address)
  1767. ;
  1768. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1769.  
  1770. _lx1     dd 0
  1771. _ly1     dd 0
  1772. _lz1     dd 0
  1773.  
  1774. _lx2     dd 0
  1775. _ly2     dd 0
  1776. _lz2     dd 0
  1777.  
  1778. _lx3     dd 0
  1779. _ly3     dd 0
  1780. _lz3     dd 0
  1781.  
  1782. finx     dd 0
  1783. finy     dd 0
  1784. finz     dd 0
  1785.  
  1786. temp1    dw 0
  1787. temp2    dw 0                               ; number of points
  1788. temp3    dw 0                               ; number of sides
  1789. temp4    dw 0
  1790. temp5    dd 0                               ; minimum address
  1791. temp6    dd 0                               ; maximum address
  1792.  
  1793. _pre_cal_lambert:
  1794.          movzx edi,di                       ; in case user is lazy
  1795.          mov esi,_objbase[edi*4]
  1796.          mov temp5,esi
  1797.          mov temp6,esi
  1798.          push esi                           ; save for exit
  1799. more_reses:
  1800.          push esi                           ; save header offset
  1801.          add esi,4
  1802.          lodsd
  1803.          add esi,eax                        ; handle first resolution
  1804.  
  1805.          lodsw
  1806.          mov temp2,ax
  1807.          lodsw
  1808.          mov temp3,ax
  1809.  
  1810.          mov xad,0
  1811.          mov yad,0
  1812.          mov zad,0
  1813.          mov temp1,-1
  1814.          mov ax,[esi+14]
  1815.          mov temp4,ax
  1816.  
  1817.          mov eax,[esi+8*2]
  1818.          or eax,[esi+8*2+4]
  1819.          jnz lam_hhgg
  1820.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  1821.          mov dword ptr [esi+8*2+4],minz
  1822. lam_hhgg:
  1823.          mov eax,[esi+12*2]
  1824.          jnz lam_hhgc
  1825.          mov dword ptr [esi+12*2],tolerance
  1826. lam_hhgc:
  1827.          add esi,25*2                       ; skip future use bytes
  1828.          mov edi,4                          ; edi=4 to skip center of gravity
  1829.          mov xp,0
  1830.          mov yp,0
  1831.          mov zp,0
  1832.          cmp temp2,0
  1833.          je no_points_2
  1834. lam_ap12:
  1835.          mov bx,w [esi]                     ; load all the points into array
  1836.          mov cx,w [esi+2]
  1837.          mov bp,w [esi+4]
  1838.          add bx,w xad
  1839.          add cx,w yad
  1840.          add bp,w zad
  1841.          movsx ebx,bx
  1842.          movsx ecx,cx
  1843.          movsx ebp,bp
  1844.          mov xp[edi],ebx
  1845.          mov yp[edi],ecx
  1846.          mov zp[edi],ebp
  1847.          add esi,6
  1848.          add edi,4
  1849.          dec temp2
  1850.          jne s lam_ap12                     ; esi = address of sides now...
  1851. no_points_2:
  1852.          mov pointindex,edi
  1853.  
  1854. lam_loadsides:
  1855.          call checkesi                      ; check minimum and maximum addresses
  1856.  
  1857.          mov edi,esi                        ; save in case of line adjust
  1858.          mov ax,[esi]                       ; get command
  1859.  
  1860.          mov bx,ax                          ; save command
  1861.          test ax,special                    ; test if special command
  1862.          jz s lam_notmap                    ; no, skip through loop
  1863.          mov di,ax
  1864.          and edi,special-1
  1865.  
  1866.          cmp ax,gosub                       ; check for jump commands, yeah,yeah, I should have made a table, who cares...
  1867.          jne ffgg1
  1868.          add esi,2
  1869.          lodsw
  1870.          push esi
  1871.          movsx eax,ax
  1872.          sub esi,2
  1873.          add esi,eax
  1874.          jmp lam_next
  1875. ffgg1:
  1876.          cmp ax,return
  1877.          jne ffgg2
  1878.          pop esi
  1879.          jmp lam_next
  1880. ffgg2:
  1881.          cmp ax,goto_offset
  1882.          jne ffgg3
  1883.          add esi,2
  1884.          lodsw
  1885.          movsx eax,ax
  1886.          sub esi,2
  1887.          add esi,eax
  1888.          jmp lam_next
  1889. ffgg3:
  1890.          mov di,number_ofb[edi*2]           ; yes, skip special command length
  1891.          add esi,edi
  1892.          xor bx,bx
  1893.          cmp ax,sub_object
  1894.          je lam_do_it
  1895.          cmp ax,static_sub_object
  1896.          je lam_do_it
  1897.          jmp lam_next                       ; go to next side
  1898. lam_notmap:
  1899.          call pcl_testashade
  1900.  
  1901.          mov ax,[esi+2]                     ; get texture for both sides
  1902.          or ax,[esi+4]
  1903.  
  1904.          test ax,shade                      ; test shading bit
  1905.          jnz lam_calcit                     ; yes, calculate shading normal
  1906.  
  1907.          push edi                           ; save command location
  1908.  
  1909.          add esi,4+4+2                      ; skip 2 colour & 2 texture words & command
  1910.          mov edi,esi
  1911.  
  1912.          lodsw                              ; get first point indexer
  1913.          add ax,temp4
  1914.          stosw
  1915.  
  1916.          mov cx,ax
  1917.          xor dx,dx
  1918. lam_ldlp:
  1919.          lodsw                              ; count number of connection points
  1920.          add ax,temp4
  1921.          stosw
  1922.  
  1923.          inc dx
  1924.          cmp ax,cx
  1925.          jne lam_ldlp
  1926.  
  1927.          call checkesi                      ; check minimum and maximum addresses
  1928.  
  1929.          pop edi                            ; pop command location
  1930.  
  1931.          cmp dx,1                           ; only 1 point?, set point command
  1932.          jne lam_test_line
  1933.          or w [edi+0],both
  1934.          or w [edi+2],point
  1935.          or w [edi+4],point
  1936.          jmp lam_test_iteration
  1937.  
  1938. lam_test_line:
  1939.          cmp dx,2                           ; only 2 points?, set line command
  1940.          jne lam_test_iteration
  1941.          or w [edi+0],both
  1942.          or w [edi+2],line
  1943.          or w [edi+4],line
  1944.  
  1945. lam_test_iteration:
  1946.          xor ax,ax
  1947.          test bx,iterate                    ; test if iteration command used
  1948.          jnz lam_do_it                      ; yes,solve internal iteration
  1949. lam_next:
  1950.          dec temp1
  1951.          jnz lam_nopop
  1952.          pop ax
  1953.          mov temp4,ax
  1954.          pop ax
  1955.          mov temp1,ax
  1956.          jmp lam_next
  1957. lam_nopop:
  1958.          dec temp3
  1959.          jnz lam_loadsides
  1960.  
  1961.          pop esi
  1962.          lodsd
  1963.          add esi,4
  1964.          cmp eax,-1                         ; last resolution?
  1965.          jne more_reses
  1966.  
  1967.          call checkesi                      ; check minimum and maximum addresses
  1968.          pop ebp                            ; pop header offset
  1969.          mov esi,temp5                      ; load up start and end offsets of object
  1970.          mov edi,temp6
  1971.  
  1972.          ret
  1973.  
  1974. lam_calcit:
  1975.          push esi                           ; save command location
  1976.          add esi,4+4+2                      ; skip colour and 2 future use words
  1977.  
  1978.          lodsw                              ; first point
  1979.          add ax,temp4
  1980.          mov [esi-2],ax
  1981.          push ax
  1982.          movzx edi,ax
  1983.  
  1984.          mov ebx,[xp+edi*4]
  1985.          mov ecx,[yp+edi*4]
  1986.          mov ebp,[zp+edi*4]
  1987.  
  1988.          mov _lx1,ebx
  1989.          mov _ly1,ecx
  1990.          mov _lz1,ebp
  1991.  
  1992.          lodsw                              ; second point
  1993.          add ax,temp4
  1994.          mov [esi-2],ax
  1995.          movzx edi,ax
  1996.  
  1997.          mov ebx,[xp+edi*4]
  1998.          mov ecx,[yp+edi*4]
  1999.          mov ebp,[zp+edi*4]
  2000.  
  2001.          mov _lx2,ebx
  2002.          mov _ly2,ecx
  2003.          mov _lz2,ebp
  2004.  
  2005.          lodsw                              ; third point
  2006.          add ax,temp4
  2007.          mov [esi-2],ax
  2008.          movzx edi,ax
  2009.  
  2010.          mov ebx,[xp+edi*4]
  2011.          mov ecx,[yp+edi*4]
  2012.          mov ebp,[zp+edi*4]
  2013.  
  2014.          mov _lx3,ebx
  2015.          mov _ly3,ecx
  2016.          mov _lz3,ebp
  2017.  
  2018.          push esi
  2019.  
  2020.          call _calc_normal
  2021.  
  2022.          pop esi
  2023.  
  2024.          pop dx                             ; now find shading normal storage, pop first connector
  2025.  
  2026. lam_ldl2:
  2027.          lodsw
  2028.          add ax,temp4
  2029.          mov [esi-2],ax
  2030.          cmp ax,dx
  2031.          jne lam_ldl2
  2032.  
  2033.          mov edi,esi
  2034.  
  2035.          mov ax,bx
  2036.          stosw
  2037.          mov ax,cx
  2038.          stosw
  2039.          mov ax,bp
  2040.          stosw
  2041.  
  2042.          add esi,6
  2043.  
  2044.          pop edi                            ; get original command location back
  2045.          or w [edi],normal
  2046.          mov bx,[edi]
  2047.          jmp lam_test_iteration
  2048.  
  2049. lam_surfc_cnt dw 0
  2050.  
  2051. ; this finds the total number of points to skip if an iteration fails, dx = #
  2052. ; remember, this is a pre-calculation routine so it doesn't need to be fast.
  2053.  
  2054. lam_do_it:
  2055.          xor dx,dx                          ; clear total number of points to skip
  2056.  
  2057.          mov ax,[esi+10]                    ; test if there is a center of rotation point
  2058.          or ax,[esi+12]
  2059.          or ax,[esi+14]
  2060.          jz done_alter2
  2061.          or w [esi+8],centroid              ; set flag if offset found (center of gravity)
  2062.  
  2063.          movsx ebx,w [esi+10]
  2064.          movsx ecx,w [esi+12]
  2065.          movsx ebp,w [esi+14]
  2066.          add xad,ebx
  2067.          add yad,ecx
  2068.          add zad,ebp
  2069.          mov ebx,xad
  2070.          mov ecx,yad
  2071.          mov ebp,zad
  2072.          mov edi,pointindex
  2073.          mov xp[edi],ebx
  2074.          mov yp[edi],ecx
  2075.          mov zp[edi],ebp
  2076.          add pointindex,2
  2077.          add dx,1                           ; centroid is an extra point to skip
  2078. done_alter2:
  2079.          mov ax,temp1
  2080.          push ax
  2081.          mov ax,temp4
  2082.          push ax
  2083.  
  2084.          mov ax,[esi+18]
  2085.          add temp4,ax
  2086.          mov w [esi+18],0
  2087.  
  2088.          mov lam_surfc_cnt,0
  2089.          push esi                           ; this is our return address (continue from here+4)
  2090.  
  2091.          lodsw                              ; get number of points.
  2092.          add dx,ax                          ; save as TOTAL number of points to skip
  2093.          mov temp2,ax
  2094.  
  2095.          lodsw                              ; get number of surfaces
  2096.          mov temp1,ax
  2097.          inc temp1
  2098.          add lam_surfc_cnt,ax               ; count until this is zero
  2099.  
  2100.          mov eax,[esi+8*2]
  2101.          or eax,[esi+10*2]
  2102.          jnz lam_hhgg2
  2103.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  2104.          mov dword ptr [esi+8*2+4],minz
  2105. lam_hhgg2:
  2106.          mov eax,[esi+12*2]
  2107.          jnz lam_hhgl
  2108.          mov dword ptr [esi+12*2],tolerance
  2109. lam_hhgl:
  2110.          add esi,25*2
  2111.  
  2112.          mov edi,pointindex
  2113.          cmp temp2,0
  2114.          je lam_test_check                  ; only sides added, no additional points
  2115. lam_ap13:
  2116.          mov bx,w [esi]                     ; load all the points into array
  2117.          mov cx,w [esi+2]                   ; for calculation of gourad shadings
  2118.          mov bp,w [esi+4]
  2119.          add bx,w xad
  2120.          add cx,w yad
  2121.          add bp,w zad
  2122.          movsx ebx,bx
  2123.          movsx ecx,cx
  2124.          movsx ebp,bp
  2125.          mov xp[edi],ebx
  2126.          mov yp[edi],ecx
  2127.          mov zp[edi],ebp
  2128.          add esi,6
  2129.          add edi,4
  2130.          dec temp2
  2131.          jne s lam_ap13                     ; esi = address of sides now...
  2132.  
  2133.          mov pointindex,edi
  2134.  
  2135. lam_test_check:
  2136.          cmp lam_surfc_cnt,0                ; test if user just wants to add points
  2137.          je lam_no_surfs                    ; i dont know why anyone would want to do this?
  2138.  
  2139. lam_test_until_target:
  2140.          lodsw                              ; get command
  2141.          mov bx,ax
  2142.          test ax,special                    ; test if special command
  2143.          jz s lam_notmap_it                 ; no, skip through loop
  2144.  
  2145.          mov di,ax
  2146.          and edi,special-1
  2147.  
  2148.          cmp ax,gosub                       ; check for jump commands, yeah,yeah, I should have made a table, who cares...
  2149.          jne ffgg1x
  2150.          add esi,2
  2151.          lodsw
  2152.          push esi
  2153.          movsx eax,ax
  2154.          sub esi,2
  2155.          add esi,eax
  2156.          jmp lam_next_it
  2157. ffgg1x:
  2158.          cmp ax,return
  2159.          jne ffgg2x
  2160.          pop esi
  2161.          jmp lam_next_it
  2162. ffgg2x:
  2163.          cmp ax,goto_offset
  2164.          jne ffgg3x
  2165.          add esi,2
  2166.          lodsw
  2167.          movsx eax,ax
  2168.          sub esi,2
  2169.          add esi,eax
  2170.          jmp lam_next_it
  2171. ffgg3x:
  2172.          movzx edi,number_ofb[edi*2]        ; yes, skip special command length
  2173.          add esi,edi
  2174.          sub esi,2
  2175.          cmp ax,sub_object
  2176.          je lam_re_lam
  2177.          cmp ax,static_sub_object
  2178.          je lam_re_lam
  2179.          jmp s lam_nog
  2180.  
  2181. lam_notmap_it:
  2182.          lodsw
  2183.          mov bp,ax
  2184.          lodsw
  2185.          or bp,ax                           ; find if shading bit used, add esi,6 if so
  2186.          add esi,4                          ; skip 2 colour words
  2187.  
  2188.          lodsw                              ; get first point indexer
  2189.          mov cx,ax
  2190. lam_ldl3:
  2191.          lodsw
  2192.          cmp ax,cx
  2193.          jne lam_ldl3
  2194.  
  2195.          test bp,shade                      ; test if gouraud normal present
  2196.          jz lam_nog
  2197.          add esi,6                          ; skip it if present
  2198. lam_nog:
  2199.          test bx,iterate                    ; test if iteration command used
  2200.          jnz lam_re_lam                     ; solve internal iteration again...
  2201. lam_next_it:
  2202.          dec lam_surfc_cnt
  2203.          jnz lam_test_until_target
  2204. lam_no_surfs:
  2205.          mov edi,esi                        ; save current location
  2206.          pop esi                            ; return original start location
  2207.          sub edi,esi                        ; get difference between them
  2208.          sub di,8                           ; offset for loadsides routine - constant
  2209.  
  2210.          lodsw                              ; get number of points
  2211.          mov bx,ax
  2212.  
  2213.          lodsw
  2214.          add temp3,ax
  2215.  
  2216.          mov cx,dx
  2217.          mov ax,6
  2218.          imul bx
  2219.          movzx ebx,ax
  2220.  
  2221.          mov ax,di
  2222.          mov edi,esi
  2223.          stosw                              ; save offset
  2224.          mov ax,cx
  2225.          stosw                              ; save number of points found in iterations
  2226.  
  2227.          mov eax,[esi+8*2]
  2228.          or eax,[esi+10*2]
  2229.          jnz lam_hhgg3
  2230.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  2231.          mov dword ptr [esi+8*2+4],minz
  2232. lam_hhgg3:
  2233.          mov eax,[esi+12*2]
  2234.          jnz lam_hhgq
  2235.          mov dword ptr [esi+12*2],tolerance
  2236. lam_hhgq:
  2237.          add esi,25*2                       ; adjust for next load
  2238.          add esi,ebx
  2239.  
  2240.          jmp lam_next
  2241.  
  2242. lam_re_lam:
  2243.          lodsw                              ; get number of points for recursed iteration
  2244.          add dx,ax                          ; save as TOTAL number of points to skip
  2245.          mov cx,ax
  2246.  
  2247.          lodsw                              ; get number of surfaces
  2248.          add lam_surfc_cnt,ax               ; count until this is zero
  2249.  
  2250.          mov eax,[esi+8*2]
  2251.          or eax,[esi+10*2]
  2252.          jnz lam_hhgg4
  2253.          mov dword ptr [esi+8*2],maxz       ; if no max/min found, force one
  2254.          mov dword ptr [esi+8*2+4],minz
  2255. lam_hhgg4:
  2256.          mov eax,[esi+12*2]
  2257.          jnz lam_hhgv
  2258.          mov dword ptr [esi+12*2],tolerance
  2259. lam_hhgv:
  2260.          add esi,25*2
  2261.  
  2262.          mov eax,6
  2263.          imul cx
  2264.          add esi,eax
  2265.  
  2266.          jmp lam_next_it
  2267.  
  2268. checkesi:
  2269.          cmp esi,temp5
  2270.          jae noesi1
  2271.          mov temp5,esi
  2272. noesi1:
  2273.          cmp esi,temp6
  2274.          jbe noesi2
  2275.          mov temp6,esi
  2276. noesi2:
  2277.          ret
  2278.  
  2279. pcl_testashade:
  2280.          mov ax,[esi+2]
  2281.          or ax,[esi+4]
  2282.          test ax,auto_s
  2283.          jnz pcl_test2
  2284.          ret
  2285. pcl_test2:
  2286.          pushad
  2287.          push esi
  2288.          push esi
  2289.          mov _vxs,0
  2290.          mov _vys,0
  2291.          mov _vzs,0
  2292.          xor esi,esi
  2293.          call _lambert
  2294.          pop esi
  2295.  
  2296.          movzx ebx,w [esi+10]
  2297.          movzx ecx,w [esi+12]
  2298.          movzx edx,w [esi+14]
  2299.  
  2300.          mov eax,xp[ebx*4]
  2301.          mov _lx1,eax
  2302.          mov eax,yp[ebx*4]
  2303.          mov _ly1,eax
  2304.          mov eax,zp[ebx*4]
  2305.          mov _lz1,eax
  2306.          mov eax,xp[ecx*4]
  2307.          mov _lx2,eax
  2308.          mov eax,yp[ecx*4]
  2309.          mov _ly2,eax
  2310.          mov eax,zp[ecx*4]
  2311.          mov _lz2,eax
  2312.          mov eax,xp[edx*4]
  2313.          mov _lx3,eax
  2314.          mov eax,yp[edx*4]
  2315.          mov _ly3,eax
  2316.          mov eax,zp[edx*4]
  2317.          mov _lz3,eax
  2318.          call _calc_normal
  2319.  
  2320.          call _l_rotate_point
  2321.          pop esi
  2322.          push edi
  2323.  
  2324.          test w [esi+2],auto_s
  2325.          jz pcl_test4
  2326.          test w [esi+2],inverse
  2327.          jz pcl_test3
  2328.          neg edi
  2329. pcl_test3:
  2330.          add edi,256
  2331.          shr edi,1                          ; result -256 to +256, turn into 0-256
  2332.          mov al,b shading_tables[edi]       ; now into 0-15
  2333.          xor ah,ah
  2334.          add w [esi+6],ax
  2335.          mov ax,[esi+2]
  2336.          and ax,65535-auto_s
  2337.          mov [esi+2],ax
  2338. pcl_test4:
  2339.          pop edi
  2340.  
  2341.          test w [esi+4],auto_s
  2342.          jz pcl_test6
  2343.          test w [esi+4],inverse
  2344.          jz pcl_test5
  2345.          neg edi
  2346. pcl_test5:
  2347.          add edi,256
  2348.          shr edi,1                          ; result -256 to +256, turn into 0-256
  2349.          mov al,b shading_tables[edi]       ; now into 0-15
  2350.          xor ah,ah
  2351.          add w [esi+8],ax
  2352.          mov ax,[esi+4]
  2353.          and ax,65535-auto_s
  2354.          mov [esi+4],ax
  2355. pcl_test6:
  2356.          popad
  2357.          ret
  2358.  
  2359. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2360. ;
  2361. ; _calc_normal: calculate surface normal
  2362. ;
  2363. ; In:
  2364. ;    _lx1 - x of point 1 on triangle
  2365. ;    _ly1 - y of point 1 on triangle
  2366. ;    _lz1 - z of point 1 on triangle
  2367. ;    _lx2 - x of point 2 on triangle
  2368. ;    _ly2 - y of point 2 on triangle
  2369. ;    _lz2 - z of point 2 on triangle
  2370. ;    _lx3 - x of point 3 on triangle
  2371. ;    _ly3 - y of point 3 on triangle
  2372. ;    _lz3 - z of point 3 on triangle
  2373. ;
  2374. ; Out:
  2375. ;    EBX = finx = x of surface normal of triangle
  2376. ;    ECX = finy = y of surface normal of triangle
  2377. ;    EBP = finz = z of surface normal of triangle
  2378. ;
  2379. ; Notes:
  2380. ; _x2 = _x2 - _x1
  2381. ; _y2 = _y2 - _y1
  2382. ; z2 = z2 - z1
  2383. ;
  2384. ; x3 = x3 - _x1
  2385. ; y3 = y3 - _y1
  2386. ; z3 = z3 - z1
  2387. ;
  2388. ; x = _y2 * z3 - z2 * y3
  2389. ; y = z2 * x3 - _x2 * z3
  2390. ; z = _x2 * y3 - _y2 * x3
  2391. ;
  2392. ; a = SQR(x ^ 2 + y ^ 2 + z ^ 2)
  2393. ;
  2394. ; x = INT(x / a * 256 + .5)
  2395. ; y = INT(y / a * 256 + .5)
  2396. ; z = INT(z / a * 256 + .5)
  2397. ;
  2398. ; This worked for me on the first try!
  2399. ;
  2400. ; If you wanted to get the equation of a plane, you could do this after:
  2401. ;  d = - x * _x1 - y * _y1 - z * z1
  2402. ;
  2403. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2404.  
  2405.          nshl = 8
  2406.  
  2407. _calc_normal:
  2408.          mov ebx,_lx1
  2409.          mov ecx,_ly1
  2410.          mov ebp,_lz1
  2411.  
  2412.          sub _lx2,ebx
  2413.          sub _ly2,ecx
  2414.          sub _lz2,ebp
  2415.  
  2416.          sub _lx3,ebx
  2417.          sub _ly3,ecx
  2418.          sub _lz3,ebp
  2419.  
  2420.          mov eax,_ly2
  2421.          mov ebx,_lz3
  2422.          imul ebx
  2423.          mov ecx,eax
  2424.  
  2425.          mov eax,_lz2
  2426.          mov ebx,_ly3
  2427.          imul ebx
  2428.          sub ecx,eax
  2429.  
  2430.          mov finx,ecx                       ; save x of normal
  2431.  
  2432.          mov eax,_lz2
  2433.          mov ebx,_lx3
  2434.          imul ebx
  2435.          mov ecx,eax
  2436.  
  2437.          mov eax,_lx2
  2438.          mov ebx,_lz3
  2439.          imul ebx
  2440.          sub ecx,eax
  2441.  
  2442.          mov finy,ecx                       ; save y of normal
  2443.  
  2444.          mov eax,_lx2
  2445.          mov ebx,_ly3
  2446.          imul ebx
  2447.          mov ecx,eax
  2448.  
  2449.          mov eax,_ly2
  2450.          mov ebx,_lx3
  2451.          imul ebx
  2452.          sub ecx,eax
  2453.  
  2454.          mov finz,ecx                       ; save z of normal
  2455.  
  2456. calc_testloop:
  2457.          cmp finx,32768                     ; make sure (normal^2)*2 is < 2^32
  2458.          jge calc_shrit
  2459.          cmp finy,32768
  2460.          jge calc_shrit
  2461.          cmp finz,32768
  2462.          jge calc_shrit
  2463.  
  2464.          cmp finx,-32768
  2465.          jle calc_shrit
  2466.          cmp finy,-32768
  2467.          jle calc_shrit
  2468.          cmp finz,-32768
  2469.          jg ok_2_bite_dust
  2470.  
  2471. calc_shrit:
  2472.          shr finx,1                         ; calculations will be too large if squared, div by 2
  2473.          test finx,40000000h
  2474.          jz no_neg_calc1
  2475.          or finx,80000000h
  2476. no_neg_calc1:
  2477.          shr finy,1
  2478.          test finy,40000000h
  2479.          jz no_neg_calc2
  2480.          or finy,80000000h
  2481. no_neg_calc2:
  2482.          shr finz,1
  2483.          test finz,40000000h
  2484.          jz no_neg_calc3
  2485.          or finz,80000000h
  2486. no_neg_calc3:
  2487.          jmp calc_testloop
  2488.  
  2489. ok_2_bite_dust:
  2490.          mov eax,finx                       ; x^2
  2491.          mov edi,eax                        ; objects
  2492.          imul edi
  2493.          mov edi,eax
  2494.  
  2495.          mov eax,finy                       ; y^2
  2496.          mov esi,eax
  2497.          imul esi
  2498.          mov esi,eax
  2499.  
  2500.          mov eax,finz                       ; z^2
  2501.          mov ebp,eax
  2502.          imul ebp
  2503.  
  2504.          add eax,esi
  2505.          add eax,edi
  2506.  
  2507.          call _sqrt                         ; get square root of number
  2508.  
  2509.          mov ecx,eax
  2510.          or ecx,ecx
  2511.          je lam_abort                       ; should never happen!
  2512.  
  2513.          mov eax,finx
  2514.          cdq
  2515.          shl eax,nshl                       ; set unit vector to 2^nshl (256)
  2516.          idiv ecx
  2517.          mov finx,eax
  2518.  
  2519.          mov eax,finy
  2520.          cdq
  2521.          shl eax,nshl
  2522.          idiv ecx
  2523.          mov finy,eax
  2524.  
  2525.          mov eax,finz
  2526.          cdq
  2527.          shl eax,nshl
  2528.          idiv ecx
  2529.          mov finz,eax
  2530.  
  2531.          mov ebx,finx
  2532.          mov ecx,finy
  2533.          mov ebp,finz
  2534.  
  2535. lam_abort:
  2536.          ret
  2537.  
  2538. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2539. ; _calc_d: Calculate D portion of equation of a plane
  2540. ; In:
  2541. ;    EBX = x of surface normal of triangle
  2542. ;    ECX = y of surface normal of triangle
  2543. ;    EBP = z of surface normal of triangle
  2544. ;    _lx1 - x of point on triangle (any point)
  2545. ;    _ly1 - y of point on triangle
  2546. ;    _lz1 - z of point on triangle
  2547. ; Out:
  2548. ;    EAX = D     (Ax+By+Cz=D)
  2549. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2550. _calc_d:
  2551.          mov eax,_lx1
  2552.          imul ebx
  2553.          mov esi,eax
  2554.  
  2555.          mov eax,_ly1
  2556.          imul ecx
  2557.          add esi,eax
  2558.  
  2559.          mov eax,_lz1
  2560.          imul ebp
  2561.          add eax,esi
  2562.  
  2563.          ret
  2564.  
  2565. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2566. ;
  2567. ; _set_up_all_lambert: set up all _lambert normals from object si to object di
  2568. ;
  2569. ; In:
  2570. ;    ESI - object # to start at
  2571. ;    EDI - object # to end at
  2572. ;    _objbase[esi*4 - edi*4] -> offsets to object data
  2573. ; Out:
  2574. ;   null
  2575. ;
  2576. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2577.  
  2578. _set_up_all_lambert:
  2579.          movzx edi,di                       ; in case user is lazy
  2580.          movzx esi,si
  2581.  
  2582.          xchg edi,esi                       ; so user doesn't get confuzed
  2583. set_lop:
  2584.          push esi
  2585.          push edi
  2586.          call _pre_cal_lambert
  2587.          pop edi
  2588.          pop esi
  2589.          inc edi
  2590.          cmp edi,esi
  2591.          jna set_lop
  2592.  
  2593.          ret
  2594.  
  2595. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2596. ;
  2597. ; _l_rotate_point: _rotate_point surface normal through _lambert matrix
  2598. ;
  2599. ; In:
  2600. ;    BX - x of surface normal
  2601. ;    CX - y of surface normal
  2602. ;    BP - z of surface normal
  2603. ;    _lmatrix - 16 bit, 1x3 _lambert shading matrix - set up by "_lambert" routine
  2604. ; Out:
  2605. ;    BX - x of surface normal (untouched)
  2606. ;    CX - y of surface normal (untouched)
  2607. ;    BP - z of surface normal (untouched)
  2608. ;   EDI - colour intensity for surface (-255 to +255)
  2609. ;
  2610. ; Notes:
  2611. ;   Your mother is a hamster.
  2612. ;
  2613. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2614.  
  2615. _l_rotate_point:
  2616.          mov eax,_lmatrix+8                 ; solve edi = bx(0)+cx(4)+bp(8)
  2617.          imul bp
  2618.          shrd ax,dx,14
  2619.          mov edi,eax
  2620.          mov eax,_lmatrix+4
  2621.          imul cx
  2622.          shrd ax,dx,14
  2623.          add edi,eax
  2624.          mov eax,_lmatrix+0
  2625.          imul bx
  2626.          shrd ax,dx,14
  2627.          add edi,eax                        ; di = new colour -256 to 255 (not edi, di!)
  2628.          movsx edi,di
  2629.  
  2630.          add edi,256                        ; make sure result is within range -256 to 256
  2631.          and edi,511                        ; sometimes is messes up...
  2632.          sub edi,256
  2633.  
  2634.          ret
  2635.  
  2636. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2637. ;
  2638. ; Shading tables used for fake cosin colour intensity - 256 bytes
  2639. ; Default is 16 colours per _lambert calculation.  But you could have 32, 48
  2640. ; or whatever you want, even an odd number like 53.  Use the SHADING.BAS
  2641. ; program to make the table to your custom size.
  2642. ;
  2643. ; Shading_bits is the variable for use with the texture command "LAST".  This
  2644. ; variable tells the routine what bits to  pluck  off  when  determining  the
  2645. ; shading intensity. Obviosly this cant  be  used  if  your  palette  shading
  2646. ; length is not a function of 2's complement.
  2647. ;
  2648. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2649.  
  2650.          if shading_colours eq 16
  2651.  
  2652. ; 16 colour shading table
  2653.  
  2654.          align 4
  2655. shading_tables:
  2656.          db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1
  2657.          db 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2
  2658.          db 2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3
  2659.          db 3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4
  2660.          db 4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5
  2661.          db 5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6
  2662.          db 6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7
  2663.          db 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  2664.          db 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
  2665.          db 8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9
  2666.          db 9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10
  2667.          db 10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11
  2668.          db 11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12
  2669.          db 12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13
  2670.          db 13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14
  2671.          db 14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15
  2672.  
  2673.          elseif shading_colours eq 32
  2674.  
  2675. ; 32 colour shading table
  2676.  
  2677.          align 4
  2678. shading_tables:
  2679.          db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2
  2680.          db 2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4
  2681.          db 4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6
  2682.          db 6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8
  2683.          db 8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10
  2684.          db 10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12
  2685.          db 12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14
  2686.          db 14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15
  2687.          db 16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17
  2688.          db 17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19
  2689.          db 19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21
  2690.          db 21,21,21,22,22,22,22,22,22,22,22,22,23,23,23,23
  2691.          db 23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25
  2692.          db 25,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27
  2693.          db 27,27,27,28,28,28,28,28,28,28,29,29,29,29,29,29
  2694.          db 29,29,30,30,30,30,30,30,30,31,31,31,31,31,31,31
  2695.          endif
  2696.  
  2697. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2698. ;
  2699. ; Generate null Y matrix (for camera)
  2700. ;
  2701. ; In: ECX => matrix for storage
  2702. ; Out:
  2703. ;     ECX => 9 doubleword resulting rotation matrix (excluding camera y angle)
  2704. ;
  2705. ; Notes:
  2706. ;      x       y           z
  2707. ;
  2708. ; x=  cz   -cx * sz   + sx * sz
  2709. ;
  2710. ; y=  sz    cx * cz   - sx * cz
  2711. ;
  2712. ; z=   0       sx         cx
  2713. ;
  2714. ;
  2715. ;  Matrix offsets: (doublewords)
  2716. ;
  2717. ;     x  y  z
  2718. ;
  2719. ; x    0  4  8
  2720. ; y   12 16 20
  2721. ; z   24 28 32
  2722. ;
  2723. ; Notes: This routine generates the camera matrix without the Y component.
  2724. ;
  2725. ;        A call to _setsincose MUST have taken place for this routine to work
  2726. ;        correctly!
  2727. ;
  2728. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2729.  
  2730.          align 4
  2731.  
  2732. _null_y_matrix:
  2733.          mov eax,_ecosz
  2734.          mov [ecx+0],eax
  2735.  
  2736.          mov ebx,_esinz
  2737.          mov [ecx+12],ebx
  2738.  
  2739.          mov edi,_esinx
  2740.          mov [ecx+28],edi
  2741.  
  2742.          mov esi,_ecosx
  2743.          mov [ecx+32],esi
  2744.  
  2745.          mov d [ecx+24],0
  2746.  
  2747.          imul edi
  2748.          shrd eax,edx,14
  2749.          neg eax
  2750.          mov [ecx+20],eax
  2751.  
  2752.          mov eax,_ecosz
  2753.          imul edi
  2754.          shrd eax,edx,14
  2755.          mov [ecx+16],eax
  2756.  
  2757.          mov eax,ebx
  2758.          imul edi
  2759.          shrd eax,edx,14
  2760.          mov [ecx+8],eax
  2761.  
  2762.          mov eax,esi
  2763.          imul ebx
  2764.          shrd eax,edx,14
  2765.          neg eax
  2766.          mov [ecx+4],eax
  2767.  
  2768.          ret
  2769.  
  2770. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2771. ; Inverse Rotate by Camera
  2772. ; In:
  2773. ;  EBX = x
  2774. ;  ECX = y
  2775. ;  EBP = z
  2776. ;  ESI => indexer to angles (object number)
  2777. ; Out:
  2778. ;  EBX = x
  2779. ;  ECX = y
  2780. ;  EBP = z
  2781. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2782.  
  2783. icosx    dd 0
  2784. isinx    dd 0
  2785. icosy    dd 0
  2786. isiny    dd 0
  2787. icosz    dd 0
  2788. isinz    dd 0
  2789. ix       dd 0
  2790. iy       dd 0
  2791. iz       dd 0
  2792.  
  2793. _inverse_rotate:
  2794.          push esi
  2795.          push ebx
  2796.          push ecx
  2797.          push ebp
  2798.  
  2799.          mov ax,_vxs[esi*2]
  2800.          neg ax
  2801.          call _cosine
  2802.          mov icosx,eax
  2803.  
  2804.          mov ax,_vxs[esi*2]
  2805.          neg ax
  2806.          call _sine
  2807.          mov isinx,eax
  2808.  
  2809.          mov ax,_vys[esi*2]
  2810.          neg ax
  2811.          call _cosine
  2812.          mov icosy,eax
  2813.  
  2814.          mov ax,_vys[esi*2]
  2815.          neg ax
  2816.          call _sine
  2817.          mov isiny,eax
  2818.  
  2819.          mov ax,_vzs[esi*2]
  2820.          neg ax
  2821.          call _cosine
  2822.          mov icosz,eax
  2823.  
  2824.          mov ax,_vzs[esi*2]
  2825.          neg ax
  2826.          call _sine
  2827.          mov isinz,eax
  2828.  
  2829.          pop ebp
  2830.          pop ecx
  2831.          pop ebx
  2832.  
  2833.          mov eax,ebx
  2834.          imul icosz
  2835.          shrd eax,edx,14
  2836.          mov esi,eax
  2837.          mov eax,ecx
  2838.          imul isinz
  2839.          shrd eax,edx,14
  2840.          sub esi,eax
  2841.          mov ix,esi
  2842.  
  2843.          mov eax,ebx
  2844.          imul isinz
  2845.          shrd eax,edx,14
  2846.          mov esi,eax
  2847.          mov eax,ecx
  2848.          imul icosz
  2849.          shrd eax,edx,14
  2850.          add esi,eax
  2851.          mov iy,esi
  2852.  
  2853.          mov ebx,ix
  2854.          mov ecx,iy
  2855.  
  2856.          mov eax,ecx
  2857.          imul icosx
  2858.          shrd eax,edx,14
  2859.          mov esi,eax
  2860.          mov eax,ebp
  2861.          imul isinx
  2862.          shrd eax,edx,14
  2863.          sub esi,eax
  2864.          mov iy,esi
  2865.  
  2866.          mov eax,ecx
  2867.          imul isinx
  2868.          shrd eax,edx,14
  2869.          mov esi,eax
  2870.          mov eax,ebp
  2871.          imul icosx
  2872.          shrd eax,edx,14
  2873.          add esi,eax
  2874.          mov iz,esi
  2875.  
  2876.          mov ecx,iy
  2877.          mov ebp,iz
  2878.  
  2879.          mov eax,ebx
  2880.          imul icosy
  2881.          shrd eax,edx,14
  2882.          mov esi,eax
  2883.          mov eax,ebp
  2884.          imul isiny
  2885.          shrd eax,edx,14
  2886.          sub esi,eax
  2887.          mov ix,esi
  2888.  
  2889.          mov eax,ebx
  2890.          imul isiny
  2891.          shrd eax,edx,14
  2892.          mov esi,eax
  2893.          mov eax,ebp
  2894.          imul icosy
  2895.          shrd eax,edx,14
  2896.          add esi,eax
  2897.          mov iz,esi
  2898.  
  2899.          mov ebx,ix
  2900.          mov ebp,iz
  2901.  
  2902.          pop esi
  2903.          ret
  2904.  
  2905. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2906. ; Rotate point along X axis
  2907. ; In:
  2908. ;  ECX = Y
  2909. ;  EBP = Z
  2910. ;   AX = angle to rotate by
  2911. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2912.  
  2913. _rotate_x:
  2914.          push ebx
  2915.          push ecx
  2916.          push ebp
  2917.          push ax
  2918.          call _cosine
  2919.          mov icosx,eax
  2920.  
  2921.          pop ax
  2922.          call _sine
  2923.          mov isinx,eax
  2924.  
  2925.          pop ebp
  2926.          pop ecx
  2927.          pop ebx
  2928.  
  2929.          mov eax,ecx
  2930.          imul icosx
  2931.          shrd eax,edx,14
  2932.          mov esi,eax
  2933.          mov eax,ebp
  2934.          imul isinx
  2935.          shrd eax,edx,14
  2936.          sub esi,eax
  2937.          mov iy,esi
  2938.  
  2939.          mov eax,ecx
  2940.          imul isinx
  2941.          shrd eax,edx,14
  2942.          mov esi,eax
  2943.          mov eax,ebp
  2944.          imul icosx
  2945.          shrd eax,edx,14
  2946.          add esi,eax
  2947.  
  2948.          mov ebp,esi
  2949.          mov ecx,iy
  2950.          ret
  2951.  
  2952. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2953. ; Rotate point along Y axis
  2954. ; In:
  2955. ;  EBX = X
  2956. ;  EBP = Z
  2957. ;   AX = angle to rotate by
  2958. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2959.  
  2960. _rotate_y:
  2961.          push ebx
  2962.          push ecx
  2963.          push ebp
  2964.          push ax
  2965.          call _cosine
  2966.          mov icosy,eax
  2967.  
  2968.          pop ax
  2969.          call _sine
  2970.          mov isiny,eax
  2971.  
  2972.          pop ebp
  2973.          pop ecx
  2974.          pop ebx
  2975.  
  2976.          mov eax,ebx
  2977.          imul icosy
  2978.          shrd eax,edx,14
  2979.          mov esi,eax
  2980.          mov eax,ebp
  2981.          imul isiny
  2982.          shrd eax,edx,14
  2983.          sub esi,eax
  2984.          mov ix,esi
  2985.  
  2986.          mov eax,ebx
  2987.          imul isiny
  2988.          shrd eax,edx,14
  2989.          mov esi,eax
  2990.          mov eax,ebp
  2991.          imul icosy
  2992.          shrd eax,edx,14
  2993.          add esi,eax
  2994.  
  2995.          mov ebp,esi
  2996.          mov ebx,ix
  2997.          ret
  2998.  
  2999. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  3000. ; Rotate point along Z axis
  3001. ; In:
  3002. ;  EBX = X
  3003. ;  ECX = Y
  3004. ;   AX = angle to rotate by
  3005. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  3006.  
  3007. _rotate_z:
  3008.          push ebx
  3009.          push ecx
  3010.          push ebp
  3011.          push ax
  3012.          call _cosine
  3013.          mov icosz,eax
  3014.  
  3015.          pop ax
  3016.          call _sine
  3017.          mov isinz,eax
  3018.  
  3019.          pop ebp
  3020.          pop ecx
  3021.          pop ebx
  3022.  
  3023.          mov eax,ebx
  3024.          imul icosz
  3025.          shrd eax,edx,14
  3026.          mov esi,eax
  3027.          mov eax,ecx
  3028.          imul isinz
  3029.          shrd eax,edx,14
  3030.          sub esi,eax
  3031.          mov ix,esi
  3032.  
  3033.          mov eax,ebx
  3034.          imul isinz
  3035.          shrd eax,edx,14
  3036.          mov esi,eax
  3037.          mov eax,ecx
  3038.          imul icosz
  3039.          shrd eax,edx,14
  3040.          add esi,eax
  3041.  
  3042.          mov ecx,esi
  3043.          mov ebx,ix
  3044.          ret
  3045.  
  3046. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  3047. ; _Point_Z: Calculate Z roll direction to line object up with point
  3048. ; In:
  3049. ;  EBX = x point
  3050. ;  ECX = y point
  3051. ;  EBP = z point
  3052. ;   AX = current Y angle of object
  3053. ;   DI = current X angle of object
  3054. ; Out:
  3055. ;   AX = Z angle
  3056. ; Notes:
  3057. ;   u = x*cos(Y) - z*sin(Y)
  3058. ;   v = x*sin(Y) + z*cos(Y)
  3059. ;   y = y*cos(X) - v*sin(X)
  3060. ;   Z = arctan (u/y)         = AX
  3061. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  3062.  
  3063. _point_z:
  3064.          push esi
  3065.          push edi
  3066.          push ebx
  3067.          push ax
  3068.          call _cosine
  3069.          mov icosy,eax
  3070.          pop ax
  3071.          call _sine
  3072.          mov isiny,eax
  3073.  
  3074.          pop ebx
  3075.          imul ebp
  3076.          shrd eax,edx,14
  3077.          mov esi,eax
  3078.          neg esi
  3079.          mov eax,icosy
  3080.          imul ebx
  3081.          shrd eax,edx,14
  3082.          add esi,eax
  3083.          mov ix,esi
  3084.  
  3085.          mov eax,ebx
  3086.          imul isiny
  3087.          shrd eax,edx,14
  3088.          mov esi,eax
  3089.          mov eax,ebp
  3090.          imul icosy
  3091.          shrd eax,edx,14
  3092.          add esi,eax
  3093.  
  3094.          mov ax,di
  3095.          call _cosine
  3096.          mov icosx,eax
  3097.          mov ax,di
  3098.          call _sine
  3099.          mov isinx,eax
  3100.          mov eax,ecx
  3101.          imul icosx
  3102.          shrd eax,edx,14
  3103.          mov edi,eax
  3104.          mov eax,esi
  3105.          imul isinx
  3106.          shrd eax,edx,14
  3107.          sub edi,eax
  3108.  
  3109.          mov eax,edi
  3110.          mov ecx,ix
  3111.          call _arctan
  3112.          pop edi
  3113.          pop esi
  3114.          ret
  3115.  
  3116.