home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 3d / draw.asm < prev    next >
Assembly Source File  |  1998-06-08  |  16KB  |  669 lines

  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/3d/rcs/draw.asm $
  13. ; $Revision: 1.30 $
  14. ; $Author: matt $
  15. ; $Date: 1995/02/15 02:26:52 $
  16. ;
  17. ; Source for drawing routines
  18. ;
  19. ; $Log: draw.asm $
  20. ; Revision 1.30  1995/02/15  02:26:52  matt
  21. ; Put in added handling for odd clipping error
  22. ; Revision 1.29  1995/02/10  16:41:41  matt
  23. ; Put in check for bad points after clip
  24. ; Revision 1.28  1995/02/09  22:00:52  matt
  25. ; Removed dependence on divide overflow handler; we now check for overflow
  26. ; before dividing.  This fixed problems on some TI chips.
  27. ; Revision 1.27  1994/11/30  00:59:32  mike
  28. ; optimizations.
  29. ; Revision 1.26  1994/10/03  12:52:04  matt
  30. ; Fixed typo
  31. ; Revision 1.25  1994/10/03  12:49:56  matt
  32. ; Took out unused routines & data
  33. ; Revision 1.24  1994/07/24  23:59:34  matt
  34. ; Made 3d no longer deal with point numbers, but only with pointers.
  35. ; Revision 1.23  1994/05/30  11:36:26  matt
  36. ; Added g3_set_special_render() to allow a user to specify functions to
  37. ; call for 2d draws.
  38. ; Revision 1.22  1994/05/19  21:46:13  matt
  39. ; Moved texture lighting out of 3d and into the game
  40. ; Revision 1.21  1994/05/13  17:06:18  matt
  41. ; Finished ripping out intersected side lighting code
  42. ; Revision 1.20  1994/05/13  17:02:58  matt
  43. ; Took our special side lighting code
  44. ; Revision 1.19  1994/04/19  18:45:19  matt
  45. ; Now call the clipped disk, which it should have done all along, but
  46. ; John had only implemented the unclipped disk, and it clipped anyway.
  47. ; Revision 1.18  1994/04/19  18:26:42  matt
  48. ; Added g3_draw_sphere() function.
  49. ; Revision 1.17  1994/04/19  17:03:40  matt
  50. ; For polygons, call the texture-mapper's flat shader
  51. ; Revision 1.16  1994/03/18  15:58:37  matt
  52. ; Fixed bug that caused light vals to be screwed up
  53. ; Revision 1.15  1994/03/14  12:37:31  matt
  54. ; Made draw routines check for rotated points
  55. ; Revision 1.14  1994/02/10  18:00:39  matt
  56. ; Changed 'if DEBUG_ON' to 'ifndef NDEBUG'
  57. ; Revision 1.13  1994/02/09  11:48:16  matt
  58. ; Changes return codes for drawing functions
  59. ; Revision 1.12  1994/02/01  13:23:05  matt
  60. ; Added use_beam var to turn off beam lighting
  61. ; Revision 1.11  1994/01/26  20:27:18  mike
  62. ; bright light on very near side.
  63. ; Revision 1.10  1994/01/26  12:49:26  matt
  64. ; Made lighting computation a seperate function, g3_compute_lighting_value.
  65. ; Note the unwieldy function name, courtesy of Mike.
  66. ; Revision 1.9  1994/01/25  16:38:02  yuan
  67. ; Fixed beam_brightness
  68. ; Revision 1.8  1994/01/24  11:08:49  matt
  69. ; Added beam_brightness variable
  70. ; Revision 1.7  1994/01/22  18:22:09  matt
  71. ; New lighting stuff now done in 3d; g3_draw_tmap() takes lighting parm
  72. ; Revision 1.6  1993/12/05  23:47:14  matt
  73. ; Added function g3_draw_line_ptrs()
  74. ; Revision 1.5  1993/11/22  10:51:29  matt
  75. ; Changed texture map function comments to reflect uvl (not just uv) struct
  76. ; Revision 1.4  1993/11/17  10:40:02  matt
  77. ; Added check for zero-length normal in do_facing_check
  78. ; Revision 1.3  1993/11/04  18:49:14  matt
  79. ; Added system to only rotate points once per frame
  80. ; Revision 1.2  1993/11/04  12:36:36  mike
  81. ; Add support for static lighting value.
  82. ; Revision 1.1  1993/10/29  22:20:27  matt
  83. ; Initial revision
  84. ;
  85. ;
  86.  
  87. DONT_USE_UPOLY = 1
  88.  
  89. .386
  90.     option    oldstructs
  91.  
  92.     .nolist
  93.     include    types.inc
  94.     include    psmacros.inc
  95.     include    gr.inc
  96.     include    3d.inc
  97.     .list
  98.  
  99.     assume    cs:_TEXT, ds:_DATA
  100.  
  101. _DATA    segment    dword public USE32 'DATA'
  102.  
  103. rcsid    db    "$Id: draw.asm 1.30 1995/02/15 02:26:52 matt Exp $"
  104.     align    4
  105.  
  106. tempv    vms_vector <>
  107.  
  108. n_verts    dd    ?
  109. n_verts_4    dd    ?    ; added by mk, 11/29/94, point coding optimization.
  110. bitmap_ptr    dd    ?
  111.  
  112. uvl_list_ptr    dd    ?
  113.  
  114. tmap_drawer_ptr    dd    draw_tmap_
  115. flat_drawer_ptr    dd    gr_upoly_tmap_
  116. line_drawer_ptr    dd    gr_line_
  117.  
  118. _DATA    ends
  119.  
  120.  
  121.  
  122. _TEXT    segment    dword public USE32 'CODE'
  123.  
  124.     extn    gr_upoly_tmap_
  125.     extn    draw_tmap_
  126.  
  127. ;specifies new routines to call to draw polygons
  128. ;takes eax=ptr to tmap routine, edx=ptr to flat routine, ebx=line rtn
  129. g3_set_special_render:
  130.     or    eax,eax
  131.     jnz    got_tmap_ptr
  132.     lea    eax,cs:draw_tmap_
  133. got_tmap_ptr:    mov    tmap_drawer_ptr,eax
  134.  
  135.     or    edx,edx
  136.     jnz    got_flat_ptr
  137.     lea    edx,cs:gr_upoly_tmap_
  138. got_flat_ptr:    mov    flat_drawer_ptr,edx
  139.  
  140.     or    ebx,ebx
  141.     jnz    got_line_ptr
  142.     lea    ebx,cs:gr_line_
  143. got_line_ptr:    mov    line_drawer_ptr,ebx
  144.  
  145.     ret
  146.  
  147.  
  148. ;alternate entry takes pointers to points. esi,edi = point pointers
  149. g3_draw_line:
  150.     ;;ifndef    NDEBUG
  151.     ;; mov    ax,_Frame_count    ;curren frame
  152.     ;; cmp    ax,[esi].p3_frame    ;rotated this frame?
  153.     ;; break_if    ne,'Point not rotated in draw_line'
  154.     ;; cmp    ax,[edi].p3_frame    ;rotated this frame?
  155.     ;; break_if    ne,'Point not rotated in draw_line'
  156.     ;;endif
  157.  
  158.     mov    al,[esi].p3_codes
  159.     mov    ah,[edi].p3_codes
  160.  
  161. ;check codes for reject, clip, or no clip
  162.  
  163.     test    al,ah    ;check codes_and
  164.     jnz    no_draw_line    ;both off same side
  165.  
  166.     or    al,ah    ;al=codes_or
  167.     js    must_clip_line    ;neg z means must clip
  168.     
  169.     test    [esi].p3_flags,PF_PROJECTED
  170.     jnz    p0_projected
  171.     call    g3_project_point
  172. p0_projected:    test    [esi].p3_flags,PF_OVERFLOW
  173.     jnz    must_clip_line
  174.  
  175.     test    [edi].p3_flags,PF_PROJECTED
  176.     jnz    p1_projected
  177.     xchg    esi,edi    ;get point in esi
  178.     call    g3_project_point
  179.     xchg    esi,edi
  180. p1_projected:    test    [edi].p3_flags,PF_OVERFLOW
  181.     jnz    must_clip_line
  182.  
  183.     pushm    ebx,ecx,edx    ;save regs
  184.  
  185.     test    al,al    ;check codes or
  186.  
  187.     mov    eax,[esi].p3_sx
  188.     mov    edx,[esi].p3_sy
  189.  
  190.     mov    ebx,[edi].p3_sx
  191.     mov    ecx,[edi].p3_sy
  192.  
  193.     jz    unclipped_line    ;cc set from test above
  194.  
  195. ;call clipping line drawer
  196. ;;    call    gr_line_    ;takes eax,edx,ebx,ecx
  197.  push esi
  198.  mov esi,line_drawer_ptr
  199.  call esi
  200.  pop esi
  201.     popm    ebx,ecx,edx
  202.     ret    ;return value from gr_line
  203.  
  204. ;we know this one is on screen
  205. unclipped_line:    ;;call    gr_uline_    ;takes eax,edx,ebx,ecx
  206. ;; call gr_line_
  207.  push esi
  208.  mov esi,line_drawer_ptr
  209.  call esi
  210.  pop esi
  211.     popm    ebx,ecx,edx
  212.     mov    al,1    ;definitely drew
  213.     ret
  214.  
  215. ;both points off same side, no do draw
  216. no_draw_line:    xor    al,al    ;not drawn
  217.     ret
  218.  
  219. ;jumped here from out of g3_draw_line. esi,edi=points, al=codes_or
  220. must_clip_line:    call    clip_line    ;do the 3d clip
  221.     call    g3_draw_line    ;try draw again
  222.  
  223. ;free up temp points
  224.     test    [esi].p3_flags,PF_TEMP_POINT
  225.     jz    not_temp_esi
  226.     call    free_temp_point
  227. not_temp_esi:    test    [edi].p3_flags,PF_TEMP_POINT
  228.     jz    not_temp_edi
  229.     xchg    esi,edi
  230.     call    free_temp_point
  231. not_temp_edi:
  232.     ret    ;ret code set from g3_draw_line
  233.  
  234.  
  235. ;returns true if a plane is facing the viewer. takes the unrotated surface 
  236. ;normal of the plane, and a point on it.  The normal need not be normalized
  237. ;takes esi=vector (unrotated point), edi=normal. 
  238. ;returns al=true if facing, cc=g if facing
  239. ;trashes esi,edi
  240. g3_check_normal_facing:
  241.     push    edi    ;save normal
  242.     lea    eax,tempv
  243.     mov    edi,esi
  244.     lea    esi,View_position
  245.     call    vm_vec_sub
  246.  
  247.     mov    esi,eax    ;view vector
  248.     pop    edi    ;normal
  249.     call    vm_vec_dotprod
  250.  
  251.     or    eax,eax    ;check sign
  252.     setg    al    ;true if positive
  253.  
  254.     ret
  255.  
  256. ;see if face is visible and draw if it is.
  257. ;takes ecx=nv, esi=point list, edi=normal, ebx=point.
  258. ;normal can be NULL, which will for compution here (which will be slow).
  259. ;returns al=-1 if not facing, else 0
  260. ;Trashes ecx,esi,edx,edi
  261. g3_check_and_draw_poly:
  262.     call    do_facing_check
  263.     or    al,al
  264.     jnz    g3_draw_poly
  265.     mov    al,-1
  266.     ret
  267.  
  268. g3_check_and_draw_tmap:
  269.     push    ebx
  270.     mov    ebx,eax
  271.     call    do_facing_check
  272.     pop    ebx
  273.     or    al,al
  274.     jnz    g3_draw_tmap
  275.     mov    al,-1
  276.     ret
  277.  
  278.  
  279. ;takes edi=normal or NULL, esi=list of vert nums, ebx=pnt
  280. ;returns al=facing?
  281. do_facing_check:
  282.     test    edi,edi    ;normal passed?
  283.     jz    compute_normal    ;..nope
  284.  
  285. ;for debug, check for NULL normal
  286.     ifndef    NDEBUG
  287.      mov    eax,[edi].x
  288.      or    eax,[edi].y
  289.      or    eax,[edi].z
  290.      break_if    z,'Zero-length normal in do_facing_check'
  291.     endif
  292.  
  293. ;we have the normal. check if facing
  294.     push    esi
  295.     mov    esi,ebx
  296.     call    g3_check_normal_facing    ;edi=normal
  297.     pop    esi
  298.     setg    al    ;set al true if facing
  299.     ret
  300.  
  301. ;normal not specified, so must compute
  302. compute_normal:
  303.     pushm    ebx,ecx,edx,esi
  304.  
  305. ;get three points (rotated) and compute normal
  306.  
  307.     mov    eax,[esi]    ;get point
  308.     mov    edi,8[esi]    ;get point
  309.     mov    esi,4[esi]    ;get point
  310.  
  311.     lea    ebx,tempv
  312.     call    vm_vec_perp    ;get normal
  313.     mov    edi,eax    ;normal in edi
  314.     call    vm_vec_dotprod    ;point in esi
  315.  
  316.     or    eax,eax    ;check result
  317.     popm    ebx,ecx,edx,esi
  318.     sets    al    ;al=true if facing
  319.     ret
  320.  
  321.  
  322. ;draw a flat-shaded face.  returns true if drew
  323. ;takes ecx=nv, esi=list of pointers to points
  324. ;returns al=0 if called 2d, 1 if all points off screen  
  325. ;Trashes ecx,esi,edx
  326. g3_draw_poly:
  327.     pushm    ebx,edi
  328.  
  329.     lea    edi,Vbuf0    ;list of ptrs
  330.     xor    ebx,ebx    ;counter
  331.     mov    dx,0ff00h    ;init codes
  332.  
  333. codes_loop:    mov    eax,[esi+ebx*4]    ;get point number
  334.     mov    [edi+ebx*4],eax    ;store in ptr array
  335.  
  336.     ;;ifndef    NDEBUG
  337.     ;; push    ebx
  338.     ;; mov    bx,_Frame_count    ;curren frame
  339.     ;; cmp    bx,[eax].p3_frame    ;rotated this frame?
  340.     ;; break_if    ne,'Point not rotated in draw_poly'
  341.     ;; pop    ebx
  342.     ;;endif
  343.  
  344.     and    dh,[eax].p3_codes    ;update codes_and
  345.     or    dl,[eax].p3_codes    ;update codes_or
  346.  
  347.     inc    ebx
  348.     cmp    ebx,ecx    ;done?
  349.     jne    codes_loop    ;..nope
  350.  
  351. ;now dx = codes
  352.     test    dh,dh    ;check codes_and
  353.     jnz    face_off_screen    ;not visible at all
  354.  
  355.     test    dl,dl    ;how about codes_or
  356.     js    must_clip_face    ;neg z means must clip
  357.  jnz must_clip_face
  358.  
  359. ;reentry point for jump back from clipper
  360. draw_poly_reentry:
  361.     push    edx    ;save codes_or
  362.  
  363. ;now make list of 2d coords (& check for overflow)
  364.  
  365.     mov    edx,edi    ;edx=Vbuf0
  366.     xor    ebx,ebx
  367.     lea    edi,Vertex_list
  368.  
  369. coords_loop:    mov    esi,[edx+ebx*4]    ;esi = point
  370.     test    [esi].p3_flags,PF_PROJECTED
  371.     jnz    pnt_projected
  372.     call    g3_project_point
  373. pnt_projected:    test    [esi].p3_flags,PF_OVERFLOW
  374.     jnz    must_clip_face2
  375.     mov    eax,[esi].p3_sx
  376.     mov    [edi+ebx*8],eax
  377.     mov    eax,[esi].p3_sy
  378.     mov    4[edi+ebx*8],eax
  379.  
  380.     inc    ebx
  381.     cmp    ebx,ecx
  382.     jne    coords_loop
  383.  
  384.     mov    eax,ecx    ;eax=nverts
  385.     mov    edx,edi    ;edx=vertslist
  386.  
  387. ;check for trivial accept
  388.     pop    ebx    ;get codes_or
  389. ife DONT_USE_UPOLY
  390.     test    bl,bl
  391.     jz    no_clip_face
  392. endif
  393.     ;;call    gr_poly_    ;takes eax,edx
  394. ;;; call gr_upoly_tmap_
  395.  push ecx
  396.  mov ecx,flat_drawer_ptr
  397.  call ecx
  398.  pop ecx
  399.  
  400.     popm    ebx,edi
  401.     xor    al,al    ;say it drew
  402.     ret
  403.  
  404. ;all on screen.  call non-clipping version
  405. no_clip_face:    ;;call    gr_upoly_    ;takes eax,edx
  406. ;; call gr_poly_
  407.  call gr_upoly_tmap_
  408.     popm    ebx,edi
  409.     xor    al,al    ;say it drew
  410.     ret
  411.  
  412. ;all the way off screen. return
  413. face_off_screen:    popm    ebx,edi
  414.     mov    al,1    ;no draw
  415.     ret
  416.  
  417. ;we require a 3d clip
  418. must_clip_face2:    pop    edx    ;get codes back
  419. must_clip_face:    lea    esi,Vbuf0    ;src
  420.     lea    edi,Vbuf1    ;dest
  421.     mov    al,dl    ;codes in al
  422.     call    clip_polygon    ;count in ecx
  423.  
  424.     mov    edi,esi    ;new list in edi
  425.  
  426. ;clipped away?
  427.     jecxz    clipped_away
  428.     or    dh,dh    ;check codes_and
  429.     jnz    clipped_away
  430.  test dl,dl    ;check codes or
  431.  js clipped_away    ;some points still behind eye
  432.  
  433.     push    edi    ;need edi to free temp pnts
  434.     push    offset cs:reentry_return
  435.     pushm    ebx,edi    ;match what draw has pushed
  436.     jmp    draw_poly_reentry
  437.  
  438. reentry_return:
  439.     pop    edi
  440. clipped_away:    
  441.     push    eax    ;save ret codes
  442. ;free temp points
  443.     xor    ebx,ebx
  444. free_loop:    mov    esi,[edi+ebx*4]    ;get point
  445.     test    [esi].p3_flags,PF_TEMP_POINT
  446.     jz    not_temp
  447.     call    free_temp_point
  448. not_temp:    inc    ebx
  449.     cmp    ebx,ecx
  450.     jne    free_loop
  451.  
  452.     pop    eax    ;get ret codes back
  453.  
  454.     popm    ebx,edi
  455.     ret
  456.  
  457.  
  458. ;draw a texture-mapped face.  returns true if drew
  459. ;takes ecx=nv, esi=point list, ebx=uvl_list, edx=bitmap
  460. ;returns al=0 if called 2d, 1 if all points off screen  
  461. ;Trashes ecx,esi,edx
  462. g3_draw_tmap:
  463.     mov    bitmap_ptr,edx    ;save
  464.  
  465.     pushm    ebx,edi
  466.  
  467.     lea    edi,Vbuf0    ;list of ptrs
  468.     push    ebp    ;save ebp
  469.     mov    ebp,ebx    ;ebp=uvl list
  470.  mov uvl_list_ptr, ebx
  471.     mov    n_verts,ecx    ;save in memory
  472.     shl    ecx, 2
  473.  
  474. ;loop to check codes, make list of point ptrs, and copy uvl's into points
  475.     mov    dh, 0ffh    ; init codes (this pipelines nicely)
  476.     mov    n_verts_4, ecx
  477.     xor    ebx, ebx
  478.     xor    dl, dl    ; init codes (this pipelines nicely)
  479.  
  480. t_codes_loop:    mov    eax,[esi+ebx]    ;get point number
  481.     mov    [edi+ebx],eax    ;store in ptr array
  482.  
  483.     and    dh,[eax].p3_codes    ;update codes_and
  484.     or    dl,[eax].p3_codes    ;update codes_or
  485.  
  486.     mov    ecx,[ebp]    ;get u
  487.     add    ebp, 4    ; (this pipelines better ..mk, 11/29/94 ((my 33rd birthday...)))
  488.     mov    [eax].p3_u,ecx
  489.     mov    ecx,[ebp]    ;get v
  490.     add    ebp, 4
  491.     mov    [eax].p3_v,ecx
  492.     mov    ecx,[ebp]    ;get l
  493.     add    ebp, 4
  494.     mov    [eax].p3_l,ecx
  495.     or    [eax].p3_flags,PF_UVS + PF_LVS    ;this point's got em
  496.  
  497.     add    ebx,4
  498.     cmp    ebx, n_verts_4
  499.     jne    t_codes_loop    ;..nope
  500.  
  501.     pop    ebp    ;restore ebp
  502. ;now dx = codes
  503.     test    dh,dh    ;check codes_and
  504.     jnz    t_face_off_screen    ;not visible at all
  505.  
  506.     test    dl,dl    ;how about codes_or
  507.     jnz    t_must_clip_face    ;non-zero means must clip
  508.  
  509. ;reentry point for jump back from clipper
  510. t_draw_poly_reentry:
  511.  
  512. ;make sure all points projected
  513.     mov    edx,edi    ;edx=Vbuf0
  514.     xor    ebx,ebx
  515.  
  516. t_proj_loop:    mov    esi,[edx+ebx*4]    ;esi = point
  517.  
  518.     ;;ifndef    NDEBUG
  519.     ;; mov    ax,_Frame_count    ;curren frame
  520.     ;; cmp    ax,[esi].p3_frame    ;rotated this frame?
  521.     ;; break_if    ne,'Point not rotated in draw_tmap'
  522.     ;;endif
  523.  
  524.     test    [esi].p3_flags,PF_PROJECTED
  525.     jnz    t_pnt_projected
  526.     call    g3_project_point
  527. t_pnt_projected:
  528.     test    [esi].p3_flags,PF_OVERFLOW
  529.     break_if    nz,'Should not overflow after clip'
  530.     jnz    t_face_off_screen
  531.  
  532.     inc    ebx
  533.     cmp    ebx,n_verts
  534.     jne    t_proj_loop
  535.  
  536. ;now call the texture mapper
  537.     mov    eax,bitmap_ptr    ;eax=bitmap ptr
  538.     mov    edx,n_verts    ;edx=count
  539.     mov    ebx,edi    ;ebx=points
  540. ;;;    call    draw_tmap_
  541.  push ecx
  542.  mov ecx,tmap_drawer_ptr
  543.  call ecx
  544.  pop ecx
  545.     popm    ebx,edi
  546.     xor    al,al    ;say it drew
  547.     ret
  548.  
  549. ;all the way off screen. return
  550. t_face_off_screen:    popm    ebx,edi
  551.     mov    al,1    ;no draw
  552.     ret
  553.  
  554. ;we require a 3d clip
  555. t_must_clip_face:    lea    esi,Vbuf0    ;src
  556.     lea    edi,Vbuf1    ;dest
  557.     mov    al,dl    ;codes in al
  558.     mov    ecx,n_verts
  559.     call    clip_polygon    ;count in ecx
  560.     mov    n_verts,ecx
  561.  
  562.     mov    edi,esi    ;new list in edi
  563.  
  564. ;clipped away?
  565.     jecxz    t_clipped_away
  566.     or    dh,dh    ;check codes_and
  567.     jnz    t_clipped_away
  568.  test dl,dl    ;check codes or
  569.  js t_clipped_away    ;some points still behind eye
  570.  
  571.     push    edi    ;need edi to free temp pnts
  572.     push    offset cs:t_reentry_return
  573.     pushm    ebx,edi    ;match what draw has pushed
  574.     jmp    t_draw_poly_reentry
  575.  
  576. t_reentry_return:
  577.     pop    edi
  578. t_clipped_away:    
  579. ; free temp points
  580.     mov    ebx, ecx
  581.     push    eax    ;save ret code
  582.     dec    ebx
  583.     shl    ebx, 2
  584.  
  585. t_free_loop:    mov    esi,[edi+ebx]    ;get point
  586.     test    [esi].p3_flags,PF_TEMP_POINT
  587.     jz    t_not_temp
  588.     call    free_temp_point
  589. t_not_temp:    sub    ebx, 4
  590.     jns    t_free_loop
  591.  
  592.     pop    eax    ;get ret code
  593.  
  594.     popm    ebx,edi
  595.     ret
  596.  
  597.  
  598.  
  599. ;draw a sortof-sphere. takes esi=point, ecx=radius
  600. g3_draw_sphere:    test    [esi].p3_codes,CC_BEHIND
  601.     jnz    reject_sphere
  602.  
  603.     test    [esi].p3_flags,PF_PROJECTED
  604.     jnz    sphere_p_projected
  605.     call    g3_project_point
  606. sphere_p_projected:
  607.     test    [esi].p3_flags,PF_OVERFLOW
  608.     jnz    reject_sphere
  609.  
  610.  
  611. ;calc radius.  since disk doesn't take width & height, let's just
  612. ;say the the radius is the width
  613.  
  614.     pushm    eax,ebx,ecx,edx
  615.  
  616.     mov    eax,ecx
  617.     fixmul    Matrix_scale.x
  618.     imul    Canv_w2
  619. sphere_proj_div:    divcheck    [esi].z,sphere_div_overflow_handler
  620.     idiv    [esi].z
  621.  
  622.     mov    ebx,eax
  623.  
  624.     mov    eax,[esi].p3_sx
  625.     mov    edx,[esi].p3_sy
  626.     call    gr_disk_
  627.  
  628. sphere_div_overflow_handler:
  629.  
  630.     popm    eax,ebx,ecx,edx
  631.  
  632.  
  633. reject_sphere:    ret
  634.  
  635.  
  636. _TEXT    ends
  637.  
  638.     end
  639.